22#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_DEPENDENCYGRAPH_H
23#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_DEPENDENCYGRAPH_H
52 while (OpIt != OpItE && !isa<Instruction>((*OpIt).get()))
68 : OpIt(OpIt), OpItE(OpItE), MemIt(MemIt),
N(
N), DAG(&DAG) {}
71 : OpIt(OpIt), OpItE(OpItE),
N(
N), DAG(&DAG) {}
159 if (
auto *
II = dyn_cast<IntrinsicInst>(
I)) {
160 auto IID =
II->getIntrinsicID();
161 return IID == Intrinsic::stackrestore || IID == Intrinsic::stacksave;
169 auto IID =
I->getIntrinsicID();
170 return IID != Intrinsic::sideeffect && IID != Intrinsic::pseudoprobe;
193 ((Alloca = dyn_cast<AllocaInst>(
I)) &&
221 assert(
N !=
this &&
"About to point to self!");
223 if (NextMemN !=
nullptr)
224 NextMemN->PrevMemN =
this;
228 assert(
N !=
this &&
"About to point to self!");
230 if (PrevMemN !=
nullptr)
231 PrevMemN->NextMemN =
this;
234 void detachFromChain() {
235 if (PrevMemN !=
nullptr)
236 PrevMemN->NextMemN = NextMemN;
237 if (NextMemN !=
nullptr)
238 NextMemN->PrevMemN = PrevMemN;
253 MemPreds.
begin(),
this, DAG);
266 [[maybe_unused]]
auto Inserted = MemPreds.
insert(PredN).second;
267 assert(Inserted &&
"PredN already exists!");
274 if (
auto *MN = dyn_cast<MemDGNode>(
N))
275 return MemPreds.
count(MN);
313 std::optional<Context::CallbackID> CreateInstrCB;
314 std::optional<Context::CallbackID> EraseInstrCB;
315 std::optional<Context::CallbackID> MoveInstrCB;
317 std::unique_ptr<BatchAAResults> BatchAA;
319 enum class DependencyType {
382 notifyMoveInstr(
I, To);
395 auto It = InstrToNodeMap.
find(
I);
396 return It != InstrToNodeMap.
end() ? It->second.get() :
nullptr;
408 It->second = std::make_unique<MemDGNode>(
I);
410 It->second = std::make_unique<DGNode>(
I);
412 return It->second.get();
420 InstrToNodeMap.
clear();
426 bool IsEmpty = InstrToNodeMap.
empty();
428 "Interval and InstrToNodeMap out of sync!");
#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::optional< std::vector< StOtherPiece > > Other
uint64_t IntrinsicInst * II
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Implements a dense probed hash-table based set.
std::pair< iterator, bool > insert(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
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.
Iterator for Instructions in a `BasicBlock.
CallbackID registerCreateInstrCallback(CreateInstrCallback CB)
Register a callback that gets called right after a SandboxIR instruction is created.
void unregisterCreateInstrCallback(CallbackID ID)
void unregisterMoveInstrCallback(CallbackID ID)
void unregisterEraseInstrCallback(CallbackID ID)
CallbackID registerMoveInstrCallback(MoveInstrCallback CB)
Register a callback that gets called when a SandboxIR instruction is about to be moved.
CallbackID registerEraseInstrCallback(EraseInstrCallback CB)
Register a callback that gets called when a SandboxIR instruction is about to be removed from its par...
A DependencyGraph Node that points to an Instruction and contains memory dependency edges.
void decrUnscheduledSuccs()
virtual void print(raw_ostream &OS, bool PrintDeps=true) const
static bool isMemDepCandidate(Instruction *I)
We consider I as a Memory Dependency Candidate instruction if it reads/write memory or if it has side...
virtual iterator preds_end(DependencyGraph &DAG)
static bool isMemIntrinsic(IntrinsicInst *I)
\Returns true if intrinsic I touches memory.
iterator preds_begin(DependencyGraph &DAG) const
DGNode(Instruction *I, DGNodeID ID)
unsigned getNumUnscheduledSuccs() const
\Returns the number of unscheduled successors.
void setSchedBundle(SchedBundle &SB)
bool scheduled() const
\Returns true if this node has been scheduled.
unsigned UnscheduledSuccs
The number of unscheduled successors.
void setScheduled(bool NewVal)
bool ready() const
\Returns true if all dependent successors have been scheduled.
iterator_range< iterator > preds(DependencyGraph &DAG) const
\Returns a range of DAG predecessors nodes.
iterator preds_end(DependencyGraph &DAG) const
SchedBundle * SB
The scheduler bundle that this node belongs to.
bool Scheduled
This is true if this node has been scheduled.
static bool isMemDepNodeCandidate(Instruction *I)
\Returns true if I is a memory dependency candidate instruction.
SchedBundle * getSchedBundle() const
\Returns the scheduling bundle that this node belongs to, or nullptr.
DGNodeID SubclassID
For isa/dyn_cast etc.
DGNode(const DGNode &Other)=delete
static bool isFenceLike(Instruction *I)
\Returns true if I is fence like. It excludes non-mem intrinsics.
LLVM_DUMP_METHOD void dump() const
Instruction * getInstruction() const
static bool isStackSaveOrRestoreIntrinsic(Instruction *I)
bool comesBefore(const DGNode *Other)
\Returns true if this is before Other in program order.
friend raw_ostream & operator<<(raw_ostream &OS, DGNode &N)
virtual iterator preds_begin(DependencyGraph &DAG)
Interval< Instruction > getInterval() const
\Returns the range of instructions included in the DAG.
bool empty() const
\Returns true if the DAG's state is clear. Used in assertions.
LLVM_DUMP_METHOD void dump() const
DGNode * getNode(Instruction *I) const
DependencyGraph(AAResults &AA, Context &Ctx)
This constructor also registers callbacks.
DGNode * getNodeOrNull(Instruction *I) const
Like getNode() but returns nullptr if I is nullptr.
void print(raw_ostream &OS) const
DGNode * getOrCreateNode(Instruction *I)
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 ...
bool mayReadOrWriteMemory() const
bool comesBefore(const Instruction *Other) const
Given an instruction Other in the same basic block as this instruction, return true if this instructi...
Convenience builders for a MemDGNode interval.
static 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()
static 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 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...
iterator preds_end(DependencyGraph &DAG) override
iterator preds_begin(DependencyGraph &DAG) override
bool hasMemPred(DGNode *N) const
\Returns true if there is a memory dependency N->this.
static bool classof(const DGNode *Other)
iterator_range< DenseSet< MemDGNode * >::const_iterator > memPreds() const
\Returns all memory dependency predecessors. Used by tests.
MemDGNode * getNextNode() const
\Returns the next Mem DGNode in instruction order.
virtual void print(raw_ostream &OS, bool PrintDeps=true) const override
MemDGNode(Instruction *I)
MemDGNode * getPrevNode() const
\Returns the previous Mem DGNode in instruction order.
void addMemPred(MemDGNode *PredN)
Adds the mem dependency edge PredN->this.
friend class PredIterator
Iterator for the Use edges of a User's operands.
Iterate over both def-use and mem dependencies.
std::ptrdiff_t difference_type
PredIterator operator++(int)
bool operator!=(const PredIterator &Other) const
PredIterator & operator++()
std::input_iterator_tag iterator_category
The nodes that need to be scheduled back-to-back in a single scheduling cycle form a SchedBundle.
virtual op_iterator op_begin()
virtual op_iterator op_end()
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
static User::op_iterator skipNonInstr(User::op_iterator OpIt, User::op_iterator OpItE)
While OpIt points to a Value that is not an Instruction keep incrementing it.
DGNodeID
SubclassIDs for isa/dyn_cast etc.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Implement std::hash so that hash_code can be used in STL containers.