LLVM: include/llvm/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_DEPENDENCYGRAPH_H
23#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_DEPENDENCYGRAPH_H
24
32
34
38
39
44
47class DependencyGraph;
48
49
51
52
53class PredIterator {
59
63 : OpIt(OpIt), OpItE(OpItE), MemIt(MemIt), N(N), DAG(&DAG) {}
66 : OpIt(OpIt), OpItE(OpItE), N(N), DAG(&DAG) {}
69
70
71
75
76public:
85 auto Copy = *this;
86 ++(*this);
87 return Copy;
88 }
91};
92
93
94
96protected:
98
99
101
103
105
107
110 friend class SchedBundle;
111
115
116public:
122
124
134
136
139
141
146 PredIterator::skipBadIt(I->op_begin(), I->op_end(), DAG), I->op_end(),
147 this, DAG);
148 }
158
159
160
161
165
168 auto IID = II->getIntrinsicID();
169 return IID == Intrinsic::stackrestore || IID == Intrinsic::stacksave;
170 }
171 return false;
172 }
173
174
175
177 auto IID = I->getIntrinsicID();
178 return IID != Intrinsic::sideeffect && IID != Intrinsic::pseudoprobe;
179 }
180
181
182
183
186 return I->mayReadOrWriteMemory() &&
188 }
189
190
193 return I->isFenceLike() &&
195 }
196
197
205
207
208#ifndef NDEBUG
209 virtual void print(raw_ostream &OS, bool PrintDeps = true) const;
211 N.print(OS);
212 return OS;
213 }
215#endif
216};
217
218
219
220
224
226
229
231 assert(N != this && "About to point to self!");
232 NextMemN = N;
233 if (NextMemN != nullptr)
234 NextMemN->PrevMemN = this;
235 }
236
238 assert(N != this && "About to point to self!");
239 PrevMemN = N;
240 if (PrevMemN != nullptr)
241 PrevMemN->NextMemN = this;
242 }
244 void detachFromChain() {
245 if (PrevMemN != nullptr)
246 PrevMemN->NextMemN = NextMemN;
247 if (NextMemN != nullptr)
248 NextMemN->PrevMemN = PrevMemN;
249 PrevMemN = nullptr;
250 NextMemN = nullptr;
251 }
252
253public:
261 auto OpEndIt = I->op_end();
262 return PredIterator(PredIterator::skipBadIt(I->op_begin(), OpEndIt, DAG),
263 OpEndIt, MemPreds.begin(), this, DAG);
264 }
266 return PredIterator(I->op_end(), I->op_end(), MemPreds.end(), this, DAG);
267 }
268
270
272
273
274
276 [[maybe_unused]] auto Inserted = MemPreds.insert(PredN).second;
277 assert(Inserted && "PredN already exists!");
278 assert(PredN != this && "Trying to add a dependency to self!");
279 PredN->MemSuccs.insert(this);
282 }
283 }
284
285
287 MemPreds.erase(PredN);
288 PredN->MemSuccs.erase(this);
291 }
292 }
293
296 return MemPreds.count(MN);
297 return false;
298 }
299
301 return make_range(MemPreds.begin(), MemPreds.end());
302 }
303
305 return make_range(MemSuccs.begin(), MemSuccs.end());
306 }
307#ifndef NDEBUG
308 void print(raw_ostream &OS, bool PrintDeps = true) const override;
309#endif
310};
311
312
314public:
315
316
319
320
323
324
325
329};
330
332private:
334
336
338 std::optionalContext::CallbackID CreateInstrCB;
339 std::optionalContext::CallbackID EraseInstrCB;
340 std::optionalContext::CallbackID MoveInstrCB;
341 std::optionalContext::CallbackID SetUseCB;
342
343 std::unique_ptr BatchAA;
344
345 enum class DependencyType {
346 ReadAfterWrite,
347 WriteAfterWrite,
348 WriteAfterRead,
349 Control,
350 Other,
351 None,
352 };
353
354
355
356
357
359
360
361
363
365
366
367
369
370
371
373
374
375
377
378
379
380
382 MemDGNode *SkipN = nullptr) const;
383
384
385
387 MemDGNode *SkipN = nullptr) const;
388
389
391
392
394
395
397
399
400public:
401
404 CreateInstrCB = Ctx.registerCreateInstrCallback(
405 [this](Instruction *I) { notifyCreateInstr(I); });
406 EraseInstrCB = Ctx.registerEraseInstrCallback(
407 [this](Instruction *I) { notifyEraseInstr(I); });
408 MoveInstrCB = Ctx.registerMoveInstrCallback(
409 [this](Instruction *I, const BBIterator &To) {
410 notifyMoveInstr(I, To);
411 });
412 SetUseCB = Ctx.registerSetUseCallback(
413 [this](const Use &U, Value *NewSrc) { notifySetUse(U, NewSrc); });
414 }
416 if (CreateInstrCB)
417 Ctx->unregisterCreateInstrCallback(*CreateInstrCB);
418 if (EraseInstrCB)
419 Ctx->unregisterEraseInstrCallback(*EraseInstrCB);
420 if (MoveInstrCB)
421 Ctx->unregisterMoveInstrCallback(*MoveInstrCB);
422 if (SetUseCB)
423 Ctx->unregisterSetUseCallback(*SetUseCB);
424 }
425
427 auto It = InstrToNodeMap.find(I);
428 return It != InstrToNodeMap.end() ? It->second.get() : nullptr;
429 }
430
432 if (I == nullptr)
433 return nullptr;
435 }
437 auto [It, NotInMap] = InstrToNodeMap.try_emplace(I);
438 if (NotInMap) {
440 It->second = std::make_unique(I);
441 else
442 It->second = std::make_unique(I);
443 }
444 return It->second.get();
445 }
446
447
449
452 InstrToNodeMap.clear();
453 DAGInterval = {};
454 }
455#ifndef NDEBUG
456
458 bool IsEmpty = InstrToNodeMap.empty();
459 assert(IsEmpty == DAGInterval.empty() &&
460 "Interval and InstrToNodeMap out of sync!");
461 return IsEmpty;
462 }
465#endif
466};
467}
468
469#endif
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_TEMPLATE_ABI
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
This file defines the DenseMap class.
std::pair< uint64_t, uint64_t > Interval
uint64_t IntrinsicInst * II
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
This class is a wrapper over an AAResults, and it is intended to be used only when there are no IR ch...
Represent a node in the directed graph.
Implements a dense probed hash-table based set.
DenseSetIterator< false > iterator
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
bool isUsedWithInAlloca() const
Return true if this alloca is used as an inalloca argument to a call.
A DependencyGraph Node that points to an Instruction and contains memory dependency edges.
Definition DependencyGraph.h:95
void incrUnscheduledSuccs()
Definition DependencyGraph.h:129
friend class SchedBundle
Definition DependencyGraph.h:110
void decrUnscheduledSuccs()
Definition DependencyGraph.h:125
friend class DependencyGraph
Definition DependencyGraph.h:114
DGNode(Instruction *I)
Definition DependencyGraph.h:117
static bool isMemDepCandidate(Instruction *I)
We consider I as a Memory Dependency Candidate instruction if it reads/write memory or if it has side...
Definition DependencyGraph.h:184
virtual iterator preds_end(DependencyGraph &DAG)
Definition DependencyGraph.h:149
static bool isMemIntrinsic(IntrinsicInst *I)
\Returns true if intrinsic I touches memory.
Definition DependencyGraph.h:176
iterator preds_begin(DependencyGraph &DAG) const
Definition DependencyGraph.h:152
Instruction * I
Definition DependencyGraph.h:97
friend class MemDGNode
Definition DependencyGraph.h:113
PredIterator iterator
Definition DependencyGraph.h:143
DGNode(Instruction *I, DGNodeID ID)
Definition DependencyGraph.h:112
unsigned getNumUnscheduledSuccs() const
\Returns the number of unscheduled successors.
Definition DependencyGraph.h:123
void setSchedBundle(SchedBundle &SB)
bool scheduled() const
\Returns true if this node has been scheduled.
Definition DependencyGraph.h:137
unsigned UnscheduledSuccs
The number of unscheduled successors.
Definition DependencyGraph.h:102
void setScheduled(bool NewVal)
Definition DependencyGraph.h:138
bool ready() const
\Returns true if all dependent successors have been scheduled.
Definition DependencyGraph.h:135
iterator_range< iterator > preds(DependencyGraph &DAG) const
\Returns a range of DAG predecessors nodes.
Definition DependencyGraph.h:162
iterator preds_end(DependencyGraph &DAG) const
Definition DependencyGraph.h:155
SchedBundle * SB
The scheduler bundle that this node belongs to.
Definition DependencyGraph.h:106
bool Scheduled
This is true if this node has been scheduled.
Definition DependencyGraph.h:104
static bool isMemDepNodeCandidate(Instruction *I)
\Returns true if I is a memory dependency candidate instruction.
Definition DependencyGraph.h:198
SchedBundle * getSchedBundle() const
\Returns the scheduling bundle that this node belongs to, or nullptr.
Definition DependencyGraph.h:140
DGNodeID SubclassID
For isa/dyn_cast etc.
Definition DependencyGraph.h:100
DGNode(const DGNode &Other)=delete
static bool isFenceLike(Instruction *I)
\Returns true if I is fence like. It excludes non-mem intrinsics.
Definition DependencyGraph.h:191
void clearSchedBundle()
Definition DependencyGraph.h:109
void resetScheduleState()
Definition DependencyGraph.h:130
Instruction * getInstruction() const
Definition DependencyGraph.h:206
static bool isStackSaveOrRestoreIntrinsic(Instruction *I)
Definition DependencyGraph.h:166
bool comesBefore(const DGNode *Other)
\Returns true if this is before Other in program order.
Definition DependencyGraph.h:142
friend raw_ostream & operator<<(raw_ostream &OS, DGNode &N)
Definition DependencyGraph.h:210
virtual iterator preds_begin(DependencyGraph &DAG)
Definition DependencyGraph.h:144
Definition DependencyGraph.h:331
void clear()
Definition DependencyGraph.h:451
Interval< Instruction > getInterval() const
\Returns the range of instructions included in the DAG.
Definition DependencyGraph.h:450
bool empty() const
\Returns true if the DAG's state is clear. Used in assertions.
Definition DependencyGraph.h:457
LLVM_DUMP_METHOD void dump() const
DGNode * getNode(Instruction *I) const
Definition DependencyGraph.h:426
DependencyGraph(AAResults &AA, Context &Ctx)
This constructor also registers callbacks.
Definition DependencyGraph.h:402
~DependencyGraph()
Definition DependencyGraph.h:415
DGNode * getNodeOrNull(Instruction *I) const
Like getNode() but returns nullptr if I is nullptr.
Definition DependencyGraph.h:431
void print(raw_ostream &OS) const
DGNode * getOrCreateNode(Instruction *I)
Definition DependencyGraph.h:436
LLVM_ABI Interval< Instruction > extend(ArrayRef< Instruction * > Instrs)
Build/extend the dependency graph such that it includes Instrs.
A sandboxir::User with operands, opcode and linked with previous/next instructions in an instruction ...
Convenience builders for a MemDGNode interval.
Definition DependencyGraph.h:313
static LLVM_ABI MemDGNode * getBotMemDGNode(const Interval< Instruction > &Intvl, const DependencyGraph &DAG)
Scans the instruction chain in Intvl bottom-up, returning the bottom-most MemDGNode,...
static Interval< MemDGNode > makeEmpty()
Definition DependencyGraph.h:328
static LLVM_ABI MemDGNode * getTopMemDGNode(const Interval< Instruction > &Intvl, const DependencyGraph &DAG)
Scans the instruction chain in Intvl top-down, returning the top-most MemDGNode, or nullptr.
static LLVM_ABI Interval< MemDGNode > make(const Interval< Instruction > &Instrs, DependencyGraph &DAG)
Given Instrs it finds their closest mem nodes in the interval and returns the corresponding mem range...
A DependencyGraph Node for instructions that may read/write memory, or have some ordering constraints...
Definition DependencyGraph.h:221
iterator preds_end(DependencyGraph &DAG) override
Definition DependencyGraph.h:265
friend class DependencyGraph
Definition DependencyGraph.h:243
iterator preds_begin(DependencyGraph &DAG) override
Definition DependencyGraph.h:260
bool hasMemPred(DGNode *N) const
\Returns true if there is a memory dependency N->this.
Definition DependencyGraph.h:294
static bool classof(const DGNode *Other)
Definition DependencyGraph.h:257
iterator_range< DenseSet< MemDGNode * >::const_iterator > memPreds() const
\Returns all memory dependency predecessors. Used by tests.
Definition DependencyGraph.h:300
MemDGNode * getNextNode() const
\Returns the next Mem DGNode in instruction order.
Definition DependencyGraph.h:271
iterator_range< DenseSet< MemDGNode * >::const_iterator > memSuccs() const
\Returns all memory dependency successors.
Definition DependencyGraph.h:304
void removeMemPred(MemDGNode *PredN)
Removes the memory dependency PredN->this.
Definition DependencyGraph.h:286
MemDGNode(Instruction *I)
Definition DependencyGraph.h:254
MemDGNode * getPrevNode() const
\Returns the previous Mem DGNode in instruction order.
Definition DependencyGraph.h:269
void addMemPred(MemDGNode *PredN)
Adds the mem dependency edge PredN->this.
Definition DependencyGraph.h:275
friend class PredIterator
Definition DependencyGraph.h:228
Iterate over both def-use and mem dependencies.
Definition DependencyGraph.h:53
std::ptrdiff_t difference_type
Definition DependencyGraph.h:77
PredIterator operator++(int)
Definition DependencyGraph.h:84
value_type & reference
Definition DependencyGraph.h:80
friend class MemDGNode
Definition DependencyGraph.h:68
DGNode * value_type
Definition DependencyGraph.h:78
value_type * pointer
Definition DependencyGraph.h:79
bool operator!=(const PredIterator &Other) const
Definition DependencyGraph.h:90
LLVM_ABI PredIterator & operator++()
friend class DGNode
Definition DependencyGraph.h:67
std::input_iterator_tag iterator_category
Definition DependencyGraph.h:81
The nodes that need to be scheduled back-to-back in a single scheduling cycle form a SchedBundle.
Represents a Def-use/Use-def edge in SandboxIR.
OperandUseIterator op_iterator
A SandboxIR Value has users. This is the base class.
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
Abstract Attribute helper functions.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
DGNodeID
SubclassIDs for isa/dyn_cast etc.
Definition DependencyGraph.h:40
@ MemDGNode
Definition DependencyGraph.h:42
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
APInt operator*(APInt a, uint64_t RHS)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
Implement std::hash so that hash_code can be used in STL containers.