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))
187 if (!
FAdd || !
FAdd->hasAllowContract())
194 Value *OtherOp =
nullptr;
203void ReassociatePass::BuildRankMap(
Function &
F,
204 ReversePostOrderTraversal<Function*> &RPOT) {
208 for (
auto &Arg :
F.args()) {
209 ValueRankMap[&Arg] = ++Rank;
210 LLVM_DEBUG(
dbgs() <<
"Calculated Rank[" << Arg.getName() <<
"] = " << Rank
215 for (BasicBlock *BB : RPOT) {
216 unsigned BBRank = RankMap[BB] = ++Rank << 16;
221 for (Instruction &
I : *BB)
223 ValueRankMap[&
I] = ++BBRank;
227unsigned ReassociatePass::getRank(
Value *V) {
231 struct RankWorkItem {
243 RankWorkItem &Item = Worklist.
back();
249 }
else if (ValueRankMap[
I]) {
251 Rank = ValueRankMap[
I];
252 }
else if (Item.OpNo ==
I->getNumOperands() ||
253 Item.Rank == RankMap[
I->getParent()]) {
262 LLVM_DEBUG(
dbgs() <<
"Calculated Rank[" <<
I->getName() <<
"] = " << Rank
265 ValueRankMap[
I] = Rank;
267 Worklist.
push_back(RankWorkItem{
I->getOperand(Item.OpNo), 0, 0});
274 if (Worklist.
empty())
277 RankWorkItem &Parent = Worklist.
back();
278 Parent.Rank = std::max(Parent.Rank, Rank);
284void ReassociatePass::canonicalizeOperands(Instruction *
I) {
286 assert(
I->isCommutative() &&
"Expected commutative operator.");
301 if (
S1->getType()->isIntOrIntVectorTy())
302 return BinaryOperator::CreateAdd(
S1, S2, Name, InsertBefore);
305 BinaryOperator::CreateFAdd(
S1, S2, Name, InsertBefore);
314 if (
S1->getType()->isIntOrIntVectorTy())
315 return BinaryOperator::CreateMul(
S1, S2, Name, InsertBefore);
318 BinaryOperator::CreateFMul(
S1, S2, Name, InsertBefore);
327 if (
S1->getType()->isIntOrIntVectorTy())
333 return UnaryOperator::CreateFNeg(
S1, Name, InsertBefore);
339 "Expected a Negate!");
343 Constant *NegOne = Ty->isIntOrIntVectorTy() ?
435 "Expected a UnaryOperator or BinaryOperator!");
437 unsigned Opcode =
I->getOpcode();
438 assert(
I->isAssociative() &&
I->isCommutative() &&
439 "Expected an associative and commutative operation!");
478 while (!Worklist.
empty()) {
482 Flags.mergeFlags(*
I);
484 for (
unsigned OpIdx = 0; OpIdx <
I->getNumOperands(); ++OpIdx) {
487 assert((!
Op->hasUseList() || !
Op->use_empty()) &&
488 "No uses, so how did we get to it?!");
496 Worklist.
push_back(std::make_pair(BO, Weight));
501 LeafMap::iterator It = Leaves.find(
Op);
502 if (It == Leaves.end()) {
505 if (!
Op->hasOneUse()) {
509 <<
"ADD USES LEAF: " << *
Op <<
" (" << Weight <<
")\n");
518 "In leaf map but not visited!");
521 It->second += Weight;
522 assert(It->second >= Weight &&
"Weight overflows");
526 if (!
Op->hasOneUse())
543 "Should have been handled above!");
544 assert(
Op->hasOneUse() &&
"Has uses outside the expression tree!");
556 <<
"MORPH LEAF: " << *
Op <<
" (" << Weight <<
") TO ");
573 "Value was morphed?");
581 for (
Value *V : LeafOrder) {
582 LeafMap::iterator It = Leaves.find(V);
583 if (It == Leaves.end())
587 "Shouldn't be a leaf!");
591 Ops.push_back(std::make_pair(V, Weight));
592 if (Opcode == Instruction::Add && Flags.AllKnownNonNegative && Flags.HasNSW)
594 else if (Opcode == Instruction::Mul) {
597 if (Flags.AllKnownNonZero &&
598 (Flags.HasNUW || (Flags.HasNSW && Flags.AllKnownNonNegative))) {
600 if (Flags.HasNSW && Flags.AllKnownNonNegative)
611 assert(Identity &&
"Associative operation without identity!");
612 Ops.emplace_back(Identity, 1);
620void ReassociatePass::RewriteExprTree(BinaryOperator *
I,
621 SmallVectorImpl<ValueEntry> &
Ops,
622 OverflowTracking Flags) {
623 assert(
Ops.size() > 1 &&
"Single values should be used directly!");
637 unsigned Opcode =
I->getOpcode();
638 BinaryOperator *
Op =
I;
650 SmallPtrSet<Value*, 8> NotRewritable;
658 BinaryOperator *ExpressionChangedStart =
nullptr,
659 *ExpressionChangedEnd =
nullptr;
660 for (
unsigned i = 0; ; ++i) {
664 if (i+2 ==
Ops.size()) {
667 Value *OldLHS =
Op->getOperand(0);
668 Value *OldRHS =
Op->getOperand(1);
670 if (NewLHS == OldLHS && NewRHS == OldRHS)
674 if (NewLHS == OldRHS && NewRHS == OldLHS) {
687 if (NewLHS != OldLHS) {
689 if (BO && !NotRewritable.
count(BO))
692 Op->setOperand(0, NewLHS);
694 if (NewRHS != OldRHS) {
696 if (BO && !NotRewritable.
count(BO))
699 Op->setOperand(1, NewRHS);
703 ExpressionChangedStart =
Op;
704 if (!ExpressionChangedEnd)
705 ExpressionChangedEnd =
Op;
715 if (NewRHS !=
Op->getOperand(1)) {
717 if (NewRHS ==
Op->getOperand(0)) {
724 if (BO && !NotRewritable.
count(BO))
727 Op->setOperand(1, NewRHS);
728 ExpressionChangedStart =
Op;
729 if (!ExpressionChangedEnd)
730 ExpressionChangedEnd =
Op;
741 if (BO && !NotRewritable.
count(BO)) {
753 BinaryOperator *NewOp;
754 if (NodesToRewrite.
empty()) {
766 Op->setOperand(0, NewOp);
768 ExpressionChangedStart =
Op;
769 if (!ExpressionChangedEnd)
770 ExpressionChangedEnd =
Op;
780 if (ExpressionChangedStart) {
781 bool ClearFlags =
true;
788 Flags.applyFlags(*ExpressionChangedStart);
792 if (ExpressionChangedStart == ExpressionChangedEnd)
794 if (ExpressionChangedStart ==
I)
797 ExpressionChangedStart->
moveBefore(
I->getIterator());
798 ExpressionChangedStart =
804 RedoInsts.insert_range(NodesToRewrite);
818 Constant *Res =
C->getType()->isFPOrFPVectorTy()
839 if (
I->getOpcode() == Instruction::Add) {
840 I->setHasNoUnsignedWrap(
false);
841 I->setHasNoSignedWrap(
false);
850 I->setName(
I->getName()+
".neg");
873 C->containsUndefOrPoisonElement())
883 auto InsertPtOpt = InstInput->getInsertionPointAfterDef();
886 InsertPt = *InsertPtOpt;
897 if (TheNeg->
getParent() != InsertPt->getParent())
899 TheNeg->
moveBefore(*InsertPt->getParent(), InsertPt);
901 if (TheNeg->
getOpcode() == Instruction::Sub) {
930 auto Enqueue = [&](
Value *V) {
944 while (!Worklist.
empty()) {
948 switch (
I->getOpcode()) {
949 case Instruction::Or:
956 case Instruction::Shl:
957 case Instruction::ZExt:
959 if (!Enqueue(
I->getOperand(0)))
963 case Instruction::Load:
981 for (
auto Op : {Instruction::Add, Instruction::Sub, Instruction::Mul,
1003 Or->getIterator(),
Or);
1004 New->setHasNoSignedWrap();
1005 New->setHasNoUnsignedWrap();
1009 Or->replaceAllUsesWith(New);
1010 New->setDebugLoc(
Or->getDebugLoc());
1012 LLVM_DEBUG(
dbgs() <<
"Converted or into an add: " << *New <<
'\n');
1030 if (MulUser->getOpcode() != Instruction::Add &&
1031 MulUser->getOpcode() != Instruction::Sub)
1034 for (
Value *Sibling : MulUser->operands()) {
1035 if (Sibling ==
Mul || !Sibling->hasOneUse())
1058 "Mul1",
Mul->getIterator());
1059 BinaryOperator *M2 = BinaryOperator::CreateMul(AddSub->getOperand(1), C2,
1060 "Mul2",
Mul->getIterator());
1062 BinaryOperator::CreateAdd(
M1, M2,
"DistAdd",
Mul->getIterator());
1064 Mul->replaceAllUsesWith(Result);
1065 Result->setDebugLoc(
Mul->getDebugLoc());
1095 if (
Sub->hasOneUse() &&
1120 Sub->replaceAllUsesWith(New);
1121 New->setDebugLoc(
Sub->getDebugLoc());
1133 assert(MulCst &&
"Constant folding of immediate constants failed");
1151 if (NSW && (NUW || SA->getValue().ult(
BitWidth - 1)))
1152 Mul->setHasNoSignedWrap(
true);
1153 Mul->setHasNoUnsignedWrap(NUW);
1162 unsigned XRank =
Ops[i].Rank;
1163 unsigned e =
Ops.size();
1164 for (
unsigned j = i+1; j != e &&
Ops[j].Rank == XRank; ++j) {
1169 if (I1->isIdenticalTo(I2))
1173 for (
unsigned j = i-1; j != ~0U &&
Ops[j].Rank == XRank; --j) {
1178 if (I1->isIdenticalTo(I2))
1188 if (
Ops.size() == 1)
return Ops.back();
1192 auto *NewAdd =
CreateAdd(V2,
V1,
"reass.add",
I->getIterator(),
I);
1193 NewAdd->setDebugLoc(
I->getDebugLoc());
1204 BinaryOperator *BO =
isReassociableOp(V, Instruction::Mul, Instruction::FMul);
1209 OverflowTracking
Flags;
1216 bool FoundFactor =
false;
1217 bool NeedsNegate =
false;
1218 for (
unsigned i = 0, e = Factors.
size(); i != e; ++i) {
1228 if (FC1->getValue() == -FC2->getValue()) {
1229 FoundFactor = NeedsNegate =
true;
1235 const APFloat &F1 = FC1->getValueAPF();
1236 APFloat F2(FC2->getValueAPF());
1239 FoundFactor = NeedsNegate =
true;
1249 RewriteExprTree(BO, Factors, Flags);
1257 if (Factors.
size() == 1) {
1258 RedoInsts.insert(BO);
1261 RewriteExprTree(BO, Factors, Flags);
1297 for (
unsigned i = 0, e =
Ops.size(); i != e; ++i) {
1304 if (Opcode == Instruction::And)
1307 if (Opcode == Instruction::Or)
1315 if (i+1 !=
Ops.size() &&
Ops[i+1].Op ==
Ops[i].Op) {
1316 if (Opcode == Instruction::And || Opcode == Instruction::Or) {
1318 Ops.erase(
Ops.begin()+i);
1325 assert(Opcode == Instruction::Xor);
1330 Ops.erase(
Ops.begin()+i,
Ops.begin()+i+2);
1344 const APInt &ConstOpnd) {
1352 Opnd, ConstantInt::get(Opnd->
getType(), ConstOpnd),
"and.ra",
1354 I->setDebugLoc(InsertBefore->getDebugLoc());
1365 APInt &ConstOpnd,
Value *&Res) {
1377 if (C1 != ConstOpnd)
1386 RedoInsts.insert(
T);
1399 XorOpnd *Opnd2, APInt &ConstOpnd,
1406 int DeadInstNum = 1;
1424 APInt C3((~C1) ^ C2);
1427 if (!C3.isZero() && !C3.isAllOnes()) {
1429 if (NewInstNum > DeadInstNum)
1445 if (NewInstNum > DeadInstNum)
1463 RedoInsts.insert(
T);
1465 RedoInsts.insert(
T);
1473Value *ReassociatePass::OptimizeXor(Instruction *
I,
1474 SmallVectorImpl<ValueEntry> &
Ops) {
1478 if (
Ops.size() == 1)
1483 Type *Ty =
Ops[0].Op->getType();
1495 O.setSymbolicRank(getRank(
O.getSymbolicPart()));
1522 return LHS->getSymbolicRank() <
RHS->getSymbolicRank();
1528 for (
unsigned i = 0, e = Opnds.size(); i < e; i++) {
1529 XorOpnd *CurrOpnd = OpndPtrs[i];
1534 if (!ConstOpnd.
isZero() &&
1535 CombineXorOpnd(
I->getIterator(), CurrOpnd, ConstOpnd, CV)) {
1545 if (!PrevOpnd || CurrOpnd->
getSymbolicPart() != PrevOpnd->getSymbolicPart()) {
1546 PrevOpnd = CurrOpnd;
1552 if (CombineXorOpnd(
I->getIterator(), CurrOpnd, PrevOpnd, ConstOpnd, CV)) {
1554 PrevOpnd->Invalidate();
1557 PrevOpnd = CurrOpnd;
1569 for (
const XorOpnd &O : Opnds) {
1575 if (!ConstOpnd.
isZero()) {
1576 Value *
C = ConstantInt::get(Ty, ConstOpnd);
1580 unsigned Sz =
Ops.size();
1582 return Ops.back().Op;
1585 return ConstantInt::get(Ty, ConstOpnd);
1595Value *ReassociatePass::OptimizeAdd(Instruction *
I,
1596 SmallVectorImpl<ValueEntry> &
Ops) {
1602 for (
unsigned i = 0, e =
Ops.size(); i != e; ++i) {
1607 if (i+1 !=
Ops.size() &&
Ops[i+1].Op == TheOp) {
1609 unsigned NumFound = 0;
1611 Ops.erase(
Ops.begin()+i);
1613 }
while (i !=
Ops.size() &&
Ops[i].Op == TheOp);
1615 LLVM_DEBUG(
dbgs() <<
"\nFACTORING [" << NumFound <<
"]: " << *TheOp
1623 ? ConstantInt::get(Ty, NumFound,
false,
1627 Mul->setDebugLoc(
I->getDebugLoc());
1632 RedoInsts.insert(
Mul);
1659 if (
Ops.size() == 2 &&
1667 Ops.erase(
Ops.begin()+i);
1672 Ops.erase(
Ops.begin()+FoundX);
1690 DenseMap<Value*, unsigned> FactorOccurrences;
1694 unsigned MaxOcc = 0;
1695 Value *MaxOccVal =
nullptr;
1702 return Occ > MaxOcc ||
1707 auto CountFactors = [&](BinaryOperator *BOp) {
1709 SmallVector<Value*, 8> Factors;
1711 assert(Factors.
size() > 1 &&
"Bad linearize!");
1714 SmallPtrSet<Value*, 8> Duplicates;
1719 unsigned Occ = ++FactorOccurrences[
Factor];
1720 if (IsBetterFactor(
Factor, MaxOccVal, Occ, MaxOcc)) {
1729 if (CI->isNegative() && !CI->isMinValue(
true)) {
1730 Factor = ConstantInt::get(CI->getContext(), -CI->getValue());
1733 unsigned Occ = ++FactorOccurrences[
Factor];
1734 if (IsBetterFactor(
Factor, MaxOccVal, Occ, MaxOcc)) {
1740 if (CF->isNegative()) {
1743 Factor = ConstantFP::get(CF->getType(),
F);
1746 unsigned Occ = ++FactorOccurrences[
Factor];
1747 if (IsBetterFactor(
Factor, MaxOccVal, Occ, MaxOcc)) {
1761 if (BinaryOperator *BOp =
1774 for (
Value *V : FMulAddCands) {
1777 Ops.emplace_back(getRank(
Op),
Op);
1783 LLVM_DEBUG(
dbgs() <<
"\nFACTORING [" << MaxOcc <<
"]: " << *MaxOccVal
1792 I->getType()->isIntOrIntVectorTy()
1793 ? BinaryOperator::CreateAdd(MaxOccVal, MaxOccVal)
1794 : BinaryOperator::CreateFAdd(MaxOccVal, MaxOccVal);
1797 for (
unsigned i = 0; i !=
Ops.size(); ++i) {
1799 BinaryOperator *BOp =
1804 if (
Value *V = RemoveFactorFromExpression(
Ops[i].
Op, MaxOccVal,
1805 I->getDebugLoc())) {
1808 for (
unsigned j =
Ops.size(); j != i;) {
1812 Ops.erase(
Ops.begin()+j);
1822 unsigned NumAddedValues = NewMulOps.
size();
1828 assert(NumAddedValues > 1 &&
"Each occurrence should contribute a value");
1829 (void)NumAddedValues;
1831 RedoInsts.insert(VI);
1839 RedoInsts.insert(V2);
1870 unsigned FactorPowerSum = 0;
1871 for (
unsigned Idx = 1,
Size =
Ops.size(); Idx <
Size; ++Idx) {
1876 for (; Idx <
Size &&
Ops[Idx].Op ==
Op; ++Idx)
1880 FactorPowerSum +=
Count;
1887 if (FactorPowerSum < 4)
1892 for (
unsigned Idx = 1; Idx <
Ops.size(); ++Idx) {
1897 for (; Idx <
Ops.size() &&
Ops[Idx].
Op ==
Op; ++Idx)
1904 FactorPowerSum +=
Count;
1911 assert(FactorPowerSum >= 4);
1914 return LHS.Power >
RHS.Power;
1922 if (
Ops.size() == 1)
1927 if (
LHS->getType()->isIntOrIntVectorTy())
1928 LHS = Builder.CreateMul(
LHS,
Ops.pop_back_val());
1930 LHS = Builder.CreateFMul(
LHS,
Ops.pop_back_val());
1931 }
while (!
Ops.empty());
1943ReassociatePass::buildMinimalMultiplyDAG(IRBuilderBase &Builder,
1944 SmallVectorImpl<Factor> &Factors) {
1945 assert(Factors[0].Power);
1946 SmallVector<Value *, 4> OuterProduct;
1947 for (
unsigned LastIdx = 0, Idx = 1,
Size = Factors.
size();
1948 Idx <
Size && Factors[Idx].Power > 0; ++Idx) {
1949 if (Factors[Idx].Power != Factors[LastIdx].Power) {
1957 SmallVector<Value *, 4> InnerProduct;
1962 }
while (Idx <
Size && Factors[Idx].Power == Factors[LastIdx].Power);
1968 RedoInsts.insert(
MI);
1976 return LHS.Power ==
RHS.Power;
1988 if (Factors[0].Power) {
1989 Value *SquareRoot = buildMinimalMultiplyDAG(Builder, Factors);
1993 if (OuterProduct.
size() == 1)
1994 return OuterProduct.
front();
2000Value *ReassociatePass::OptimizeMul(BinaryOperator *
I,
2001 SmallVectorImpl<ValueEntry> &
Ops) {
2021 Value *
V = buildMinimalMultiplyDAG(Builder, Factors);
2030Value *ReassociatePass::OptimizeExpression(BinaryOperator *
I,
2031 SmallVectorImpl<ValueEntry> &
Ops) {
2034 const DataLayout &
DL =
I->getDataLayout();
2036 unsigned Opcode =
I->getOpcode();
2037 while (!
Ops.empty()) {
2065 if (
Ops.size() == 1)
return Ops[0].
Op;
2072 case Instruction::And:
2073 case Instruction::Or:
2078 case Instruction::Xor:
2079 if (
Value *Result = OptimizeXor(
I,
Ops))
2083 case Instruction::Add:
2084 case Instruction::FAdd:
2085 if (
Value *Result = OptimizeAdd(
I,
Ops))
2089 case Instruction::Mul:
2090 case Instruction::FMul:
2091 if (
Value *Result = OptimizeMul(
I,
Ops))
2097 return OptimizeExpression(
I,
Ops);
2103void ReassociatePass::RecursivelyEraseDeadInsts(Instruction *
I,
2104 OrderedSet &Insts) {
2106 SmallVector<Value *, 4>
Ops(
I->operands());
2107 ValueRankMap.erase(
I);
2109 RedoInsts.remove(
I);
2113 I->eraseFromParent();
2114 for (
auto *
Op :
Ops)
2116 if (OpInst->use_empty())
2117 Insts.insert(OpInst);
2121void ReassociatePass::EraseInst(Instruction *
I) {
2125 SmallVector<Value *, 8>
Ops(
I->operands());
2127 ValueRankMap.erase(
I);
2128 RedoInsts.remove(
I);
2132 I->eraseFromParent();
2134 SmallPtrSet<Instruction *, 8> Visited;
2139 unsigned Opcode =
Op->getOpcode();
2140 while (
Op->hasOneUse() &&
Op->user_back()->getOpcode() == Opcode &&
2142 Op =
Op->user_back();
2149 if (ValueRankMap.contains(
Op))
2150 RedoInsts.insert(
Op);
2170 switch (
I->getOpcode()) {
2171 case Instruction::FMul:
2183 case Instruction::FDiv:
2205Instruction *ReassociatePass::canonicalizeNegFPConstantsForOp(Instruction *
I,
2208 assert((
I->getOpcode() == Instruction::FAdd ||
2209 I->getOpcode() == Instruction::FSub) &&
"Expected fadd/fsub");
2213 SmallVector<Instruction *, 4> Candidates;
2215 if (Candidates.
empty())
2221 bool IsFSub =
I->getOpcode() == Instruction::FSub;
2222 bool NeedsSubtract = !IsFSub && Candidates.
size() % 2 == 1;
2226 for (Instruction *Negatible : Candidates) {
2230 "Expecting only 1 constant operand");
2231 assert(
C->isNegative() &&
"Expected negative FP constant");
2232 Negatible->setOperand(0, ConstantFP::get(Negatible->getType(),
abs(*
C)));
2237 "Expecting only 1 constant operand");
2238 assert(
C->isNegative() &&
"Expected negative FP constant");
2239 Negatible->setOperand(1, ConstantFP::get(Negatible->getType(),
abs(*
C)));
2243 assert(MadeChange ==
true &&
"Negative constant candidate was not changed");
2246 if (Candidates.size() % 2 == 0)
2251 assert(Candidates.size() % 2 == 1 &&
"Expected odd number");
2256 RedoInsts.insert(
I);
2268Instruction *ReassociatePass::canonicalizeNegFPConstants(Instruction *
I) {
2273 if (Instruction *R = canonicalizeNegFPConstantsForOp(
I,
Op,
X))
2276 if (Instruction *R = canonicalizeNegFPConstantsForOp(
I,
Op,
X))
2279 if (Instruction *R = canonicalizeNegFPConstantsForOp(
I,
Op,
X))
2286void ReassociatePass::OptimizeInst(Instruction *
I) {
2299 RedoInsts.insert(
I);
2307 if (
I->isCommutative())
2308 canonicalizeOperands(
I);
2311 if (Instruction *Res = canonicalizeNegFPConstants(
I))
2326 if (
I->getType()->isIntOrIntVectorTy(1))
2331 if (
I->getOpcode() == Instruction::Or &&
2335 SimplifyQuery(
I->getDataLayout(),
2336 nullptr,
nullptr,
I)))) {
2338 RedoInsts.insert(
I);
2346 RedoInsts.insert(
I);
2347 RedoInsts.insert(MulUser);
2354 if (
I->getOpcode() == Instruction::Sub) {
2357 RedoInsts.insert(
I);
2369 for (User *U : NI->
users()) {
2371 RedoInsts.insert(Tmp);
2373 RedoInsts.insert(
I);
2378 }
else if (
I->getOpcode() == Instruction::FNeg ||
2379 I->getOpcode() == Instruction::FSub) {
2382 RedoInsts.insert(
I);
2396 for (User *U : NI->
users()) {
2398 RedoInsts.insert(Tmp);
2400 RedoInsts.insert(
I);
2408 if (!
I->isAssociative())
return;
2433 ReassociateExpression(BO);
2436void ReassociatePass::ReassociateExpression(BinaryOperator *
I) {
2440 OverflowTracking
Flags;
2455 if (UA &&
Ops.size() > 2) {
2456 constexpr unsigned DivergentRankOffset = 1U << 28;
2461 bool Divergent =
false;
2462 for (
const Use &U :
Entry.Op->uses()) {
2464 if (Usr && Usr->
getParent() == ParentBB) {
2465 Divergent = UA->isDivergentAtUse(U);
2470 Entry.Rank += DivergentRankOffset;
2484 if (
Value *V = OptimizeExpression(
I,
Ops)) {
2491 I->replaceAllUsesWith(V);
2493 if (
I->getDebugLoc())
2494 VI->setDebugLoc(
I->getDebugLoc());
2495 RedoInsts.insert(
I);
2504 if (
I->hasOneUse()) {
2505 if (
I->getOpcode() == Instruction::Mul &&
2510 Ops.insert(
Ops.begin(), Tmp);
2511 }
else if (
I->getOpcode() == Instruction::FMul &&
2513 Instruction::FAdd &&
2517 Ops.insert(
Ops.begin(), Tmp);
2523 if (
Ops.size() == 1) {
2530 I->replaceAllUsesWith(
Ops[0].
Op);
2532 OI->setDebugLoc(
I->getDebugLoc());
2533 RedoInsts.insert(
I);
2537 if (
Ops.size() > 2 &&
Ops.size() <= GlobalReassociateLimit) {
2545 unsigned BestRank = 0;
2546 std::pair<unsigned, unsigned> BestPair;
2547 unsigned Idx =
I->getOpcode() - Instruction::BinaryOpsBegin;
2548 unsigned LimitIdx = 0;
2558 int StartIdx =
Ops.size() - 1;
2563 for (
int i = StartIdx - 1; i != -1; --i) {
2567 if (!CurrLeafInstr) {
2592 FirstSeenBB = SeenBB;
2595 if (FirstSeenBB != SeenBB) {
2601 << LimitIdx <<
", " << StartIdx <<
"]\n");
2606 for (
unsigned i =
Ops.size() - 1; i > LimitIdx; --i) {
2608 for (
int j = i - 1;
j >= (int)LimitIdx; --
j) {
2612 if (std::less<Value *>()(Op1, Op0))
2614 auto it = PairMap[Idx].find({Op0, Op1});
2615 if (it != PairMap[Idx].
end()) {
2621 if (it->second.isValid())
2622 Score += it->second.Score;
2625 unsigned MaxRank = std::max(
Ops[i].Rank,
Ops[j].Rank);
2639 if (Score > Max || (Score == Max && MaxRank < BestRank)) {
2647 auto Op0 =
Ops[BestPair.first];
2648 auto Op1 =
Ops[BestPair.second];
2649 Ops.erase(&
Ops[BestPair.second]);
2650 Ops.erase(&
Ops[BestPair.first]);
2659 RewriteExprTree(
I,
Ops, Flags);
2663ReassociatePass::BuildPairMap(ReversePostOrderTraversal<Function *> &RPOT) {
2665 for (BasicBlock *BI : RPOT) {
2666 for (Instruction &
I : *BI) {
2667 if (!
I.isAssociative() || !
I.isBinaryOp())
2671 if (
I.hasOneUse() &&
I.user_back()->getOpcode() ==
I.getOpcode())
2677 SmallVector<Value *, 8> Worklist = {
I.getOperand(0),
I.getOperand(1) };
2678 SmallVector<Value *, 8>
Ops;
2679 while (!Worklist.
empty() &&
Ops.size() <= GlobalReassociateLimit) {
2693 if (
Ops.size() > GlobalReassociateLimit)
2697 unsigned BinaryIdx =
I.getOpcode() - Instruction::BinaryOpsBegin;
2698 SmallSet<std::pair<Value *, Value*>, 32> Visited;
2699 for (
unsigned i = 0; i <
Ops.size() - 1; ++i) {
2700 for (
unsigned j = i + 1;
j <
Ops.size(); ++
j) {
2704 if (std::less<Value *>()(Op1, Op0))
2706 if (!Visited.
insert({Op0, Op1}).second)
2708 auto res = PairMap[BinaryIdx].insert({{Op0, Op1}, {Op0, Op1, 1}});
2714 assert(res.first->second.isValid() &&
"WeakVH invalidated");
2715 ++res.first->second.Score;
2741 BuildRankMap(
F, RPOT);
2765 assert(
II->getParent() == &*BI &&
"Moved to a different block!");
2776 while (!ToRedo.
empty()) {
2779 RecursivelyEraseDeadInsts(
I, ToRedo);
2825 if (skipFunction(
F))
2829 getAnalysis<UniformityInfoWrapperPass>().getUniformityInfo();
2835 void getAnalysisUsage(AnalysisUsage &AU)
const override {
2845char ReassociateLegacyPass::ID = 0;
2848 "Reassociate expressions",
false,
false)
2855 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.