48 #define DEBUG_TYPE "reassociate"
50 STATISTIC(NumChanged,
"Number of insts reassociated");
51 STATISTIC(NumAnnihil,
"Number of expr tree annihilated");
52 STATISTIC(NumFactor ,
"Number of multiplies factored");
60 << *Ops[0].
Op->getType() <<
'\t';
61 for (
unsigned i = 0, e = Ops.
size();
i != e; ++
i) {
63 Ops[
i].Op->printAsOperand(
dbgs(),
false, M);
64 dbgs() <<
", #" << Ops[
i].Rank <<
"] ";
81 bool isInvalid()
const {
return SymbolicPart ==
nullptr; }
95 unsigned SymbolicRank;
100 assert(!isa<ConstantInt>(V) &&
"No ConstantInt");
109 if (isa<ConstantInt>(V0))
113 ConstPart =
C->getValue();
129 if (V->
hasOneUse() && isa<Instruction>(V) &&
130 cast<Instruction>(V)->getOpcode() == Opcode &&
131 (!isa<FPMathOperator>(V) ||
132 cast<Instruction>(V)->hasUnsafeAlgebra()))
133 return cast<BinaryOperator>(V);
139 if (V->
hasOneUse() && isa<Instruction>(V) &&
140 (cast<Instruction>(V)->getOpcode() == Opcode1 ||
141 cast<Instruction>(V)->getOpcode() == Opcode2) &&
142 (!isa<FPMathOperator>(V) ||
143 cast<Instruction>(V)->hasUnsafeAlgebra()))
144 return cast<BinaryOperator>(V);
148 void ReassociatePass::BuildRankMap(
Function &
F,
154 ValueRankMap[&*
I] = ++
i;
155 DEBUG(
dbgs() <<
"Calculated Rank[" <<
I->getName() <<
"] = " << i <<
"\n");
160 unsigned BBRank = RankMap[BB] = ++i << 16;
167 ValueRankMap[&
I] = ++BBRank;
171 unsigned ReassociatePass::getRank(
Value *V) {
174 if (isa<Argument>(V))
return ValueRankMap[V];
178 if (
unsigned Rank = ValueRankMap[I])
185 unsigned Rank = 0, MaxRank = RankMap[I->getParent()];
186 for (
unsigned i = 0, e = I->getNumOperands();
187 i != e && Rank != MaxRank; ++
i)
188 Rank = std::max(Rank, getRank(I->getOperand(i)));
196 DEBUG(
dbgs() <<
"Calculated Rank[" << V->
getName() <<
"] = " << Rank <<
"\n");
198 return ValueRankMap[
I] = Rank;
202 void ReassociatePass::canonicalizeOperands(
Instruction *I) {
203 assert(isa<BinaryOperator>(I) &&
"Expected binary operator.");
208 unsigned LHSRank = getRank(LHS);
209 unsigned RHSRank = getRank(RHS);
211 if (isa<Constant>(RHS))
214 if (isa<Constant>(LHS) || RHSRank < LHSRank)
215 cast<BinaryOperator>(
I)->swapOperands();
224 BinaryOperator::CreateFAdd(S1, S2, Name, InsertBefore);
236 BinaryOperator::CreateFMul(S1, S2, Name, InsertBefore);
262 Neg->replaceAllUsesWith(Res);
307 assert(LHS == 1 && RHS == 1 &&
"Weights not reduced!");
312 assert(LHS == 1 && RHS == 1 &&
"Weights not reduced!");
322 assert((Opcode == Instruction::Mul || Opcode == Instruction::FMul) &&
323 "Unknown associative operation!");
339 assert(LHS.
ult(Threshold) && RHS.
ult(Threshold) &&
"Weights not reduced!");
342 while (LHS.uge(Threshold))
350 "Weights not reduced!");
352 while (Total >= Threshold)
436 DEBUG(
dbgs() <<
"LINEARIZE: " << *I <<
'\n');
440 "Expected an associative and commutative operation!");
454 bool Changed =
false;
478 while (!Worklist.empty()) {
479 std::pair<BinaryOperator*, APInt>
P = Worklist.pop_back_val();
482 for (
unsigned OpIdx = 0; OpIdx < 2; ++OpIdx) {
484 APInt Weight = P.second;
485 DEBUG(
dbgs() <<
"OPERAND: " << *Op <<
" (" << Weight <<
")\n");
491 assert(Visited.
insert(Op).second &&
"Not first visit!");
492 DEBUG(
dbgs() <<
"DIRECT ADD: " << *Op <<
" (" << Weight <<
")\n");
493 Worklist.push_back(std::make_pair(BO, Weight));
498 LeafMap::iterator It = Leaves.find(Op);
499 if (It == Leaves.end()) {
501 assert(Visited.
insert(Op).second &&
"Not first visit!");
505 DEBUG(
dbgs() <<
"ADD USES LEAF: " << *Op <<
" (" << Weight <<
")\n");
514 "In leaf map but not visited!");
519 #if 0 // TODO: Re-enable once PR13021 is fixed.
531 DEBUG(
dbgs() <<
"UNLEAF: " << *Op <<
" (" << It->second <<
")\n");
532 Worklist.push_back(std::make_pair(BO, It->second));
552 assert((!isa<Instruction>(Op) ||
553 cast<Instruction>(Op)->getOpcode() != Opcode
554 || (isa<FPMathOperator>(Op) &&
555 !cast<Instruction>(Op)->hasUnsafeAlgebra())) &&
556 "Should have been handled above!");
564 DEBUG(
dbgs() <<
"MORPH LEAF: " << *Op <<
" (" << Weight <<
") TO ");
567 Worklist.push_back(std::make_pair(BO, Weight));
574 DEBUG(
dbgs() <<
"ADD LEAF: " << *Op <<
" (" << Weight <<
")\n");
583 for (
unsigned i = 0, e = LeafOrder.
size(); i != e; ++
i) {
585 LeafMap::iterator It = Leaves.find(V);
586 if (It == Leaves.end())
590 APInt Weight = It->second;
596 Ops.
push_back(std::make_pair(V, Weight));
604 assert(Identity &&
"Associative operation without identity!");
615 assert(Ops.
size() > 1 &&
"Single values should be used directly!");
643 for (
unsigned i = 0, e = Ops.
size(); i != e; ++
i)
644 NotRewritable.
insert(Ops[i].Op);
650 for (
unsigned i = 0; ; ++
i) {
654 if (i+2 == Ops.
size()) {
655 Value *NewLHS = Ops[
i].Op;
656 Value *NewRHS = Ops[i+1].Op;
660 if (NewLHS == OldLHS && NewRHS == OldRHS)
664 if (NewLHS == OldRHS && NewRHS == OldLHS) {
677 if (NewLHS != OldLHS) {
679 if (BO && !NotRewritable.
count(BO))
680 NodesToRewrite.push_back(BO);
683 if (NewRHS != OldRHS) {
685 if (BO && !NotRewritable.
count(BO))
686 NodesToRewrite.push_back(BO);
691 ExpressionChanged =
Op;
700 Value *NewRHS = Ops[
i].Op;
710 if (BO && !NotRewritable.
count(BO))
711 NodesToRewrite.push_back(BO);
713 ExpressionChanged =
Op;
724 if (BO && !NotRewritable.
count(BO)) {
737 if (NodesToRewrite.empty()) {
740 Undef, Undef,
"", I);
741 if (NewOp->getType()->isFPOrFPVectorTy())
744 NewOp = NodesToRewrite.pop_back_val();
750 ExpressionChanged =
Op;
760 if (ExpressionChanged)
763 if (isa<FPMathOperator>(I)) {
770 if (ExpressionChanged == I)
773 ExpressionChanged = cast<BinaryOperator>(*ExpressionChanged->
user_begin());
777 for (
unsigned i = 0, e = NodesToRewrite.size(); i != e; ++
i)
778 RedoInsts.insert(NodesToRewrite[i]);
790 if (
Constant *
C = dyn_cast<Constant>(V)) {
791 if (
C->getType()->isFPOrFPVectorTy()) {
848 if (
Instruction *InstInput = dyn_cast<Instruction>(V)) {
849 if (
InvokeInst *II = dyn_cast<InvokeInst>(InstInput)) {
850 InsertPt = II->getNormalDest()->begin();
852 InsertPt = ++InstInput->getIterator();
854 while (isa<PHINode>(InsertPt)) ++InsertPt;
859 if (TheNeg->
getOpcode() == Instruction::Sub) {
865 ToRedo.insert(TheNeg);
872 ToRedo.insert(NewNeg);
922 Sub->replaceAllUsesWith(New);
923 New->setDebugLoc(Sub->getDebugLoc());
925 DEBUG(
dbgs() <<
"Negated: " << *New <<
'\n');
947 bool NSW = cast<BinaryOperator>(Shl)->hasNoSignedWrap();
948 bool NUW = cast<BinaryOperator>(Shl)->hasNoUnsignedWrap();
960 unsigned XRank = Ops[
i].Rank;
961 unsigned e = Ops.
size();
962 for (
unsigned j = i+1; j != e && Ops[j].Rank == XRank; ++j) {
965 if (
Instruction *I1 = dyn_cast<Instruction>(Ops[j].Op))
967 if (I1->isIdenticalTo(I2))
971 for (
unsigned j = i-1; j != ~0U && Ops[j].Rank == XRank; --j) {
974 if (
Instruction *I1 = dyn_cast<Instruction>(Ops[j].Op))
976 if (I1->isIdenticalTo(I2))
986 if (Ops.
size() == 1)
return Ops.
back();
1006 for (
unsigned i = 0, e = Tree.
size(); i != e; ++
i) {
1008 Factors.
append(E.second.getZExtValue(),
1012 bool FoundFactor =
false;
1013 bool NeedsNegate =
false;
1014 for (
unsigned i = 0, e = Factors.
size(); i != e; ++
i) {
1015 if (Factors[i].Op == Factor) {
1022 if (
ConstantInt *FC1 = dyn_cast<ConstantInt>(Factor)) {
1023 if (
ConstantInt *FC2 = dyn_cast<ConstantInt>(Factors[i].Op))
1024 if (FC1->getValue() == -FC2->getValue()) {
1025 FoundFactor = NeedsNegate =
true;
1029 }
else if (
ConstantFP *FC1 = dyn_cast<ConstantFP>(Factor)) {
1030 if (
ConstantFP *FC2 = dyn_cast<ConstantFP>(Factors[i].Op)) {
1031 const APFloat &F1 = FC1->getValueAPF();
1032 APFloat F2(FC2->getValueAPF());
1035 FoundFactor = NeedsNegate =
true;
1045 RewriteExprTree(BO, Factors);
1053 if (Factors.
size() == 1) {
1054 RedoInsts.insert(BO);
1057 RewriteExprTree(BO, Factors);
1062 V =
CreateNeg(V,
"neg", &*InsertPt, BO);
1092 for (
unsigned i = 0, e = Ops.
size(); i != e; ++
i) {
1110 if (i+1 != Ops.
size() && Ops[i+1].Op == Ops[
i].Op) {
1139 const APInt &ConstOpnd) {
1140 if (ConstOpnd != 0) {
1145 "and.ra", InsertBefore);
1172 if (C1 != ConstOpnd)
1181 RedoInsts.insert(
T);
1204 int DeadInstNum = 1;
1222 APInt C3((~C1) ^ C2);
1225 if (C3 != 0 && !C3.isAllOnesValue()) {
1226 int NewInstNum = ConstOpnd != 0 ? 1 : 2;
1227 if (NewInstNum > DeadInstNum)
1243 int NewInstNum = ConstOpnd != 0 ? 1 : 2;
1244 if (NewInstNum > DeadInstNum)
1262 RedoInsts.insert(
T);
1264 RedoInsts.insert(
T);
1277 if (Ops.
size() == 1)
1282 Type *Ty = Ops[0].Op->getType();
1286 for (
unsigned i = 0, e = Ops.
size(); i != e; ++
i) {
1288 if (!isa<ConstantInt>(V)) {
1290 O.setSymbolicRank(getRank(O.getSymbolicPart()));
1293 ConstOpnd ^= cast<ConstantInt>(V)->getValue();
1301 for (
unsigned i = 0, e = Opnds.
size(); i != e; ++
i)
1317 std::stable_sort(OpndPtrs.
begin(), OpndPtrs.
end(),
1324 bool Changed =
false;
1325 for (
unsigned i = 0, e = Opnds.
size(); i < e; i++) {
1331 if (ConstOpnd != 0 && CombineXorOpnd(I, CurrOpnd, ConstOpnd, CV)) {
1341 if (!PrevOpnd || CurrOpnd->
getSymbolicPart() != PrevOpnd->getSymbolicPart()) {
1342 PrevOpnd = CurrOpnd;
1349 if (CombineXorOpnd(I, CurrOpnd, PrevOpnd, ConstOpnd, CV)) {
1354 PrevOpnd = CurrOpnd;
1366 for (
unsigned int i = 0, e = Opnds.
size(); i < e; i++) {
1373 if (ConstOpnd != 0) {
1378 int Sz = Ops.
size();
1400 for (
unsigned i = 0, e = Ops.
size(); i != e; ++
i) {
1401 Value *TheOp = Ops[
i].Op;
1405 if (i+1 != Ops.
size() && Ops[i+1].Op == TheOp) {
1407 unsigned NumFound = 0;
1411 }
while (i != Ops.
size() && Ops[
i].Op == TheOp);
1413 DEBUG(
dbgs() <<
"\nFACTORING [" << NumFound <<
"]: " << *TheOp <<
'\n');
1425 RedoInsts.insert(Mul);
1457 if (Ops.
size() == 2 &&
1492 unsigned MaxOcc = 0;
1493 Value *MaxOccVal =
nullptr;
1494 for (
unsigned i = 0, e = Ops.
size(); i != e; ++
i) {
1503 assert(Factors.
size() > 1 &&
"Bad linearize!");
1507 for (
unsigned i = 0, e = Factors.
size(); i != e; ++
i) {
1508 Value *Factor = Factors[
i];
1509 if (!Duplicates.insert(Factor).second)
1512 unsigned Occ = ++FactorOccurrences[Factor];
1521 if (
ConstantInt *CI = dyn_cast<ConstantInt>(Factor)) {
1522 if (CI->isNegative() && !CI->isMinValue(
true)) {
1524 if (!Duplicates.insert(Factor).second)
1526 unsigned Occ = ++FactorOccurrences[Factor];
1532 }
else if (
ConstantFP *CF = dyn_cast<ConstantFP>(Factor)) {
1533 if (CF->isNegative()) {
1537 if (!Duplicates.insert(Factor).second)
1539 unsigned Occ = ++FactorOccurrences[Factor];
1551 DEBUG(
dbgs() <<
"\nFACTORING [" << MaxOcc <<
"]: " << *MaxOccVal <<
'\n');
1564 for (
unsigned i = 0; i != Ops.
size(); ++
i) {
1571 if (
Value *V = RemoveFactorFromExpression(Ops[i].Op, MaxOccVal)) {
1574 for (
unsigned j = Ops.
size(); j !=
i;) {
1576 if (Ops[j].Op == Ops[i].Op) {
1588 unsigned NumAddedValues = NewMulOps.
size();
1594 assert(NumAddedValues > 1 &&
"Each occurrence should contribute a value");
1595 (void)NumAddedValues;
1597 RedoInsts.insert(
VI);
1604 RedoInsts.insert(V2);
1635 unsigned FactorPowerSum = 0;
1636 for (
unsigned Idx = 1, Size = Ops.
size(); Idx < Size; ++Idx) {
1637 Value *Op = Ops[Idx-1].Op;
1641 for (; Idx < Size && Ops[Idx].Op ==
Op; ++Idx)
1645 FactorPowerSum += Count;
1652 if (FactorPowerSum < 4)
1657 for (
unsigned Idx = 1; Idx < Ops.
size(); ++Idx) {
1658 Value *Op = Ops[Idx-1].Op;
1662 for (; Idx < Ops.
size() && Ops[Idx].Op ==
Op; ++Idx)
1669 FactorPowerSum += Count;
1676 assert(FactorPowerSum >= 4);
1678 std::stable_sort(Factors.
begin(), Factors.
end(),
1679 [](
const Factor &LHS,
const Factor &RHS) {
1680 return LHS.
Power > RHS.Power;
1688 if (Ops.
size() == 1)
1697 }
while (!Ops.
empty());
1709 ReassociatePass::buildMinimalMultiplyDAG(
IRBuilder<> &Builder,
1711 assert(Factors[0].Power);
1713 for (
unsigned LastIdx = 0, Idx = 1, Size = Factors.
size();
1714 Idx < Size && Factors[Idx].Power > 0; ++Idx) {
1715 if (Factors[Idx].Power != Factors[LastIdx].Power) {
1724 InnerProduct.
push_back(Factors[LastIdx].Base);
1726 InnerProduct.
push_back(Factors[Idx].Base);
1728 }
while (Idx < Size && Factors[Idx].Power == Factors[LastIdx].Power);
1734 RedoInsts.insert(
MI);
1741 [](
const Factor &LHS,
const Factor &RHS) {
1742 return LHS.
Power == RHS.Power;
1749 for (
unsigned Idx = 0, Size = Factors.
size(); Idx != Size; ++Idx) {
1750 if (Factors[Idx].Power & 1)
1751 OuterProduct.
push_back(Factors[Idx].Base);
1752 Factors[Idx].Power >>= 1;
1754 if (Factors[0].Power) {
1755 Value *SquareRoot = buildMinimalMultiplyDAG(Builder, Factors);
1759 if (OuterProduct.
size() == 1)
1760 return OuterProduct.
front();
1777 if (!collectMultiplyFactors(Ops, Factors))
1784 if (
auto FPI = dyn_cast<FPMathOperator>(I))
1787 Value *V = buildMinimalMultiplyDAG(Builder, Factors);
1792 Ops.
insert(std::lower_bound(Ops.
begin(), Ops.
end(), NewEntry), NewEntry);
1802 while (!Ops.
empty() && isa<Constant>(Ops.
back().
Op)) {
1819 if (Ops.
size() == 1)
return Ops[0].Op;
1823 unsigned NumOps = Ops.
size();
1833 if (
Value *Result = OptimizeXor(I, Ops))
1838 case Instruction::FAdd:
1839 if (
Value *Result = OptimizeAdd(I, Ops))
1843 case Instruction::Mul:
1844 case Instruction::FMul:
1845 if (
Value *Result = OptimizeMul(I, Ops))
1850 if (Ops.
size() != NumOps)
1851 return OptimizeExpression(I, Ops);
1857 void ReassociatePass::RecursivelyEraseDeadInsts(
1861 ValueRankMap.
erase(I);
1863 RedoInsts.remove(I);
1866 if (
Instruction *OpInst = dyn_cast<Instruction>(Op))
1867 if (OpInst->use_empty())
1878 ValueRankMap.
erase(I);
1879 RedoInsts.remove(I);
1883 for (
unsigned i = 0, e = Ops.size(); i != e; ++
i)
1884 if (
Instruction *Op = dyn_cast<Instruction>(Ops[i])) {
1887 unsigned Opcode = Op->getOpcode();
1889 Visited.
insert(Op).second)
1891 RedoInsts.insert(Op);
1904 if (Opcode != Instruction::FMul && Opcode != Instruction::FDiv)
1929 unsigned UserOpcode = User->
getOpcode();
1930 if (UserOpcode != Instruction::FAdd && UserOpcode != Instruction::FSub)
1946 cast<BinaryOperator>(User)->swapOperands();
1951 switch (UserOpcode) {
1954 case Instruction::FAdd:
1955 NI = BinaryOperator::CreateFSub(Op0, Op1);
1958 case Instruction::FSub:
1959 NI = BinaryOperator::CreateFAdd(Op0, Op1);
1968 RedoInsts.insert(I);
1975 void ReassociatePass::OptimizeInst(
Instruction *I) {
1977 if (!isa<BinaryOperator>(I))
1988 RedoInsts.insert(I);
1994 if (
Instruction *Res = canonicalizeNegConstExpr(I))
2001 canonicalizeOperands(I);
2023 if (I->
getOpcode() == Instruction::Sub) {
2026 RedoInsts.insert(I);
2038 for (User *U : NI->
users()) {
2040 RedoInsts.insert(Tmp);
2042 RedoInsts.insert(I);
2047 }
else if (I->
getOpcode() == Instruction::FSub) {
2050 RedoInsts.insert(I);
2062 for (User *U : NI->
users()) {
2064 RedoInsts.insert(Tmp);
2066 RedoInsts.insert(I);
2093 cast<Instruction>(BO->
user_back())->getOpcode() == Instruction::Sub)
2096 cast<Instruction>(BO->
user_back())->getOpcode() == Instruction::FSub)
2099 ReassociateExpression(BO);
2109 for (
unsigned i = 0, e = Tree.
size(); i != e; ++
i) {
2111 Ops.
append(E.second.getZExtValue(),
2123 std::stable_sort(Ops.
begin(), Ops.
end());
2127 if (
Value *V = OptimizeExpression(I, Ops)) {
2133 DEBUG(
dbgs() <<
"Reassoc to scalar: " << *V <<
'\n');
2137 RedoInsts.insert(I);
2147 if (I->
getOpcode() == Instruction::Mul &&
2149 isa<ConstantInt>(Ops.
back().
Op) &&
2150 cast<ConstantInt>(Ops.
back().
Op)->isAllOnesValue()) {
2153 }
else if (I->
getOpcode() == Instruction::FMul &&
2154 cast<Instruction>(I->
user_back())->getOpcode() ==
2155 Instruction::FAdd &&
2156 isa<ConstantFP>(Ops.
back().
Op) &&
2157 cast<ConstantFP>(Ops.
back().
Op)->isExactlyValue(-1.0)) {
2165 if (Ops.
size() == 1) {
2173 if (
Instruction *OI = dyn_cast<Instruction>(Ops[0].Op))
2175 RedoInsts.insert(I);
2181 RewriteExprTree(I, Ops);
2192 BuildRankMap(F, RPOT);
2197 assert(RankMap.count(&*BI) &&
"BB should be ranked.");
2204 assert(II->getParent() == &*BI &&
"Moved to a different block!");
2215 while (!ToRedo.
empty()) {
2218 RecursivelyEraseDeadInsts(I, ToRedo);
2225 while (!RedoInsts.empty()) {
2236 ValueRankMap.clear();
2257 bool runOnFunction(
Function &F)
override {
2258 if (skipFunction(F))
2262 auto PA = Impl.run(F, DummyFAM);
2263 return !PA.areAllPreserved();
2275 "Reassociate expressions",
false,
false)
2279 return new ReassociateLegacyPass();
Legacy wrapper pass to provide the GlobalsAAResult object.
bool isNilpotent() const
Return true if the instruction is nilpotent:
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
void push_back(const T &Elt)
void setFastMathFlags(FastMathFlags FMF)
Convenience function for setting multiple fast-math flags on this instruction, which must be an opera...
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
uint64_t getZExtValue() const
Get zero extended value.
STATISTIC(NumFunctions,"Total number of functions")
LLVM_NODISCARD T pop_back_val()
static BinaryOperator * LowerNegateToMultiply(Instruction *Neg)
Replace 0-X with X*-1.
This is the interface for a simple mod/ref and alias analysis over globals.
A Module instance is used to store all the information related to an LLVM module. ...
Utility class representing a non-constant Xor-operand.
static Constant * getBinOpIdentity(unsigned Opcode, Type *Ty)
Return the identity for the given binary operation, i.e.
size_type count(PtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
Utility class representing a base and exponent pair which form one factor of some product...
FastMathFlags getFastMathFlags() const
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
const Function * getParent() const
Return the enclosing method, or null if none.
void reserve(size_type N)
Reassociate commutative expressions.
static void FindSingleUseMultiplyFactors(Value *V, SmallVectorImpl< Value * > &Factors, const SmallVectorImpl< ValueEntry > &Ops)
If V is a single-use multiply, recursively add its operands as factors, otherwise add V to the list o...
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
StringRef getName() const
Return a constant reference to the value's name.
iterator begin()
Instruction iterator methods.
bool swapOperands()
Exchange the two operands to this instruction.
static const Value * getNegArgument(const Value *BinOp)
Helper functions to extract the unary argument of a NEG, FNEG or NOT operation implemented via Sub...
struct fuzzer::@269 Flags
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
FunctionPass * createReassociatePass()
static BinaryOperator * BreakUpSubtract(Instruction *Sub, SetVector< AssertingVH< Instruction >> &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 (...
void setName(const Twine &Name)
Change the name of the value.
LLVM_NODISCARD bool empty() const
static Constant * get(unsigned Opcode, Constant *C1, Constant *C2, unsigned Flags=0, Type *OnlyIfReducedTy=nullptr)
get - Return a binary or shift operator constant expression, folding if possible. ...
static Value * OptimizeAndOrXor(unsigned Opcode, SmallVectorImpl< ValueEntry > &Ops)
Optimize a series of operands to an 'and', 'or', or 'xor' instruction.
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
std::pair< Value *, APInt > RepeatedValue
bool isAssociative() const
Return true if the instruction is associative:
void andIRFlags(const Value *V)
Logical 'and' of any supported wrapping, exact, and fast-math flags of V and this instruction...
bool hasUnsafeAlgebra() const
Determine whether the unsafe-algebra flag is set.
bool empty() const
Determine if the SetVector is empty or not.
static Value * createAndInstr(Instruction *InsertBefore, Value *Opnd, const APInt &ConstOpnd)
Helper function of CombineXorOpnd().
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
void takeName(Value *V)
Transfer the name from V to this value.
const char * getOpcodeName() const
Type * getScalarType() const LLVM_READONLY
If this is a vector type, return the element type, otherwise return 'this'.
static BinaryOperator * CreateAdd(Value *S1, Value *S2, const Twine &Name, Instruction *InsertBefore, Value *FlagsOp)
static const Value * getNotArgument(const Value *BinOp)
bool ult(const APInt &RHS) const
Unsigned less than comparison.
Value * getSymbolicPart() const
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
static Constant * getFNeg(Constant *C)
A set of analyses that are preserved following a run of a transformation pass.
static Value * buildMultiplyTree(IRBuilder<> &Builder, SmallVectorImpl< Value * > &Ops)
Build a tree of multiplies, computing the product of Ops.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
void insertBefore(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified instruction...
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
This is an important class for using LLVM in a threaded context.
bool isVectorTy() const
True if this is an instance of VectorType.
This is an important base class in LLVM.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
This file contains the declarations for the subclasses of Constant, which represent the different fla...
APInt Or(const APInt &LHS, const APInt &RHS)
Bitwise OR function for APInt.
static Value * EmitAddTreeOfValues(Instruction *I, SmallVectorImpl< WeakVH > &Ops)
Emit a tree of add instructions, summing Ops together and returning the result.
ConstantFP - Floating Point Values [float, double].
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
APInt Xor(const APInt &LHS, const APInt &RHS)
Bitwise XOR function for APInt.
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
Represent the analysis usage information of a pass.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
Analysis pass providing a never-invalidated alias analysis result.
unsigned getBitWidth() const
Return the number of bits in the APInt.
FunctionPass class - This class is used to implement most global optimizations.
Value * getOperand(unsigned i) const
bool isCommutative() const
Return true if the instruction is commutative:
static bool isNot(const Value *V)
self_iterator getIterator()
unsigned getIntegerBitWidth() const
static Constant * getAllOnesValue(Type *Ty)
Get the all ones value.
NUW NUW NUW NUW Exact static Exact BinaryOperator * CreateNeg(Value *Op, const Twine &Name="", Instruction *InsertBefore=nullptr)
Helper functions to construct and inspect unary operations (NEG and NOT) via binary operators SUB and...
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
iterator erase(const_iterator CI)
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
LLVMContext & getContext() const
All values hold a context through their type.
static unsigned CarmichaelShift(unsigned Bitwidth)
Returns k such that lambda(2^Bitwidth) = 2^k, where lambda is the Carmichael function.
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
void dump() const
Support for debugging, callable in GDB: V->dump()
unsigned getSymbolicRank() const
BinaryOps getOpcode() const
static BinaryOperator * CreateFNeg(Value *Op, const Twine &Name="", Instruction *InsertBefore=nullptr)
void setHasNoSignedWrap(bool b=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag...
Iterator for intrusive lists based on ilist_node.
INITIALIZE_PASS(ReassociateLegacyPass,"reassociate","Reassociate expressions", false, false) FunctionPass *llvm
This is the shared class of boolean and integer constants.
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
static Value * NegateValue(Value *V, Instruction *BI, SetVector< AssertingVH< Instruction >> &ToRedo)
Insert instructions before the instruction pointed to by BI, that computes the negative version of th...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Type * getType() const
All values are typed, get the type of this value.
Instruction * user_back()
Specialize the methods defined in Value, as we know that an instruction can only be used by other ins...
const APInt & getConstPart() const
LLVM_NODISCARD T pop_back_val()
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
void setSymbolicRank(unsigned R)
void setPreservesCFG()
This function should be called by the pass, iff they do not:
const BasicBlock & getEntryBlock() const
static Constant * get(Type *Ty, double V)
This returns a ConstantFP, or a vector containing a splat of a ConstantFP, for the specified value in...
Value handle that asserts if the Value is deleted.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
void setOperand(unsigned i, Value *Val)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
static bool isNeg(const Value *V)
Check if the given Value is a NEG, FNeg, or NOT instruction.
Class for arbitrary precision integers.
bool isIntegerTy() const
True if this is an instance of IntegerType.
static BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), Instruction *InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
iterator_range< user_iterator > users()
iterator insert(iterator I, T &&Elt)
bool isMinValue() const
Determine if this is the smallest unsigned value.
APInt And(const APInt &LHS, const APInt &RHS)
Bitwise AND function for APInt.
static Constant * getNeg(Constant *C, bool HasNUW=false, bool HasNSW=false)
bool isAllOnesValue() const
Determine if all bits are set.
bool isNegative() const
Return true if the sign bit is set.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
iterator insert(iterator where, pointer New)
void emplace_back(ArgTypes &&...Args)
bool mayBeMemoryDependent(const Instruction &I)
Returns true if the result or effects of the given instructions I depend on or influence global memor...
static bool isFNeg(const Value *V, bool IgnoreZeroSign=false)
bool isIdempotent() const
Return true if the instruction is idempotent:
static void PrintOps(Instruction *I, const SmallVectorImpl< ValueEntry > &Ops)
Print out the expression identified in the Ops list.
static void IncorporateWeight(APInt &LHS, const APInt &RHS, unsigned Opcode)
Add the extra weight 'RHS' to the existing weight 'LHS', reducing the combined weight using any speci...
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
bool hasOneUse() const
Return true if there is exactly one user of this value.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
static Constant * getShl(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static BinaryOperator * CreateNeg(Value *S1, const Twine &Name, Instruction *InsertBefore, Value *FlagsOp)
bool hasNUsesOrMore(unsigned N) const
Return true if this value has N users or more.
const APFloat & getValueAPF() const
static int const Threshold
TODO: Write a new FunctionPass AliasAnalysis so that it can keep a cache.
void setHasNoUnsignedWrap(bool b=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag...
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...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
user_iterator user_begin()
void initializeReassociateLegacyPassPass(PassRegistry &)
unsigned getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction has no side ef...
LLVM Value Representation.
static unsigned FindInOperandList(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...
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
A vector that has set insertion semantics.
void clearSubclassOptionalData()
Clear the optional flags contained in this value.
void setFastMathFlags(FastMathFlags NewFMF)
Set the fast-math flags to be used with generated fp-math operators.
void moveBefore(Instruction *MovePos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
static BinaryOperator * isReassociableOp(Value *V, unsigned Opcode)
Return true if V is an instruction of the specified opcode and if it only has one use...
cmpResult compare(const APFloat &RHS) const
Convenience struct for specifying and reasoning about fast-math flags.
A container for analyses that lazily runs them and caches their results.
static bool ShouldBreakUpSubtract(Instruction *Sub)
Return true if we should break up this subtract of X-Y into (X + -Y).
static APInt getNullValue(unsigned numBits)
Get the '0' value.
static BinaryOperator * CreateMul(Value *S1, Value *S2, const Twine &Name, Instruction *InsertBefore, Value *FlagsOp)
Value * CreateFMul(Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
static Constant * getBinOpAbsorber(unsigned Opcode, Type *Ty)
Return the absorbing element for the given binary operation, i.e.
static bool LinearizeExprTree(BinaryOperator *I, SmallVectorImpl< RepeatedValue > &Ops)
Given an associative binary expression, return the leaf nodes in Ops along with their weights (how ma...
const BasicBlock * getParent() const
PreservedAnalyses run(Function &F, FunctionAnalysisManager &)