Enable Enter/Leave/Tailcall hooks for RyuJIT/x86
authorBruce Forstall <brucefo@microsoft.com>
Fri, 14 Oct 2016 01:10:33 +0000 (18:10 -0700)
committerBruce Forstall <brucefo@microsoft.com>
Wed, 19 Oct 2016 17:25:38 +0000 (10:25 -0700)
Commit migrated from https://github.com/dotnet/coreclr/commit/fba86f9b18cb39195aea1465beed3df90f004524

12 files changed:
src/coreclr/src/jit/codegenarm.cpp
src/coreclr/src/jit/codegencommon.cpp
src/coreclr/src/jit/codegenxarch.cpp
src/coreclr/src/jit/compiler.cpp
src/coreclr/src/jit/compiler.h
src/coreclr/src/jit/compiler.hpp
src/coreclr/src/jit/emit.cpp
src/coreclr/src/jit/jit.h
src/coreclr/src/jit/jitconfigvalues.h
src/coreclr/src/jit/lower.cpp
src/coreclr/src/jit/lsra.cpp
src/coreclr/src/jit/target.h

index a08f46a..057521f 100644 (file)
@@ -93,16 +93,7 @@ void CodeGen::instGen_Set_Reg_To_Imm(emitAttr size, regNumber reg, ssize_t imm,
     }
     else
     {
-#ifdef _TARGET_AMD64_
-        if (AddrShouldUsePCRel(imm))
-        {
-            getEmitter()->emitIns_R_AI(INS_lea, EA_PTR_DSP_RELOC, reg, imm);
-        }
-        else
-#endif // _TARGET_AMD64_
-        {
-            getEmitter()->emitIns_R_I(INS_mov, size, reg, imm);
-        }
+        getEmitter()->emitIns_R_I(INS_mov, size, reg, imm);
     }
     regTracker.rsTrackRegIntCns(reg, imm);
 }
index 91977e9..1f3a869 100755 (executable)
@@ -656,17 +656,24 @@ regMaskTP Compiler::compHelperCallKillSet(CorInfoHelpFunc helper)
 #endif
 
         case CORINFO_HELP_PROF_FCN_ENTER:
-#ifdef _TARGET_AMD64_
+#ifdef RBM_PROFILER_ENTER_TRASH
             return RBM_PROFILER_ENTER_TRASH;
 #else
-            unreached();
+            NYI("Model kill set for CORINFO_HELP_PROF_FCN_ENTER on target arch");
 #endif
+
         case CORINFO_HELP_PROF_FCN_LEAVE:
-        case CORINFO_HELP_PROF_FCN_TAILCALL:
-#ifdef _TARGET_AMD64_
+#ifdef RBM_PROFILER_LEAVE_TRASH
             return RBM_PROFILER_LEAVE_TRASH;
 #else
-            unreached();
+            NYI("Model kill set for CORINFO_HELP_PROF_FCN_LEAVE on target arch");
+#endif
+
+        case CORINFO_HELP_PROF_FCN_TAILCALL:
+#ifdef RBM_PROFILER_TAILCALL_TRASH
+            return RBM_PROFILER_TAILCALL_TRASH;
+#else
+            NYI("Model kill set for CORINFO_HELP_PROF_FCN_TAILCALL on target arch");
 #endif
 
         case CORINFO_HELP_STOP_FOR_GC:
@@ -689,26 +696,29 @@ regMaskTP Compiler::compHelperCallKillSet(CorInfoHelpFunc helper)
 regMaskTP Compiler::compNoGCHelperCallKillSet(CorInfoHelpFunc helper)
 {
     assert(emitter::emitNoGChelper(helper));
-#ifdef _TARGET_AMD64_
+
     switch (helper)
     {
+#if defined(_TARGET_AMD64_) || defined(_TARGET_X86_)
         case CORINFO_HELP_PROF_FCN_ENTER:
             return RBM_PROFILER_ENTER_TRASH;
 
         case CORINFO_HELP_PROF_FCN_LEAVE:
-        case CORINFO_HELP_PROF_FCN_TAILCALL:
             return RBM_PROFILER_LEAVE_TRASH;
 
+        case CORINFO_HELP_PROF_FCN_TAILCALL:
+            return RBM_PROFILER_TAILCALL_TRASH;
+#endif // defined(_TARGET_AMD64_) || defined(_TARGET_X86_)
+
+#if defined(_TARGET_AMD64_)
         case CORINFO_HELP_ASSIGN_BYREF:
             // this helper doesn't trash RSI and RDI
             return RBM_CALLEE_TRASH_NOGC & ~(RBM_RSI | RBM_RDI);
+#endif // defined(_TARGET_AMD64_)
 
         default:
             return RBM_CALLEE_TRASH_NOGC;
     }
-#else
-    return RBM_CALLEE_TRASH_NOGC;
-#endif
 }
 
 // Update liveness (always var liveness, i.e., compCurLife, and also, if "ForCodeGen" is true, reg liveness, i.e.,
@@ -7253,11 +7263,31 @@ void CodeGen::genSetGSSecurityCookie(regNumber initReg, bool* pInitRegZeroed)
 
 #ifdef PROFILING_SUPPORTED
 
-/*-----------------------------------------------------------------------------
- *
- *  Generate the profiling function enter callback.
- */
-
+//-----------------------------------------------------------------------------------
+// genProfilingEnterCallback: Generate the profiling function enter callback.
+//
+// Arguments:
+//     initReg        - register to use as scratch register
+//     pInitRegZeroed - OUT parameter. *pInitRegZeroed set to 'false' if 'initReg' is
+//                      not zero after this call.
+//
+// Return Value:
+//     None
+//
+// Notes:
+// The x86 profile enter helper has the following requirements (see ProfileEnterNaked in
+// VM\i386\asmhelpers.asm for details):
+// 1. The calling sequence for calling the helper is:
+//          push FunctionIDOrClientID
+//          call ProfileEnterHelper
+// 2. The calling function has an EBP frame.
+// 3. EBP points to the saved ESP which is the first thing saved in the function. Thus,
+//    the following prolog is assumed:
+//          push ESP
+//          mov EBP, ESP
+// 4. All registers are preserved.
+// 5. The helper pops the FunctionIDOrClientID argument from the stack.
+//
 void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed)
 {
     assert(compiler->compGeneratingProlog);
@@ -7268,7 +7298,6 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed)
         return;
     }
 
-#ifndef LEGACY_BACKEND
 #if defined(_TARGET_AMD64_) && !defined(UNIX_AMD64_ABI) // No profiling for System V systems yet.
     unsigned   varNum;
     LclVarDsc* varDsc;
@@ -7312,7 +7341,7 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed)
     else
     {
         // No need to record relocations, if we are generating ELT hooks under the influence
-        // of complus_JitELtHookEnabled=1
+        // of COMPlus_JitELTHookEnabled=1
         if (compiler->opts.compJitELTHookEnabled)
         {
             genSetRegToIcon(REG_ARG_0, (ssize_t)compiler->compProfilerMethHnd, TYP_I_IMPL);
@@ -7378,11 +7407,7 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed)
         *pInitRegZeroed = false;
     }
 
-#else //!_TARGET_AMD64_
-    NYI("RyuJIT: Emit Profiler Enter callback");
-#endif
-
-#else // LEGACY_BACKEND
+#elif defined(_TARGET_X86_) || (defined(_TARGET_ARM_) && defined(LEGACY_BACKEND))
 
     unsigned saveStackLvl2 = genStackLevel;
 
@@ -7455,17 +7480,41 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed)
     /* Restore the stack level */
 
     genStackLevel = saveStackLvl2;
-#endif // LEGACY_BACKEND
-}
 
-/*****************************************************************************
- *
- *  Generates Leave profiler hook.
- *  Technically, this is not part of the epilog; it is called when we are generating code for a GT_RETURN node.
- */
+#else  // target
+    NYI("Emit Profiler Enter callback");
+#endif // target
+}
 
+//-----------------------------------------------------------------------------------
+// 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
+//
+// Notes:
+// The x86 profile leave/tailcall helper has the following requirements (see ProfileLeaveNaked and
+// ProfileTailcallNaked in VM\i386\asmhelpers.asm for details):
+// 1. The calling sequence for calling the helper is:
+//          push FunctionIDOrClientID
+//          call ProfileLeaveHelper or ProfileTailcallHelper
+// 2. The calling function has an EBP frame.
+// 3. EBP points to the saved ESP which is the first thing saved in the function. Thus,
+//    the following prolog is assumed:
+//          push ESP
+//          mov EBP, ESP
+// 4. helper == CORINFO_HELP_PROF_FCN_LEAVE: All registers are preserved.
+//    helper == CORINFO_HELP_PROF_FCN_TAILCALL: Only argument registers are preserved.
+// 5. The helper pops the FunctionIDOrClientID argument from the stack.
+//
 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())
     {
@@ -7474,12 +7523,11 @@ void CodeGen::genProfilingLeaveCallback(unsigned helper /*= CORINFO_HELP_PROF_FC
 
     compiler->info.compProfilerCallback = true;
 
-    // Need to save on to the stack level, since the callee will pop the argument
+    // Need to save on to the stack level, since the helper call will pop the argument
     unsigned saveStackLvl2 = genStackLevel;
 
-#ifndef LEGACY_BACKEND
-
 #if defined(_TARGET_AMD64_) && !defined(UNIX_AMD64_ABI) // No profiling for System V systems yet.
+
     // Since the method needs to make a profiler callback, it should have out-going arg space allocated.
     noway_assert(compiler->lvaOutgoingArgSpaceVar != BAD_VAR_NUM);
     noway_assert(compiler->lvaOutgoingArgSpaceSize >= (4 * REGSIZE_BYTES));
@@ -7509,7 +7557,7 @@ void CodeGen::genProfilingLeaveCallback(unsigned helper /*= CORINFO_HELP_PROF_FC
     else
     {
         // Don't record relocations, if we are generating ELT hooks under the influence
-        // of complus_JitELtHookEnabled=1
+        // of COMPlus_JitELTHookEnabled=1
         if (compiler->opts.compJitELTHookEnabled)
         {
             genSetRegToIcon(REG_ARG_0, (ssize_t)compiler->compProfilerMethHnd, TYP_I_IMPL);
@@ -7549,13 +7597,8 @@ void CodeGen::genProfilingLeaveCallback(unsigned helper /*= CORINFO_HELP_PROF_FC
     // "mov r8, helper addr; call r8"
     genEmitHelperCall(helper, 0, EA_UNKNOWN, REG_ARG_2);
 
-#else  //!_TARGET_AMD64_
-    NYI("RyuJIT: Emit Profiler Leave callback");
-#endif // _TARGET_*
-
-#else // LEGACY_BACKEND
+#elif defined(_TARGET_X86_)
 
-#if defined(_TARGET_X86_)
     //
     // Push the profilerHandle
     //
@@ -7570,7 +7613,7 @@ void CodeGen::genProfilingLeaveCallback(unsigned helper /*= CORINFO_HELP_PROF_FC
     }
     genSinglePush();
 
-    genEmitHelperCall(CORINFO_HELP_PROF_FCN_LEAVE,
+    genEmitHelperCall(helper,
                       sizeof(int) * 1, // argSize
                       EA_UNKNOWN);     // retSize
 
@@ -7581,7 +7624,9 @@ void CodeGen::genProfilingLeaveCallback(unsigned helper /*= CORINFO_HELP_PROF_FC
     {
         compiler->fgPtrArgCntMax = 1;
     }
-#elif defined(_TARGET_ARM_)
+
+#elif defined(LEGACY_BACKEND) && defined(_TARGET_ARM_)
+
     //
     // Push the profilerHandle
     //
@@ -7657,11 +7702,10 @@ void CodeGen::genProfilingLeaveCallback(unsigned helper /*= CORINFO_HELP_PROF_FC
     }
 
     regSet.rsUnlockReg(RBM_PROFILER_RET_USED);
-#else  // _TARGET_*
-    NYI("Pushing the profilerHandle & caller's sp for the profiler callout and locking them");
-#endif // _TARGET_*
 
-#endif // LEGACY_BACKEND
+#else  // target
+    NYI("Emit Profiler Leave callback");
+#endif // target
 
     /* Restore the stack level */
     genStackLevel = saveStackLvl2;
index 4171f14..f63a268 100644 (file)
@@ -1147,7 +1147,7 @@ void CodeGen::genReturn(GenTreePtr treeNode)
     //
     // Reason for not materializing Leave callback as a GT_PROF_HOOK node after GT_RETURN:
     // In flowgraph and other places assert that the last node of a block marked as
-    // GT_RETURN is either a GT_RETURN or GT_JMP or a tail call.  It would be nice to
+    // BBJ_RETURN is either a GT_RETURN or GT_JMP or a tail call.  It would be nice to
     // maintain such an invariant irrespective of whether profiler hook needed or not.
     // Also, there is not much to be gained by materializing it as an explicit node.
     if (compiler->compCurBB == compiler->genReturnBB)
index 1965e7f..c6e6e03 100644 (file)
@@ -3001,22 +3001,25 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags)
     opts.compTailCallLoopOpt = true;
 #endif
 
-#ifdef DEBUG
-    opts.dspInstrs             = false;
-    opts.dspEmit               = false;
-    opts.dspLines              = false;
-    opts.varNames              = false;
-    opts.dmpHex                = false;
-    opts.disAsm                = false;
-    opts.disAsmSpilled         = false;
-    opts.disDiffable           = false;
-    opts.dspCode               = false;
-    opts.dspEHTable            = false;
-    opts.dspGCtbls             = false;
-    opts.disAsm2               = false;
-    opts.dspUnwind             = false;
-    opts.compLongAddress       = false;
+#ifdef PROFILING_SUPPORTED
     opts.compJitELTHookEnabled = false;
+#endif // PROFILING_SUPPORTED
+
+#ifdef DEBUG
+    opts.dspInstrs       = false;
+    opts.dspEmit         = false;
+    opts.dspLines        = false;
+    opts.varNames        = false;
+    opts.dmpHex          = false;
+    opts.disAsm          = false;
+    opts.disAsmSpilled   = false;
+    opts.disDiffable     = false;
+    opts.dspCode         = false;
+    opts.dspEHTable      = false;
+    opts.dspGCtbls       = false;
+    opts.disAsm2         = false;
+    opts.dspUnwind       = false;
+    opts.compLongAddress = false;
 
 #ifdef LATE_DISASM
     opts.doLateDisasm = false;
@@ -3212,11 +3215,8 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags)
         compProfilerMethHndIndirected = false;
     }
 
-#if defined(_TARGET_ARM_) || defined(_TARGET_AMD64_)
-    // Right now this ELT hook option is enabled only for arm and amd64
-
-    // Honour complus_JitELTHookEnabled only if VM has not asked us to generate profiler
-    // hooks in the first place. That is, Override VM only if it hasn't asked for a
+    // Honour COMPlus_JitELTHookEnabled only if VM has not asked us to generate profiler
+    // hooks in the first place. That is, override VM only if it hasn't asked for a
     // profiler callback for this method.
     if (!compProfilerHookNeeded && (JitConfig.JitELTHookEnabled() != 0))
     {
@@ -3229,7 +3229,6 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags)
         compProfilerMethHnd           = (void*)DummyProfilerELTStub;
         compProfilerMethHndIndirected = false;
     }
-#endif // _TARGET_ARM_ || _TARGET_AMD64_
 
 #endif // PROFILING_SUPPORTED
 
index 73df15e..a12d87b 100644 (file)
@@ -7660,9 +7660,11 @@ public:
         // for any call. We have a plan for not needing for stubs though
         bool compNeedStackProbes;
 
-        // Whether to emit Enter/Leave/TailCall hooks using a dummy stub (DummyProfilerELTStub())
-        // This options helps one to make JIT behave as if it is under profiler.
+#ifdef PROFILING_SUPPORTED
+        // Whether to emit Enter/Leave/TailCall hooks using a dummy stub (DummyProfilerELTStub()).
+        // This option helps make the JIT behave as if it is running under a profiler.
         bool compJitELTHookEnabled;
+#endif // PROFILING_SUPPORTED
 
 #if FEATURE_TAILCALL_OPT
         // Whether opportunistic or implicit tail call optimization is enabled.
@@ -8343,14 +8345,14 @@ protected:
 #endif
     void compCompile(void** methodCodePtr, ULONG* methodCodeSize, CORJIT_FLAGS* compileFlags);
 
+#ifdef PROFILING_SUPPORTED
     // Data required for generating profiler Enter/Leave/TailCall hooks
-    CLANG_FORMAT_COMMENT_ANCHOR;
 
-#ifdef PROFILING_SUPPORTED
     bool  compProfilerHookNeeded; // Whether profiler Enter/Leave/TailCall hook needs to be generated for the method
     void* compProfilerMethHnd;    // Profiler handle of the method being compiled. Passed as param to ELT callbacks
     bool  compProfilerMethHndIndirected; // Whether compProfilerHandle is pointer to the handle or is an actual handle
 #endif
+
 #ifdef _TARGET_AMD64_
     bool compQuirkForPPP(); // Check if this method should be Quirked for the PPP issue
 #endif
index 0a0687a..c0e044a 100644 (file)
@@ -4106,16 +4106,12 @@ inline bool Compiler::compIsProfilerHookNeeded()
 {
 #ifdef PROFILING_SUPPORTED
     return compProfilerHookNeeded
-
-#if defined(_TARGET_ARM_) || defined(_TARGET_AMD64_)
            // IL stubs are excluded by VM and we need to do the same even running
            // under a complus env hook to generate profiler hooks
-           || (opts.compJitELTHookEnabled && !(opts.eeFlags & CORJIT_FLG_IL_STUB))
-#endif
-        ;
-#else // PROFILING_SUPPORTED
+           || (opts.compJitELTHookEnabled && !(opts.eeFlags & CORJIT_FLG_IL_STUB));
+#else  // !PROFILING_SUPPORTED
     return false;
-#endif
+#endif // !PROFILING_SUPPORTED
 }
 
 /*****************************************************************************
index 65d2b89..5d58d1a 100644 (file)
@@ -2314,7 +2314,7 @@ bool emitter::emitNoGChelper(unsigned IHX)
 
         case CORINFO_HELP_PROF_FCN_LEAVE:
         case CORINFO_HELP_PROF_FCN_ENTER:
-#ifdef _TARGET_AMD64_
+#if defined(_TARGET_AMD64_) || (defined(_TARGET_X86_) && !defined(LEGACY_BACKEND))
         case CORINFO_HELP_PROF_FCN_TAILCALL:
 #endif
         case CORINFO_HELP_LLSH:
index 1bb21e3..5775e4f 100644 (file)
@@ -28,6 +28,7 @@
 
 #ifdef _MSC_VER
 // These don't seem useful, so turning them off is no big deal
+#pragma warning(disable : 4065) // "switch statement contains 'default' but no 'case' labels" (happens due to #ifdefs)
 #pragma warning(disable : 4510) // can't generate default constructor
 #pragma warning(disable : 4511) // can't generate copy constructor
 #pragma warning(disable : 4512) // can't generate assignment constructor
index de340fa..c471c9a 100644 (file)
@@ -220,8 +220,7 @@ CONFIG_INTEGER(JitEnableNoWayAssert, W("JitEnableNoWayAssert"), 1)
 CONFIG_INTEGER(DisplayMemStats, W("JitMemStats"), 0) // Display JIT memory usage statistics
 
 CONFIG_INTEGER(JitAggressiveInlining, W("JitAggressiveInlining"), 0) // Aggressive inlining of all methods
-CONFIG_INTEGER(JitELTHookEnabled, W("JitELTHookEnabled"), 0) // On ARM, setting this will emit Enter/Leave/TailCall
-                                                             // callbacks
+CONFIG_INTEGER(JitELTHookEnabled, W("JitELTHookEnabled"), 0)         // If 1, emit Enter/Leave/TailCall callbacks
 CONFIG_INTEGER(JitInlineSIMDMultiplier, W("JitInlineSIMDMultiplier"), 3)
 
 #if defined(FEATURE_ENABLE_NO_RANGE_CHECKS)
index dc47bf0..dbe4b5d 100644 (file)
@@ -1394,6 +1394,7 @@ void Lowering::CheckVSQuirkStackPaddingNeeded(GenTreeCall* call)
 
 // Inserts profiler hook, GT_PROF_HOOK for a tail call node.
 //
+// AMD64:
 // We need to insert this after all nested calls, but before all the arguments to this call have been set up.
 // To do this, we look for the first GT_PUTARG_STK or GT_PUTARG_REG, and insert the hook immediately before
 // that. If there are no args, then it should be inserted before the call node.
@@ -1418,16 +1419,30 @@ void Lowering::CheckVSQuirkStackPaddingNeeded(GenTreeCall* call)
 // In this case, the GT_PUTARG_REG src is a nested call. We need to put the instructions after that call
 // (as shown). We assume that of all the GT_PUTARG_*, only the first one can have a nested call.
 //
+// X86:
+// Insert the profiler hook immediately before the call. The profiler hook will preserve
+// all argument registers (ECX, EDX), but nothing else.
+//
 // Params:
 //    callNode        - tail call node
-//    insertionPoint  - if caller has an insertion point; If null
-//                      profiler hook is inserted before args are setup
+//    insertionPoint  - if non-null, insert the profiler hook before this point.
+//                      If null, insert the profiler hook before args are setup
 //                      but after all arg side effects are computed.
+//
 void Lowering::InsertProfTailCallHook(GenTreeCall* call, GenTree* insertionPoint)
 {
     assert(call->IsTailCall());
     assert(comp->compIsProfilerHookNeeded());
 
+#if defined(_TARGET_X86_)
+
+    if (insertionPoint == nullptr)
+    {
+        insertionPoint = call;
+    }
+
+#else // !defined(_TARGET_X86_)
+
     if (insertionPoint == nullptr)
     {
         GenTreePtr tmp = nullptr;
@@ -1464,6 +1479,8 @@ void Lowering::InsertProfTailCallHook(GenTreeCall* call, GenTree* insertionPoint
         }
     }
 
+#endif // !defined(_TARGET_X86_)
+
     assert(insertionPoint != nullptr);
     GenTreePtr profHookNode = new (comp, GT_PROF_HOOK) GenTree(GT_PROF_HOOK, TYP_VOID);
     BlockRange().InsertBefore(insertionPoint, profHookNode);
@@ -1869,12 +1886,16 @@ GenTree* Lowering::LowerTailCallViaHelper(GenTreeCall* call, GenTree* callTarget
     // Now add back tail call flags for identifying this node as tail call dispatched via helper.
     call->gtCallMoreFlags |= GTF_CALL_M_TAILCALL | GTF_CALL_M_TAILCALL_VIA_HELPER;
 
+#ifdef PROFILING_SUPPORTED
     // Insert profiler tail call hook if needed.
     // Since we don't know the insertion point, pass null for second param.
     if (comp->compIsProfilerHookNeeded())
     {
         InsertProfTailCallHook(call, nullptr);
     }
+#endif // PROFILING_SUPPORTED
+
+    assert(call->IsTailCallViaHelper());
 
     return result;
 }
index e427b5d..9fdf9c5 100644 (file)
@@ -2777,7 +2777,7 @@ regMaskTP LinearScan::getKillSetForNode(GenTree* tree)
             }
             break;
 
-#if defined(PROFILING_SUPPORTED) && defined(_TARGET_AMD64_)
+#if defined(PROFILING_SUPPORTED)
         // If this method requires profiler ELT hook then mark these nodes as killing
         // callee trash registers (excluding RAX and XMM0). The reason for this is that
         // profiler callback would trash these registers. See vm\amd64\asmhelpers.asm for
@@ -2793,10 +2793,9 @@ regMaskTP LinearScan::getKillSetForNode(GenTree* tree)
             if (compiler->compIsProfilerHookNeeded())
             {
                 killMask = compiler->compHelperCallKillSet(CORINFO_HELP_PROF_FCN_TAILCALL);
-                ;
             }
             break;
-#endif // PROFILING_SUPPORTED && _TARGET_AMD64_
+#endif // PROFILING_SUPPORTED
 
         default:
             // for all other 'tree->OperGet()' kinds, leave 'killMask' = RBM_NONE
index c78c6b4..1625189 100644 (file)
@@ -678,6 +678,12 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
 
   #define RBM_ARG_REGS            (RBM_ARG_0|RBM_ARG_1)
 
+  // The registers trashed by profiler enter/leave/tailcall hook
+  // See vm\i386\asmhelpers.asm for more details.
+  #define RBM_PROFILER_ENTER_TRASH     RBM_NONE
+  #define RBM_PROFILER_LEAVE_TRASH     RBM_NONE
+  #define RBM_PROFILER_TAILCALL_TRASH  (RBM_ALLINT & ~RBM_ARG_REGS)
+
   // What sort of reloc do we use for [disp32] address mode
   #define IMAGE_REL_BASED_DISP32   IMAGE_REL_BASED_HIGHLOW
 
@@ -1119,9 +1125,10 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
 #endif // !UNIX_AMD64_ABI
 
   // The registers trashed by profiler enter/leave/tailcall hook
-  // See vm\amd64\amshelpers.asm for more details.
-  #define RBM_PROFILER_ENTER_TRASH  RBM_CALLEE_TRASH
-  #define RBM_PROFILER_LEAVE_TRASH  (RBM_CALLEE_TRASH & ~(RBM_FLOATRET | RBM_INTRET))
+  // See vm\amd64\asmhelpers.asm for more details.
+  #define RBM_PROFILER_ENTER_TRASH     RBM_CALLEE_TRASH
+  #define RBM_PROFILER_LEAVE_TRASH     (RBM_CALLEE_TRASH & ~(RBM_FLOATRET | RBM_INTRET))
+  #define RBM_PROFILER_TAILCALL_TRASH  RBM_PROFILER_LEAVE_TRASH
 
   // The registers trashed by the CORINFO_HELP_STOP_FOR_GC helper.
 #ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING