/*
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-XX XX
-XX Optimization activation rules XX
-XX XX
-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-*/
-
-// should we try to replace integer multiplication with lea/add/shift sequences?
-inline bool Compiler::optAvoidIntMult(void)
-{
- return (compCodeOpt() != SMALL_CODE);
-}
-
-/*
-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XX EEInterface XX
XX Inline functions XX
XX XX
std::swap(tree->gtOp1, tree->gtOp2);
}
- if (!optValnumCSE_phase)
- {
- GenTree* optimizedTree = nullptr;
- if (tree->OperIs(GT_ADD))
- {
- optimizedTree = fgOptimizeAddition(tree);
- }
- else if (tree->OperIs(GT_MUL))
- {
- optimizedTree = fgOptimizeMultiply(tree);
- }
- else if (tree->OperIs(GT_AND))
- {
- optimizedTree = fgOptimizeBitwiseAnd(tree);
- }
-
- if (optimizedTree != nullptr)
- {
- return optimizedTree;
- }
- }
-
if (fgOperIsBitwiseRotationRoot(tree->OperGet()))
{
GenTree* rotationTree = fgRecognizeAndMorphBitwiseRotation(tree);
if (varTypeIsIntegralOrI(tree))
{
+ genTreeOps oldTreeOper = tree->OperGet();
GenTreeOp* optimizedTree = fgMorphCommutative(tree->AsOp());
if (optimizedTree != nullptr)
{
+ if (!optimizedTree->OperIs(oldTreeOper))
+ {
+ // "optimizedTree" could end up being a COMMA.
+ return optimizedTree;
+ }
+
+ tree = optimizedTree;
+ }
+ }
+
+ if (!optValnumCSE_phase)
+ {
+ GenTree* optimizedTree = nullptr;
+ if (tree->OperIs(GT_ADD))
+ {
+ optimizedTree = fgOptimizeAddition(tree);
+ }
+ else if (tree->OperIs(GT_MUL))
+ {
+ optimizedTree = fgOptimizeMultiply(tree);
+ }
+ else if (tree->OperIs(GT_AND))
+ {
+ optimizedTree = fgOptimizeBitwiseAnd(tree);
+ }
+
+ if (optimizedTree != nullptr)
+ {
return optimizedTree;
}
}
// Fold (x + 0) - given it won't change the tree type to TYP_REF.
// TODO-Bug: this code will lose the GC-ness of a tree like "native int + byref(0)".
- if (op2->IsCnsIntOrI() && (op2->AsIntCon()->IconValue() == 0) &&
- ((add->TypeGet() == op1->TypeGet()) || !op1->TypeIs(TYP_REF)))
+ if (op2->IsIntegralConst(0) && ((add->TypeGet() == op1->TypeGet()) || !op1->TypeIs(TYP_REF)))
{
if (op2->IsCnsIntOrI() && (op2->AsIntCon()->gtFieldSeq != nullptr) &&
(op2->AsIntCon()->gtFieldSeq != FieldSeqStore::NotAField()))
return op1;
}
- // TODO-CQ: this transform preserves VNs and can be enabled outside global morph.
// Note that these transformations are legal for floating-point ADDs as well.
- if (opts.OptimizationEnabled() && fgGlobalMorph)
+ if (opts.OptimizationEnabled())
{
// - a + b = > b - a
// ADD((NEG(a), b) => SUB(b, a)
return mul;
}
+#ifdef TARGET_XARCH
+ // Should we try to replace integer multiplication with lea/add/shift sequences?
+ bool mulShiftOpt = compCodeOpt() != SMALL_CODE;
+#else // !TARGET_XARCH
+ bool mulShiftOpt = false;
+#endif // !TARGET_XARCH
+
size_t abs_mult = (mult >= 0) ? mult : -mult;
size_t lowestBit = genFindLowestBit(abs_mult);
bool changeToShift = false;
op2->AsIntConCommon()->SetIconValue(genLog2(abs_mult));
changeToShift = true;
}
- else if ((lowestBit > 1) && jitIsScaleIndexMul(lowestBit) && optAvoidIntMult())
+ else if (mulShiftOpt && (lowestBit > 1) && jitIsScaleIndexMul(lowestBit))
{
int shift = genLog2(lowestBit);
ssize_t factor = abs_mult >> shift;