From: Andy Ayers Date: Thu, 30 Jul 2020 18:05:17 +0000 (-0700) Subject: For arm32, kill REG_PROFILER_RET_SCRATCH for LSRA but not for GC (#40123) X-Git-Tag: submit/tizen/20210909.063632~6319 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=32ddcd3f7056914c95e600c0f2055b632e323463;p=platform%2Fupstream%2Fdotnet%2Fruntime.git For arm32, kill REG_PROFILER_RET_SCRATCH for LSRA but not for GC (#40123) 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 --- diff --git a/src/coreclr/src/jit/emit.cpp b/src/coreclr/src/jit/emit.cpp index cc12dab..ab1c281 100644 --- a/src/coreclr/src/jit/emit.cpp +++ b/src/coreclr/src/jit/emit.cpp @@ -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: diff --git a/src/coreclr/src/jit/lsraarm.cpp b/src/coreclr/src/jit/lsraarm.cpp index b9b4d0f..8402bcd 100644 --- a/src/coreclr/src/jit/lsraarm.cpp +++ b/src/coreclr/src/jit/lsraarm.cpp @@ -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: diff --git a/src/coreclr/src/jit/target.h b/src/coreclr/src/jit/target.h index 17ecc23..5eac471 100644 --- a/src/coreclr/src/jit/target.h +++ b/src/coreclr/src/jit/target.h @@ -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 ?