Skip to content

Commit a78211b

Browse files
authored
Unpin locals, attempt 2 (#70655)
Contributes to #40553
1 parent 5fc5c68 commit a78211b

File tree

3 files changed

+55
-30
lines changed

3 files changed

+55
-30
lines changed

src/coreclr/jit/compiler.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,8 @@ class LclVarDsc
614614
unsigned char lvSingleDefDisqualifyReason = 'H';
615615
#endif
616616

617+
unsigned char lvAllDefsAreNoGc : 1; // For pinned locals: true if all defs of this local are no-gc
618+
617619
#if FEATURE_MULTIREG_ARGS
618620
regNumber lvRegNumForSlot(unsigned slotNum)
619621
{

src/coreclr/jit/gentree.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,6 +1104,11 @@ struct GenTree
11041104
return true;
11051105
}
11061106

1107+
bool IsNotGcDef() const
1108+
{
1109+
return IsIntegralConst(0) || IsLocalAddrExpr();
1110+
}
1111+
11071112
// LIR flags
11081113
// These helper methods, along with the flag values they manipulate, are defined in lir.h
11091114
//

src/coreclr/jit/lclvars.cpp

Lines changed: 48 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4234,49 +4234,57 @@ void Compiler::lvaMarkLclRefs(GenTree* tree, BasicBlock* block, Statement* stmt,
42344234

42354235
/* Is this an assignment to a local variable? */
42364236

4237-
if (op1->gtOper == GT_LCL_VAR && op2->gtType != TYP_BOOL)
4237+
if (op1->gtOper == GT_LCL_VAR)
42384238
{
4239-
/* Only simple assignments allowed for booleans */
4239+
LclVarDsc* varDsc = lvaGetDesc(op1->AsLclVarCommon());
42404240

4241-
if (tree->gtOper != GT_ASG)
4241+
if (varDsc->lvPinned && varDsc->lvAllDefsAreNoGc)
42424242
{
4243-
goto NOT_BOOL;
4243+
if (!op2->IsNotGcDef())
4244+
{
4245+
varDsc->lvAllDefsAreNoGc = false;
4246+
}
42444247
}
42454248

4246-
/* Is the RHS clearly a boolean value? */
4247-
4248-
switch (op2->gtOper)
4249+
if (op2->gtType != TYP_BOOL)
42494250
{
4250-
unsigned lclNum;
4251+
/* Only simple assignments allowed for booleans */
42514252

4252-
case GT_CNS_INT:
4253+
if (tree->gtOper != GT_ASG)
4254+
{
4255+
goto NOT_BOOL;
4256+
}
42534257

4254-
if (op2->AsIntCon()->gtIconVal == 0)
4255-
{
4256-
break;
4257-
}
4258-
if (op2->AsIntCon()->gtIconVal == 1)
4259-
{
4260-
break;
4261-
}
4258+
/* Is the RHS clearly a boolean value? */
42624259

4263-
// Not 0 or 1, fall through ....
4264-
FALLTHROUGH;
4260+
switch (op2->gtOper)
4261+
{
4262+
case GT_CNS_INT:
42654263

4266-
default:
4264+
if (op2->AsIntCon()->gtIconVal == 0)
4265+
{
4266+
break;
4267+
}
4268+
if (op2->AsIntCon()->gtIconVal == 1)
4269+
{
4270+
break;
4271+
}
42674272

4268-
if (op2->OperIsCompare())
4269-
{
4270-
break;
4271-
}
4273+
// Not 0 or 1, fall through ....
4274+
FALLTHROUGH;
42724275

4273-
NOT_BOOL:
4276+
default:
42744277

4275-
lclNum = op1->AsLclVarCommon()->GetLclNum();
4276-
noway_assert(lclNum < lvaCount);
4278+
if (op2->OperIsCompare())
4279+
{
4280+
break;
4281+
}
42774282

4278-
lvaTable[lclNum].lvIsBoolean = false;
4279-
break;
4283+
NOT_BOOL:
4284+
4285+
varDsc->lvIsBoolean = false;
4286+
break;
4287+
}
42804288
}
42814289
}
42824290
}
@@ -4331,7 +4339,8 @@ void Compiler::lvaMarkLclRefs(GenTree* tree, BasicBlock* block, Statement* stmt,
43314339
{
43324340
if (lvaVarAddrExposed(lclNum))
43334341
{
4334-
varDsc->lvIsBoolean = false;
4342+
varDsc->lvIsBoolean = false;
4343+
varDsc->lvAllDefsAreNoGc = false;
43354344
}
43364345

43374346
if (tree->gtOper == GT_LCL_FLD)
@@ -4803,6 +4812,8 @@ void Compiler::lvaComputeRefCounts(bool isRecompute, bool setSlotNumbers)
48034812
{
48044813
varDsc->lvSingleDef = varDsc->lvIsParam;
48054814
varDsc->lvSingleDefRegCandidate = varDsc->lvIsParam;
4815+
4816+
varDsc->lvAllDefsAreNoGc = (varDsc->lvImplicitlyReferenced == false);
48064817
}
48074818
}
48084819

@@ -4921,6 +4932,13 @@ void Compiler::lvaComputeRefCounts(bool isRecompute, bool setSlotNumbers)
49214932
varDsc->lvImplicitlyReferenced = 1;
49224933
}
49234934
}
4935+
4936+
if (varDsc->lvPinned && varDsc->lvAllDefsAreNoGc)
4937+
{
4938+
varDsc->lvPinned = 0;
4939+
4940+
JITDUMP("V%02u was unpinned as all def candidates were local.\n", lclNum);
4941+
}
49244942
}
49254943
}
49264944

0 commit comments

Comments
 (0)