Go to the documentation of this file.
67 #define DEBUG_TYPE "guard-widening"
69 STATISTIC(GuardsEliminated,
"Number of eliminated guards");
70 STATISTIC(CondBranchEliminated,
"Number of eliminated conditional branches");
74 cl::desc(
"Whether or not we should widen guards "
75 "expressed as branches by widenable conditions"),
83 assert(GI->getIntrinsicID() == Intrinsic::experimental_guard &&
84 "Bad guard intrinsic?");
85 return GI->getArgOperand(0);
92 return cast<BranchInst>(
I)->getCondition();
99 assert(GI->getIntrinsicID() == Intrinsic::experimental_guard &&
100 "Bad guard intrinsic?");
101 GI->setArgOperand(0, NewCond);
104 cast<BranchInst>(
I)->setCondition(NewCond);
115 class GuardWideningImpl {
138 bool eliminateInstrViaWidening(
141 GuardsPerBlock,
bool InvertCondition =
false);
146 WS_IllegalOrNegative,
161 static StringRef scoreTypeToString(WideningScore WS);
166 WideningScore computeWideningScore(
Instruction *DominatedInstr,
173 return isAvailableAt(V, InsertPos, Visited);
191 Value *&Result,
bool InvertCondition);
208 void setBase(
const Value *NewBase) {
Base = NewBase; }
211 const Value *getBase()
const {
return Base; }
213 const APInt &getOffsetValue()
const {
return getOffset()->getValue(); }
214 const Value *getLength()
const {
return Length; };
215 ICmpInst *getCheckInst()
const {
return CheckInst; }
219 Base->printAsOperand(OS, PrintTypes);
221 Offset->printAsOperand(OS, PrintTypes);
237 return parseRangeChecks(CheckCond, Checks, Visited);
252 bool isWideningCondProfitable(
Value *Cond0,
Value *Cond1,
bool InvertCond) {
254 return widenCondCommon(Cond0, Cond1,
nullptr, ResultUnused,
262 bool InvertCondition) {
265 widenCondCommon(getCondition(ToWiden), NewCondition, ToWiden, Result,
271 setCondition(ToWiden, Result);
279 : DT(DT), PDT(PDT), LI(LI), MSSAU(MSSAU), Root(Root),
280 BlockFilter(BlockFilter) {}
297 bool Changed =
false;
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 |= eliminateInstrViaWidening(II, DFI, GuardsInBlock);
314 assert(EliminatedGuardsAndBranches.empty() || Changed);
315 for (
auto *
I : EliminatedGuardsAndBranches)
316 if (!WidenedGuards.
count(
I)) {
317 assert(isa<ConstantInt>(getCondition(
I)) &&
"Should be!");
319 eliminateGuard(
I, MSSAU);
322 "Eliminated something other than guard or branch?");
323 ++CondBranchEliminated;
330 bool GuardWideningImpl::eliminateInstrViaWidening(
333 GuardsInBlock,
bool InvertCondition) {
337 if (isa<ConstantInt>(getCondition(Instr)))
341 auto BestScoreSoFar = WS_IllegalOrNegative;
346 auto *CurBB = DFSI.
getPath(
i)->getBlock();
347 if (!BlockFilter(CurBB))
349 assert(GuardsInBlock.
count(CurBB) &&
"Must have been populated by now!");
350 const auto &GuardsInCurBB = GuardsInBlock.
find(CurBB)->second;
352 auto I = GuardsInCurBB.begin();
354 : GuardsInCurBB.
end();
359 for (
auto &
I : *CurBB) {
360 if (Index == GuardsInCurBB.size())
362 if (GuardsInCurBB[Index] == &
I)
365 assert(Index == GuardsInCurBB.size() &&
366 "Guards expected to be in order!");
373 auto Score = computeWideningScore(Instr, Candidate, InvertCondition);
375 <<
" and " << *getCondition(Candidate) <<
" is "
376 << scoreTypeToString(Score) <<
"\n");
377 if (Score > BestScoreSoFar) {
378 BestScoreSoFar = Score;
379 BestSoFar = Candidate;
384 if (BestScoreSoFar == WS_IllegalOrNegative) {
385 LLVM_DEBUG(
dbgs() <<
"Did not eliminate guard " << *Instr <<
"\n");
389 assert(BestSoFar != Instr &&
"Should have never visited same guard!");
392 LLVM_DEBUG(
dbgs() <<
"Widening " << *Instr <<
" into " << *BestSoFar
393 <<
" with score " << scoreTypeToString(BestScoreSoFar)
395 widenGuard(BestSoFar, getCondition(Instr), InvertCondition);
396 auto NewGuardCondition = InvertCondition
399 setCondition(Instr, NewGuardCondition);
400 EliminatedGuardsAndBranches.push_back(Instr);
401 WidenedGuards.
insert(BestSoFar);
405 GuardWideningImpl::WideningScore
406 GuardWideningImpl::computeWideningScore(
Instruction *DominatedInstr,
411 bool HoistingOutOfLoop =
false;
413 if (DominatingGuardLoop != DominatedInstrLoop) {
416 if (DominatingGuardLoop &&
417 !DominatingGuardLoop->
contains(DominatedInstrLoop))
418 return WS_IllegalOrNegative;
420 HoistingOutOfLoop =
true;
423 if (!isAvailableAt(getCondition(DominatedInstr), DominatingGuard))
424 return WS_IllegalOrNegative;
434 if (isWideningCondProfitable(getCondition(DominatedInstr),
435 getCondition(DominatingGuard), InvertCond))
436 return HoistingOutOfLoop ? WS_VeryPositive : WS_Positive;
438 if (HoistingOutOfLoop)
444 auto MaybeHoistingOutOfIf = [&]() {
445 auto *DominatingBlock = DominatingGuard->
getParent();
446 auto *DominatedBlock = DominatedInstr->
getParent();
448 DominatingBlock = cast<BranchInst>(DominatingGuard)->getSuccessor(0);
451 if (DominatedBlock == DominatingBlock)
454 if (DominatedBlock == DominatingBlock->getUniqueSuccessor())
457 if (!PDT)
return true;
458 return !PDT->
dominates(DominatedBlock, DominatingBlock);
461 return MaybeHoistingOutOfIf() ? WS_IllegalOrNegative : WS_Neutral;
464 bool GuardWideningImpl::isAvailableAt(
467 auto *Inst = dyn_cast<Instruction>(V);
472 Inst->mayReadFromMemory())
478 assert(!isa<PHINode>(Loc) &&
479 "PHIs should return false for isSafeToSpeculativelyExecute");
481 "We did a DFS from the block entry!");
482 return all_of(Inst->operands(),
483 [&](
Value *
Op) { return isAvailableAt(Op, Loc, Visited); });
487 auto *Inst = dyn_cast<Instruction>(V);
492 !Inst->mayReadFromMemory() &&
"Should've checked with isAvailableAt!");
494 for (
Value *
Op : Inst->operands())
495 makeAvailableAt(
Op, Loc);
497 Inst->moveBefore(Loc);
500 bool GuardWideningImpl::widenCondCommon(
Value *Cond0,
Value *Cond1,
502 bool InvertCondition) {
526 if (Intersect->getEquivalentICmp(Pred, NewRHSAP)) {
541 if (!InvertCondition &&
542 parseRangeChecks(Cond0, Checks) && parseRangeChecks(Cond1, Checks) &&
543 combineRangeChecks(Checks, CombinedChecks)) {
546 for (
auto &RC : CombinedChecks) {
547 makeAvailableAt(RC.getCheckInst(), InsertPt);
549 Result = BinaryOperator::CreateAnd(RC.getCheckInst(), Result,
"",
552 Result = RC.getCheckInst();
554 assert(Result &&
"Failed to find result value");
555 Result->setName(
"wide.chk");
564 makeAvailableAt(Cond0, InsertPt);
565 makeAvailableAt(Cond1, InsertPt);
568 Result = BinaryOperator::CreateAnd(Cond0, Cond1,
"wide.chk", InsertPt);
575 bool GuardWideningImpl::parseRangeChecks(
578 if (!Visited.
insert(CheckCond).second)
584 Value *AndLHS, *AndRHS;
586 return parseRangeChecks(AndLHS, Checks) &&
587 parseRangeChecks(AndRHS, Checks);
590 auto *IC = dyn_cast<ICmpInst>(CheckCond);
591 if (!IC || !IC->getOperand(0)->getType()->isIntegerTy() ||
596 const Value *CmpLHS = IC->getOperand(0), *CmpRHS = IC->getOperand(1);
600 auto &
DL = IC->getModule()->getDataLayout();
602 GuardWideningImpl::RangeCheck
Check(
621 auto *BaseInst = dyn_cast<Instruction>(
Check.getBase());
623 "Unreachable instruction?");
627 Check.setBase(OpLHS);
635 Check.setBase(OpLHS);
643 Checks.push_back(
Check);
647 bool GuardWideningImpl::combineRangeChecks(
650 unsigned OldCount = Checks.size();
651 while (!Checks.empty()) {
654 const Value *CurrentBase = Checks.front().getBase();
655 const Value *CurrentLength = Checks.front().getLength();
659 auto IsCurrentCheck = [&](GuardWideningImpl::RangeCheck &RC) {
660 return RC.getBase() == CurrentBase && RC.getLength() == CurrentLength;
663 copy_if(Checks, std::back_inserter(CurrentChecks), IsCurrentCheck);
666 assert(CurrentChecks.size() != 0 &&
"We know we have at least one!");
668 if (CurrentChecks.size() < 3) {
676 llvm::sort(CurrentChecks, [&](
const GuardWideningImpl::RangeCheck &
LHS,
677 const GuardWideningImpl::RangeCheck &
RHS) {
678 return LHS.getOffsetValue().slt(
RHS.getOffsetValue());
683 const ConstantInt *MinOffset = CurrentChecks.front().getOffset();
684 const ConstantInt *MaxOffset = CurrentChecks.back().getOffset();
687 if ((MaxOffset->
getValue() - MinOffset->getValue())
691 APInt MaxDiff = MaxOffset->
getValue() - MinOffset->getValue();
693 auto OffsetOK = [&](
const GuardWideningImpl::RangeCheck &RC) {
694 return (HighOffset - RC.getOffsetValue()).ult(MaxDiff);
739 assert(RangeChecksOut.size() <= OldCount &&
"We pessimized!");
740 return RangeChecksOut.size() != OldCount;
744 StringRef GuardWideningImpl::scoreTypeToString(WideningScore WS) {
746 case WS_IllegalOrNegative:
747 return "IllegalOrNegative";
752 case WS_VeryPositive:
753 return "VeryPositive";
766 std::unique_ptr<MemorySSAUpdater> MSSAU;
768 MSSAU = std::make_unique<MemorySSAUpdater>(&MSSAA->getMSSA());
769 if (!GuardWideningImpl(DT, &PDT, LI, MSSAU ? MSSAU.get() :
nullptr,
789 std::unique_ptr<MemorySSAUpdater> MSSAU;
791 MSSAU = std::make_unique<MemorySSAUpdater>(AR.
MSSA);
792 if (!GuardWideningImpl(AR.
DT,
nullptr, AR.
LI, MSSAU ? MSSAU.get() :
nullptr,
793 AR.
DT.
getNode(RootBB), BlockFilter).run())
813 auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
814 auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
815 auto &PDT = getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree();
816 auto *MSSAWP = getAnalysisIfAvailable<MemorySSAWrapperPass>();
817 std::unique_ptr<MemorySSAUpdater> MSSAU;
819 MSSAU = std::make_unique<MemorySSAUpdater>(&MSSAWP->getMSSA());
820 return GuardWideningImpl(DT, &PDT, LI, MSSAU ? MSSAU.get() :
nullptr,
837 struct LoopGuardWideningLegacyPass :
public LoopPass {
840 LoopGuardWideningLegacyPass() :
LoopPass(
ID) {
847 auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
848 auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
849 auto *PDTWP = getAnalysisIfAvailable<PostDominatorTreeWrapperPass>();
850 auto *PDT = PDTWP ? &PDTWP->getPostDomTree() :
nullptr;
851 auto *MSSAWP = getAnalysisIfAvailable<MemorySSAWrapperPass>();
852 std::unique_ptr<MemorySSAUpdater> MSSAU;
854 MSSAU = std::make_unique<MemorySSAUpdater>(&MSSAWP->getMSSA());
862 return GuardWideningImpl(DT, PDT, LI, MSSAU ? MSSAU.get() :
nullptr,
863 DT.
getNode(RootBB), BlockFilter).run();
897 return new GuardWideningLegacyPass();
901 return new LoopGuardWideningLegacyPass();
A set of analyses that are preserved following a run of a transformation pass.
compiles conv shl5 shl ret i32 or10 it would be better as
unsigned getPathLength() const
getPathLength - Return the length of the path from the entry node to the current node,...
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
This is an optimization pass for GlobalISel generic memory operations.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
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.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
bool isSafeToSpeculativelyExecute(const Value *V, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr)
Return true if the instruction does not have any effects besides calculating the result and does not ...
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represents a single loop in the control flow graph.
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
static BinaryOperator * CreateNot(Value *Op, const Twine &Name="", Instruction *InsertBefore=nullptr)
const APInt & getValue() const
Return the constant as an APInt value reference.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
BlockT * getLoopPredecessor() const
If the given loop's header has exactly one unique predecessor outside the loop, return it.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
df_iterator< T > df_end(const T &G)
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
void getLoopAnalysisUsage(AnalysisUsage &AU)
Helper to consistently add the set of standard passes to a loop pass's AnalysisUsage.
Optional< ConstantRange > exactIntersectWith(const ConstantRange &CR) const
Intersect the two ranges and return the result if it can be represented exactly, otherwise return Non...
unsigned getBitWidth() const
Return the number of bits in the APInt.
const_iterator end(StringRef path)
Get end iterator over path.
The legacy pass manager's analysis pass to compute loop information.
FunctionPass * createGuardWideningPass()
The adaptor from a function pass to a loop pass computes these analyses and makes them available to t...
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
std::pair< iterator, bool > insert(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
static Error getOffset(const SymbolRef &Sym, SectionRef Sec, uint64_t &Result)
bool isMinValue() const
Determine if this is the smallest unsigned value.
Analysis the ScalarEvolution expression for r is< loop > Outside the loop
LLVM Basic Block Representation.
=0.0 ? 0.0 :(a > 0.0 ? 1.0 :-1.0) a
static SDValue Widen(SelectionDAG *CurDAG, SDValue N)
Pass * createLoopGuardWideningPass()
bool isGuard(const User *U)
Returns true iff U has semantics of a guard expressed in a form of call of llvm.experimental....
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
This is the shared class of boolean and integer constants.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
void setWidenableBranchCond(BranchInst *WidenableBR, Value *Cond)
Given a branch we know is widenable (defined per Analysis/GuardUtils.h), set it's condition such that...
Legacy analysis pass which computes MemorySSA.
DomTreeNodeBase< NodeT > * getRootNode()
getRootNode - This returns the entry node for the CFG of the function.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
bool match(Val *V, const Pattern &P)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Represent the analysis usage information of a pass.
modulo schedule Modulo Schedule test pass
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
Legacy analysis pass which computes a DominatorTree.
static bool isSupportedGuardInstruction(const Instruction *Insn)
STATISTIC(NumFunctions, "Total number of functions")
void initializeLoopGuardWideningLegacyPassPass(PassRegistry &)
This class implements an extremely fast bulk output stream that can only output to a stream.
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.
static cl::opt< bool > WidenBranchGuards("guard-widening-widen-branch-guards", cl::Hidden, cl::desc("Whether or not we should widen guards " "expressed as branches by widenable conditions"), cl::init(true))
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
void initializeGuardWideningLegacyPassPass(PassRegistry &)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
Implements a dense probed hash-table based set.
PreservedAnalyses getLoopPassPreservedAnalyses()
Returns the minimum set of Analyses that all loop passes must preserve.
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
This instruction compares its operands according to the predicate given to the constructor.
This class provides an interface for updating the loop pass manager based on mutations to the loop ne...
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
void preserve()
Mark an analysis as preserved.
BinaryOp_match< LHS, RHS, Instruction::Or > m_Or(const LHS &L, const RHS &R)
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
initializer< Ty > init(const Ty &Val)
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
df_iterator< T > df_begin(const T &G)
iterator find(const_arg_type_t< KeyT > Val)
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...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
print Print MemDeps of function
An analysis that produces MemorySSA for a function.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
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.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
Class for arbitrary precision integers.
bool parseWidenableBranch(const User *U, Value *&Condition, Value *&WidenableCondition, BasicBlock *&IfTrueBB, BasicBlock *&IfFalseBB)
If U is widenable branch looking like: cond = ...
SmallVector< MachineOperand, 4 > Cond
void setPreservesCFG()
This function should be called by the pass, iff they do not:
StringRef - Represent a constant reference to a string, i.e.
@ ICMP_ULT
unsigned less than
PostDominatorTree Class - Concrete subclass of DominatorTree that is used to compute the post-dominat...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Represents analyses that only rely on functions' control flow.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
void append_range(Container &C, Range &&R)
Wrapper function to append a range to a container.
LLVMContext & getContext() const
All values hold a context through their type.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static ConstantInt * getFalse(LLVMContext &Context)
static bool runOnFunction(Function &F, bool PostInlining)
SmallVector< AArch64_IMM::ImmInsnModel, 4 > Insn
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
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.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
bool isGuardAsWidenableBranch(const User *U)
Returns true iff U has semantics of a guard expressed in a form of a widenable conditional branch to ...
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
constexpr unsigned BitWidth
BlockT * getHeader() const
void sort(IteratorTy Start, IteratorTy End)
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
This class represents a range of values.
NodeRef getPath(unsigned n) const
getPath - Return the n'th node in the path from the entry node to the current node.
A wrapper class for inspecting calls to intrinsic functions.
Analysis pass which computes a DominatorTree.
Pass interface - Implemented by all 'passes'.
void preserveSet()
Mark an analysis set as preserved.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
CmpClass_match< LHS, RHS, ICmpInst, ICmpInst::Predicate > m_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R)
@ ICMP_UGT
unsigned greater than
const BasicBlock * getParent() const
static Constant * getTrue(Type *Ty)
For a boolean type or a vector of boolean type, return true or a vector with every element true.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
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...
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
A container for analyses that lazily runs them and caches their results.
FunctionPass class - This class is used to implement most global optimizations.
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
Analysis pass which computes a PostDominatorTree.
AnalysisUsage & addRequired()
INITIALIZE_PASS_BEGIN(GuardWideningLegacyPass, "guard-widening", "Widen guards", false, false) INITIALIZE_PASS_END(GuardWideningLegacyPass
bool dominates(const Instruction *I1, const Instruction *I2) const
Return true if I1 dominates I2.
LLVM Value Representation.
Analysis pass that exposes the LoopInfo for a function.
void removeMemoryAccess(MemoryAccess *, bool OptimizePhis=false)
Remove a MemoryAccess from MemorySSA, including updating all definitions and uses.
reference emplace_back(ArgTypes &&... Args)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.