summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Andreenko <seandree@microsoft.com>2019-03-13 18:31:27 -0700
committerGitHub <noreply@github.com>2019-03-13 18:31:27 -0700
commit83327daf3c6186587f91182c39afd8e768baecfd (patch)
tree187e621f4232a7d00831cd712c6537de5e7e2869
parent3d4ed7c829803206db7caea1e348bc4791aec0a6 (diff)
downloadcoreclr-83327daf3c6186587f91182c39afd8e768baecfd.tar.gz
coreclr-83327daf3c6186587f91182c39afd8e768baecfd.tar.bz2
coreclr-83327daf3c6186587f91182c39afd8e768baecfd.zip
Fix/clean compNoGCHelperCallKillSet for arm. (#23078)
* Add an assert to compNoGCHelperCallKillSet. That registers that lose GC or byref values also are in compHelperCallKillSet return set. * Move compNoGCHelperCallKillSet from compiler to emitter. * Rename `compNoGCHelperCallKillSet` to `emitGetGCRegsKilledByNoGCCall`. * Fix GCRegsKill sets for arm CORINFO_HELP_PROF_FCN_ENTER and CORINFO_HELP_PROF_FCN_LEAVE.
-rw-r--r--src/jit/codegencommon.cpp66
-rw-r--r--src/jit/compiler.h3
-rw-r--r--src/jit/emit.cpp81
-rw-r--r--src/jit/emit.h3
4 files changed, 83 insertions, 70 deletions
diff --git a/src/jit/codegencommon.cpp b/src/jit/codegencommon.cpp
index 55028e9e82..a45710330f 100644
--- a/src/jit/codegencommon.cpp
+++ b/src/jit/codegencommon.cpp
@@ -618,72 +618,6 @@ regMaskTP Compiler::compHelperCallKillSet(CorInfoHelpFunc helper)
}
}
-//----------------------------------------------------------------------
-// compNoGCHelperCallKillSet: Gets a register mask that represents the set of registers that no longer
-// contain GC or byref pointers, for "NO GC" helper calls. This is used by the emitter when determining
-// what registers to remove from the current live GC/byref sets (and thus what to report as dead in the
-// GC info). Note that for the CORINFO_HELP_ASSIGN_BYREF helper, in particular, the kill set reported by
-// compHelperCallKillSet() doesn't match this kill set. compHelperCallKillSet() reports the dst/src
-// address registers as killed for liveness purposes, since their values change. However, they still are
-// valid byref pointers after the call, so the dst/src address registers are NOT reported as killed here.
-//
-// Note: This list may not be complete and defaults to the default RBM_CALLEE_TRASH_NOGC registers.
-//
-// Arguments:
-// helper - The helper being inquired about
-//
-// Return Value:
-// Mask of GC register kills
-//
-regMaskTP Compiler::compNoGCHelperCallKillSet(CorInfoHelpFunc helper)
-{
- assert(emitter::emitNoGChelper(helper));
-
- switch (helper)
- {
- case CORINFO_HELP_ASSIGN_BYREF:
-#if defined(_TARGET_X86_)
- // This helper only trashes ECX.
- return RBM_ECX;
-#elif defined(_TARGET_AMD64_)
- // This uses and defs RDI and RSI.
- return RBM_CALLEE_TRASH_NOGC & ~(RBM_RDI | RBM_RSI);
-#elif defined(_TARGET_ARMARCH_)
- return RBM_CALLEE_GCTRASH_WRITEBARRIER_BYREF;
-#else
- assert(!"unknown arch");
-#endif
-
-#if defined(_TARGET_XARCH_)
- case CORINFO_HELP_PROF_FCN_ENTER:
- return RBM_PROFILER_ENTER_TRASH;
-
- case CORINFO_HELP_PROF_FCN_LEAVE:
- return RBM_PROFILER_LEAVE_TRASH;
-
- case CORINFO_HELP_PROF_FCN_TAILCALL:
- return RBM_PROFILER_TAILCALL_TRASH;
-#endif // defined(_TARGET_XARCH_)
-
-#if defined(_TARGET_ARMARCH_)
- case CORINFO_HELP_ASSIGN_REF:
- case CORINFO_HELP_CHECKED_ASSIGN_REF:
- return RBM_CALLEE_GCTRASH_WRITEBARRIER;
- case CORINFO_HELP_PROF_FCN_LEAVE:
- // In case of Leave profiler callback, we need to preserve liveness of REG_PROFILER_RET_SCRATCH on ARMARCH.
- return RBM_CALLEE_TRASH_NOGC & ~RBM_PROFILER_RET_SCRATCH;
-#endif
-
-#if defined(_TARGET_X86_)
- case CORINFO_HELP_INIT_PINVOKE_FRAME:
- return RBM_INIT_PINVOKE_FRAME_TRASH;
-#endif // defined(_TARGET_X86_)
-
- default:
- return RBM_CALLEE_TRASH_NOGC;
- }
-}
-
template <bool ForCodeGen>
void Compiler::compChangeLife(VARSET_VALARG_TP newLife)
{
diff --git a/src/jit/compiler.h b/src/jit/compiler.h
index 8c2b945863..d6edd6483f 100644
--- a/src/jit/compiler.h
+++ b/src/jit/compiler.h
@@ -7195,9 +7195,6 @@ public:
// not all JIT Helper calls follow the standard ABI on the target architecture.
regMaskTP compHelperCallKillSet(CorInfoHelpFunc helper);
- // Gets a register mask that represent the kill set for a NoGC helper call.
- regMaskTP compNoGCHelperCallKillSet(CorInfoHelpFunc helper);
-
#ifdef _TARGET_ARM_
// Requires that "varDsc" be a promoted struct local variable being passed as an argument, beginning at
// "firstArgRegNum", which is assumed to have already been aligned to the register alignment restriction of the
diff --git a/src/jit/emit.cpp b/src/jit/emit.cpp
index db6aa10112..982417d9d6 100644
--- a/src/jit/emit.cpp
+++ b/src/jit/emit.cpp
@@ -7481,7 +7481,7 @@ regMaskTP emitter::emitGetGCRegsSavedOrModified(CORINFO_METHOD_HANDLE methHnd)
CorInfoHelpFunc helpFunc = Compiler::eeGetHelperNum(methHnd);
// Get the set of registers that this call kills and remove it from the saved set.
- regMaskTP savedSet = RBM_ALLINT & ~emitComp->compNoGCHelperCallKillSet(helpFunc);
+ regMaskTP savedSet = RBM_ALLINT & ~emitGetGCRegsKilledByNoGCCall(helpFunc);
#ifdef DEBUG
if (emitComp->verbose)
@@ -7500,3 +7500,82 @@ regMaskTP emitter::emitGetGCRegsSavedOrModified(CORINFO_METHOD_HANDLE methHnd)
return RBM_CALLEE_SAVED;
}
}
+
+//----------------------------------------------------------------------
+// emitGetGCRegsKilledByNoGCCall: Gets a register mask that represents the set of registers that no longer
+// contain GC or byref pointers, for "NO GC" helper calls. This is used by the emitter when determining
+// what registers to remove from the current live GC/byref sets (and thus what to report as dead in the
+// GC info). Note that for the CORINFO_HELP_ASSIGN_BYREF helper, in particular, the kill set reported by
+// compHelperCallKillSet() doesn't match this kill set. compHelperCallKillSet() reports the dst/src
+// address registers as killed for liveness purposes, since their values change. However, they still are
+// valid byref pointers after the call, so the dst/src address registers are NOT reported as killed here.
+//
+// Note: This list may not be complete and defaults to the default RBM_CALLEE_TRASH_NOGC registers.
+//
+// Arguments:
+// helper - The helper being inquired about
+//
+// Return Value:
+// Mask of GC register kills
+//
+regMaskTP emitter::emitGetGCRegsKilledByNoGCCall(CorInfoHelpFunc helper)
+{
+ assert(emitNoGChelper(helper));
+ regMaskTP result;
+ switch (helper)
+ {
+ case CORINFO_HELP_ASSIGN_BYREF:
+#if defined(_TARGET_X86_)
+ // This helper only trashes ECX.
+ result = RBM_ECX;
+ break;
+#elif defined(_TARGET_AMD64_)
+ // This uses and defs RDI and RSI.
+ result = RBM_CALLEE_TRASH_NOGC & ~(RBM_RDI | RBM_RSI);
+ break;
+#elif defined(_TARGET_ARMARCH_)
+ result = RBM_CALLEE_GCTRASH_WRITEBARRIER_BYREF;
+ break;
+#else
+ assert(!"unknown arch");
+#endif
+
+#if defined(_TARGET_XARCH_) || defined(_TARGET_ARM_)
+ case CORINFO_HELP_PROF_FCN_ENTER:
+ result = RBM_PROFILER_ENTER_TRASH;
+ break;
+
+ case CORINFO_HELP_PROF_FCN_LEAVE:
+ result = RBM_PROFILER_LEAVE_TRASH;
+ break;
+#if defined(_TARGET_XARCH_)
+ case CORINFO_HELP_PROF_FCN_TAILCALL:
+ result = RBM_PROFILER_TAILCALL_TRASH;
+ break;
+#endif // defined(_TARGET_XARCH_)
+#endif // defined(_TARGET_XARCH_) || defined(_TARGET_ARM_)
+
+#if defined(_TARGET_ARMARCH_)
+ case CORINFO_HELP_ASSIGN_REF:
+ case CORINFO_HELP_CHECKED_ASSIGN_REF:
+ result = RBM_CALLEE_GCTRASH_WRITEBARRIER;
+ break;
+#endif // defined(_TARGET_ARMARCH_)
+
+#if defined(_TARGET_X86_)
+ case CORINFO_HELP_INIT_PINVOKE_FRAME:
+ result = RBM_INIT_PINVOKE_FRAME_TRASH;
+ break;
+#endif // defined(_TARGET_X86_)
+
+ default:
+ result = RBM_CALLEE_TRASH_NOGC;
+ break;
+ }
+
+ // compHelperCallKillSet returns a superset of the registers which values are not guranteed to be the same
+ // after the call, if a register loses its GC or byref it has to be in the compHelperCallKillSet set as well.
+ assert((result & emitComp->compHelperCallKillSet(helper)) == result);
+
+ return result;
+}
diff --git a/src/jit/emit.h b/src/jit/emit.h
index 7d6e43f90f..876dc085fc 100644
--- a/src/jit/emit.h
+++ b/src/jit/emit.h
@@ -1927,6 +1927,9 @@ public:
regMaskTP emitGetGCRegsSavedOrModified(CORINFO_METHOD_HANDLE methHnd);
+ // Gets a register mask that represent the kill set for a NoGC helper call.
+ regMaskTP emitGetGCRegsKilledByNoGCCall(CorInfoHelpFunc helper);
+
#if EMIT_TRACK_STACK_DEPTH
unsigned emitCntStackDepth; // 0 in prolog/epilog, One DWORD elsewhere
unsigned emitMaxStackDepth; // actual computed max. stack depth