For arm32, kill REG_PROFILER_RET_SCRATCH for LSRA but not for GC (#40123)
authorAndy Ayers <andya@microsoft.com>
Thu, 30 Jul 2020 18:05:17 +0000 (11:05 -0700)
committerGitHub <noreply@github.com>
Thu, 30 Jul 2020 18:05:17 +0000 (11:05 -0700)
Reworking of #37969. Block LSRA from using R2 around the profiler leave
callback, but don't kill GC refs in R2, since late codegen will use
R2 to temporarily hold return values around the callback.

Fixes #37223.

Co-authored-by: Carol Eidt <carol.eidt@microsoft.com>
src/coreclr/src/jit/emit.cpp
src/coreclr/src/jit/lsraarm.cpp
src/coreclr/src/jit/target.h

index cc12dab..ab1c281 100644 (file)
@@ -7692,7 +7692,12 @@ regMaskTP emitter::emitGetGCRegsKilledByNoGCCall(CorInfoHelpFunc helper)
             break;
 
         case CORINFO_HELP_PROF_FCN_LEAVE:
+#if defined(TARGET_ARM)
+            // profiler scratch remains gc live
+            result = RBM_PROFILER_LEAVE_TRASH & ~RBM_PROFILER_RET_SCRATCH;
+#else
             result = RBM_PROFILER_LEAVE_TRASH;
+#endif
             break;
 
         case CORINFO_HELP_PROF_FCN_TAILCALL:
index b9b4d0f..8402bcd 100644 (file)
@@ -491,6 +491,8 @@ int LinearScan::BuildNode(GenTree* tree)
 
         case GT_RETURN:
             srcCount = BuildReturn(tree);
+            killMask = getKillSetForReturn();
+            BuildDefsWithKills(tree, 0, RBM_NONE, killMask);
             break;
 
         case GT_RETFILT:
index 17ecc23..5eac471 100644 (file)
@@ -1106,7 +1106,9 @@ typedef unsigned char   regNumberSmall;
   // The registers trashed by profiler enter/leave/tailcall hook
   // See vm\arm\asmhelpers.asm for more details.
   #define RBM_PROFILER_ENTER_TRASH     RBM_NONE
-  #define RBM_PROFILER_LEAVE_TRASH     RBM_NONE
+  // While REG_PROFILER_RET_SCRATCH is not trashed by the method, the register allocator must
+  // consider it killed by the return.
+  #define RBM_PROFILER_LEAVE_TRASH     RBM_PROFILER_RET_SCRATCH
   #define RBM_PROFILER_TAILCALL_TRASH  RBM_NONE
 
   // Which register are int and long values returned in ?