68#define DEBUG_TYPE "reassociate"
70STATISTIC(NumChanged,
"Number of insts reassociated");
71STATISTIC(NumAnnihil,
"Number of expr tree annihilated");
72STATISTIC(NumFactor ,
"Number of multiplies factored");
76 cl::desc(
"Only reorder expressions within a basic block "
77 "when exposing CSE opportunities"),
85 << *
Ops[0].Op->getType() <<
'\t';
88 Op.Op->printAsOperand(
dbgs(),
false, M);
89 dbgs() <<
", #" <<
Op.Rank <<
"] ";
106 bool isInvalid()
const {
return SymbolicPart ==
nullptr; }
120 unsigned SymbolicRank;
130 if (
I && (
I->getOpcode() == Instruction::Or ||
131 I->getOpcode() == Instruction::And)) {
132 Value *V0 =
I->getOperand(0);
141 isOr = (
I->getOpcode() == Instruction::Or);
158 return I->hasAllowReassoc() &&
I->hasNoSignedZeros();
165 if (BO && BO->hasOneUse() && BO->getOpcode() == Opcode)
174 if (BO && BO->hasOneUse() &&
175 (BO->getOpcode() == Opcode1 || BO->getOpcode() == Opcode2))
191 if (!
FAdd || !
FAdd->hasAllowContract())
198 Value *OtherOp =
nullptr;
209void ReassociatePass::BuildRankMap(
Function &
F,
210 ReversePostOrderTraversal<Function*> &RPOT) {
214 for (
auto &Arg :
F.args()) {
215 ValueRankMap[&Arg] = ++Rank;
216 LLVM_DEBUG(
dbgs() <<
"Calculated Rank[" << Arg.getName() <<
"] = " << Rank
221 for (BasicBlock *BB : RPOT) {
222 unsigned BBRank = RankMap[BB] = ++Rank << 16;
227 for (Instruction &
I : *BB)
229 ValueRankMap[&
I] = ++BBRank;
233unsigned ReassociatePass::getRank(
Value *V) {
237 struct RankWorkItem {
249 RankWorkItem &Item = Worklist.
back();
255 }
else if (ValueRankMap[
I]) {
257 Rank = ValueRankMap[
I];
258 }
else if (Item.OpNo ==
I->getNumOperands() ||
259 Item.Rank == RankMap[
I->getParent()]) {
268 LLVM_DEBUG(
dbgs() <<
"Calculated Rank[" <<
I->getName() <<
"] = " << Rank
271 ValueRankMap[
I] = Rank;
273 Worklist.
push_back(RankWorkItem{
I->getOperand(Item.OpNo), 0, 0});
280 if (Worklist.
empty())
283 RankWorkItem &Parent = Worklist.
back();
284 Parent.Rank = std::max(Parent.Rank, Rank);
290void ReassociatePass::canonicalizeOperands(Instruction *
I) {
292 assert(
I->isCommutative() &&
"Expected commutative operator.");
307 if (
S1->getType()->isIntOrIntVectorTy())
308 return BinaryOperator::CreateAdd(
S1, S2, Name, InsertBefore);
311 BinaryOperator::CreateFAdd(
S1, S2, Name, InsertBefore);
320 if (
S1->getType()->isIntOrIntVectorTy())
321 return BinaryOperator::CreateMul(
S1, S2, Name, InsertBefore);
324 BinaryOperator::CreateFMul(
S1, S2, Name, InsertBefore);
333 if (
S1->getType()->isIntOrIntVectorTy())
339 return UnaryOperator::CreateFNeg(
S1, Name, InsertBefore);
345 "Expected a Negate!");
349 Constant *NegOne = Ty->isIntOrIntVectorTy() ?
441 "Expected a UnaryOperator or BinaryOperator!");
443 unsigned Opcode =
I->getOpcode();
444 assert(
I->isAssociative() &&
I->isCommutative() &&
445 "Expected an associative and commutative operation!");
484 while (!Worklist.
empty()) {
488 Flags.mergeFlags(*
I);
490 for (
unsigned OpIdx = 0; OpIdx <
I->getNumOperands(); ++OpIdx) {
493 assert((!
Op->hasUseList() || !
Op->use_empty()) &&
494 "No uses, so how did we get to it?!");
502 Worklist.
push_back(std::make_pair(BO, Weight));
507 LeafMap::iterator It = Leaves.find(
Op);
508 if (It == Leaves.end()) {
511 if (!
Op->hasOneUse()) {
515 <<
"ADD USES LEAF: " << *
Op <<
" (" << Weight <<
")\n");
524 "In leaf map but not visited!");
527 It->second += Weight;
528 assert(It->second >= Weight &&
"Weight overflows");
532 if (!
Op->hasOneUse())
549 "Should have been handled above!");
550 assert(
Op->hasOneUse() &&
"Has uses outside the expression tree!");
562 <<
"MORPH LEAF: " << *
Op <<
" (" << Weight <<
") TO ");
579 "Value was morphed?");
587 for (
Value *V : LeafOrder) {
588 LeafMap::iterator It = Leaves.find(V);
589 if (It == Leaves.end())
593 "Shouldn't be a leaf!");
597 Ops.push_back(std::make_pair(V, Weight));
598 if (Opcode == Instruction::Add && Flags.AllKnownNonNegative && Flags.HasNSW)
600 else if (Opcode == Instruction::Mul) {
603 if (Flags.AllKnownNonZero &&
604 (Flags.HasNUW || (Flags.HasNSW && Flags.AllKnownNonNegative))) {
606 if (Flags.HasNSW && Flags.AllKnownNonNegative)
617 assert(Identity &&
"Associative operation without identity!");
618 Ops.emplace_back(Identity, 1);
626void ReassociatePass::RewriteExprTree(BinaryOperator *
I,
627 SmallVectorImpl<ValueEntry> &
Ops,
628 OverflowTracking Flags) {
629 assert(
Ops.size() > 1 &&
"Single values should be used directly!");
643 unsigned Opcode =
I->getOpcode();
644 BinaryOperator *
Op =
I;
656 SmallPtrSet<Value*, 8> NotRewritable;
664 BinaryOperator *ExpressionChangedStart =
nullptr,
665 *ExpressionChangedEnd =
nullptr;
666 for (
unsigned i = 0; ; ++i) {
670 if (i+2 ==
Ops.size()) {
673 Value *OldLHS =
Op->getOperand(0);
674 Value *OldRHS =
Op->getOperand(1);
676 if (NewLHS == OldLHS && NewRHS == OldRHS)
680 if (NewLHS == OldRHS && NewRHS == OldLHS) {
693 if (NewLHS != OldLHS) {
695 if (BO && !NotRewritable.
count(BO))
698 Op->setOperand(0, NewLHS);
700 if (NewRHS != OldRHS) {
702 if (BO && !NotRewritable.
count(BO))
705 Op->setOperand(1, NewRHS);
709 ExpressionChangedStart =
Op;
710 if (!ExpressionChangedEnd)
711 ExpressionChangedEnd =
Op;
721 if (NewRHS !=
Op->getOperand(1)) {
723 if (NewRHS ==
Op->getOperand(0)) {
730 if (BO && !NotRewritable.
count(BO))
733 Op->setOperand(1, NewRHS);
734 ExpressionChangedStart =
Op;
735 if (!ExpressionChangedEnd)
736 ExpressionChangedEnd =
Op;
747 if (BO && !NotRewritable.
count(BO)) {
759 BinaryOperator *NewOp;
760 if (NodesToRewrite.
empty()) {
772 Op->setOperand(0, NewOp);
774 ExpressionChangedStart =
Op;
775 if (!ExpressionChangedEnd)
776 ExpressionChangedEnd =
Op;
786 if (ExpressionChangedStart) {
787 bool ClearFlags =
true;
794 Flags.applyFlags(*ExpressionChangedStart);
798 if (ExpressionChangedStart == ExpressionChangedEnd)
800 if (ExpressionChangedStart ==
I)
803 ExpressionChangedStart->
moveBefore(
I->getIterator());
804 ExpressionChangedStart =
810 RedoInsts.insert_range(NodesToRewrite);
824 Constant *Res =
C->getType()->isFPOrFPVectorTy()
845 if (
I->getOpcode() == Instruction::Add) {
846 I->setHasNoUnsignedWrap(
false);
847 I->setHasNoSignedWrap(
false);
856 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());
1101 if (
Sub->hasOneUse() &&
1126 Sub->replaceAllUsesWith(New);
1127 New->setDebugLoc(
Sub->getDebugLoc());
1139 assert(MulCst &&
"Constant folding of immediate constants failed");
1157 if (NSW && (NUW || SA->getValue().ult(
BitWidth - 1)))
1158 Mul->setHasNoSignedWrap(
true);
1159 Mul->setHasNoUnsignedWrap(NUW);
1168 unsigned XRank =
Ops[i].Rank;
1169 unsigned e =
Ops.size();
1170 for (
unsigned j = i+1; j != e &&
Ops[j].Rank == XRank; ++j) {
1175 if (I1->isIdenticalTo(I2))
1179 for (
unsigned j = i-1; j != ~0U &&
Ops[j].Rank == XRank; --j) {
1184 if (I1->isIdenticalTo(I2))
1194 if (
Ops.size() == 1)
return Ops.back();
1198 auto *NewAdd =
CreateAdd(V2,
V1,
"reass.add",
I->getIterator(),
I);
1199 NewAdd->setDebugLoc(
I->getDebugLoc());
1210 BinaryOperator *BO =
isReassociableOp(V, Instruction::Mul, Instruction::FMul);
1215 OverflowTracking
Flags;
1222 bool FoundFactor =
false;
1223 bool NeedsNegate =
false;
1224 for (
unsigned i = 0, e = Factors.
size(); i != e; ++i) {
1234 if (FC1->getValue() == -FC2->getValue()) {
1235 FoundFactor = NeedsNegate =
true;
1241 const APFloat &F1 = FC1->getValueAPF();
1242 APFloat F2(FC2->getValueAPF());
1245 FoundFactor = NeedsNegate =
true;
1255 RewriteExprTree(BO, Factors, Flags);
1263 if (Factors.
size() == 1) {
1264 RedoInsts.insert(BO);
1267 RewriteExprTree(BO, Factors, Flags);
1303 for (
unsigned i = 0, e =
Ops.size(); i != e; ++i) {
1310 if (Opcode == Instruction::And)
1313 if (Opcode == Instruction::Or)
1321 if (i+1 !=
Ops.size() &&
Ops[i+1].Op ==
Ops[i].Op) {
1322 if (Opcode == Instruction::And || Opcode == Instruction::Or) {
1324 Ops.erase(
Ops.begin()+i);
1331 assert(Opcode == Instruction::Xor);
1336 Ops.erase(
Ops.begin()+i,
Ops.begin()+i+2);
1350 const APInt &ConstOpnd) {
1358 Opnd, ConstantInt::get(Opnd->
getType(), ConstOpnd),
"and.ra",
1360 I->setDebugLoc(InsertBefore->getDebugLoc());
1371 APInt &ConstOpnd,
Value *&Res) {
1383 if (C1 != ConstOpnd)
1392 RedoInsts.insert(
T);
1405 XorOpnd *Opnd2, APInt &ConstOpnd,
1412 int DeadInstNum = 1;
1430 APInt C3((~C1) ^ C2);
1433 if (!C3.isZero() && !C3.isAllOnes()) {
1435 if (NewInstNum > DeadInstNum)
1451 if (NewInstNum > DeadInstNum)
1469 RedoInsts.insert(
T);
1471 RedoInsts.insert(
T);
1479Value *ReassociatePass::OptimizeXor(Instruction *
I,
1480 SmallVectorImpl<ValueEntry> &
Ops) {
1484 if (
Ops.size() == 1)
1489 Type *Ty =
Ops[0].Op->getType();
1501 O.setSymbolicRank(getRank(
O.getSymbolicPart()));
1528 return LHS->getSymbolicRank() <
RHS->getSymbolicRank();
1534 for (
unsigned i = 0, e = Opnds.size(); i < e; i++) {
1535 XorOpnd *CurrOpnd = OpndPtrs[i];
1540 if (!ConstOpnd.
isZero() &&
1541 CombineXorOpnd(
I->getIterator(), CurrOpnd, ConstOpnd, CV)) {
1551 if (!PrevOpnd || CurrOpnd->
getSymbolicPart() != PrevOpnd->getSymbolicPart()) {
1552 PrevOpnd = CurrOpnd;
1558 if (CombineXorOpnd(
I->getIterator(), CurrOpnd, PrevOpnd, ConstOpnd, CV)) {
1560 PrevOpnd->Invalidate();
1563 PrevOpnd = CurrOpnd;
1575 for (
const XorOpnd &O : Opnds) {
1581 if (!ConstOpnd.
isZero()) {
1582 Value *
C = ConstantInt::get(Ty, ConstOpnd);
1586 unsigned Sz =
Ops.size();
1588 return Ops.back().Op;
1591 return ConstantInt::get(Ty, ConstOpnd);
1601Value *ReassociatePass::OptimizeAdd(Instruction *
I,
1602 SmallVectorImpl<ValueEntry> &
Ops) {
1608 for (
unsigned i = 0, e =
Ops.size(); i != e; ++i) {
1613 if (i+1 !=
Ops.size() &&
Ops[i+1].Op == TheOp) {
1615 unsigned NumFound = 0;
1617 Ops.erase(
Ops.begin()+i);
1619 }
while (i !=
Ops.size() &&
Ops[i].Op == TheOp);
1621 LLVM_DEBUG(
dbgs() <<
"\nFACTORING [" << NumFound <<
"]: " << *TheOp
1629 ? ConstantInt::get(Ty, NumFound,
false,
1633 Mul->setDebugLoc(
I->getDebugLoc());
1638 RedoInsts.insert(
Mul);
1665 if (
Ops.size() == 2 &&
1673 Ops.erase(
Ops.begin()+i);
1678 Ops.erase(
Ops.begin()+FoundX);
1696 DenseMap<Value*, unsigned> FactorOccurrences;
1700 unsigned MaxOcc = 0;
1701 Value *MaxOccVal =
nullptr;
1708 return Occ > MaxOcc ||
1713 auto CountFactors = [&](BinaryOperator *BOp) {
1715 SmallVector<Value*, 8> Factors;
1717 assert(Factors.
size() > 1 &&
"Bad linearize!");
1720 SmallPtrSet<Value*, 8> Duplicates;
1725 unsigned Occ = ++FactorOccurrences[
Factor];
1726 if (IsBetterFactor(
Factor, MaxOccVal, Occ, MaxOcc)) {
1735 if (CI->isNegative() && !CI->isMinValue(
true)) {
1736 Factor = ConstantInt::get(CI->getContext(), -CI->getValue());
1739 unsigned Occ = ++FactorOccurrences[
Factor];
1740 if (IsBetterFactor(
Factor, MaxOccVal, Occ, MaxOcc)) {
1746 if (CF->isNegative()) {
1749 Factor = ConstantFP::get(CF->getType(),
F);
1752 unsigned Occ = ++FactorOccurrences[
Factor];
1753 if (IsBetterFactor(
Factor, MaxOccVal, Occ, MaxOcc)) {
1767 if (BinaryOperator *BOp =
1780 for (
Value *V : FMulAddCands) {
1783 Ops.emplace_back(getRank(
Op),
Op);
1789 LLVM_DEBUG(
dbgs() <<
"\nFACTORING [" << MaxOcc <<
"]: " << *MaxOccVal
1798 I->getType()->isIntOrIntVectorTy()
1799 ? BinaryOperator::CreateAdd(MaxOccVal, MaxOccVal)
1800 : BinaryOperator::CreateFAdd(MaxOccVal, MaxOccVal);
1803 for (
unsigned i = 0; i !=
Ops.size(); ++i) {
1805 BinaryOperator *BOp =
1810 if (
Value *V = RemoveFactorFromExpression(
Ops[i].
Op, MaxOccVal,
1811 I->getDebugLoc())) {
1814 for (
unsigned j =
Ops.size(); j != i;) {
1818 Ops.erase(
Ops.begin()+j);
1828 unsigned NumAddedValues = NewMulOps.
size();
1834 assert(NumAddedValues > 1 &&
"Each occurrence should contribute a value");
1835 (void)NumAddedValues;
1837 RedoInsts.insert(VI);
1845 RedoInsts.insert(V2);
1876 unsigned FactorPowerSum = 0;
1877 for (
unsigned Idx = 1,
Size =
Ops.size(); Idx <
Size; ++Idx) {
1882 for (; Idx <
Size &&
Ops[Idx].Op ==
Op; ++Idx)
1886 FactorPowerSum +=
Count;
1893 if (FactorPowerSum < 4)
1898 for (
unsigned Idx = 1; Idx <
Ops.size(); ++Idx) {
1903 for (; Idx <
Ops.size() &&
Ops[Idx].
Op ==
Op; ++Idx)
1910 FactorPowerSum +=
Count;
1917 assert(FactorPowerSum >= 4);
1920 return LHS.Power >
RHS.Power;
1928 if (
Ops.size() == 1)
1933 if (
LHS->getType()->isIntOrIntVectorTy())
1934 LHS = Builder.CreateMul(
LHS,
Ops.pop_back_val());
1936 LHS = Builder.CreateFMul(
LHS,
Ops.pop_back_val());
1937 }
while (!
Ops.empty());
1949ReassociatePass::buildMinimalMultiplyDAG(IRBuilderBase &Builder,
1950 SmallVectorImpl<Factor> &Factors) {
1951 assert(Factors[0].Power);
1952 SmallVector<Value *, 4> OuterProduct;
1953 for (
unsigned LastIdx = 0, Idx = 1,
Size = Factors.
size();
1954 Idx <
Size && Factors[Idx].Power > 0; ++Idx) {
1955 if (Factors[Idx].Power != Factors[LastIdx].Power) {
1963 SmallVector<Value *, 4> InnerProduct;
1968 }
while (Idx <
Size && Factors[Idx].Power == Factors[LastIdx].Power);
1974 RedoInsts.insert(
MI);
1982 return LHS.Power ==
RHS.Power;
1994 if (Factors[0].Power) {
1995 Value *SquareRoot = buildMinimalMultiplyDAG(Builder, Factors);
1999 if (OuterProduct.
size() == 1)
2000 return OuterProduct.
front();
2006Value *ReassociatePass::OptimizeMul(BinaryOperator *
I,
2007 SmallVectorImpl<ValueEntry> &
Ops) {
2027 Value *
V = buildMinimalMultiplyDAG(Builder, Factors);
2036Value *ReassociatePass::OptimizeExpression(BinaryOperator *
I,
2037 SmallVectorImpl<ValueEntry> &
Ops) {
2040 const DataLayout &
DL =
I->getDataLayout();
2042 unsigned Opcode =
I->getOpcode();
2043 while (!
Ops.empty()) {
2071 if (
Ops.size() == 1)
return Ops[0].
Op;
2078 case Instruction::And:
2079 case Instruction::Or:
2084 case Instruction::Xor:
2085 if (
Value *Result = OptimizeXor(
I,
Ops))
2089 case Instruction::Add:
2090 case Instruction::FAdd:
2091 if (
Value *Result = OptimizeAdd(
I,
Ops))
2095 case Instruction::Mul:
2096 case Instruction::FMul:
2097 if (
Value *Result = OptimizeMul(
I,
Ops))
2103 return OptimizeExpression(
I,
Ops);
2109void ReassociatePass::RecursivelyEraseDeadInsts(Instruction *
I,
2110 OrderedSet &Insts) {
2112 SmallVector<Value *, 4>
Ops(
I->operands());
2113 ValueRankMap.erase(
I);
2115 RedoInsts.remove(
I);
2119 I->eraseFromParent();
2120 for (
auto *
Op :
Ops)
2122 if (OpInst->use_empty())
2123 Insts.insert(OpInst);
2127void ReassociatePass::EraseInst(Instruction *
I) {
2131 SmallVector<Value *, 8>
Ops(
I->operands());
2133 ValueRankMap.erase(
I);
2134 RedoInsts.remove(
I);
2138 I->eraseFromParent();
2140 SmallPtrSet<Instruction *, 8> Visited;
2145 unsigned Opcode =
Op->getOpcode();
2146 while (
Op->hasOneUse() &&
Op->user_back()->getOpcode() == Opcode &&
2148 Op =
Op->user_back();
2155 if (ValueRankMap.contains(
Op))
2156 RedoInsts.insert(
Op);
2176 switch (
I->getOpcode()) {
2177 case Instruction::FMul:
2189 case Instruction::FDiv:
2211Instruction *ReassociatePass::canonicalizeNegFPConstantsForOp(Instruction *
I,
2214 assert((
I->getOpcode() == Instruction::FAdd ||
2215 I->getOpcode() == Instruction::FSub) &&
"Expected fadd/fsub");
2219 SmallVector<Instruction *, 4> Candidates;
2221 if (Candidates.
empty())
2227 bool IsFSub =
I->getOpcode() == Instruction::FSub;
2228 bool NeedsSubtract = !IsFSub && Candidates.
size() % 2 == 1;
2232 for (Instruction *Negatible : Candidates) {
2236 "Expecting only 1 constant operand");
2237 assert(
C->isNegative() &&
"Expected negative FP constant");
2238 Negatible->setOperand(0, ConstantFP::get(Negatible->getType(),
abs(*
C)));
2243 "Expecting only 1 constant operand");
2244 assert(
C->isNegative() &&
"Expected negative FP constant");
2245 Negatible->setOperand(1, ConstantFP::get(Negatible->getType(),
abs(*
C)));
2249 assert(MadeChange ==
true &&
"Negative constant candidate was not changed");
2252 if (Candidates.size() % 2 == 0)
2257 assert(Candidates.size() % 2 == 1 &&
"Expected odd number");
2262 RedoInsts.insert(
I);
2274Instruction *ReassociatePass::canonicalizeNegFPConstants(Instruction *
I) {
2279 if (Instruction *R = canonicalizeNegFPConstantsForOp(
I,
Op,
X))
2282 if (Instruction *R = canonicalizeNegFPConstantsForOp(
I,
Op,
X))
2285 if (Instruction *R = canonicalizeNegFPConstantsForOp(
I,
Op,
X))
2292void ReassociatePass::OptimizeInst(Instruction *
I) {
2305 RedoInsts.insert(
I);
2313 if (
I->isCommutative())
2314 canonicalizeOperands(
I);
2317 if (Instruction *Res = canonicalizeNegFPConstants(
I))
2332 if (
I->getType()->isIntOrIntVectorTy(1))
2337 if (
I->getOpcode() == Instruction::Or &&
2341 SimplifyQuery(
I->getDataLayout(),
2342 nullptr,
nullptr,
I)))) {
2344 RedoInsts.insert(
I);
2352 RedoInsts.insert(
I);
2353 RedoInsts.insert(MulUser);
2360 if (
I->getOpcode() == Instruction::Sub) {
2363 RedoInsts.insert(
I);
2375 for (User *U : NI->
users()) {
2377 RedoInsts.insert(Tmp);
2379 RedoInsts.insert(
I);
2384 }
else if (
I->getOpcode() == Instruction::FNeg ||
2385 I->getOpcode() == Instruction::FSub) {
2388 RedoInsts.insert(
I);
2402 for (User *U : NI->
users()) {
2404 RedoInsts.insert(Tmp);
2406 RedoInsts.insert(
I);
2414 if (!
I->isAssociative())
return;
2439 ReassociateExpression(BO);
2442void ReassociatePass::ReassociateExpression(BinaryOperator *
I) {
2446 OverflowTracking
Flags;
2461 if (UA &&
Ops.size() > 2) {
2462 constexpr unsigned DivergentRankOffset = 1U << 28;
2467 bool Divergent =
false;
2468 for (
const Use &U :
Entry.Op->uses()) {
2470 if (Usr && Usr->
getParent() == ParentBB) {
2471 Divergent = UA->isDivergentAtUse(U);
2476 Entry.Rank += DivergentRankOffset;
2490 if (
Value *V = OptimizeExpression(
I,
Ops)) {
2497 I->replaceAllUsesWith(V);
2499 if (
I->getDebugLoc())
2500 VI->setDebugLoc(
I->getDebugLoc());
2501 RedoInsts.insert(
I);
2510 if (
I->hasOneUse()) {
2511 if (
I->getOpcode() == Instruction::Mul &&
2516 Ops.insert(
Ops.begin(), Tmp);
2517 }
else if (
I->getOpcode() == Instruction::FMul &&
2519 Instruction::FAdd &&
2523 Ops.insert(
Ops.begin(), Tmp);
2529 if (
Ops.size() == 1) {
2536 I->replaceAllUsesWith(
Ops[0].
Op);
2538 OI->setDebugLoc(
I->getDebugLoc());
2539 RedoInsts.insert(
I);
2543 if (
Ops.size() > 2 &&
Ops.size() <= GlobalReassociateLimit) {
2551 unsigned BestRank = 0;
2552 std::pair<unsigned, unsigned> BestPair;
2553 unsigned Idx =
I->getOpcode() - Instruction::BinaryOpsBegin;
2554 unsigned LimitIdx = 0;
2564 int StartIdx =
Ops.size() - 1;
2569 for (
int i = StartIdx - 1; i != -1; --i) {
2573 if (!CurrLeafInstr) {
2598 FirstSeenBB = SeenBB;
2601 if (FirstSeenBB != SeenBB) {
2607 << LimitIdx <<
", " << StartIdx <<
"]\n");
2612 for (
unsigned i =
Ops.size() - 1; i > LimitIdx; --i) {
2614 for (
int j = i - 1;
j >= (int)LimitIdx; --
j) {
2618 if (std::less<Value *>()(Op1, Op0))
2620 auto it = PairMap[Idx].find({Op0, Op1});
2621 if (it != PairMap[Idx].
end()) {
2627 if (it->second.isValid())
2628 Score += it->second.Score;
2631 unsigned MaxRank = std::max(
Ops[i].Rank,
Ops[j].Rank);
2645 if (Score > Max || (Score == Max && MaxRank < BestRank)) {
2653 auto Op0 =
Ops[BestPair.first];
2654 auto Op1 =
Ops[BestPair.second];
2655 Ops.erase(&
Ops[BestPair.second]);
2656 Ops.erase(&
Ops[BestPair.first]);
2665 RewriteExprTree(
I,
Ops, Flags);
2669ReassociatePass::BuildPairMap(ReversePostOrderTraversal<Function *> &RPOT) {
2671 for (BasicBlock *BI : RPOT) {
2672 for (Instruction &
I : *BI) {
2673 if (!
I.isAssociative() || !
I.isBinaryOp())
2677 if (
I.hasOneUse() &&
I.user_back()->getOpcode() ==
I.getOpcode())
2683 SmallVector<Value *, 8> Worklist = {
I.getOperand(0),
I.getOperand(1) };
2684 SmallVector<Value *, 8>
Ops;
2685 while (!Worklist.
empty() &&
Ops.size() <= GlobalReassociateLimit) {
2699 if (
Ops.size() > GlobalReassociateLimit)
2703 unsigned BinaryIdx =
I.getOpcode() - Instruction::BinaryOpsBegin;
2704 SmallSet<std::pair<Value *, Value*>, 32> Visited;
2705 for (
unsigned i = 0; i <
Ops.size() - 1; ++i) {
2706 for (
unsigned j = i + 1;
j <
Ops.size(); ++
j) {
2710 if (std::less<Value *>()(Op1, Op0))
2712 if (!Visited.
insert({Op0, Op1}).second)
2714 auto res = PairMap[BinaryIdx].insert({{Op0, Op1}, {Op0, Op1, 1}});
2720 assert(res.first->second.isValid() &&
"WeakVH invalidated");
2721 ++res.first->second.Score;
2747 BuildRankMap(
F, RPOT);
2771 assert(
II->getParent() == &*BI &&
"Moved to a different block!");
2782 while (!ToRedo.
empty()) {
2785 RecursivelyEraseDeadInsts(
I, ToRedo);
2831 if (skipFunction(
F))
2835 getAnalysis<UniformityInfoWrapperPass>().getUniformityInfo();
2841 void getAnalysisUsage(AnalysisUsage &AU)
const override {
2851char ReassociateLegacyPass::ID = 0;
2854 "Reassociate expressions",
false,
false)
2861 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.