siVarLoc* varLoc);
void genSetScopeInfo();
+#ifdef USING_SCOPE_INFO
+ void genSetScopeInfoUsingsiScope();
-protected:
/*
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
const char* siStackVarName(size_t offs, size_t size, unsigned reg, unsigned stkOffs);
#endif // LATE_DISASM
-public:
/*
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
void psiEndPrologScope(psiScope* scope);
void psSetScopeOffset(psiScope* newScope, LclVarDsc* lclVarDsc1);
+#endif // USING_SCOPE_INFO
-/*****************************************************************************
- * TrnslLocalVarInfo
- *
- * This struct holds the LocalVarInfo in terms of the generated native code
- * after a call to genSetScopeInfo()
- */
+ /*****************************************************************************
+ * TrnslLocalVarInfo
+ *
+ * This struct holds the LocalVarInfo in terms of the generated native code
+ * after a call to genSetScopeInfo()
+ */
+protected:
#ifdef DEBUG
struct TrnslLocalVarInfo
#ifdef _TARGET_ARM_
compiler->unwindAllocStack(frameSize);
-
+#ifdef USING_SCOPE_INFO
if (!doubleAlignOrFramePointerUsed())
{
psiAdjustStackLevel(frameSize);
}
+#endif // USING_SCOPE_INFO
#endif // _TARGET_ARM_
}
JITDUMP("\t\t\t\t\t\t\tV%02u becoming live\n", varNum);
}
}
-
+#ifdef USING_SCOPE_INFO
codeGen->siUpdate();
+#endif // USING_SCOPE_INFO
}
// Need an explicit instantiation.
assert(varDsc->lvSize() >= baseOffset + (unsigned)size);
}
#endif // !UNIX_AMD64_ABI
-
+#ifdef USING_SCOPE_INFO
if (regArgTab[argNum].slot == 1)
{
psiMoveToStack(varNum);
}
+#endif // USING_SCOPE_INFO
}
/* mark the argument as processed */
regArgMaskLive &= ~genRegMask(varDscSrc->lvArgReg);
regArgMaskLive &= ~genRegMask(varDscDest->lvArgReg);
-
+#ifdef USING_SCOPE_INFO
psiMoveToReg(varNumSrc);
psiMoveToReg(varNumDest);
+#endif // USING_SCOPE_INFO
}
else
#endif // _TARGET_XARCH_
regSet.verifyRegUsed(xtraReg);
*pXtraRegClobbered = true;
-
+#ifdef USING_SCOPE_INFO
psiMoveToReg(varNumDest, xtraReg);
-
+#endif // USING_SCOPE_INFO
/* start moving everything to its right place */
while (srcReg != begReg)
getEmitter()->emitIns_R_R(insCopy, size, destRegNum, xtraReg);
regSet.verifyRegUsed(destRegNum);
-
+#ifdef USING_SCOPE_INFO
psiMoveToReg(varNumSrc);
-
+#endif // USING_SCOPE_INFO
/* mark the beginning register as processed */
regArgTab[srcReg].processed = true;
#endif
getEmitter()->emitIns_R_R(ins_Copy(destMemType), size, destRegNum, regNum);
-
+#ifdef USING_SCOPE_INFO
psiMoveToReg(varNum);
+#endif // USING_SCOPE_INFO
}
/* mark the argument as processed */
getEmitter()->emitIns_R_S(ins_Load(type), emitTypeSize(type), regNum, varNum, 0);
regSet.verifyRegUsed(regNum);
-
+#ifdef USING_SCOPE_INFO
psiMoveToReg(varNum);
+#endif // USING_SCOPE_INFO
}
}
{
inst_RV(INS_push, reg, TYP_REF);
compiler->unwindPush(reg);
-
+#ifdef USING_SCOPE_INFO
if (!doubleAlignOrFramePointerUsed())
{
psiAdjustStackLevel(REGSIZE_BYTES);
}
-
+#endif // USING_SCOPE_INFO
rsPushRegs &= ~regBit;
}
}
if (delta == 0)
{
getEmitter()->emitIns_R_R(INS_mov, EA_PTRSIZE, REG_FPBASE, REG_SPBASE);
+#ifdef USING_SCOPE_INFO
psiMoveESPtoEBP();
+#endif // USING_SCOPE_INFO
}
else
{
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
{
inst_RV(INS_push, REG_FPBASE, TYP_REF);
compiler->unwindPush(REG_FPBASE);
+#ifdef USING_SCOPE_INFO
psiAdjustStackLevel(REGSIZE_BYTES);
-
+#endif // USING_SCOPE_INFO
#ifndef _TARGET_AMD64_ // On AMD64, establish the frame pointer after the "sub rsp"
genEstablishFramePointer(0, /*reportUnwindData*/ true);
#endif // !_TARGET_AMD64_
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);
}
noway_assert(compiler->opts.compScopeInfo && (compiler->info.compVarScopesCount > 0));
- noway_assert(psiOpenScopeList.scNext == nullptr);
-
- unsigned i;
- unsigned scopeCnt = siScopeCnt + psiScopeCnt;
- compiler->eeSetLVcount(scopeCnt);
+ unsigned varsHomeCount = 0;
+#ifdef USING_SCOPE_INFO
+ varsHomeCount = siScopeCnt + psiScopeCnt;
+#endif // USING_SCOPE_INFO
+ compiler->eeSetLVcount(varsHomeCount);
#ifdef DEBUG
- genTrnslLocalVarCount = scopeCnt;
- if (scopeCnt)
+ genTrnslLocalVarCount = varsHomeCount;
+ if (varsHomeCount)
{
- genTrnslLocalVarInfo = new (compiler, CMK_DebugOnly) TrnslLocalVarInfo[scopeCnt];
+ genTrnslLocalVarInfo = new (compiler, CMK_DebugOnly) TrnslLocalVarInfo[varsHomeCount];
}
#endif
+#ifdef USING_SCOPE_INFO
+ genSetScopeInfoUsingsiScope();
+#endif // USING_SCOPE_INFO
+
+ compiler->eeSetLVdone();
+}
+
+#ifdef USING_SCOPE_INFO
+void CodeGen::genSetScopeInfoUsingsiScope()
+{
+ noway_assert(psiOpenScopeList.scNext == nullptr);
+
// Record the scopes found for the parameters over the prolog.
// The prolog needs to be treated differently as a variable may not
// have the same info in the prolog block as is given by compiler->lvaTable.
// eg. A register parameter is actually on the stack, before it is loaded to reg.
CodeGen::psiScope* scopeP;
+ unsigned i;
for (i = 0, scopeP = psiScopeList.scNext; i < psiScopeCnt; i++, scopeP = scopeP->scNext)
{
genSetScopeInfo(psiScopeCnt + i, startOffs, endOffs - startOffs, scopeL->scVarNum, scopeL->scLVnum,
scopeL->scAvailable, &varLoc);
}
-
- compiler->eeSetLVdone();
}
+#endif // USING_SCOPE_INFO
//------------------------------------------------------------------------
// genSetScopeInfo: Record scope information for debug info
#include "jitgcinfo.h"
#include "treelifeupdater.h"
+// Disable this flag to avoid using psiScope/siScope info to report reporting
+// variables' home location during the method/prolog code.
+#if 1
+#define USING_SCOPE_INFO
+#endif // USING_SCOPE_INFO
+
// Forward reference types
class CodeGenInterface;
bool m_cgFullPtrRegMap;
public:
+#ifdef USING_SCOPE_INFO
virtual void siUpdate() = 0;
+#endif // USING_SCOPE_INFO
/* These are the different addressing modes used to access a local var.
* The JIT has to report the location of the locals back to the EE
// iterated.
void CodeGen::genInitialize()
{
+#ifdef USING_SCOPE_INFO
// Initialize the line# tracking logic
-
if (compiler->opts.compScopeInfo)
{
siInit();
}
+#endif // USING_SCOPE_INFO
// The current implementation of switch tables requires the first block to have a label so it
// can generate offsets to the switch label targets.
/* Tell everyone which basic block we're working on */
compiler->compCurBB = block;
-
+#ifdef USING_SCOPE_INFO
siBeginBlock(block);
-
+#endif // USING_SCOPE_INFO
// BBF_INTERNAL blocks don't correspond to any single IL instruction.
if (compiler->opts.compDbgInfo && (block->bbFlags & BBF_INTERNAL) &&
!compiler->fgBBisScratch(block)) // If the block is the distinguished first scratch block, then no need to
// This can lead to problems when debugging the generated code. To prevent these issues, make sure
// we've generated code for the last IL offset we saw in the block.
genEnsureCodeEmitted(currentILOffset);
-
+#ifdef USING_SCOPE_INFO
if (compiler->opts.compScopeInfo && (compiler->info.compVarScopesCount > 0))
{
siEndBlock(block);
siCloseAllOpenScopes();
}
}
+#endif // USING_SCOPE_INFO
SubtractStackLevel(savedStkLvl);
}
compiler->unwindAllocStack(frameSize);
-
+#ifdef USING_SCOPE_INFO
if (!doubleAlignOrFramePointerUsed())
{
psiAdjustStackLevel(frameSize);
}
+#endif // USING_SCOPE_INFO
}
//------------------------------------------------------------------------
}
//------------------------------------------------------------------------
-// siVarLoc: Non-empty constructor of siVarLoc struct
-// Arguments:
-// varDsc - a "LclVarDsc *" to the variable it is desired to build the "siVarLoc".
-// baseReg - a "regNumber" use as a base for the offset.
-// offset - a signed amount of bytes distance from "baseReg" for the position of the variable.
-// isFramePointerUsed - a boolean variable
-//
-// Notes:
-// Called for every psiScope in "psiScopeList" codegen.h
-CodeGenInterface::siVarLoc::siVarLoc(const LclVarDsc* varDsc, regNumber baseReg, int offset, bool isFramePointerUsed)
-{
- var_types type = genActualType(varDsc->TypeGet());
-
- if (varDsc->lvIsInReg())
- {
- siFillRegisterVarLoc(varDsc, type, baseReg, offset, isFramePointerUsed);
- }
- else
- {
- siFillStackVarLoc(varDsc, type, baseReg, offset, isFramePointerUsed);
- }
-}
-
-//------------------------------------------------------------------------
// Equals: Compares first reference and then values of the structures.
//
// Arguments:
}
//------------------------------------------------------------------------
-// getSiVarLoc: Creates a "CodegenInterface::siVarLoc" instance from using the properties
-// of the "psiScope" instance.
-//
-// Notes:
-// Called for every psiScope in "psiScopeList" codegen.h
-CodeGenInterface::siVarLoc CodeGen::psiScope::getSiVarLoc() const
-{
- CodeGenInterface::siVarLoc varLoc;
-
- if (scRegister)
- {
- varLoc.vlType = VLT_REG;
- varLoc.vlReg.vlrReg = (regNumber)u1.scRegNum;
- }
- else
- {
- varLoc.vlType = VLT_STK;
- varLoc.vlStk.vlsBaseReg = (regNumber)u2.scBaseReg;
- varLoc.vlStk.vlsOffset = u2.scOffset;
- }
-
- return varLoc;
-}
-
-//------------------------------------------------------------------------
-// getSiVarLoc: Returns a "siVarLoc" instance representing the place where the variable
-// is given its description, "baseReg", and "offset" (if needed).
-//
-// Arguments:
-// varDsc - a "LclVarDsc *" to the variable it is desired to build the "siVarLoc".
-// scope - a "siScope" Scope info of the variable.
-//
-// Return Value:
-// A "siVarLoc" filled with the correct case struct fields for the variable, which could live
-// in a register, an stack position, or a combination of both.
-//
-// Notes:
-// Called for each siScope in siScopeList when "genSetScopeInfo".
-CodeGenInterface::siVarLoc CodeGen::getSiVarLoc(const LclVarDsc* varDsc, const siScope* scope) const
-{
- // For stack vars, find the base register, and offset
-
- regNumber baseReg;
- signed offset = varDsc->lvStkOffs;
-
- if (!varDsc->lvFramePointerBased)
- {
- baseReg = REG_SPBASE;
- offset += scope->scStackLevel;
- }
- else
- {
- baseReg = REG_FPBASE;
- }
-
- return CodeGenInterface::siVarLoc(varDsc, baseReg, offset, isFramePointerUsed());
-}
-
-//------------------------------------------------------------------------
// siFillStackVarLoc: Fill "siVarLoc" struct indicating the stack position of the variable
// using "LclVarDsc" and "baseReg"/"offset".
//
}
}
+//------------------------------------------------------------------------
+// siVarLoc: Non-empty constructor of siVarLoc struct
+// Arguments:
+// varDsc - a "LclVarDsc *" to the variable it is desired to build the "siVarLoc".
+// baseReg - a "regNumber" use as a base for the offset.
+// offset - a signed amount of bytes distance from "baseReg" for the position of the variable.
+// isFramePointerUsed - a boolean variable
+//
+// Notes:
+// Called for every psiScope in "psiScopeList" codegen.h
+CodeGenInterface::siVarLoc::siVarLoc(const LclVarDsc* varDsc, regNumber baseReg, int offset, bool isFramePointerUsed)
+{
+ var_types type = genActualType(varDsc->TypeGet());
+
+ if (varDsc->lvIsInReg())
+ {
+ siFillRegisterVarLoc(varDsc, type, baseReg, offset, isFramePointerUsed);
+ }
+ else
+ {
+ siFillStackVarLoc(varDsc, type, baseReg, offset, isFramePointerUsed);
+ }
+}
+
+#ifdef USING_SCOPE_INFO
+//------------------------------------------------------------------------
+// getSiVarLoc: Returns a "siVarLoc" instance representing the place where the variable
+// is given its description, "baseReg", and "offset" (if needed).
+//
+// Arguments:
+// varDsc - a "LclVarDsc *" to the variable it is desired to build the "siVarLoc".
+// scope - a "siScope" Scope info of the variable.
+//
+// Return Value:
+// A "siVarLoc" filled with the correct case struct fields for the variable, which could live
+// in a register, an stack position, or a combination of both.
+//
+// Notes:
+// Called for each siScope in siScopeList when "genSetScopeInfo".
+CodeGenInterface::siVarLoc CodeGen::getSiVarLoc(const LclVarDsc* varDsc, const siScope* scope) const
+{
+ // For stack vars, find the base register, and offset
+
+ regNumber baseReg;
+ signed offset = varDsc->lvStkOffs;
+
+ if (!varDsc->lvFramePointerBased)
+ {
+ baseReg = REG_SPBASE;
+ offset += scope->scStackLevel;
+ }
+ else
+ {
+ baseReg = REG_FPBASE;
+ }
+
+ return CodeGenInterface::siVarLoc(varDsc, baseReg, offset, isFramePointerUsed());
+}
+
+//------------------------------------------------------------------------
+// getSiVarLoc: Creates a "CodegenInterface::siVarLoc" instance from using the properties
+// of the "psiScope" instance.
+//
+// Notes:
+// Called for every psiScope in "psiScopeList" codegen.h
+CodeGenInterface::siVarLoc CodeGen::psiScope::getSiVarLoc() const
+{
+ CodeGenInterface::siVarLoc varLoc;
+
+ if (scRegister)
+ {
+ varLoc.vlType = VLT_REG;
+ varLoc.vlReg.vlrReg = (regNumber)u1.scRegNum;
+ }
+ else
+ {
+ varLoc.vlType = VLT_STK;
+ varLoc.vlStk.vlsBaseReg = (regNumber)u2.scBaseReg;
+ varLoc.vlStk.vlsOffset = u2.scOffset;
+ }
+
+ return varLoc;
+}
+
/*============================================================================
*
* Implementation for ScopeInfo
psiEndPrologScope(scope);
}
}
+#endif // USING_SCOPE_INFO
}
#endif // DEBUG
}
-
+#ifdef USING_SCOPE_INFO
compiler->codeGen->siUpdate();
+#endif // USING_SCOPE_INFO
}
}