21#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_SCHEDULER_H
22#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_SCHEDULER_H
40 bool IsTerm1 = I1->isTerminator();
41 bool IsTerm2 = I2->isTerminator();
42 if (IsTerm1 != IsTerm2)
44 return IsTerm1 > IsTerm2;
49 return IsPHI1 < IsPHI2;
51 return I2->comesBefore(I1);
70 assert(!
N->scheduled() &&
"Don't insert a scheduled node!");
75 assert(List.size() == Set.size() &&
"List and Set out-of-sync!");
78 auto *Back = List.top();
81 assert(List.size() == Set.size() &&
"List and Set out-of-sync!");
85 assert(List.empty() == Set.empty() &&
"List and Set out-of-sync!");
95 auto ListContains = [
this](
DGNode *
N) {
97 while (!ListCopy.empty()) {
98 DGNode *Top = ListCopy.top();
105 assert(ListContains(
N) == Set.contains(
N) &&
"List and Set out-of-sync!");
107 return Set.contains(
N);
111 auto It = Set.find(
N);
112 if (It != Set.end()) {
117 assert(List.size() == Set.size() &&
"List and Set out-of-sync!");
143 for (
auto *
N : this->Nodes)
144 N->setSchedBundle(*
this);
151 for (
auto *
N : this->Nodes)
152 N->clearSchedBundle();
154 bool empty()
const {
return Nodes.empty(); }
174 return all_of(Nodes, [](
const auto *
N) {
return N->ready(); });
198class SchedulingPoint {
202 std::variant<BasicBlock::iterator, BasicBlock *> Where;
205 SchedulingPoint(
BasicBlock &BB) : Where(&BB) {}
213 return SchedulingPoint(It);
218 if (It == BB.
begin())
219 return SchedulingPoint(BB);
220 return SchedulingPoint(std::prev(It));
224 assert(It != It.getNodeParent()->end() &&
"Already at end!");
225 return SchedulingPoint(std::next(It));
231 if (std::holds_alternative<BasicBlock::iterator>(Where))
233 return std::get<BasicBlock *>(Where);
238 if (std::holds_alternative<BasicBlock *>(Where))
240 auto It = std::get<BasicBlock::iterator>(Where);
241 return It == It.getNodeParent()->end() ? It.getNodeParent() :
nullptr;
248 return &*std::get<BasicBlock::iterator>(Where);
257 return std::get<BasicBlock::iterator>(Where);
271 auto *BB = It.getNodeParent();
272 if (It == BB->
begin())
274 return std::prev(It);
277 return Where ==
Other.Where;
284 assert(BB ==
I.getParent() &&
"We don't support crossing BBs!");
289 assert(BB ==
I.getParent() &&
"We don't support crossing BBs!");
293 assert(SchedPointI !=
nullptr &&
"Should have been already handled!");
317 std::optional<SchedulingPoint> ScheduleTopItOpt;
323 std::optional<Context::CallbackID> CreateInstrCB;
337 void scheduleAndUpdateReadyList(
SchedBundle &Bndl);
339 enum class BndlSchedState {
343 TemporarilyScheduled,
368 : DAG(Dir,
AA, Ctx), Ctx(Ctx), Dir(Dir) {
371 CreateInstrCB = Ctx.registerCreateInstrCallback(
376 Ctx.unregisterCreateInstrCallback(*CreateInstrCB);
390 ScheduleTopItOpt = std::nullopt;
391 ScheduledBB =
nullptr;
392 assert(Bndls.empty() && DAG.empty() && ReadyList.empty() &&
393 !ScheduleTopItOpt && ScheduledBB ==
nullptr &&
394 "Expected empty state!");
411 return Sched.getBndlSchedState(Instrs);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
PostRA Machine Instruction Scheduler
This file defines the PriorityQueue class.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
iterator begin()
Instruction iterator methods.
InstListType::iterator iterator
Instruction iterators...
PriorityQueue - This class behaves like std::priority_queue and provides a few additional convenience...
Implements a dense probed hash-table based set with some number of buckets stored inline.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class implements an extremely fast bulk output stream that can only output to a stream.
A DependencyGraph Node that points to an Instruction and contains memory dependency edges.
void setSchedBundle(SchedBundle &SB)
Instruction * getInstruction() const
A sandboxir::User with operands, opcode and linked with previous/next instructions in an instruction ...
bool comesBefore(const Instruction *Other) const
Given an instruction Other in the same basic block as this instruction, return true if this instructi...
bool operator()(const DGNode *N1, const DGNode *N2)
The list holding nodes that are ready to schedule. Used by the scheduler.
LLVM_DUMP_METHOD void dump() const
void remove(DGNode *N)
\Removes N if found in the ready list. Note: this is linear time!
bool contains(DGNode *N) const
The nodes that need to be scheduled back-to-back in a single scheduling cycle form a SchedBundle.
LLVM_ABI DGNode * getBot() const
\Returns the bundle node that comes after the others in program order.
SchedBundle(ContainerTy &&Nodes)
SchedBundle & operator=(const SchedBundle &Other)=delete
Copy Assignment (unimplemented).
LLVM_ABI DGNode * getTop() const
\Returns the bundle node that comes before the others in program order.
bool isSingleton() const
Singleton bundles are created when scheduling instructions temporarily to fill in the schedule until ...
SmallVector< DGNode *, 4 > ContainerTy
const_iterator begin() const
LLVM_DUMP_METHOD void dump() const
SchedBundle(const SchedBundle &Other)=delete
Copy CTOR (unimplemented).
ContainerTy::iterator iterator
const_iterator end() const
ContainerTy::const_iterator const_iterator
LLVM_ABI void cluster(BasicBlock::iterator Where)
Move all bundle instructions to Where back-to-back.
bool ready(SchedDirection Dir) const
\Returns true if all nodes in the bundle are ready.
A client-attorney class for accessing the Scheduler's internals (used for unit tests).
static BndlSchedState getBndlSchedState(const Scheduler &Sched, ArrayRef< Instruction * > Instrs)
Scheduler::BndlSchedState BndlSchedState
static DependencyGraph & getDAG(Scheduler &Sched)
friend class SchedulerInternalsAttorney
LLVM_DUMP_METHOD void dump() const
LLVM_ABI bool trySchedule(ArrayRef< Instruction * > Instrs)
Tries to build a schedule that includes all of Instrs scheduled at the same scheduling cycle.
void clear()
Clear the scheduler's state, including the DAG.
Scheduler(AAResults &AA, Context &Ctx, SchedDirection Dir)
SchedulingPoint getNext() const
Returns the SchedulingPoint pointing after this.
BasicBlock * atEndOrNull() const
If the SchedulingPoint points after the last instruction in the BB then this returns the correspondin...
Instruction * atInstrOrNull() const
Returns the instruction pointed to by this SchedulingPoint or null if we are before/after BB.
LLVM_DUMP_METHOD void dump() const
SchedulingPoint getPrev() const
Returns the SchedulingPoint pointing before this.
BasicBlock::iterator getIterator() const
Returns the corresponding BB::iterator.
BasicBlock * atBeforeBeginOrNull() const
If the SchedulingPoint points to before the beginning of a BB, then this returns that BB,...
static SchedulingPoint createAt(BasicBlock::iterator It)
Returns a SchedulingPoint that points to It.
static SchedulingPoint createBefore(BasicBlock::iterator It)
Returns a SchedulingPoint that points to one element before It.
SchedulingPoint(BasicBlock::iterator It)
Creates a scheduling point pointing at It, meaning any instruction in a BB or BB.end().
bool operator==(const SchedulingPoint &Other) const
void print(raw_ostream &OS) const
static SchedulingPoint createAfter(BasicBlock::iterator It)
Returns a SchedulingPoint that points to one element after It.
bool comesBefore(Instruction &I) const
Returns true if the scheduling point is after I in program order.
Abstract Attribute helper functions.
BasicBlock(llvm::BasicBlock *BB, Context &SBCtx)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Implement std::hash so that hash_code can be used in STL containers.