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()]) {
264 LLVM_DEBUG(
dbgs() <<
"Calculated Rank[" <<
I->getName() <<
"] = " << Rank
267 ValueRankMap[
I] = Rank;
269 Worklist.
push_back(RankWorkItem{
I->getOperand(Item.OpNo), 0, 0});
276 if (Worklist.
empty())
279 RankWorkItem &Parent = Worklist.
back();
280 Parent.Rank = std::max(Parent.Rank, Rank);
286void ReassociatePass::canonicalizeOperands(Instruction *
I) {
288 assert(
I->isCommutative() &&
"Expected commutative operator.");
303 if (
S1->getType()->isIntOrIntVectorTy())
304 return BinaryOperator::CreateAdd(
S1, S2, Name, InsertBefore);
307 BinaryOperator::CreateFAdd(
S1, S2, Name, InsertBefore);
316 if (
S1->getType()->isIntOrIntVectorTy())
317 return BinaryOperator::CreateMul(
S1, S2, Name, InsertBefore);
320 BinaryOperator::CreateFMul(
S1, S2, Name, InsertBefore);
329 if (
S1->getType()->isIntOrIntVectorTy())
335 return UnaryOperator::CreateFNeg(
S1, Name, InsertBefore);
341 "Expected a Negate!");
345 Constant *NegOne = Ty->isIntOrIntVectorTy() ?
437 "Expected a UnaryOperator or BinaryOperator!");
439 unsigned Opcode =
I->getOpcode();
440 assert(
I->isAssociative() &&
I->isCommutative() &&
441 "Expected an associative and commutative operation!");
480 while (!Worklist.
empty()) {
484 Flags.mergeFlags(*
I);
486 for (
unsigned OpIdx = 0; OpIdx <
I->getNumOperands(); ++OpIdx) {
489 assert((!
Op->hasUseList() || !
Op->use_empty()) &&
490 "No uses, so how did we get to it?!");
498 Worklist.
push_back(std::make_pair(BO, Weight));
503 LeafMap::iterator It = Leaves.find(
Op);
504 if (It == Leaves.end()) {
507 if (!
Op->hasOneUse()) {
511 <<
"ADD USES LEAF: " << *
Op <<
" (" << Weight <<
")\n");
520 "In leaf map but not visited!");
523 It->second += Weight;
524 assert(It->second >= Weight &&
"Weight overflows");
528 if (!
Op->hasOneUse())
545 "Should have been handled above!");
546 assert(
Op->hasOneUse() &&
"Has uses outside the expression tree!");
556 (Opcode == Instruction::FMul &&
560 <<
"MORPH LEAF: " << *
Op <<
" (" << Weight <<
") TO ");
577 "Value was morphed?");
585 for (
Value *V : LeafOrder) {
586 LeafMap::iterator It = Leaves.find(V);
587 if (It == Leaves.end())
591 "Shouldn't be a leaf!");
595 Ops.push_back(std::make_pair(V, Weight));
596 if (Opcode == Instruction::Add && Flags.AllKnownNonNegative && Flags.HasNSW)
598 else if (Opcode == Instruction::Mul) {
601 if (Flags.AllKnownNonZero &&
602 (Flags.HasNUW || (Flags.HasNSW && Flags.AllKnownNonNegative))) {
604 if (Flags.HasNSW && Flags.AllKnownNonNegative)
615 assert(Identity &&
"Associative operation without identity!");
616 Ops.emplace_back(Identity, 1);
624void ReassociatePass::RewriteExprTree(BinaryOperator *
I,
625 SmallVectorImpl<ValueEntry> &
Ops,
626 OverflowTracking Flags) {
627 assert(
Ops.size() > 1 &&
"Single values should be used directly!");
641 unsigned Opcode =
I->getOpcode();
642 BinaryOperator *
Op =
I;
654 SmallPtrSet<Value*, 8> NotRewritable;
662 BinaryOperator *ExpressionChangedStart =
nullptr,
663 *ExpressionChangedEnd =
nullptr;
664 for (
unsigned i = 0; ; ++i) {
668 if (i+2 ==
Ops.size()) {
671 Value *OldLHS =
Op->getOperand(0);
672 Value *OldRHS =
Op->getOperand(1);
674 if (NewLHS == OldLHS && NewRHS == OldRHS)
678 if (NewLHS == OldRHS && NewRHS == OldLHS) {
691 if (NewLHS != OldLHS) {
693 if (BO && !NotRewritable.
count(BO))
696 Op->setOperand(0, NewLHS);
698 if (NewRHS != OldRHS) {
700 if (BO && !NotRewritable.
count(BO))
703 Op->setOperand(1, NewRHS);
707 ExpressionChangedStart =
Op;
708 if (!ExpressionChangedEnd)
709 ExpressionChangedEnd =
Op;
719 if (NewRHS !=
Op->getOperand(1)) {
721 if (NewRHS ==
Op->getOperand(0)) {
728 if (BO && !NotRewritable.
count(BO))
731 Op->setOperand(1, NewRHS);
732 ExpressionChangedStart =
Op;
733 if (!ExpressionChangedEnd)
734 ExpressionChangedEnd =
Op;
745 if (BO && !NotRewritable.
count(BO)) {
757 BinaryOperator *NewOp;
758 if (NodesToRewrite.
empty()) {
761 Poison,
"",
I->getIterator());
770 Op->setOperand(0, NewOp);
772 ExpressionChangedStart =
Op;
773 if (!ExpressionChangedEnd)
774 ExpressionChangedEnd =
Op;
784 if (ExpressionChangedStart) {
785 bool ClearFlags =
true;
792 Flags.applyFlags(*ExpressionChangedStart);
796 if (ExpressionChangedStart == ExpressionChangedEnd)
798 if (ExpressionChangedStart ==
I)
801 ExpressionChangedStart->
moveBefore(
I->getIterator());
802 ExpressionChangedStart =
808 RedoInsts.insert_range(NodesToRewrite);
822 Constant *Res =
C->getType()->isFPOrFPVectorTy()
843 if (
I->getOpcode() == Instruction::Add) {
844 I->setHasNoUnsignedWrap(
false);
845 I->setHasNoSignedWrap(
false);
854 I->setName(
I->getName()+
".neg");
879 C->containsUndefOrPoisonElement())
889 auto InsertPtOpt = InstInput->getInsertionPointAfterDef();
892 InsertPt = *InsertPtOpt;
903 if (TheNeg->
getParent() != InsertPt->getParent())
905 TheNeg->
moveBefore(*InsertPt->getParent(), InsertPt);
907 if (TheNeg->
getOpcode() == Instruction::Sub) {
936 auto Enqueue = [&](
Value *V) {
950 while (!Worklist.
empty()) {
954 switch (
I->getOpcode()) {
955 case Instruction::Or:
962 case Instruction::Shl:
963 case Instruction::ZExt:
965 if (!Enqueue(
I->getOperand(0)))
969 case Instruction::Load:
987 for (
auto Op : {Instruction::Add, Instruction::Sub, Instruction::Mul,
1009 Or->getIterator(),
Or);
1010 New->setHasNoSignedWrap();
1011 New->setHasNoUnsignedWrap();
1015 Or->replaceAllUsesWith(New);
1016 New->setDebugLoc(
Or->getDebugLoc());
1018 LLVM_DEBUG(
dbgs() <<
"Converted or into an add: " << *New <<
'\n');
1036 if (MulUser->getOpcode() != Instruction::Add &&
1037 MulUser->getOpcode() != Instruction::Sub)
1040 for (
Value *Sibling : MulUser->operands()) {
1041 if (Sibling ==
Mul || !Sibling->hasOneUse())
1064 "Mul1",
Mul->getIterator());
1065 BinaryOperator *M2 = BinaryOperator::CreateMul(AddSub->getOperand(1), C2,
1066 "Mul2",
Mul->getIterator());
1068 BinaryOperator::CreateAdd(
M1, M2,
"DistAdd",
Mul->getIterator());
1070 Mul->replaceAllUsesWith(Result);
1071 Result->setDebugLoc(
Mul->getDebugLoc());
1103 if (
Sub->hasOneUse() &&
1128 Sub->replaceAllUsesWith(New);
1129 New->setDebugLoc(
Sub->getDebugLoc());
1141 assert(MulCst &&
"Constant folding of immediate constants failed");
1159 if (NSW && (NUW || SA->getValue().ult(
BitWidth - 1)))
1160 Mul->setHasNoSignedWrap(
true);
1161 Mul->setHasNoUnsignedWrap(NUW);
1170 unsigned XRank =
Ops[i].Rank;
1171 unsigned e =
Ops.size();
1172 for (
unsigned j = i+1; j != e &&
Ops[j].Rank == XRank; ++j) {
1177 if (I1->isIdenticalTo(I2))
1181 for (
unsigned j = i-1; j != ~0U &&
Ops[j].Rank == XRank; --j) {
1186 if (I1->isIdenticalTo(I2))
1196 if (
Ops.size() == 1)
return Ops.back();
1200 auto *NewAdd =
CreateAdd(V2,
V1,
"reass.add",
I->getIterator(),
I);
1201 NewAdd->setDebugLoc(
I->getDebugLoc());
1212 BinaryOperator *BO =
isReassociableOp(V, Instruction::Mul, Instruction::FMul);
1217 OverflowTracking
Flags;
1224 bool FoundFactor =
false;
1225 bool NeedsNegate =
false;
1226 for (
unsigned i = 0, e = Factors.
size(); i != e; ++i) {
1236 if (FC1->getValue() == -FC2->getValue()) {
1237 FoundFactor = NeedsNegate =
true;
1243 const APFloat &F1 = FC1->getValueAPF();
1244 APFloat F2(FC2->getValueAPF());
1247 FoundFactor = NeedsNegate =
true;
1257 RewriteExprTree(BO, Factors, Flags);
1265 if (Factors.
size() == 1) {
1266 RedoInsts.insert(BO);
1269 RewriteExprTree(BO, Factors, Flags);
1305 for (
unsigned i = 0, e =
Ops.size(); i != e; ++i) {
1312 if (Opcode == Instruction::And)
1315 if (Opcode == Instruction::Or)
1323 if (i+1 !=
Ops.size() &&
Ops[i+1].Op ==
Ops[i].Op) {
1324 if (Opcode == Instruction::And || Opcode == Instruction::Or) {
1326 Ops.erase(
Ops.begin()+i);
1333 assert(Opcode == Instruction::Xor);
1338 Ops.erase(
Ops.begin()+i,
Ops.begin()+i+2);
1352 const APInt &ConstOpnd) {
1360 Opnd, ConstantInt::get(Opnd->
getType(), ConstOpnd),
"and.ra",
1362 I->setDebugLoc(InsertBefore->getDebugLoc());
1373 APInt &ConstOpnd,
Value *&Res) {
1385 if (
C1 != ConstOpnd)
1394 RedoInsts.insert(
T);
1407 XorOpnd *Opnd2, APInt &ConstOpnd,
1414 int DeadInstNum = 1;
1432 APInt C3((~
C1) ^ C2);
1435 if (!C3.isZero() && !C3.isAllOnes()) {
1437 if (NewInstNum > DeadInstNum)
1453 if (NewInstNum > DeadInstNum)
1471 RedoInsts.insert(
T);
1473 RedoInsts.insert(
T);
1481Value *ReassociatePass::OptimizeXor(Instruction *
I,
1482 SmallVectorImpl<ValueEntry> &
Ops) {
1486 if (
Ops.size() == 1)
1491 Type *Ty =
Ops[0].Op->getType();
1503 O.setSymbolicRank(getRank(
O.getSymbolicPart()));
1530 return LHS->getSymbolicRank() <
RHS->getSymbolicRank();
1536 for (
unsigned i = 0, e = Opnds.size(); i < e; i++) {
1537 XorOpnd *CurrOpnd = OpndPtrs[i];
1542 if (!ConstOpnd.
isZero() &&
1543 CombineXorOpnd(
I->getIterator(), CurrOpnd, ConstOpnd, CV)) {
1553 if (!PrevOpnd || CurrOpnd->
getSymbolicPart() != PrevOpnd->getSymbolicPart()) {
1554 PrevOpnd = CurrOpnd;
1560 if (CombineXorOpnd(
I->getIterator(), CurrOpnd, PrevOpnd, ConstOpnd, CV)) {
1562 PrevOpnd->Invalidate();
1565 PrevOpnd = CurrOpnd;
1577 for (
const XorOpnd &O : Opnds) {
1583 if (!ConstOpnd.
isZero()) {
1584 Value *
C = ConstantInt::get(Ty, ConstOpnd);
1588 unsigned Sz =
Ops.size();
1590 return Ops.back().Op;
1593 return ConstantInt::get(Ty, ConstOpnd);
1603Value *ReassociatePass::OptimizeAdd(Instruction *
I,
1604 SmallVectorImpl<ValueEntry> &
Ops) {
1610 for (
unsigned i = 0, e =
Ops.size(); i != e; ++i) {
1615 if (i+1 !=
Ops.size() &&
Ops[i+1].Op == TheOp) {
1617 unsigned NumFound = 0;
1619 Ops.erase(
Ops.begin()+i);
1621 }
while (i !=
Ops.size() &&
Ops[i].Op == TheOp);
1623 LLVM_DEBUG(
dbgs() <<
"\nFACTORING [" << NumFound <<
"]: " << *TheOp
1631 ? ConstantInt::get(Ty, NumFound,
false,
1635 Mul->setDebugLoc(
I->getDebugLoc());
1640 RedoInsts.insert(
Mul);
1677 Ops.erase(
Ops.begin()+i);
1682 Ops.erase(
Ops.begin()+FoundX);
1700 DenseMap<Value*, unsigned> FactorOccurrences;
1704 unsigned MaxOcc = 0;
1705 Value *MaxOccVal =
nullptr;
1712 return Occ > MaxOcc ||
1717 auto CountFactors = [&](BinaryOperator *BOp) {
1719 SmallVector<Value*, 8> Factors;
1721 assert(Factors.
size() > 1 &&
"Bad linearize!");
1724 SmallPtrSet<Value*, 8> Duplicates;
1729 unsigned Occ = ++FactorOccurrences[
Factor];
1730 if (IsBetterFactor(
Factor, MaxOccVal, Occ, MaxOcc)) {
1739 if (CI->isNegative() && !CI->isMinValue(
true)) {
1740 Factor = ConstantInt::get(CI->getContext(), -CI->getValue());
1743 unsigned Occ = ++FactorOccurrences[
Factor];
1744 if (IsBetterFactor(
Factor, MaxOccVal, Occ, MaxOcc)) {
1750 if (CF->isNegative()) {
1753 Factor = ConstantFP::get(CF->getType(),
F);
1756 unsigned Occ = ++FactorOccurrences[
Factor];
1757 if (IsBetterFactor(
Factor, MaxOccVal, Occ, MaxOcc)) {
1771 if (BinaryOperator *BOp =
1784 for (
Value *V : FMulAddCands) {
1787 Ops.emplace_back(getRank(
Op),
Op);
1793 LLVM_DEBUG(
dbgs() <<
"\nFACTORING [" << MaxOcc <<
"]: " << *MaxOccVal
1802 I->getType()->isIntOrIntVectorTy()
1803 ? BinaryOperator::CreateAdd(MaxOccVal, MaxOccVal)
1804 : BinaryOperator::CreateFAdd(MaxOccVal, MaxOccVal);
1807 for (
unsigned i = 0; i !=
Ops.size(); ++i) {
1809 BinaryOperator *BOp =
1814 if (
Value *V = RemoveFactorFromExpression(
Ops[i].
Op, MaxOccVal,
1815 I->getDebugLoc())) {
1818 for (
unsigned j =
Ops.size(); j != i;) {
1822 Ops.erase(
Ops.begin()+j);
1832 unsigned NumAddedValues = NewMulOps.
size();
1838 assert(NumAddedValues > 1 &&
"Each occurrence should contribute a value");
1839 (void)NumAddedValues;
1841 RedoInsts.insert(VI);
1849 RedoInsts.insert(V2);
1880 unsigned FactorPowerSum = 0;
1881 for (
unsigned Idx = 1,
Size =
Ops.size(); Idx <
Size; ++Idx) {
1886 for (; Idx <
Size &&
Ops[Idx].Op ==
Op; ++Idx)
1890 FactorPowerSum +=
Count;
1897 if (FactorPowerSum < 4)
1902 for (
unsigned Idx = 1; Idx <
Ops.size(); ++Idx) {
1907 for (; Idx <
Ops.size() &&
Ops[Idx].
Op ==
Op; ++Idx)
1914 FactorPowerSum +=
Count;
1921 assert(FactorPowerSum >= 4);
1924 return LHS.Power >
RHS.Power;
1932 if (
Ops.size() == 1)
1937 if (
LHS->getType()->isIntOrIntVectorTy())
1938 LHS = Builder.CreateMul(
LHS,
Ops.pop_back_val());
1940 LHS = Builder.CreateFMul(
LHS,
Ops.pop_back_val());
1941 }
while (!
Ops.empty());
1953ReassociatePass::buildMinimalMultiplyDAG(IRBuilderBase &Builder,
1954 SmallVectorImpl<Factor> &Factors) {
1955 assert(Factors[0].Power);
1956 SmallVector<Value *, 4> OuterProduct;
1957 for (
unsigned LastIdx = 0, Idx = 1,
Size = Factors.
size();
1958 Idx <
Size && Factors[Idx].Power > 0; ++Idx) {
1959 if (Factors[Idx].Power != Factors[LastIdx].Power) {
1967 SmallVector<Value *, 4> InnerProduct;
1972 }
while (Idx <
Size && Factors[Idx].Power == Factors[LastIdx].Power);
1978 RedoInsts.insert(
MI);
1986 return LHS.Power ==
RHS.Power;
1998 if (Factors[0].Power) {
1999 Value *SquareRoot = buildMinimalMultiplyDAG(Builder, Factors);
2003 if (OuterProduct.
size() == 1)
2004 return OuterProduct.
front();
2010Value *ReassociatePass::OptimizeMul(BinaryOperator *
I,
2011 SmallVectorImpl<ValueEntry> &
Ops) {
2031 Value *
V = buildMinimalMultiplyDAG(Builder, Factors);
2040Value *ReassociatePass::OptimizeExpression(BinaryOperator *
I,
2041 SmallVectorImpl<ValueEntry> &
Ops) {
2044 const DataLayout &
DL =
I->getDataLayout();
2046 unsigned Opcode =
I->getOpcode();
2047 while (!
Ops.empty()) {
2075 if (
Ops.size() == 1)
return Ops[0].
Op;
2082 case Instruction::And:
2083 case Instruction::Or:
2088 case Instruction::Xor:
2089 if (
Value *Result = OptimizeXor(
I,
Ops))
2093 case Instruction::Add:
2094 case Instruction::FAdd:
2095 if (
Value *Result = OptimizeAdd(
I,
Ops))
2099 case Instruction::Mul:
2100 case Instruction::FMul:
2101 if (
Value *Result = OptimizeMul(
I,
Ops))
2107 return OptimizeExpression(
I,
Ops);
2113void ReassociatePass::RecursivelyEraseDeadInsts(Instruction *
I,
2114 OrderedSet &Insts) {
2116 SmallVector<Value *, 4>
Ops(
I->operands());
2117 ValueRankMap.erase(
I);
2119 RedoInsts.remove(
I);
2123 I->eraseFromParent();
2124 for (
auto *
Op :
Ops)
2126 if (OpInst->use_empty())
2127 Insts.insert(OpInst);
2131void ReassociatePass::EraseInst(Instruction *
I) {
2135 SmallVector<Value *, 8>
Ops(
I->operands());
2137 ValueRankMap.erase(
I);
2138 RedoInsts.remove(
I);
2142 I->eraseFromParent();
2144 SmallPtrSet<Instruction *, 8> Visited;
2149 unsigned Opcode =
Op->getOpcode();
2150 while (
Op->hasOneUse() &&
Op->user_back()->getOpcode() == Opcode &&
2152 Op =
Op->user_back();
2159 if (ValueRankMap.contains(
Op))
2160 RedoInsts.insert(
Op);
2180 switch (
I->getOpcode()) {
2181 case Instruction::FMul:
2193 case Instruction::FDiv:
2215Instruction *ReassociatePass::canonicalizeNegFPConstantsForOp(Instruction *
I,
2218 assert((
I->getOpcode() == Instruction::FAdd ||
2219 I->getOpcode() == Instruction::FSub) &&
"Expected fadd/fsub");
2223 SmallVector<Instruction *, 4> Candidates;
2225 if (Candidates.
empty())
2231 bool IsFSub =
I->getOpcode() == Instruction::FSub;
2232 bool NeedsSubtract = !IsFSub && Candidates.
size() % 2 == 1;
2236 for (Instruction *Negatible : Candidates) {
2240 "Expecting only 1 constant operand");
2241 assert(
C->isNegative() &&
"Expected negative FP constant");
2242 Negatible->setOperand(0, ConstantFP::get(Negatible->getType(),
abs(*
C)));
2247 "Expecting only 1 constant operand");
2248 assert(
C->isNegative() &&
"Expected negative FP constant");
2249 Negatible->setOperand(1, ConstantFP::get(Negatible->getType(),
abs(*
C)));
2253 assert(MadeChange ==
true &&
"Negative constant candidate was not changed");
2256 if (Candidates.size() % 2 == 0)
2261 assert(Candidates.size() % 2 == 1 &&
"Expected odd number");
2266 RedoInsts.insert(
I);
2278Instruction *ReassociatePass::canonicalizeNegFPConstants(Instruction *
I) {
2283 if (Instruction *R = canonicalizeNegFPConstantsForOp(
I,
Op,
X))
2286 if (Instruction *R = canonicalizeNegFPConstantsForOp(
I,
Op,
X))
2289 if (Instruction *R = canonicalizeNegFPConstantsForOp(
I,
Op,
X))
2296void ReassociatePass::OptimizeInst(Instruction *
I) {
2309 RedoInsts.insert(
I);
2317 if (
I->isCommutative())
2318 canonicalizeOperands(
I);
2321 if (Instruction *Res = canonicalizeNegFPConstants(
I))
2336 if (
I->getType()->isIntOrIntVectorTy(1))
2341 if (
I->getOpcode() == Instruction::Or &&
2345 SimplifyQuery(
I->getDataLayout(),
2346 nullptr,
nullptr,
I)))) {
2348 RedoInsts.insert(
I);
2356 RedoInsts.insert(
I);
2357 RedoInsts.insert(MulUser);
2364 if (
I->getOpcode() == Instruction::Sub) {
2367 RedoInsts.insert(
I);
2379 for (User *U : NI->
users()) {
2381 RedoInsts.insert(Tmp);
2383 RedoInsts.insert(
I);
2388 }
else if (
I->getOpcode() == Instruction::FNeg ||
2389 I->getOpcode() == Instruction::FSub) {
2392 RedoInsts.insert(
I);
2407 for (User *U : NI->
users()) {
2409 RedoInsts.insert(Tmp);
2411 RedoInsts.insert(
I);
2419 if (!
I->isAssociative())
return;
2444 ReassociateExpression(BO);
2447void ReassociatePass::ReassociateExpression(BinaryOperator *
I) {
2451 OverflowTracking
Flags;
2466 if (UA &&
Ops.size() > 2) {
2467 constexpr unsigned DivergentRankOffset = 1U << 28;
2472 bool Divergent =
false;
2473 for (
const Use &U :
Entry.Op->uses()) {
2475 if (Usr && Usr->
getParent() == ParentBB) {
2476 Divergent = UA->isDivergentAtUse(U);
2481 Entry.Rank += DivergentRankOffset;
2495 if (
Value *V = OptimizeExpression(
I,
Ops)) {
2502 I->replaceAllUsesWith(V);
2504 if (
I->getDebugLoc())
2505 VI->setDebugLoc(
I->getDebugLoc());
2506 RedoInsts.insert(
I);
2515 if (
I->hasOneUse()) {
2516 if (
I->getOpcode() == Instruction::Mul &&
2521 Ops.insert(
Ops.begin(), Tmp);
2522 }
else if (
I->getOpcode() == Instruction::FMul &&
2524 Instruction::FAdd &&
2528 Ops.insert(
Ops.begin(), Tmp);
2534 if (
Ops.size() == 1) {
2541 I->replaceAllUsesWith(
Ops[0].
Op);
2543 OI->setDebugLoc(
I->getDebugLoc());
2544 RedoInsts.insert(
I);
2548 if (
Ops.size() > 2 &&
Ops.size() <= GlobalReassociateLimit) {
2556 unsigned BestRank = 0;
2557 std::pair<unsigned, unsigned> BestPair;
2558 unsigned Idx =
I->getOpcode() - Instruction::BinaryOpsBegin;
2559 unsigned LimitIdx = 0;
2569 int StartIdx =
Ops.size() - 1;
2574 for (
int i = StartIdx - 1; i != -1; --i) {
2578 if (!CurrLeafInstr) {
2603 FirstSeenBB = SeenBB;
2606 if (FirstSeenBB != SeenBB) {
2612 << LimitIdx <<
", " << StartIdx <<
"]\n");
2617 for (
unsigned i =
Ops.size() - 1; i > LimitIdx; --i) {
2619 for (
int j = i - 1;
j >= (int)LimitIdx; --
j) {
2623 if (std::less<Value *>()(Op1, Op0))
2625 auto it = PairMap[
Idx].find({Op0, Op1});
2626 if (it != PairMap[Idx].
end()) {
2632 if (it->second.isValid())
2633 Score += it->second.Score;
2636 unsigned MaxRank = std::max(
Ops[i].Rank,
Ops[j].Rank);
2650 if (Score > Max || (Score == Max && MaxRank < BestRank)) {
2658 auto Op0 =
Ops[BestPair.first];
2659 auto Op1 =
Ops[BestPair.second];
2660 Ops.erase(&
Ops[BestPair.second]);
2661 Ops.erase(&
Ops[BestPair.first]);
2670 RewriteExprTree(
I,
Ops, Flags);
2674ReassociatePass::BuildPairMap(ReversePostOrderTraversal<Function *> &RPOT) {
2676 for (BasicBlock *BI : RPOT) {
2677 for (Instruction &
I : *BI) {
2678 if (!
I.isAssociative() || !
I.isBinaryOp())
2682 if (
I.hasOneUse() &&
I.user_back()->getOpcode() ==
I.getOpcode())
2688 SmallVector<Value *, 8> Worklist = {
I.getOperand(0),
I.getOperand(1) };
2689 SmallVector<Value *, 8>
Ops;
2690 while (!Worklist.
empty() &&
Ops.size() <= GlobalReassociateLimit) {
2704 if (
Ops.size() > GlobalReassociateLimit)
2708 unsigned BinaryIdx =
I.getOpcode() - Instruction::BinaryOpsBegin;
2709 SmallSet<std::pair<Value *, Value*>, 32> Visited;
2710 for (
unsigned i = 0; i <
Ops.size() - 1; ++i) {
2711 for (
unsigned j = i + 1;
j <
Ops.size(); ++
j) {
2715 if (std::less<Value *>()(Op1, Op0))
2717 if (!Visited.
insert({Op0, Op1}).second)
2719 auto res = PairMap[BinaryIdx].insert({{Op0, Op1}, {Op0, Op1, 1}});
2725 assert(res.first->second.isValid() &&
"WeakVH invalidated");
2726 ++res.first->second.Score;
2753 BuildRankMap(
F, RPOT);
2777 assert(
II->getParent() == &*BI &&
"Moved to a different block!");
2788 while (!ToRedo.
empty()) {
2791 RecursivelyEraseDeadInsts(
I, ToRedo);
2837 if (skipFunction(
F))
2841 getAnalysis<UniformityInfoWrapperPass>().getUniformityInfo();
2847 void getAnalysisUsage(AnalysisUsage &AU)
const override {
2857char ReassociateLegacyPass::ID = 0;
2860 "Reassociate expressions",
false,
false)
2867 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 getFirstNonPHIOrPseudoProbe() const
Returns an iterator to the first instruction in this block that is not a PHINode or a pseudo operatio...
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, true > m_FNegOrFSubNegZero(const OpTy &X)
Match fneg X or 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.
const ScalarOptions & getScalarOptions(const LLVMContext &C)
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.