56 #define DEBUG_TYPE "loopsink" 58 STATISTIC(NumLoopSunk,
"Number of instructions sunk into loop");
59 STATISTIC(NumLoopSunkCloned,
"Number of cloned instructions sunk into loop");
63 cl::desc(
"Do not sink instructions that require cloning unless they " 64 "execute less than this percent of the time."));
68 cl::desc(
"Do not sink instructions that have too many uses."));
125 if (UseBBs.
size() == 0)
126 return BBsToSinkInto;
140 BBsDominatedByColdestBB.
clear();
143 BBsDominatedByColdestBB.
insert(SinkedBB);
144 if (BBsDominatedByColdestBB.
size() == 0)
148 for (
BasicBlock *DominatedBB : BBsDominatedByColdestBB) {
149 BBsToSinkInto.erase(DominatedBB);
151 BBsToSinkInto.insert(ColdestBB);
157 if (BB->getFirstInsertionPt() == BB->end()) {
158 BBsToSinkInto.clear();
167 BBsToSinkInto.clear();
168 return BBsToSinkInto;
182 for (
auto &U : I.
uses()) {
185 if (dyn_cast<PHINode>(UI))
202 if (BBsToSinkInto.
empty())
206 if (BBsToSinkInto.
size() > 1) {
207 for (
auto *BB : BBsToSinkInto)
208 if (!LoopBlockNumber.
count(BB))
216 SortedBBsToSinkInto.
insert(SortedBBsToSinkInto.
begin(), BBsToSinkInto.
begin(),
217 BBsToSinkInto.
end());
219 return LoopBlockNumber.
find(A)->second < LoopBlockNumber.
find(B)->second;
227 LoopBlockNumber.
find(MoveBB)->second &&
232 IC->insertBefore(&*
N->getFirstInsertionPt());
236 auto *I = cast<Instruction>(U.
getUser());
242 LLVM_DEBUG(
dbgs() <<
"Sinking a clone of " << I <<
" To: " <<
N->getName()
248 I.
moveBefore(&*MoveBB->getFirstInsertionPt());
277 bool Changed =
false;
283 CurAST.
add(*Preheader);
292 LoopBlockNumber[
B] = ++i;
294 std::stable_sort(ColdLoopBBs.
begin(), ColdLoopBBs.
end(),
302 for (
auto II = Preheader->
rbegin(),
E = Preheader->
rend(); II !=
E;) {
306 "Insts in a loop's preheader should have loop invariant operands!");
335 bool Changed =
false;
337 Loop &L = *PreorderLoops.pop_back_val();
344 }
while (!PreorderLoops.empty());
355 struct LegacyLoopSinkPass :
public LoopPass {
357 LegacyLoopSinkPass() :
LoopPass(ID) {
365 auto *SE = getAnalysisIfAvailable<ScalarEvolutionWrapperPass>();
367 *L, getAnalysis<AAResultsWrapperPass>().getAAResults(),
368 getAnalysis<LoopInfoWrapperPass>().getLoopInfo(),
369 getAnalysis<DominatorTreeWrapperPass>().getDomTree(),
370 getAnalysis<BlockFrequencyInfoWrapperPass>().getBFI(),
371 SE ? &SE->getSE() :
nullptr);
Pass interface - Implemented by all 'passes'.
iterator_range< use_iterator > uses()
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
gvn sink
When an instruction is found to only be used outside of the loop, this function moves it to the exit ...
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
This class represents lattice values for constants.
This header provides classes for managing a pipeline of passes over loops in LLVM IR...
void push_back(const T &Elt)
void add(Value *Ptr, LocationSize Size, const AAMDNodes &AAInfo)
These methods are used to add different types of instructions to the alias sets.
The main scalar evolution driver.
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly...
STATISTIC(NumFunctions, "Total number of functions")
Analysis pass which computes a DominatorTree.
reverse_iterator rbegin()
unsigned replaceDominatedUsesWith(Value *From, Value *To, DominatorTree &DT, const BasicBlockEdge &Edge)
Replace each use of 'From' with 'To' if that use is dominated by the given edge.
bool hasLoopInvariantOperands(const Instruction *I) const
Return true if all the operands of the specified instruction are loop invariant.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
This is the interface for a SCEV-based alias analysis.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
A Use represents the edge between a Value definition and its users.
Legacy analysis pass which computes BlockFrequencyInfo.
void setName(const Twine &Name)
Change the name of the value.
Analysis pass that exposes the LoopInfo for a function.
Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following: ...
User * getUser() const LLVM_READONLY
Returns the User that contains this Use.
INITIALIZE_PASS_BEGIN(LegacyLoopSinkPass, "loop-sink", "Loop Sink", false, false) Pass *llvm
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
void forgetLoopDispositions(const Loop *L)
Called when the client has changed the disposition of values in this loop.
use_iterator_impl< Use > use_iterator
iterator find(const_arg_type_t< KeyT > Val)
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
initializer< Ty > init(const Ty &Val)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
A set of analyses that are preserved following a run of a transformation pass.
LLVM Basic Block Representation.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
LLVM_NODISCARD bool empty() const
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
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.
bool canSinkOrHoistInst(Instruction &I, AAResults *AA, DominatorTree *DT, Loop *CurLoop, AliasSetTracker *CurAST, MemorySSAUpdater *MSSAU, bool TargetExecutesOncePerLoop, OptimizationRemarkEmitter *ORE=nullptr)
Returns true if is legal to hoist or sink this instruction disregarding the possible introduction of ...
static bool sinkLoopInvariantInstructions(Loop &L, AAResults &AA, LoopInfo &LI, DominatorTree &DT, BlockFrequencyInfo &BFI, ScalarEvolution *SE)
Sinks instructions from loop's preheader to the loop body if the sum frequency of inserted copy is sm...
Pass * createLoopSinkPass()
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
void sort(IteratorTy Start, IteratorTy End)
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
Analysis pass which computes BlockFrequencyInfo.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
bool dominates(const Instruction *Def, const Use &U) const
Return true if Def dominates a use in User.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
BlockFrequency getBlockFreq(const BasicBlock *BB) const
getblockFreq - Return block frequency.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static cl::opt< unsigned > SinkFrequencyPercentThreshold("sink-freq-percent-threshold", cl::Hidden, cl::init(90), cl::desc("Do not sink instructions that require cloning unless they " "execute less than this percent of the time."))
Represents analyses that only rely on functions' control flow.
iterator insert(iterator I, T &&Elt)
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
static BlockFrequency adjustedSumFreq(SmallPtrSetImpl< BasicBlock *> &BBs, BlockFrequencyInfo &BFI)
Return adjusted total frequency of BBs.
Represents a single loop in the control flow graph.
void preserveSet()
Mark an analysis set as preserved.
StringRef getName() const
Return a constant reference to the value's name.
const Function * getParent() const
Return the enclosing method, or null if none.
void getLoopAnalysisUsage(AnalysisUsage &AU)
Helper to consistently add the set of standard passes to a loop pass's AnalysisUsage.
static SmallPtrSet< BasicBlock *, 2 > findBBsToSinkInto(const Loop &L, const SmallPtrSetImpl< BasicBlock *> &UseBBs, const SmallVectorImpl< BasicBlock *> &ColdLoopBBs, DominatorTree &DT, BlockFrequencyInfo &BFI)
Return a set of basic blocks to insert sinked instructions.
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
SmallVector< LoopT *, 4 > getLoopsInPreorder()
Return all of the loops in the function in preorder across the loop nests, with siblings in forward p...
static cl::opt< unsigned > MaxNumberOfUseBBsForSinking("max-uses-for-sinking", cl::Hidden, cl::init(30), cl::desc("Do not sink instructions that have too many uses."))
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void initializeLegacyLoopSinkPassPass(PassRegistry &)
void moveBefore(Instruction *MovePos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
static bool sinkInstruction(Loop &L, Instruction &I, const SmallVectorImpl< BasicBlock *> &ColdLoopBBs, const SmallDenseMap< BasicBlock *, int, 16 > &LoopBlockNumber, LoopInfo &LI, DominatorTree &DT, BlockFrequencyInfo &BFI)
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.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
iterator_range< block_iterator > blocks() const
bool hasProfileData() const
Return true if the function is annotated with profile data.
const BasicBlock * getParent() const