summaryrefslogtreecommitdiff
path: root/src/jit/codegencommon.cpp
diff options
context:
space:
mode:
authorBrian Bohe <brianbohe@gmail.com>2019-03-29 16:38:53 -0700
committerBruce Forstall <brucefo@microsoft.com>2019-03-29 16:38:53 -0700
commit493023e6e1bc03ec04ee4aa9f390e37dc4d0906e (patch)
treea7e0994c783217f0bcbc0fe23a2bbf5517a2b79d /src/jit/codegencommon.cpp
parent1df87c785e0e43392abf4bcba56e2bf4d9249fd4 (diff)
downloadcoreclr-493023e6e1bc03ec04ee4aa9f390e37dc4d0906e.tar.gz
coreclr-493023e6e1bc03ec04ee4aa9f390e37dc4d0906e.tar.bz2
coreclr-493023e6e1bc03ec04ee4aa9f390e37dc4d0906e.zip
A new way of tracking variables (#23373)
* Defining VariableLiveRange class * Adding some typedefs to avoid rewriting * Defining VariableLiveDescriptor class * Initializing VariableLiveRange structures before BasicBlock code is being generated * Getting a siVarLoc for variable homes from a given LclVarDsc and stack level * Defining VariableLiveKeeper class * Reporting VariableLiveRanges on changes of variable livenesss or variable homes * Adding USING_VARIABLE_LIVE_RANGE flag to enable disable VariableLiveRange * Send VariableLiveRanges to debugger * Reporting variable homes on prolog * Wrong argument * Miss to change variable homes count before sending them to debugger * Adding dumper of VariableLiveRanges for each blocks and end of code generation * Close all open VaribleLiveRanges on last BasicBlock * Changing order of properties initialization on VariableLiveRange constructor * Type error on assignation * Rephrasing comments, moving dumps and fixing typos * Changing const VARSET_TP* for VARSET_VALARG_TP on args * Variable home was variable location in VariableLiveRange context * Rephrase and rename of VariableLiveKeeper properties * Missing some renames * Adding const where BasicBlock should not be modified * siBeginBlock and siInit have support for debug code for VariableLiveRange and siScope info * Adding USING_VARIABLE_LIVE_RANGE flags on methods definition. * Variable home -> variable location * Renaming and rephrasing names and uses of VariableLiveRange * Moving LiveRangeDumper ctor to class declation * Removing destructors Signed-off-by: Brian Bohe <brianbohe@gmail.com> * Removing blank spaces and reordering functions inside class definition Signed-off-by: Brian Bohe <brianbohe@gmail.com> * Miss to increment the index after refactoring * Logic for keeping the last BasicBlock end IL offset is shared between siScope and VariableLiverange for debug code * Missing to print on debug the last block VariableLiveRanges * Avoid updating VariableLiveRange when unspilling and dying at the same assembly instruction * Rephrasing #ifs and #ifdefs * Calling VariableLiveKeeper in one line * Avoid copying siVarLoc on genSetScopeInfo * Removing unused args from eeSetLVinfo * Changing VariableLiveKeeper ctor * Typo Signed-off-by: Brian Bohe <brianbohe@gmail.com> * Updating VariableLiveDescriptor ctor Signed-off-by: Brian Bohe <brianbohe@gmail.com> * Error on first argument Signed-off-by: Brian Bohe <brianbohe@gmail.com> * Changing reference for pointer Signed-off-by: Brian Bohe <brianbohe@gmail.com> * Renaming assembly offset -> native offset * removing unnecesary comments and asserts Signed-off-by: Brian Bohe <brianbohe@gmail.com> * Update VariableLiveRange dump message Signed-off-by: Brian Bohe <brianbohe@gmail.com> * Moving VariableLiveRanges classes inside VariableLiveKeeper * Wrong flag name * Adding documentation about how we track variables for debug info Signed-off-by: Brian Bohe <brianbohe@gmail.com> * Adding opened issues to doc file Signed-off-by: Brian Bohe <brianbohe@gmail.com> * Changing dump tittle Signed-off-by: Brian Bohe <brianbohe@gmail.com> * Renaming VariableLiveKeeper property Signed-off-by: Brian Bohe <brianbohe@gmail.com> * Update documentation Signed-off-by: Brian Bohe <brianbohe@gmail.com> * Updating comments on flags Signed-off-by: Brian Bohe <brianbohe@gmail.com> * Setting Scope Info as default way of tracking variables for debug info Signed-off-by: Brian Bohe <brianbohe@gmail.com>
Diffstat (limited to 'src/jit/codegencommon.cpp')
-rw-r--r--src/jit/codegencommon.cpp114
1 files changed, 98 insertions, 16 deletions
diff --git a/src/jit/codegencommon.cpp b/src/jit/codegencommon.cpp
index e54342a1d5..781f0fc549 100644
--- a/src/jit/codegencommon.cpp
+++ b/src/jit/codegencommon.cpp
@@ -694,6 +694,11 @@ void Compiler::compChangeLife(VARSET_VALARG_TP newLife)
VarSetOps::RemoveElemD(this, codeGen->gcInfo.gcVarPtrSetCur, deadVarIndex);
JITDUMP("\t\t\t\t\t\t\tV%02u becoming dead\n", varNum);
}
+
+#ifdef USING_VARIABLE_LIVE_RANGE
+ VariableLiveKeeper* varLiveKeeper = getVariableLiveKeeper();
+ varLiveKeeper->siEndVariableLiveRange(varNum);
+#endif // USING_VARIABLE_LIVE_RANGE
}
VarSetOps::Iter bornIter(this, bornSet);
@@ -731,7 +736,13 @@ void Compiler::compChangeLife(VARSET_VALARG_TP newLife)
VarSetOps::AddElemD(this, codeGen->gcInfo.gcVarPtrSetCur, bornVarIndex);
JITDUMP("\t\t\t\t\t\t\tV%02u becoming live\n", varNum);
}
+
+#ifdef USING_VARIABLE_LIVE_RANGE
+ VariableLiveKeeper* varLiveKeeper = getVariableLiveKeeper();
+ varLiveKeeper->siStartVariableLiveRange(varDsc, varNum);
+#endif // USING_VARIABLE_LIVE_RANGE
}
+
#ifdef USING_SCOPE_INFO
codeGen->siUpdate();
#endif // USING_SCOPE_INFO
@@ -2284,6 +2295,13 @@ void CodeGen::genGenerateCode(void** codePtr, ULONG* nativeSizeOfCode)
genSetScopeInfo();
+#if defined(USING_VARIABLE_LIVE_RANGE) && defined(DEBUG)
+ if (compiler->verbose)
+ {
+ compiler->getVariableLiveKeeper()->dumpLvaVariableLiveRanges();
+ }
+#endif // defined(USING_VARIABLE_LIVE_RANGE) && defined(DEBUG)
+
#ifdef LATE_DISASM
unsigned finalHotCodeSize;
unsigned finalColdCodeSize;
@@ -7631,13 +7649,12 @@ void CodeGen::genFnProlog()
printf("\n__prolog:\n");
}
#endif
-#ifdef USING_SCOPE_INFO
+
if (compiler->opts.compScopeInfo && (compiler->info.compVarScopesCount > 0))
{
// Create new scopes for the method-parameters for the prolog-block.
psiBegProlog();
}
-#endif // USING_SCOPE_INFO
#ifdef DEBUG
@@ -8284,12 +8301,11 @@ void CodeGen::genFnProlog()
genPrologPadForReJit();
getEmitter()->emitMarkPrologEnd();
}
-#ifdef USING_SCOPE_INFO
if (compiler->opts.compScopeInfo && (compiler->info.compVarScopesCount > 0))
{
psiEndProlog();
}
-#endif // USING_SCOPE_INFO
+
if (hasGCRef)
{
getEmitter()->emitSetFrameRangeGCRs(GCrefLo, GCrefHi);
@@ -10478,7 +10494,22 @@ void CodeGen::genSetScopeInfo()
}
#endif
- if (compiler->info.compVarScopesCount == 0)
+ unsigned varsLocationsCount = 0;
+
+#ifdef USING_SCOPE_INFO
+ if (compiler->info.compVarScopesCount > 0)
+ {
+ varsLocationsCount = siScopeCnt + psiScopeCnt;
+ }
+#else // USING_SCOPE_INFO
+
+#ifdef USING_VARIABLE_LIVE_RANGE
+ varsLocationsCount = (unsigned int)compiler->getVariableLiveKeeper()->getLiveRangesCount();
+#endif // USING_VARIABLE_LIVE_RANGE
+
+#endif // USING_SCOPE_INFO
+
+ if (varsLocationsCount == 0)
{
compiler->eeSetLVcount(0);
compiler->eeSetLVdone();
@@ -10487,22 +10518,27 @@ void CodeGen::genSetScopeInfo()
noway_assert(compiler->opts.compScopeInfo && (compiler->info.compVarScopesCount > 0));
- unsigned varsHomeCount = 0;
-#ifdef USING_SCOPE_INFO
- varsHomeCount = siScopeCnt + psiScopeCnt;
-#endif // USING_SCOPE_INFO
- compiler->eeSetLVcount(varsHomeCount);
+ compiler->eeSetLVcount(varsLocationsCount);
#ifdef DEBUG
- genTrnslLocalVarCount = varsHomeCount;
- if (varsHomeCount)
+ genTrnslLocalVarCount = varsLocationsCount;
+ if (varsLocationsCount)
{
- genTrnslLocalVarInfo = new (compiler, CMK_DebugOnly) TrnslLocalVarInfo[varsHomeCount];
+ genTrnslLocalVarInfo = new (compiler, CMK_DebugOnly) TrnslLocalVarInfo[varsLocationsCount];
}
#endif
#ifdef USING_SCOPE_INFO
genSetScopeInfoUsingsiScope();
+#else // USING_SCOPE_INFO
+#ifdef USING_VARIABLE_LIVE_RANGE
+ // We can have one of both flags defined, both, or none. Specially if we need to compare both
+ // both results. But we cannot report both to the debugger, since there would be overlapping
+ // intervals, and may not indicate the same variable location.
+
+ genSetScopeInfoUsingVariableRanges();
+
+#endif // USING_VARIABLE_LIVE_RANGE
#endif // USING_SCOPE_INFO
compiler->eeSetLVdone();
@@ -10579,6 +10615,53 @@ void CodeGen::genSetScopeInfoUsingsiScope()
}
#endif // USING_SCOPE_INFO
+#ifdef USING_VARIABLE_LIVE_RANGE
+//------------------------------------------------------------------------
+// genSetScopeInfoUsingVariableRanges: Call "genSetScopeInfo" with the
+// "VariableLiveRanges" created for the arguments, special arguments and
+// IL local variables.
+//
+// Notes:
+// This function is called from "genSetScopeInfo" once the code is generated
+// and we want to send debug info to the debugger.
+//
+void CodeGen::genSetScopeInfoUsingVariableRanges()
+{
+ VariableLiveKeeper* varLiveKeeper = compiler->getVariableLiveKeeper();
+ unsigned int liveRangeIndex = 0;
+
+ for (unsigned int varNum = 0; varNum < compiler->info.compLocalsCount; varNum++)
+ {
+ LclVarDsc* varDsc = compiler->lvaGetDesc(varNum);
+
+ if (compiler->compMap2ILvarNum(varNum) != (unsigned int)ICorDebugInfo::UNKNOWN_ILNUM)
+ {
+ VariableLiveKeeper::LiveRangeList* liveRanges = varLiveKeeper->getLiveRangesForVar(varNum);
+
+ for (VariableLiveKeeper::VariableLiveRange& liveRange : *liveRanges)
+ {
+ UNATIVE_OFFSET startOffs = liveRange.m_StartEmitLocation.CodeOffset(getEmitter());
+ UNATIVE_OFFSET endOffs = liveRange.m_EndEmitLocation.CodeOffset(getEmitter());
+
+ if (varDsc->lvIsParam && (startOffs == endOffs))
+ {
+ // If the length is zero, it means that the prolog is empty. In that case,
+ // CodeGen::genSetScopeInfo will report the liveness of all arguments
+ // as spanning the first instruction in the method, so that they can
+ // at least be inspected on entry to the method.
+ endOffs++;
+ }
+
+ genSetScopeInfo(liveRangeIndex, startOffs, endOffs - startOffs, varNum,
+ varNum /* I dont know what is the which in eeGetLvInfo */, true,
+ &liveRange.m_VarLocation);
+ liveRangeIndex++;
+ }
+ }
+ }
+}
+#endif // USING_VARIABLE_LIVE_RANGE
+
//------------------------------------------------------------------------
// genSetScopeInfo: Record scope information for debug info
//
@@ -10612,7 +10695,6 @@ void CodeGen::genSetScopeInfo(unsigned which,
// so we don't need this code.
// Is this a varargs function?
-
if (compiler->info.compIsVarArgs && varNum != compiler->lvaVarargsHandleArg &&
varNum < compiler->info.compArgsCount && !compiler->lvaTable[varNum].lvIsRegArg)
{
@@ -10673,7 +10755,7 @@ void CodeGen::genSetScopeInfo(unsigned which,
#endif // DEBUG
- compiler->eeSetLVinfo(which, startOffs, length, ilVarNum, LVnum, name, avail, varLoc);
+ compiler->eeSetLVinfo(which, startOffs, length, ilVarNum, *varLoc);
}
/*****************************************************************************/
@@ -10728,7 +10810,7 @@ const char* CodeGen::siStackVarName(size_t offs, size_t size, unsigned reg, unsi
for (unsigned i = 0; i < genTrnslLocalVarCount; i++)
{
- if ((genTrnslLocalVarInfo[i].tlviVarLoc.vlIsOnStk((regNumber)reg, stkOffs)) &&
+ if ((genTrnslLocalVarInfo[i].tlviVarLoc.vlIsOnStack((regNumber)reg, stkOffs)) &&
(genTrnslLocalVarInfo[i].tlviAvailable == true) && (genTrnslLocalVarInfo[i].tlviStartPC <= offs + size) &&
(genTrnslLocalVarInfo[i].tlviStartPC + genTrnslLocalVarInfo[i].tlviLength > offs))
{