Skip to content

Commit a193cb5

Browse files
Set lvSingleDef for non TYP_REF locals (#85398)
* Set lvSingleDef for non TYP_REF locals * Apply suggestions from code review Co-authored-by: Andy Ayers <[email protected]> * Rewrite an if --------- Co-authored-by: Andy Ayers <[email protected]>
1 parent b8aeaad commit a193cb5

File tree

4 files changed

+51
-47
lines changed

4 files changed

+51
-47
lines changed

src/coreclr/jit/fgbasic.cpp

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2536,7 +2536,6 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed
25362536
{
25372537
LclVarDsc* lclDsc = lvaGetDesc(lclNum);
25382538
assert(lclDsc->lvSingleDef == 0);
2539-
// could restrict this to TYP_REF
25402539
lclDsc->lvSingleDef = !lclDsc->lvHasMultipleILStoreOp && !lclDsc->lvHasLdAddrOp;
25412540

25422541
if (lclDsc->lvSingleDef)
@@ -3494,19 +3493,20 @@ void Compiler::fgFindBasicBlocks()
34943493
// This temp should already have the type of the return value.
34953494
JITDUMP("\nInliner: re-using pre-existing spill temp V%02u\n", lvaInlineeReturnSpillTemp);
34963495

3497-
if (info.compRetType == TYP_REF)
3496+
// We may have co-opted an existing temp for the return spill.
3497+
// We likely assumed it was single-def at the time, but now
3498+
// we can see it has multiple definitions.
3499+
if ((fgReturnCount > 1) && (lvaTable[lvaInlineeReturnSpillTemp].lvSingleDef == 1))
34983500
{
3499-
// We may have co-opted an existing temp for the return spill.
3500-
// We likely assumed it was single-def at the time, but now
3501-
// we can see it has multiple definitions.
3502-
if ((fgReturnCount > 1) && (lvaTable[lvaInlineeReturnSpillTemp].lvSingleDef == 1))
3501+
// Make sure it is no longer marked single def. This is only safe
3502+
// to do if we haven't ever updated the type.
3503+
if (info.compRetType == TYP_REF)
35033504
{
3504-
// Make sure it is no longer marked single def. This is only safe
3505-
// to do if we haven't ever updated the type.
35063505
assert(!lvaTable[lvaInlineeReturnSpillTemp].lvClassInfoUpdated);
3507-
JITDUMP("Marked return spill temp V%02u as NOT single def temp\n", lvaInlineeReturnSpillTemp);
3508-
lvaTable[lvaInlineeReturnSpillTemp].lvSingleDef = 0;
35093506
}
3507+
3508+
JITDUMP("Marked return spill temp V%02u as NOT single def temp\n", lvaInlineeReturnSpillTemp);
3509+
lvaTable[lvaInlineeReturnSpillTemp].lvSingleDef = 0;
35103510
}
35113511
}
35123512
else
@@ -3515,18 +3515,18 @@ void Compiler::fgFindBasicBlocks()
35153515
lvaInlineeReturnSpillTemp = lvaGrabTemp(false DEBUGARG("Inline return value spill temp"));
35163516
lvaTable[lvaInlineeReturnSpillTemp].lvType = info.compRetType;
35173517

3518+
// The return spill temp is single def only if the method has a single return block.
3519+
if (fgReturnCount == 1)
3520+
{
3521+
lvaTable[lvaInlineeReturnSpillTemp].lvSingleDef = 1;
3522+
JITDUMP("Marked return spill temp V%02u as a single def temp\n", lvaInlineeReturnSpillTemp);
3523+
}
3524+
35183525
// If the method returns a ref class, set the class of the spill temp
35193526
// to the method's return value. We may update this later if it turns
35203527
// out we can prove the method returns a more specific type.
35213528
if (info.compRetType == TYP_REF)
35223529
{
3523-
// The return spill temp is single def only if the method has a single return block.
3524-
if (fgReturnCount == 1)
3525-
{
3526-
lvaTable[lvaInlineeReturnSpillTemp].lvSingleDef = 1;
3527-
JITDUMP("Marked return spill temp V%02u as a single def temp\n", lvaInlineeReturnSpillTemp);
3528-
}
3529-
35303530
CORINFO_CLASS_HANDLE retClassHnd = impInlineInfo->inlineCandidateInfo->methInfo.args.retTypeClass;
35313531
if (retClassHnd != nullptr)
35323532
{

src/coreclr/jit/fgopt.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1453,7 +1453,7 @@ PhaseStatus Compiler::fgPostImportationCleanup()
14531453
{
14541454
LclVarDsc* returnSpillVarDsc = lvaGetDesc(lvaInlineeReturnSpillTemp);
14551455

1456-
if (returnSpillVarDsc->lvSingleDef)
1456+
if ((returnSpillVarDsc->lvType == TYP_REF) && returnSpillVarDsc->lvSingleDef)
14571457
{
14581458
lvaUpdateClass(lvaInlineeReturnSpillTemp, retExprClassHnd, impInlineInfo->retExprClassHndIsExact);
14591459
}

src/coreclr/jit/importer.cpp

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1862,14 +1862,18 @@ bool Compiler::impSpillStackEntry(unsigned level,
18621862
/* Assign the spilled entry to the temp */
18631863
impAssignTempGen(tnum, tree, verCurrentState.esStack[level].seTypeInfo.GetClassHandle(), level);
18641864

1865-
// If temp is newly introduced and a ref type, grab what type info we can.
1866-
if (isNewTemp && (lvaTable[tnum].lvType == TYP_REF))
1865+
if (isNewTemp)
18671866
{
18681867
assert(lvaTable[tnum].lvSingleDef == 0);
18691868
lvaTable[tnum].lvSingleDef = 1;
18701869
JITDUMP("Marked V%02u as a single def temp\n", tnum);
1871-
CORINFO_CLASS_HANDLE stkHnd = verCurrentState.esStack[level].seTypeInfo.GetClassHandle();
1872-
lvaSetClass(tnum, tree, stkHnd);
1870+
1871+
// If temp is newly introduced and a ref type, grab what type info we can.
1872+
if (lvaTable[tnum].lvType == TYP_REF)
1873+
{
1874+
CORINFO_CLASS_HANDLE stkHnd = verCurrentState.esStack[level].seTypeInfo.GetClassHandle();
1875+
lvaSetClass(tnum, tree, stkHnd);
1876+
}
18731877

18741878
// If we're assigning a GT_RET_EXPR, note the temp over on the call,
18751879
// so the inliner can use it in case it needs a return spill temp.
@@ -8373,12 +8377,12 @@ void Compiler::impImportBlockCode(BasicBlock* block)
83738377
impAssignTempGen(tmpNum, op1, tiRetVal.GetClassHandle(), CHECK_SPILL_ALL);
83748378
var_types type = genActualType(lvaTable[tmpNum].TypeGet());
83758379

8380+
assert(lvaTable[tmpNum].lvSingleDef == 0);
8381+
lvaTable[tmpNum].lvSingleDef = 1;
8382+
JITDUMP("Marked V%02u as a single def local\n", tmpNum);
83768383
// Propagate type info to the temp from the stack and the original tree
83778384
if (type == TYP_REF)
83788385
{
8379-
assert(lvaTable[tmpNum].lvSingleDef == 0);
8380-
lvaTable[tmpNum].lvSingleDef = 1;
8381-
JITDUMP("Marked V%02u as a single def local\n", tmpNum);
83828386
lvaSetClass(tmpNum, tree, tiRetVal.GetClassHandle());
83838387
}
83848388

@@ -13582,19 +13586,19 @@ unsigned Compiler::impInlineFetchLocal(unsigned lclNum DEBUGARG(const char* reas
1358213586
lvaTable[tmpNum].lvHasILStoreOp = inlineeLocal.lclHasStlocOp;
1358313587
lvaTable[tmpNum].lvHasMultipleILStoreOp = inlineeLocal.lclHasMultipleStlocOp;
1358413588

13589+
assert(lvaTable[tmpNum].lvSingleDef == 0);
13590+
13591+
lvaTable[tmpNum].lvSingleDef = !inlineeLocal.lclHasMultipleStlocOp && !inlineeLocal.lclHasLdlocaOp;
13592+
if (lvaTable[tmpNum].lvSingleDef)
13593+
{
13594+
JITDUMP("Marked V%02u as a single def temp\n", tmpNum);
13595+
}
13596+
1358513597
// Copy over class handle for ref types. Note this may be a
1358613598
// shared type -- someday perhaps we can get the exact
1358713599
// signature and pass in a more precise type.
1358813600
if (lclTyp == TYP_REF)
1358913601
{
13590-
assert(lvaTable[tmpNum].lvSingleDef == 0);
13591-
13592-
lvaTable[tmpNum].lvSingleDef = !inlineeLocal.lclHasMultipleStlocOp && !inlineeLocal.lclHasLdlocaOp;
13593-
if (lvaTable[tmpNum].lvSingleDef)
13594-
{
13595-
JITDUMP("Marked V%02u as a single def temp\n", tmpNum);
13596-
}
13597-
1359813602
lvaSetClass(tmpNum, inlineeLocal.lclVerTypeInfo.GetClassHandleForObjRef());
1359913603
}
1360013604

@@ -13779,20 +13783,21 @@ GenTree* Compiler::impInlineFetchArg(unsigned lclNum, InlArgInfo* inlArgInfo, In
1377913783

1378013784
lvaTable[tmpNum].lvType = lclTyp;
1378113785

13782-
// For ref types, determine the type of the temp.
13783-
if (lclTyp == TYP_REF)
13786+
// If arg can't be modified, mark it as single def.
13787+
// For ref types, determine the class of the arg temp.
13788+
if (!argCanBeModified)
1378413789
{
13785-
if (!argCanBeModified)
13790+
assert(lvaTable[tmpNum].lvSingleDef == 0);
13791+
lvaTable[tmpNum].lvSingleDef = 1;
13792+
JITDUMP("Marked V%02u as a single def temp\n", tmpNum);
13793+
if (lclTyp == TYP_REF)
1378613794
{
13787-
// If the arg can't be modified in the method
13788-
// body, use the type of the value, if
13789-
// known. Otherwise, use the declared type.
13790-
assert(lvaTable[tmpNum].lvSingleDef == 0);
13791-
lvaTable[tmpNum].lvSingleDef = 1;
13792-
JITDUMP("Marked V%02u as a single def temp\n", tmpNum);
1379313795
lvaSetClass(tmpNum, argNode, lclInfo.lclVerTypeInfo.GetClassHandleForObjRef());
1379413796
}
13795-
else
13797+
}
13798+
else
13799+
{
13800+
if (lclTyp == TYP_REF)
1379613801
{
1379713802
// Arg might be modified, use the declared type of
1379813803
// the argument.

src/coreclr/jit/importercalls.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5477,12 +5477,11 @@ class SpillRetExprHelper
54775477
comp->impAssignTempGen(tmp, retExpr, (unsigned)Compiler::CHECK_SPILL_NONE);
54785478
*pRetExpr = comp->gtNewLclvNode(tmp, retExpr->TypeGet());
54795479

5480+
assert(comp->lvaTable[tmp].lvSingleDef == 0);
5481+
comp->lvaTable[tmp].lvSingleDef = 1;
5482+
JITDUMP("Marked V%02u as a single def temp\n", tmp);
54805483
if (retExpr->TypeGet() == TYP_REF)
54815484
{
5482-
assert(comp->lvaTable[tmp].lvSingleDef == 0);
5483-
comp->lvaTable[tmp].lvSingleDef = 1;
5484-
JITDUMP("Marked V%02u as a single def temp\n", tmp);
5485-
54865485
bool isExact = false;
54875486
bool isNonNull = false;
54885487
CORINFO_CLASS_HANDLE retClsHnd = comp->gtGetClassHandle(retExpr, &isExact, &isNonNull);

0 commit comments

Comments
 (0)