81#ifdef EXPENSIVE_CHECKS
87#define DEBUG_TYPE "dfa-jump-threading"
89STATISTIC(NumTransforms,
"Number of transformations done");
91STATISTIC(NumPaths,
"Number of individual paths threaded");
95 cl::desc(
"View the CFG before DFA Jump Threading"),
99 "dfa-early-exit-heuristic",
100 cl::desc(
"Exit early if an unpredictable value come from the same loop"),
104 "dfa-max-path-length",
105 cl::desc(
"Max number of blocks searched to find a threading path"),
109 "dfa-max-num-visited-paths",
111 "Max number of blocks visited while enumerating paths around a switch"),
116 cl::desc(
"Max number of paths enumerated around a switch"),
121 cl::desc(
"Maximum cost accepted for the transformation"),
126class SelectInstToUnfold {
134 PHINode *getUse() {
return SIUse; }
136 explicit operator bool()
const {
return SI && SIUse; }
140 std::vector<SelectInstToUnfold> *NewSIsToUnfold,
141 std::vector<BasicBlock *> *NewBBs);
143class DFAJumpThreading {
147 : AC(AC), DT(DT), LI(LI),
TTI(
TTI), ORE(ORE) {}
159 while (!
Stack.empty()) {
160 SelectInstToUnfold SIToUnfold =
Stack.pop_back_val();
162 std::vector<SelectInstToUnfold> NewSIsToUnfold;
163 std::vector<BasicBlock *> NewBBs;
164 unfold(&DTU, LI, SIToUnfold, &NewSIsToUnfold, &NewBBs);
167 for (
const SelectInstToUnfold &NewSIToUnfold : NewSIsToUnfold)
168 Stack.push_back(NewSIToUnfold);
191 std::vector<SelectInstToUnfold> *NewSIsToUnfold,
192 std::vector<BasicBlock *> *NewBBs) {
194 PHINode *SIUse = SIToUnfold.getUse();
206 SI->getContext(),
Twine(
SI->getName(),
".si.unfold.false"),
208 NewBBs->push_back(NewBlock);
210 DTU->
applyUpdates({{DominatorTree::Insert, NewBlock, EndBlock}});
217 Value *SIOp1 =
SI->getTrueValue();
218 Value *SIOp2 =
SI->getFalseValue();
229 Phi.addIncoming(
Phi.getIncomingValueForBlock(StartBlock), NewBlock);
238 Twine(
SI->getName(),
".si.unfold.phi"),
241 if (Pred != StartBlock && Pred != NewBlock)
251 if (
auto *OpSi = dyn_cast<SelectInst>(SIOp1))
252 NewSIsToUnfold->push_back(SelectInstToUnfold(OpSi, SIUse));
253 if (
auto *OpSi = dyn_cast<SelectInst>(SIOp2))
254 NewSIsToUnfold->push_back(SelectInstToUnfold(OpSi, NewPhi));
259 DTU->
applyUpdates({{DominatorTree::Insert, StartBlock, EndBlock},
260 {DominatorTree::Insert, StartBlock, NewBlock}});
264 SI->getContext(),
Twine(
SI->getName(),
".si.unfold.true"),
267 SI->getContext(),
Twine(
SI->getName(),
".si.unfold.false"),
270 NewBBs->push_back(NewBlockT);
271 NewBBs->push_back(NewBlockF);
294 DTU->
applyUpdates({{DominatorTree::Insert, NewBlockT, NewBlockF},
295 {DominatorTree::Insert, NewBlockT, EndBlock},
296 {DominatorTree::Insert, NewBlockF, EndBlock}});
310 if (
auto *TrueSI = dyn_cast<SelectInst>(TrueVal))
311 NewSIsToUnfold->push_back(SelectInstToUnfold(TrueSI, NewPhiT));
312 if (
auto *FalseSi = dyn_cast<SelectInst>(FalseVal))
313 NewSIsToUnfold->push_back(SelectInstToUnfold(FalseSi, NewPhiF));
323 Phi.addIncoming(
Phi.getIncomingValueForBlock(StartBlock), NewBlockT);
324 Phi.addIncoming(
Phi.getIncomingValueForBlock(StartBlock), NewBlockF);
325 Phi.removeIncomingValue(StartBlock);
330 unsigned SuccNum = StartBlockTerm->
getSuccessor(1) == EndBlock ? 1 : 0;
332 DTU->
applyUpdates({{DominatorTree::Delete, StartBlock, EndBlock},
333 {DominatorTree::Insert, StartBlock, NewBlockT}});
339 L->addBasicBlockToLoop(NewBB, *LI);
343 assert(
SI->use_empty() &&
"Select must be dead now");
344 SI->eraseFromParent();
352typedef std::deque<BasicBlock *> PathType;
353typedef std::vector<PathType> PathsType;
355typedef std::vector<ClonedBlock> CloneList;
384struct ThreadingPath {
386 APInt getExitValue()
const {
return ExitVal; }
388 ExitVal =
V->getValue();
391 bool isExitValueSet()
const {
return IsExitValSet; }
394 const BasicBlock *getDeterminatorBB()
const {
return DBB; }
395 void setDeterminator(
const BasicBlock *BB) { DBB = BB; }
398 const PathType &getPath()
const {
return Path; }
399 void setPath(
const PathType &NewPath) {
Path = NewPath; }
402 void appendExcludingFirst(
const PathType &OtherPath) {
403 Path.insert(
Path.end(), OtherPath.begin() + 1, OtherPath.end());
407 OS <<
Path <<
" [ " << ExitVal <<
", " << DBB->getName() <<
" ]";
414 bool IsExitValSet =
false;
432 <<
"Switch instruction is not predictable.";
437 virtual ~MainSwitch() =
default;
450 std::deque<std::pair<Value *, BasicBlock *>> Q;
454 Value *SICond =
SI->getCondition();
456 if (!isa<PHINode>(SICond))
464 addToQueue(SICond,
nullptr, Q, SeenValues);
467 Value *Current = Q.front().first;
471 if (
auto *Phi = dyn_cast<PHINode>(Current)) {
474 addToQueue(
Incoming, IncomingBB, Q, SeenValues);
477 }
else if (
SelectInst *SelI = dyn_cast<SelectInst>(Current)) {
478 if (!isValidSelectInst(SelI))
480 addToQueue(SelI->getTrueValue(), CurrentIncomingBB, Q, SeenValues);
481 addToQueue(SelI->getFalseValue(), CurrentIncomingBB, Q, SeenValues);
483 if (
auto *SelIUse = dyn_cast<PHINode>(SelI->user_back()))
484 SelectInsts.
push_back(SelectInstToUnfold(SelI, SelIUse));
485 }
else if (isa<Constant>(Current)) {
502 <<
"\tExiting early due to unpredictability heuristic.\n");
514 std::deque<std::pair<Value *, BasicBlock *>> &Q,
516 if (SeenValues.
insert(Val).second)
517 Q.push_back({Val, BB});
521 if (!
SI->hasOneUse())
526 if (!SIUse && !(isa<PHINode>(SIUse) || isa<SelectInst>(SIUse)))
538 PHINode *PHIUser = dyn_cast<PHINode>(SIUse);
544 for (SelectInstToUnfold SIToUnfold : SelectInsts) {
559struct AllSwitchPaths {
563 LI(LI), SwitchOuterLoop(
L) {}
565 std::vector<ThreadingPath> &getThreadingPaths() {
return TPaths; }
566 unsigned getNumThreadingPaths() {
return TPaths.size(); }
568 BasicBlock *getSwitchBlock() {
return SwitchBlock; }
571 StateDefMap StateDef = getStateDefMap();
572 if (StateDef.empty()) {
576 <<
"Switch instruction is not predictable.";
581 auto *SwitchPhi = cast<PHINode>(
Switch->getOperand(0));
582 auto *SwitchPhiDefBB = SwitchPhi->getParent();
585 std::vector<ThreadingPath> PathsToPhiDef =
586 getPathsFromStateDefMap(StateDef, SwitchPhi, VB);
587 if (SwitchPhiDefBB == SwitchBlock) {
588 TPaths = std::move(PathsToPhiDef);
593 PathsType PathsToSwitchBB =
594 paths(SwitchPhiDefBB, SwitchBlock, VB, 1);
595 if (PathsToSwitchBB.empty())
598 std::vector<ThreadingPath> TempList;
599 for (
const ThreadingPath &Path : PathsToPhiDef) {
600 for (
const PathType &PathToSw : PathsToSwitchBB) {
601 ThreadingPath PathCopy(Path);
602 PathCopy.appendExcludingFirst(PathToSw);
603 TempList.push_back(PathCopy);
606 TPaths = std::move(TempList);
613 std::vector<ThreadingPath> getPathsFromStateDefMap(StateDefMap &StateDef,
616 std::vector<ThreadingPath> Res;
617 auto *PhiBB =
Phi->getParent();
620 VisitedBlocks UniqueBlocks;
621 for (
auto *IncomingBB :
Phi->blocks()) {
622 if (!UniqueBlocks.insert(IncomingBB).second)
624 if (!SwitchOuterLoop->contains(IncomingBB))
627 Value *IncomingValue =
Phi->getIncomingValueForBlock(IncomingBB);
629 if (
auto *
C = dyn_cast<ConstantInt>(IncomingValue)) {
631 if (PhiBB == SwitchBlock &&
632 SwitchBlock != cast<PHINode>(
Switch->getOperand(0))->getParent())
634 ThreadingPath NewPath;
635 NewPath.setDeterminator(PhiBB);
636 NewPath.setExitValue(
C);
638 if (IncomingBB != SwitchBlock)
639 NewPath.push_back(IncomingBB);
640 NewPath.push_back(PhiBB);
641 Res.push_back(NewPath);
645 if (
VB.contains(IncomingBB) || IncomingBB == SwitchBlock)
648 auto *IncomingPhi = dyn_cast<PHINode>(IncomingValue);
651 auto *IncomingPhiDefBB = IncomingPhi->getParent();
652 if (!StateDef.contains(IncomingPhiDefBB))
656 if (IncomingPhiDefBB == IncomingBB) {
657 std::vector<ThreadingPath> PredPaths =
658 getPathsFromStateDefMap(StateDef, IncomingPhi, VB);
659 for (ThreadingPath &Path : PredPaths) {
660 Path.push_back(PhiBB);
661 Res.push_back(std::move(Path));
667 if (
VB.contains(IncomingPhiDefBB))
670 PathsType IntermediatePaths;
672 paths(IncomingPhiDefBB, IncomingBB, VB, 1);
673 if (IntermediatePaths.empty())
676 std::vector<ThreadingPath> PredPaths =
677 getPathsFromStateDefMap(StateDef, IncomingPhi, VB);
678 for (
const ThreadingPath &Path : PredPaths) {
679 for (
const PathType &IPath : IntermediatePaths) {
680 ThreadingPath NewPath(Path);
681 NewPath.appendExcludingFirst(IPath);
682 NewPath.push_back(PhiBB);
683 Res.push_back(NewPath);
692 unsigned PathDepth) {
700 <<
"Exploration stopped after visiting MaxPathLength="
712 if (!SwitchOuterLoop->contains(BB))
719 if (!Successors.
insert(Succ).second)
724 Res.push_back({BB, ToBB});
729 if (Visited.contains(Succ))
734 if (Succ == CurrLoop->getHeader())
741 PathsType SuccPaths = paths(Succ, ToBB, Visited, PathDepth + 1);
742 for (PathType &Path : SuccPaths) {
761 StateDefMap getStateDefMap()
const {
764 assert(isa<PHINode>(FirstDef) &&
"The first definition must be a phi.");
767 Stack.push_back(dyn_cast<PHINode>(FirstDef));
770 while (!
Stack.empty()) {
774 SeenValues.
insert(CurPhi);
778 bool IsOutsideLoops = !SwitchOuterLoop->contains(IncomingBB);
786 return StateDefMap();
795 unsigned NumVisited = 0;
799 std::vector<ThreadingPath> TPaths;
801 Loop *SwitchOuterLoop;
809 : SwitchPaths(SwitchPaths), DT(DT), AC(AC),
TTI(
TTI), ORE(ORE),
810 EphValues(EphValues) {}
813 if (isLegalAndProfitableToTransform()) {
814 createAllExitPaths();
824 bool isLegalAndProfitableToTransform() {
829 if (
Switch->getNumSuccessors() <= 1)
834 DuplicateBlockMap DuplicateMap;
836 for (ThreadingPath &TPath : SwitchPaths->getThreadingPaths()) {
837 PathType PathBBs = TPath.getPath();
838 APInt NextState = TPath.getExitValue();
839 const BasicBlock *Determinator = TPath.getDeterminatorBB();
842 BasicBlock *BB = SwitchPaths->getSwitchBlock();
843 BasicBlock *VisitedBB = getClonedBB(BB, NextState, DuplicateMap);
845 Metrics.analyzeBasicBlock(BB, *
TTI, EphValues);
846 DuplicateMap[BB].push_back({BB, NextState});
851 if (PathBBs.front() == Determinator)
856 auto DetIt =
llvm::find(PathBBs, Determinator);
857 for (
auto BBIt = DetIt; BBIt != PathBBs.end(); BBIt++) {
859 VisitedBB = getClonedBB(BB, NextState, DuplicateMap);
862 Metrics.analyzeBasicBlock(BB, *
TTI, EphValues);
863 DuplicateMap[BB].push_back({BB, NextState});
867 LLVM_DEBUG(
dbgs() <<
"DFA Jump Threading: Not jump threading, contains "
868 <<
"non-duplicatable instructions.\n");
872 <<
"Contains non-duplicatable instructions.";
878 if (
Metrics.Convergence != ConvergenceKind::None) {
879 LLVM_DEBUG(
dbgs() <<
"DFA Jump Threading: Not jump threading, contains "
880 <<
"convergent instructions.\n");
883 <<
"Contains convergent instructions.";
888 if (!
Metrics.NumInsts.isValid()) {
889 LLVM_DEBUG(
dbgs() <<
"DFA Jump Threading: Not jump threading, contains "
890 <<
"instructions with invalid cost.\n");
893 <<
"Contains instructions with invalid cost.";
901 unsigned JumpTableSize = 0;
904 if (JumpTableSize == 0) {
908 unsigned CondBranches =
910 assert(CondBranches > 0 &&
911 "The threaded switch must have multiple branches");
912 DuplicationCost =
Metrics.NumInsts / CondBranches;
920 DuplicationCost =
Metrics.NumInsts / JumpTableSize;
923 LLVM_DEBUG(
dbgs() <<
"\nDFA Jump Threading: Cost to jump thread block "
924 << SwitchPaths->getSwitchBlock()->getName()
925 <<
" is: " << DuplicationCost <<
"\n\n");
928 LLVM_DEBUG(
dbgs() <<
"Not jump threading, duplication cost exceeds the "
929 <<
"cost threshold.\n");
932 <<
"Duplication cost exceeds the cost threshold (cost="
933 <<
ore::NV(
"Cost", DuplicationCost)
941 <<
"Switch statement jump-threaded.";
948 void createAllExitPaths() {
952 BasicBlock *SwitchBlock = SwitchPaths->getSwitchBlock();
953 for (ThreadingPath &TPath : SwitchPaths->getThreadingPaths()) {
957 TPath.push_front(SwitchBlock);
961 DuplicateBlockMap DuplicateMap;
968 for (ThreadingPath &TPath : SwitchPaths->getThreadingPaths()) {
969 createExitPath(NewDefs, TPath, DuplicateMap, BlocksToClean, &DTU);
975 for (ThreadingPath &TPath : SwitchPaths->getThreadingPaths())
976 updateLastSuccessor(TPath, DuplicateMap, &DTU);
992 void createExitPath(DefMap &NewDefs, ThreadingPath &Path,
993 DuplicateBlockMap &DuplicateMap,
998 PathType PathBBs =
Path.getPath();
1001 if (PathBBs.front() == Determinator)
1002 PathBBs.pop_front();
1004 auto DetIt =
llvm::find(PathBBs, Determinator);
1007 BasicBlock *PrevBB = PathBBs.
size() == 1 ? *DetIt : *std::prev(DetIt);
1008 for (
auto BBIt = DetIt; BBIt != PathBBs.end(); BBIt++) {
1010 BlocksToClean.
insert(BB);
1014 BasicBlock *NextBB = getClonedBB(BB, NextState, DuplicateMap);
1016 updatePredecessor(PrevBB, BB, NextBB, DTU);
1022 BasicBlock *NewBB = cloneBlockAndUpdatePredecessor(
1023 BB, PrevBB, NextState, DuplicateMap, NewDefs, DTU);
1024 DuplicateMap[BB].push_back({NewBB, NextState});
1025 BlocksToClean.
insert(NewBB);
1036 void updateSSA(DefMap &NewDefs) {
1040 for (
const auto &KV : NewDefs) {
1043 std::vector<Instruction *> Cloned = KV.second;
1047 for (
Use &U :
I->uses()) {
1050 if (UserPN->getIncomingBlock(U) == BB)
1052 }
else if (
User->getParent() == BB) {
1061 if (UsesToRename.
empty())
1069 unsigned VarNum = SSAUpdate.
AddVariable(
I->getName(),
I->getType());
1074 while (!UsesToRename.
empty())
1089 const APInt &NextState,
1090 DuplicateBlockMap &DuplicateMap,
1104 if (isa<PHINode>(&
I))
1109 AC->registerAssumption(
II);
1112 updateSuccessorPhis(BB, NewBB, NextState, VMap, DuplicateMap);
1113 updatePredecessor(PrevBB, BB, NewBB, DTU);
1114 updateDefMap(NewDefs, VMap);
1119 if (SuccSet.
insert(SuccBB).second)
1120 DTU->
applyUpdates({{DominatorTree::Insert, NewBB, SuccBB}});
1132 DuplicateBlockMap &DuplicateMap) {
1133 std::vector<BasicBlock *> BlocksToUpdate;
1137 if (BB == SwitchPaths->getSwitchBlock()) {
1139 BasicBlock *NextCase = getNextCaseSuccessor(Switch, NextState);
1140 BlocksToUpdate.push_back(NextCase);
1141 BasicBlock *ClonedSucc = getClonedBB(NextCase, NextState, DuplicateMap);
1143 BlocksToUpdate.push_back(ClonedSucc);
1148 BlocksToUpdate.push_back(Succ);
1153 BasicBlock *ClonedSucc = getClonedBB(Succ, NextState, DuplicateMap);
1155 BlocksToUpdate.push_back(ClonedSucc);
1163 for (
auto II = Succ->begin();
PHINode *Phi = dyn_cast<PHINode>(
II);
1173 Phi->addIncoming(ClonedVal, ClonedBB);
1187 if (!isPredecessor(OldBB, PrevBB))
1197 DTU->
applyUpdates({{DominatorTree::Delete, PrevBB, OldBB},
1198 {DominatorTree::Insert, PrevBB, NewBB}});
1207 for (
auto Entry : VMap) {
1209 dyn_cast<Instruction>(
const_cast<Value *
>(
Entry.first));
1210 if (!Inst || !
Entry.second || isa<BranchInst>(Inst) ||
1211 isa<SwitchInst>(Inst)) {
1219 NewDefsVector.
push_back({Inst, Cloned});
1223 sort(NewDefsVector, [](
const auto &LHS,
const auto &RHS) {
1224 if (
LHS.first ==
RHS.first)
1225 return LHS.second->comesBefore(
RHS.second);
1226 return LHS.first->comesBefore(
RHS.first);
1229 for (
const auto &KV : NewDefsVector)
1230 NewDefs[KV.first].push_back(KV.second);
1238 void updateLastSuccessor(ThreadingPath &TPath,
1239 DuplicateBlockMap &DuplicateMap,
1241 APInt NextState = TPath.getExitValue();
1243 BasicBlock *LastBlock = getClonedBB(BB, NextState, DuplicateMap);
1250 BasicBlock *NextCase = getNextCaseSuccessor(Switch, NextState);
1252 std::vector<DominatorTree::UpdateType> DTUpdates;
1255 if (Succ != NextCase && SuccSet.
insert(Succ).second)
1256 DTUpdates.push_back({DominatorTree::Delete, LastBlock, Succ});
1259 Switch->eraseFromParent();
1270 std::vector<PHINode *> PhiToRemove;
1272 PhiToRemove.push_back(Phi);
1274 for (
PHINode *PN : PhiToRemove) {
1276 PN->eraseFromParent();
1283 std::vector<BasicBlock *> BlocksToRemove;
1285 if (!isPredecessor(BB, IncomingBB))
1286 BlocksToRemove.push_back(IncomingBB);
1289 Phi->removeIncomingValue(BB);
1296 DuplicateBlockMap &DuplicateMap) {
1297 CloneList ClonedBBs = DuplicateMap[BB];
1301 auto It =
llvm::find_if(ClonedBBs, [NextState](
const ClonedBlock &
C) {
1302 return C.State == NextState;
1304 return It != ClonedBBs.end() ? (*It).BB :
nullptr;
1311 for (
auto Case :
Switch->cases()) {
1312 if (Case.getCaseValue()->getValue() == NextState) {
1313 NextCase = Case.getCaseSuccessor();
1318 NextCase =
Switch->getDefaultDest();
1327 AllSwitchPaths *SwitchPaths;
1333 std::vector<ThreadingPath> TPaths;
1336bool DFAJumpThreading::run(
Function &
F) {
1337 LLVM_DEBUG(
dbgs() <<
"\nDFA Jump threading: " <<
F.getName() <<
"\n");
1339 if (
F.hasOptSize()) {
1340 LLVM_DEBUG(
dbgs() <<
"Skipping due to the 'minsize' attribute\n");
1348 bool MadeChanges =
false;
1349 LoopInfoBroken =
false;
1357 <<
" is a candidate\n");
1358 MainSwitch
Switch(SI, LI, ORE);
1360 if (!
Switch.getInstr()) {
1362 <<
"candidate for jump threading\n");
1367 <<
"candidate for jump threading\n");
1370 unfoldSelectInstrs(DT,
Switch.getSelectInsts());
1371 if (!
Switch.getSelectInsts().empty())
1374 AllSwitchPaths SwitchPaths(&Switch, ORE, LI,
1378 if (SwitchPaths.getNumThreadingPaths() > 0) {
1396 if (ThreadableLoops.
size() > 0)
1399 for (AllSwitchPaths SwitchPaths : ThreadableLoops) {
1400 TransformDFA Transform(&SwitchPaths, DT, AC,
TTI, ORE, EphValues);
1403 LoopInfoBroken =
true;
1406#ifdef EXPENSIVE_CHECKS
1407 assert(DT->
verify(DominatorTree::VerificationLevel::Full));
1424 DFAJumpThreading ThreadImpl(&AC, &DT, &LI, &
TTI, &ORE);
1425 if (!ThreadImpl.run(
F))
1430 if (!ThreadImpl.LoopInfoBroken)
This file implements a class to represent arbitrary precision integral constant values and operations...
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static const Function * getParent(const Value *V)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static cl::opt< unsigned > MaxPathLength("dfa-max-path-length", cl::desc("Max number of blocks searched to find a threading path"), cl::Hidden, cl::init(20))
static cl::opt< unsigned > MaxNumVisitiedPaths("dfa-max-num-visited-paths", cl::desc("Max number of blocks visited while enumerating paths around a switch"), cl::Hidden, cl::init(2000))
static cl::opt< bool > ClViewCfgBefore("dfa-jump-view-cfg-before", cl::desc("View the CFG before DFA Jump Threading"), cl::Hidden, cl::init(false))
static cl::opt< unsigned > CostThreshold("dfa-cost-threshold", cl::desc("Maximum cost accepted for the transformation"), cl::Hidden, cl::init(50))
static cl::opt< bool > EarlyExitHeuristic("dfa-early-exit-heuristic", cl::desc("Exit early if an unpredictable value come from the same loop"), cl::Hidden, cl::init(true))
static cl::opt< unsigned > MaxNumPaths("dfa-max-num-paths", cl::desc("Max number of paths enumerated around a switch"), cl::Hidden, cl::init(200))
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
static bool isCandidate(const MachineInstr *MI, Register &DefedReg, Register FrameReg)
uint64_t IntrinsicInst * II
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallSet 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.
unsigned ceilLogBase2() const
uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX) const
If this value is smaller than the specified limit, return it, otherwise return the limit value.
A container for analyses that lazily runs them and caches their results.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
This represents the llvm.assume intrinsic.
A function analysis which provides an AssumptionCache.
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const Instruction & front() const
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
void moveAfter(BasicBlock *MovePos)
Unlink this basic block from its current function and insert it right after MovePos in the function M...
const BasicBlock * getUniqueSuccessor() const
Return the successor of this block if it has a unique successor.
const Function * getParent() const
Return the enclosing method, or null if none.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
const Instruction & back() const
void removePredecessor(BasicBlock *Pred, bool KeepOneInputPHIs=false)
Update PHI nodes in this BasicBlock before removal of predecessor Pred.
Conditional or Unconditional Branch instruction.
static BranchInst * Create(BasicBlock *IfTrue, InsertPosition InsertBefore=nullptr)
BasicBlock * getSuccessor(unsigned i) const
bool isUnconditional() const
void setSuccessor(unsigned idx, BasicBlock *NewSucc)
This is the shared class of boolean and integer constants.
Analysis pass which computes a DominatorTree.
bool verify(VerificationLevel VL=VerificationLevel::Full) const
verify - checks if the tree is correct.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
void applyUpdates(ArrayRef< UpdateT > Updates)
Submit updates to all available trees.
unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
void setSuccessor(unsigned Idx, BasicBlock *BB)
Update the specified successor to point at the provided block.
Analysis pass that exposes the LoopInfo for a function.
const LoopT * getOutermostLoop() const
Get the outermost loop in which this loop is contained.
void verify(const DominatorTreeBase< BlockT, false > &DomTree) const
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
Represents a single loop in the control flow graph.
This class implements a map that also provides access to all stored values in a deterministic order.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
iterator_range< const_block_iterator > blocks() const
Value * removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty=true)
Remove an incoming value.
Value * getIncomingValueForBlock(const BasicBlock *BB) const
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static 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.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
void preserve()
Mark an analysis as preserved.
Helper class for SSA formation on a set of values defined in multiple blocks.
unsigned AddVariable(StringRef Name, Type *Ty)
Add a new variable to the SSA rewriter.
void AddAvailableValue(unsigned Var, BasicBlock *BB, Value *V)
Indicate that a rewritten value is available in the specified block with the specified value.
void RewriteAllUses(DominatorTree *DT, SmallVectorImpl< PHINode * > *InsertedPHIs=nullptr)
Perform all the necessary updates, including new PHI-nodes insertion and the requested uses update.
void AddUse(unsigned Var, Use *U)
Record a use of the symbolic value.
This class represents the LLVM 'select' instruction.
const Value * getFalseValue() const
const Value * getTrueValue() const
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.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
bool contains(const T &V) const
Check if the SmallSet contains the given element.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Analysis pass providing the TargetTransformInfo.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
A Use represents the edge between a Value definition and its users.
bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
StringRef getName() const
Return a constant reference to the value's name.
const ParentTy * getParent() const
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
@ C
The default llvm calling convention, compatible with C.
initializer< Ty > init(const Ty &Val)
@ Switch
The "resume-switch" lowering, where there are separate resume and destroy functions that are shared b...
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< InstrNode * > Instr
NodeAddr< PhiNode * > Phi
This is an optimization pass for GlobalISel generic memory operations.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
bool verifyFunction(const Function &F, raw_ostream *OS=nullptr)
Check a function for errors, useful for use when debugging a pass.
auto successors(const MachineBasicBlock *BB)
auto pred_size(const MachineBasicBlock *BB)
void sort(IteratorTy Start, IteratorTy End)
@ RF_IgnoreMissingLocals
If this flag is set, the remapper ignores missing function-local entries (Argument,...
@ RF_NoModuleLevelChanges
If this flag is set, the remapper knows that only local values within a function (such as an instruct...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void RemapInstruction(Instruction *I, ValueToValueMapTy &VM, RemapFlags Flags=RF_None, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr)
Convert the instruction operands from referencing the current values into those specified by VM.
BasicBlock * CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap, const Twine &NameSuffix="", Function *F=nullptr, ClonedCodeInfo *CodeInfo=nullptr)
Return a copy of the specified basic block, but without embedding the block into a particular functio...
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
auto predecessors(const MachineBasicBlock *BB)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
bool pred_empty(const BasicBlock *BB)
Utility to calculate the size and a few similar metrics for a set of basic blocks.
static void collectEphemeralValues(const Loop *L, AssumptionCache *AC, SmallPtrSetImpl< const Value * > &EphValues)
Collect a loop's ephemeral values (those used only by an assume or similar intrinsics in the loop).
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Integrate with the new Pass Manager.
Incoming for lane maks phi as machine instruction, incoming register Reg and incoming block Block are...