Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LoongArch64-RISCV64] Refactor the profiler for LoongArch64 and also fix some errors for RISCV64. #91722

Merged
merged 4 commits into from
Sep 8, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 70 additions & 30 deletions src/coreclr/jit/codegenloongarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7758,35 +7758,6 @@ void CodeGen::instGen_MemoryBarrier(BarrierKind barrierKind)
GetEmitter()->emitIns_I(INS_dbar, EA_4BYTE, INS_BARRIER_FULL);
}

//-----------------------------------------------------------------------------------
// genProfilingLeaveCallback: Generate the profiling function leave or tailcall callback.
// Technically, this is not part of the epilog; it is called when we are generating code for a GT_RETURN node.
//
// Arguments:
// helper - which helper to call. Either CORINFO_HELP_PROF_FCN_LEAVE or CORINFO_HELP_PROF_FCN_TAILCALL
//
// Return Value:
// None
//
void CodeGen::genProfilingLeaveCallback(unsigned helper /*= CORINFO_HELP_PROF_FCN_LEAVE*/)
{
assert((helper == CORINFO_HELP_PROF_FCN_LEAVE) || (helper == CORINFO_HELP_PROF_FCN_TAILCALL));

// Only hook if profiler says it's okay.
if (!compiler->compIsProfilerHookNeeded())
{
return;
}

compiler->info.compProfilerCallback = true;

// Need to save on to the stack level, since the helper call will pop the argument
unsigned saveStackLvl2 = genStackLevel;

/* Restore the stack level */
SetStackLevel(saveStackLvl2);
}

/*-----------------------------------------------------------------------------
*
* Push/Pop any callee-saved registers we have used
Expand Down Expand Up @@ -8662,6 +8633,7 @@ void CodeGen::genFnPrologCalleeRegArgs()
assert(!regArgMaskLive);
}

#ifdef PROFILING_SUPPORTED
//-----------------------------------------------------------------------------------
// genProfilingEnterCallback: Generate the profiling function enter callback.
//
Expand All @@ -8677,10 +8649,78 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed)
{
assert(compiler->compGeneratingProlog);

// Give profiler a chance to back out of hooking this method
if (!compiler->compIsProfilerHookNeeded())
{
return;
}

if (compiler->compProfilerMethHndIndirected)
{
instGen_Set_Reg_To_Imm(EA_PTR_DSP_RELOC, REG_PROFILER_ENTER_ARG_FUNC_ID,
(ssize_t)compiler->compProfilerMethHnd);
GetEmitter()->emitIns_R_R_I(INS_ld_d, EA_PTRSIZE, REG_PROFILER_ENTER_ARG_FUNC_ID,
REG_PROFILER_ENTER_ARG_FUNC_ID, 0);
}
else
{
instGen_Set_Reg_To_Imm(EA_PTRSIZE, REG_PROFILER_ENTER_ARG_FUNC_ID, (ssize_t)compiler->compProfilerMethHnd);
}

int callerSPOffset = compiler->lvaToCallerSPRelativeOffset(0, isFramePointerUsed());
genInstrWithConstant(INS_addi_d, EA_PTRSIZE, REG_PROFILER_ENTER_ARG_CALLER_SP, genFramePointerReg(),
(ssize_t)(-callerSPOffset), REG_PROFILER_ENTER_ARG_CALLER_SP);

genEmitHelperCall(CORINFO_HELP_PROF_FCN_ENTER, 0, EA_UNKNOWN);

if ((genRegMask(initReg) & RBM_PROFILER_ENTER_TRASH) != RBM_NONE)
{
*pInitRegZeroed = false;
}
}

//-----------------------------------------------------------------------------------
// genProfilingLeaveCallback: Generate the profiling function leave or tailcall callback.
// Technically, this is not part of the epilog; it is called when we are generating code for a GT_RETURN node.
//
// Arguments:
// helper - which helper to call. Either CORINFO_HELP_PROF_FCN_LEAVE or CORINFO_HELP_PROF_FCN_TAILCALL
//
// Return Value:
// None
//
void CodeGen::genProfilingLeaveCallback(unsigned helper /*= CORINFO_HELP_PROF_FCN_LEAVE*/)
{
assert((helper == CORINFO_HELP_PROF_FCN_LEAVE) || (helper == CORINFO_HELP_PROF_FCN_TAILCALL));

if (!compiler->compIsProfilerHookNeeded())
{
return;
}

compiler->info.compProfilerCallback = true;

if (compiler->compProfilerMethHndIndirected)
shushanhf marked this conversation as resolved.
Show resolved Hide resolved
{
instGen_Set_Reg_To_Imm(EA_PTR_DSP_RELOC, REG_PROFILER_LEAVE_ARG_FUNC_ID,
(ssize_t)compiler->compProfilerMethHnd);
GetEmitter()->emitIns_R_R_I(INS_ld_d, EA_PTRSIZE, REG_PROFILER_LEAVE_ARG_FUNC_ID,
REG_PROFILER_LEAVE_ARG_FUNC_ID, 0);
}
else
{
instGen_Set_Reg_To_Imm(EA_PTRSIZE, REG_PROFILER_LEAVE_ARG_FUNC_ID, (ssize_t)compiler->compProfilerMethHnd);
}

gcInfo.gcMarkRegSetNpt(RBM_PROFILER_LEAVE_ARG_FUNC_ID);

int callerSPOffset = compiler->lvaToCallerSPRelativeOffset(0, isFramePointerUsed());
genInstrWithConstant(INS_addi_d, EA_PTRSIZE, REG_PROFILER_LEAVE_ARG_CALLER_SP, genFramePointerReg(),
(ssize_t)(-callerSPOffset), REG_PROFILER_LEAVE_ARG_CALLER_SP);

gcInfo.gcMarkRegSetNpt(RBM_PROFILER_LEAVE_ARG_CALLER_SP);

genEmitHelperCall(helper, 0, EA_UNKNOWN);
}
#endif // PROFILING_SUPPORTED

#endif // TARGET_LOONGARCH64
16 changes: 8 additions & 8 deletions src/coreclr/jit/targetloongarch64.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,14 +212,14 @@
#define REG_PREV(reg) ((regNumber)((unsigned)(reg) - 1))

// The following registers are used in emitting Enter/Leave/Tailcall profiler callbacks
#define REG_PROFILER_ENTER_ARG_FUNC_ID REG_R10
#define RBM_PROFILER_ENTER_ARG_FUNC_ID RBM_R10
#define REG_PROFILER_ENTER_ARG_CALLER_SP REG_R11
#define RBM_PROFILER_ENTER_ARG_CALLER_SP RBM_R11
#define REG_PROFILER_LEAVE_ARG_FUNC_ID REG_R10
#define RBM_PROFILER_LEAVE_ARG_FUNC_ID RBM_R10
#define REG_PROFILER_LEAVE_ARG_CALLER_SP REG_R11
#define RBM_PROFILER_LEAVE_ARG_CALLER_SP RBM_R11
#define REG_PROFILER_ENTER_ARG_FUNC_ID REG_T1
#define RBM_PROFILER_ENTER_ARG_FUNC_ID RBM_T1
#define REG_PROFILER_ENTER_ARG_CALLER_SP REG_T2
#define RBM_PROFILER_ENTER_ARG_CALLER_SP RBM_T2
#define REG_PROFILER_LEAVE_ARG_FUNC_ID REG_PROFILER_ENTER_ARG_FUNC_ID
#define RBM_PROFILER_LEAVE_ARG_FUNC_ID RBM_PROFILER_ENTER_ARG_FUNC_ID
#define REG_PROFILER_LEAVE_ARG_CALLER_SP REG_PROFILER_ENTER_ARG_CALLER_SP
#define RBM_PROFILER_LEAVE_ARG_CALLER_SP RBM_PROFILER_ENTER_ARG_CALLER_SP

// The registers trashed by profiler enter/leave/tailcall hook
#define RBM_PROFILER_ENTER_TRASH (RBM_CALLEE_TRASH & ~(RBM_ARG_REGS|RBM_FLTARG_REGS|RBM_FP))
Expand Down
49 changes: 22 additions & 27 deletions src/coreclr/vm/loongarch64/asmconstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,43 +255,38 @@ ASMCONSTANTS_C_ASSERT(CallCountingStubData__TargetForMethod == offsetof(CallCoun
ASMCONSTANTS_C_ASSERT(CallCountingStubData__TargetForThresholdReached == offsetof(CallCountingStubData, TargetForThresholdReached))

#ifdef PROFILING_SUPPORTED
#define PROFILE_ENTER 1
#define PROFILE_LEAVE 2
#define PROFILE_TAILCALL 4

#define SIZEOF__PROFILE_PLATFORM_SPECIFIC_DATA 272
ASMCONSTANTS_C_ASSERT(SIZEOF__PROFILE_PLATFORM_SPECIFIC_DATA == sizeof(PROFILE_PLATFORM_SPECIFIC_DATA))
#define PROFILE_ENTER 1
#define PROFILE_LEAVE 2
#define PROFILE_TAILCALL 4

// NOTE: this should be 16-byte aligned as stack size.
#define SIZEOF__PROFILE_PLATFORM_SPECIFIC_DATA 0x140
ASMCONSTANTS_C_ASSERT(SIZEOF__PROFILE_PLATFORM_SPECIFIC_DATA == (sizeof(PROFILE_PLATFORM_SPECIFIC_DATA)+8))

#define PROFILE_PLATFORM_SPECIFIC_DATA__Fp 0
#define PROFILE_PLATFORM_SPECIFIC_DATA__Pc 8
#define PROFILE_PLATFORM_SPECIFIC_DATA__probeSp 16
#define PROFILE_PLATFORM_SPECIFIC_DATA__profiledSp 24
#define PROFILE_PLATFORM_SPECIFIC_DATA__hiddenArg 32
#define PROFILE_PLATFORM_SPECIFIC_DATA__functionId 40
#define PROFILE_PLATFORM_SPECIFIC_DATA__flags 48
#define PROFILE_PLATFORM_SPECIFIC_DATA__argumentRegisters 56
#define PROFILE_PLATFORM_SPECIFIC_DATA__floatArgumentRegisters 120

#define ASMCONSTANTS_C_ASSERT_OFFSET(type, field) \
ASMCONSTANTS_C_ASSERT(type##__##field == offsetof(type, field))

#define PROFILE_PLATFORM_SPECIFIC_DATA__Fp 0
ASMCONSTANTS_C_ASSERT_OFFSET(PROFILE_PLATFORM_SPECIFIC_DATA, Fp)
#define PROFILE_PLATFORM_SPECIFIC_DATA__Pc 8
ASMCONSTANTS_C_ASSERT_OFFSET(PROFILE_PLATFORM_SPECIFIC_DATA, Pc)
#define PROFILE_PLATFORM_SPECIFIC_DATA__x8 16
ASMCONSTANTS_C_ASSERT_OFFSET(PROFILE_PLATFORM_SPECIFIC_DATA, x8)
#define PROFILE_PLATFORM_SPECIFIC_DATA__argumentRegisters 24
ASMCONSTANTS_C_ASSERT_OFFSET(PROFILE_PLATFORM_SPECIFIC_DATA, argumentRegisters)
#define PROFILE_PLATFORM_SPECIFIC_DATA__functionId 88
ASMCONSTANTS_C_ASSERT_OFFSET(PROFILE_PLATFORM_SPECIFIC_DATA, functionId)
#define PROFILE_PLATFORM_SPECIFIC_DATA__floatArgumentRegisters 96
ASMCONSTANTS_C_ASSERT_OFFSET(PROFILE_PLATFORM_SPECIFIC_DATA, floatArgumentRegisters)
#define PROFILE_PLATFORM_SPECIFIC_DATA__probeSp 224
ASMCONSTANTS_C_ASSERT_OFFSET(PROFILE_PLATFORM_SPECIFIC_DATA, probeSp)
#define PROFILE_PLATFORM_SPECIFIC_DATA__profiledSp 232
ASMCONSTANTS_C_ASSERT_OFFSET(PROFILE_PLATFORM_SPECIFIC_DATA, profiledSp)
#define PROFILE_PLATFORM_SPECIFIC_DATA__hiddenArg 240
ASMCONSTANTS_C_ASSERT_OFFSET(PROFILE_PLATFORM_SPECIFIC_DATA, hiddenArg)
#define PROFILE_PLATFORM_SPECIFIC_DATA__flags 248
ASMCONSTANTS_C_ASSERT_OFFSET(PROFILE_PLATFORM_SPECIFIC_DATA, functionId)
ASMCONSTANTS_C_ASSERT_OFFSET(PROFILE_PLATFORM_SPECIFIC_DATA, flags)
#define PROFILE_PLATFORM_SPECIFIC_DATA__unused 252
ASMCONSTANTS_C_ASSERT_OFFSET(PROFILE_PLATFORM_SPECIFIC_DATA, unused)
#define PROFILE_PLATFORM_SPECIFIC_DATA__buffer 256
ASMCONSTANTS_C_ASSERT_OFFSET(PROFILE_PLATFORM_SPECIFIC_DATA, buffer)

ASMCONSTANTS_C_ASSERT_OFFSET(PROFILE_PLATFORM_SPECIFIC_DATA, argumentRegisters)
ASMCONSTANTS_C_ASSERT_OFFSET(PROFILE_PLATFORM_SPECIFIC_DATA, floatArgumentRegisters)
#undef ASMCONSTANTS_C_ASSERT_OFFSET
#endif

#endif // PROFILING_SUPPORTED

#undef ASMCONSTANTS_RUNTIME_ASSERT
#undef ASMCONSTANTS_C_ASSERT
24 changes: 11 additions & 13 deletions src/coreclr/vm/loongarch64/asmhelpers.S
Original file line number Diff line number Diff line change
Expand Up @@ -1078,29 +1078,27 @@ NESTED_ENTRY \helper\()Naked, _TEXT, NoHandler
// Values of $a0-$a7, $fa0-$fa7, $fp are preserved.
// Values of other volatile registers are not preserved.

// $fp,$ra
// $fp,$ra
PROLOG_SAVE_REG_PAIR_INDEXED 22, 1, SIZEOF__PROFILE_PLATFORM_SPECIFIC_DATA // Allocate space and save Fp, Pc.
// Please validate, SAVE_ARGUMENT_REGISTERS doesn't save $t0
SAVE_ARGUMENT_REGISTERS $sp, PROFILE_PLATFORM_SPECIFIC_DATA__argumentRegisters // Save $t0 and argument registers ($a0-$a7).
st.d $zero, $sp, PROFILE_PLATFORM_SPECIFIC_DATA__functionId // Clear functionId.

SAVE_ARGUMENT_REGISTERS $sp, PROFILE_PLATFORM_SPECIFIC_DATA__argumentRegisters
SAVE_FLOAT_ARGUMENT_REGISTERS $sp, PROFILE_PLATFORM_SPECIFIC_DATA__floatArgumentRegisters
addi.d $t3, $fp, SIZEOF__PROFILE_PLATFORM_SPECIFIC_DATA // Compute probeSp - initial value of Sp on entry to the helper.
st.d $t3, $sp, PROFILE_PLATFORM_SPECIFIC_DATA__probeSp
st.d $t2, $sp, PROFILE_PLATFORM_SPECIFIC_DATA__profiledSp
st.d $zero, $sp, PROFILE_PLATFORM_SPECIFIC_DATA__functionId
addi.d $t3, $fp, SIZEOF__PROFILE_PLATFORM_SPECIFIC_DATA // Compute probeSp - initial value of Sp on entry to the helper.
st.d $t3, $sp, PROFILE_PLATFORM_SPECIFIC_DATA__probeSp
st.d $t2, $sp, PROFILE_PLATFORM_SPECIFIC_DATA__profiledSp

st.d $zero, $sp, PROFILE_PLATFORM_SPECIFIC_DATA__hiddenArg // Clear hiddenArg.
addi.d $t3, $zero, \flags
st.d $zero, $sp, PROFILE_PLATFORM_SPECIFIC_DATA__hiddenArg
addi.w $t3, $zero, \flags
st.w $t3, $sp, PROFILE_PLATFORM_SPECIFIC_DATA__flags
st.d $zero, $sp, PROFILE_PLATFORM_SPECIFIC_DATA__unused

ori $a1, $t1, 0
ori $a2, $sp, 0
bl C_FUNC(\helper)

// Please validate, RESTORE_ARGUMENT_REGISTERS doesn't restore $t0
RESTORE_ARGUMENT_REGISTERS $sp, PROFILE_PLATFORM_SPECIFIC_DATA__argumentRegisters // Restore $t0 and argument registers.
RESTORE_ARGUMENT_REGISTERS $sp, PROFILE_PLATFORM_SPECIFIC_DATA__argumentRegisters
RESTORE_FLOAT_ARGUMENT_REGISTERS $sp, PROFILE_PLATFORM_SPECIFIC_DATA__floatArgumentRegisters
// $fp, $ra
// $fp, $ra
EPILOG_RESTORE_REG_PAIR_INDEXED 22, 1, SIZEOF__PROFILE_PLATFORM_SPECIFIC_DATA
EPILOG_RETURN

Expand Down
30 changes: 11 additions & 19 deletions src/coreclr/vm/loongarch64/cgencpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,58 +114,50 @@ struct CalleeSavedRegisters {
// will probably have to communicate this back to the PromoteCallerStack
// routine to avoid a double promotion.
//--------------------------------------------------------------------
#define NUM_ARGUMENT_REGISTERS 8
typedef DPTR(struct ArgumentRegisters) PTR_ArgumentRegisters;
struct ArgumentRegisters {
INT64 a[8]; // a0 ....a7
INT64 a[NUM_ARGUMENT_REGISTERS]; // a0 ....a7
};
#define NUM_ARGUMENT_REGISTERS 8

#define ARGUMENTREGISTERS_SIZE sizeof(ArgumentRegisters)


//--------------------------------------------------------------------
// This represents the floating point argument registers which are saved
// as part of the NegInfo for a FramedMethodFrame. Note that these
// might not be saved by all stubs: typically only those that call into
// C++ helpers will need to preserve the values in these volatile
// registers.
//--------------------------------------------------------------------
#define NUM_FLOAT_ARGUMENT_REGISTERS 8
typedef DPTR(struct FloatArgumentRegisters) PTR_FloatArgumentRegisters;
struct FloatArgumentRegisters {
//TODO: not supports LOONGARCH-SIMD.
double f[8]; // f0-f7
double f[NUM_FLOAT_ARGUMENT_REGISTERS]; // fa0-fa7
};
#define NUM_FLOAT_ARGUMENT_REGISTERS 8


#ifdef PROFILING_SUPPORTED
//**********************************************************************
// Profiling
//**********************************************************************

#ifdef PROFILING_SUPPORTED

// Scratch space to store HFA return values (max 16 bytes)
#define PROFILE_PLATFORM_SPECIFIC_DATA_BUFFER_SIZE 16

typedef struct _PROFILE_PLATFORM_SPECIFIC_DATA
{
void* Fp;
void* Pc;
void* x8;
ArgumentRegisters argumentRegisters;
FunctionID functionId;
FloatArgumentRegisters floatArgumentRegisters;
void* probeSp;
void* profiledSp;
void* hiddenArg;
FunctionID functionId;
UINT32 flags;
UINT32 unused;
BYTE buffer[PROFILE_PLATFORM_SPECIFIC_DATA_BUFFER_SIZE];
ArgumentRegisters argumentRegisters;
FloatArgumentRegisters floatArgumentRegisters;
// Scratch space to reconstruct struct passed two registers:
// one float register and one general register. Including the return args.
BYTE buffer[sizeof(ArgumentRegisters) + sizeof(FloatArgumentRegisters)];
} PROFILE_PLATFORM_SPECIFIC_DATA, *PPROFILE_PLATFORM_SPECIFIC_DATA;

#endif // PROFILING_SUPPORTED


//**********************************************************************
// Exception handling
//**********************************************************************
Expand Down
Loading
Loading