68#define DEBUG_TYPE "reassociate"
70STATISTIC(NumChanged,
"Number of insts reassociated");
71STATISTIC(NumAnnihil,
"Number of expr tree annihilated");
72STATISTIC(NumFactor ,
"Number of multiplies factored");
76 cl::desc(
"Only reorder expressions within a basic block "
77 "when exposing CSE opportunities"),
85 << *
Ops[0].Op->getType() <<
'\t';
88 Op.Op->printAsOperand(
dbgs(),
false, M);
89 dbgs() <<
", #" <<
Op.Rank <<
"] ";
106 bool isInvalid()
const {
return SymbolicPart ==
nullptr; }
120 unsigned SymbolicRank;
130 if (
I && (
I->getOpcode() == Instruction::Or ||
131 I->getOpcode() == Instruction::And)) {
132 Value *V0 =
I->getOperand(0);
141 isOr = (
I->getOpcode() == Instruction::Or);
158 return I->hasAllowReassoc() &&
I->hasNoSignedZeros();
165 if (BO && BO->hasOneUse() && BO->getOpcode() == Opcode)
174 if (BO && BO->hasOneUse() &&
175 (BO->getOpcode() == Opcode1 || BO->getOpcode() == Opcode2))
191 if (!
FAdd || !
FAdd->hasAllowContract())
198 Value *OtherOp =
nullptr;
203 match(OtherOp, ContractableFMul(OtherMul)))
208void ReassociatePass::BuildRankMap(
Function &
F,
209 ReversePostOrderTraversal<Function*> &RPOT) {
213 for (
auto &Arg :
F.args()) {
214 ValueRankMap[&Arg] = ++Rank;
215 LLVM_DEBUG(
dbgs() <<
"Calculated Rank[" << Arg.getName() <<
"] = " << Rank
220 for (BasicBlock *BB : RPOT) {
221 unsigned BBRank = RankMap[BB] = ++Rank << 16;
226 for (Instruction &
I : *BB)
228 ValueRankMap[&
I] = ++BBRank;
232unsigned ReassociatePass::getRank(
Value *V) {
236 struct RankWorkItem {
248 RankWorkItem &Item = Worklist.
back();
254 }
else if (ValueRankMap[
I]) {
256 Rank = ValueRankMap[
I];
257 }
else if (Item.OpNo ==
I->getNumOperands() ||
258 Item.Rank == RankMap[
I->getParent()]) {
267 LLVM_DEBUG(
dbgs() <<
"Calculated Rank[" <<
I->getName() <<
"] = " << Rank
270 ValueRankMap[
I] = Rank;
272 Worklist.
push_back(RankWorkItem{
I->getOperand(Item.OpNo), 0, 0});
279 if (Worklist.
empty())
282 RankWorkItem &Parent = Worklist.
back();
283 Parent.Rank = std::max(Parent.Rank, Rank);
289void ReassociatePass::canonicalizeOperands(Instruction *
I) {
291 assert(
I->isCommutative() &&
"Expected commutative operator.");
306 if (
S1->getType()->isIntOrIntVectorTy())
307 return BinaryOperator::CreateAdd(
S1, S2, Name, InsertBefore);
310 BinaryOperator::CreateFAdd(
S1, S2, Name, InsertBefore);
319 if (
S1->getType()->isIntOrIntVectorTy())
320 return BinaryOperator::CreateMul(
S1, S2, Name, InsertBefore);
323 BinaryOperator::CreateFMul(
S1, S2, Name, InsertBefore);
332 if (
S1->getType()->isIntOrIntVectorTy())
338 return UnaryOperator::CreateFNeg(
S1, Name, InsertBefore);
344 "Expected a Negate!");
348 Constant *NegOne = Ty->isIntOrIntVectorTy() ?
440 "Expected a UnaryOperator or BinaryOperator!");
442 unsigned Opcode =
I->getOpcode();
443 assert(
I->isAssociative() &&
I->isCommutative() &&
444 "Expected an associative and commutative operation!");
483 while (!Worklist.
empty()) {
487 Flags.mergeFlags(*
I);
489 for (
unsigned OpIdx = 0; OpIdx <
I->getNumOperands(); ++OpIdx) {
492 assert((!
Op->hasUseList() || !
Op->use_empty()) &&
493 "No uses, so how did we get to it?!");
501 Worklist.
push_back(std::make_pair(BO, Weight));
506 LeafMap::iterator It = Leaves.find(
Op);
507 if (It == Leaves.end()) {
510 if (!
Op->hasOneUse()) {
514 <<
"ADD USES LEAF: " << *
Op <<
" (" << Weight <<
")\n");
523 "In leaf map but not visited!");
526 It->second += Weight;
527 assert(It->second >= Weight &&
"Weight overflows");
531 if (!
Op->hasOneUse())
548 "Should have been handled above!");
549 assert(
Op->hasOneUse() &&
"Has uses outside the expression tree!");
561 <<
"MORPH LEAF: " << *
Op <<
" (" << Weight <<
") TO ");
578 "Value was morphed?");
586 for (
Value *V : LeafOrder) {
587 LeafMap::iterator It = Leaves.find(V);
588 if (It == Leaves.end())
592 "Shouldn't be a leaf!");
596 Ops.push_back(std::make_pair(V, Weight));
597 if (Opcode == Instruction::Add && Flags.AllKnownNonNegative && Flags.HasNSW)
599 else if (Opcode == Instruction::Mul) {
602 if (Flags.AllKnownNonZero &&
603 (Flags.HasNUW || (Flags.HasNSW && Flags.AllKnownNonNegative))) {
605 if (Flags.HasNSW && Flags.AllKnownNonNegative)
616 assert(Identity &&
"Associative operation without identity!");
617 Ops.emplace_back(Identity, 1);
625void ReassociatePass::RewriteExprTree(BinaryOperator *
I,
626 SmallVectorImpl<ValueEntry> &
Ops,
627 OverflowTracking Flags) {
628 assert(
Ops.size() > 1 &&
"Single values should be used directly!");
642 unsigned Opcode =
I->getOpcode();
643 BinaryOperator *
Op =
I;
655 SmallPtrSet<Value*, 8> NotRewritable;
663 BinaryOperator *ExpressionChangedStart =
nullptr,
664 *ExpressionChangedEnd =
nullptr;
665 for (
unsigned i = 0; ; ++i) {
669 if (i+2 ==
Ops.size()) {
672 Value *OldLHS =
Op->getOperand(0);
673 Value *OldRHS =
Op->getOperand(1);
675 if (NewLHS == OldLHS && NewRHS == OldRHS)
679 if (NewLHS == OldRHS && NewRHS == OldLHS) {
692 if (NewLHS != OldLHS) {
694 if (BO && !NotRewritable.
count(BO))
697 Op->setOperand(0, NewLHS);
699 if (NewRHS != OldRHS) {
701 if (BO && !NotRewritable.
count(BO))
704 Op->setOperand(1, NewRHS);
708 ExpressionChangedStart =
Op;
709 if (!ExpressionChangedEnd)
710 ExpressionChangedEnd =
Op;
720 if (NewRHS !=
Op->getOperand(1)) {
722 if (NewRHS ==
Op->getOperand(0)) {
729 if (BO && !NotRewritable.
count(BO))
732 Op->setOperand(1, NewRHS);
733 ExpressionChangedStart =
Op;
734 if (!ExpressionChangedEnd)
735 ExpressionChangedEnd =
Op;
746 if (BO && !NotRewritable.
count(BO)) {
758 BinaryOperator *NewOp;
759 if (NodesToRewrite.
empty()) {
771 Op->setOperand(0, NewOp);
773 ExpressionChangedStart =
Op;
774 if (!ExpressionChangedEnd)
775 ExpressionChangedEnd =
Op;
785 if (ExpressionChangedStart) {
786 bool ClearFlags =
true;
793 Flags.applyFlags(*ExpressionChangedStart);
797 if (ExpressionChangedStart == ExpressionChangedEnd)
799 if (ExpressionChangedStart ==
I)
802 ExpressionChangedStart->
moveBefore(
I->getIterator());
803 ExpressionChangedStart =
809 RedoInsts.insert_range(NodesToRewrite);
823 Constant *Res =
C->getType()->isFPOrFPVectorTy()
844 if (
I->getOpcode() == Instruction::Add) {
845 I->setHasNoUnsignedWrap(
false);
846 I->setHasNoSignedWrap(
false);
855 I->setName(
I->getName()+
".neg");
878 C->containsUndefOrPoisonElement())
888 auto InsertPtOpt = InstInput->getInsertionPointAfterDef();
891 InsertPt = *InsertPtOpt;
902 if (TheNeg->
getParent() != InsertPt->getParent())
904 TheNeg->
moveBefore(*InsertPt->getParent(), InsertPt);
906 if (TheNeg->
getOpcode() == Instruction::Sub) {
935 auto Enqueue = [&](
Value *V) {
949 while (!Worklist.
empty()) {
953 switch (
I->getOpcode()) {
954 case Instruction::Or:
961 case Instruction::Shl:
962 case Instruction::ZExt:
964 if (!Enqueue(
I->getOperand(0)))
968 case Instruction::Load:
986 for (
auto Op : {Instruction::Add, Instruction::Sub, Instruction::Mul,
1008 Or->getIterator(),
Or);
1009 New->setHasNoSignedWrap();
1010 New->setHasNoUnsignedWrap();
1014 Or->replaceAllUsesWith(New);
1015 New->setDebugLoc(
Or->getDebugLoc());
1017 LLVM_DEBUG(
dbgs() <<
"Converted or into an add: " << *New <<
'\n');
1035 if (MulUser->getOpcode() != Instruction::Add &&
1036 MulUser->getOpcode() != Instruction::Sub)
1039 for (
Value *Sibling : MulUser->operands()) {
1040 if (Sibling ==
Mul || !Sibling->hasOneUse())
1063 "Mul1",
Mul->getIterator());
1064 BinaryOperator *M2 = BinaryOperator::CreateMul(AddSub->getOperand(1), C2,
1065 "Mul2",
Mul->getIterator());
1067 BinaryOperator::CreateAdd(
M1, M2,
"DistAdd",
Mul->getIterator());
1069 Mul->replaceAllUsesWith(Result);
1070 Result->setDebugLoc(
Mul->getDebugLoc());
1100 if (
Sub->hasOneUse() &&
1125 Sub->replaceAllUsesWith(New);
1126 New->setDebugLoc(
Sub->getDebugLoc());
1138 assert(MulCst &&
"Constant folding of immediate constants failed");
1156 if (NSW && (NUW || SA->getValue().ult(
BitWidth - 1)))
1157 Mul->setHasNoSignedWrap(
true);
1158 Mul->setHasNoUnsignedWrap(NUW);
1167 unsigned XRank =
Ops[i].Rank;
1168 unsigned e =
Ops.size();
1169 for (
unsigned j = i+1; j != e &&
Ops[j].Rank == XRank; ++j) {
1174 if (I1->isIdenticalTo(I2))
1178 for (
unsigned j = i-1; j != ~0U &&
Ops[j].Rank == XRank; --j) {
1183 if (I1->isIdenticalTo(I2))
1193 if (
Ops.size() == 1)
return Ops.back();
1197 auto *NewAdd =
CreateAdd(V2,
V1,
"reass.add",
I->getIterator(),
I);
1198 NewAdd->setDebugLoc(
I->getDebugLoc());
1209 BinaryOperator *BO =
isReassociableOp(V, Instruction::Mul, Instruction::FMul);
1214 OverflowTracking
Flags;
1221 bool FoundFactor =
false;
1222 bool NeedsNegate =
false;
1223 for (
unsigned i = 0, e = Factors.
size(); i != e; ++i) {
1233 if (FC1->getValue() == -FC2->getValue()) {
1234 FoundFactor = NeedsNegate =
true;
1240 const APFloat &F1 = FC1->getValueAPF();
1241 APFloat F2(FC2->getValueAPF());
1244 FoundFactor = NeedsNegate =
true;
1254 RewriteExprTree(BO, Factors, Flags);
1262 if (Factors.
size() == 1) {
1263 RedoInsts.insert(BO);
1266 RewriteExprTree(BO, Factors, Flags);
1302 for (
unsigned i = 0, e =
Ops.size(); i != e; ++i) {
1309 if (Opcode == Instruction::And)
1312 if (Opcode == Instruction::Or)
1320 if (i+1 !=
Ops.size() &&
Ops[i+1].Op ==
Ops[i].Op) {
1321 if (Opcode == Instruction::And || Opcode == Instruction::Or) {
1323 Ops.erase(
Ops.begin()+i);
1330 assert(Opcode == Instruction::Xor);
1335 Ops.erase(
Ops.begin()+i,
Ops.begin()+i+2);
1349 const APInt &ConstOpnd) {
1357 Opnd, ConstantInt::get(Opnd->
getType(), ConstOpnd),
"and.ra",
1359 I->setDebugLoc(InsertBefore->getDebugLoc());
1370 APInt &ConstOpnd,
Value *&Res) {
1382 if (C1 != ConstOpnd)
1391 RedoInsts.insert(
T);
1404 XorOpnd *Opnd2, APInt &ConstOpnd,
1411 int DeadInstNum = 1;
1429 APInt C3((~C1) ^ C2);
1432 if (!C3.isZero() && !C3.isAllOnes()) {
1434 if (NewInstNum > DeadInstNum)
1450 if (NewInstNum > DeadInstNum)
1468 RedoInsts.insert(
T);
1470 RedoInsts.insert(
T);
1478Value *ReassociatePass::OptimizeXor(Instruction *
I,
1479 SmallVectorImpl<ValueEntry> &
Ops) {
1483 if (
Ops.size() == 1)
1488 Type *Ty =
Ops[0].Op->getType();
1500 O.setSymbolicRank(getRank(
O.getSymbolicPart()));
1527 return LHS->getSymbolicRank() <
RHS->getSymbolicRank();
1533 for (
unsigned i = 0, e = Opnds.size(); i < e; i++) {
1534 XorOpnd *CurrOpnd = OpndPtrs[i];
1539 if (!ConstOpnd.
isZero() &&
1540 CombineXorOpnd(
I->getIterator(), CurrOpnd, ConstOpnd, CV)) {
1550 if (!PrevOpnd || CurrOpnd->
getSymbolicPart() != PrevOpnd->getSymbolicPart()) {
1551 PrevOpnd = CurrOpnd;
1557 if (CombineXorOpnd(
I->getIterator(), CurrOpnd, PrevOpnd, ConstOpnd, CV)) {
1559 PrevOpnd->Invalidate();
1562 PrevOpnd = CurrOpnd;
1574 for (
const XorOpnd &O : Opnds) {
1580 if (!ConstOpnd.
isZero()) {
1581 Value *
C = ConstantInt::get(Ty, ConstOpnd);
1585 unsigned Sz =
Ops.size();
1587 return Ops.back().Op;
1590 return ConstantInt::get(Ty, ConstOpnd);
1600Value *ReassociatePass::OptimizeAdd(Instruction *
I,
1601 SmallVectorImpl<ValueEntry> &
Ops) {
1607 for (
unsigned i = 0, e =
Ops.size(); i != e; ++i) {
1612 if (i+1 !=
Ops.size() &&
Ops[i+1].Op == TheOp) {
1614 unsigned NumFound = 0;
1616 Ops.erase(
Ops.begin()+i);
1618 }
while (i !=
Ops.size() &&
Ops[i].Op == TheOp);
1620 LLVM_DEBUG(
dbgs() <<
"\nFACTORING [" << NumFound <<
"]: " << *TheOp
1628 ? ConstantInt::get(Ty, NumFound,
false,
1632 Mul->setDebugLoc(
I->getDebugLoc());
1637 RedoInsts.insert(
Mul);
1664 if (
Ops.size() == 2 &&
1672 Ops.erase(
Ops.begin()+i);
1677 Ops.erase(
Ops.begin()+FoundX);
1695 DenseMap<Value*, unsigned> FactorOccurrences;
1699 unsigned MaxOcc = 0;
1700 Value *MaxOccVal =
nullptr;
1707 return Occ > MaxOcc ||
1712 auto CountFactors = [&](BinaryOperator *BOp) {
1714 SmallVector<Value*, 8> Factors;
1716 assert(Factors.
size() > 1 &&
"Bad linearize!");
1719 SmallPtrSet<Value*, 8> Duplicates;
1724 unsigned Occ = ++FactorOccurrences[
Factor];
1725 if (IsBetterFactor(
Factor, MaxOccVal, Occ, MaxOcc)) {
1734 if (CI->isNegative() && !CI->isMinValue(
true)) {
1735 Factor = ConstantInt::get(CI->getContext(), -CI->getValue());
1738 unsigned Occ = ++FactorOccurrences[
Factor];
1739 if (IsBetterFactor(
Factor, MaxOccVal, Occ, MaxOcc)) {
1745 if (CF->isNegative()) {
1748 Factor = ConstantFP::get(CF->getType(),
F);
1751 unsigned Occ = ++FactorOccurrences[
Factor];
1752 if (IsBetterFactor(
Factor, MaxOccVal, Occ, MaxOcc)) {
1766 if (BinaryOperator *BOp =
1779 for (
Value *V : FMulAddCands) {
1782 Ops.emplace_back(getRank(
Op),
Op);
1788 LLVM_DEBUG(
dbgs() <<
"\nFACTORING [" << MaxOcc <<
"]: " << *MaxOccVal
1797 I->getType()->isIntOrIntVectorTy()
1798 ? BinaryOperator::CreateAdd(MaxOccVal, MaxOccVal)
1799 : BinaryOperator::CreateFAdd(MaxOccVal, MaxOccVal);
1802 for (
unsigned i = 0; i !=
Ops.size(); ++i) {
1804 BinaryOperator *BOp =
1809 if (
Value *V = RemoveFactorFromExpression(
Ops[i].
Op, MaxOccVal,
1810 I->getDebugLoc())) {
1813 for (
unsigned j =
Ops.size(); j != i;) {
1817 Ops.erase(
Ops.begin()+j);
1827 unsigned NumAddedValues = NewMulOps.
size();
1833 assert(NumAddedValues > 1 &&
"Each occurrence should contribute a value");
1834 (void)NumAddedValues;
1836 RedoInsts.insert(VI);
1844 RedoInsts.insert(V2);
1875 unsigned FactorPowerSum = 0;
1876 for (
unsigned Idx = 1,
Size =
Ops.size(); Idx <
Size; ++Idx) {
1881 for (; Idx <
Size &&
Ops[Idx].Op ==
Op; ++Idx)
1885 FactorPowerSum +=
Count;
1892 if (FactorPowerSum < 4)
1897 for (
unsigned Idx = 1; Idx <
Ops.size(); ++Idx) {
1902 for (; Idx <
Ops.size() &&
Ops[Idx].
Op ==
Op; ++Idx)
1909 FactorPowerSum +=
Count;
1916 assert(FactorPowerSum >= 4);
1919 return LHS.Power >
RHS.Power;
1927 if (
Ops.size() == 1)
1932 if (
LHS->getType()->isIntOrIntVectorTy())
1933 LHS = Builder.CreateMul(
LHS,
Ops.pop_back_val());
1935 LHS = Builder.CreateFMul(
LHS,
Ops.pop_back_val());
1936 }
while (!
Ops.empty());
1948ReassociatePass::buildMinimalMultiplyDAG(IRBuilderBase &Builder,
1949 SmallVectorImpl<Factor> &Factors) {
1950 assert(Factors[0].Power);
1951 SmallVector<Value *, 4> OuterProduct;
1952 for (
unsigned LastIdx = 0, Idx = 1,
Size = Factors.
size();
1953 Idx <
Size && Factors[Idx].Power > 0; ++Idx) {
1954 if (Factors[Idx].Power != Factors[LastIdx].Power) {
1962 SmallVector<Value *, 4> InnerProduct;
1967 }
while (Idx <
Size && Factors[Idx].Power == Factors[LastIdx].Power);
1973 RedoInsts.insert(
MI);
1981 return LHS.Power ==
RHS.Power;
1993 if (Factors[0].Power) {
1994 Value *SquareRoot = buildMinimalMultiplyDAG(Builder, Factors);
1998 if (OuterProduct.
size() == 1)
1999 return OuterProduct.
front();
2005Value *ReassociatePass::OptimizeMul(BinaryOperator *
I,
2006 SmallVectorImpl<ValueEntry> &
Ops) {
2026 Value *
V = buildMinimalMultiplyDAG(Builder, Factors);
2035Value *ReassociatePass::OptimizeExpression(BinaryOperator *
I,
2036 SmallVectorImpl<ValueEntry> &
Ops) {
2039 const DataLayout &
DL =
I->getDataLayout();
2041 unsigned Opcode =
I->getOpcode();
2042 while (!
Ops.empty()) {
2070 if (
Ops.size() == 1)
return Ops[0].
Op;
2077 case Instruction::And:
2078 case Instruction::Or:
2083 case Instruction::Xor:
2084 if (
Value *Result = OptimizeXor(
I,
Ops))
2088 case Instruction::Add:
2089 case Instruction::FAdd:
2090 if (
Value *Result = OptimizeAdd(
I,
Ops))
2094 case Instruction::Mul:
2095 case Instruction::FMul:
2096 if (
Value *Result = OptimizeMul(
I,
Ops))
2102 return OptimizeExpression(
I,
Ops);
2108void ReassociatePass::RecursivelyEraseDeadInsts(Instruction *
I,
2109 OrderedSet &Insts) {
2111 SmallVector<Value *, 4>
Ops(
I->operands());
2112 ValueRankMap.erase(
I);
2114 RedoInsts.remove(
I);
2118 I->eraseFromParent();
2119 for (
auto *
Op :
Ops)
2121 if (OpInst->use_empty())
2122 Insts.insert(OpInst);
2126void ReassociatePass::EraseInst(Instruction *
I) {
2130 SmallVector<Value *, 8>
Ops(
I->operands());
2132 ValueRankMap.erase(
I);
2133 RedoInsts.remove(
I);
2137 I->eraseFromParent();
2139 SmallPtrSet<Instruction *, 8> Visited;
2144 unsigned Opcode =
Op->getOpcode();
2145 while (
Op->hasOneUse() &&
Op->user_back()->getOpcode() == Opcode &&
2147 Op =
Op->user_back();
2154 if (ValueRankMap.contains(
Op))
2155 RedoInsts.insert(
Op);
2175 switch (
I->getOpcode()) {
2176 case Instruction::FMul:
2188 case Instruction::FDiv:
2210Instruction *ReassociatePass::canonicalizeNegFPConstantsForOp(Instruction *
I,
2213 assert((
I->getOpcode() == Instruction::FAdd ||
2214 I->getOpcode() == Instruction::FSub) &&
"Expected fadd/fsub");
2218 SmallVector<Instruction *, 4> Candidates;
2220 if (Candidates.
empty())
2226 bool IsFSub =
I->getOpcode() == Instruction::FSub;
2227 bool NeedsSubtract = !IsFSub && Candidates.
size() % 2 == 1;
2231 for (Instruction *Negatible : Candidates) {
2235 "Expecting only 1 constant operand");
2236 assert(
C->isNegative() &&
"Expected negative FP constant");
2237 Negatible->setOperand(0, ConstantFP::get(Negatible->getType(),
abs(*
C)));
2242 "Expecting only 1 constant operand");
2243 assert(
C->isNegative() &&
"Expected negative FP constant");
2244 Negatible->setOperand(1, ConstantFP::get(Negatible->getType(),
abs(*
C)));
2248 assert(MadeChange ==
true &&
"Negative constant candidate was not changed");
2251 if (Candidates.size() % 2 == 0)
2256 assert(Candidates.size() % 2 == 1 &&
"Expected odd number");
2261 RedoInsts.insert(
I);
2273Instruction *ReassociatePass::canonicalizeNegFPConstants(Instruction *
I) {
2278 if (Instruction *R = canonicalizeNegFPConstantsForOp(
I,
Op,
X))
2281 if (Instruction *R = canonicalizeNegFPConstantsForOp(
I,
Op,
X))
2284 if (Instruction *R = canonicalizeNegFPConstantsForOp(
I,
Op,
X))
2291void ReassociatePass::OptimizeInst(Instruction *
I) {
2304 RedoInsts.insert(
I);
2312 if (
I->isCommutative())
2313 canonicalizeOperands(
I);
2316 if (Instruction *Res = canonicalizeNegFPConstants(
I))
2331 if (
I->getType()->isIntOrIntVectorTy(1))
2336 if (
I->getOpcode() == Instruction::Or &&
2340 SimplifyQuery(
I->getDataLayout(),
2341 nullptr,
nullptr,
I)))) {
2343 RedoInsts.insert(
I);
2351 RedoInsts.insert(
I);
2352 RedoInsts.insert(MulUser);
2359 if (
I->getOpcode() == Instruction::Sub) {
2362 RedoInsts.insert(
I);
2374 for (User *U : NI->
users()) {
2376 RedoInsts.insert(Tmp);
2378 RedoInsts.insert(
I);
2383 }
else if (
I->getOpcode() == Instruction::FNeg ||
2384 I->getOpcode() == Instruction::FSub) {
2387 RedoInsts.insert(
I);
2401 for (User *U : NI->
users()) {
2403 RedoInsts.insert(Tmp);
2405 RedoInsts.insert(
I);
2413 if (!
I->isAssociative())
return;
2438 ReassociateExpression(BO);
2441void ReassociatePass::ReassociateExpression(BinaryOperator *
I) {
2445 OverflowTracking
Flags;
2460 if (UA &&
Ops.size() > 2) {
2461 constexpr unsigned DivergentRankOffset = 1U << 28;
2466 bool Divergent =
false;
2467 for (
const Use &U :
Entry.Op->uses()) {
2469 if (Usr && Usr->
getParent() == ParentBB) {
2470 Divergent = UA->isDivergentAtUse(U);
2475 Entry.Rank += DivergentRankOffset;
2489 if (
Value *V = OptimizeExpression(
I,
Ops)) {
2496 I->replaceAllUsesWith(V);
2498 if (
I->getDebugLoc())
2499 VI->setDebugLoc(
I->getDebugLoc());
2500 RedoInsts.insert(
I);
2509 if (
I->hasOneUse()) {
2510 if (
I->getOpcode() == Instruction::Mul &&
2515 Ops.insert(
Ops.begin(), Tmp);
2516 }
else if (
I->getOpcode() == Instruction::FMul &&
2518 Instruction::FAdd &&
2522 Ops.insert(
Ops.begin(), Tmp);
2528 if (
Ops.size() == 1) {
2535 I->replaceAllUsesWith(
Ops[0].
Op);
2537 OI->setDebugLoc(
I->getDebugLoc());
2538 RedoInsts.insert(
I);
2542 if (
Ops.size() > 2 &&
Ops.size() <= GlobalReassociateLimit) {
2550 unsigned BestRank = 0;
2551 std::pair<unsigned, unsigned> BestPair;
2552 unsigned Idx =
I->getOpcode() - Instruction::BinaryOpsBegin;
2553 unsigned LimitIdx = 0;
2563 int StartIdx =
Ops.size() - 1;
2568 for (
int i = StartIdx - 1; i != -1; --i) {
2572 if (!CurrLeafInstr) {
2597 FirstSeenBB = SeenBB;
2600 if (FirstSeenBB != SeenBB) {
2606 << LimitIdx <<
", " << StartIdx <<
"]\n");
2611 for (
unsigned i =
Ops.size() - 1; i > LimitIdx; --i) {
2613 for (
int j = i - 1;
j >= (int)LimitIdx; --
j) {
2617 if (std::less<Value *>()(Op1, Op0))
2619 auto it = PairMap[Idx].find({Op0, Op1});
2620 if (it != PairMap[Idx].
end()) {
2626 if (it->second.isValid())
2627 Score += it->second.Score;
2630 unsigned MaxRank = std::max(
Ops[i].Rank,
Ops[j].Rank);
2644 if (Score > Max || (Score == Max && MaxRank < BestRank)) {
2652 auto Op0 =
Ops[BestPair.first];
2653 auto Op1 =
Ops[BestPair.second];
2654 Ops.erase(&
Ops[BestPair.second]);
2655 Ops.erase(&
Ops[BestPair.first]);
2664 RewriteExprTree(
I,
Ops, Flags);
2668ReassociatePass::BuildPairMap(ReversePostOrderTraversal<Function *> &RPOT) {
2670 for (BasicBlock *BI : RPOT) {
2671 for (Instruction &
I : *BI) {
2672 if (!
I.isAssociative() || !
I.isBinaryOp())
2676 if (
I.hasOneUse() &&
I.user_back()->getOpcode() ==
I.getOpcode())
2682 SmallVector<Value *, 8> Worklist = {
I.getOperand(0),
I.getOperand(1) };
2683 SmallVector<Value *, 8>
Ops;
2684 while (!Worklist.
empty() &&
Ops.size() <= GlobalReassociateLimit) {
2698 if (
Ops.size() > GlobalReassociateLimit)
2702 unsigned BinaryIdx =
I.getOpcode() - Instruction::BinaryOpsBegin;
2703 SmallSet<std::pair<Value *, Value*>, 32> Visited;
2704 for (
unsigned i = 0; i <
Ops.size() - 1; ++i) {
2705 for (
unsigned j = i + 1;
j <
Ops.size(); ++
j) {
2709 if (std::less<Value *>()(Op1, Op0))
2711 if (!Visited.
insert({Op0, Op1}).second)
2713 auto res = PairMap[BinaryIdx].insert({{Op0, Op1}, {Op0, Op1, 1}});
2719 assert(res.first->second.isValid() &&
"WeakVH invalidated");
2720 ++res.first->second.Score;
2746 BuildRankMap(
F, RPOT);
2770 assert(
II->getParent() == &*BI &&
"Moved to a different block!");
2781 while (!ToRedo.
empty()) {
2784 RecursivelyEraseDeadInsts(
I, ToRedo);
2830 if (skipFunction(
F))
2834 getAnalysis<UniformityInfoWrapperPass>().getUniformityInfo();
2840 void getAnalysisUsage(AnalysisUsage &AU)
const override {
2850char ReassociateLegacyPass::ID = 0;
2853 "Reassociate expressions",
false,
false)
2860 return new ReassociateLegacyPass();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This is the interface for LLVM's primary stateless and local alias analysis.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool runImpl(MachineFunction &MF)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
static bool runOnFunction(Function &F, bool PostInlining)
This is the interface for a simple mod/ref and alias analysis over globals.
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
This header defines various interfaces for pass management in LLVM.
static bool isInteresting(const SCEV *S, const Instruction *I, const Loop *L, ScalarEvolution *SE, LoopInfo *LI)
isInteresting - Test whether the given expression is "interesting" when used by the given expression,...
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static bool isReassociableOp(Instruction *I, unsigned IntOpcode, unsigned FPOpcode)
uint64_t IntrinsicInst * II
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
static bool LinearizeExprTree(Instruction *I, SmallVectorImpl< RepeatedValue > &Ops, ReassociatePass::OrderedSet &ToRedo, OverflowTracking &Flags)
Given an associative binary expression, return the leaf nodes in Ops along with their weights (how ma...
static void PrintOps(Instruction *I, const SmallVectorImpl< ValueEntry > &Ops)
Print out the expression identified in the Ops list.
static bool ShouldBreakUpSubtract(Instruction *Sub)
Return true if we should break up this subtract of X-Y into (X + -Y).
static Value * buildMultiplyTree(IRBuilderBase &Builder, SmallVectorImpl< Value * > &Ops)
Build a tree of multiplies, computing the product of Ops.
static void getNegatibleInsts(Value *V, SmallVectorImpl< Instruction * > &Candidates)
Recursively analyze an expression to build a list of instructions that have negative floating-point c...
static BinaryOperator * CreateMul(Value *S1, Value *S2, const Twine &Name, BasicBlock::iterator InsertBefore, Value *FlagsOp)
static BinaryOperator * BreakUpSubtract(Instruction *Sub, ReassociatePass::OrderedSet &ToRedo)
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 void FindSingleUseMultiplyFactors(Value *V, SmallVectorImpl< Value * > &Factors)
If V is a single-use multiply, recursively add its operands as factors, otherwise add V to the list o...
std::pair< Value *, uint64_t > RepeatedValue
static Value * OptimizeAndOrXor(unsigned Opcode, SmallVectorImpl< ValueEntry > &Ops)
Optimize a series of operands to an 'and', 'or', or 'xor' instruction.
static BinaryOperator * convertOrWithNoCommonBitsToAdd(Instruction *Or)
If we have (X|Y), and iff X and Y have no common bits set, transform this into (X+Y) to allow arithme...
static BinaryOperator * isFMulAddCandidate(Value *V)
Return the fmul operand if V is a one-use fadd with a single one-use fmul operand,...
static bool ShouldBreakUpDistribution(Instruction *Mul)
Return true if Mul is of the form (X+Y)*C or (X-Y)*C where C is a constant, and there exists a siblin...
static BinaryOperator * CreateAdd(Value *S1, Value *S2, const Twine &Name, BasicBlock::iterator InsertBefore, Value *FlagsOp)
static BinaryOperator * BreakUpDistribute(Instruction *Mul, ReassociatePass::OrderedSet &ToRedo)
Distribute Mul of the form (X+Y)*C into X*C + Y*C.
static bool collectMultiplyFactors(SmallVectorImpl< ValueEntry > &Ops, SmallVectorImpl< Factor > &Factors)
Build up a vector of value/power pairs factoring a product.
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...
static cl::opt< bool > UseCSELocalOpt(DEBUG_TYPE "-use-cse-local", cl::desc("Only reorder expressions within a basic block " "when exposing CSE opportunities"), cl::init(true), cl::Hidden)
static unsigned FindInOperandList(const 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.
static BinaryOperator * LowerNegateToMultiply(Instruction *Neg)
Replace 0-X with X*-1.
static Instruction * CreateNeg(Value *S1, const Twine &Name, BasicBlock::iterator InsertBefore, Value *FlagsOp)
static bool hasFPAssociativeFlags(Instruction *I)
Return true if I is an instruction with the FastMathFlags that are needed for general reassociation s...
static Value * createAndInstr(BasicBlock::iterator InsertBefore, Value *Opnd, const APInt &ConstOpnd)
Helper function of CombineXorOpnd().
static Value * NegateValue(Value *V, Instruction *BI, ReassociatePass::OrderedSet &ToRedo)
Insert instructions before the instruction pointed to by BI, that computes the negative version of th...
static bool shouldConvertOrWithNoCommonBitsToAdd(Instruction *Or)
Return true if it may be profitable to convert this (X|Y) into (X+Y).
static bool isLoadCombineCandidate(Instruction *Or)
static Value * EmitAddTreeOfValues(Instruction *I, SmallVectorImpl< WeakTrackingVH > &Ops)
Emit a tree of add instructions, summing Ops together and returning the result.
static unsigned getFastMathFlags(const MachineInstr &I, const SPIRVSubtarget &ST)
This file defines the SmallPtrSet class.
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Class for arbitrary precision integers.
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
bool getBoolValue() const
Convert APInt to a boolean value.
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
LLVM Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
LLVM_ABI InstListType::const_iterator getFirstNonPHIOrDbg(bool SkipPseudoOp=true) const
Returns a pointer to the first instruction in this block that is not a PHINode or a debug intrinsic,...
InstListType::iterator iterator
Instruction iterators...
static LLVM_ABI BinaryOperator * CreateNeg(Value *Op, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Helper functions to construct and inspect unary operations (NEG and NOT) via binary operators SUB and...
BinaryOps getOpcode() const
static LLVM_ABI BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), InsertPosition InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
Represents analyses that only rely on functions' control flow.
static LLVM_ABI Constant * getBinOpAbsorber(unsigned Opcode, Type *Ty, bool AllowLHSConstant=false)
Return the absorbing element for the given binary operation, i.e.
static LLVM_ABI Constant * getBinOpIdentity(unsigned Opcode, Type *Ty, bool AllowRHSConstant=false, bool NSZ=false)
Return the identity constant for a binary opcode.
static LLVM_ABI Constant * getNeg(Constant *C, bool HasNSW=false)
This is an important base class in LLVM.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
This provides a helper for copying FMF from an instruction or setting specified flags.
FunctionPass class - This class is used to implement most global optimizations.
const BasicBlock & getEntryBlock() const
Module * getParent()
Get the module that this global value is contained inside of...
Common base class shared among various IRBuilders.
Value * CreateFSubFMF(Value *L, Value *R, FMFSource FMFSource, const Twine &Name="", MDNode *FPMD=nullptr)
void setFastMathFlags(FastMathFlags NewFMF)
Set the fast-math flags to be used with generated fp-math operators.
Value * CreateFAddFMF(Value *L, Value *R, FMFSource FMFSource, const Twine &Name="", MDNode *FPMD=nullptr)
LLVM_ABI void setHasNoUnsignedWrap(bool b=true)
Set or clear the nuw flag on this instruction, which must be an operator which supports this flag.
LLVM_ABI void copyFastMathFlags(FastMathFlags FMF)
Convenience function for transferring all fast-math flag values to this instruction,...
LLVM_ABI void setHasNoSignedWrap(bool b=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag.
LLVM_ABI void dropLocation()
Drop the instruction's debug location.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI void andIRFlags(const Value *V)
Logical 'and' of any supported wrapping, exact, and fast-math flags of V and this instruction.
LLVM_ABI void moveBefore(InstListType::iterator InsertPos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
LLVM_ABI void setFastMathFlags(FastMathFlags FMF)
Convenience function for setting multiple fast-math flags on this instruction, which must be an opera...
Instruction * user_back()
Specialize the methods defined in Value, as we know that an instruction can only be used by other ins...
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
const char * getOpcodeName() const
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
A Module instance is used to store all the information related to an LLVM module.
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
bool areAllPreserved() const
Test whether all analyses are preserved (and none are abandoned).
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Reassociate commutative expressions.
DenseMap< BasicBlock *, unsigned > RankMap
DenseMap< AssertingVH< Value >, unsigned > ValueRankMap
LLVM_ABI PreservedAnalyses runImpl(Function &F, UniformityInfo &UI)
SetVector< AssertingVH< Instruction >, std::deque< AssertingVH< Instruction > > > OrderedSet
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
DenseMap< std::pair< Value *, Value * >, PairMapValue > PairMap[NumBinaryOps]
bool empty() const
Determine if the SetVector is empty or not.
bool insert(const value_type &X)
Insert a new element into the SetVector.
value_type pop_back_val()
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
iterator erase(const_iterator CI)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
static UnaryOperator * CreateFNegFMF(Value *Op, Instruction *FMFSource, const Twine &Name="", InsertPosition InsertBefore=nullptr)
void setOperand(unsigned i, Value *Val)
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
user_iterator user_begin()
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
LLVM_ABI void deleteValue()
Delete a pointer to a generic Value.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
const ParentTy * getParent() const
self_iterator getIterator()
Utility class representing a non-constant Xor-operand.
Value * getSymbolicPart() const
unsigned getSymbolicRank() const
void setSymbolicRank(unsigned R)
const APInt & getConstPart() const
@ BasicBlock
Various leaf nodes.
BinaryOp_match< SpecificConstantMatch, SrcTy, TargetOpcode::G_SUB > m_Neg(const SrcTy &&Src)
Matches a register negated by a G_SUB.
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
match_combine_or< Ty... > m_CombineOr(const Ty &...Ps)
Combine pattern matchers matching any of Ps patterns.
match_combine_and< Ty... > m_CombineAnd(const Ty &...Ps)
Combine pattern matchers matching all of Ps patterns.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::FSub > m_FSub(const LHS &L, const RHS &R)
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
BinaryOp_match< LHS, RHS, Instruction::FMul > m_FMul(const LHS &L, const RHS &R)
bool match(Val *V, const Pattern &P)
match_bind< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
ap_match< APFloat > m_APFloat(const APFloat *&Res)
Match a ConstantFP or splatted ConstantVector, binding the specified pointer to the contained APFloat...
auto m_BinOp()
Match an arbitrary binary operation and ignore it.
auto m_Value()
Match an arbitrary value and ignore it.
BinaryOp_match< LHS, RHS, Instruction::FAdd > m_FAdd(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
auto m_Constant()
Match an arbitrary Constant and ignore it.
match_immconstant_ty m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
FNeg_match< OpTy > m_FNeg(const OpTy &X)
Match 'fneg X' as 'fsub -0.0, X'.
BinaryOp_match< LHS, RHS, Instruction::FAdd, true > m_c_FAdd(const LHS &L, const RHS &R)
Matches FAdd with LHS and RHS in either order.
AllowFmf_match< T, FastMathFlags::AllowContract > m_AllowContract(const T &SubPattern)
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
initializer< Ty > init(const Ty &Val)
A private "module" namespace for types and utilities used by Reassociate.
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
GenericUniformityInfo< SSAContext > UniformityInfo
LLVM_ABI bool haveNoCommonBitsSet(const WithCache< const Value * > &LHSCache, const WithCache< const Value * > &RHSCache, const SimplifyQuery &SQ)
Return true if LHS and RHS have no common bits set.
void stable_sort(R &&Range)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI void salvageDebugInfo(const MachineRegisterInfo &MRI, MachineInstr &MI)
Assuming the instruction MI is going to be deleted, attempt to salvage debug users of MI by writing t...
APFloat abs(APFloat X)
Returns the absolute value of the argument.
auto unique(Range &&R, Predicate P)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
unsigned M1(unsigned Val)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction will return.
LLVM_ABI Constant * ConstantFoldUnaryOpOperand(unsigned Opcode, Constant *Op, const DataLayout &DL)
Attempt to constant fold a unary operation with the specified operand.
LLVM_ABI FunctionPass * createReassociatePass()
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void initializeReassociateLegacyPassPass(PassRegistry &)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI Constant * ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS, Constant *RHS, const DataLayout &DL)
Attempt to constant fold a binary operation with the specified operands.
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
@ Mul
Product of integers.
@ Sub
Subtraction of integers.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
DWARFExpression::Operation Op
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI bool isKnownNonNegative(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the give value is known to be non-negative.
LLVM_ABI bool mayHaveNonDefUseDependency(const Instruction &I)
Returns true if the result or effects of the given instructions I depend values not reachable through...
LLVM_ABI Constant * ConstantFoldBinaryInstruction(unsigned Opcode, Constant *V1, Constant *V2)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Utility class representing a base and exponent pair which form one factor of some product.