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++;
+ }
}
}
}
}
// 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();
}
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);
}
}
}
}
//------------------------------------------------------------------------
-// getLiveRangesForVar: Return the "VariableLiveRange" that correspond to
+// getLiveRangesForVarForBody: Return the "VariableLiveRange" that correspond to
// the given "varNum".
//
// Arguments:
// 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
}
//------------------------------------------------------------------------
+// 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.
//
{
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();
+ }
}
}
}
// 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());
}
for (unsigned int varNum = 0; varNum < m_LiveArgsCount; varNum++)
{
- VariableLiveDescriptor* varLiveDsc = m_vlrLiveDsc + varNum;
+ VariableLiveDescriptor* varLiveDsc = m_vlrLiveDscForProlog + varNum;
if (varLiveDsc->hasVariableLiveRangeOpen())
{
{
VariableLiveDescriptor* varLiveDsc = m_vlrLiveDsc + varNum;
- if (varLiveDsc->hasVarLiverRangesFromLastBlockToDump())
+ if (varLiveDsc->hasVarLiveRangesFromLastBlockToDump())
{
hasDumpedHistory = true;
printf("IL Var Num %d:\n", m_Compiler->compMap2ILvarNum(varNum));
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
};
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.
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