65 #define DEBUG_TYPE "guard-widening" 67 STATISTIC(GuardsEliminated,
"Number of eliminated guards");
68 STATISTIC(CondBranchEliminated,
"Number of eliminated conditional branches");
71 "guard-widening-widen-frequent-branches",
cl::Hidden,
72 cl::desc(
"Widen conditions of explicit branches into dominating guards in " 73 "case if their taken frequency exceeds threshold set by " 74 "guard-widening-frequent-branch-threshold option"),
78 "guard-widening-frequent-branch-threshold",
cl::Hidden,
79 cl::desc(
"When WidenFrequentBranches is set to true, this option is used " 80 "to determine which branches are frequently taken. The criteria " 81 "that a branch is taken more often than " 82 "((FrequentBranchThreshold - 1) / FrequentBranchThreshold), then " 83 "it is considered frequently taken"),
93 "Bad guard intrinsic?");
94 return GI->getArgOperand(0);
96 return cast<BranchInst>(
I)->getCondition();
104 "Bad guard intrinsic?");
105 GI->setArgOperand(0, NewCond);
108 cast<BranchInst>(
I)->setCondition(NewCond);
112 static void eliminateGuard(
Instruction *GuardInst) {
117 class GuardWideningImpl {
126 std::function<bool(BasicBlock*)> BlockFilter;
140 bool eliminateGuardViaWidening(
143 GuardsPerBlock,
bool InvertCondition =
false);
148 WS_IllegalOrNegative,
163 static StringRef scoreTypeToString(WideningScore WS);
169 WideningScore computeWideningScore(
Instruction *DominatedGuard,
170 Loop *DominatedGuardLoop,
172 Loop *DominatingGuardLoop,
178 return isAvailableAt(V, InsertPos, Visited);
196 Value *&Result,
bool InvertCondition);
211 : Base(Base), Offset(Offset), Length(Length), CheckInst(CheckInst) {}
213 void setBase(
Value *NewBase) { Base = NewBase; }
214 void setOffset(
ConstantInt *NewOffset) { Offset = NewOffset; }
216 Value *getBase()
const {
return Base; }
218 const APInt &getOffsetValue()
const {
return getOffset()->getValue(); }
219 Value *getLength()
const {
return Length; };
220 ICmpInst *getCheckInst()
const {
return CheckInst; }
242 return parseRangeChecks(CheckCond, Checks, Visited);
257 bool isWideningCondProfitable(
Value *Cond0,
Value *Cond1,
bool InvertCond) {
259 return widenCondCommon(Cond0, Cond1,
nullptr, ResultUnused,
267 bool InvertCondition) {
269 widenCondCommon(ToWiden->
getOperand(0), NewCondition, ToWiden, Result,
271 setCondition(ToWiden, Result);
280 : DT(DT), PDT(PDT), LI(LI), BPI(BPI), Root(Root), BlockFilter(BlockFilter)
288 bool GuardWideningImpl::run() {
290 bool Changed =
false;
294 assert(Threshold > 0 &&
"Zero threshold makes no sense!");
300 auto *BB = (*DFI)->getBlock();
301 if (!BlockFilter(BB))
304 auto &CurrentList = GuardsInBlock[BB];
308 CurrentList.push_back(cast<Instruction>(&I));
310 for (
auto *II : CurrentList)
311 Changed |= eliminateGuardViaWidening(II, DFI, GuardsInBlock);
313 if (
auto *BI = dyn_cast<BranchInst>(BB->getTerminator()))
314 if (BI->isConditional()) {
318 Changed |= eliminateGuardViaWidening(BI, DFI, GuardsInBlock);
320 Changed |= eliminateGuardViaWidening(BI, DFI, GuardsInBlock,
325 assert(EliminatedGuardsAndBranches.
empty() || Changed);
326 for (
auto *I : EliminatedGuardsAndBranches)
327 if (!WidenedGuards.
count(I)) {
328 assert(isa<ConstantInt>(getCondition(I)) &&
"Should be!");
332 assert(isa<BranchInst>(I) &&
333 "Eliminated something other than guard or branch?");
334 ++CondBranchEliminated;
341 bool GuardWideningImpl::eliminateGuardViaWidening(
344 GuardsInBlock,
bool InvertCondition) {
348 if (isa<ConstantInt>(getCondition(GuardInst)))
352 auto BestScoreSoFar = WS_IllegalOrNegative;
357 for (
unsigned i = 0, e = DFSI.
getPathLength(); i != e; ++i) {
358 auto *CurBB = DFSI.
getPath(i)->getBlock();
359 if (!BlockFilter(CurBB))
362 assert(GuardsInBlock.
count(CurBB) &&
"Must have been populated by now!");
363 const auto &GuardsInCurBB = GuardsInBlock.
find(CurBB)->second;
365 auto I = GuardsInCurBB.begin();
366 auto E = GuardsInCurBB.end();
371 for (
auto &I : *CurBB) {
372 if (Index == GuardsInCurBB.size())
374 if (GuardsInCurBB[Index] == &I)
377 assert(Index == GuardsInCurBB.size() &&
378 "Guards expected to be in order!");
382 assert((i == (e - 1)) == (GuardInst->
getParent() == CurBB) &&
"Bad DFS?");
384 if (i == (e - 1) && CurBB->getTerminator() != GuardInst) {
388 assert(NewEnd !=
E &&
"GuardInst not in its own block?");
394 computeWideningScore(GuardInst, GuardInstLoop, Candidate, CurLoop,
397 <<
" and " << *getCondition(Candidate) <<
" is " 398 << scoreTypeToString(Score) <<
"\n");
399 if (Score > BestScoreSoFar) {
400 BestScoreSoFar = Score;
401 BestSoFar = Candidate;
406 if (BestScoreSoFar == WS_IllegalOrNegative) {
407 LLVM_DEBUG(
dbgs() <<
"Did not eliminate guard " << *GuardInst <<
"\n");
411 assert(BestSoFar != GuardInst &&
"Should have never visited same guard!");
414 LLVM_DEBUG(
dbgs() <<
"Widening " << *GuardInst <<
" into " << *BestSoFar
415 <<
" with score " << scoreTypeToString(BestScoreSoFar)
417 widenGuard(BestSoFar, getCondition(GuardInst), InvertCondition);
418 auto NewGuardCondition = InvertCondition
421 setCondition(GuardInst, NewGuardCondition);
422 EliminatedGuardsAndBranches.push_back(GuardInst);
423 WidenedGuards.
insert(BestSoFar);
427 GuardWideningImpl::WideningScore GuardWideningImpl::computeWideningScore(
429 Instruction *DominatingGuard,
Loop *DominatingGuardLoop,
bool InvertCond) {
430 bool HoistingOutOfLoop =
false;
432 if (DominatingGuardLoop != DominatedGuardLoop) {
435 if (DominatingGuardLoop &&
436 !DominatingGuardLoop->
contains(DominatedGuardLoop))
437 return WS_IllegalOrNegative;
439 HoistingOutOfLoop =
true;
442 if (!isAvailableAt(getCondition(DominatedGuard), DominatingGuard))
443 return WS_IllegalOrNegative;
453 if (isWideningCondProfitable(getCondition(DominatedGuard),
454 getCondition(DominatingGuard), InvertCond))
455 return HoistingOutOfLoop ? WS_VeryPositive : WS_Positive;
457 if (HoistingOutOfLoop)
463 auto MaybeHoistingOutOfIf = [&]() {
464 auto *DominatingBlock = DominatingGuard->
getParent();
465 auto *DominatedBlock = DominatedGuard->
getParent();
468 if (DominatedBlock == DominatingBlock)
471 if (DominatedBlock == DominatingBlock->getUniqueSuccessor())
474 if (!PDT)
return true;
475 return !PDT->
dominates(DominatedBlock, DominatingBlock);
478 return MaybeHoistingOutOfIf() ? WS_IllegalOrNegative : WS_Neutral;
488 Inst->mayReadFromMemory())
494 assert(!isa<PHINode>(Loc) &&
495 "PHIs should return false for isSafeToSpeculativelyExecute");
497 "We did a DFS from the block entry!");
498 return all_of(Inst->operands(),
499 [&](
Value *
Op) {
return isAvailableAt(
Op, Loc, Visited); });
508 !Inst->mayReadFromMemory() &&
"Should've checked with isAvailableAt!");
510 for (
Value *
Op : Inst->operands())
511 makeAvailableAt(
Op, Loc);
513 Inst->moveBefore(Loc);
516 bool GuardWideningImpl::widenCondCommon(
Value *Cond0,
Value *Cond1,
518 bool InvertCondition) {
550 if (SubsetIntersect == SupersetIntersect &&
551 SubsetIntersect.getEquivalentICmp(Pred, NewRHSAP)) {
554 Result =
new ICmpInst(InsertPt, Pred, LHS, NewRHS,
"wide.chk");
564 if (!InvertCondition &&
565 parseRangeChecks(Cond0, Checks) && parseRangeChecks(Cond1, Checks) &&
566 combineRangeChecks(Checks, CombinedChecks)) {
569 for (
auto &RC : CombinedChecks) {
570 makeAvailableAt(RC.getCheckInst(), InsertPt);
572 Result = BinaryOperator::CreateAnd(RC.getCheckInst(), Result,
"",
575 Result = RC.getCheckInst();
587 makeAvailableAt(Cond0, InsertPt);
588 makeAvailableAt(Cond1, InsertPt);
591 Result = BinaryOperator::CreateAnd(Cond0, Cond1,
"wide.chk", InsertPt);
598 bool GuardWideningImpl::parseRangeChecks(
601 if (!Visited.
insert(CheckCond).second)
607 Value *AndLHS, *AndRHS;
609 return parseRangeChecks(AndLHS, Checks) &&
610 parseRangeChecks(AndRHS, Checks);
614 if (!IC || !IC->getOperand(0)->getType()->isIntegerTy() ||
619 Value *CmpLHS = IC->getOperand(0), *CmpRHS = IC->getOperand(1);
623 auto &DL = IC->getModule()->getDataLayout();
625 GuardWideningImpl::RangeCheck
Check(
646 "Unreachable instruction?");
650 Check.setBase(OpLHS);
658 Check.setBase(OpLHS);
670 bool GuardWideningImpl::combineRangeChecks(
673 unsigned OldCount = Checks.
size();
674 while (!Checks.
empty()) {
677 Value *CurrentBase = Checks.
front().getBase();
678 Value *CurrentLength = Checks.
front().getLength();
682 auto IsCurrentCheck = [&](GuardWideningImpl::RangeCheck &RC) {
683 return RC.getBase() == CurrentBase && RC.getLength() == CurrentLength;
686 copy_if(Checks, std::back_inserter(CurrentChecks), IsCurrentCheck);
689 assert(CurrentChecks.
size() != 0 &&
"We know we have at least one!");
691 if (CurrentChecks.
size() < 3) {
692 RangeChecksOut.
insert(RangeChecksOut.
end(), CurrentChecks.
begin(),
693 CurrentChecks.
end());
700 llvm::sort(CurrentChecks, [&](
const GuardWideningImpl::RangeCheck &LHS,
701 const GuardWideningImpl::RangeCheck &RHS) {
702 return LHS.getOffsetValue().slt(RHS.getOffsetValue());
708 *MaxOffset = CurrentChecks.
back().getOffset();
710 unsigned BitWidth = MaxOffset->getValue().getBitWidth();
711 if ((MaxOffset->getValue() - MinOffset->getValue())
715 APInt MaxDiff = MaxOffset->getValue() - MinOffset->getValue();
716 const APInt &HighOffset = MaxOffset->getValue();
717 auto OffsetOK = [&](
const GuardWideningImpl::RangeCheck &RC) {
718 return (HighOffset - RC.getOffsetValue()).ult(MaxDiff);
765 assert(RangeChecksOut.
size() <= OldCount &&
"We pessimized!");
766 return RangeChecksOut.
size() != OldCount;
770 StringRef GuardWideningImpl::scoreTypeToString(WideningScore WS) {
772 case WS_IllegalOrNegative:
773 return "IllegalOrNegative";
778 case WS_VeryPositive:
779 return "VeryPositive";
794 if (!GuardWideningImpl(DT, &PDT, LI, BPI, DT.
getRootNode(),
814 auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
815 auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
816 auto &PDT = getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree();
819 BPI = &getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
820 return GuardWideningImpl(DT, &PDT, LI, BPI, DT.
getRootNode(),
836 struct LoopGuardWideningLegacyPass :
public LoopPass {
839 LoopGuardWideningLegacyPass() :
LoopPass(ID) {
846 auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
847 auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
848 auto *PDTWP = getAnalysisIfAvailable<PostDominatorTreeWrapperPass>();
849 auto *PDT = PDTWP ? &PDTWP->getPostDomTree() :
nullptr;
854 return BB == RootBB || L->
contains(BB);
858 BPI = &getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
859 return GuardWideningImpl(DT, PDT, LI, BPI,
860 DT.
getNode(RootBB), BlockFilter).run();
887 "
Widen guards (within a single loop, as a loop
pass)",
895 "
Widen guards (within a single loop, as a loop pass)",
899 return new GuardWideningLegacyPass();
903 return new LoopGuardWideningLegacyPass();
Pass interface - Implemented by all 'passes'.
static bool Check(DecodeStatus &Out, DecodeStatus In)
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, OptimizationRemarkEmitter *ORE=nullptr, bool UseInstrInfo=true)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
static ConstantInt * getFalse(LLVMContext &Context)
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
Safe Stack instrumentation pass
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...
ConstantRange unionWith(const ConstantRange &CR) const
Return the range that results from the union of this range with another range.
static BinaryOperator * CreateNot(Value *Op, const Twine &Name="", Instruction *InsertBefore=nullptr)
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
This class represents lattice values for constants.
OutputIt copy_if(R &&Range, OutputIt Out, UnaryPredicate P)
Provide wrappers to std::copy_if which take ranges instead of having to pass begin/end explicitly...
Implements a dense probed hash-table based set.
void push_back(const T &Elt)
void initializeGuardWideningLegacyPassPass(PassRegistry &)
LLVMContext & getContext() const
All values hold a context through their type.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly...
STATISTIC(NumFunctions, "Total number of functions")
Analysis pass which computes a DominatorTree.
bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
bool match(Val *V, const Pattern &P)
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE, etc.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
NodeRef getPath(unsigned n) const
getPath - Return the n'th node in the path from the entry node to the current node.
unsigned getPathLength() const
getPathLength - Return the length of the path from the entry node to the current node, counting both nodes.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void setName(const Twine &Name)
Change the name of the value.
Analysis pass that exposes the LoopInfo for a function.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
BlockT * getHeader() const
Analysis pass which computes BranchProbabilityInfo.
ConstantRange intersectWith(const ConstantRange &CR) const
Return the range that results from the intersection of this range with another range.
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
const APInt & getValue() const
Return the constant as an APInt value reference.
static Error getOffset(const SymbolRef &Sym, SectionRef Sec, uint64_t &Result)
bool isKnownNonNegative(const Value *V, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Returns true if the give value is known to be non-negative.
static cl::opt< bool > WidenFrequentBranches("guard-widening-widen-frequent-branches", cl::Hidden, cl::desc("Widen conditions of explicit branches into dominating guards in " "case if their taken frequency exceeds threshold set by " "guard-widening-frequent-branch-threshold option"), cl::init(false))
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
Legacy analysis pass which computes BranchProbabilityInfo.
Value * getOperand(unsigned i) const
iterator find(const_arg_type_t< KeyT > Val)
static bool runOnFunction(Function &F, bool PostInlining)
initializer< Ty > init(const Ty &Val)
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
A set of analyses that are preserved following a run of a transformation pass.
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
LLVM Basic Block Representation.
BinaryOp_match< LHS, RHS, Instruction::Or > m_Or(const LHS &L, const RHS &R)
df_iterator< T > df_end(const T &G)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
std::pair< iterator, bool > insert(const ValueT &V)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
Represent the analysis usage information of a pass.
FunctionPass * createGuardWideningPass()
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
This instruction compares its operands according to the predicate given to the constructor.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
FunctionPass class - This class is used to implement most global optimizations.
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
auto remove_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range))
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly...
DomTreeNodeBase< NodeT > * getRootNode()
getRootNode - This returns the entry node for the CFG of the function.
iterator erase(const_iterator CI)
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
auto find(R &&Range, const T &Val) -> decltype(adl_begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const
Print the name of this Value out to the specified raw_ostream.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static SDValue Widen(SelectionDAG *CurDAG, SDValue N)
BranchProbability getEdgeProbability(const BasicBlock *Src, unsigned IndexInSuccessors) const
Get an edge's probability, relative to other out-edges of the Src.
void sort(IteratorTy Start, IteratorTy End)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
BlockT * getLoopPredecessor() const
If the given loop's header has exactly one unique predecessor outside the loop, return it...
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
void initializeLoopGuardWideningLegacyPassPass(PassRegistry &)
static ConstantRange makeExactICmpRegion(CmpInst::Predicate Pred, const APInt &Other)
Produce the exact range such that all values in the returned range satisfy the given predicate with a...
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
This is the shared class of boolean and integer constants.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
bool dominates(const Instruction *Def, const Use &U) const
Return true if Def dominates a use in User.
Analysis pass which computes a PostDominatorTree.
INITIALIZE_PASS_BEGIN(GuardWideningLegacyPass, "guard-widening", "Widen guards", false, false) if(WidenFrequentBranches) INITIALIZE_PASS_END(GuardWideningLegacyPass
This class represents a range of values.
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 setPreservesCFG()
This function should be called by the pass, iff they do not:
static ConstantInt * getTrue(LLVMContext &Context)
static cl::opt< unsigned > FrequentBranchThreshold("guard-widening-frequent-branch-threshold", cl::Hidden, cl::desc("When WidenFrequentBranches is set to true, this option is used " "to determine which branches are frequently taken. The criteria " "that a branch is taken more often than " "((FrequentBranchThreshold - 1) / FrequentBranchThreshold), then " "it is considered frequently taken"), cl::init(1000))
bool isGuard(const User *U)
Returns true iff U has semantics of a guard.
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.
df_iterator< T > df_begin(const T &G)
Class for arbitrary precision integers.
static cl::opt< unsigned > Threshold("loop-unswitch-threshold", cl::desc("Max loop size to unswitch"), cl::init(100), cl::Hidden)
PostDominatorTree Class - Concrete subclass of DominatorTree that is used to compute the post-dominat...
Represents analyses that only rely on functions' control flow.
iterator insert(iterator I, T &&Elt)
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
Analysis providing branch probability information.
void emplace_back(ArgTypes &&... Args)
LLVM_NODISCARD bool empty() const
Represents a single loop in the control flow graph.
void preserveSet()
Mark an analysis set as preserved.
void getLoopAnalysisUsage(AnalysisUsage &AU)
Helper to consistently add the set of standard passes to a loop pass's AnalysisUsage.
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
bool isMinValue() const
Determine if this is the smallest unsigned value.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
bool isSafeToSpeculativelyExecute(const Value *V, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr)
Return true if the instruction does not have any effects besides calculating the result and does not ...
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream...
The legacy pass manager's analysis pass to compute loop information.
print Print MemDeps of function
StringRef - Represent a constant reference to a string, i.e.
A container for analyses that lazily runs them and caches their results.
Legacy analysis pass which computes a DominatorTree.
Pass * createLoopGuardWideningPass()
ConstantRange inverse() const
Return a new range that is the logical not of the current set.
A wrapper class for inspecting calls to intrinsic functions.
const BasicBlock * getParent() const
CmpClass_match< LHS, RHS, ICmpInst, ICmpInst::Predicate > m_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R)