LLVM 24.0.0git
VPlanPredicator.cpp
Go to the documentation of this file.
1//===-- VPlanPredicator.cpp - VPlan predicator ----------------------------===//
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/// \file
10/// This file implements predication for VPlans.
11///
12//===----------------------------------------------------------------------===//
13
14#include "VPRecipeBuilder.h"
15#include "VPlan.h"
16#include "VPlanCFG.h"
17#include "VPlanDominatorTree.h"
18#include "VPlanPatternMatch.h"
19#include "VPlanTransforms.h"
20#include "VPlanUtils.h"
22
23using namespace llvm;
24using namespace VPlanPatternMatch;
25
26namespace {
27class VPPredicator {
28 VPlan &Plan;
29
30 /// Builder to construct recipes to compute masks.
31 VPBuilder Builder;
32
33 /// Dominator tree for the VPlan.
34 VPDominatorTree VPDT;
35
36 /// Post-dominator tree for the VPlan.
37 VPPostDominatorTree VPPDT;
38
39 /// Post-dominator frontier for the VPlan.
40 VPPostDominanceFrontier VPPDF;
41
42 /// When we if-convert we need to create edge masks. We have to cache values
43 /// so that we don't end up with exponential recursion/IR.
44 using EdgeMaskCacheTy =
45 DenseMap<std::pair<const VPBasicBlock *, const VPBasicBlock *>,
46 VPValue *>;
47 using BlockMaskCacheTy = DenseMap<const VPBasicBlock *, VPValue *>;
48 EdgeMaskCacheTy EdgeMaskCache;
49
50 BlockMaskCacheTy BlockMaskCache;
51
52 /// Create an edge mask for every destination of cases and/or default.
53 void createSwitchEdgeMasks(const VPInstruction *SI);
54
55 /// Computes and return the predicate of the edge between \p Src and \p Dst,
56 /// possibly inserting new recipes at \p Dst (using Builder's insertion point)
57 VPValue *createEdgeMask(const VPBasicBlock *Src, const VPBasicBlock *Dst);
58
59 /// Record \p Mask as the *entry* mask of \p VPBB, which is expected to not
60 /// already have a mask.
61 void setBlockInMask(const VPBasicBlock *VPBB, VPValue *Mask) {
62 // TODO: Include the masks as operands in the predicated VPlan directly to
63 // avoid keeping the map of masks beyond the predication transform.
64 assert(!getBlockInMask(VPBB) && "Mask already set");
65 BlockMaskCache[VPBB] = Mask;
66 }
67
68 /// Record \p Mask as the mask of the edge from \p Src to \p Dst. The edge is
69 /// expected to not have a mask already.
70 VPValue *setEdgeMask(const VPBasicBlock *Src, const VPBasicBlock *Dst,
71 VPValue *Mask) {
72 assert(Src != Dst && "Src and Dst must be different");
73 assert(!getEdgeMask(Src, Dst) && "Mask already set");
74 return EdgeMaskCache[{Src, Dst}] = Mask;
75 }
76
77 /// Returns where to insert new masks in \p VPBB.
78 VPBasicBlock::iterator getMaskInsertPoint(VPBasicBlock *VPBB) {
79 if (VPValue *Mask = getBlockInMask(VPBB))
80 if (VPRecipeBase *MaskR = Mask->getDefiningRecipe())
81 if (MaskR->getParent() == VPBB) // In-mask may be the IDom's.
82 return std::next(MaskR->getIterator());
83 return VPBB->getFirstNonPhi();
84 }
85
86 using EdgeTy = std::pair<const VPBasicBlock *, const VPBasicBlock *>;
87
88 /// Compute the set of edges that are "furthest up" in the CFG for each
89 /// incoming value of \p Phi.
90 MapVector<EdgeTy, VPValue *> computeBlendEdges(VPPhi *Phi);
91
92 /// Given a set of \p Edges that each can reach \p VPBB, return the OR of all
93 /// edges, or an equivalent block in-mask.
94 VPValue *createBlendMaskForEdges(ArrayRef<EdgeTy> Edges, VPBasicBlock *VPBB);
95
96public:
97 VPPredicator(VPlan &Plan)
98 : Plan(Plan), VPDT(Plan), VPPDT(Plan), VPPDF(VPPDT) {}
99
100 /// Returns the *entry* mask for \p VPBB.
101 VPValue *getBlockInMask(const VPBasicBlock *VPBB) const {
102 return BlockMaskCache.lookup(VPBB);
103 }
104
105 /// Returns the precomputed predicate of the edge from \p Src to \p Dst.
106 VPValue *getEdgeMask(const VPBasicBlock *Src, const VPBasicBlock *Dst) const {
107 return EdgeMaskCache.lookup({Src, Dst});
108 }
109
110 /// Compute the predicate of \p VPBB.
111 void createBlockInMask(VPBasicBlock *VPBB);
112
113 /// Convert phi recipes in \p VPBB to VPBlendRecipes.
114 void convertPhisToBlends(VPBasicBlock *VPBB);
115
116 /// Predicate and linearize the plan.
117 void run();
118};
119} // namespace
120
121VPValue *VPPredicator::createEdgeMask(const VPBasicBlock *Src,
122 const VPBasicBlock *Dst) {
123 assert(is_contained(Dst->getPredecessors(), Src) && "Invalid edge");
124
125 // Look for cached value.
126 VPValue *EdgeMask = getEdgeMask(Src, Dst);
127 if (EdgeMask)
128 return EdgeMask;
129
130 VPValue *SrcMask = getBlockInMask(Src);
131
132 // If there's a single successor, there's no terminator recipe.
133 if (Src->getNumSuccessors() == 1)
134 return setEdgeMask(Src, Dst, SrcMask);
135
136 auto *Term = cast<VPInstruction>(Src->getTerminator());
137 if (Term->getOpcode() == Instruction::Switch) {
138 createSwitchEdgeMasks(Term);
139 return getEdgeMask(Src, Dst);
140 }
141
142 assert(Term->getOpcode() == VPInstruction::BranchOnCond &&
143 "Unsupported terminator");
144 if (Src->getSuccessors()[0] == Src->getSuccessors()[1])
145 return setEdgeMask(Src, Dst, SrcMask);
146
147 EdgeMask = Term->getOperand(0);
148 assert(EdgeMask && "No Edge Mask found for condition");
149
150 if (Src->getSuccessors()[0] != Dst)
151 EdgeMask = Builder.createNot(EdgeMask, Term->getDebugLoc());
152
153 if (SrcMask) { // Otherwise block in-mask is all-one, no need to AND.
154 // The bitwise 'And' of SrcMask and EdgeMask introduces new UB if SrcMask
155 // is false and EdgeMask is poison. Avoid that by using 'LogicalAnd'
156 // instead which generates 'select i1 SrcMask, i1 EdgeMask, i1 false'.
157 EdgeMask = Builder.createLogicalAnd(SrcMask, EdgeMask, Term->getDebugLoc());
158 }
159
160 return setEdgeMask(Src, Dst, EdgeMask);
161}
162
163void VPPredicator::createBlockInMask(VPBasicBlock *VPBB) {
164 // Start inserting after the block's phis, which be replaced by blends later.
165 Builder.setInsertPoint(VPBB, VPBB->getFirstNonPhi());
166
167 // Reuse the mask of the immediate dominator if the VPBB post-dominates the
168 // immediate dominator.
169 auto *IDom = VPDT.getNode(VPBB)->getIDom();
170 assert(IDom && "Block in loop must have immediate dominator");
171 auto *IDomBB = cast<VPBasicBlock>(IDom->getBlock());
172 if (VPPDT.properlyDominates(VPBB, IDomBB)) {
173 setBlockInMask(VPBB, getBlockInMask(IDomBB));
174 return;
175 }
176 // All-one mask is modelled as no-mask following the convention for masked
177 // load/store/gather/scatter. Initialize BlockMask to no-mask.
178 VPValue *BlockMask = nullptr;
179 // This is the block mask. We OR all unique incoming edges.
180 for (auto *Predecessor : SetVector<VPBlockBase *>(
181 VPBB->getPredecessors().begin(), VPBB->getPredecessors().end())) {
182 VPValue *EdgeMask = createEdgeMask(cast<VPBasicBlock>(Predecessor), VPBB);
183 if (!EdgeMask) { // Mask of predecessor is all-one so mask of block is
184 // too.
185 setBlockInMask(VPBB, EdgeMask);
186 return;
187 }
188
189 if (!BlockMask) { // BlockMask has its initial nullptr value.
190 BlockMask = EdgeMask;
191 continue;
192 }
193
194 BlockMask = Builder.createOr(BlockMask, EdgeMask, {});
195 }
196
197 setBlockInMask(VPBB, BlockMask);
198}
199
200void VPPredicator::createSwitchEdgeMasks(const VPInstruction *SI) {
201 const VPBasicBlock *Src = SI->getParent();
202
203 // Create masks where SI is a switch. We create masks for all edges from SI's
204 // parent block at the same time. This is more efficient, as we can create and
205 // collect compares for all cases once.
206 VPValue *Cond = SI->getOperand(0);
207 VPBasicBlock *DefaultDst = cast<VPBasicBlock>(Src->getSuccessors()[0]);
208 MapVector<VPBasicBlock *, SmallVector<VPValue *>> Dst2Compares;
209 for (const auto &[Idx, Succ] : enumerate(drop_begin(Src->getSuccessors()))) {
210 VPBasicBlock *Dst = cast<VPBasicBlock>(Succ);
211 assert(!getEdgeMask(Src, Dst) && "Edge masks already created");
212 // Cases whose destination is the same as default are redundant and can
213 // be ignored - they will get there anyhow.
214 if (Dst == DefaultDst)
215 continue;
216 auto &Compares = Dst2Compares[Dst];
217 VPValue *V = SI->getOperand(Idx + 1);
218 Compares.push_back(Builder.createICmp(CmpInst::ICMP_EQ, Cond, V));
219 }
220
221 // We need to handle 2 separate cases below for all entries in Dst2Compares,
222 // which excludes destinations matching the default destination.
223 VPValue *SrcMask = getBlockInMask(Src);
224 VPValue *DefaultMask = nullptr;
225 for (const auto &[Dst, Conds] : Dst2Compares) {
226 // 1. Dst is not the default destination. Dst is reached if any of the
227 // cases with destination == Dst are taken. Join the conditions for each
228 // case whose destination == Dst using an OR.
229 VPValue *Mask = Conds[0];
230 for (VPValue *V : drop_begin(Conds))
231 Mask = Builder.createOr(Mask, V);
232 if (SrcMask)
233 Mask = Builder.createLogicalAnd(SrcMask, Mask);
234 setEdgeMask(Src, Dst, Mask);
235
236 // 2. Create the mask for the default destination, which is reached if
237 // none of the cases with destination != default destination are taken.
238 // Join the conditions for each case where the destination is != Dst using
239 // an OR and negate it.
240 DefaultMask = DefaultMask ? Builder.createOr(DefaultMask, Mask) : Mask;
241 }
242
243 if (DefaultMask) {
244 DefaultMask = Builder.createNot(DefaultMask);
245 if (SrcMask)
246 DefaultMask = Builder.createLogicalAnd(SrcMask, DefaultMask);
247 } else {
248 // There are no destinations other than the default destination, so this is
249 // an unconditional branch.
250 DefaultMask = SrcMask;
251 }
252 setEdgeMask(Src, DefaultDst, DefaultMask);
253}
254
255// Start by keeping track of what edges lead to which value. Then see if any
256// node has the same value for all outgoing edges. If so then propagate that
257// value up to every node it postdominates. E.g:
258//
259// Entry Edges = {C->ɸ : %x, D->ɸ : %x, F->ɸ : %y}
260// / \ [C,D,F all outgoing edges equal: go up postdom frontier]
261// A B ~> {A->C : %x, A->D : %x, Entry->B : %y}
262// / \ |\ [A all outgoing edges equal: go up postdom frontier]
263// C D | E ~> {Entry->A : %x, Entry->B : %y}
264// \ \ |/
265// \ | F
266// \ | /
267// ɸ = phi [%x, C], [%x, D], [%y, F]
268MapVector<VPPredicator::EdgeTy, VPValue *>
269VPPredicator::computeBlendEdges(VPPhi *Phi) {
270 MapVector<EdgeTy, VPValue *> Edges;
271
272 // Mark the given edge as providing the value \p V.
273 auto AddEdge = [&Edges](const VPBlockBase *From, const VPBlockBase *To,
274 VPValue *V) {
275 EdgeTy Edge = {cast<VPBasicBlock>(From), cast<VPBasicBlock>(To)};
276 assert((!Edges.contains(Edge) || Edges.lookup(Edge) == V) &&
277 "Clobbering an edge?");
278 Edges[Edge] = V;
279 };
280
281 for (auto [InVal, InVPBB] : Phi->incoming_values_and_blocks())
282 AddEdge(InVPBB, Phi->getParent(), InVal);
283
284 SetVector<const VPBlockBase *> Worklist(from_range, Phi->incoming_blocks());
285 while (!Worklist.empty()) {
286 auto *VPBB = cast<VPBasicBlock>(Worklist.pop_back_val());
287
288 // Check that all outgoing edges from VPBB have the same value.
289 SmallVector<EdgeTy> OutEdges;
290 for (const VPBlockBase *Succ : VPBB->getSuccessors())
291 OutEdges.emplace_back(VPBB, cast<VPBasicBlock>(Succ));
292 auto OutVals =
293 map_range(OutEdges, [&Edges](EdgeTy E) { return Edges.lookup(E); });
294 VPValue *Common = *OutVals.begin();
295 if (!Common || !all_equal(OutVals))
296 continue;
297
298 // They have the same value: we can move the edges up.
299 for (EdgeTy Edge : OutEdges)
300 Edges.erase(Edge);
301
302 // Iterate up through the post dominance frontier.
303 assert(VPPDF.find(VPBB) != VPPDF.end() &&
304 "VPBB must have a post-dominance frontier entry");
305 for (const VPBlockBase *Frontier : VPPDF.find(VPBB)->second) {
306 for (const VPBlockBase *FrontierSucc : Frontier->getSuccessors())
307 if (VPPDT.dominates(VPBB, FrontierSucc))
308 AddEdge(Frontier, FrontierSucc, Common);
309 Worklist.insert(cast<VPBasicBlock>(Frontier));
310 }
311 }
312
313 return Edges;
314}
315
316VPValue *VPPredicator::createBlendMaskForEdges(ArrayRef<EdgeTy> Edges,
317 VPBasicBlock *VPBB) {
318 // If the nearest common postdominator to all of Edges destinations isn't VPBB
319 // then we can use its block in-mask. E.g:
320 //
321 // A ... B
322 // \ \ /
323 // \ C
324 // \ /
325 // ... D ...
326 // \ | /
327 // VPBB
328 //
329 // If the edges are A->D and B->C, PostDom will be D. We can reuse Ds block
330 // in-mask.
331 const VPBasicBlock *PostDom = Edges[0].second;
332 for (auto [_, DstVPBB] : drop_begin(Edges))
333 PostDom =
334 cast<VPBasicBlock>(VPPDT.findNearestCommonDominator(PostDom, DstVPBB));
335 assert(VPPDT.dominates(VPBB, PostDom) && "VPBB doesn't postdominate edges");
336 if (PostDom != VPBB)
337 return getBlockInMask(PostDom);
338
339 // Otherwise, compute the disjunction of edges.
340 VPValue *Mask = nullptr;
341 for (auto [Src, ConstDst] : Edges) {
342 auto *Dst = const_cast<VPBasicBlock *>(ConstDst);
343 VPValue *EdgeMask;
344 {
345 VPBuilder::InsertPointGuard Guard(Builder);
346 Builder.setInsertPoint(Dst, getMaskInsertPoint(Dst));
347 EdgeMask = createEdgeMask(Src, Dst);
348 }
349 Mask = Mask ? Builder.createOr(Mask, EdgeMask) : EdgeMask;
350 }
351 return Mask;
352}
353
354void VPPredicator::convertPhisToBlends(VPBasicBlock *VPBB) {
355 Builder.setInsertPoint(VPBB, getMaskInsertPoint(VPBB));
356
358 for (VPRecipeBase &R : VPBB->phis())
359 Phis.push_back(cast<VPPhi>(&R));
360 for (VPPhi *PhiR : Phis) {
361 // The non-header Phi is converted into a Blend recipe below,
362 // so we don't have to worry about the insertion order and we can just use
363 // the builder. At this point we generate the predication tree. There may
364 // be duplications since this is a simple recursive scan, but future
365 // optimizations will clean it up.
366
367 auto NotPoison = make_filter_range(PhiR->incoming_values(), [](VPValue *V) {
368 return !match(V, m_Poison());
369 });
370 if (all_equal(NotPoison)) {
371 PhiR->replaceAllUsesWith(NotPoison.empty() ? PhiR->getIncomingValue(0)
372 : *NotPoison.begin());
373 PhiR->eraseFromParent();
374 continue;
375 }
376
377 MapVector<VPValue *, SmallVector<EdgeTy>> InValEdgesMap;
378 for (auto [Edge, Val] : computeBlendEdges(PhiR))
379 InValEdgesMap[Val].push_back(Edge);
380 auto InValEdges = InValEdgesMap.takeVector();
381
382 // Sort the incoming value order to match PhiR as much as possible.
383 llvm::stable_sort(InValEdges, [&PhiR](auto &L, auto &R) {
384 auto InVs = PhiR->incoming_values();
385 return std::distance(InVs.begin(), find(InVs, L.first)) <
386 std::distance(InVs.begin(), find(InVs, R.first));
387 });
388
389 SmallVector<VPValue *, 2> OperandsWithMask;
390 for (const auto &[InVPV, Edges] : InValEdges) {
391 OperandsWithMask.push_back(InVPV);
392 OperandsWithMask.push_back(createBlendMaskForEdges(Edges, VPBB));
393 }
394 PHINode *IRPhi = cast_or_null<PHINode>(PhiR->getUnderlyingValue());
395 auto *Blend =
396 new VPBlendRecipe(IRPhi, OperandsWithMask, *PhiR, PhiR->getDebugLoc());
397 Builder.insert(Blend);
398 PhiR->replaceAllUsesWith(Blend);
399 PhiR->eraseFromParent();
400 }
401}
402
403void VPPredicator::run() {
404 VPBasicBlock *Header = Plan.getVectorLoopRegion()->getEntryBasicBlock();
405 // Scan the body of the loop in a topological order to visit each basic
406 // block after having visited its predecessor basic blocks.
407 ReversePostOrderTraversal<VPBlockShallowTraversalWrapper<VPBlockBase *>> RPOT(
408 Header);
409 // Non-outer regions with VPBBs only are supported at the moment.
411
412 for (VPBasicBlock *VPBB : Blocks) {
413 // Introduce the mask for VPBB, which may introduce needed edge masks, and
414 // convert all phi recipes of VPBB to blend recipes unless VPBB is the
415 // header.
416 if (VPBB != Header)
417 createBlockInMask(VPBB);
418
419 VPValue *BlockMask = getBlockInMask(VPBB);
420 // Mask all VPInstructions in the block.
421 for (VPInstruction &VPI : make_isa_range<VPInstruction>(*VPBB)) {
422 if (BlockMask)
423 VPI.addMask(BlockMask);
424
425 // Drop the execution frequency of unmasked VPInstructions, as they
426 // always execute.
427 if (!VPI.isMasked())
428 VPI.clearExecutionFrequency();
429 }
430 }
431
432 for (VPBasicBlock *VPBB : reverse(Blocks))
433 if (VPBB != Header)
434 convertPhisToBlends(VPBB);
435
436 // Linearize the blocks of the loop into one serial chain.
437 VPBlockBase *PrevVPBB = nullptr;
438 for (VPBasicBlock *VPBB : Blocks) {
439 auto Successors = to_vector(VPBB->getSuccessors());
440 if (Successors.size() > 1)
442
443 // Flatten the CFG in the loop. To do so, first disconnect VPBB from its
444 // successors. Then connect VPBB to the previously visited VPBB.
445 for (auto *Succ : Successors)
447 if (PrevVPBB)
448 VPBlockUtils::connectBlocks(PrevVPBB, VPBB);
449
450 PrevVPBB = VPBB;
451 }
452}
453
455 // Nested loop regions (outer-loop vectorization) are not supported yet.
456 if (Plan.isOuterLoop())
457 return;
458 VPPredicator(Plan).run();
459}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define _
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
const SmallVectorImpl< MachineOperand > & Cond
std::pair< BasicBlock *, BasicBlock * > Edge
This file implements dominator tree analysis for a single level of a VPlan's H-CFG.
This file provides utility VPlan to VPlan transformations.
This file contains the declarations of the Vectorization Plan base classes:
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
Definition DenseMap.h:285
iterator begin()
Definition DenseMap.h:172
DomTreeNodeBase * getIDom() const
NodeT * findNearestCommonDominator(NodeT *A, NodeT *B) const
Find nearest common dominator basic block for basic block A and B.
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
bool properlyDominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
properlyDominates - Returns true iff A dominates B and A != B.
ValueT lookup(const KeyT &Key) const
Definition MapVector.h:110
VectorType takeVector()
Clear the MapVector and return the underlying vector.
Definition MapVector.h:50
bool contains(const KeyT &Key) const
Definition MapVector.h:148
VectorType::iterator erase(typename VectorType::iterator Iterator)
Remove the element given by Iterator.
Definition MapVector.h:210
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
Definition VPlan.h:4418
RecipeListTy::iterator iterator
Instruction iterators...
Definition VPlan.h:4445
iterator_range< iterator > phis()
Returns an iterator range over the PHI-like recipes in the block.
Definition VPlan.h:4506
iterator getFirstNonPhi()
Return the position of the first non-phi node recipe in the block.
Definition VPlan.cpp:233
VPRecipeBase * getTerminator()
If the block has multiple successors, return the branch recipe terminating the block.
Definition VPlan.cpp:610
const VPBlocksTy & getPredecessors() const
Definition VPlan.h:228
const VPBasicBlock * getEntryBasicBlock() const
Definition VPlan.cpp:188
const VPBlocksTy & getSuccessors() const
Definition VPlan.h:217
static auto blocksAs(T &&Range)
Return an iterator range over Range with each block cast to BlockTy.
Definition VPlanUtils.h:424
static void connectBlocks(VPBlockBase *From, VPBlockBase *To, unsigned PredIdx=-1u, unsigned SuccIdx=-1u)
Connect VPBlockBases From and To bi-directionally.
Definition VPlanUtils.h:361
static void disconnectBlocks(VPBlockBase *From, VPBlockBase *To)
Disconnect VPBlockBases From and To bi-directionally.
Definition VPlanUtils.h:379
VPInstruction * createOr(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
T * insert(T *R)
Insert R at the current insertion point. Returns R unchanged.
VPInstruction * createNot(VPValue *Operand, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
void setInsertPoint(const VPInsertPoint &IP)
Set the current insert point.
VPInstruction * createLogicalAnd(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createICmp(CmpInst::Predicate Pred, VPValue *A, VPValue *B, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
Create a new ICmp VPInstruction with predicate Pred and operands A and B.
iplist< VPRecipeBase >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
This is the base class of the VPlan Def/Use graph, used for modeling the data flow into,...
Definition VPlanValue.h:50
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4830
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
Definition VPlan.cpp:1033
LLVM_ABI_FOR_TEST bool isOuterLoop() const
Returns true if this VPlan is for an outer loop, i.e., its vector loop region contains a nested loop ...
Definition VPlan.cpp:1052
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
NodeAddr< PhiNode * > Phi
Definition RDFGraph.h:390
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:316
void stable_sort(R &&Range)
Definition STLExtras.h:2132
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1781
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2570
constexpr from_range_t from_range
auto cast_or_null(const Y &Val)
Definition Casting.h:714
auto map_range(ContainerTy &&C, FuncTy F)
Return a range that applies F to the elements of C.
Definition STLExtras.h:366
auto make_isa_range(RangeT &&Range)
Return a range over Range containing only elements for which isa<T> holds, casting each of them to T.
Definition STLExtras.h:567
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
SmallVector< ValueTypeFromRangeType< R >, Size > to_vector(R &&Range)
Given a range of type R, iterate the entire range and return a SmallVector with elements of the vecto...
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
Definition STLExtras.h:552
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
bool all_equal(std::initializer_list< T > Values)
Returns true if all Values in the initializer lists are equal or the list.
Definition STLExtras.h:2182
static void introduceMasksAndLinearize(VPlan &Plan)
Predicate and linearize the control-flow in the only loop region of Plan.