File indexing completed on 2026-05-10 08:44:45
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 #ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_SCHEDULER_H
0022 #define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_SCHEDULER_H
0023
0024 #include "llvm/SandboxIR/Instruction.h"
0025 #include "llvm/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.h"
0026 #include <queue>
0027
0028 namespace llvm::sandboxir {
0029
0030 class PriorityCmp {
0031 public:
0032 bool operator()(const DGNode *N1, const DGNode *N2) {
0033
0034 return N1->getInstruction()->comesBefore(N2->getInstruction());
0035 }
0036 };
0037
0038
0039 class ReadyListContainer {
0040 PriorityCmp Cmp;
0041
0042
0043
0044
0045 std::priority_queue<DGNode *, std::vector<DGNode *>, PriorityCmp> List;
0046
0047 public:
0048 ReadyListContainer() : List(Cmp) {}
0049 void insert(DGNode *N) { List.push(N); }
0050 DGNode *pop() {
0051 auto *Back = List.top();
0052 List.pop();
0053 return Back;
0054 }
0055 bool empty() const { return List.empty(); }
0056 void clear() { List = {}; }
0057 #ifndef NDEBUG
0058 void dump(raw_ostream &OS) const;
0059 LLVM_DUMP_METHOD void dump() const;
0060 #endif
0061 };
0062
0063
0064
0065 class SchedBundle {
0066 public:
0067 using ContainerTy = SmallVector<DGNode *, 4>;
0068
0069 private:
0070 ContainerTy Nodes;
0071
0072
0073 void eraseFromBundle(DGNode *N) { Nodes.erase(find(Nodes, N)); }
0074 friend DGNode::~DGNode();
0075
0076 public:
0077 SchedBundle() = default;
0078 SchedBundle(ContainerTy &&Nodes) : Nodes(std::move(Nodes)) {
0079 for (auto *N : this->Nodes)
0080 N->setSchedBundle(*this);
0081 }
0082
0083 SchedBundle(const SchedBundle &Other) = delete;
0084
0085 SchedBundle &operator=(const SchedBundle &Other) = delete;
0086 ~SchedBundle() {
0087 for (auto *N : this->Nodes)
0088 N->clearSchedBundle();
0089 }
0090 bool empty() const { return Nodes.empty(); }
0091 DGNode *back() const { return Nodes.back(); }
0092 using iterator = ContainerTy::iterator;
0093 using const_iterator = ContainerTy::const_iterator;
0094 iterator begin() { return Nodes.begin(); }
0095 iterator end() { return Nodes.end(); }
0096 const_iterator begin() const { return Nodes.begin(); }
0097 const_iterator end() const { return Nodes.end(); }
0098
0099 DGNode *getTop() const;
0100
0101 DGNode *getBot() const;
0102
0103 void cluster(BasicBlock::iterator Where);
0104 #ifndef NDEBUG
0105 void dump(raw_ostream &OS) const;
0106 LLVM_DUMP_METHOD void dump() const;
0107 #endif
0108 };
0109
0110
0111 class Scheduler {
0112
0113
0114
0115 ReadyListContainer ReadyList;
0116
0117
0118 DependencyGraph DAG;
0119
0120
0121
0122 std::optional<BasicBlock::iterator> ScheduleTopItOpt;
0123
0124 DenseMap<SchedBundle *, std::unique_ptr<SchedBundle>> Bndls;
0125
0126 BasicBlock *ScheduledBB = nullptr;
0127
0128
0129 SchedBundle *createBundle(ArrayRef<Instruction *> Instrs);
0130 void eraseBundle(SchedBundle *SB);
0131
0132 bool tryScheduleUntil(ArrayRef<Instruction *> Instrs);
0133
0134
0135
0136 void scheduleAndUpdateReadyList(SchedBundle &Bndl);
0137
0138 enum class BndlSchedState {
0139 NoneScheduled,
0140 PartiallyOrDifferentlyScheduled,
0141
0142
0143
0144 FullyScheduled,
0145
0146 };
0147
0148 BndlSchedState getBndlSchedState(ArrayRef<Instruction *> Instrs) const;
0149
0150 void trimSchedule(ArrayRef<Instruction *> Instrs);
0151
0152 Scheduler(const Scheduler &) = delete;
0153 Scheduler &operator=(const Scheduler &) = delete;
0154
0155 public:
0156 Scheduler(AAResults &AA, Context &Ctx) : DAG(AA, Ctx) {}
0157 ~Scheduler() {}
0158
0159
0160
0161
0162
0163 bool trySchedule(ArrayRef<Instruction *> Instrs);
0164
0165 void clear() {
0166 Bndls.clear();
0167
0168 DAG.clear();
0169 ReadyList.clear();
0170 ScheduleTopItOpt = std::nullopt;
0171 ScheduledBB = nullptr;
0172 assert(Bndls.empty() && DAG.empty() && ReadyList.empty() &&
0173 !ScheduleTopItOpt && ScheduledBB == nullptr &&
0174 "Expected empty state!");
0175 }
0176
0177 #ifndef NDEBUG
0178 void dump(raw_ostream &OS) const;
0179 LLVM_DUMP_METHOD void dump() const;
0180 #endif
0181 };
0182
0183 }
0184
0185 #endif