From 0dfecace0a065af2137101f262d7410fcb025c28 Mon Sep 17 00:00:00 2001 From: aromaa Date: Sun, 5 Jun 2022 00:16:57 +0300 Subject: [PATCH 1/3] Unpin locals --- src/coreclr/jit/compiler.h | 2 + src/coreclr/jit/gentree.h | 5 +++ src/coreclr/jit/lclvars.cpp | 85 ++++++++++++++++++++++++------------- 3 files changed, 62 insertions(+), 30 deletions(-) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index ed2f3f55ce905..b6b3a54b7fdb1 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -614,6 +614,8 @@ class LclVarDsc unsigned char lvSingleDefDisqualifyReason = 'H'; #endif + unsigned char lvAllDefsAreNoGc : 1; // True if all defs of this local are no-gc + #if FEATURE_MULTIREG_ARGS regNumber lvRegNumForSlot(unsigned slotNum) { diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index 34ef15e8ebd0e..6407458a06fee 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -1110,6 +1110,11 @@ struct GenTree return true; } + bool IsNotGcDef() const + { + return IsIntegralConst(0) || IsLocalAddrExpr(); + } + // LIR flags // These helper methods, along with the flag values they manipulate, are defined in lir.h // diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index cc12c8a3837da..e7c3fd241a42b 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -4181,49 +4181,62 @@ void Compiler::lvaMarkLclRefs(GenTree* tree, BasicBlock* block, Statement* stmt, /* Is this an assignment to a local variable? */ - if (op1->gtOper == GT_LCL_VAR && op2->gtType != TYP_BOOL) + if (op1->gtOper == GT_LCL_VAR) { - /* Only simple assignments allowed for booleans */ + LclVarDsc* varDsc = lvaGetDesc(op1->AsLclVarCommon()); - if (tree->gtOper != GT_ASG) + if (varDsc->lvPinned && varDsc->lvAllDefsAreNoGc) { - goto NOT_BOOL; + if (!op2->IsNotGcDef()) + { + varDsc->lvAllDefsAreNoGc = false; + } } - /* Is the RHS clearly a boolean value? */ - - switch (op2->gtOper) + if (op2->gtType != TYP_BOOL) { - unsigned lclNum; + /* Only simple assignments allowed for booleans */ - case GT_CNS_INT: + if (tree->gtOper != GT_ASG) + { + goto NOT_BOOL; + } - if (op2->AsIntCon()->gtIconVal == 0) - { - break; - } - if (op2->AsIntCon()->gtIconVal == 1) - { - break; - } + /* Is the RHS clearly a boolean value? */ - // Not 0 or 1, fall through .... - FALLTHROUGH; + switch (op2->gtOper) + { + unsigned lclNum; - default: + case GT_CNS_INT: - if (op2->OperIsCompare()) - { - break; - } + if (op2->AsIntCon()->gtIconVal == 0) + { + break; + } + if (op2->AsIntCon()->gtIconVal == 1) + { + break; + } - NOT_BOOL: + // Not 0 or 1, fall through .... + FALLTHROUGH; - lclNum = op1->AsLclVarCommon()->GetLclNum(); - noway_assert(lclNum < lvaCount); + default: - lvaTable[lclNum].lvIsBoolean = false; - break; + if (op2->OperIsCompare()) + { + break; + } + + NOT_BOOL: + + lclNum = op1->AsLclVarCommon()->GetLclNum(); + noway_assert(lclNum < lvaCount); + + lvaTable[lclNum].lvIsBoolean = false; + break; + } } } } @@ -4278,7 +4291,8 @@ void Compiler::lvaMarkLclRefs(GenTree* tree, BasicBlock* block, Statement* stmt, { if (lvaVarAddrExposed(lclNum)) { - varDsc->lvIsBoolean = false; + varDsc->lvIsBoolean = false; + varDsc->lvAllDefsAreNoGc = false; } if (tree->gtOper == GT_LCL_FLD) @@ -4703,6 +4717,8 @@ void Compiler::lvaComputeRefCounts(bool isRecompute, bool setSlotNumbers) varDsc->setLvRefCnt(0); varDsc->setLvRefCntWtd(BB_ZERO_WEIGHT); + varDsc->lvAllDefsAreNoGc = true; + // Special case for some varargs params ... these must // remain unreferenced. const bool isSpecialVarargsParam = varDsc->lvIsParam && raIsVarargsStackArg(lclNum); @@ -4750,6 +4766,8 @@ void Compiler::lvaComputeRefCounts(bool isRecompute, bool setSlotNumbers) { varDsc->lvSingleDef = varDsc->lvIsParam; varDsc->lvSingleDefRegCandidate = varDsc->lvIsParam; + + varDsc->lvAllDefsAreNoGc = true; } } @@ -4868,6 +4886,13 @@ void Compiler::lvaComputeRefCounts(bool isRecompute, bool setSlotNumbers) varDsc->lvImplicitlyReferenced = 1; } } + + if (varDsc->lvPinned && varDsc->lvAllDefsAreNoGc) + { + varDsc->lvPinned = 0; + + JITDUMP("V%02u was unpinned as all def candidates were local.\n", lclNum); + } } } From 20ed170ae939b1abefbeb59a983ed913e29f52c4 Mon Sep 17 00:00:00 2001 From: Joni Aromaa Date: Tue, 7 Jun 2022 18:14:29 +0300 Subject: [PATCH 2/3] Apply suggestions from code review Co-authored-by: Andy Ayers --- src/coreclr/jit/compiler.h | 2 +- src/coreclr/jit/lclvars.cpp | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index b6b3a54b7fdb1..235cc34ea6ed0 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -614,7 +614,7 @@ class LclVarDsc unsigned char lvSingleDefDisqualifyReason = 'H'; #endif - unsigned char lvAllDefsAreNoGc : 1; // True if all defs of this local are no-gc + unsigned char lvAllDefsAreNoGc : 1; // For pinned locals: true if all defs of this local are no-gc #if FEATURE_MULTIREG_ARGS regNumber lvRegNumForSlot(unsigned slotNum) diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index e7c3fd241a42b..083addbb5c566 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -4231,10 +4231,7 @@ void Compiler::lvaMarkLclRefs(GenTree* tree, BasicBlock* block, Statement* stmt, NOT_BOOL: - lclNum = op1->AsLclVarCommon()->GetLclNum(); - noway_assert(lclNum < lvaCount); - - lvaTable[lclNum].lvIsBoolean = false; + varDsc->lvIsBoolean = false; break; } } From 816bd0d3b7dc369777e993cb67ac7724ee48e594 Mon Sep 17 00:00:00 2001 From: aromaa Date: Tue, 7 Jun 2022 20:49:38 +0300 Subject: [PATCH 3/3] Fix compile --- src/coreclr/jit/lclvars.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index 083addbb5c566..d51104d1b93e4 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -4206,8 +4206,6 @@ void Compiler::lvaMarkLclRefs(GenTree* tree, BasicBlock* block, Statement* stmt, switch (op2->gtOper) { - unsigned lclNum; - case GT_CNS_INT: if (op2->AsIntCon()->gtIconVal == 0)