Skip to content

Commit d06d9c9

Browse files
Commutative morph optimizations (#64122)
* Optimize order of morphing "fgMorphCommutative" exposes information to the later transforms that make them more precise. For example, "MUL(MUL(X, CONST1), CONST2)" is now morphed properly into a single "mul" instead of one "mul" plus a shift and lea in case "CONST2" was a viable candidate for "mulshift". Another example is how "fgMorphCommutative" can end up with an "ADD(X, 0)" that was only being discarded in lowering. * Fold (x + 0) => 0 for LONGs on 32 bit * Enable one opt outside global morph No reason not to. Just a few diffs. * Disable mulshift on ARM/64 No LEAs - no point.
1 parent 91da4ac commit d06d9c9

File tree

3 files changed

+39
-49
lines changed

3 files changed

+39
-49
lines changed

src/coreclr/jit/compiler.h

-6
Original file line numberDiff line numberDiff line change
@@ -7122,12 +7122,6 @@ class Compiler
71227122

71237123
bool optNarrowTree(GenTree* tree, var_types srct, var_types dstt, ValueNumPair vnpNarrow, bool doit);
71247124

7125-
/**************************************************************************
7126-
* Optimization conditions
7127-
*************************************************************************/
7128-
7129-
bool optAvoidIntMult(void);
7130-
71317125
protected:
71327126
// The following is the upper limit on how many expressions we'll keep track
71337127
// of for the CSE analysis.

src/coreclr/jit/compiler.hpp

-16
Original file line numberDiff line numberDiff line change
@@ -3578,22 +3578,6 @@ inline bool Compiler::LoopDsc::lpArrLenLimit(Compiler* comp, ArrIndex* index) co
35783578
return false;
35793579
}
35803580

3581-
/*
3582-
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3583-
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3584-
XX XX
3585-
XX Optimization activation rules XX
3586-
XX XX
3587-
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3588-
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3589-
*/
3590-
3591-
// should we try to replace integer multiplication with lea/add/shift sequences?
3592-
inline bool Compiler::optAvoidIntMult(void)
3593-
{
3594-
return (compCodeOpt() != SMALL_CODE);
3595-
}
3596-
35973581
/*
35983582
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
35993583
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

src/coreclr/jit/morph.cpp

+39-27
Original file line numberDiff line numberDiff line change
@@ -13435,28 +13435,6 @@ GenTree* Compiler::fgOptimizeCommutativeArithmetic(GenTreeOp* tree)
1343513435
std::swap(tree->gtOp1, tree->gtOp2);
1343613436
}
1343713437

13438-
if (!optValnumCSE_phase)
13439-
{
13440-
GenTree* optimizedTree = nullptr;
13441-
if (tree->OperIs(GT_ADD))
13442-
{
13443-
optimizedTree = fgOptimizeAddition(tree);
13444-
}
13445-
else if (tree->OperIs(GT_MUL))
13446-
{
13447-
optimizedTree = fgOptimizeMultiply(tree);
13448-
}
13449-
else if (tree->OperIs(GT_AND))
13450-
{
13451-
optimizedTree = fgOptimizeBitwiseAnd(tree);
13452-
}
13453-
13454-
if (optimizedTree != nullptr)
13455-
{
13456-
return optimizedTree;
13457-
}
13458-
}
13459-
1346013438
if (fgOperIsBitwiseRotationRoot(tree->OperGet()))
1346113439
{
1346213440
GenTree* rotationTree = fgRecognizeAndMorphBitwiseRotation(tree);
@@ -13477,7 +13455,36 @@ GenTree* Compiler::fgOptimizeCommutativeArithmetic(GenTreeOp* tree)
1347713455

1347813456
if (varTypeIsIntegralOrI(tree))
1347913457
{
13458+
genTreeOps oldTreeOper = tree->OperGet();
1348013459
GenTreeOp* optimizedTree = fgMorphCommutative(tree->AsOp());
13460+
if (optimizedTree != nullptr)
13461+
{
13462+
if (!optimizedTree->OperIs(oldTreeOper))
13463+
{
13464+
// "optimizedTree" could end up being a COMMA.
13465+
return optimizedTree;
13466+
}
13467+
13468+
tree = optimizedTree;
13469+
}
13470+
}
13471+
13472+
if (!optValnumCSE_phase)
13473+
{
13474+
GenTree* optimizedTree = nullptr;
13475+
if (tree->OperIs(GT_ADD))
13476+
{
13477+
optimizedTree = fgOptimizeAddition(tree);
13478+
}
13479+
else if (tree->OperIs(GT_MUL))
13480+
{
13481+
optimizedTree = fgOptimizeMultiply(tree);
13482+
}
13483+
else if (tree->OperIs(GT_AND))
13484+
{
13485+
optimizedTree = fgOptimizeBitwiseAnd(tree);
13486+
}
13487+
1348113488
if (optimizedTree != nullptr)
1348213489
{
1348313490
return optimizedTree;
@@ -13529,8 +13536,7 @@ GenTree* Compiler::fgOptimizeAddition(GenTreeOp* add)
1352913536

1353013537
// Fold (x + 0) - given it won't change the tree type to TYP_REF.
1353113538
// TODO-Bug: this code will lose the GC-ness of a tree like "native int + byref(0)".
13532-
if (op2->IsCnsIntOrI() && (op2->AsIntCon()->IconValue() == 0) &&
13533-
((add->TypeGet() == op1->TypeGet()) || !op1->TypeIs(TYP_REF)))
13539+
if (op2->IsIntegralConst(0) && ((add->TypeGet() == op1->TypeGet()) || !op1->TypeIs(TYP_REF)))
1353413540
{
1353513541
if (op2->IsCnsIntOrI() && (op2->AsIntCon()->gtFieldSeq != nullptr) &&
1353613542
(op2->AsIntCon()->gtFieldSeq != FieldSeqStore::NotAField()))
@@ -13544,9 +13550,8 @@ GenTree* Compiler::fgOptimizeAddition(GenTreeOp* add)
1354413550
return op1;
1354513551
}
1354613552

13547-
// TODO-CQ: this transform preserves VNs and can be enabled outside global morph.
1354813553
// Note that these transformations are legal for floating-point ADDs as well.
13549-
if (opts.OptimizationEnabled() && fgGlobalMorph)
13554+
if (opts.OptimizationEnabled())
1355013555
{
1355113556
// - a + b = > b - a
1355213557
// ADD((NEG(a), b) => SUB(b, a)
@@ -13655,6 +13660,13 @@ GenTree* Compiler::fgOptimizeMultiply(GenTreeOp* mul)
1365513660
return mul;
1365613661
}
1365713662

13663+
#ifdef TARGET_XARCH
13664+
// Should we try to replace integer multiplication with lea/add/shift sequences?
13665+
bool mulShiftOpt = compCodeOpt() != SMALL_CODE;
13666+
#else // !TARGET_XARCH
13667+
bool mulShiftOpt = false;
13668+
#endif // !TARGET_XARCH
13669+
1365813670
size_t abs_mult = (mult >= 0) ? mult : -mult;
1365913671
size_t lowestBit = genFindLowestBit(abs_mult);
1366013672
bool changeToShift = false;
@@ -13697,7 +13709,7 @@ GenTree* Compiler::fgOptimizeMultiply(GenTreeOp* mul)
1369713709
op2->AsIntConCommon()->SetIconValue(genLog2(abs_mult));
1369813710
changeToShift = true;
1369913711
}
13700-
else if ((lowestBit > 1) && jitIsScaleIndexMul(lowestBit) && optAvoidIntMult())
13712+
else if (mulShiftOpt && (lowestBit > 1) && jitIsScaleIndexMul(lowestBit))
1370113713
{
1370213714
int shift = genLog2(lowestBit);
1370313715
ssize_t factor = abs_mult >> shift;

0 commit comments

Comments
 (0)