Skip to content

Commit 4d44308

Browse files
JIT: Do not propagate some constants (#70378)
Co-authored-by: Tanner Gooding <tagoo@outlook.com>
1 parent 95e8cae commit 4d44308

2 files changed

Lines changed: 59 additions & 0 deletions

File tree

src/coreclr/jit/assertionprop.cpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3177,6 +3177,15 @@ GenTree* Compiler::optVNConstantPropOnTree(BasicBlock* block, GenTree* tree)
31773177

31783178
if (conValTree != nullptr)
31793179
{
3180+
if (tree->OperIs(GT_LCL_VAR))
3181+
{
3182+
if (!optIsProfitableToSubstitute(tree->AsLclVar(), block, conValTree))
3183+
{
3184+
// Not profitable to substitute
3185+
return nullptr;
3186+
}
3187+
}
3188+
31803189
// Were able to optimize.
31813190
conValTree->gtVNPair = vnPair;
31823191
GenTree* sideEffList = optExtractSideEffListFromConst(tree);
@@ -3199,6 +3208,55 @@ GenTree* Compiler::optVNConstantPropOnTree(BasicBlock* block, GenTree* tree)
31993208
}
32003209
}
32013210

3211+
//------------------------------------------------------------------------------
3212+
// optIsProfitableToSubstitute: Checks if value worth substituting to lcl location
3213+
//
3214+
// Arguments:
3215+
// lcl - lcl to replace with value if profitable
3216+
// lclBlock - Basic block lcl located in
3217+
// value - value we plan to substitute to lcl
3218+
//
3219+
// Returns:
3220+
// False if it's likely not profitable to do substitution, True otherwise
3221+
//
3222+
bool Compiler::optIsProfitableToSubstitute(GenTreeLclVarCommon* lcl, BasicBlock* lclBlock, GenTree* value)
3223+
{
3224+
// A simple heuristic: If the constant is defined outside of a loop (not far from its head)
3225+
// and is used inside it - don't propagate.
3226+
3227+
// TODO: Extend on more kinds of trees
3228+
if (!value->OperIs(GT_CNS_VEC, GT_CNS_DBL))
3229+
{
3230+
return true;
3231+
}
3232+
3233+
gtPrepareCost(value);
3234+
3235+
if ((value->GetCostEx() > 1) && (value->GetCostSz() > 1))
3236+
{
3237+
// Try to find the block this constant was originally defined in
3238+
if (lcl->HasSsaName())
3239+
{
3240+
BasicBlock* defBlock = lvaGetDesc(lcl)->GetPerSsaData(lcl->GetSsaNum())->GetBlock();
3241+
if (defBlock != nullptr)
3242+
{
3243+
// Avoid propagating if the weighted use cost is significantly greater than the def cost.
3244+
// NOTE: this currently does not take "a float living across a call" case into account
3245+
// where we might end up with spill/restore on ABIs without callee-saved registers
3246+
const weight_t defBlockWeight = defBlock->getBBWeight(this);
3247+
const weight_t lclblockWeight = lclBlock->getBBWeight(this);
3248+
3249+
if ((defBlockWeight > 0) && ((lclblockWeight / defBlockWeight) >= BB_LOOP_WEIGHT_SCALE))
3250+
{
3251+
JITDUMP("Constant propagation inside loop " FMT_BB " is not profitable\n", lclBlock->bbNum);
3252+
return false;
3253+
}
3254+
}
3255+
}
3256+
}
3257+
return true;
3258+
}
3259+
32023260
//------------------------------------------------------------------------------
32033261
// optConstantAssertionProp: Possibly substitute a constant for a local use
32043262
//

src/coreclr/jit/compiler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7264,6 +7264,7 @@ class Compiler
72647264
GenTree* optConstantAssertionProp(AssertionDsc* curAssertion,
72657265
GenTreeLclVarCommon* tree,
72667266
Statement* stmt DEBUGARG(AssertionIndex index));
7267+
bool optIsProfitableToSubstitute(GenTreeLclVarCommon* lcl, BasicBlock* lclBlock, GenTree* value);
72677268
bool optZeroObjAssertionProp(GenTree* tree, ASSERT_VALARG_TP assertions);
72687269

72697270
// Assertion propagation functions.

0 commit comments

Comments
 (0)