110#define DEBUG_TYPE "slsr"
113 std::numeric_limits<unsigned>::max();
116 "Controls whether rewriteCandidate is executed.");
120class StraightLineStrengthReduceLegacyPass :
public FunctionPass {
131 void getAnalysisUsage(AnalysisUsage &AU)
const override {
139 bool doInitialization(
Module &M)
override {
140 DL = &
M.getDataLayout();
147class StraightLineStrengthReduce {
149 StraightLineStrengthReduce(
const DataLayout *DL, DominatorTree *DT,
150 ScalarEvolution *SE, TargetTransformInfo *TTI)
151 : DL(DL), DT(DT), SE(SE), TTI(TTI) {}
170 Candidate() =
default;
171 Candidate(Kind CT,
const SCEV *
B, ConstantInt *Idx,
Value *S,
172 Instruction *
I,
const SCEV *StrideSCEV)
173 : CandidateKind(CT), Base(
B), Index(Idx), Stride(S), Ins(
I),
174 StrideSCEV(StrideSCEV) {}
176 Kind CandidateKind = Invalid;
178 const SCEV *Base =
nullptr;
183 ConstantInt *Index =
nullptr;
185 Value *Stride =
nullptr;
205 Candidate *Basis =
nullptr;
207 DKind DeltaKind = InvalidDelta;
210 const SCEV *StrideSCEV =
nullptr;
213 Value *Delta =
nullptr;
223 enum EfficiencyLevel :
unsigned {
232 static EfficiencyLevel
233 getComputationEfficiency(Kind CandidateKind,
const ConstantInt *Index,
234 const Value *Stride,
const SCEV *Base =
nullptr) {
235 bool IsConstantBase =
false;
236 bool IsZeroBase =
false;
240 IsConstantBase =
true;
241 IsZeroBase = ConstBase->getValue()->isZero();
248 if (IsConstantBase && IsConstantStride)
252 if (CandidateKind == Mul) {
256 return (IsConstantStride || IsConstantBase) ? OneInstOneVar
260 return IsZeroBase && (Index->isOne() || Index->isMinusOne())
264 if (IsConstantStride) {
266 return (CI->isOne() || CI->isMinusOne()) ? OneInstOneVar
269 return TwoInstTwoVar;
273 assert(CandidateKind == Add || CandidateKind == GEP);
274 if (Index->isZero() || IsZeroStride)
277 bool IsSimpleIndex = Index->isOne() || Index->isMinusOne();
280 return IsZeroBase ? (IsSimpleIndex ? ZeroInst : OneInstOneVar)
281 : (IsSimpleIndex ? OneInstOneVar : TwoInstOneVar);
283 if (IsConstantStride)
284 return IsZeroStride ? ZeroInst : OneInstOneVar;
287 return OneInstTwoVar;
289 return TwoInstTwoVar;
293 bool isProfitableRewrite(
const Value *Delta,
const DKind DeltaKind)
const {
305 return getComputationEfficiency(CandidateKind, Index, Stride, Base) <=
306 getRewriteEfficiency(Delta, DeltaKind);
310 EfficiencyLevel getRewriteEfficiency()
const {
311 return Basis ? getRewriteEfficiency(Delta, DeltaKind) : Unknown;
315 EfficiencyLevel getRewriteEfficiency(
const Value *Delta,
316 const DKind DeltaKind)
const {
319 return getComputationEfficiency(
323 return getComputationEfficiency(CandidateKind, Index, Delta);
332 bool isHighEfficiency()
const {
333 return getComputationEfficiency(CandidateKind, Index, Stride, Base) >=
339 bool hasValidDelta(
const Candidate &Basis)
const {
343 return Base == Basis.Base && StrideSCEV == Basis.StrideSCEV;
346 return Base == Basis.Base && Index == Basis.Index;
349 return StrideSCEV == Basis.StrideSCEV && Index == Basis.Index;
361 void setBasisAndDeltaFor(Candidate &
C);
363 bool isFoldable(
const Candidate &
C, TargetTransformInfo *TTI);
367 void allocateCandidatesAndFindBasis(Instruction *
I);
370 void allocateCandidatesAndFindBasisForAdd(Instruction *
I);
377 void allocateCandidatesAndFindBasisForMul(Instruction *
I);
385 void allocateCandidatesAndFindBasisForGEP(GetElementPtrInst *
GEP);
389 void allocateCandidatesAndFindBasis(Candidate::Kind CT,
const SCEV *
B,
390 ConstantInt *Idx,
Value *S,
394 void rewriteCandidate(
const Candidate &
C);
397 static Value *emitBump(
const Candidate &Basis,
const Candidate &
C,
400 const DataLayout *DL =
nullptr;
401 DominatorTree *DT =
nullptr;
403 TargetTransformInfo *TTI =
nullptr;
404 std::list<Candidate> Candidates;
408 DenseMap<const SCEV *, SmallSetVector<Instruction *, 2>> SCEVToInsts;
412 MapVector<Instruction *, std::vector<Instruction *>> DependencyGraph;
415 DenseMap<Instruction *, SmallVector<Candidate *, 3>> RewriteCandidates;
419 std::vector<Instruction *> SortedCandidateInsts;
423 std::vector<Instruction *> DeadInstructions;
426 class CandidateDictTy {
428 using CandsTy = SmallVector<Candidate *, 8>;
429 using BBToCandsTy = DenseMap<const BasicBlock *, CandsTy>;
433 using IndexDeltaKeyTy = std::tuple<const SCEV *, const SCEV *, Type *>;
434 DenseMap<IndexDeltaKeyTy, BBToCandsTy> IndexDeltaCandidates;
437 using BaseDeltaKeyTy = std::tuple<const SCEV *, ConstantInt *, Type *>;
438 DenseMap<BaseDeltaKeyTy, BBToCandsTy> BaseDeltaCandidates;
441 using StrideDeltaKeyTy = std::tuple<const SCEV *, ConstantInt *, Type *>;
442 DenseMap<StrideDeltaKeyTy, BBToCandsTy> StrideDeltaCandidates;
447 const BBToCandsTy *getCandidatesWithDeltaKind(
const Candidate &
C,
448 Candidate::DKind K)
const {
449 assert(K != Candidate::InvalidDelta);
450 if (K == Candidate::IndexDelta) {
451 IndexDeltaKeyTy IndexDeltaKey(
C.Base,
C.StrideSCEV,
C.Ins->getType());
452 auto It = IndexDeltaCandidates.find(IndexDeltaKey);
453 if (It != IndexDeltaCandidates.end())
455 }
else if (K == Candidate::BaseDelta) {
456 BaseDeltaKeyTy BaseDeltaKey(
C.StrideSCEV,
C.Index,
C.Ins->getType());
457 auto It = BaseDeltaCandidates.find(BaseDeltaKey);
458 if (It != BaseDeltaCandidates.end())
461 assert(K == Candidate::StrideDelta);
462 StrideDeltaKeyTy StrideDeltaKey(
C.Base,
C.Index,
C.Ins->getType());
463 auto It = StrideDeltaCandidates.find(StrideDeltaKey);
464 if (It != StrideDeltaCandidates.end())
471 void add(Candidate &
C) {
474 IndexDeltaKeyTy IndexDeltaKey(
C.Base,
C.StrideSCEV,
ValueType);
475 BaseDeltaKeyTy BaseDeltaKey(
C.StrideSCEV,
C.Index,
ValueType);
476 StrideDeltaKeyTy StrideDeltaKey(
C.Base,
C.Index,
ValueType);
477 IndexDeltaCandidates[IndexDeltaKey][BB].push_back(&
C);
478 BaseDeltaCandidates[BaseDeltaKey][BB].push_back(&
C);
479 StrideDeltaCandidates[StrideDeltaKey][BB].push_back(&
C);
483 IndexDeltaCandidates.clear();
484 BaseDeltaCandidates.clear();
485 StrideDeltaCandidates.clear();
489 const SCEV *getAndRecordSCEV(
Value *V) {
490 auto *S = SE->getSCEV(V);
501 Value *getNearestValueOfSCEV(
const SCEV *S,
const Instruction *CI)
const {
506 return SU->getValue();
508 return SC->getValue();
510 auto It = SCEVToInsts.find(S);
511 if (It == SCEVToInsts.end())
516 for (Instruction *
I :
reverse(It->second))
517 if (DT->dominates(
I, CI))
525 Candidate::DKind DeltaKind;
529 : Cand(nullptr), DeltaKind(Candidate::InvalidDelta), Delta(nullptr) {}
530 DeltaInfo(Candidate *Cand, Candidate::DKind DeltaKind,
Value *Delta)
531 : Cand(Cand), DeltaKind(DeltaKind), Delta(Delta) {}
532 operator bool()
const {
return Cand !=
nullptr; }
535 friend raw_ostream &
operator<<(raw_ostream &OS,
const DeltaInfo &DI);
537 DeltaInfo compressPath(Candidate &
C, Candidate *Basis)
const;
539 Candidate *pickRewriteCandidate(Instruction *
I)
const;
540 void sortCandidateInstructions();
541 static Constant *getIndexDelta(Candidate &
C, Candidate &Basis);
542 static bool isSimilar(Candidate &
C, Candidate &Basis, Candidate::DKind K);
546 void addDependency(Candidate &
C, Candidate *Basis) {
548 DependencyGraph[Basis->Ins].emplace_back(
C.Ins);
553 auto PropagateDependency = [&](
Instruction *Inst) {
554 if (
auto CandsIt = RewriteCandidates.find(Inst);
555 CandsIt != RewriteCandidates.end() &&
557 [](Candidate *Cand) { return Cand->Basis; }))
558 DependencyGraph[Inst].emplace_back(
C.Ins);
564 PropagateDependency(DeltaInst);
568 PropagateDependency(StrideInst);
573 const StraightLineStrengthReduce::Candidate &
C) {
574 OS <<
"Ins: " << *
C.Ins <<
"\n Base: " << *
C.Base
575 <<
"\n Index: " << *
C.Index <<
"\n Stride: " << *
C.Stride
576 <<
"\n StrideSCEV: " << *
C.StrideSCEV;
578 OS <<
"\n Delta: " << *
C.Delta <<
"\n Basis: \n [ " << *
C.Basis <<
" ]";
584 OS <<
"Cand: " << *DI.Cand <<
"\n";
585 OS <<
"Delta Kind: ";
586 switch (DI.DeltaKind) {
587 case StraightLineStrengthReduce::Candidate::IndexDelta:
590 case StraightLineStrengthReduce::Candidate::BaseDelta:
593 case StraightLineStrengthReduce::Candidate::StrideDelta:
599 OS <<
"\nDelta: " << *DI.Delta;
605char StraightLineStrengthReduceLegacyPass::ID = 0;
608 "Straight line strength reduction",
false,
false)
616 return new StraightLineStrengthReduceLegacyPass();
621 if (
A.getBitWidth() <
B.getBitWidth())
622 A =
A.sext(
B.getBitWidth());
623 else if (
A.getBitWidth() >
B.getBitWidth())
624 B =
B.sext(
A.getBitWidth());
627Constant *StraightLineStrengthReduce::getIndexDelta(Candidate &
C,
629 APInt Idx =
C.Index->getValue(), BasisIdx = Basis.Index->getValue();
631 APInt IndexDelta = Idx - BasisIdx;
632 IntegerType *DeltaType =
634 return ConstantInt::get(DeltaType, IndexDelta);
637bool StraightLineStrengthReduce::isSimilar(Candidate &
C, Candidate &Basis,
638 Candidate::DKind K) {
639 bool SameType =
false;
641 case Candidate::StrideDelta:
642 SameType =
C.StrideSCEV->getType() == Basis.StrideSCEV->getType();
644 case Candidate::BaseDelta:
645 SameType =
C.Base->getType() == Basis.Base->getType();
647 case Candidate::IndexDelta:
652 return SameType && Basis.Ins !=
C.Ins &&
653 Basis.CandidateKind ==
C.CandidateKind;
656void StraightLineStrengthReduce::setBasisAndDeltaFor(Candidate &
C) {
657 auto SearchFrom = [
this, &
C](
const CandidateDictTy::BBToCandsTy &BBToCands,
658 auto IsTarget) ->
bool {
664 auto It = BBToCands.find(BB);
665 if (It != BBToCands.end())
666 for (Candidate *Basis :
reverse(It->second))
674 BB =
Node ?
Node->getBlock() :
nullptr;
685 if (
const auto *IndexDeltaCandidates =
686 CandidateDict.getCandidatesWithDeltaKind(
C, Candidate::IndexDelta)) {
687 bool FoundConstDelta =
688 SearchFrom(*IndexDeltaCandidates, [&](Candidate *Basis) {
689 if (isSimilar(
C, *Basis, Candidate::IndexDelta)) {
691 auto *Delta = getIndexDelta(
C, *Basis);
692 if (!
C.isProfitableRewrite(Delta, Candidate::IndexDelta))
695 C.DeltaKind = Candidate::IndexDelta;
709 if (
C.CandidateKind == Candidate::Mul)
712 auto For = [
this, &
C](Candidate::DKind
K) {
716 return [
K,
this, &
C](Candidate *Basis) ->
bool {
717 if (!isSimilar(
C, *Basis, K))
721 const SCEV *BasisPart =
722 (
K == Candidate::BaseDelta) ? Basis->Base : Basis->StrideSCEV;
723 const SCEV *CandPart =
724 (
K == Candidate::BaseDelta) ?
C.Base :
C.StrideSCEV;
725 const SCEV *Diff = SE->
getMinusSCEV(CandPart, BasisPart);
726 Value *AvailableVal = getNearestValueOfSCEV(Diff,
C.Ins);
733 C.Delta = AvailableVal;
741 if (
const auto *BaseDeltaCandidates =
742 CandidateDict.getCandidatesWithDeltaKind(
C, Candidate::BaseDelta)) {
743 if (SearchFrom(*BaseDeltaCandidates, For(Candidate::BaseDelta))) {
749 if (
const auto *StrideDeltaCandidates =
750 CandidateDict.getCandidatesWithDeltaKind(
C, Candidate::StrideDelta)) {
751 if (SearchFrom(*StrideDeltaCandidates, For(Candidate::StrideDelta))) {
760 dbgs() <<
"Found delta from ";
761 if (
C.DeltaKind == Candidate::BaseDelta)
764 dbgs() <<
"Stride: ";
765 dbgs() << *
C.Delta <<
"\n";
767 assert(
C.DeltaKind != Candidate::InvalidDelta &&
C.Basis);
781auto StraightLineStrengthReduce::compressPath(Candidate &
C,
782 Candidate *Basis)
const
784 if (!Basis || !Basis->Basis ||
C.CandidateKind == Candidate::Mul)
786 Candidate *Root = Basis;
787 Value *NewDelta =
nullptr;
788 auto NewKind = Candidate::InvalidDelta;
790 while (Root->Basis) {
791 Candidate *NextRoot = Root->Basis;
792 if (
C.Base == NextRoot->Base &&
C.StrideSCEV == NextRoot->StrideSCEV &&
793 isSimilar(
C, *NextRoot, Candidate::IndexDelta)) {
797 NewKind = Candidate::IndexDelta;
803 const SCEV *CandPart =
nullptr;
804 const SCEV *BasisPart =
nullptr;
805 auto CurrKind = Candidate::InvalidDelta;
806 if (
C.Base == NextRoot->Base &&
C.Index == NextRoot->Index) {
807 CandPart =
C.StrideSCEV;
808 BasisPart = NextRoot->StrideSCEV;
809 CurrKind = Candidate::StrideDelta;
810 }
else if (
C.StrideSCEV == NextRoot->StrideSCEV &&
811 C.Index == NextRoot->Index) {
813 BasisPart = NextRoot->Base;
814 CurrKind = Candidate::BaseDelta;
818 assert(CandPart && BasisPart);
819 if (!isSimilar(
C, *NextRoot, CurrKind))
825 NewDelta = DeltaVal->getValue();
832 assert(NewKind != Candidate::InvalidDelta && NewDelta);
834 <<
" from path compression.\n");
835 return {Root, NewKind, NewDelta};
843void StraightLineStrengthReduce::sortCandidateInstructions() {
844 SortedCandidateInsts.clear();
850 DenseMap<Instruction *, int> InDegree;
851 for (
auto &KV : DependencyGraph) {
854 for (
auto *Child : KV.second) {
858 std::queue<Instruction *> WorkList;
859 DenseSet<Instruction *> Visited;
861 for (
auto &KV : DependencyGraph)
862 if (InDegree[KV.first] == 0)
863 WorkList.push(KV.first);
865 while (!WorkList.empty()) {
871 SortedCandidateInsts.push_back(
I);
873 for (
auto *
Next : DependencyGraph[
I]) {
874 auto &Degree = InDegree[
Next];
880 assert(SortedCandidateInsts.size() == DependencyGraph.size() &&
881 "Dependency graph should not have cycles");
884auto StraightLineStrengthReduce::pickRewriteCandidate(Instruction *
I)
const
887 auto It = RewriteCandidates.
find(
I);
888 if (It == RewriteCandidates.
end())
891 Candidate *BestC =
nullptr;
892 auto BestEfficiency = Candidate::Unknown;
893 for (Candidate *
C :
reverse(It->second))
895 auto Efficiency =
C->getRewriteEfficiency();
896 if (Efficiency > BestEfficiency) {
897 BestEfficiency = Efficiency;
908 return TTI->getGEPCost(
GEP->getSourceElementType(),
GEP->getPointerOperand(),
916 return Index->getBitWidth() <= 64 &&
917 TTI->isLegalAddressingMode(
Base->getType(),
nullptr, 0,
true,
921bool StraightLineStrengthReduce::isFoldable(
const Candidate &
C,
922 TargetTransformInfo *
TTI) {
923 if (
C.CandidateKind == Candidate::Add)
925 if (
C.CandidateKind == Candidate::GEP)
930void StraightLineStrengthReduce::allocateCandidatesAndFindBasis(
931 Candidate::Kind CT,
const SCEV *
B, ConstantInt *Idx,
Value *S,
936 Candidate
C(CT,
B, Idx, S,
I, getAndRecordSCEV(S));
947 if (!isFoldable(
C,
TTI) && !
C.isHighEfficiency()) {
948 setBasisAndDeltaFor(
C);
951 if (
auto Res = compressPath(
C,
C.Basis)) {
953 C.DeltaKind = Res.DeltaKind;
960 Candidates.push_back(
C);
961 RewriteCandidates[
C.Ins].push_back(&Candidates.back());
962 CandidateDict.add(Candidates.back());
965void StraightLineStrengthReduce::allocateCandidatesAndFindBasis(
967 switch (
I->getOpcode()) {
968 case Instruction::Add:
969 allocateCandidatesAndFindBasisForAdd(
I);
971 case Instruction::Mul:
972 allocateCandidatesAndFindBasisForMul(
I);
974 case Instruction::GetElementPtr:
980void StraightLineStrengthReduce::allocateCandidatesAndFindBasisForAdd(
986 assert(
I->getNumOperands() == 2 &&
"isn't I an add?");
988 allocateCandidatesAndFindBasisForAdd(
LHS,
RHS,
I);
990 allocateCandidatesAndFindBasisForAdd(
RHS,
LHS,
I);
993void StraightLineStrengthReduce::allocateCandidatesAndFindBasisForAdd(
996 ConstantInt *Idx =
nullptr;
999 allocateCandidatesAndFindBasis(Candidate::Add, SE->
getSCEV(
LHS), Idx, S,
I);
1004 allocateCandidatesAndFindBasis(Candidate::Add, SE->
getSCEV(
LHS), Idx, S,
I);
1008 allocateCandidatesAndFindBasis(Candidate::Add, SE->
getSCEV(
LHS), One,
RHS,
1023void StraightLineStrengthReduce::allocateCandidatesAndFindBasisForMul(
1026 ConstantInt *Idx =
nullptr;
1030 allocateCandidatesAndFindBasis(Candidate::Mul, SE->
getSCEV(
B), Idx,
RHS,
I);
1036 allocateCandidatesAndFindBasis(Candidate::Mul, SE->
getSCEV(
B), Idx,
RHS,
I);
1040 allocateCandidatesAndFindBasis(Candidate::Mul, SE->
getSCEV(
LHS), Zero,
RHS,
1045void StraightLineStrengthReduce::allocateCandidatesAndFindBasisForMul(
1052 assert(
I->getNumOperands() == 2 &&
"isn't I a mul?");
1054 allocateCandidatesAndFindBasisForMul(
LHS,
RHS,
I);
1057 allocateCandidatesAndFindBasisForMul(
RHS,
LHS,
I);
1061void StraightLineStrengthReduce::allocateCandidatesAndFindBasisForGEP(
1062 GetElementPtrInst *
GEP) {
1064 if (
GEP->getType()->isVectorTy())
1068 for (Use &Idx :
GEP->indices())
1072 for (
unsigned I = 1,
E =
GEP->getNumOperands();
I !=
E; ++
I, ++GTI) {
1076 const SCEV *OrigIndexExpr = IndexExprs[
I - 1];
1085 ConstantInt *ElementSizeIdx = ConstantInt::get(PtrIdxTy, ElementSize,
true);
1087 DL->getIndexSizeInBits(
GEP->getAddressSpace())) {
1090 allocateCandidatesAndFindBasis(Candidate::GEP, BaseExpr, ElementSizeIdx,
1096 Value *TruncatedArrayIdx =
nullptr;
1099 DL->getIndexSizeInBits(
GEP->getAddressSpace())) {
1102 allocateCandidatesAndFindBasis(Candidate::GEP, BaseExpr, ElementSizeIdx,
1103 TruncatedArrayIdx,
GEP);
1106 IndexExprs[
I - 1] = OrigIndexExpr;
1110Value *StraightLineStrengthReduce::emitBump(
const Candidate &Basis,
1113 const DataLayout *
DL) {
1116 const APInt &ConstRHS = CR->getValue();
1117 IntegerType *DeltaType =
1121 ConstantInt::get(DeltaType, ConstRHS.
logBase2());
1126 ConstantInt::get(DeltaType, (-ConstRHS).logBase2());
1141 if (
C.DeltaKind == Candidate::IndexDelta) {
1152 if (IndexDelta == 1)
1158 IntegerType *DeltaType =
1165 assert(
C.DeltaKind == Candidate::StrideDelta ||
1166 C.DeltaKind == Candidate::BaseDelta);
1167 assert(
C.CandidateKind != Candidate::Mul);
1183 if (
C.DeltaKind == Candidate::StrideDelta) {
1186 if (
C.CandidateKind == Candidate::GEP) {
1188 Type *NewScalarIndexTy =
1189 DL->getIndexType(
GEP->getPointerOperandType()->getScalarType());
1192 if (!
C.Index->isOne()) {
1193 Value *ExtendedIndex =
1201void StraightLineStrengthReduce::rewriteCandidate(
const Candidate &
C) {
1205 const Candidate &Basis = *
C.Basis;
1206 assert(
C.Delta &&
C.CandidateKind == Basis.CandidateKind &&
1207 C.hasValidDelta(Basis));
1210 Value *Bump = emitBump(Basis,
C, Builder,
DL);
1211 Value *Reduced =
nullptr;
1215 Reduced = Basis.Ins;
1217 switch (
C.CandidateKind) {
1218 case Candidate::Add:
1219 case Candidate::Mul: {
1224 Reduced = Builder.
CreateSub(Basis.Ins, NegBump);
1238 Reduced = Builder.
CreateAdd(Basis.Ins, Bump);
1242 case Candidate::GEP: {
1245 Reduced = Builder.
CreatePtrAdd(Basis.Ins, Bump,
"", InBounds);
1253 C.Ins->replaceAllUsesWith(Reduced);
1254 DeadInstructions.push_back(
C.Ins);
1257bool StraightLineStrengthReduceLegacyPass::runOnFunction(Function &
F) {
1258 if (skipFunction(
F))
1261 auto *
TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
F);
1262 auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
1263 auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
1264 return StraightLineStrengthReduce(
DL, DT, SE,
TTI).runOnFunction(
F);
1267bool StraightLineStrengthReduce::runOnFunction(Function &
F) {
1272 for (
auto &
I : *(
Node->getBlock()))
1273 allocateCandidatesAndFindBasis(&
I);
1277 for (
auto &
C : Candidates) {
1278 DependencyGraph.try_emplace(
C.Ins);
1279 addDependency(
C,
C.Basis);
1281 sortCandidateInstructions();
1285 for (Instruction *
I :
reverse(SortedCandidateInsts))
1286 if (Candidate *
C = pickRewriteCandidate(
I))
1287 rewriteCandidate(*
C);
1289 for (
auto *DeadIns : DeadInstructions)
1292 if (DeadIns->getParent())
1295 bool Ret = !DeadInstructions.empty();
1296 DeadInstructions.clear();
1297 DependencyGraph.clear();
1298 RewriteCandidates.
clear();
1299 SortedCandidateInsts.clear();
1301 CandidateDict.clear();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
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")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
static bool runOnFunction(Function &F, bool PostInlining)
Module.h This file contains the declarations for the Module class.
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
Machine Check Debug Module
static bool isGEPFoldable(GetElementPtrInst *GEP, const TargetTransformInfo *TTI)
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
static BinaryOperator * CreateMul(Value *S1, Value *S2, const Twine &Name, BasicBlock::iterator InsertBefore, Value *FlagsOp)
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallVector class.
static bool matchesOr(Value *A, Value *&B, ConstantInt *&C)
static bool isAddFoldable(const SCEV *Base, ConstantInt *Index, Value *Stride, TargetTransformInfo *TTI)
static void unifyBitWidth(APInt &A, APInt &B)
static bool matchesAdd(Value *A, Value *&B, ConstantInt *&C)
static const unsigned UnknownAddressSpace
Class for arbitrary precision integers.
bool isNegatedPowerOf2() const
Check if this APInt's negated value is a power of two greater than zero.
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
unsigned getBitWidth() const
Return the number of bits in the APInt.
unsigned logBase2() const
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
AnalysisUsage & addRequired()
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
const Function * getParent() const
Return the enclosing method, or null if none.
Represents analyses that only rely on functions' control flow.
This is the shared class of boolean and integer constants.
bool isOne() const
This is just a convenience method to make client code smaller for a common case.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
unsigned getBitWidth() const
getBitWidth - Return the scalar bitwidth of this constant.
const APInt & getValue() const
Return the constant as an APInt value reference.
This is an important base class in LLVM.
A parsed version of the target data layout string in and methods for querying it.
static bool shouldExecute(unsigned CounterName)
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Analysis pass which computes a DominatorTree.
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
Legacy analysis pass which computes a DominatorTree.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
FunctionPass class - This class is used to implement most global optimizations.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Value * CreateNeg(Value *V, const Twine &Name="", bool HasNSW=false)
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateSExtOrTrunc(Value *V, Type *DestTy, const Twine &Name="")
Create a SExt or Trunc from the integer value V to DestTy.
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
This class represents an analyzed expression in the program.
LLVM_ABI Type * getType() const
Return the LLVM type of this SCEV expression.
Analysis pass that exposes the ScalarEvolution for a function.
const SCEV * getZero(Type *Ty)
Return a SCEV for the constant 0 of a specific type.
LLVM_ABI const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
LLVM_ABI const SCEV * getMinusSCEV(const SCEV *LHS, const SCEV *RHS, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Return LHS-RHS.
LLVM_ABI const SCEV * getGEPExpr(GEPOperator *GEP, ArrayRef< const SCEV * > IndexExprs)
Returns an expression for a GEP.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Analysis pass providing the TargetTransformInfo.
LLVM_ABI unsigned getIntegerBitWidth() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
std::pair< iterator, bool > insert(const ValueT &V)
TypeSize getSequentialElementStride(const DataLayout &DL) const
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ BasicBlock
Various leaf nodes.
BinaryOp_match< SpecificConstantMatch, SrcTy, TargetOpcode::G_SUB > m_Neg(const SrcTy &&Src)
Matches a register negated by a G_SUB.
bool match(Val *V, const Pattern &P)
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Add, true > m_c_Add(const LHS &L, const RHS &R)
Matches a Add with LHS and RHS in either order.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
BinaryOp_match< LHS, RHS, Instruction::Or, true > m_c_Or(const LHS &L, const RHS &R)
Matches an Or with LHS and RHS in either order.
NodeAddr< NodeBase * > Node
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
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.
FunctionAddr VTableAddr Value
LLVM_ABI bool RecursivelyDeleteTriviallyDeadInstructions(Value *V, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, std::function< void(Value *)> AboutToDeleteCallback=std::function< void(Value *)>())
If the specified value is a trivially dead instruction, delete it.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI void initializeStraightLineStrengthReduceLegacyPassPass(PassRegistry &)
DomTreeNodeBase< BasicBlock > DomTreeNode
auto dyn_cast_or_null(const Y &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.
auto reverse(ContainerTy &&C)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
generic_gep_type_iterator<> gep_type_iterator
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...
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
FunctionAddr VTableAddr Next
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
gep_type_iterator gep_type_begin(const User *GEP)
PointerUnion< const Value *, const PseudoSourceValue * > ValueType
iterator_range< df_iterator< T > > depth_first(const T &G)
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI FunctionPass * createStraightLineStrengthReducePass()