From 6cc112523a7ca7573b7abbaafe2fd541605df407 Mon Sep 17 00:00:00 2001 From: Joni Aromaa Date: Sat, 11 Jun 2022 19:06:34 +0300 Subject: [PATCH 1/2] Unpin locals (#70264) Contributes to #40553 --- src/coreclr/jit/compiler.h | 2 + src/coreclr/jit/gentree.h | 5 +++ src/coreclr/jit/lclvars.cpp | 80 +++++++++++++++++++++++-------------- 3 files changed, 57 insertions(+), 30 deletions(-) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index c838b9e9c7268..909c22906c892 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; // 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/gentree.h b/src/coreclr/jit/gentree.h index 6ef9cb3032e0a..5728b9e43fc89 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -1109,6 +1109,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..d51104d1b93e4 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -4181,49 +4181,57 @@ 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) + { + case GT_CNS_INT: - default: + if (op2->AsIntCon()->gtIconVal == 0) + { + break; + } + if (op2->AsIntCon()->gtIconVal == 1) + { + break; + } - if (op2->OperIsCompare()) - { - break; - } + // Not 0 or 1, fall through .... + FALLTHROUGH; - NOT_BOOL: + default: - lclNum = op1->AsLclVarCommon()->GetLclNum(); - noway_assert(lclNum < lvaCount); + if (op2->OperIsCompare()) + { + break; + } - lvaTable[lclNum].lvIsBoolean = false; - break; + NOT_BOOL: + + varDsc->lvIsBoolean = false; + break; + } } } } @@ -4278,7 +4286,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 +4712,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 +4761,8 @@ void Compiler::lvaComputeRefCounts(bool isRecompute, bool setSlotNumbers) { varDsc->lvSingleDef = varDsc->lvIsParam; varDsc->lvSingleDefRegCandidate = varDsc->lvIsParam; + + varDsc->lvAllDefsAreNoGc = true; } } @@ -4868,6 +4881,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 73df65928cddbd8f034ee7fa00f8e1186f1b584a Mon Sep 17 00:00:00 2001 From: aromaa Date: Mon, 13 Jun 2022 13:47:36 +0300 Subject: [PATCH 2/2] Fix OSR --- src/coreclr/jit/lclvars.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index d51104d1b93e4..5a73d5dc143ed 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -4712,8 +4712,6 @@ 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); @@ -4762,7 +4760,7 @@ void Compiler::lvaComputeRefCounts(bool isRecompute, bool setSlotNumbers) varDsc->lvSingleDef = varDsc->lvIsParam; varDsc->lvSingleDefRegCandidate = varDsc->lvIsParam; - varDsc->lvAllDefsAreNoGc = true; + varDsc->lvAllDefsAreNoGc = (varDsc->lvImplicitlyReferenced == false); } }