Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit f087eb3

Browse files
committed
Merge pull request #3067 from erozenfeld/MultToShiftVN
Preserve value numbers when morphing multiplication into shift.
2 parents 2d19b0c + 96a998d commit f087eb3

File tree

3 files changed

+47
-23
lines changed

3 files changed

+47
-23
lines changed

src/jit/compiler.hpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,7 +1304,7 @@ inline unsigned Compiler::gtSetEvalOrderAndRestoreFPstkLevel(GenTree * t
13041304
/*****************************************************************************/
13051305

13061306
inline
1307-
void GenTree::SetOper(genTreeOps oper)
1307+
void GenTree::SetOper(genTreeOps oper, ValueNumberUpdate vnUpdate)
13081308
{
13091309
assert(((gtFlags & GTF_NODE_SMALL) != 0) !=
13101310
((gtFlags & GTF_NODE_LARGE) != 0));
@@ -1342,9 +1342,11 @@ void GenTree::SetOper(genTreeOps oper)
13421342
gtIntCon.gtFieldSeq = NULL;
13431343
}
13441344

1345-
// Clear the ValueNum field as well.
1346-
//
1347-
gtVNPair.SetBoth(ValueNumStore::NoVN);
1345+
if (vnUpdate == CLEAR_VN)
1346+
{
1347+
// Clear the ValueNum field as well.
1348+
gtVNPair.SetBoth(ValueNumStore::NoVN);
1349+
}
13481350
}
13491351

13501352
inline
@@ -1405,9 +1407,15 @@ inline
14051407
void GenTree::InitNodeSize(){}
14061408

14071409
inline
1408-
void GenTree::SetOper(genTreeOps oper)
1410+
void GenTree::SetOper(genTreeOps oper, ValueNumberUpdate vnUpdate)
14091411
{
14101412
gtOper = oper;
1413+
1414+
if (vnUpdate == CLEAR_VN)
1415+
{
1416+
// Clear the ValueNum field.
1417+
gtVNPair.SetBoth(ValueNumStore::NoVN);
1418+
}
14111419
}
14121420

14131421
inline
@@ -1461,11 +1469,11 @@ void GenTree::ChangeOperConst(genTreeOps oper)
14611469
}
14621470

14631471
inline
1464-
void GenTree::ChangeOper(genTreeOps oper)
1472+
void GenTree::ChangeOper(genTreeOps oper, ValueNumberUpdate vnUpdate)
14651473
{
14661474
assert(!OperIsConst(oper)); // use ChangeOperLeaf() instead
14671475

1468-
SetOper(oper);
1476+
SetOper(oper, vnUpdate);
14691477
gtFlags &= GTF_COMMON_MASK;
14701478

14711479
// Do "oper"-specific initializations...

src/jit/gentree.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1408,11 +1408,19 @@ struct GenTree
14081408
bool IsNothingNode () const;
14091409
void gtBashToNOP ();
14101410

1411-
void SetOper (genTreeOps oper); // set gtOper
1411+
// Value number update action enumeration
1412+
enum ValueNumberUpdate
1413+
{
1414+
CLEAR_VN, // Clear value number
1415+
PRESERVE_VN // Preserve value number
1416+
};
1417+
1418+
void SetOper(genTreeOps oper, ValueNumberUpdate vnUpdate = CLEAR_VN); // set gtOper
14121419
void SetOperResetFlags (genTreeOps oper); // set gtOper and reset flags
14131420

14141421
void ChangeOperConst (genTreeOps oper); // ChangeOper(constOper)
1415-
void ChangeOper (genTreeOps oper); // set gtOper and only keep GTF_COMMON_MASK flags
1422+
// set gtOper and only keep GTF_COMMON_MASK flags
1423+
void ChangeOper(genTreeOps oper, ValueNumberUpdate vnUpdate = CLEAR_VN);
14161424
void ChangeOperUnchecked (genTreeOps oper);
14171425

14181426
bool IsLocal() const

src/jit/morph.cpp

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10324,20 +10324,16 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* ma
1032410324
// IF we get here we should be changing 'oper'
1032510325
assert(tree->OperGet() != oper);
1032610326

10327-
ValueNumPair vnp;
10328-
vnp = tree->gtVNPair; // Save the existing ValueNumber for 'tree'
10329-
10330-
tree->SetOper(oper);
10327+
// Keep the old ValueNumber for 'tree' as the new expr
10328+
// will still compute the same value as before
10329+
tree->SetOper(oper, GenTree::PRESERVE_VN);
1033110330
cns2->gtIntCon.gtIconVal = 0;
1033210331

1033310332
// vnStore is null before the ValueNumber phase has run
1033410333
if (vnStore != nullptr)
1033510334
{
1033610335
// Update the ValueNumber for 'cns2', as we just changed it to 0
1033710336
fgValueNumberTreeConst(cns2);
10338-
// Restore the old ValueNumber for 'tree' as the new expr
10339-
// will still compute the same value as before
10340-
tree->gtVNPair = vnp;
1034110337
}
1034210338

1034310339
op2 = tree->gtOp.gtOp2 = gtFoldExpr(op2);
@@ -10776,7 +10772,8 @@ CM_OVF_OP :
1077610772

1077710773
size_t abs_mult = (mult >= 0) ? mult : -mult;
1077810774
size_t lowestBit = genFindLowestBit(abs_mult);
10779-
10775+
bool changeToShift = false;
10776+
1078010777
// is it a power of two? (positive or negative)
1078110778
if (abs_mult == lowestBit)
1078210779
{
@@ -10811,9 +10808,7 @@ CM_OVF_OP :
1081110808

1081210809
/* Change the multiplication into a shift by log2(val) bits */
1081310810
op2->gtIntConCommon.SetIconValue(genLog2(abs_mult));
10814-
oper = GT_LSH;
10815-
tree->ChangeOper(oper);
10816-
goto DONE_MORPHING_CHILDREN;
10811+
changeToShift = true;
1081710812
}
1081810813
#if LEA_AVAILABLE
1081910814
else if ((lowestBit > 1) && jitIsScaleIndexMul(lowestBit) && optAvoidIntMult())
@@ -10841,11 +10836,24 @@ CM_OVF_OP :
1084110836
fgMorphTreeDone(op1);
1084210837

1084310838
op2->gtIntConCommon.SetIconValue(shift);
10844-
oper = GT_LSH;
10845-
tree->ChangeOper(oper);
10839+
changeToShift = true;
10840+
}
10841+
}
1084610842

10847-
goto DONE_MORPHING_CHILDREN;
10843+
if (changeToShift)
10844+
{
10845+
// vnStore is null before the ValueNumber phase has run
10846+
if (vnStore != nullptr)
10847+
{
10848+
// Update the ValueNumber for 'op2', as we just changed the constant
10849+
fgValueNumberTreeConst(op2);
1084810850
}
10851+
oper = GT_LSH;
10852+
// Keep the old ValueNumber for 'tree' as the new expr
10853+
// will still compute the same value as before
10854+
tree->ChangeOper(oper, GenTree::PRESERVE_VN);
10855+
10856+
goto DONE_MORPHING_CHILDREN;
1084910857
}
1085010858
#endif // LEA_AVAILABLE
1085110859
}

0 commit comments

Comments
 (0)