Skip to content

Commit

Permalink
Make sure variable live range for prolog is reported first
Browse files Browse the repository at this point in the history
  • Loading branch information
cshung authored and franksinankaya committed May 30, 2019
1 parent a40e5a3 commit eccbb45
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 29 deletions.
93 changes: 66 additions & 27 deletions src/jit/codegencommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10672,26 +10672,37 @@ void CodeGen::genSetScopeInfoUsingVariableRanges()

if (compiler->compMap2ILvarNum(varNum) != (unsigned int)ICorDebugInfo::UNKNOWN_ILNUM)
{
VariableLiveKeeper::LiveRangeList* liveRanges = varLiveKeeper->getLiveRangesForVar(varNum);
VariableLiveKeeper::LiveRangeList* liveRanges = nullptr;

for (VariableLiveKeeper::VariableLiveRange& liveRange : *liveRanges)
for (int rangeIndex = 0; rangeIndex < 2; rangeIndex++)
{
UNATIVE_OFFSET startOffs = liveRange.m_StartEmitLocation.CodeOffset(getEmitter());
UNATIVE_OFFSET endOffs = liveRange.m_EndEmitLocation.CodeOffset(getEmitter());

if (varDsc->lvIsParam && (startOffs == endOffs))
if (rangeIndex == 0)
{
// 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++;
liveRanges = varLiveKeeper->getLiveRangesForVarForProlog(varNum);
}
else
{
liveRanges = varLiveKeeper->getLiveRangesForVarForBody(varNum);
}
for (VariableLiveKeeper::VariableLiveRange& liveRange : *liveRanges)
{
UNATIVE_OFFSET startOffs = liveRange.m_StartEmitLocation.CodeOffset(getEmitter());
UNATIVE_OFFSET endOffs = liveRange.m_EndEmitLocation.CodeOffset(getEmitter());

genSetScopeInfo(liveRangeIndex, startOffs, endOffs - startOffs, varNum,
varNum /* I dont know what is the which in eeGetLvInfo */, true,
&liveRange.m_VarLocation);
liveRangeIndex++;
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++;
}
}
}
}
Expand Down Expand Up @@ -11996,7 +12007,7 @@ bool CodeGenInterface::VariableLiveKeeper::VariableLiveDescriptor::hasVarLiveRan
}

// Returns true if a live range for this variable has been recorded from last call to EndBlock
bool CodeGenInterface::VariableLiveKeeper::VariableLiveDescriptor::hasVarLiverRangesFromLastBlockToDump() const
bool CodeGenInterface::VariableLiveKeeper::VariableLiveDescriptor::hasVarLiveRangesFromLastBlockToDump() const
{
return m_VariableLifeBarrier->hasLiveRangesToDump();
}
Expand Down Expand Up @@ -12050,11 +12061,13 @@ CodeGenInterface::VariableLiveKeeper::VariableLiveKeeper(unsigned int totalLoca
if (m_LiveDscCount > 0)
{
// Allocate memory for "m_vlrLiveDsc" and initialize each "VariableLiveDescriptor"
m_vlrLiveDsc = allocator.allocate<VariableLiveDescriptor>(m_LiveDscCount);
m_vlrLiveDsc = allocator.allocate<VariableLiveDescriptor>(m_LiveDscCount);
m_vlrLiveDscForProlog = allocator.allocate<VariableLiveDescriptor>(m_LiveDscCount);

for (unsigned int varNum = 0; varNum < m_LiveDscCount; varNum++)
{
new (m_vlrLiveDsc + varNum, jitstd::placement_t()) VariableLiveDescriptor(allocator);
new (m_vlrLiveDscForProlog + varNum, jitstd::placement_t()) VariableLiveDescriptor(allocator);
}
}
}
Expand Down Expand Up @@ -12297,7 +12310,7 @@ void CodeGenInterface::VariableLiveKeeper::siEndAllVariableLiveRange()
}

//------------------------------------------------------------------------
// getLiveRangesForVar: Return the "VariableLiveRange" that correspond to
// getLiveRangesForVarForBody: Return the "VariableLiveRange" that correspond to
// the given "varNum".
//
// Arguments:
Expand All @@ -12307,10 +12320,10 @@ void CodeGenInterface::VariableLiveKeeper::siEndAllVariableLiveRange()
// Return Value:
// A const pointer to the list of variable locations reported for the variable.
//
// Assumtions:
// Assumptions:
// This variable should be an argument, a special argument or an IL local
// variable.
CodeGenInterface::VariableLiveKeeper::LiveRangeList* CodeGenInterface::VariableLiveKeeper::getLiveRangesForVar(
CodeGenInterface::VariableLiveKeeper::LiveRangeList* CodeGenInterface::VariableLiveKeeper::getLiveRangesForVarForBody(
unsigned int varNum) const
{
// There should be at least one variable for which its liveness is tracked
Expand All @@ -12319,6 +12332,29 @@ CodeGenInterface::VariableLiveKeeper::LiveRangeList* CodeGenInterface::VariableL
return m_vlrLiveDsc[varNum].getLiveRanges();
}

//------------------------------------------------------------------------
// getLiveRangesForVarForProlog: Return the "VariableLiveRange" that correspond to
// the given "varNum".
//
// Arguments:
// varNum - the index of the variable in m_vlrLiveDsc, which is the same as
// in lvaTable.
//
// Return Value:
// A const pointer to the list of variable locations reported for the variable.
//
// Assumptions:
// This variable should be an argument, a special argument or an IL local
// variable.
CodeGenInterface::VariableLiveKeeper::LiveRangeList* CodeGenInterface::VariableLiveKeeper::getLiveRangesForVarForProlog(
unsigned int varNum) const
{
// There should be at least one variable for which its liveness is tracked
noway_assert(varNum < m_LiveDscCount);

return m_vlrLiveDscForProlog[varNum].getLiveRanges();
}

//------------------------------------------------------------------------
// getLiveRangesCount: Returns the count of variable locations reported for the tracked
// variables, which are arguments, special arguments, and local IL variables.
Expand All @@ -12338,11 +12374,14 @@ size_t CodeGenInterface::VariableLiveKeeper::getLiveRangesCount() const
{
for (unsigned int varNum = 0; varNum < m_LiveDscCount; varNum++)
{
VariableLiveDescriptor* varLiveDsc = m_vlrLiveDsc + varNum;

if (m_Compiler->compMap2ILvarNum(varNum) != (unsigned int)ICorDebugInfo::UNKNOWN_ILNUM)
for (int i = 0; i < 2; i++)
{
liveRangesCount += varLiveDsc->getLiveRanges()->size();
VariableLiveDescriptor* varLiveDsc = (i == 0 ? m_vlrLiveDscForProlog : m_vlrLiveDsc) + varNum;

if (m_Compiler->compMap2ILvarNum(varNum) != (unsigned int)ICorDebugInfo::UNKNOWN_ILNUM)
{
liveRangesCount += varLiveDsc->getLiveRanges()->size();
}
}
}
}
Expand All @@ -12368,7 +12407,7 @@ void CodeGenInterface::VariableLiveKeeper::psiStartVariableLiveRange(CodeGenInte
// are arguments and special arguments.
noway_assert(varNum < m_LiveArgsCount);

VariableLiveDescriptor* varLiveDsc = &m_vlrLiveDsc[varNum];
VariableLiveDescriptor* varLiveDsc = &m_vlrLiveDscForProlog[varNum];
varLiveDsc->startLiveRangeFromEmitter(varLocation, m_Compiler->getEmitter());
}

Expand All @@ -12385,7 +12424,7 @@ void CodeGenInterface::VariableLiveKeeper::psiClosePrologVariableRanges()

for (unsigned int varNum = 0; varNum < m_LiveArgsCount; varNum++)
{
VariableLiveDescriptor* varLiveDsc = m_vlrLiveDsc + varNum;
VariableLiveDescriptor* varLiveDsc = m_vlrLiveDscForProlog + varNum;

if (varLiveDsc->hasVariableLiveRangeOpen())
{
Expand Down Expand Up @@ -12414,7 +12453,7 @@ void CodeGenInterface::VariableLiveKeeper::dumpBlockVariableLiveRanges(const Bas
{
VariableLiveDescriptor* varLiveDsc = m_vlrLiveDsc + varNum;

if (varLiveDsc->hasVarLiverRangesFromLastBlockToDump())
if (varLiveDsc->hasVarLiveRangesFromLastBlockToDump())
{
hasDumpedHistory = true;
printf("IL Var Num %d:\n", m_Compiler->compMap2ILvarNum(varNum));
Expand Down
8 changes: 6 additions & 2 deletions src/jit/codegeninterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,7 @@ class CodeGenInterface
void dumpAllRegisterLiveRangesForBlock(emitter* emit, const CodeGenInterface* codeGen) const;
void dumpRegisterLiveRangesForBlockBeforeCodeGenerated(const CodeGenInterface* codeGen) const;
bool hasVarLiveRangesToDump() const;
bool hasVarLiverRangesFromLastBlockToDump() const;
bool hasVarLiveRangesFromLastBlockToDump() const;
void endBlockLiveRanges();
#endif // DEBUG
};
Expand All @@ -719,6 +719,9 @@ class CodeGenInterface
VariableLiveDescriptor* m_vlrLiveDsc; // Array of descriptors that manage VariableLiveRanges.
// Its indices correspond to lvaTable indexes (or lvSlotNum).

VariableLiveDescriptor* m_vlrLiveDscForProlog; // Array of descriptors that manage VariableLiveRanges.
// Its indices correspond to lvaTable indexes (or lvSlotNum).

bool m_LastBasicBlockHasBeenEmited; // When true no more siEndVariableLiveRange is considered.
// No update/start happens when code has been generated.

Expand All @@ -737,7 +740,8 @@ class CodeGenInterface
void siEndAllVariableLiveRange(VARSET_VALARG_TP varsToClose);
void siEndAllVariableLiveRange();

LiveRangeList* getLiveRangesForVar(unsigned int varNum) const;
LiveRangeList* getLiveRangesForVarForBody(unsigned int varNum) const;
LiveRangeList* getLiveRangesForVarForProlog(unsigned int varNum) const;
size_t getLiveRangesCount() const;

// For parameters locations on prolog
Expand Down

0 comments on commit eccbb45

Please sign in to comment.