LLVM 20.0.0git
LoopSink.cpp
Go to the documentation of this file.
1//===-- LoopSink.cpp - Loop Sink Pass -------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This pass does the inverse transformation of what LICM does.
10// It traverses all of the instructions in the loop's preheader and sinks
11// them to the loop body where frequency is lower than the loop's preheader.
12// This pass is a reverse-transformation of LICM. It differs from the Sink
13// pass in the following ways:
14//
15// * It only handles sinking of instructions from the loop's preheader to the
16// loop's body
17// * It uses alias set tracker to get more accurate alias info
18// * It uses block frequency info to find the optimal sinking locations
19//
20// Overall algorithm:
21//
22// For I in Preheader:
23// InsertBBs = BBs that uses I
24// For BB in sorted(LoopBBs):
25// DomBBs = BBs in InsertBBs that are dominated by BB
26// if freq(DomBBs) > freq(BB)
27// InsertBBs = UseBBs - DomBBs + BB
28// For BB in InsertBBs:
29// Insert I at BB's beginning
30//
31//===----------------------------------------------------------------------===//
32
35#include "llvm/ADT/Statistic.h"
42#include "llvm/IR/Dominators.h"
49using namespace llvm;
50
51#define DEBUG_TYPE "loopsink"
52
53STATISTIC(NumLoopSunk, "Number of instructions sunk into loop");
54STATISTIC(NumLoopSunkCloned, "Number of cloned instructions sunk into loop");
55
57 "sink-freq-percent-threshold", cl::Hidden, cl::init(90),
58 cl::desc("Do not sink instructions that require cloning unless they "
59 "execute less than this percent of the time."));
60
62 "max-uses-for-sinking", cl::Hidden, cl::init(30),
63 cl::desc("Do not sink instructions that have too many uses."));
64
65/// Return adjusted total frequency of \p BBs.
66///
67/// * If there is only one BB, sinking instruction will not introduce code
68/// size increase. Thus there is no need to adjust the frequency.
69/// * If there are more than one BB, sinking would lead to code size increase.
70/// In this case, we add some "tax" to the total frequency to make it harder
71/// to sink. E.g.
72/// Freq(Preheader) = 100
73/// Freq(BBs) = sum(50, 49) = 99
74/// Even if Freq(BBs) < Freq(Preheader), we will not sink from Preheade to
75/// BBs as the difference is too small to justify the code size increase.
76/// To model this, The adjusted Freq(BBs) will be:
77/// AdjustedFreq(BBs) = 99 / SinkFrequencyPercentThreshold%
79 BlockFrequencyInfo &BFI) {
81 for (BasicBlock *B : BBs)
82 T += BFI.getBlockFreq(B);
83 if (BBs.size() > 1)
85 return T;
86}
87
88/// Return a set of basic blocks to insert sinked instructions.
89///
90/// The returned set of basic blocks (BBsToSinkInto) should satisfy:
91///
92/// * Inside the loop \p L
93/// * For each UseBB in \p UseBBs, there is at least one BB in BBsToSinkInto
94/// that domintates the UseBB
95/// * Has minimum total frequency that is no greater than preheader frequency
96///
97/// The purpose of the function is to find the optimal sinking points to
98/// minimize execution cost, which is defined as "sum of frequency of
99/// BBsToSinkInto".
100/// As a result, the returned BBsToSinkInto needs to have minimum total
101/// frequency.
102/// Additionally, if the total frequency of BBsToSinkInto exceeds preheader
103/// frequency, the optimal solution is not sinking (return empty set).
104///
105/// \p ColdLoopBBs is used to help find the optimal sinking locations.
106/// It stores a list of BBs that is:
107///
108/// * Inside the loop \p L
109/// * Has a frequency no larger than the loop's preheader
110/// * Sorted by BB frequency
111///
112/// The complexity of the function is O(UseBBs.size() * ColdLoopBBs.size()).
113/// To avoid expensive computation, we cap the maximum UseBBs.size() in its
114/// caller.
117 const SmallVectorImpl<BasicBlock *> &ColdLoopBBs,
119 SmallPtrSet<BasicBlock *, 2> BBsToSinkInto;
120 if (UseBBs.size() == 0)
121 return BBsToSinkInto;
122
123 BBsToSinkInto.insert(UseBBs.begin(), UseBBs.end());
124 SmallPtrSet<BasicBlock *, 2> BBsDominatedByColdestBB;
125
126 // For every iteration:
127 // * Pick the ColdestBB from ColdLoopBBs
128 // * Find the set BBsDominatedByColdestBB that satisfy:
129 // - BBsDominatedByColdestBB is a subset of BBsToSinkInto
130 // - Every BB in BBsDominatedByColdestBB is dominated by ColdestBB
131 // * If Freq(ColdestBB) < Freq(BBsDominatedByColdestBB), remove
132 // BBsDominatedByColdestBB from BBsToSinkInto, add ColdestBB to
133 // BBsToSinkInto
134 for (BasicBlock *ColdestBB : ColdLoopBBs) {
135 BBsDominatedByColdestBB.clear();
136 for (BasicBlock *SinkedBB : BBsToSinkInto)
137 if (DT.dominates(ColdestBB, SinkedBB))
138 BBsDominatedByColdestBB.insert(SinkedBB);
139 if (BBsDominatedByColdestBB.size() == 0)
140 continue;
141 if (adjustedSumFreq(BBsDominatedByColdestBB, BFI) >
142 BFI.getBlockFreq(ColdestBB)) {
143 for (BasicBlock *DominatedBB : BBsDominatedByColdestBB) {
144 BBsToSinkInto.erase(DominatedBB);
145 }
146 BBsToSinkInto.insert(ColdestBB);
147 continue;
148 }
149 // Otherwise, see if we can stop the search through the cold BBs early.
150 // Since the ColdLoopBBs list is sorted in increasing magnitude of
151 // frequency the cold BB frequencies can only get larger. The
152 // BBsToSinkInto set can only get smaller and have a smaller
153 // adjustedSumFreq, due to the earlier checking. So once we find a cold BB
154 // with a frequency at least as large as the adjustedSumFreq of the
155 // current BBsToSinkInto set, the earlier frequency check can never be
156 // true for a future iteration. Note we could do check this more
157 // aggressively earlier, but in practice this ended up being more
158 // expensive overall (added checking to the critical path through the loop
159 // that often ended up continuing early due to an empty
160 // BBsDominatedByColdestBB set, and the frequency check there was false
161 // most of the time anyway).
162 if (adjustedSumFreq(BBsToSinkInto, BFI) <= BFI.getBlockFreq(ColdestBB))
163 break;
164 }
165
166 // Can't sink into blocks that have no valid insertion point.
167 for (BasicBlock *BB : BBsToSinkInto) {
168 if (BB->getFirstInsertionPt() == BB->end()) {
169 BBsToSinkInto.clear();
170 break;
171 }
172 }
173
174 // If the total frequency of BBsToSinkInto is larger than preheader frequency,
175 // do not sink.
176 if (adjustedSumFreq(BBsToSinkInto, BFI) >
177 BFI.getBlockFreq(L.getLoopPreheader()))
178 BBsToSinkInto.clear();
179 return BBsToSinkInto;
180}
181
182// Sinks \p I from the loop \p L's preheader to its uses. Returns true if
183// sinking is successful.
184// \p LoopBlockNumber is used to sort the insertion blocks to ensure
185// determinism.
186static bool sinkInstruction(
187 Loop &L, Instruction &I, const SmallVectorImpl<BasicBlock *> &ColdLoopBBs,
188 const SmallDenseMap<BasicBlock *, int, 16> &LoopBlockNumber, LoopInfo &LI,
190 // Compute the set of blocks in loop L which contain a use of I.
192 for (auto &U : I.uses()) {
193 Instruction *UI = cast<Instruction>(U.getUser());
194
195 // We cannot sink I if it has uses outside of the loop.
196 if (!L.contains(LI.getLoopFor(UI->getParent())))
197 return false;
198
199 if (!isa<PHINode>(UI)) {
200 BBs.insert(UI->getParent());
201 continue;
202 }
203
204 // We cannot sink I to PHI-uses, try to look through PHI to find the incoming
205 // block of the value being used.
206 PHINode *PN = dyn_cast<PHINode>(UI);
207 BasicBlock *PhiBB = PN->getIncomingBlock(U);
208
209 // If value's incoming block is from loop preheader directly, there's no
210 // place to sink to, bailout.
211 if (L.getLoopPreheader() == PhiBB)
212 return false;
213
214 BBs.insert(PhiBB);
215 }
216
217 // findBBsToSinkInto is O(BBs.size() * ColdLoopBBs.size()). We cap the max
218 // BBs.size() to avoid expensive computation.
219 // FIXME: Handle code size growth for min_size and opt_size.
221 return false;
222
223 // Find the set of BBs that we should insert a copy of I.
224 SmallPtrSet<BasicBlock *, 2> BBsToSinkInto =
225 findBBsToSinkInto(L, BBs, ColdLoopBBs, DT, BFI);
226 if (BBsToSinkInto.empty())
227 return false;
228
229 // Return if any of the candidate blocks to sink into is non-cold.
230 if (BBsToSinkInto.size() > 1 &&
231 !llvm::set_is_subset(BBsToSinkInto, LoopBlockNumber))
232 return false;
233
234 // Copy the final BBs into a vector and sort them using the total ordering
235 // of the loop block numbers as iterating the set doesn't give a useful
236 // order. No need to stable sort as the block numbers are a total ordering.
237 SmallVector<BasicBlock *, 2> SortedBBsToSinkInto;
238 llvm::append_range(SortedBBsToSinkInto, BBsToSinkInto);
239 if (SortedBBsToSinkInto.size() > 1) {
240 llvm::sort(SortedBBsToSinkInto, [&](BasicBlock *A, BasicBlock *B) {
241 return LoopBlockNumber.find(A)->second < LoopBlockNumber.find(B)->second;
242 });
243 }
244
245 BasicBlock *MoveBB = *SortedBBsToSinkInto.begin();
246 // FIXME: Optimize the efficiency for cloned value replacement. The current
247 // implementation is O(SortedBBsToSinkInto.size() * I.num_uses()).
248 for (BasicBlock *N : ArrayRef(SortedBBsToSinkInto).drop_front(1)) {
249 assert(LoopBlockNumber.find(N)->second >
250 LoopBlockNumber.find(MoveBB)->second &&
251 "BBs not sorted!");
252 // Clone I and replace its uses.
253 Instruction *IC = I.clone();
254 IC->setName(I.getName());
255 IC->insertBefore(&*N->getFirstInsertionPt());
256
257 if (MSSAU && MSSAU->getMemorySSA()->getMemoryAccess(&I)) {
258 // Create a new MemoryAccess and let MemorySSA set its defining access.
259 MemoryAccess *NewMemAcc =
260 MSSAU->createMemoryAccessInBB(IC, nullptr, N, MemorySSA::Beginning);
261 if (NewMemAcc) {
262 if (auto *MemDef = dyn_cast<MemoryDef>(NewMemAcc))
263 MSSAU->insertDef(MemDef, /*RenameUses=*/true);
264 else {
265 auto *MemUse = cast<MemoryUse>(NewMemAcc);
266 MSSAU->insertUse(MemUse, /*RenameUses=*/true);
267 }
268 }
269 }
270
271 // Replaces uses of I with IC in N, except PHI-use which is being taken
272 // care of by defs in PHI's incoming blocks.
273 I.replaceUsesWithIf(IC, [N](Use &U) {
274 Instruction *UIToReplace = cast<Instruction>(U.getUser());
275 return UIToReplace->getParent() == N && !isa<PHINode>(UIToReplace);
276 });
277 // Replaces uses of I with IC in blocks dominated by N
278 replaceDominatedUsesWith(&I, IC, DT, N);
279 LLVM_DEBUG(dbgs() << "Sinking a clone of " << I << " To: " << N->getName()
280 << '\n');
281 NumLoopSunkCloned++;
282 }
283 LLVM_DEBUG(dbgs() << "Sinking " << I << " To: " << MoveBB->getName() << '\n');
284 NumLoopSunk++;
285 I.moveBefore(&*MoveBB->getFirstInsertionPt());
286
287 if (MSSAU)
288 if (MemoryUseOrDef *OldMemAcc = cast_or_null<MemoryUseOrDef>(
289 MSSAU->getMemorySSA()->getMemoryAccess(&I)))
290 MSSAU->moveToPlace(OldMemAcc, MoveBB, MemorySSA::Beginning);
291
292 return true;
293}
294
295/// Sinks instructions from loop's preheader to the loop body if the
296/// sum frequency of inserted copy is smaller than preheader's frequency.
298 DominatorTree &DT,
300 MemorySSA &MSSA,
301 ScalarEvolution *SE) {
302 BasicBlock *Preheader = L.getLoopPreheader();
303 assert(Preheader && "Expected loop to have preheader");
304
305 assert(Preheader->getParent()->hasProfileData() &&
306 "Unexpected call when profile data unavailable.");
307
308 const BlockFrequency PreheaderFreq = BFI.getBlockFreq(Preheader);
309 // If there are no basic blocks with lower frequency than the preheader then
310 // we can avoid the detailed analysis as we will never find profitable sinking
311 // opportunities.
312 if (all_of(L.blocks(), [&](const BasicBlock *BB) {
313 return BFI.getBlockFreq(BB) > PreheaderFreq;
314 }))
315 return false;
316
317 MemorySSAUpdater MSSAU(&MSSA);
318 SinkAndHoistLICMFlags LICMFlags(/*IsSink=*/true, L, MSSA);
319
320 bool Changed = false;
321
322 // Sort loop's basic blocks by frequency
325 int i = 0;
326 for (BasicBlock *B : L.blocks())
327 if (BFI.getBlockFreq(B) < BFI.getBlockFreq(L.getLoopPreheader())) {
328 ColdLoopBBs.push_back(B);
329 LoopBlockNumber[B] = ++i;
330 }
331 llvm::stable_sort(ColdLoopBBs, [&](BasicBlock *A, BasicBlock *B) {
332 return BFI.getBlockFreq(A) < BFI.getBlockFreq(B);
333 });
334
335 // Traverse preheader's instructions in reverse order because if A depends
336 // on B (A appears after B), A needs to be sunk first before B can be
337 // sinked.
339 if (isa<PHINode>(&I))
340 continue;
341 // No need to check for instruction's operands are loop invariant.
342 assert(L.hasLoopInvariantOperands(&I) &&
343 "Insts in a loop's preheader should have loop invariant operands!");
344 if (!canSinkOrHoistInst(I, &AA, &DT, &L, MSSAU, false, LICMFlags))
345 continue;
346 if (sinkInstruction(L, I, ColdLoopBBs, LoopBlockNumber, LI, DT, BFI,
347 &MSSAU)) {
348 Changed = true;
349 if (SE)
351 }
352 }
353
354 return Changed;
355}
356
358 // Enable LoopSink only when runtime profile is available.
359 // With static profile, the sinking decision may be sub-optimal.
360 if (!F.hasProfileData())
361 return PreservedAnalyses::all();
362
364 // Nothing to do if there are no loops.
365 if (LI.empty())
366 return PreservedAnalyses::all();
367
371 MemorySSA &MSSA = FAM.getResult<MemorySSAAnalysis>(F).getMSSA();
372
373 // We want to do a postorder walk over the loops. Since loops are a tree this
374 // is equivalent to a reversed preorder walk and preorder is easy to compute
375 // without recursion. Since we reverse the preorder, we will visit siblings
376 // in reverse program order. This isn't expected to matter at all but is more
377 // consistent with sinking algorithms which generally work bottom-up.
378 SmallVector<Loop *, 4> PreorderLoops = LI.getLoopsInPreorder();
379
380 bool Changed = false;
381 do {
382 Loop &L = *PreorderLoops.pop_back_val();
383
384 BasicBlock *Preheader = L.getLoopPreheader();
385 if (!Preheader)
386 continue;
387
388 // Note that we don't pass SCEV here because it is only used to invalidate
389 // loops in SCEV and we don't preserve (or request) SCEV at all making that
390 // unnecessary.
391 Changed |= sinkLoopInvariantInstructions(L, AA, LI, DT, BFI, MSSA,
392 /*ScalarEvolution*/ nullptr);
393 } while (!PreorderLoops.empty());
394
395 if (!Changed)
396 return PreservedAnalyses::all();
397
401
402 if (VerifyMemorySSA)
403 MSSA.verifyMemorySSA();
404
405 return PA;
406}
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define LLVM_DEBUG(...)
Definition: Debug.h:106
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."))
static bool sinkInstruction(Loop &L, Instruction &I, const SmallVectorImpl< BasicBlock * > &ColdLoopBBs, const SmallDenseMap< BasicBlock *, int, 16 > &LoopBlockNumber, LoopInfo &LI, DominatorTree &DT, BlockFrequencyInfo &BFI, MemorySSAUpdater *MSSAU)
Definition: LoopSink.cpp:186
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.
Definition: LoopSink.cpp:116
static bool sinkLoopInvariantInstructions(Loop &L, AAResults &AA, LoopInfo &LI, DominatorTree &DT, BlockFrequencyInfo &BFI, MemorySSA &MSSA, ScalarEvolution *SE)
Sinks instructions from loop's preheader to the loop body if the sum frequency of inserted copy is sm...
Definition: LoopSink.cpp:297
static BlockFrequency adjustedSumFreq(SmallPtrSetImpl< BasicBlock * > &BBs, BlockFrequencyInfo &BFI)
Return adjusted total frequency of BBs.
Definition: LoopSink.cpp:78
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."))
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
This file exposes an interface to building/using memory SSA to walk memory instructions using a use/d...
FunctionAnalysisManager FAM
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines generic set operations that may be used on set's of different types,...
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition: Statistic.h:166
A manager for alias analyses.
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:253
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:410
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
LLVM Basic Block Representation.
Definition: BasicBlock.h:61
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
Definition: BasicBlock.cpp:416
const Function * getParent() const
Return the enclosing method, or null if none.
Definition: BasicBlock.h:219
Analysis pass which computes BlockFrequencyInfo.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
Represents analyses that only rely on functions' control flow.
Definition: Analysis.h:72
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:156
Analysis pass which computes a DominatorTree.
Definition: Dominators.h:279
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition: Dominators.h:162
bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
Definition: Dominators.cpp:122
bool hasProfileData(bool IncludeSynthetic=false) const
Return true if the function is annotated with profile data.
Definition: Function.h:329
void insertBefore(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified instruction.
Definition: Instruction.cpp:97
Analysis pass that exposes the LoopInfo for a function.
Definition: LoopInfo.h:566
SmallVector< LoopT *, 4 > getLoopsInPreorder() const
Return all of the loops in the function in preorder across the loop nests, with siblings in forward p...
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
Definition: LoopSink.cpp:357
Represents a single loop in the control flow graph.
Definition: LoopInfo.h:39
An analysis that produces MemorySSA for a function.
Definition: MemorySSA.h:928
MemorySSA * getMemorySSA() const
Get handle on MemorySSA.
void insertDef(MemoryDef *Def, bool RenameUses=false)
Insert a definition into the MemorySSA IR.
void insertUse(MemoryUse *Use, bool RenameUses=false)
MemoryAccess * createMemoryAccessInBB(Instruction *I, MemoryAccess *Definition, const BasicBlock *BB, MemorySSA::InsertionPlace Point, bool CreationMustSucceed=true)
Create a MemoryAccess in MemorySSA at a specified point in a block.
void moveToPlace(MemoryUseOrDef *What, BasicBlock *BB, MemorySSA::InsertionPlace Where)
Encapsulates MemorySSA, including all data associated with memory accesses.
Definition: MemorySSA.h:701
MemoryUseOrDef * getMemoryAccess(const Instruction *I) const
Given a memory Mod/Ref'ing instruction, get the MemorySSA access associated with it.
Definition: MemorySSA.h:719
Class that has the common methods + fields of memory uses/defs.
Definition: MemorySSA.h:249
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:111
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: Analysis.h:117
void preserveSet()
Mark an analysis set as preserved.
Definition: Analysis.h:146
void preserve()
Mark an analysis as preserved.
Definition: Analysis.h:131
The main scalar evolution driver.
void forgetBlockAndLoopDispositions(Value *V=nullptr)
Called when the client has changed the disposition of values in a loop or block.
Flags controlling how much is checked when sinking or hoisting instructions.
Definition: LoopUtils.h:120
size_type size() const
Definition: SmallPtrSet.h:94
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
Definition: SmallPtrSet.h:363
iterator end() const
Definition: SmallPtrSet.h:477
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:384
iterator begin() const
Definition: SmallPtrSet.h:472
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:519
bool empty() const
Definition: SmallVector.h:81
size_t size() const
Definition: SmallVector.h:78
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
void push_back(const T &Elt)
Definition: SmallVector.h:413
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
A Use represents the edge between a Value definition and its users.
Definition: Use.h:43
void setName(const Twine &Name)
Change the name of the value.
Definition: Value.cpp:377
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:309
const ParentTy * getParent() const
Definition: ilist_node.h:32
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
void stable_sort(R &&Range)
Definition: STLExtras.h:2037
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1739
bool canSinkOrHoistInst(Instruction &I, AAResults *AA, DominatorTree *DT, Loop *CurLoop, MemorySSAUpdater &MSSAU, bool TargetExecutesOncePerLoop, SinkAndHoistLICMFlags &LICMFlags, OptimizationRemarkEmitter *ORE=nullptr)
Returns true if is legal to hoist or sink this instruction disregarding the possible introduction of ...
Definition: LICM.cpp:1161
bool set_is_subset(const S1Ty &S1, const S2Ty &S2)
set_is_subset(A, B) - Return true iff A in B
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition: STLExtras.h:2115
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition: STLExtras.h:657
auto reverse(ContainerTy &&C)
Definition: STLExtras.h:420
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1664
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
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.
Definition: Local.cpp:3578
bool VerifyMemorySSA
Enables verification of MemorySSA.
Definition: MemorySSA.cpp:84
#define N