44 #define DEBUG_TYPE "reassociate"
46 STATISTIC(NumChanged,
"Number of insts reassociated");
47 STATISTIC(NumAnnihil,
"Number of expr tree annihilated");
48 STATISTIC(NumFactor ,
"Number of multiplies factored");
54 ValueEntry(
unsigned R,
Value *O) : Rank(R), Op(O) {}
56 inline bool operator<(
const ValueEntry &LHS,
const ValueEntry &RHS) {
57 return LHS.Rank > RHS.Rank;
67 << *Ops[0].Op->getType() <<
'\t';
68 for (
unsigned i = 0, e = Ops.
size(); i != e; ++i) {
70 Ops[i].Op->printAsOperand(
dbgs(),
false, M);
71 dbgs() <<
", #" << Ops[i].Rank <<
"] ";
83 Factor(
Value *Base,
unsigned Power) : Base(Base), Power(Power) {}
87 bool operator()(
const Factor &LHS,
const Factor &RHS) {
88 return LHS.Base < RHS.Base;
94 bool operator()(
const Factor &LHS,
const Factor &RHS) {
95 return LHS.Base == RHS.Base;
100 struct PowerDescendingSorter {
101 bool operator()(
const Factor &LHS,
const Factor &RHS) {
102 return LHS.Power > RHS.Power;
108 bool operator()(
const Factor &LHS,
const Factor &RHS) {
109 return LHS.Power == RHS.Power;
126 bool isInvalid()
const {
return SymbolicPart ==
nullptr; }
127 bool isOrExpr()
const {
return isOr; }
128 Value *getValue()
const {
return OrigVal; }
129 Value *getSymbolicPart()
const {
return SymbolicPart; }
130 unsigned getSymbolicRank()
const {
return SymbolicRank; }
131 const APInt &getConstPart()
const {
return ConstPart; }
133 void Invalidate() { SymbolicPart = OrigVal =
nullptr; }
134 void setSymbolicRank(
unsigned R) { SymbolicRank = R; }
145 struct PtrSortFunctor {
146 bool operator()(XorOpnd *
const &LHS, XorOpnd *
const &RHS) {
147 return LHS->getSymbolicRank() < RHS->getSymbolicRank();
154 unsigned SymbolicRank;
171 bool runOnFunction(
Function &
F)
override;
178 unsigned getRank(
Value *V);
188 bool CombineXorOpnd(
Instruction *
I, XorOpnd *Opnd1, XorOpnd *Opnd2,
202 XorOpnd::XorOpnd(
Value *V) {
203 assert(!isa<ConstantInt>(V) &&
"No ConstantInt");
212 if (isa<ConstantInt>(V0))
216 ConstPart =
C->getValue();
231 "Reassociate expressions",
false,
false)
239 if (V->
hasOneUse() && isa<Instruction>(V) &&
240 cast<Instruction>(V)->getOpcode() == Opcode &&
241 (!isa<FPMathOperator>(V) ||
242 cast<Instruction>(V)->hasUnsafeAlgebra()))
243 return cast<BinaryOperator>(V);
249 if (V->
hasOneUse() && isa<Instruction>(V) &&
250 (cast<Instruction>(V)->getOpcode() == Opcode1 ||
251 cast<Instruction>(V)->getOpcode() == Opcode2) &&
252 (!isa<FPMathOperator>(V) ||
253 cast<Instruction>(V)->hasUnsafeAlgebra()))
254 return cast<BinaryOperator>(V);
261 case Instruction::LandingPad:
262 case Instruction::Alloca:
264 case Instruction::Invoke:
265 case Instruction::UDiv:
266 case Instruction::SDiv:
267 case Instruction::FDiv:
268 case Instruction::URem:
269 case Instruction::SRem:
270 case Instruction::FRem:
273 return !isa<DbgInfoIntrinsic>(
I);
279 void Reassociate::BuildRankMap(
Function &
F) {
284 ValueRankMap[&*
I] = ++i;
290 E = RPOT.end(); I != E; ++
I) {
292 unsigned BBRank = RankMap[BB] = ++i << 16;
299 ValueRankMap[&*I] = ++BBRank;
303 unsigned Reassociate::getRank(
Value *V) {
306 if (isa<Argument>(V))
return ValueRankMap[V];
310 if (
unsigned Rank = ValueRankMap[I])
317 unsigned Rank = 0, MaxRank = RankMap[I->getParent()];
318 for (
unsigned i = 0, e = I->getNumOperands();
319 i != e && Rank != MaxRank; ++i)
320 Rank = std::max(Rank, getRank(I->getOperand(i)));
328 DEBUG(
dbgs() <<
"Calculated Rank[" << V->
getName() <<
"] = " << Rank <<
"\n");
330 return ValueRankMap[
I] = Rank;
334 void Reassociate::canonicalizeOperands(
Instruction *I) {
335 assert(isa<BinaryOperator>(I) &&
"Expected binary operator.");
336 assert(I->
isCommutative() &&
"Expected commutative operator.");
340 unsigned LHSRank = getRank(LHS);
341 unsigned RHSRank = getRank(RHS);
343 if (isa<Constant>(RHS))
346 if (isa<Constant>(LHS) || RHSRank < LHSRank)
347 cast<BinaryOperator>(
I)->swapOperands();
356 BinaryOperator::CreateFAdd(S1, S2, Name, InsertBefore);
368 BinaryOperator::CreateFMul(S1, S2, Name, InsertBefore);
394 Neg->replaceAllUsesWith(Res);
439 assert(LHS == 1 && RHS == 1 &&
"Weights not reduced!");
444 assert(LHS == 1 && RHS == 1 &&
"Weights not reduced!");
448 if (Opcode == Instruction::Add || Opcode == Instruction::FAdd) {
454 assert((Opcode == Instruction::Mul || Opcode == Instruction::FMul) &&
455 "Unknown associative operation!");
471 assert(LHS.
ult(Threshold) && RHS.
ult(Threshold) &&
"Weights not reduced!");
474 while (LHS.uge(Threshold))
482 "Weights not reduced!");
484 while (Total >= Threshold)
568 DEBUG(
dbgs() <<
"LINEARIZE: " << *I <<
'\n');
572 "Expected an associative and commutative operation!");
586 bool Changed =
false;
610 while (!Worklist.empty()) {
611 std::pair<BinaryOperator*, APInt>
P = Worklist.pop_back_val();
614 for (
unsigned OpIdx = 0; OpIdx < 2; ++OpIdx) {
616 APInt Weight = P.second;
617 DEBUG(
dbgs() <<
"OPERAND: " << *Op <<
" (" << Weight <<
")\n");
618 assert(!Op->
use_empty() &&
"No uses, so how did we get to it?!");
623 assert(Visited.
insert(Op).second &&
"Not first visit!");
624 DEBUG(
dbgs() <<
"DIRECT ADD: " << *Op <<
" (" << Weight <<
")\n");
625 Worklist.push_back(std::make_pair(BO, Weight));
630 LeafMap::iterator It = Leaves.find(Op);
631 if (It == Leaves.end()) {
633 assert(Visited.
insert(Op).second &&
"Not first visit!");
637 DEBUG(
dbgs() <<
"ADD USES LEAF: " << *Op <<
" (" << Weight <<
")\n");
643 }
else if (It != Leaves.end()) {
645 assert(Visited.
count(Op) &&
"In leaf map but not visited!");
650 #if 0 // TODO: Re-enable once PR13021 is fixed.
653 assert(!Op->
hasOneUse() &&
"Only one use, but we got here twice!");
662 DEBUG(
dbgs() <<
"UNLEAF: " << *Op <<
" (" << It->second <<
")\n");
663 Worklist.push_back(std::make_pair(BO, It->second));
683 assert((!isa<Instruction>(Op) ||
684 cast<Instruction>(Op)->getOpcode() != Opcode
685 || (isa<FPMathOperator>(Op) &&
686 !cast<Instruction>(Op)->hasUnsafeAlgebra())) &&
687 "Should have been handled above!");
688 assert(Op->
hasOneUse() &&
"Has uses outside the expression tree!");
695 DEBUG(
dbgs() <<
"MORPH LEAF: " << *Op <<
" (" << Weight <<
") TO ");
698 Worklist.push_back(std::make_pair(BO, Weight));
705 DEBUG(
dbgs() <<
"ADD LEAF: " << *Op <<
" (" << Weight <<
")\n");
714 for (
unsigned i = 0, e = LeafOrder.
size(); i != e; ++i) {
715 Value *V = LeafOrder[i];
716 LeafMap::iterator It = Leaves.find(V);
717 if (It == Leaves.end())
721 APInt Weight = It->second;
727 Ops.
push_back(std::make_pair(V, Weight));
735 assert(Identity &&
"Associative operation without identity!");
746 assert(Ops.
size() > 1 &&
"Single values should be used directly!");
774 for (
unsigned i = 0, e = Ops.
size(); i != e; ++i)
775 NotRewritable.
insert(Ops[i].Op);
781 for (
unsigned i = 0; ; ++i) {
785 if (i+2 == Ops.
size()) {
786 Value *NewLHS = Ops[i].Op;
787 Value *NewRHS = Ops[i+1].Op;
791 if (NewLHS == OldLHS && NewRHS == OldRHS)
795 if (NewLHS == OldRHS && NewRHS == OldLHS) {
808 if (NewLHS != OldLHS) {
810 if (BO && !NotRewritable.
count(BO))
811 NodesToRewrite.push_back(BO);
814 if (NewRHS != OldRHS) {
816 if (BO && !NotRewritable.
count(BO))
817 NodesToRewrite.push_back(BO);
822 ExpressionChanged = Op;
831 Value *NewRHS = Ops[i].Op;
841 if (BO && !NotRewritable.
count(BO))
842 NodesToRewrite.push_back(BO);
844 ExpressionChanged = Op;
855 if (BO && !NotRewritable.
count(BO)) {
868 if (NodesToRewrite.empty()) {
871 Undef, Undef,
"", I);
872 if (NewOp->getType()->isFPOrFPVectorTy())
875 NewOp = NodesToRewrite.pop_back_val();
881 ExpressionChanged = Op;
891 if (ExpressionChanged)
894 if (isa<FPMathOperator>(I)) {
901 if (ExpressionChanged == I)
904 ExpressionChanged = cast<BinaryOperator>(*ExpressionChanged->
user_begin());
908 for (
unsigned i = 0, e = NodesToRewrite.size(); i != e; ++i)
909 RedoInsts.insert(NodesToRewrite[i]);
917 if (
Constant *C = dyn_cast<Constant>(V)) {
918 if (C->getType()->isFPOrFPVectorTy()) {
939 if (I->
getOpcode() == Instruction::Add) {
971 if (
Instruction *InstInput = dyn_cast<Instruction>(V)) {
972 if (
InvokeInst *II = dyn_cast<InvokeInst>(InstInput)) {
973 InsertPt = II->getNormalDest()->begin();
975 InsertPt = InstInput;
978 while (isa<PHINode>(InsertPt)) ++InsertPt;
983 if (TheNeg->
getOpcode() == Instruction::Sub) {
1042 Sub->replaceAllUsesWith(New);
1043 New->setDebugLoc(Sub->getDebugLoc());
1045 DEBUG(
dbgs() <<
"Negated: " << *New <<
'\n');
1067 bool NSW = cast<BinaryOperator>(Shl)->hasNoSignedWrap();
1068 bool NUW = cast<BinaryOperator>(Shl)->hasNoUnsignedWrap();
1080 unsigned XRank = Ops[i].Rank;
1081 unsigned e = Ops.
size();
1082 for (
unsigned j = i+1; j != e && Ops[j].Rank == XRank; ++j) {
1085 if (
Instruction *I1 = dyn_cast<Instruction>(Ops[j].Op))
1087 if (I1->isIdenticalTo(I2))
1091 for (
unsigned j = i-1; j != ~0U && Ops[j].Rank == XRank; --j) {
1094 if (
Instruction *I1 = dyn_cast<Instruction>(Ops[j].Op))
1096 if (I1->isIdenticalTo(I2))
1106 if (Ops.
size() == 1)
return Ops.
back();
1117 Value *Reassociate::RemoveFactorFromExpression(
Value *V,
Value *Factor) {
1126 for (
unsigned i = 0, e = Tree.
size(); i != e; ++i) {
1128 Factors.
append(E.second.getZExtValue(),
1129 ValueEntry(getRank(E.first), E.first));
1132 bool FoundFactor =
false;
1133 bool NeedsNegate =
false;
1134 for (
unsigned i = 0, e = Factors.
size(); i != e; ++i) {
1135 if (Factors[i].Op == Factor) {
1142 if (
ConstantInt *FC1 = dyn_cast<ConstantInt>(Factor)) {
1143 if (
ConstantInt *FC2 = dyn_cast<ConstantInt>(Factors[i].Op))
1144 if (FC1->getValue() == -FC2->getValue()) {
1145 FoundFactor = NeedsNegate =
true;
1149 }
else if (
ConstantFP *FC1 = dyn_cast<ConstantFP>(Factor)) {
1150 if (
ConstantFP *FC2 = dyn_cast<ConstantFP>(Factors[i].Op)) {
1151 APFloat F1(FC1->getValueAPF());
1152 APFloat F2(FC2->getValueAPF());
1155 FoundFactor = NeedsNegate =
true;
1165 RewriteExprTree(BO, Factors);
1173 if (Factors.
size() == 1) {
1174 RedoInsts.insert(BO);
1177 RewriteExprTree(BO, Factors);
1212 for (
unsigned i = 0, e = Ops.
size(); i != e; ++i) {
1214 assert(i < Ops.
size());
1229 assert(i < Ops.
size());
1230 if (i+1 != Ops.
size() && Ops[i+1].Op == Ops[i].Op) {
1259 const APInt &ConstOpnd) {
1260 if (ConstOpnd != 0) {
1265 "and.ra", InsertBefore);
1281 bool Reassociate::CombineXorOpnd(
Instruction *I, XorOpnd *Opnd1,
1287 if (Opnd1->isOrExpr() && Opnd1->getConstPart() != 0) {
1288 if (!Opnd1->getValue()->hasOneUse())
1291 const APInt &C1 = Opnd1->getConstPart();
1292 if (C1 != ConstOpnd)
1295 Value *
X = Opnd1->getSymbolicPart();
1300 if (
Instruction *
T = dyn_cast<Instruction>(Opnd1->getValue()))
1301 RedoInsts.insert(
T);
1316 bool Reassociate::CombineXorOpnd(
Instruction *I, XorOpnd *Opnd1, XorOpnd *Opnd2,
1318 Value *X = Opnd1->getSymbolicPart();
1319 if (X != Opnd2->getSymbolicPart())
1323 int DeadInstNum = 1;
1324 if (Opnd1->getValue()->hasOneUse())
1326 if (Opnd2->getValue()->hasOneUse())
1335 if (Opnd1->isOrExpr() != Opnd2->isOrExpr()) {
1336 if (Opnd2->isOrExpr())
1339 const APInt &C1 = Opnd1->getConstPart();
1340 const APInt &C2 = Opnd2->getConstPart();
1341 APInt C3((~C1) ^ C2);
1344 if (C3 != 0 && !C3.isAllOnesValue()) {
1345 int NewInstNum = ConstOpnd != 0 ? 1 : 2;
1346 if (NewInstNum > DeadInstNum)
1353 }
else if (Opnd1->isOrExpr()) {
1356 const APInt &C1 = Opnd1->getConstPart();
1357 const APInt &C2 = Opnd2->getConstPart();
1362 int NewInstNum = ConstOpnd != 0 ? 1 : 2;
1363 if (NewInstNum > DeadInstNum)
1372 const APInt &C1 = Opnd1->getConstPart();
1373 const APInt &C2 = Opnd2->getConstPart();
1380 if (
Instruction *
T = dyn_cast<Instruction>(Opnd1->getValue()))
1381 RedoInsts.insert(
T);
1382 if (
Instruction *
T = dyn_cast<Instruction>(Opnd2->getValue()))
1383 RedoInsts.insert(
T);
1396 if (Ops.
size() == 1)
1401 Type *Ty = Ops[0].Op->getType();
1405 for (
unsigned i = 0, e = Ops.
size(); i != e; ++i) {
1406 Value *V = Ops[i].Op;
1407 if (!isa<ConstantInt>(V)) {
1409 O.setSymbolicRank(getRank(O.getSymbolicPart()));
1412 ConstOpnd ^= cast<ConstantInt>(V)->getValue();
1420 for (
unsigned i = 0, e = Opnds.
size(); i != e; ++i)
1427 std::stable_sort(OpndPtrs.
begin(), OpndPtrs.
end(), XorOpnd::PtrSortFunctor());
1430 XorOpnd *PrevOpnd =
nullptr;
1431 bool Changed =
false;
1432 for (
unsigned i = 0, e = Opnds.
size(); i < e; i++) {
1433 XorOpnd *CurrOpnd = OpndPtrs[i];
1438 if (ConstOpnd != 0 && CombineXorOpnd(I, CurrOpnd, ConstOpnd, CV)) {
1441 *CurrOpnd = XorOpnd(CV);
1443 CurrOpnd->Invalidate();
1448 if (!PrevOpnd || CurrOpnd->getSymbolicPart() != PrevOpnd->getSymbolicPart()) {
1449 PrevOpnd = CurrOpnd;
1456 if (CombineXorOpnd(I, CurrOpnd, PrevOpnd, ConstOpnd, CV)) {
1458 PrevOpnd->Invalidate();
1460 *CurrOpnd = XorOpnd(CV);
1461 PrevOpnd = CurrOpnd;
1463 CurrOpnd->Invalidate();
1473 for (
unsigned int i = 0, e = Opnds.
size(); i < e; i++) {
1474 XorOpnd &O = Opnds[i];
1477 ValueEntry VE(getRank(O.getValue()), O.getValue());
1480 if (ConstOpnd != 0) {
1482 ValueEntry VE(getRank(C), C);
1485 int Sz = Ops.
size();
1487 return Ops.
back().Op;
1489 assert(ConstOpnd == 0);
1507 for (
unsigned i = 0, e = Ops.
size(); i != e; ++i) {
1508 Value *TheOp = Ops[i].Op;
1512 if (i+1 != Ops.
size() && Ops[i+1].Op == TheOp) {
1514 unsigned NumFound = 0;
1518 }
while (i != Ops.
size() && Ops[i].Op == TheOp);
1520 DEBUG(
dbgs() <<
"\nFACTORING [" << NumFound <<
"]: " << *TheOp <<
'\n');
1532 RedoInsts.insert(Mul);
1541 Ops.
insert(Ops.
begin(), ValueEntry(getRank(Mul), Mul));
1564 if (Ops.
size() == 2 &&
1585 Ops.
insert(Ops.
end(), ValueEntry(getRank(V), V));
1599 unsigned MaxOcc = 0;
1600 Value *MaxOccVal =
nullptr;
1601 for (
unsigned i = 0, e = Ops.
size(); i != e; ++i) {
1610 assert(Factors.
size() > 1 &&
"Bad linearize!");
1614 for (
unsigned i = 0, e = Factors.
size(); i != e; ++i) {
1615 Value *Factor = Factors[i];
1616 if (!Duplicates.insert(Factor).second)
1619 unsigned Occ = ++FactorOccurrences[Factor];
1628 if (
ConstantInt *CI = dyn_cast<ConstantInt>(Factor)) {
1629 if (CI->isNegative() && !CI->isMinValue(
true)) {
1631 assert(!Duplicates.count(Factor) &&
1632 "Shouldn't have two constant factors, missed a canonicalize");
1633 unsigned Occ = ++FactorOccurrences[Factor];
1639 }
else if (
ConstantFP *CF = dyn_cast<ConstantFP>(Factor)) {
1640 if (CF->isNegative()) {
1644 assert(!Duplicates.count(Factor) &&
1645 "Shouldn't have two constant factors, missed a canonicalize");
1646 unsigned Occ = ++FactorOccurrences[Factor];
1658 DEBUG(
dbgs() <<
"\nFACTORING [" << MaxOcc <<
"]: " << *MaxOccVal <<
'\n');
1671 for (
unsigned i = 0; i != Ops.
size(); ++i) {
1678 if (
Value *V = RemoveFactorFromExpression(Ops[i].Op, MaxOccVal)) {
1681 for (
unsigned j = Ops.
size(); j != i;) {
1683 if (Ops[j].Op == Ops[i].Op) {
1695 unsigned NumAddedValues = NewMulOps.
size();
1701 assert(NumAddedValues > 1 &&
"Each occurrence should contribute a value");
1702 (void)NumAddedValues;
1704 RedoInsts.insert(
VI);
1711 RedoInsts.insert(V2);
1721 Ops.
insert(Ops.
begin(), ValueEntry(getRank(V2), V2));
1742 unsigned FactorPowerSum = 0;
1743 for (
unsigned Idx = 1, Size = Ops.
size(); Idx < Size; ++Idx) {
1744 Value *Op = Ops[Idx-1].Op;
1748 for (; Idx < Size && Ops[Idx].Op == Op; ++Idx)
1752 FactorPowerSum += Count;
1759 if (FactorPowerSum < 4)
1764 for (
unsigned Idx = 1; Idx < Ops.
size(); ++Idx) {
1765 Value *Op = Ops[Idx-1].Op;
1769 for (; Idx < Ops.
size() && Ops[Idx].Op == Op; ++Idx)
1776 FactorPowerSum += Count;
1783 assert(FactorPowerSum >= 4);
1785 std::stable_sort(Factors.
begin(), Factors.
end(), Factor::PowerDescendingSorter());
1792 if (Ops.
size() == 1)
1801 }
while (!Ops.
empty());
1814 assert(Factors[0].Power);
1816 for (
unsigned LastIdx = 0, Idx = 1, Size = Factors.
size();
1817 Idx < Size && Factors[Idx].Power > 0; ++Idx) {
1818 if (Factors[Idx].Power != Factors[LastIdx].Power) {
1827 InnerProduct.
push_back(Factors[LastIdx].Base);
1829 InnerProduct.
push_back(Factors[Idx].Base);
1831 }
while (Idx < Size && Factors[Idx].Power == Factors[LastIdx].Power);
1837 RedoInsts.insert(
MI);
1844 Factor::PowerEqual()),
1850 for (
unsigned Idx = 0, Size = Factors.
size(); Idx != Size; ++Idx) {
1851 if (Factors[Idx].Power & 1)
1852 OuterProduct.
push_back(Factors[Idx].Base);
1853 Factors[Idx].Power >>= 1;
1855 if (Factors[0].Power) {
1856 Value *SquareRoot = buildMinimalMultiplyDAG(Builder, Factors);
1860 if (OuterProduct.
size() == 1)
1861 return OuterProduct.
front();
1878 if (!collectMultiplyFactors(Ops, Factors))
1882 Value *V = buildMinimalMultiplyDAG(Builder, Factors);
1886 ValueEntry NewEntry = ValueEntry(getRank(V), V);
1887 Ops.
insert(std::lower_bound(Ops.
begin(), Ops.
end(), NewEntry), NewEntry);
1897 while (!Ops.
empty() && isa<Constant>(Ops.
back().Op)) {
1914 if (Ops.
size() == 1)
return Ops[0].Op;
1918 unsigned NumOps = Ops.
size();
1928 if (
Value *Result = OptimizeXor(I, Ops))
1932 case Instruction::Add:
1933 case Instruction::FAdd:
1934 if (
Value *Result = OptimizeAdd(I, Ops))
1938 case Instruction::Mul:
1939 case Instruction::FMul:
1940 if (
Value *Result = OptimizeMul(I, Ops))
1945 if (Ops.
size() != NumOps)
1946 return OptimizeExpression(I, Ops);
1955 ValueRankMap.
erase(I);
1956 RedoInsts.remove(I);
1960 for (
unsigned i = 0, e = Ops.
size(); i != e; ++i)
1961 if (
Instruction *Op = dyn_cast<Instruction>(Ops[i])) {
1964 unsigned Opcode = Op->getOpcode();
1966 Visited.
insert(Op).second)
1968 RedoInsts.insert(Op);
1981 if (Opcode != Instruction::FMul && Opcode != Instruction::FDiv)
2006 unsigned UserOpcode = User->
getOpcode();
2007 if (UserOpcode != Instruction::FAdd && UserOpcode != Instruction::FSub)
2023 cast<BinaryOperator>(User)->swapOperands();
2028 switch (UserOpcode) {
2031 case Instruction::FAdd:
2032 NI = BinaryOperator::CreateFSub(Op0, Op1);
2035 case Instruction::FSub:
2036 NI = BinaryOperator::CreateFAdd(Op0, Op1);
2045 RedoInsts.insert(I);
2054 if (!isa<BinaryOperator>(I))
2065 RedoInsts.insert(I);
2071 if (
Instruction *Res = canonicalizeNegConstExpr(I))
2078 canonicalizeOperands(I);
2100 if (I->
getOpcode() == Instruction::Sub) {
2103 RedoInsts.insert(I);
2113 RedoInsts.insert(I);
2118 }
else if (I->
getOpcode() == Instruction::FSub) {
2121 RedoInsts.insert(I);
2131 RedoInsts.insert(I);
2151 cast<Instruction>(BO->
user_back())->getOpcode() == Instruction::Sub)
2154 cast<Instruction>(BO->
user_back())->getOpcode() == Instruction::FSub)
2157 ReassociateExpression(BO);
2167 for (
unsigned i = 0, e = Tree.
size(); i != e; ++i) {
2169 Ops.
append(E.second.getZExtValue(),
2170 ValueEntry(getRank(E.first), E.first));
2181 std::stable_sort(Ops.
begin(), Ops.
end());
2185 if (
Value *V = OptimizeExpression(I, Ops)) {
2191 DEBUG(
dbgs() <<
"Reassoc to scalar: " << *V <<
'\n');
2195 RedoInsts.insert(I);
2205 if (I->
getOpcode() == Instruction::Mul &&
2206 cast<Instruction>(I->
user_back())->getOpcode() == Instruction::Add &&
2207 isa<ConstantInt>(Ops.
back().Op) &&
2208 cast<ConstantInt>(Ops.
back().Op)->isAllOnesValue()) {
2211 }
else if (I->
getOpcode() == Instruction::FMul &&
2212 cast<Instruction>(I->
user_back())->getOpcode() ==
2213 Instruction::FAdd &&
2214 isa<ConstantFP>(Ops.
back().Op) &&
2215 cast<ConstantFP>(Ops.
back().Op)->isExactlyValue(-1.0)) {
2223 if (Ops.
size() == 1) {
2231 if (
Instruction *OI = dyn_cast<Instruction>(Ops[0].Op))
2233 RedoInsts.insert(I);
2239 RewriteExprTree(I, Ops);
2242 bool Reassociate::runOnFunction(
Function &F) {
2243 if (skipOptnoneFunction(F))
2257 assert(II->getParent() == BI &&
"Moved to a different block!");
2262 while (!RedoInsts.empty()) {
2273 ValueRankMap.clear();
bool isNilpotent() const
isNilpotent - Return true if the instruction is nilpotent:
iplist< Instruction >::iterator eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing basic block and deletes it...
void push_back(const T &Elt)
void setHasNoSignedWrap(bool b=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag...
void setFastMathFlags(FastMathFlags FMF)
Convenience function for setting multiple fast-math flags on this instruction, which must be an opera...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
uint64_t getZExtValue() const
Get zero extended value.
STATISTIC(NumFunctions,"Total number of functions")
static BinaryOperator * LowerNegateToMultiply(Instruction *Neg)
Replace 0-X with X*-1.
A Module instance is used to store all the information related to an LLVM module. ...
static Constant * getBinOpIdentity(unsigned Opcode, Type *Ty)
getBinOpIdentity - Return the identity for the given binary operation, i.e.
size_type count(PtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
FastMathFlags getFastMathFlags() const
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
const Function * getParent() const
Return the enclosing method, or null if none.
void reserve(size_type N)
static void FindSingleUseMultiplyFactors(Value *V, SmallVectorImpl< Value * > &Factors, const SmallVectorImpl< ValueEntry > &Ops)
If V is a single-use multiply, recursively add its operands as factors, otherwise add V to the list o...
static Constant * getNullValue(Type *Ty)
StringRef getName() const
Return a constant reference to the value's name.
iterator begin()
Instruction iterator methods.
bool swapOperands()
Exchange the two operands to this instruction.
static const Value * getNegArgument(const Value *BinOp)
Helper functions to extract the unary argument of a NEG, FNEG or NOT operation implemented via Sub...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void setHasNoUnsignedWrap(bool b=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
static bool isUnmovableInstruction(Instruction *I)
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
FunctionPass * createReassociatePass()
void setName(const Twine &Name)
Change the name of the value.
static Constant * get(unsigned Opcode, Constant *C1, Constant *C2, unsigned Flags=0, Type *OnlyIfReducedTy=nullptr)
get - Return a binary or shift operator constant expression, folding if possible. ...
static Value * OptimizeAndOrXor(unsigned Opcode, SmallVectorImpl< ValueEntry > &Ops)
Optimize a series of operands to an 'and', 'or', or 'xor' instruction.
LLVMContext & getContext() const
getContext - Return the LLVMContext in which this type was uniqued.
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
std::pair< Value *, APInt > RepeatedValue
bool isAssociative() const
isAssociative - Return true if the instruction is associative:
bool hasUnsafeAlgebra() const
Determine whether the unsafe-algebra flag is set.
static Value * createAndInstr(Instruction *InsertBefore, Value *Opnd, const APInt &ConstOpnd)
Helper funciton of CombineXorOpnd().
bool isFloatingPointTy() const
isFloatingPointTy - Return true if this is one of the six floating point types
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
void takeName(Value *V)
Transfer the name from V to this value.
const char * getOpcodeName() const
static BinaryOperator * CreateAdd(Value *S1, Value *S2, const Twine &Name, Instruction *InsertBefore, Value *FlagsOp)
static const Value * getNotArgument(const Value *BinOp)
bool ult(const APInt &RHS) const
Unsigned less than comparison.
A self-contained host- and target-independent arbitrary-precision floating-point software implementat...
bool isIntOrIntVectorTy() const
isIntOrIntVectorTy - Return true if this is an integer type or a vector of integer types...
static Constant * getFNeg(Constant *C)
static Value * buildMultiplyTree(IRBuilder<> &Builder, SmallVectorImpl< Value * > &Ops)
Build a tree of multiplies, computing the product of Ops.
void setDebugLoc(DebugLoc Loc)
setDebugLoc - Set the debug location information for this instruction.
void insertBefore(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified instruction...
INITIALIZE_PASS(Reassociate,"reassociate","Reassociate expressions", false, false) FunctionPass *llvm
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
This is an important class for using LLVM in a threaded context.
bool isVectorTy() const
isVectorTy - True if this is an instance of VectorType.
This is an important base class in LLVM.
static Value * NegateValue(Value *V, Instruction *BI)
Insert instructions before the instruction pointed to by BI, that computes the negative version of th...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
APInt Or(const APInt &LHS, const APInt &RHS)
Bitwise OR function for APInt.
static Value * EmitAddTreeOfValues(Instruction *I, SmallVectorImpl< WeakVH > &Ops)
Emit a tree of add instructions, summing Ops together and returning the result.
ConstantFP - Floating Point Values [float, double].
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
APInt Xor(const APInt &LHS, const APInt &RHS)
Bitwise XOR function for APInt.
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
const DebugLoc & getDebugLoc() const
getDebugLoc - Return the debug location for this node as a DebugLoc.
Represent the analysis usage information of a pass.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
unsigned getBitWidth() const
Return the number of bits in the APInt.
FunctionPass class - This class is used to implement most global optimizations.
Value * getOperand(unsigned i) const
bool isCommutative() const
isCommutative - Return true if the instruction is commutative:
static bool isNot(const Value *V)
static Constant * getAllOnesValue(Type *Ty)
Get the all ones value.
NUW NUW NUW NUW Exact static Exact BinaryOperator * CreateNeg(Value *Op, const Twine &Name="", Instruction *InsertBefore=nullptr)
Helper functions to construct and inspect unary operations (NEG and NOT) via binary operators SUB and...
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
static UndefValue * get(Type *T)
get() - Static factory methods - Return an 'undef' object of the specified type.
void andIRFlags(const Value *V)
Logical 'and' of any supported wrapping, exact, and fast-math flags of V and this instruction...
iterator erase(iterator I)
LLVMContext & getContext() const
All values hold a context through their type.
static unsigned CarmichaelShift(unsigned Bitwidth)
Returns k such that lambda(2^Bitwidth) = 2^k, where lambda is the Carmichael function.
std::vector< NodeType * >::reverse_iterator rpo_iterator
BinaryOps getOpcode() const
static BinaryOperator * CreateFNeg(Value *Op, const Twine &Name="", Instruction *InsertBefore=nullptr)
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
unsigned getIntegerBitWidth() const
This is the shared class of boolean and integer constants.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Type * getType() const
All values are typed, get the type of this value.
Instruction * user_back()
user_back - Specialize the methods defined in Value, as we know that an instruction can only be used ...
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
const BasicBlock & getEntryBlock() const
static Constant * get(Type *Ty, double V)
get() - This returns a ConstantFP, or a vector containing a splat of a ConstantFP, for the specified value in the specified type.
void setOperand(unsigned i, Value *Val)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
void initializeReassociatePass(PassRegistry &)
static bool isNeg(const Value *V)
Check if the given Value is a NEG, FNeg, or NOT instruction.
Class for arbitrary precision integers.
bool isIntegerTy() const
isIntegerTy - True if this is an instance of IntegerType.
static BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), Instruction *InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
iterator_range< user_iterator > users()
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
iterator insert(iterator I, T &&Elt)
bool isMinValue() const
Determine if this is the smallest unsigned value.
const Type * getScalarType() const LLVM_READONLY
getScalarType - If this is a vector type, return the element type, otherwise return 'this'...
APInt And(const APInt &LHS, const APInt &RHS)
Bitwise AND function for APInt.
static Constant * getNeg(Constant *C, bool HasNUW=false, bool HasNSW=false)
bool isAllOnesValue() const
Determine if all bits are set.
bool isNegative() const
isNegative - Return true if the sign bit is set.
void emplace_back(ArgTypes &&...Args)
static BinaryOperator * BreakUpSubtract(Instruction *Sub)
If we have (X-Y), and if either X is an add, or if this is only used by an add, transform this into (...
static bool isFNeg(const Value *V, bool IgnoreZeroSign=false)
bool isIdempotent() const
isIdempotent - Return true if the instruction is idempotent:
static void PrintOps(Instruction *I, const SmallVectorImpl< ValueEntry > &Ops)
Print out the expression identified in the Ops list.
static void IncorporateWeight(APInt &LHS, const APInt &RHS, unsigned Opcode)
Add the extra weight 'RHS' to the existing weight 'LHS', reducing the combined weight using any speci...
bool hasOneUse() const
Return true if there is exactly one user of this value.
static Constant * getShl(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static BinaryOperator * CreateNeg(Value *S1, const Twine &Name, Instruction *InsertBefore, Value *FlagsOp)
bool hasNUsesOrMore(unsigned N) const
Return true if this value has N users or more.
const APFloat & getValueAPF() const
static int const Threshold
TODO: Write a new FunctionPass AliasAnalysis so that it can keep a cache.
Value * CreateFMul(Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
static BinaryOperator * ConvertShiftToMul(Instruction *Shl)
If this is a shift of a reassociable multiply or is used by one, change this into a multiply by a con...
user_iterator user_begin()
bool operator<(int64_t V1, const APSInt &V2)
unsigned getPrimitiveSizeInBits() const LLVM_READONLY
getPrimitiveSizeInBits - Return the basic size of this type if it is a primitive type.
Module * getParent()
Get the module that this global value is contained inside of...
bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
isInstructionTriviallyDead - Return true if the result produced by the instruction is not used...
LLVM Value Representation.
static unsigned FindInOperandList(SmallVectorImpl< ValueEntry > &Ops, unsigned i, Value *X)
Scan backwards and forwards among values with the same rank as element i to see if X exists...
unsigned getOpcode() const
getOpcode() returns a member of one of the enums like Instruction::Add.
A vector that has set insertion semantics.
void clearSubclassOptionalData()
Clear the optional flags contained in this value.
void moveBefore(Instruction *MovePos)
moveBefore - Unlink this instruction from its current basic block and insert it into the basic block ...
static BinaryOperator * isReassociableOp(Value *V, unsigned Opcode)
Return true if V is an instruction of the specified opcode and if it only has one use...
InvokeInst - Invoke instruction.
C - The default llvm calling convention, compatible with C.
Convenience struct for specifying and reasoning about fast-math flags.
static bool ShouldBreakUpSubtract(Instruction *Sub)
Return true if we should break up this subtract of X-Y into (X + -Y).
static APInt getNullValue(unsigned numBits)
Get the '0' value.
static BinaryOperator * CreateMul(Value *S1, Value *S2, const Twine &Name, Instruction *InsertBefore, Value *FlagsOp)
static Constant * getBinOpAbsorber(unsigned Opcode, Type *Ty)
getBinOpAbsorber - Return the absorbing element for the given binary operation, i.e.
static bool LinearizeExprTree(BinaryOperator *I, SmallVectorImpl< RepeatedValue > &Ops)
Given an associative binary expression, return the leaf nodes in Ops along with their weights (how ma...
const BasicBlock * getParent() const