68#define DEBUG_TYPE "reassociate"
70STATISTIC(NumChanged,
"Number of insts reassociated");
71STATISTIC(NumAnnihil,
"Number of expr tree annihilated");
72STATISTIC(NumFactor ,
"Number of multiplies factored");
79 << *
Ops[0].Op->getType() <<
'\t';
82 Op.Op->printAsOperand(
dbgs(),
false, M);
83 dbgs() <<
", #" <<
Op.Rank <<
"] ";
100 bool isInvalid()
const {
return SymbolicPart ==
nullptr; }
114 unsigned SymbolicRank;
124 if (
I && (
I->getOpcode() == Instruction::Or ||
125 I->getOpcode() == Instruction::And)) {
126 Value *V0 =
I->getOperand(0);
135 isOr = (
I->getOpcode() == Instruction::Or);
152 return I->hasAllowReassoc() &&
I->hasNoSignedZeros();
159 if (BO && BO->hasOneUse() && BO->getOpcode() == Opcode)
168 if (BO && BO->hasOneUse() &&
169 (BO->getOpcode() == Opcode1 || BO->getOpcode() == Opcode2))
185 if (!
FAdd || !
FAdd->hasAllowContract())
192 Value *OtherOp =
nullptr;
204void ReassociatePass::BuildRankMap(
Function &
F,
205 ReversePostOrderTraversal<Function*> &RPOT) {
209 for (
auto &Arg :
F.args()) {
210 ValueRankMap[&Arg] = ++Rank;
211 LLVM_DEBUG(
dbgs() <<
"Calculated Rank[" << Arg.getName() <<
"] = " << Rank
216 for (BasicBlock *BB : RPOT) {
217 unsigned BBRank = RankMap[BB] = ++Rank << 16;
222 for (Instruction &
I : *BB)
224 ValueRankMap[&
I] = ++BBRank;
228unsigned ReassociatePass::getRank(
Value *V) {
232 struct RankWorkItem {
244 RankWorkItem &Item = Worklist.
back();
250 }
else if (ValueRankMap[
I]) {
252 Rank = ValueRankMap[
I];
253 }
else if (Item.OpNo ==
I->getNumOperands() ||
254 Item.Rank == RankMap[
I->getParent()]) {
263 LLVM_DEBUG(
dbgs() <<
"Calculated Rank[" <<
I->getName() <<
"] = " << Rank
266 ValueRankMap[
I] = Rank;
268 Worklist.
push_back(RankWorkItem{
I->getOperand(Item.OpNo), 0, 0});
275 if (Worklist.
empty())
278 RankWorkItem &Parent = Worklist.
back();
279 Parent.Rank = std::max(Parent.Rank, Rank);
285void ReassociatePass::canonicalizeOperands(Instruction *
I) {
287 assert(
I->isCommutative() &&
"Expected commutative operator.");
302 if (
S1->getType()->isIntOrIntVectorTy())
303 return BinaryOperator::CreateAdd(
S1, S2, Name, InsertBefore);
306 BinaryOperator::CreateFAdd(
S1, S2, Name, InsertBefore);
315 if (
S1->getType()->isIntOrIntVectorTy())
316 return BinaryOperator::CreateMul(
S1, S2, Name, InsertBefore);
319 BinaryOperator::CreateFMul(
S1, S2, Name, InsertBefore);
328 if (
S1->getType()->isIntOrIntVectorTy())
334 return UnaryOperator::CreateFNeg(
S1, Name, InsertBefore);
340 "Expected a Negate!");
344 Constant *NegOne = Ty->isIntOrIntVectorTy() ?
436 "Expected a UnaryOperator or BinaryOperator!");
438 unsigned Opcode =
I->getOpcode();
439 assert(
I->isAssociative() &&
I->isCommutative() &&
440 "Expected an associative and commutative operation!");
479 while (!Worklist.
empty()) {
483 Flags.mergeFlags(*
I);
485 for (
unsigned OpIdx = 0; OpIdx <
I->getNumOperands(); ++OpIdx) {
488 assert((!
Op->hasUseList() || !
Op->use_empty()) &&
489 "No uses, so how did we get to it?!");
497 Worklist.
push_back(std::make_pair(BO, Weight));
502 LeafMap::iterator It = Leaves.find(
Op);
503 if (It == Leaves.end()) {
506 if (!
Op->hasOneUse()) {
510 <<
"ADD USES LEAF: " << *
Op <<
" (" << Weight <<
")\n");
519 "In leaf map but not visited!");
522 It->second += Weight;
523 assert(It->second >= Weight &&
"Weight overflows");
527 if (!
Op->hasOneUse())
544 "Should have been handled above!");
545 assert(
Op->hasOneUse() &&
"Has uses outside the expression tree!");
557 <<
"MORPH LEAF: " << *
Op <<
" (" << Weight <<
") TO ");
574 "Value was morphed?");
582 for (
Value *V : LeafOrder) {
583 LeafMap::iterator It = Leaves.find(V);
584 if (It == Leaves.end())
588 "Shouldn't be a leaf!");
592 Ops.push_back(std::make_pair(V, Weight));
593 if (Opcode == Instruction::Add && Flags.AllKnownNonNegative && Flags.HasNSW)
595 else if (Opcode == Instruction::Mul) {
598 if (Flags.AllKnownNonZero &&
599 (Flags.HasNUW || (Flags.HasNSW && Flags.AllKnownNonNegative))) {
601 if (Flags.HasNSW && Flags.AllKnownNonNegative)
612 assert(Identity &&
"Associative operation without identity!");
613 Ops.emplace_back(Identity, 1);
621void ReassociatePass::RewriteExprTree(BinaryOperator *
I,
622 SmallVectorImpl<ValueEntry> &
Ops,
623 OverflowTracking Flags) {
624 assert(
Ops.size() > 1 &&
"Single values should be used directly!");
638 unsigned Opcode =
I->getOpcode();
639 BinaryOperator *
Op =
I;
651 SmallPtrSet<Value*, 8> NotRewritable;
659 BinaryOperator *ExpressionChangedStart =
nullptr,
660 *ExpressionChangedEnd =
nullptr;
661 for (
unsigned i = 0; ; ++i) {
665 if (i+2 ==
Ops.size()) {
668 Value *OldLHS =
Op->getOperand(0);
669 Value *OldRHS =
Op->getOperand(1);
671 if (NewLHS == OldLHS && NewRHS == OldRHS)
675 if (NewLHS == OldRHS && NewRHS == OldLHS) {
688 if (NewLHS != OldLHS) {
690 if (BO && !NotRewritable.
count(BO))
693 Op->setOperand(0, NewLHS);
695 if (NewRHS != OldRHS) {
697 if (BO && !NotRewritable.
count(BO))
700 Op->setOperand(1, NewRHS);
704 ExpressionChangedStart =
Op;
705 if (!ExpressionChangedEnd)
706 ExpressionChangedEnd =
Op;
716 if (NewRHS !=
Op->getOperand(1)) {
718 if (NewRHS ==
Op->getOperand(0)) {
725 if (BO && !NotRewritable.
count(BO))
728 Op->setOperand(1, NewRHS);
729 ExpressionChangedStart =
Op;
730 if (!ExpressionChangedEnd)
731 ExpressionChangedEnd =
Op;
742 if (BO && !NotRewritable.
count(BO)) {
754 BinaryOperator *NewOp;
755 if (NodesToRewrite.
empty()) {
758 Poison,
"",
I->getIterator());
767 Op->setOperand(0, NewOp);
769 ExpressionChangedStart =
Op;
770 if (!ExpressionChangedEnd)
771 ExpressionChangedEnd =
Op;
781 if (ExpressionChangedStart) {
782 bool ClearFlags =
true;
789 Flags.applyFlags(*ExpressionChangedStart);
793 if (ExpressionChangedStart == ExpressionChangedEnd)
795 if (ExpressionChangedStart ==
I)
798 ExpressionChangedStart->
moveBefore(
I->getIterator());
799 ExpressionChangedStart =
805 RedoInsts.insert_range(NodesToRewrite);
819 Constant *Res =
C->getType()->isFPOrFPVectorTy()
840 if (
I->getOpcode() == Instruction::Add) {
841 I->setHasNoUnsignedWrap(
false);
842 I->setHasNoSignedWrap(
false);
851 I->setName(
I->getName()+
".neg");
874 C->containsUndefOrPoisonElement())
884 auto InsertPtOpt = InstInput->getInsertionPointAfterDef();
887 InsertPt = *InsertPtOpt;
898 if (TheNeg->
getParent() != InsertPt->getParent())
900 TheNeg->
moveBefore(*InsertPt->getParent(), InsertPt);
902 if (TheNeg->
getOpcode() == Instruction::Sub) {
931 auto Enqueue = [&](
Value *V) {
945 while (!Worklist.
empty()) {
949 switch (
I->getOpcode()) {
950 case Instruction::Or:
957 case Instruction::Shl:
958 case Instruction::ZExt:
960 if (!Enqueue(
I->getOperand(0)))
964 case Instruction::Load:
982 for (
auto Op : {Instruction::Add, Instruction::Sub, Instruction::Mul,
1004 Or->getIterator(),
Or);
1005 New->setHasNoSignedWrap();
1006 New->setHasNoUnsignedWrap();
1010 Or->replaceAllUsesWith(New);
1011 New->setDebugLoc(
Or->getDebugLoc());
1013 LLVM_DEBUG(
dbgs() <<
"Converted or into an add: " << *New <<
'\n');
1031 if (MulUser->getOpcode() != Instruction::Add &&
1032 MulUser->getOpcode() != Instruction::Sub)
1035 for (
Value *Sibling : MulUser->operands()) {
1036 if (Sibling ==
Mul || !Sibling->hasOneUse())
1059 "Mul1",
Mul->getIterator());
1060 BinaryOperator *M2 = BinaryOperator::CreateMul(AddSub->getOperand(1), C2,
1061 "Mul2",
Mul->getIterator());
1063 BinaryOperator::CreateAdd(
M1, M2,
"DistAdd",
Mul->getIterator());
1065 Mul->replaceAllUsesWith(Result);
1066 Result->setDebugLoc(
Mul->getDebugLoc());
1096 if (
Sub->hasOneUse() &&
1121 Sub->replaceAllUsesWith(New);
1122 New->setDebugLoc(
Sub->getDebugLoc());
1134 assert(MulCst &&
"Constant folding of immediate constants failed");
1152 if (NSW && (NUW || SA->getValue().ult(
BitWidth - 1)))
1153 Mul->setHasNoSignedWrap(
true);
1154 Mul->setHasNoUnsignedWrap(NUW);
1163 unsigned XRank =
Ops[i].Rank;
1164 unsigned e =
Ops.size();
1165 for (
unsigned j = i+1; j != e &&
Ops[j].Rank == XRank; ++j) {
1170 if (I1->isIdenticalTo(I2))
1174 for (
unsigned j = i-1; j != ~0U &&
Ops[j].Rank == XRank; --j) {
1179 if (I1->isIdenticalTo(I2))
1189 if (
Ops.size() == 1)
return Ops.back();
1193 auto *NewAdd =
CreateAdd(V2,
V1,
"reass.add",
I->getIterator(),
I);
1194 NewAdd->setDebugLoc(
I->getDebugLoc());
1205 BinaryOperator *BO =
isReassociableOp(V, Instruction::Mul, Instruction::FMul);
1210 OverflowTracking
Flags;
1217 bool FoundFactor =
false;
1218 bool NeedsNegate =
false;
1219 for (
unsigned i = 0, e = Factors.
size(); i != e; ++i) {
1229 if (FC1->getValue() == -FC2->getValue()) {
1230 FoundFactor = NeedsNegate =
true;
1236 const APFloat &F1 = FC1->getValueAPF();
1237 APFloat F2(FC2->getValueAPF());
1240 FoundFactor = NeedsNegate =
true;
1250 RewriteExprTree(BO, Factors, Flags);
1258 if (Factors.
size() == 1) {
1259 RedoInsts.insert(BO);
1262 RewriteExprTree(BO, Factors, Flags);
1298 for (
unsigned i = 0, e =
Ops.size(); i != e; ++i) {
1305 if (Opcode == Instruction::And)
1308 if (Opcode == Instruction::Or)
1316 if (i+1 !=
Ops.size() &&
Ops[i+1].Op ==
Ops[i].Op) {
1317 if (Opcode == Instruction::And || Opcode == Instruction::Or) {
1319 Ops.erase(
Ops.begin()+i);
1326 assert(Opcode == Instruction::Xor);
1331 Ops.erase(
Ops.begin()+i,
Ops.begin()+i+2);
1345 const APInt &ConstOpnd) {
1353 Opnd, ConstantInt::get(Opnd->
getType(), ConstOpnd),
"and.ra",
1355 I->setDebugLoc(InsertBefore->getDebugLoc());
1366 APInt &ConstOpnd,
Value *&Res) {
1378 if (C1 != ConstOpnd)
1387 RedoInsts.insert(
T);
1400 XorOpnd *Opnd2, APInt &ConstOpnd,
1407 int DeadInstNum = 1;
1425 APInt C3((~C1) ^ C2);
1428 if (!C3.isZero() && !C3.isAllOnes()) {
1430 if (NewInstNum > DeadInstNum)
1446 if (NewInstNum > DeadInstNum)
1464 RedoInsts.insert(
T);
1466 RedoInsts.insert(
T);
1474Value *ReassociatePass::OptimizeXor(Instruction *
I,
1475 SmallVectorImpl<ValueEntry> &
Ops) {
1479 if (
Ops.size() == 1)
1484 Type *Ty =
Ops[0].Op->getType();
1496 O.setSymbolicRank(getRank(
O.getSymbolicPart()));
1523 return LHS->getSymbolicRank() <
RHS->getSymbolicRank();
1529 for (
unsigned i = 0, e = Opnds.size(); i < e; i++) {
1530 XorOpnd *CurrOpnd = OpndPtrs[i];
1535 if (!ConstOpnd.
isZero() &&
1536 CombineXorOpnd(
I->getIterator(), CurrOpnd, ConstOpnd, CV)) {
1546 if (!PrevOpnd || CurrOpnd->
getSymbolicPart() != PrevOpnd->getSymbolicPart()) {
1547 PrevOpnd = CurrOpnd;
1553 if (CombineXorOpnd(
I->getIterator(), CurrOpnd, PrevOpnd, ConstOpnd, CV)) {
1555 PrevOpnd->Invalidate();
1558 PrevOpnd = CurrOpnd;
1570 for (
const XorOpnd &O : Opnds) {
1576 if (!ConstOpnd.
isZero()) {
1577 Value *
C = ConstantInt::get(Ty, ConstOpnd);
1581 unsigned Sz =
Ops.size();
1583 return Ops.back().Op;
1586 return ConstantInt::get(Ty, ConstOpnd);
1596Value *ReassociatePass::OptimizeAdd(Instruction *
I,
1597 SmallVectorImpl<ValueEntry> &
Ops) {
1603 for (
unsigned i = 0, e =
Ops.size(); i != e; ++i) {
1608 if (i+1 !=
Ops.size() &&
Ops[i+1].Op == TheOp) {
1610 unsigned NumFound = 0;
1612 Ops.erase(
Ops.begin()+i);
1614 }
while (i !=
Ops.size() &&
Ops[i].Op == TheOp);
1616 LLVM_DEBUG(
dbgs() <<
"\nFACTORING [" << NumFound <<
"]: " << *TheOp
1624 ? ConstantInt::get(Ty, NumFound,
false,
1628 Mul->setDebugLoc(
I->getDebugLoc());
1633 RedoInsts.insert(
Mul);
1660 if (
Ops.size() == 2 &&
1668 Ops.erase(
Ops.begin()+i);
1673 Ops.erase(
Ops.begin()+FoundX);
1691 DenseMap<Value*, unsigned> FactorOccurrences;
1695 unsigned MaxOcc = 0;
1696 Value *MaxOccVal =
nullptr;
1703 return Occ > MaxOcc ||
1708 auto CountFactors = [&](BinaryOperator *BOp) {
1710 SmallVector<Value*, 8> Factors;
1712 assert(Factors.
size() > 1 &&
"Bad linearize!");
1715 SmallPtrSet<Value*, 8> Duplicates;
1720 unsigned Occ = ++FactorOccurrences[
Factor];
1721 if (IsBetterFactor(
Factor, MaxOccVal, Occ, MaxOcc)) {
1730 if (CI->isNegative() && !CI->isMinValue(
true)) {
1731 Factor = ConstantInt::get(CI->getContext(), -CI->getValue());
1734 unsigned Occ = ++FactorOccurrences[
Factor];
1735 if (IsBetterFactor(
Factor, MaxOccVal, Occ, MaxOcc)) {
1741 if (CF->isNegative()) {
1744 Factor = ConstantFP::get(CF->getType(),
F);
1747 unsigned Occ = ++FactorOccurrences[
Factor];
1748 if (IsBetterFactor(
Factor, MaxOccVal, Occ, MaxOcc)) {
1762 if (BinaryOperator *BOp =
1775 for (
Value *V : FMulAddCands) {
1778 Ops.emplace_back(getRank(
Op),
Op);
1784 LLVM_DEBUG(
dbgs() <<
"\nFACTORING [" << MaxOcc <<
"]: " << *MaxOccVal
1793 I->getType()->isIntOrIntVectorTy()
1794 ? BinaryOperator::CreateAdd(MaxOccVal, MaxOccVal)
1795 : BinaryOperator::CreateFAdd(MaxOccVal, MaxOccVal);
1798 for (
unsigned i = 0; i !=
Ops.size(); ++i) {
1800 BinaryOperator *BOp =
1805 if (
Value *V = RemoveFactorFromExpression(
Ops[i].
Op, MaxOccVal,
1806 I->getDebugLoc())) {
1809 for (
unsigned j =
Ops.size(); j != i;) {
1813 Ops.erase(
Ops.begin()+j);
1823 unsigned NumAddedValues = NewMulOps.
size();
1829 assert(NumAddedValues > 1 &&
"Each occurrence should contribute a value");
1830 (void)NumAddedValues;
1832 RedoInsts.insert(VI);
1840 RedoInsts.insert(V2);
1871 unsigned FactorPowerSum = 0;
1872 for (
unsigned Idx = 1,
Size =
Ops.size(); Idx <
Size; ++Idx) {
1877 for (; Idx <
Size &&
Ops[Idx].Op ==
Op; ++Idx)
1881 FactorPowerSum +=
Count;
1888 if (FactorPowerSum < 4)
1893 for (
unsigned Idx = 1; Idx <
Ops.size(); ++Idx) {
1898 for (; Idx <
Ops.size() &&
Ops[Idx].
Op ==
Op; ++Idx)
1905 FactorPowerSum +=
Count;
1912 assert(FactorPowerSum >= 4);
1915 return LHS.Power >
RHS.Power;
1923 if (
Ops.size() == 1)
1928 if (
LHS->getType()->isIntOrIntVectorTy())
1929 LHS = Builder.CreateMul(
LHS,
Ops.pop_back_val());
1931 LHS = Builder.CreateFMul(
LHS,
Ops.pop_back_val());
1932 }
while (!
Ops.empty());
1944ReassociatePass::buildMinimalMultiplyDAG(IRBuilderBase &Builder,
1945 SmallVectorImpl<Factor> &Factors) {
1946 assert(Factors[0].Power);
1947 SmallVector<Value *, 4> OuterProduct;
1948 for (
unsigned LastIdx = 0, Idx = 1,
Size = Factors.
size();
1949 Idx <
Size && Factors[Idx].Power > 0; ++Idx) {
1950 if (Factors[Idx].Power != Factors[LastIdx].Power) {
1958 SmallVector<Value *, 4> InnerProduct;
1963 }
while (Idx <
Size && Factors[Idx].Power == Factors[LastIdx].Power);
1969 RedoInsts.insert(
MI);
1977 return LHS.Power ==
RHS.Power;
1989 if (Factors[0].Power) {
1990 Value *SquareRoot = buildMinimalMultiplyDAG(Builder, Factors);
1994 if (OuterProduct.
size() == 1)
1995 return OuterProduct.
front();
2001Value *ReassociatePass::OptimizeMul(BinaryOperator *
I,
2002 SmallVectorImpl<ValueEntry> &
Ops) {
2022 Value *
V = buildMinimalMultiplyDAG(Builder, Factors);
2031Value *ReassociatePass::OptimizeExpression(BinaryOperator *
I,
2032 SmallVectorImpl<ValueEntry> &
Ops) {
2035 const DataLayout &
DL =
I->getDataLayout();
2037 unsigned Opcode =
I->getOpcode();
2038 while (!
Ops.empty()) {
2066 if (
Ops.size() == 1)
return Ops[0].
Op;
2073 case Instruction::And:
2074 case Instruction::Or:
2079 case Instruction::Xor:
2080 if (
Value *Result = OptimizeXor(
I,
Ops))
2084 case Instruction::Add:
2085 case Instruction::FAdd:
2086 if (
Value *Result = OptimizeAdd(
I,
Ops))
2090 case Instruction::Mul:
2091 case Instruction::FMul:
2092 if (
Value *Result = OptimizeMul(
I,
Ops))
2098 return OptimizeExpression(
I,
Ops);
2104void ReassociatePass::RecursivelyEraseDeadInsts(Instruction *
I,
2105 OrderedSet &Insts) {
2107 SmallVector<Value *, 4>
Ops(
I->operands());
2108 ValueRankMap.erase(
I);
2110 RedoInsts.remove(
I);
2114 I->eraseFromParent();
2115 for (
auto *
Op :
Ops)
2117 if (OpInst->use_empty())
2118 Insts.insert(OpInst);
2122void ReassociatePass::EraseInst(Instruction *
I) {
2126 SmallVector<Value *, 8>
Ops(
I->operands());
2128 ValueRankMap.erase(
I);
2129 RedoInsts.remove(
I);
2133 I->eraseFromParent();
2135 SmallPtrSet<Instruction *, 8> Visited;
2140 unsigned Opcode =
Op->getOpcode();
2141 while (
Op->hasOneUse() &&
Op->user_back()->getOpcode() == Opcode &&
2143 Op =
Op->user_back();
2150 if (ValueRankMap.contains(
Op))
2151 RedoInsts.insert(
Op);
2171 switch (
I->getOpcode()) {
2172 case Instruction::FMul:
2184 case Instruction::FDiv:
2206Instruction *ReassociatePass::canonicalizeNegFPConstantsForOp(Instruction *
I,
2209 assert((
I->getOpcode() == Instruction::FAdd ||
2210 I->getOpcode() == Instruction::FSub) &&
"Expected fadd/fsub");
2214 SmallVector<Instruction *, 4> Candidates;
2216 if (Candidates.
empty())
2222 bool IsFSub =
I->getOpcode() == Instruction::FSub;
2223 bool NeedsSubtract = !IsFSub && Candidates.
size() % 2 == 1;
2227 for (Instruction *Negatible : Candidates) {
2231 "Expecting only 1 constant operand");
2232 assert(
C->isNegative() &&
"Expected negative FP constant");
2233 Negatible->setOperand(0, ConstantFP::get(Negatible->getType(),
abs(*
C)));
2238 "Expecting only 1 constant operand");
2239 assert(
C->isNegative() &&
"Expected negative FP constant");
2240 Negatible->setOperand(1, ConstantFP::get(Negatible->getType(),
abs(*
C)));
2244 assert(MadeChange ==
true &&
"Negative constant candidate was not changed");
2247 if (Candidates.size() % 2 == 0)
2252 assert(Candidates.size() % 2 == 1 &&
"Expected odd number");
2257 RedoInsts.insert(
I);
2269Instruction *ReassociatePass::canonicalizeNegFPConstants(Instruction *
I) {
2274 if (Instruction *R = canonicalizeNegFPConstantsForOp(
I,
Op,
X))
2277 if (Instruction *R = canonicalizeNegFPConstantsForOp(
I,
Op,
X))
2280 if (Instruction *R = canonicalizeNegFPConstantsForOp(
I,
Op,
X))
2287void ReassociatePass::OptimizeInst(Instruction *
I) {
2300 RedoInsts.insert(
I);
2308 if (
I->isCommutative())
2309 canonicalizeOperands(
I);
2312 if (Instruction *Res = canonicalizeNegFPConstants(
I))
2327 if (
I->getType()->isIntOrIntVectorTy(1))
2332 if (
I->getOpcode() == Instruction::Or &&
2336 SimplifyQuery(
I->getDataLayout(),
2337 nullptr,
nullptr,
I)))) {
2339 RedoInsts.insert(
I);
2347 RedoInsts.insert(
I);
2348 RedoInsts.insert(MulUser);
2355 if (
I->getOpcode() == Instruction::Sub) {
2358 RedoInsts.insert(
I);
2370 for (User *U : NI->
users()) {
2372 RedoInsts.insert(Tmp);
2374 RedoInsts.insert(
I);
2379 }
else if (
I->getOpcode() == Instruction::FNeg ||
2380 I->getOpcode() == Instruction::FSub) {
2383 RedoInsts.insert(
I);
2397 for (User *U : NI->
users()) {
2399 RedoInsts.insert(Tmp);
2401 RedoInsts.insert(
I);
2409 if (!
I->isAssociative())
return;
2434 ReassociateExpression(BO);
2437void ReassociatePass::ReassociateExpression(BinaryOperator *
I) {
2441 OverflowTracking
Flags;
2456 if (UA &&
Ops.size() > 2) {
2457 constexpr unsigned DivergentRankOffset = 1U << 28;
2462 bool Divergent =
false;
2463 for (
const Use &U :
Entry.Op->uses()) {
2465 if (Usr && Usr->
getParent() == ParentBB) {
2466 Divergent = UA->isDivergentAtUse(U);
2471 Entry.Rank += DivergentRankOffset;
2485 if (
Value *V = OptimizeExpression(
I,
Ops)) {
2492 I->replaceAllUsesWith(V);
2494 if (
I->getDebugLoc())
2495 VI->setDebugLoc(
I->getDebugLoc());
2496 RedoInsts.insert(
I);
2505 if (
I->hasOneUse()) {
2506 if (
I->getOpcode() == Instruction::Mul &&
2511 Ops.insert(
Ops.begin(), Tmp);
2512 }
else if (
I->getOpcode() == Instruction::FMul &&
2514 Instruction::FAdd &&
2518 Ops.insert(
Ops.begin(), Tmp);
2524 if (
Ops.size() == 1) {
2531 I->replaceAllUsesWith(
Ops[0].
Op);
2533 OI->setDebugLoc(
I->getDebugLoc());
2534 RedoInsts.insert(
I);
2538 if (
Ops.size() > 2 &&
Ops.size() <= GlobalReassociateLimit) {
2546 unsigned BestRank = 0;
2547 std::pair<unsigned, unsigned> BestPair;
2548 unsigned Idx =
I->getOpcode() - Instruction::BinaryOpsBegin;
2549 unsigned LimitIdx = 0;
2557 if (ScalarOptions::Global.reassociate_use_cse_local) {
2559 int StartIdx =
Ops.size() - 1;
2564 for (
int i = StartIdx - 1; i != -1; --i) {
2568 if (!CurrLeafInstr) {
2593 FirstSeenBB = SeenBB;
2596 if (FirstSeenBB != SeenBB) {
2602 << LimitIdx <<
", " << StartIdx <<
"]\n");
2607 for (
unsigned i =
Ops.size() - 1; i > LimitIdx; --i) {
2609 for (
int j = i - 1;
j >= (int)LimitIdx; --
j) {
2613 if (std::less<Value *>()(Op1, Op0))
2615 auto it = PairMap[
Idx].find({Op0, Op1});
2616 if (it != PairMap[Idx].
end()) {
2622 if (it->second.isValid())
2623 Score += it->second.Score;
2626 unsigned MaxRank = std::max(
Ops[i].Rank,
Ops[j].Rank);
2640 if (Score > Max || (Score == Max && MaxRank < BestRank)) {
2648 auto Op0 =
Ops[BestPair.first];
2649 auto Op1 =
Ops[BestPair.second];
2650 Ops.erase(&
Ops[BestPair.second]);
2651 Ops.erase(&
Ops[BestPair.first]);
2660 RewriteExprTree(
I,
Ops, Flags);
2664ReassociatePass::BuildPairMap(ReversePostOrderTraversal<Function *> &RPOT) {
2666 for (BasicBlock *BI : RPOT) {
2667 for (Instruction &
I : *BI) {
2668 if (!
I.isAssociative() || !
I.isBinaryOp())
2672 if (
I.hasOneUse() &&
I.user_back()->getOpcode() ==
I.getOpcode())
2678 SmallVector<Value *, 8> Worklist = {
I.getOperand(0),
I.getOperand(1) };
2679 SmallVector<Value *, 8>
Ops;
2680 while (!Worklist.
empty() &&
Ops.size() <= GlobalReassociateLimit) {
2694 if (
Ops.size() > GlobalReassociateLimit)
2698 unsigned BinaryIdx =
I.getOpcode() - Instruction::BinaryOpsBegin;
2699 SmallSet<std::pair<Value *, Value*>, 32> Visited;
2700 for (
unsigned i = 0; i <
Ops.size() - 1; ++i) {
2701 for (
unsigned j = i + 1;
j <
Ops.size(); ++
j) {
2705 if (std::less<Value *>()(Op1, Op0))
2707 if (!Visited.
insert({Op0, Op1}).second)
2709 auto res = PairMap[BinaryIdx].insert({{Op0, Op1}, {Op0, Op1, 1}});
2715 assert(res.first->second.isValid() &&
"WeakVH invalidated");
2716 ++res.first->second.Score;
2742 BuildRankMap(
F, RPOT);
2766 assert(
II->getParent() == &*BI &&
"Moved to a different block!");
2777 while (!ToRedo.
empty()) {
2780 RecursivelyEraseDeadInsts(
I, ToRedo);
2826 if (skipFunction(
F))
2830 getAnalysis<UniformityInfoWrapperPass>().getUniformityInfo();
2836 void getAnalysisUsage(AnalysisUsage &AU)
const override {
2846char ReassociateLegacyPass::ID = 0;
2849 "Reassociate expressions",
false,
false)
2856 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 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()
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
iterator_range< user_iterator > users()
const char * getOpcodeName() const
user_iterator user_begin()
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.
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)
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.
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
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.
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.