50 #define DEBUG_TYPE "lcssa"
52 STATISTIC(NumLCSSA,
"Number of live out of a loop variables");
54 #ifdef EXPENSIVE_CHECKS
61 cl::desc(
"Verify loop lcssa form (time consuming)"));
84 while (!Worklist.
empty()) {
85 UsesToRewrite.
clear();
90 if (!LoopExitBlocks.
count(L))
95 if (ExitBlocks.empty())
108 if (
PHINode *PN = dyn_cast<PHINode>(User))
109 UserBB = PN->getIncomingBlock(U);
111 if (InstBB != UserBB && !L->contains(UserBB))
116 if (UsesToRewrite.
empty())
126 if (
InvokeInst *Inv = dyn_cast<InvokeInst>(I))
127 DomBB = Inv->getNormalDest();
158 if (!L->contains(Pred))
178 if (!L->contains(OtherLoop))
184 for (
Use *UseToRewrite : UsesToRewrite) {
191 if (
PHINode *PN = dyn_cast<PHINode>(User))
192 UserBB = PN->getIncomingBlock(*UseToRewrite);
194 if (isa<PHINode>(UserBB->begin()) &&
isExitBlock(UserBB, ExitBlocks)) {
196 if (UseToRewrite->get()->hasValueHandle())
198 UseToRewrite->set(&UserBB->front());
208 for (
PHINode *InsertedPN : InsertedPHIs) {
209 if (
auto *OtherLoop = LI.
getLoopFor(InsertedPN->getParent()))
210 if (!L->contains(OtherLoop))
216 for (
auto *PostProcessPN : PostProcessPHIs) {
217 if (PostProcessPN->use_empty())
233 for (
PHINode *PN : PHIsToRemove) {
234 assert (PN->use_empty() &&
"Trying to remove a phi with uses.");
235 PN->eraseFromParent();
254 bool Changed =
false;
260 if (ExitBlocks.
empty())
278 (
I.hasOneUse() &&
I.user_back()->getParent() == BB &&
279 !isa<PHINode>(
I.user_back())))
301 bool Changed =
false;
314 bool Changed =
false;
332 bool runOnFunction(
Function &
F)
override;
333 void verifyAnalysis()
const override {
343 "LCSSA form is broken!");
382 bool LCSSAWrapperPass::runOnFunction(
Function &
F) {
383 LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
384 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
385 auto *SEWP = getAnalysisIfAvailable<ScalarEvolutionWrapperPass>();
386 SE = SEWP ? &SEWP->getSE() :
nullptr;
Legacy wrapper pass to provide the GlobalsAAResult object.
Pass interface - Implemented by all 'passes'.
void initializeLCSSAWrapperPassPass(PassRegistry &)
const Use & getOperandUse(unsigned i) const
void push_back(const T &Elt)
iterator_range< use_iterator > uses()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
Helper class for SSA formation on a set of values defined in multiple blocks.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
STATISTIC(NumFunctions,"Total number of functions")
This is the interface for a simple mod/ref and alias analysis over globals.
void Initialize(Type *Ty, StringRef Name)
Reset this object to get ready for a new set of SSA updates with type 'Ty'.
void AddAvailableValue(BasicBlock *BB, Value *V)
Indicate that a rewritten value is available in the specified block with the specified value...
The main scalar evolution driver.
bool isTokenTy() const
Return true if this is 'token'.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly...
Analysis pass which computes a DominatorTree.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
StringRef getName() const
Return a constant reference to the value's name.
bool formLCSSARecursively(Loop &L, DominatorTree &DT, LoopInfo *LI, ScalarEvolution *SE)
Put a loop nest into LCSSA form.
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
INITIALIZE_PASS_BEGIN(LCSSAWrapperPass,"lcssa","Loop-Closed SSA Form Pass", false, false) INITIALIZE_PASS_END(LCSSAWrapperPass
static unsigned getOperandNumForIncomingValue(unsigned i)
AnalysisUsage & addRequired()
ArrayRef< BasicBlock * > get(BasicBlock *BB)
#define INITIALIZE_PASS_DEPENDENCY(depName)
This is the interface for a SCEV-based alias analysis.
A Use represents the edge between a Value definition and its users.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
static cl::opt< bool, true > VerifyLoopLCSSAFlag("verify-loop-lcssa", cl::location(VerifyLoopLCSSA), cl::desc("Verify loop lcssa form (time consuming)"))
Analysis pass that exposes the LoopInfo for a function.
LLVM_NODISCARD bool empty() const
void getExitBlocks(SmallVectorImpl< BlockT * > &ExitBlocks) const
Return all of the successor blocks of this loop.
bool insert(const value_type &X)
Insert a new element into the SetVector.
PredIteratorCache - This class is an extremely trivial cache for predecessor iterator queries...
Base class for the actual dominator tree node.
AnalysisUsage & addPreservedID(const void *ID)
static void ValueIsRAUWd(Value *Old, Value *New)
LLVM_NODISCARD char front() const
front - Get the first character in the string.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
unsigned getNumIncomingValues() const
Return the number of incoming edges.
iterator_range< block_iterator > blocks() const
A set of analyses that are preserved following a run of a transformation pass.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs...ExtraArgs)
Get the result of an analysis pass for a given IR unit.
LLVM Basic Block Representation.
static bool VerifyLoopLCSSA
This file contains the declarations for the subclasses of Constant, which represent the different fla...
bool isRecursivelyLCSSAForm(DominatorTree &DT, const LoopInfo &LI) const
Return true if this Loop and all inner subloops are in LCSSA form.
Represent the analysis usage information of a pass.
bool any_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly...
Analysis pass providing a never-invalidated alias analysis result.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
FunctionPass class - This class is used to implement most global optimizations.
Analysis pass providing a never-invalidated alias analysis result.
bool HasValueForBlock(BasicBlock *BB) const
Return true if the SSAUpdater already has a value for the specified block.
static bool blockDominatesAnExit(BasicBlock *BB, DominatorTree &DT, const SmallVectorImpl< BasicBlock * > &ExitBlocks)
Return true if the specified block dominates at least one of the blocks in the specified list...
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
bool dominates(const Instruction *Def, const Use &U) const
Return true if Def dominates a use in User.
static bool formLCSSAOnAllLoops(LoopInfo *LI, DominatorTree &DT, ScalarEvolution *SE)
Process all loops in the function, inner-most out.
bool formLCSSA(Loop &L, DominatorTree &DT, LoopInfo *LI, ScalarEvolution *SE)
Put loop into LCSSA form.
A SetVector that performs no allocations if smaller than a certain size.
Legacy wrapper pass to provide the SCEVAAResult object.
bool formLCSSAForInstructions(SmallVectorImpl< Instruction * > &Worklist, DominatorTree &DT, LoopInfo &LI)
Ensures LCSSA form for every instruction from the Worklist in the scope of innermost containing loop...
bool isLCSSAForm(DominatorTree &DT) const
Return true if the Loop is in LCSSA form.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Type * getType() const
All values are typed, get the type of this value.
LLVM_NODISCARD T pop_back_val()
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
void setPreservesCFG()
This function should be called by the pass, iff they do not:
size_type count(const KeyT &Val) const
Return 1 if the specified key is in the map, 0 otherwise.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Loop Closed SSA Form false
Analysis pass that exposes the ScalarEvolution for a function.
Analysis pass providing a never-invalidated alias analysis result.
void forgetLoop(const Loop *L)
This method should be called by the client when it has changed a loop in a way that may effect Scalar...
Represents a single loop in the control flow graph.
void preserve()
Mark an analysis as preserved.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const std::vector< LoopT * > & getSubLoops() const
Return the loops contained entirely within this loop.
The legacy pass manager's analysis pass to compute loop information.
static bool isExitBlock(BasicBlock *BB, const SmallVectorImpl< BasicBlock * > &ExitBlocks)
Return true if the specified block is in the list.
This is the interface for LLVM's primary stateless and local alias analysis.
A container for analyses that lazily runs them and caches their results.
Legacy analysis pass which computes a DominatorTree.
DomTreeNodeBase< NodeT > * getNode(NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object...
void RewriteUse(Use &U)
Rewrite a use of the symbolic value.
size_t size(BasicBlock *BB)
LocationClass< Ty > location(Ty &L)
const BasicBlock * getParent() const
Legacy wrapper pass to provide the BasicAAResult object.
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.