29 #define DEBUG_TYPE "sink"
31 STATISTIC(NumSunk,
"Number of instructions sunk");
32 STATISTIC(NumSinkIter,
"Number of sinking iterations");
76 bool Sinking::AllUsesDominatedByBlock(
Instruction *Inst,
84 Instruction *UseInst = cast<Instruction>(U.getUser());
86 if (
PHINode *PN = dyn_cast<PHINode>(UseInst)) {
90 UseBlock = PN->getIncomingBlock(Num);
93 if (!DT->dominates(BB, UseBlock))
99 bool Sinking::runOnFunction(
Function &
F) {
100 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
101 LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
102 AA = &getAnalysis<AliasAnalysis>();
104 bool MadeChange, EverMadeChange =
false;
108 DEBUG(
dbgs() <<
"Sinking iteration " << NumSinkIter <<
"\n");
112 MadeChange |= ProcessBlock(*
I);
113 EverMadeChange |= MadeChange;
115 }
while (MadeChange);
117 return EverMadeChange;
127 if (!DT->isReachableFromEntry(&BB))
return false;
129 bool MadeChange =
false;
134 bool ProcessedBegin =
false;
141 ProcessedBegin = I == BB.
begin();
145 if (isa<DbgInfoIntrinsic>(Inst))
148 if (SinkInstruction(Inst, Stores))
149 ++NumSunk, MadeChange =
true;
152 }
while (!ProcessedBegin);
165 if (
LoadInst *L = dyn_cast<LoadInst>(Inst)) {
172 if (isa<TerminatorInst>(Inst) || isa<PHINode>(Inst))
186 bool Sinking::IsAcceptableTarget(
Instruction *Inst,
188 assert(Inst &&
"Instruction to be sunk is null");
189 assert(SuccToSinkTo &&
"Candidate sink target is null");
208 if (!DT->dominates(Inst->
getParent(), SuccToSinkTo))
212 Loop *succ = LI->getLoopFor(SuccToSinkTo);
214 if (succ !=
nullptr && succ != cur)
220 return AllUsesDominatedByBlock(Inst, SuccToSinkTo);
230 if (
AllocaInst *AI = dyn_cast<AllocaInst>(Inst))
231 if (AI->isStaticAlloca())
255 I != E && SuccToSinkTo ==
nullptr; ++
I) {
257 if ((*I)->getIDom()->getBlock() == Inst->
getParent() &&
258 IsAcceptableTarget(Inst, Candidate))
259 SuccToSinkTo = Candidate;
266 if (IsAcceptableTarget(Inst, *I))
277 SuccToSinkTo->printAsOperand(
dbgs(),
false);
281 Inst->
moveBefore(SuccToSinkTo->getFirstInsertionPt());
static bool isSafeToMove(Instruction *Inst, AliasAnalysis *AA, SmallPtrSetImpl< Instruction * > &Stores)
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...
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
LoadInst - an instruction for reading from 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)
std::vector< DomTreeNodeBase< NodeT > * >::iterator iterator
A Use represents the edge between a Value definition and its users.
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
FunctionPass * createSinkingPass()
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.
Base class for the actual dominator tree node.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
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.
LLVM Basic Block Representation.
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.
FunctionPass class - This class is used to implement most global optimizations.
#define INITIALIZE_AG_DEPENDENCY(depName)
static unsigned getIncomingValueNumForOperand(unsigned i)
bool mayWriteToMemory() const
mayWriteToMemory - Return true if this instruction may modify memory.
Representation for a specific memory location.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
Module.h This file contains the declarations for the Module class.
ModRefResult getModRefInfo(const Instruction *I)
getModRefInfo - Return information about whether or not an instruction may read or write memory (with...
#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.
void initializeSinkingPass(PassRegistry &)
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
void moveBefore(Instruction *MovePos)
moveBefore - Unlink this instruction from its current basic block and insert it into the basic block ...
The legacy pass manager's analysis pass to compute loop information.
bool isSafeToSpeculativelyExecute(const Value *V, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr)
isSafeToSpeculativelyExecute - Return true if the instruction does not have any effects besides calcu...
Legacy analysis pass which computes a DominatorTree.
Can only be moved to control-equivalent blocks.
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
AllocaInst - an instruction to allocate memory on the stack.