30 #define DEBUG_TYPE "sink"
32 STATISTIC(NumSunk,
"Number of instructions sunk");
33 STATISTIC(NumSinkIter,
"Number of sinking iterations");
45 Instruction *UseInst = cast<Instruction>(U.getUser());
47 if (
PHINode *PN = dyn_cast<PHINode>(UseInst)) {
51 UseBlock = PN->getIncomingBlock(Num);
68 if (
LoadInst *
L = dyn_cast<LoadInst>(Inst)) {
75 if (isa<TerminatorInst>(Inst) || isa<PHINode>(Inst) || Inst->
isEHPad() ||
97 assert(Inst &&
"Instruction to be sunk is null");
98 assert(SuccToSinkTo &&
"Candidate sink target is null");
128 if (succ !=
nullptr && succ != cur)
145 if (
AllocaInst *AI = dyn_cast<AllocaInst>(Inst))
146 if (AI->isStaticAlloca())
170 I !=
E && SuccToSinkTo ==
nullptr; ++
I) {
172 if ((*I)->getIDom()->getBlock() == Inst->
getParent() &&
174 SuccToSinkTo = Candidate;
192 SuccToSinkTo->printAsOperand(
dbgs(),
false);
196 Inst->
moveBefore(&*SuccToSinkTo->getFirstInsertionPt());
210 bool MadeChange =
false;
215 bool ProcessedBegin =
false;
222 ProcessedBegin = I == BB.
begin();
226 if (isa<DbgInfoIntrinsic>(Inst))
235 }
while (!ProcessedBegin);
242 bool MadeChange, EverMadeChange =
false;
246 DEBUG(
dbgs() <<
"Sinking iteration " << NumSinkIter <<
"\n");
250 EverMadeChange |= MadeChange;
252 }
while (MadeChange);
254 return EverMadeChange;
279 bool runOnFunction(
Function &
F)
override {
280 auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
281 auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
282 auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
iterator_range< use_iterator > uses()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
BasicBlock * getUniquePredecessor()
Return the predecessor of this block if it has a unique predecessor block.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
static bool AllUsesDominatedByBlock(Instruction *Inst, BasicBlock *BB, DominatorTree &DT)
AllUsesDominatedByBlock - Return true if all uses of the specified value occur in blocks dominated by...
STATISTIC(NumFunctions,"Total number of functions")
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
machine Machine code sinking
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Analysis pass which computes a DominatorTree.
An instruction for reading from memory.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
The access modifies the value stored in memory.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
iterator begin()
Instruction iterator methods.
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
A Use represents the edge between a Value definition and its users.
FunctionPass * createSinkingPass()
Analysis pass that exposes the LoopInfo for a function.
Interval::succ_iterator succ_begin(Interval *I)
succ_begin/succ_end - define methods so that Intervals may be used just like BasicBlocks can with the...
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.
bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
static bool isSafeToMove(Instruction *Inst, AliasAnalysis &AA, SmallPtrSetImpl< Instruction * > &Stores)
Function Alias Analysis false
Base class for the actual dominator tree node.
static bool ProcessBlock(BasicBlock &BB, DominatorTree &DT, LoopInfo &LI, AAResults &AA)
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
Interval::succ_iterator succ_end(Interval *I)
unsigned getNumSuccessors() const
Return the number of successors that this terminator has.
static MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
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.
A manager for alias analyses.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Represent the analysis usage information of a pass.
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.
void initializeSinkingLegacyPassPass(PassRegistry &)
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
static unsigned getIncomingValueNumForOperand(unsigned i)
bool mayWriteToMemory() const
Return true if this instruction may modify memory.
bool dominates(const Instruction *Def, const Use &U) const
Return true if Def dominates a use in User.
Representation for a specific memory location.
Iterator for intrusive lists based on ilist_node.
static bool SinkInstruction(Instruction *Inst, SmallPtrSetImpl< Instruction * > &Stores, DominatorTree &DT, LoopInfo &LI, AAResults &AA)
SinkInstruction - Determine whether it is safe to sink the specified machine instruction out of its c...
Module.h This file contains the declarations for the Module class.
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
void setPreservesCFG()
This function should be called by the pass, iff they do not:
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
ModRefInfo getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc)
getModRefInfo (for call sites) - Return information about whether a particular call site modifies or ...
bool mayThrow() const
Return true if this instruction may throw an exception.
bool isEHPad() const
Return true if the instruction is a variety of EH-block.
static bool IsAcceptableTarget(Instruction *Inst, BasicBlock *SuccToSinkTo, DominatorTree &DT, LoopInfo &LI)
IsAcceptableTarget - Return true if it is possible to sink the instruction in the specified basic blo...
Represents a single loop in the control flow graph.
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
static bool iterativelySinkInstructions(Function &F, DominatorTree &DT, LoopInfo &LI, AAResults &AA)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
std::vector< DomTreeNodeBase< NodeT > * >::iterator iterator
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 ...
void moveBefore(Instruction *MovePos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
bool isExceptional() const
The legacy pass manager's analysis pass to compute loop information.
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...
machine sink
When an instruction is found to only be used outside of the loop, this function moves it to the exit ...
const BasicBlock * getParent() const
an instruction to allocate memory on the stack