File indexing completed on 2026-05-10 08:43:32
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 #ifndef LLVM_CODEGEN_MACHINEPIPELINER_H
0041 #define LLVM_CODEGEN_MACHINEPIPELINER_H
0042
0043 #include "llvm/ADT/STLExtras.h"
0044 #include "llvm/ADT/SetVector.h"
0045 #include "llvm/CodeGen/DFAPacketizer.h"
0046 #include "llvm/CodeGen/MachineDominators.h"
0047 #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
0048 #include "llvm/CodeGen/MachineScheduler.h"
0049 #include "llvm/CodeGen/RegisterClassInfo.h"
0050 #include "llvm/CodeGen/ScheduleDAGInstrs.h"
0051 #include "llvm/CodeGen/ScheduleDAGMutation.h"
0052 #include "llvm/CodeGen/TargetInstrInfo.h"
0053 #include "llvm/CodeGen/WindowScheduler.h"
0054 #include "llvm/InitializePasses.h"
0055
0056 #include <deque>
0057
0058 namespace llvm {
0059
0060 class AAResults;
0061 class NodeSet;
0062 class SMSchedule;
0063
0064 extern cl::opt<bool> SwpEnableCopyToPhi;
0065 extern cl::opt<int> SwpForceIssueWidth;
0066
0067
0068
0069 class MachinePipeliner : public MachineFunctionPass {
0070 public:
0071 MachineFunction *MF = nullptr;
0072 MachineOptimizationRemarkEmitter *ORE = nullptr;
0073 const MachineLoopInfo *MLI = nullptr;
0074 const MachineDominatorTree *MDT = nullptr;
0075 const InstrItineraryData *InstrItins = nullptr;
0076 const TargetInstrInfo *TII = nullptr;
0077 RegisterClassInfo RegClassInfo;
0078 bool disabledByPragma = false;
0079 unsigned II_setByPragma = 0;
0080
0081 #ifndef NDEBUG
0082 static int NumTries;
0083 #endif
0084
0085
0086 struct LoopInfo {
0087 MachineBasicBlock *TBB = nullptr;
0088 MachineBasicBlock *FBB = nullptr;
0089 SmallVector<MachineOperand, 4> BrCond;
0090 MachineInstr *LoopInductionVar = nullptr;
0091 MachineInstr *LoopCompare = nullptr;
0092 std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo> LoopPipelinerInfo =
0093 nullptr;
0094 };
0095 LoopInfo LI;
0096
0097 static char ID;
0098
0099 MachinePipeliner() : MachineFunctionPass(ID) {
0100 initializeMachinePipelinerPass(*PassRegistry::getPassRegistry());
0101 }
0102
0103 bool runOnMachineFunction(MachineFunction &MF) override;
0104
0105 void getAnalysisUsage(AnalysisUsage &AU) const override;
0106
0107 private:
0108 void preprocessPhiNodes(MachineBasicBlock &B);
0109 bool canPipelineLoop(MachineLoop &L);
0110 bool scheduleLoop(MachineLoop &L);
0111 bool swingModuloScheduler(MachineLoop &L);
0112 void setPragmaPipelineOptions(MachineLoop &L);
0113 bool runWindowScheduler(MachineLoop &L);
0114 bool useSwingModuloScheduler();
0115 bool useWindowScheduler(bool Changed);
0116 };
0117
0118
0119 class SwingSchedulerDDGEdge {
0120 SUnit *Dst = nullptr;
0121 SDep Pred;
0122 unsigned Distance = 0;
0123
0124 public:
0125
0126
0127
0128
0129 SwingSchedulerDDGEdge(SUnit *PredOrSucc, const SDep &Dep, bool IsSucc)
0130 : Dst(PredOrSucc), Pred(Dep), Distance(0u) {
0131 SUnit *Src = Dep.getSUnit();
0132
0133 if (IsSucc) {
0134 std::swap(Src, Dst);
0135 Pred.setSUnit(Src);
0136 }
0137
0138
0139 if (Pred.getKind() == SDep::Anti && Src->getInstr()->isPHI()) {
0140 Distance = 1;
0141 std::swap(Src, Dst);
0142 auto Reg = Pred.getReg();
0143 Pred = SDep(Src, SDep::Kind::Data, Reg);
0144 }
0145 }
0146
0147
0148 SUnit *getSrc() const { return Pred.getSUnit(); }
0149
0150
0151 SUnit *getDst() const { return Dst; }
0152
0153
0154 unsigned getLatency() const { return Pred.getLatency(); }
0155
0156
0157 void setLatency(unsigned Latency) { Pred.setLatency(Latency); }
0158
0159
0160 unsigned getDistance() const { return Distance; }
0161
0162
0163 void setDistance(unsigned D) { Distance = D; }
0164
0165
0166 Register getReg() const { return Pred.getReg(); }
0167
0168
0169 bool isAntiDep() const { return Pred.getKind() == SDep::Kind::Anti; }
0170
0171
0172 bool isOutputDep() const { return Pred.getKind() == SDep::Kind::Output; }
0173
0174
0175
0176 bool isOrderDep() const { return Pred.getKind() == SDep::Kind::Order; }
0177
0178
0179 bool isBarrier() const { return Pred.isBarrier(); }
0180
0181
0182 bool isArtificial() const { return Pred.isArtificial(); }
0183
0184
0185 bool isAssignedRegDep() const { return Pred.isAssignedRegDep(); }
0186
0187
0188
0189
0190 bool ignoreDependence(bool IgnoreAnti) const;
0191 };
0192
0193
0194
0195
0196
0197
0198 class SwingSchedulerDDG {
0199 using EdgesType = SmallVector<SwingSchedulerDDGEdge, 4>;
0200
0201 struct SwingSchedulerDDGEdges {
0202 EdgesType Preds;
0203 EdgesType Succs;
0204 };
0205
0206 void initEdges(SUnit *SU);
0207
0208 SUnit *EntrySU;
0209 SUnit *ExitSU;
0210
0211 std::vector<SwingSchedulerDDGEdges> EdgesVec;
0212 SwingSchedulerDDGEdges EntrySUEdges;
0213 SwingSchedulerDDGEdges ExitSUEdges;
0214
0215 void addEdge(const SUnit *SU, const SwingSchedulerDDGEdge &Edge);
0216
0217 SwingSchedulerDDGEdges &getEdges(const SUnit *SU);
0218 const SwingSchedulerDDGEdges &getEdges(const SUnit *SU) const;
0219
0220 public:
0221 SwingSchedulerDDG(std::vector<SUnit> &SUnits, SUnit *EntrySU, SUnit *ExitSU);
0222
0223 const EdgesType &getInEdges(const SUnit *SU) const;
0224
0225 const EdgesType &getOutEdges(const SUnit *SU) const;
0226 };
0227
0228
0229
0230 class SwingSchedulerDAG : public ScheduleDAGInstrs {
0231 MachinePipeliner &Pass;
0232
0233 std::unique_ptr<SwingSchedulerDDG> DDG;
0234
0235
0236 unsigned MII = 0;
0237
0238 unsigned MAX_II = 0;
0239
0240 bool Scheduled = false;
0241 MachineLoop &Loop;
0242 LiveIntervals &LIS;
0243 const RegisterClassInfo &RegClassInfo;
0244 unsigned II_setByPragma = 0;
0245 TargetInstrInfo::PipelinerLoopInfo *LoopPipelinerInfo = nullptr;
0246
0247
0248
0249 ScheduleDAGTopologicalSort Topo;
0250
0251 struct NodeInfo {
0252 int ASAP = 0;
0253 int ALAP = 0;
0254 int ZeroLatencyDepth = 0;
0255 int ZeroLatencyHeight = 0;
0256
0257 NodeInfo() = default;
0258 };
0259
0260 std::vector<NodeInfo> ScheduleInfo;
0261
0262 enum OrderKind { BottomUp = 0, TopDown = 1 };
0263
0264 SetVector<SUnit *> NodeOrder;
0265
0266 using NodeSetType = SmallVector<NodeSet, 8>;
0267 using ValueMapTy = DenseMap<unsigned, unsigned>;
0268 using MBBVectorTy = SmallVectorImpl<MachineBasicBlock *>;
0269 using InstrMapTy = DenseMap<MachineInstr *, MachineInstr *>;
0270
0271
0272 DenseMap<SUnit *, std::pair<unsigned, int64_t>> InstrChanges;
0273
0274
0275
0276 DenseMap<MachineInstr*, MachineInstr *> NewMIs;
0277
0278
0279 std::vector<std::unique_ptr<ScheduleDAGMutation>> Mutations;
0280
0281
0282 class Circuits {
0283 std::vector<SUnit> &SUnits;
0284 SetVector<SUnit *> Stack;
0285 BitVector Blocked;
0286 SmallVector<SmallPtrSet<SUnit *, 4>, 10> B;
0287 SmallVector<SmallVector<int, 4>, 16> AdjK;
0288
0289 std::vector<int> *Node2Idx;
0290 unsigned NumPaths = 0u;
0291 static unsigned MaxPaths;
0292
0293 public:
0294 Circuits(std::vector<SUnit> &SUs, ScheduleDAGTopologicalSort &Topo)
0295 : SUnits(SUs), Blocked(SUs.size()), B(SUs.size()), AdjK(SUs.size()) {
0296 Node2Idx = new std::vector<int>(SUs.size());
0297 unsigned Idx = 0;
0298 for (const auto &NodeNum : Topo)
0299 Node2Idx->at(NodeNum) = Idx++;
0300 }
0301 Circuits &operator=(const Circuits &other) = delete;
0302 Circuits(const Circuits &other) = delete;
0303 ~Circuits() { delete Node2Idx; }
0304
0305
0306 void reset() {
0307 Stack.clear();
0308 Blocked.reset();
0309 B.assign(SUnits.size(), SmallPtrSet<SUnit *, 4>());
0310 NumPaths = 0;
0311 }
0312
0313 void createAdjacencyStructure(SwingSchedulerDAG *DAG);
0314 bool circuit(int V, int S, NodeSetType &NodeSets,
0315 const SwingSchedulerDAG *DAG, bool HasBackedge = false);
0316 void unblock(int U);
0317 };
0318
0319 struct CopyToPhiMutation : public ScheduleDAGMutation {
0320 void apply(ScheduleDAGInstrs *DAG) override;
0321 };
0322
0323 public:
0324 SwingSchedulerDAG(MachinePipeliner &P, MachineLoop &L, LiveIntervals &lis,
0325 const RegisterClassInfo &rci, unsigned II,
0326 TargetInstrInfo::PipelinerLoopInfo *PLI)
0327 : ScheduleDAGInstrs(*P.MF, P.MLI, false), Pass(P), Loop(L), LIS(lis),
0328 RegClassInfo(rci), II_setByPragma(II), LoopPipelinerInfo(PLI),
0329 Topo(SUnits, &ExitSU) {
0330 P.MF->getSubtarget().getSMSMutations(Mutations);
0331 if (SwpEnableCopyToPhi)
0332 Mutations.push_back(std::make_unique<CopyToPhiMutation>());
0333 }
0334
0335 void schedule() override;
0336 void finishBlock() override;
0337
0338
0339 bool hasNewSchedule() { return Scheduled; }
0340
0341
0342 int getASAP(SUnit *Node) { return ScheduleInfo[Node->NodeNum].ASAP; }
0343
0344
0345 int getALAP(SUnit *Node) { return ScheduleInfo[Node->NodeNum].ALAP; }
0346
0347
0348
0349 int getMOV(SUnit *Node) { return getALAP(Node) - getASAP(Node); }
0350
0351
0352 unsigned getDepth(SUnit *Node) { return Node->getDepth(); }
0353
0354
0355
0356 int getZeroLatencyDepth(SUnit *Node) {
0357 return ScheduleInfo[Node->NodeNum].ZeroLatencyDepth;
0358 }
0359
0360
0361 unsigned getHeight(SUnit *Node) { return Node->getHeight(); }
0362
0363
0364
0365 int getZeroLatencyHeight(SUnit *Node) {
0366 return ScheduleInfo[Node->NodeNum].ZeroLatencyHeight;
0367 }
0368
0369 bool isLoopCarriedDep(const SwingSchedulerDDGEdge &Edge) const;
0370
0371 void applyInstrChange(MachineInstr *MI, SMSchedule &Schedule);
0372
0373 void fixupRegisterOverlaps(std::deque<SUnit *> &Instrs);
0374
0375
0376
0377 unsigned getInstrBaseReg(SUnit *SU) const {
0378 DenseMap<SUnit *, std::pair<unsigned, int64_t>>::const_iterator It =
0379 InstrChanges.find(SU);
0380 if (It != InstrChanges.end())
0381 return It->second.first;
0382 return 0;
0383 }
0384
0385 void addMutation(std::unique_ptr<ScheduleDAGMutation> Mutation) {
0386 Mutations.push_back(std::move(Mutation));
0387 }
0388
0389 static bool classof(const ScheduleDAGInstrs *DAG) { return true; }
0390
0391 const SwingSchedulerDDG *getDDG() const { return DDG.get(); }
0392
0393 private:
0394 void addLoopCarriedDependences(AAResults *AA);
0395 void updatePhiDependences();
0396 void changeDependences();
0397 unsigned calculateResMII();
0398 unsigned calculateRecMII(NodeSetType &RecNodeSets);
0399 void findCircuits(NodeSetType &NodeSets);
0400 void fuseRecs(NodeSetType &NodeSets);
0401 void removeDuplicateNodes(NodeSetType &NodeSets);
0402 void computeNodeFunctions(NodeSetType &NodeSets);
0403 void registerPressureFilter(NodeSetType &NodeSets);
0404 void colocateNodeSets(NodeSetType &NodeSets);
0405 void checkNodeSets(NodeSetType &NodeSets);
0406 void groupRemainingNodes(NodeSetType &NodeSets);
0407 void addConnectedNodes(SUnit *SU, NodeSet &NewSet,
0408 SetVector<SUnit *> &NodesAdded);
0409 void computeNodeOrder(NodeSetType &NodeSets);
0410 void checkValidNodeOrder(const NodeSetType &Circuits) const;
0411 bool schedulePipeline(SMSchedule &Schedule);
0412 bool computeDelta(MachineInstr &MI, unsigned &Delta) const;
0413 MachineInstr *findDefInLoop(Register Reg);
0414 bool canUseLastOffsetValue(MachineInstr *MI, unsigned &BasePos,
0415 unsigned &OffsetPos, unsigned &NewBase,
0416 int64_t &NewOffset);
0417 void postProcessDAG();
0418
0419 void setMII(unsigned ResMII, unsigned RecMII);
0420
0421 void setMAX_II();
0422 };
0423
0424
0425
0426 class NodeSet {
0427 SetVector<SUnit *> Nodes;
0428 bool HasRecurrence = false;
0429 unsigned RecMII = 0;
0430 int MaxMOV = 0;
0431 unsigned MaxDepth = 0;
0432 unsigned Colocate = 0;
0433 SUnit *ExceedPressure = nullptr;
0434 unsigned Latency = 0;
0435
0436 public:
0437 using iterator = SetVector<SUnit *>::const_iterator;
0438
0439 NodeSet() = default;
0440 NodeSet(iterator S, iterator E, const SwingSchedulerDAG *DAG)
0441 : Nodes(S, E), HasRecurrence(true) {
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456 const SwingSchedulerDDG *DDG = DAG->getDDG();
0457 DenseMap<SUnit *, unsigned> SUnitToDistance;
0458 for (auto *Node : Nodes)
0459 SUnitToDistance[Node] = 0;
0460
0461 for (unsigned I = 1, E = Nodes.size(); I <= E; ++I) {
0462 SUnit *U = Nodes[I - 1];
0463 SUnit *V = Nodes[I % Nodes.size()];
0464 for (const SwingSchedulerDDGEdge &Succ : DDG->getOutEdges(U)) {
0465 SUnit *SuccSUnit = Succ.getDst();
0466 if (V != SuccSUnit)
0467 continue;
0468 if (SUnitToDistance[U] + Succ.getLatency() > SUnitToDistance[V]) {
0469 SUnitToDistance[V] = SUnitToDistance[U] + Succ.getLatency();
0470 }
0471 }
0472 }
0473
0474 SUnit *FirstNode = Nodes[0];
0475 SUnit *LastNode = Nodes[Nodes.size() - 1];
0476
0477 for (auto &PI : DDG->getInEdges(LastNode)) {
0478
0479
0480
0481
0482 if (PI.getSrc() != FirstNode || !PI.isOrderDep() ||
0483 !DAG->isLoopCarriedDep(PI))
0484 continue;
0485 SUnitToDistance[FirstNode] =
0486 std::max(SUnitToDistance[FirstNode], SUnitToDistance[LastNode] + 1);
0487 }
0488
0489
0490 Latency = SUnitToDistance[Nodes.front()];
0491 }
0492
0493 bool insert(SUnit *SU) { return Nodes.insert(SU); }
0494
0495 void insert(iterator S, iterator E) { Nodes.insert(S, E); }
0496
0497 template <typename UnaryPredicate> bool remove_if(UnaryPredicate P) {
0498 return Nodes.remove_if(P);
0499 }
0500
0501 unsigned count(SUnit *SU) const { return Nodes.count(SU); }
0502
0503 bool hasRecurrence() { return HasRecurrence; };
0504
0505 unsigned size() const { return Nodes.size(); }
0506
0507 bool empty() const { return Nodes.empty(); }
0508
0509 SUnit *getNode(unsigned i) const { return Nodes[i]; };
0510
0511 void setRecMII(unsigned mii) { RecMII = mii; };
0512
0513 void setColocate(unsigned c) { Colocate = c; };
0514
0515 void setExceedPressure(SUnit *SU) { ExceedPressure = SU; }
0516
0517 bool isExceedSU(SUnit *SU) { return ExceedPressure == SU; }
0518
0519 int compareRecMII(NodeSet &RHS) { return RecMII - RHS.RecMII; }
0520
0521 int getRecMII() { return RecMII; }
0522
0523
0524 void computeNodeSetInfo(SwingSchedulerDAG *SSD) {
0525 for (SUnit *SU : *this) {
0526 MaxMOV = std::max(MaxMOV, SSD->getMOV(SU));
0527 MaxDepth = std::max(MaxDepth, SSD->getDepth(SU));
0528 }
0529 }
0530
0531 unsigned getLatency() { return Latency; }
0532
0533 unsigned getMaxDepth() { return MaxDepth; }
0534
0535 void clear() {
0536 Nodes.clear();
0537 RecMII = 0;
0538 HasRecurrence = false;
0539 MaxMOV = 0;
0540 MaxDepth = 0;
0541 Colocate = 0;
0542 ExceedPressure = nullptr;
0543 }
0544
0545 operator SetVector<SUnit *> &() { return Nodes; }
0546
0547
0548
0549
0550
0551 bool operator>(const NodeSet &RHS) const {
0552 if (RecMII == RHS.RecMII) {
0553 if (Colocate != 0 && RHS.Colocate != 0 && Colocate != RHS.Colocate)
0554 return Colocate < RHS.Colocate;
0555 if (MaxMOV == RHS.MaxMOV)
0556 return MaxDepth > RHS.MaxDepth;
0557 return MaxMOV < RHS.MaxMOV;
0558 }
0559 return RecMII > RHS.RecMII;
0560 }
0561
0562 bool operator==(const NodeSet &RHS) const {
0563 return RecMII == RHS.RecMII && MaxMOV == RHS.MaxMOV &&
0564 MaxDepth == RHS.MaxDepth;
0565 }
0566
0567 bool operator!=(const NodeSet &RHS) const { return !operator==(RHS); }
0568
0569 iterator begin() { return Nodes.begin(); }
0570 iterator end() { return Nodes.end(); }
0571 void print(raw_ostream &os) const;
0572
0573 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
0574 LLVM_DUMP_METHOD void dump() const;
0575 #endif
0576 };
0577
0578
0579
0580 static const int DefaultProcResSize = 16;
0581
0582 class ResourceManager {
0583 private:
0584 const MCSubtargetInfo *STI;
0585 const MCSchedModel &SM;
0586 const TargetSubtargetInfo *ST;
0587 const TargetInstrInfo *TII;
0588 ScheduleDAGInstrs *DAG;
0589 const bool UseDFA;
0590
0591 llvm::SmallVector<std::unique_ptr<DFAPacketizer>> DFAResources;
0592
0593
0594 llvm::SmallVector<llvm::SmallVector<uint64_t, DefaultProcResSize>> MRT;
0595
0596
0597
0598 llvm::SmallVector<int> NumScheduledMops;
0599
0600
0601
0602
0603 llvm::SmallVector<uint64_t, DefaultProcResSize> ProcResourceMasks;
0604 int InitiationInterval = 0;
0605
0606 int IssueWidth;
0607
0608 int calculateResMIIDFA() const;
0609
0610 bool isOverbooked() const;
0611
0612 void reserveResources(const MCSchedClassDesc *SCDesc, int Cycle);
0613
0614 void unreserveResources(const MCSchedClassDesc *SCDesc, int Cycle);
0615
0616
0617
0618
0619 int positiveModulo(int Dividend, int Divisor) const {
0620 assert(Divisor > 0);
0621 int R = Dividend % Divisor;
0622 if (R < 0)
0623 R += Divisor;
0624 return R;
0625 }
0626
0627 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
0628 LLVM_DUMP_METHOD void dumpMRT() const;
0629 #endif
0630
0631 public:
0632 ResourceManager(const TargetSubtargetInfo *ST, ScheduleDAGInstrs *DAG)
0633 : STI(ST), SM(ST->getSchedModel()), ST(ST), TII(ST->getInstrInfo()),
0634 DAG(DAG), UseDFA(ST->useDFAforSMS()),
0635 ProcResourceMasks(SM.getNumProcResourceKinds(), 0),
0636 IssueWidth(SM.IssueWidth) {
0637 initProcResourceVectors(SM, ProcResourceMasks);
0638 if (IssueWidth <= 0)
0639
0640 IssueWidth = 100;
0641 if (SwpForceIssueWidth > 0)
0642 IssueWidth = SwpForceIssueWidth;
0643 }
0644
0645 void initProcResourceVectors(const MCSchedModel &SM,
0646 SmallVectorImpl<uint64_t> &Masks);
0647
0648
0649
0650 bool canReserveResources(SUnit &SU, int Cycle);
0651
0652
0653
0654 void reserveResources(SUnit &SU, int Cycle);
0655
0656 int calculateResMII() const;
0657
0658
0659 void init(int II);
0660 };
0661
0662
0663
0664
0665
0666
0667
0668
0669
0670 class SMSchedule {
0671 private:
0672
0673 DenseMap<int, std::deque<SUnit *>> ScheduledInstrs;
0674
0675
0676 std::map<SUnit *, int> InstrToCycle;
0677
0678
0679
0680 int FirstCycle = 0;
0681
0682
0683 int LastCycle = 0;
0684
0685
0686 int InitiationInterval = 0;
0687
0688
0689 const TargetSubtargetInfo &ST;
0690
0691
0692 MachineRegisterInfo &MRI;
0693
0694 ResourceManager ProcItinResources;
0695
0696 public:
0697 SMSchedule(MachineFunction *mf, SwingSchedulerDAG *DAG)
0698 : ST(mf->getSubtarget()), MRI(mf->getRegInfo()),
0699 ProcItinResources(&ST, DAG) {}
0700
0701 void reset() {
0702 ScheduledInstrs.clear();
0703 InstrToCycle.clear();
0704 FirstCycle = 0;
0705 LastCycle = 0;
0706 InitiationInterval = 0;
0707 }
0708
0709
0710 void setInitiationInterval(int ii) {
0711 InitiationInterval = ii;
0712 ProcItinResources.init(ii);
0713 }
0714
0715
0716 int getInitiationInterval() const { return InitiationInterval; }
0717
0718
0719
0720 int getFirstCycle() const { return FirstCycle; }
0721
0722
0723 int getFinalCycle() const { return FirstCycle + InitiationInterval - 1; }
0724
0725
0726
0727 int earliestCycleInChain(const SwingSchedulerDDGEdge &Dep,
0728 const SwingSchedulerDDG *DDG);
0729
0730
0731
0732 int latestCycleInChain(const SwingSchedulerDDGEdge &Dep,
0733 const SwingSchedulerDDG *DDG);
0734
0735 void computeStart(SUnit *SU, int *MaxEarlyStart, int *MinLateStart, int II,
0736 SwingSchedulerDAG *DAG);
0737 bool insert(SUnit *SU, int StartCycle, int EndCycle, int II);
0738
0739
0740 using sched_iterator = DenseMap<int, std::deque<SUnit *>>::iterator;
0741 using const_sched_iterator =
0742 DenseMap<int, std::deque<SUnit *>>::const_iterator;
0743
0744
0745 bool isScheduledAtStage(SUnit *SU, unsigned StageNum) {
0746 return (stageScheduled(SU) == (int)StageNum);
0747 }
0748
0749
0750
0751 int stageScheduled(SUnit *SU) const {
0752 std::map<SUnit *, int>::const_iterator it = InstrToCycle.find(SU);
0753 if (it == InstrToCycle.end())
0754 return -1;
0755 return (it->second - FirstCycle) / InitiationInterval;
0756 }
0757
0758
0759
0760 unsigned cycleScheduled(SUnit *SU) const {
0761 std::map<SUnit *, int>::const_iterator it = InstrToCycle.find(SU);
0762 assert(it != InstrToCycle.end() && "Instruction hasn't been scheduled.");
0763 return (it->second - FirstCycle) % InitiationInterval;
0764 }
0765
0766
0767 unsigned getMaxStageCount() {
0768 return (LastCycle - FirstCycle) / InitiationInterval;
0769 }
0770
0771
0772 std::deque<SUnit *> &getInstructions(int cycle) {
0773 return ScheduledInstrs[cycle];
0774 }
0775
0776 SmallSet<SUnit *, 8>
0777 computeUnpipelineableNodes(SwingSchedulerDAG *SSD,
0778 TargetInstrInfo::PipelinerLoopInfo *PLI);
0779
0780 std::deque<SUnit *>
0781 reorderInstructions(const SwingSchedulerDAG *SSD,
0782 const std::deque<SUnit *> &Instrs) const;
0783
0784 bool
0785 normalizeNonPipelinedInstructions(SwingSchedulerDAG *SSD,
0786 TargetInstrInfo::PipelinerLoopInfo *PLI);
0787 bool isValidSchedule(SwingSchedulerDAG *SSD);
0788 void finalizeSchedule(SwingSchedulerDAG *SSD);
0789 void orderDependence(const SwingSchedulerDAG *SSD, SUnit *SU,
0790 std::deque<SUnit *> &Insts) const;
0791 bool isLoopCarried(const SwingSchedulerDAG *SSD, MachineInstr &Phi) const;
0792 bool isLoopCarriedDefOfUse(const SwingSchedulerDAG *SSD, MachineInstr *Def,
0793 MachineOperand &MO) const;
0794
0795 bool onlyHasLoopCarriedOutputOrOrderPreds(SUnit *SU,
0796 const SwingSchedulerDDG *DDG) const;
0797 void print(raw_ostream &os) const;
0798 void dump() const;
0799 };
0800
0801 }
0802
0803 #endif