Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Importer forward substitution #98380

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/coreclr/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1964,6 +1964,11 @@ void Compiler::compInit(ArenaAllocator* pAlloc,

compUsesThrowHelper = false;

impLclValues = nullptr;
impLclVersions = nullptr;
impLclMapSize = 0;
impLclCurVer = 1;

m_preferredInitCctor = CORINFO_HELP_UNDEF;
}

Expand Down
10 changes: 10 additions & 0 deletions src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -4552,6 +4552,13 @@ class Compiler
Statement* impStmtList; // Statements for the BB being imported.
Statement* impLastStmt; // The last statement for the current BB.

//----------------- Importer forward sub ----------------------

GenTree** impLclValues; // Current values stored in locals.
unsigned* impLclVersions; // Versions current values belong to.
unsigned impLclMapSize; // Current local map size.
unsigned impLclCurVer; // Current local map version.

public:
static const unsigned CHECK_SPILL_ALL = static_cast<unsigned>(-1);
static const unsigned CHECK_SPILL_NONE = static_cast<unsigned>(-2);
Expand Down Expand Up @@ -4583,6 +4590,9 @@ class Compiler
BasicBlock* block = nullptr);
GenTree* impStoreStructPtr(GenTree* destAddr, GenTree* value, unsigned curLevel);

GenTree* impGetLclVal(GenTree* val);
void impSetLclVal(unsigned lclNum, GenTree* val);

GenTree* impGetNodeAddr(GenTree* val, unsigned curLevel, GenTreeFlags* pDerefFlags);

var_types impNormStructType(CORINFO_CLASS_HANDLE structHnd, CorInfoType* simdBaseJitType = nullptr);
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/compmemkind.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ CompMemKindMacro(AssertionProp)
CompMemKindMacro(ASTNode)
CompMemKindMacro(InstDesc)
CompMemKindMacro(ImpStack)
CompMemKindMacro(ImpLclMap)
CompMemKindMacro(BasicBlock)
CompMemKindMacro(CallArgs)
CompMemKindMacro(FlowEdge)
Expand Down
8 changes: 8 additions & 0 deletions src/coreclr/jit/gentree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8296,6 +8296,8 @@ GenTreeLclVar* Compiler::gtNewStoreLclVarNode(unsigned lclNum, GenTree* data)

gtInitializeStoreNode(store, data);

impSetLclVal(lclNum, data);

return store;
}

Expand Down Expand Up @@ -19065,6 +19067,12 @@ CORINFO_CLASS_HANDLE Compiler::gtGetFieldClassHandle(CORINFO_FIELD_HANDLE fieldH
//
bool Compiler::gtIsTypeof(GenTree* tree, CORINFO_CLASS_HANDLE* handle)
{
GenTree* typeValue = impGetLclVal(tree);
if (typeValue != nullptr)
{
tree = typeValue;
}

if (tree->IsCall())
{
GenTreeCall* call = tree->AsCall();
Expand Down
88 changes: 88 additions & 0 deletions src/coreclr/jit/importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,8 @@ void Compiler::impEndTreeList(BasicBlock* block)
impLastILoffsStmt = nullptr;
}
#endif
impLclCurVer++;
assert(impLclCurVer != 0);
impStmtList = impLastStmt = nullptr;
}

Expand Down Expand Up @@ -1063,6 +1065,92 @@ GenTree* Compiler::impStoreStructPtr(GenTree* destAddr, GenTree* value, unsigned
return store;
}

//------------------------------------------------------------------------
// impGetLclVal: Get the value of a LCL_VAR
//
// Arguments:
// val - Tree to extract the value from
//
// Return Value:
// Extracted value if the tree is a LclVar with a known value in the
// current Basic Block, nullptr otherwise.
//
// Notes:
// Returned value must be cloned before importing it again.
//
GenTree* Compiler::impGetLclVal(GenTree* val)
{
assert(val != nullptr);
if (!val->OperIs(GT_LCL_VAR))
{
return nullptr;
}

while (true)
{
unsigned lclNum = val->AsLclVar()->GetLclNum();
if (lclNum >= impLclMapSize || !lvaGetDesc(lclNum)->lvSingleDef)
{
return nullptr;
}

assert(impLclValues != nullptr);
GenTree* lclValue = impLclValues[lclNum];
if (lclValue != nullptr)
{
if (impLclVersions[lclNum] != impLclCurVer)
{
return nullptr;
}
if (lclValue->OperIs(GT_LCL_VAR))
{
unsigned newLcl = lclValue->AsLclVar()->GetLclNum();
if (lclNum == newLcl)
{
JITDUMP("\nLCL_VAR V%02u is only assigned to itself, aborting substitution\n", lclNum);
return nullptr;
}
val = lclValue;
JITDUMP("\nChecking LCL_VAR V%02u for substitution of V%02u\n", newLcl, lclNum);
continue;
}
JITDUMP("\nSubstituting value of LCL_VAR V%02u with node [%06u]\n", lclNum, dspTreeID(lclValue));
}

return lclValue;
}
}

//------------------------------------------------------------------------
// impSetLclVal: Sets the value of a LclVar for substitution
//
// Arguments:
// lclNum - Local number
// val - Current value of the local
//
void Compiler::impSetLclVal(unsigned lclNum, GenTree* val)
{
assert(val != nullptr);
if (lclNum >= impLclMapSize)
{
if (impLclValues != nullptr)
{
assert(impLclVersions != nullptr);
JITDUMP("impLclValues is too small to hold local V%02u\n", lclNum);
return;
}
// reserve more space for locals created later
impLclMapSize = max(lvaCount * 2, 32);
impLclValues = new (getAllocator(CMK_ImpLclMap)) GenTree*[impLclMapSize];
impLclVersions = new (getAllocator(CMK_ImpLclMap)) unsigned[impLclMapSize];
memset(impLclVersions, 0, impLclMapSize * sizeof(unsigned));
}
assert(impLclValues != nullptr);
assert(impLclVersions != nullptr);
impLclValues[lclNum] = val;
impLclVersions[lclNum] = impLclCurVer;
}

//------------------------------------------------------------------------
// impGetNodeAddr: Get the address of a value.
//
Expand Down
Loading