27#define DEBUG_TYPE "must-execute"
40 ColorVector &ColorsForNewBlock = (*BlockColors)[New];
41 ColorVector &ColorsForOldBlock = (*BlockColors)[Old];
42 ColorsForNewBlock = ColorsForOldBlock;
54void SimpleLoopSafetyInfo::computeLoopSafetyInfo() {
59 MayThrow = HeaderMayThrow;
64 "First block must be header");
73 return ICF.hasICF(BB);
80void ICFLoopSafetyInfo::computeLoopSafetyInfo() {
95 ICF.insertInstructionTo(Inst, BB);
96 MW.insertInstructionTo(Inst, BB);
100 ICF.removeInstruction(Inst);
101 MW.removeInstruction(Inst);
104void LoopSafetyInfo::computeBlockColors()
const {
107 BlockColors.emplace();
123 const Loop *CurLoop) {
128 assert(CurLoop->
contains(CondExitBlock) &&
"meaning of exit block");
135 return BI->getSuccessor(
Cond->getZExtValue() ? 1 : 0) == ExitBlock;
144 auto *
RHS =
Cond->getOperand(1);
146 Pred =
Cond->getSwappedPredicate();
161 auto *IVStart =
LHS->getIncomingValueForBlock(Predecessor);
163 Pred, IVStart,
RHS, {
DL,
nullptr, DT,
nullptr, BI});
167 if (ExitBlock == BI->getSuccessor(0))
168 return SimpleCst->isNullValue();
169 assert(ExitBlock == BI->getSuccessor(1) &&
"implied by above");
170 return SimpleCst->isAllOnesValue();
182 assert(Predecessors.
empty() &&
"Garbage in predecessors set?");
183 assert(CurLoop->
contains(BB) &&
"Should only be called for loop blocks!");
190 Predecessors.
insert(Pred);
193 while (!WorkList.
empty()) {
195 assert(CurLoop->
contains(Pred) &&
"Should only reach loop blocks!");
206 if (CurLoop->
contains(PredPred) && Predecessors.
insert(PredPred).second)
213 assert(
CurLoop->contains(BB) &&
"Should only be called for loop blocks!");
216 if (BB ==
CurLoop->getHeader())
219 auto [It, Inserted] = GuaranteedToExecute.try_emplace(BB,
false);
221 It->second = allLoopPathsLeadToBlockImpl(BB, DT);
225bool LoopSafetyInfo::allLoopPathsLeadToBlockImpl(
248 for (
const auto *Pred : Predecessors) {
259 if (CheckedSuccessors.
insert(Succ).second &&
260 Succ != BB && !Predecessors.count(Succ))
296 return !HeaderMayThrow ||
297 &*Inst.
getParent()->getFirstNonPHIOrDbg() == &Inst;
306 return !ICF.isDominatedByICFIFromSameBlock(&Inst) &&
311 assert(
CurLoop->contains(BB) &&
"Should only be called for loop blocks!");
314 if (BB ==
CurLoop->getHeader())
323 for (
const auto *Pred : Predecessors)
324 if (MW.mayWriteToMemory(Pred))
330 auto *BB =
I.getParent();
331 assert(
CurLoop->contains(BB) &&
"Should only be called for loop blocks!");
332 return !MW.isDominatedByMemoryWriteFromSameBlock(&
I) &&
349 DenseMap<const Value*, SmallVector<Loop*, 4> > MustExec;
352 MustExecuteAnnotatedWriter(
const Function &
F,
353 DominatorTree &DT, LoopInfo &LI) {
358 MustExec[&
I].push_back(L);
360 L =
L->getParentLoop();
364 MustExecuteAnnotatedWriter(
const Module &M,
365 DominatorTree &DT, LoopInfo &LI) {
366 for (
const auto &
F : M)
371 MustExec[&
I].push_back(L);
373 L =
L->getParentLoop();
379 void printInfoComment(
const Value &V, formatted_raw_ostream &OS)
override {
380 if (!MustExec.
count(&V))
384 const auto NumLoops =
Loops.size();
386 OS <<
" ; (mustexec in " << NumLoops <<
" loops: ";
388 OS <<
" ; (mustexec in: ";
392 OS <<
LS <<
L->getHeader()->getName();
400 if (L.getHeader()->getParent()->hasFnAttribute(Attribute::WillReturn))
411 RPOTraversal FuncRPOT(&
F);
418template <
typename K,
typename V,
typename FnTy,
typename... ArgsTy>
420 FnTy &&Fn, ArgsTy &&...
args) {
421 std::optional<V> &OptVal = Map[
Key];
423 OptVal = Fn(std::forward<ArgsTy>(
args)...);
433 << (LI ?
" [LI]" :
"") << (PDT ?
" [PDT]" :
""));
437 const BasicBlock *HeaderBB = L ? L->getHeader() : InitBB;
438 bool WillReturnAndNoThrow = (
F.hasFnAttribute(Attribute::WillReturn) ||
442 << (WillReturnAndNoThrow ?
" [WillReturn] [NoUnwind]" :
"")
449 bool IsLatch = SuccBB == HeaderBB;
452 if (!WillReturnAndNoThrow || !IsLatch)
458 if (Worklist.
empty())
462 if (Worklist.
size() == 1)
470 if (
const auto *InitNode = PDT->
getNode(InitBB))
471 if (
const auto *IDomNode = InitNode->getIDom())
472 JoinBB = IDomNode->getBlock();
474 if (!JoinBB && Worklist.
size() == 2) {
479 if (Succ0UniqueSucc == InitBB) {
483 }
else if (Succ1UniqueSucc == InitBB) {
487 }
else if (Succ0 == Succ1UniqueSucc) {
491 }
else if (Succ1 == Succ0UniqueSucc) {
495 }
else if (Succ0UniqueSucc == Succ1UniqueSucc) {
498 JoinBB = Succ0UniqueSucc;
503 JoinBB = L->getUniqueExitBlock();
518 if (!
F.hasFnAttribute(Attribute::WillReturn) || !
F.doesNotThrow()) {
520 auto BlockTransfersExecutionToSuccessor = [](
const BasicBlock *BB) {
525 while (!Worklist.
empty()) {
531 if (!Visited.
insert(ToBB).second) {
532 if (!
F.hasFnAttribute(Attribute::WillReturn)) {
538 if (MayContainIrreducibleControl)
552 ToBB, BlockTransferMap, BlockTransfersExecutionToSuccessor, ToBB);
553 if (!TransfersExecution)
568 << (LI ?
" [LI]" :
"") << (DT ?
" [DT]" :
""));
574 if (
const auto *InitNode = DT->
getNode(InitBB))
575 if (
const auto *IDomNode = InitNode->getIDom())
576 return IDomNode->getBlock();
579 const BasicBlock *HeaderBB = L ? L->getHeader() :
nullptr;
585 (PredBB == InitBB) || (HeaderBB == InitBB && L->contains(PredBB));
593 if (Worklist.
empty())
597 if (Worklist.
size() == 1)
601 if (Worklist.
size() == 2) {
606 if (Pred0 == Pred1UniquePred) {
610 }
else if (Pred1 == Pred0UniquePred) {
614 }
else if (Pred0UniquePred == Pred1UniquePred) {
617 JoinBB = Pred0UniquePred;
622 JoinBB = L->getHeader();
635 LLVM_DEBUG(
dbgs() <<
"Find next instruction for " << *PP <<
"\n");
639 LLVM_DEBUG(
dbgs() <<
"\tReached terminator in intra-block mode, done\n");
647 if (!TransfersExecution)
656 LLVM_DEBUG(
dbgs() <<
"\tIntermediate instruction does transfer control\n");
673 dbgs() <<
"\tUnconditional terminator, continue with successor\n");
681 return &JoinBB->front();
695 << (IsFirst ?
" [IsFirst]" :
"") <<
"\n");
700 LLVM_DEBUG(
dbgs() <<
"\tReached block front in intra-block mode, done\n");
712 dbgs() <<
"\tIntermediate instruction, continue with previous\n");
722 return &JoinBB->back();
730 : Explorer(Explorer), CurInst(
I) {
734void MustBeExecutedIterator::reset(
const Instruction *
I) {
739void MustBeExecutedIterator::resetInstruction(
const Instruction *
I) {
741 Head = Tail =
nullptr;
744 if (Explorer.ExploreCFGForward)
746 if (Explorer.ExploreCFGBackward)
750const Instruction *MustBeExecutedIterator::advance() {
751 assert(CurInst &&
"Cannot advance an end iterator!");
752 Head = Explorer.getMustBeExecutedNextInstruction(*
this, Head);
753 if (Head && Visited.insert({Head, ExplorationDirection ::FORWARD}).second)
757 Tail = Explorer.getMustBeExecutedPrevInstruction(*
this, Tail);
758 if (Tail && Visited.insert({Tail, ExplorationDirection ::BACKWARD}).second)
769 MustExecuteAnnotatedWriter Writer(
F, DT, LI);
770 F.print(OS, &Writer);
778 GetterTy<const LoopInfo> LIGetter = [&](
const Function &
F) {
781 GetterTy<const DominatorTree> DTGetter = [&](
const Function &
F) {
784 GetterTy<const PostDominatorTree> PDTGetter = [&](
const Function &
F) {
791 true, LIGetter, DTGetter, PDTGetter);
795 OS <<
"-- Explore context of: " <<
I <<
"\n";
797 OS <<
" [F: " << CI->getFunction()->getName() <<
"] " << *CI <<
"\n";
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Expand Atomic instructions
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
Machine Check Debug Module
static void collectTransitivePredecessors(const Loop *CurLoop, const BasicBlock *BB, SmallPtrSetImpl< const BasicBlock * > &Predecessors)
Collect all blocks from CurLoop which lie on all possible paths from the header of CurLoop (inclusive...
static bool maybeEndlessLoop(const Loop &L)
Return true if L might be an endless loop.
static V getOrCreateCachedOptional(K Key, DenseMap< K, std::optional< V > > &Map, FnTy &&Fn, ArgsTy &&...args)
Lookup Key in Map and return the result, potentially after initializing the optional through Fn(args)...
static bool isMustExecuteIn(const Instruction &I, Loop *L, DominatorTree *DT)
static bool CanProveNotTakenFirstIteration(const BasicBlock *ExitBlock, const DominatorTree *DT, const Loop *CurLoop)
Return true if we can prove that the given ExitBlock is not reached on the first iteration of the giv...
Contains a collection of routines for determining if a given instruction is guaranteed to execute if ...
FunctionAnalysisManager FAM
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
const SmallVectorImpl< MachineOperand > & Cond
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
LLVM Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
LLVM_ABI const BasicBlock * getUniqueSuccessor() const
Return the successor of this block if it has a unique successor.
LLVM_ABI const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
const Instruction & front() const
LLVM_ABI const BasicBlock * getUniquePredecessor() const
Return the predecessor of this block if it has a unique predecessor block.
LLVM_ABI const Module * getModule() const
Return the module owning the function this basic block belongs to, or nullptr if the function does no...
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
This is an important base class in LLVM.
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Analysis pass which computes a DominatorTree.
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
bool hasPersonalityFn() const
Check whether this function has a personality function.
Constant * getPersonalityFn() const
Get the personality function associated with this function.
bool doesNotWriteMemoryBefore(const BasicBlock *BB) const
Returns true if we could not execute a memory-modifying instruction before we enter BB under assumpti...
bool blockMayThrow(const BasicBlock *BB) const override
Returns true iff the block BB potentially may throw exception.
bool isGuaranteedToExecute(const Instruction &Inst, const DominatorTree *DT) const override
Returns true if the instruction in a loop is guaranteed to execute at least once (under the assumptio...
void removeInstruction(const Instruction *Inst)
Inform safety info that we are planning to remove the instruction Inst from its block.
bool anyBlockMayThrow() const override
Returns true iff any block of the loop for which this info is contains an instruction that may throw ...
void insertInstructionTo(const Instruction *Inst, const BasicBlock *BB)
Inform the safety info that we are planning to insert a new instruction Inst into the basic block BB.
bool hasICF(const BasicBlock *BB)
Returns true if at least one instruction from the given basic block has implicit control flow.
LLVM_ABI void clear()
Invalidates all information from this tracking.
LLVM_ABI unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
LLVM_ABI BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
bool isTerminator() const
Analysis pass that exposes the LoopInfo for a function.
bool contains(const LoopT *L) const
Return true if the specified loop is contained within this loop.
BlockT * getHeader() const
iterator_range< block_iterator > blocks() const
BlockT * getLoopPredecessor() const
If the given loop's header has exactly one unique predecessor outside the loop, return it.
ArrayRef< BlockT * > getBlocks() const
Get a list of the basic blocks which make up this loop.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
LLVM_ABI void copyColors(BasicBlock *New, BasicBlock *Old)
Copy colors of block Old into the block New.
LLVM_ABI const DenseMap< BasicBlock *, ColorVector > & getBlockColors() const
Returns block colors map that is used to update funclet operand bundles.
LLVM_ABI bool allLoopPathsLeadToBlock(const BasicBlock *BB, const DominatorTree *DT) const
Return true if we must reach the block BB under assumption that the loop is entered.
virtual bool blockMayThrow(const BasicBlock *BB) const =0
Returns true iff the block BB potentially may throw exception.
Represents a single loop in the control flow graph.
A Module instance is used to store all the information related to an LLVM module.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Analysis pass which computes a PostDominatorTree.
PostDominatorTree Class - Concrete subclass of DominatorTree that is used to compute the post-dominat...
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.
Simple and conservative implementation of LoopSafetyInfo that can give false-positive answers to its ...
bool isGuaranteedToExecute(const Instruction &Inst, const DominatorTree *DT) const override
Returns true if the instruction in a loop is guaranteed to execute at least once.
bool anyBlockMayThrow() const override
Returns true iff any block of the loop for which this info is contains an instruction that may throw ...
bool blockMayThrow(const BasicBlock *BB) const override
Returns true iff the block BB potentially may throw exception.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
const ParentTy * getParent() const
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto successors(const MachineBasicBlock *BB)
LLVM_ABI bool isGuaranteedToExecuteForEveryIteration(const Instruction *I, const Loop *L)
Return true if this function can prove that the instruction I is executed for every iteration of the ...
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
LLVM_ABI DenseMap< BasicBlock *, ColorVector > colorEHFunclets(Function &F)
If an EH funclet personality is in use (see isFuncletEHPersonality), this will recompute which blocks...
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
bool isScopedEHPersonality(EHPersonality Pers)
Returns true if this personality uses scope-style EH IR instructions: catchswitch,...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
auto dyn_cast_or_null(const Y &Val)
bool containsIrreducibleCFG(RPOTraversalT &RPOTraversal, const LoopInfoT &LI)
Return true if the control flow in RPOTraversal is irreducible.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI bool isGuaranteedToTransferExecutionToSuccessor(const Instruction *I)
Return true if this function can prove that the instruction I will always transfer execution to one o...
TinyPtrVector< BasicBlock * > ColorVector
auto predecessors(const MachineBasicBlock *BB)
LLVM_ABI Value * simplifyCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a CmpInst, fold the result or return null.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI bool mayContainIrreducibleControl(const Function &F, const LoopInfo *LI)
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
A "must be executed context" for a given program point PP is the set of instructions,...
const bool ExploreInterBlock
Parameter that limit the performed exploration.
LLVM_ABI const BasicBlock * findBackwardJoinPoint(const BasicBlock *InitBB)
Find the next join point from InitBB in backward direction.
LLVM_ABI const Instruction * getMustBeExecutedNextInstruction(MustBeExecutedIterator &It, const Instruction *PP)
Return the next instruction that is guaranteed to be executed after PP.
llvm::iterator_range< iterator > range(const Instruction *PP)
}
LLVM_ABI const Instruction * getMustBeExecutedPrevInstruction(MustBeExecutedIterator &It, const Instruction *PP)
Return the previous instr.
LLVM_ABI const BasicBlock * findForwardJoinPoint(const BasicBlock *InitBB)
Find the next join point from InitBB in forward direction.
Must be executed iterators visit stretches of instructions that are guaranteed to be executed togethe...
MustBeExecutedIterator(const MustBeExecutedIterator &Other)=default