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) {
759 StateDefMap getStateDefMap()
const {
761 PHINode *FirstDef = dyn_cast<PHINode>(
Switch->getOperand(0));
762 assert(FirstDef &&
"The first definition must be a phi.");
765 Stack.push_back(FirstDef);
768 while (!
Stack.empty()) {
772 SeenValues.
insert(CurPhi);
779 bool IsOutsideLoops = !SwitchOuterLoop->contains(IncomingBB);
780 if (SeenValues.
contains(IncomingPhi) || IsOutsideLoops)
783 Stack.push_back(IncomingPhi);
790 unsigned NumVisited = 0;
794 std::vector<ThreadingPath> TPaths;
796 Loop *SwitchOuterLoop;
804 : SwitchPaths(SwitchPaths), DT(DT), AC(AC),
TTI(
TTI), ORE(ORE),
805 EphValues(EphValues) {}
808 if (isLegalAndProfitableToTransform()) {
809 createAllExitPaths();
819 bool isLegalAndProfitableToTransform() {
824 if (
Switch->getNumSuccessors() <= 1)
829 DuplicateBlockMap DuplicateMap;
831 for (ThreadingPath &TPath : SwitchPaths->getThreadingPaths()) {
832 PathType PathBBs = TPath.getPath();
833 APInt NextState = TPath.getExitValue();
834 const BasicBlock *Determinator = TPath.getDeterminatorBB();
837 BasicBlock *BB = SwitchPaths->getSwitchBlock();
838 BasicBlock *VisitedBB = getClonedBB(BB, NextState, DuplicateMap);
840 Metrics.analyzeBasicBlock(BB, *
TTI, EphValues);
841 DuplicateMap[BB].push_back({BB, NextState});
846 if (PathBBs.front() == Determinator)
851 auto DetIt =
llvm::find(PathBBs, Determinator);
852 for (
auto BBIt = DetIt; BBIt != PathBBs.end(); BBIt++) {
854 VisitedBB = getClonedBB(BB, NextState, DuplicateMap);
857 Metrics.analyzeBasicBlock(BB, *
TTI, EphValues);
858 DuplicateMap[BB].push_back({BB, NextState});
862 LLVM_DEBUG(
dbgs() <<
"DFA Jump Threading: Not jump threading, contains "
863 <<
"non-duplicatable instructions.\n");
867 <<
"Contains non-duplicatable instructions.";
873 if (
Metrics.Convergence != ConvergenceKind::None) {
874 LLVM_DEBUG(
dbgs() <<
"DFA Jump Threading: Not jump threading, contains "
875 <<
"convergent instructions.\n");
878 <<
"Contains convergent instructions.";
883 if (!
Metrics.NumInsts.isValid()) {
884 LLVM_DEBUG(
dbgs() <<
"DFA Jump Threading: Not jump threading, contains "
885 <<
"instructions with invalid cost.\n");
888 <<
"Contains instructions with invalid cost.";
896 unsigned JumpTableSize = 0;
899 if (JumpTableSize == 0) {
903 unsigned CondBranches =
905 assert(CondBranches > 0 &&
906 "The threaded switch must have multiple branches");
907 DuplicationCost =
Metrics.NumInsts / CondBranches;
915 DuplicationCost =
Metrics.NumInsts / JumpTableSize;
918 LLVM_DEBUG(
dbgs() <<
"\nDFA Jump Threading: Cost to jump thread block "
919 << SwitchPaths->getSwitchBlock()->getName()
920 <<
" is: " << DuplicationCost <<
"\n\n");
923 LLVM_DEBUG(
dbgs() <<
"Not jump threading, duplication cost exceeds the "
924 <<
"cost threshold.\n");
927 <<
"Duplication cost exceeds the cost threshold (cost="
928 <<
ore::NV(
"Cost", DuplicationCost)
936 <<
"Switch statement jump-threaded.";
943 void createAllExitPaths() {
947 BasicBlock *SwitchBlock = SwitchPaths->getSwitchBlock();
948 for (ThreadingPath &TPath : SwitchPaths->getThreadingPaths()) {
952 TPath.push_front(SwitchBlock);
956 DuplicateBlockMap DuplicateMap;
963 for (ThreadingPath &TPath : SwitchPaths->getThreadingPaths()) {
964 createExitPath(NewDefs, TPath, DuplicateMap, BlocksToClean, &DTU);
970 for (ThreadingPath &TPath : SwitchPaths->getThreadingPaths())
971 updateLastSuccessor(TPath, DuplicateMap, &DTU);
987 void createExitPath(DefMap &NewDefs, ThreadingPath &Path,
988 DuplicateBlockMap &DuplicateMap,
993 PathType PathBBs =
Path.getPath();
996 if (PathBBs.front() == Determinator)
999 auto DetIt =
llvm::find(PathBBs, Determinator);
1002 BasicBlock *PrevBB = PathBBs.
size() == 1 ? *DetIt : *std::prev(DetIt);
1003 for (
auto BBIt = DetIt; BBIt != PathBBs.end(); BBIt++) {
1005 BlocksToClean.
insert(BB);
1009 BasicBlock *NextBB = getClonedBB(BB, NextState, DuplicateMap);
1011 updatePredecessor(PrevBB, BB, NextBB, DTU);
1017 BasicBlock *NewBB = cloneBlockAndUpdatePredecessor(
1018 BB, PrevBB, NextState, DuplicateMap, NewDefs, DTU);
1019 DuplicateMap[BB].push_back({NewBB, NextState});
1020 BlocksToClean.
insert(NewBB);
1031 void updateSSA(DefMap &NewDefs) {
1035 for (
const auto &KV : NewDefs) {
1038 std::vector<Instruction *> Cloned = KV.second;
1042 for (
Use &U :
I->uses()) {
1045 if (UserPN->getIncomingBlock(U) == BB)
1047 }
else if (
User->getParent() == BB) {
1056 if (UsesToRename.
empty())
1064 unsigned VarNum = SSAUpdate.
AddVariable(
I->getName(),
I->getType());
1069 while (!UsesToRename.
empty())
1084 const APInt &NextState,
1085 DuplicateBlockMap &DuplicateMap,
1099 if (isa<PHINode>(&
I))
1104 AC->registerAssumption(
II);
1107 updateSuccessorPhis(BB, NewBB, NextState, VMap, DuplicateMap);
1108 updatePredecessor(PrevBB, BB, NewBB, DTU);
1109 updateDefMap(NewDefs, VMap);
1114 if (SuccSet.
insert(SuccBB).second)
1115 DTU->
applyUpdates({{DominatorTree::Insert, NewBB, SuccBB}});
1127 DuplicateBlockMap &DuplicateMap) {
1128 std::vector<BasicBlock *> BlocksToUpdate;
1132 if (BB == SwitchPaths->getSwitchBlock()) {
1134 BasicBlock *NextCase = getNextCaseSuccessor(Switch, NextState);
1135 BlocksToUpdate.push_back(NextCase);
1136 BasicBlock *ClonedSucc = getClonedBB(NextCase, NextState, DuplicateMap);
1138 BlocksToUpdate.push_back(ClonedSucc);
1143 BlocksToUpdate.push_back(Succ);
1148 BasicBlock *ClonedSucc = getClonedBB(Succ, NextState, DuplicateMap);
1150 BlocksToUpdate.push_back(ClonedSucc);
1158 for (
auto II = Succ->begin();
PHINode *Phi = dyn_cast<PHINode>(
II);
1168 Phi->addIncoming(ClonedVal, ClonedBB);
1182 if (!isPredecessor(OldBB, PrevBB))
1192 DTU->
applyUpdates({{DominatorTree::Delete, PrevBB, OldBB},
1193 {DominatorTree::Insert, PrevBB, NewBB}});
1202 for (
auto Entry : VMap) {
1204 dyn_cast<Instruction>(
const_cast<Value *
>(
Entry.first));
1205 if (!Inst || !
Entry.second || isa<BranchInst>(Inst) ||
1206 isa<SwitchInst>(Inst)) {
1214 NewDefsVector.
push_back({Inst, Cloned});
1218 sort(NewDefsVector, [](
const auto &LHS,
const auto &RHS) {
1219 if (
LHS.first ==
RHS.first)
1220 return LHS.second->comesBefore(
RHS.second);
1221 return LHS.first->comesBefore(
RHS.first);
1224 for (
const auto &KV : NewDefsVector)
1225 NewDefs[KV.first].push_back(KV.second);
1233 void updateLastSuccessor(ThreadingPath &TPath,
1234 DuplicateBlockMap &DuplicateMap,
1236 APInt NextState = TPath.getExitValue();
1238 BasicBlock *LastBlock = getClonedBB(BB, NextState, DuplicateMap);
1245 BasicBlock *NextCase = getNextCaseSuccessor(Switch, NextState);
1247 std::vector<DominatorTree::UpdateType> DTUpdates;
1250 if (Succ != NextCase && SuccSet.
insert(Succ).second)
1251 DTUpdates.push_back({DominatorTree::Delete, LastBlock, Succ});
1254 Switch->eraseFromParent();
1265 std::vector<PHINode *> PhiToRemove;
1267 PhiToRemove.push_back(Phi);
1269 for (
PHINode *PN : PhiToRemove) {
1271 PN->eraseFromParent();
1278 std::vector<BasicBlock *> BlocksToRemove;
1280 if (!isPredecessor(BB, IncomingBB))
1281 BlocksToRemove.push_back(IncomingBB);
1284 Phi->removeIncomingValue(BB);
1291 DuplicateBlockMap &DuplicateMap) {
1292 CloneList ClonedBBs = DuplicateMap[BB];
1296 auto It =
llvm::find_if(ClonedBBs, [NextState](
const ClonedBlock &
C) {
1297 return C.State == NextState;
1299 return It != ClonedBBs.end() ? (*It).BB :
nullptr;
1306 for (
auto Case :
Switch->cases()) {
1307 if (Case.getCaseValue()->getValue() == NextState) {
1308 NextCase = Case.getCaseSuccessor();
1313 NextCase =
Switch->getDefaultDest();
1322 AllSwitchPaths *SwitchPaths;
1328 std::vector<ThreadingPath> TPaths;
1331bool DFAJumpThreading::run(
Function &
F) {
1332 LLVM_DEBUG(
dbgs() <<
"\nDFA Jump threading: " <<
F.getName() <<
"\n");
1334 if (
F.hasOptSize()) {
1335 LLVM_DEBUG(
dbgs() <<
"Skipping due to the 'minsize' attribute\n");
1343 bool MadeChanges =
false;
1344 LoopInfoBroken =
false;
1352 <<
" is a candidate\n");
1353 MainSwitch
Switch(SI, LI, ORE);
1355 if (!
Switch.getInstr()) {
1357 <<
"candidate for jump threading\n");
1362 <<
"candidate for jump threading\n");
1365 unfoldSelectInstrs(DT,
Switch.getSelectInsts());
1366 if (!
Switch.getSelectInsts().empty())
1369 AllSwitchPaths SwitchPaths(&Switch, ORE, LI,
1373 if (SwitchPaths.getNumThreadingPaths() > 0) {
1391 if (ThreadableLoops.
size() > 0)
1394 for (AllSwitchPaths SwitchPaths : ThreadableLoops) {
1395 TransformDFA Transform(&SwitchPaths, DT, AC,
TTI, ORE, EphValues);
1398 LoopInfoBroken =
true;
1401#ifdef EXPENSIVE_CHECKS
1402 assert(DT->
verify(DominatorTree::VerificationLevel::Full));
1419 DFAJumpThreading ThreadImpl(&AC, &DT, &LI, &
TTI, &ORE);
1420 if (!ThreadImpl.run(
F))
1425 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(2500))
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...