File indexing completed on 2026-05-10 08:43:33
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
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060 #ifndef LLVM_CODEGEN_MODULOSCHEDULE_H
0061 #define LLVM_CODEGEN_MODULOSCHEDULE_H
0062
0063 #include "llvm/CodeGen/MachineFunction.h"
0064 #include "llvm/CodeGen/MachineLoopUtils.h"
0065 #include "llvm/CodeGen/TargetInstrInfo.h"
0066 #include "llvm/CodeGen/TargetSubtargetInfo.h"
0067 #include <deque>
0068 #include <map>
0069 #include <vector>
0070
0071 namespace llvm {
0072 class MachineBasicBlock;
0073 class MachineLoop;
0074 class MachineRegisterInfo;
0075 class MachineInstr;
0076 class LiveIntervals;
0077
0078
0079
0080 class ModuloSchedule {
0081 private:
0082
0083 MachineLoop *Loop;
0084
0085
0086
0087
0088 std::vector<MachineInstr *> ScheduledInstrs;
0089
0090
0091 DenseMap<MachineInstr *, int> Cycle;
0092
0093
0094 DenseMap<MachineInstr *, int> Stage;
0095
0096
0097 int NumStages;
0098
0099 public:
0100
0101
0102
0103
0104
0105
0106
0107 ModuloSchedule(MachineFunction &MF, MachineLoop *Loop,
0108 std::vector<MachineInstr *> ScheduledInstrs,
0109 DenseMap<MachineInstr *, int> Cycle,
0110 DenseMap<MachineInstr *, int> Stage)
0111 : Loop(Loop), ScheduledInstrs(ScheduledInstrs), Cycle(std::move(Cycle)),
0112 Stage(std::move(Stage)) {
0113 NumStages = 0;
0114 for (auto &KV : this->Stage)
0115 NumStages = std::max(NumStages, KV.second);
0116 ++NumStages;
0117 }
0118
0119
0120 MachineLoop *getLoop() const { return Loop; }
0121
0122
0123
0124 int getNumStages() const { return NumStages; }
0125
0126
0127
0128 int getFirstCycle() { return Cycle[ScheduledInstrs.front()]; }
0129
0130
0131
0132 int getFinalCycle() { return Cycle[ScheduledInstrs.back()]; }
0133
0134
0135 int getStage(MachineInstr *MI) {
0136 auto I = Stage.find(MI);
0137 return I == Stage.end() ? -1 : I->second;
0138 }
0139
0140
0141 int getCycle(MachineInstr *MI) {
0142 auto I = Cycle.find(MI);
0143 return I == Cycle.end() ? -1 : I->second;
0144 }
0145
0146
0147 void setStage(MachineInstr *MI, int MIStage) {
0148 assert(Stage.count(MI) == 0);
0149 Stage[MI] = MIStage;
0150 }
0151
0152
0153 ArrayRef<MachineInstr *> getInstructions() { return ScheduledInstrs; }
0154
0155 void dump() { print(dbgs()); }
0156 void print(raw_ostream &OS);
0157 };
0158
0159
0160
0161 class ModuloScheduleExpander {
0162 public:
0163 using InstrChangesTy = DenseMap<MachineInstr *, std::pair<unsigned, int64_t>>;
0164
0165 private:
0166 using ValueMapTy = DenseMap<unsigned, unsigned>;
0167 using MBBVectorTy = SmallVectorImpl<MachineBasicBlock *>;
0168 using InstrMapTy = DenseMap<MachineInstr *, MachineInstr *>;
0169
0170 ModuloSchedule &Schedule;
0171 MachineFunction &MF;
0172 const TargetSubtargetInfo &ST;
0173 MachineRegisterInfo &MRI;
0174 const TargetInstrInfo *TII = nullptr;
0175 LiveIntervals &LIS;
0176
0177 MachineBasicBlock *BB = nullptr;
0178 MachineBasicBlock *Preheader = nullptr;
0179 MachineBasicBlock *NewKernel = nullptr;
0180 std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo> LoopInfo;
0181
0182
0183
0184
0185
0186 std::map<unsigned, std::pair<unsigned, bool>> RegToStageDiff;
0187
0188
0189 InstrChangesTy InstrChanges;
0190
0191 void generatePipelinedLoop();
0192 void generateProlog(unsigned LastStage, MachineBasicBlock *KernelBB,
0193 ValueMapTy *VRMap, MBBVectorTy &PrologBBs);
0194 void generateEpilog(unsigned LastStage, MachineBasicBlock *KernelBB,
0195 MachineBasicBlock *OrigBB, ValueMapTy *VRMap,
0196 ValueMapTy *VRMapPhi, MBBVectorTy &EpilogBBs,
0197 MBBVectorTy &PrologBBs);
0198 void generateExistingPhis(MachineBasicBlock *NewBB, MachineBasicBlock *BB1,
0199 MachineBasicBlock *BB2, MachineBasicBlock *KernelBB,
0200 ValueMapTy *VRMap, InstrMapTy &InstrMap,
0201 unsigned LastStageNum, unsigned CurStageNum,
0202 bool IsLast);
0203 void generatePhis(MachineBasicBlock *NewBB, MachineBasicBlock *BB1,
0204 MachineBasicBlock *BB2, MachineBasicBlock *KernelBB,
0205 ValueMapTy *VRMap, ValueMapTy *VRMapPhi,
0206 InstrMapTy &InstrMap, unsigned LastStageNum,
0207 unsigned CurStageNum, bool IsLast);
0208 void removeDeadInstructions(MachineBasicBlock *KernelBB,
0209 MBBVectorTy &EpilogBBs);
0210 void splitLifetimes(MachineBasicBlock *KernelBB, MBBVectorTy &EpilogBBs);
0211 void addBranches(MachineBasicBlock &PreheaderBB, MBBVectorTy &PrologBBs,
0212 MachineBasicBlock *KernelBB, MBBVectorTy &EpilogBBs,
0213 ValueMapTy *VRMap);
0214 bool computeDelta(MachineInstr &MI, unsigned &Delta);
0215 void updateMemOperands(MachineInstr &NewMI, MachineInstr &OldMI,
0216 unsigned Num);
0217 MachineInstr *cloneInstr(MachineInstr *OldMI, unsigned CurStageNum,
0218 unsigned InstStageNum);
0219 MachineInstr *cloneAndChangeInstr(MachineInstr *OldMI, unsigned CurStageNum,
0220 unsigned InstStageNum);
0221 void updateInstruction(MachineInstr *NewMI, bool LastDef,
0222 unsigned CurStageNum, unsigned InstrStageNum,
0223 ValueMapTy *VRMap);
0224 MachineInstr *findDefInLoop(unsigned Reg);
0225 unsigned getPrevMapVal(unsigned StageNum, unsigned PhiStage, unsigned LoopVal,
0226 unsigned LoopStage, ValueMapTy *VRMap,
0227 MachineBasicBlock *BB);
0228 void rewritePhiValues(MachineBasicBlock *NewBB, unsigned StageNum,
0229 ValueMapTy *VRMap, InstrMapTy &InstrMap);
0230 void rewriteScheduledInstr(MachineBasicBlock *BB, InstrMapTy &InstrMap,
0231 unsigned CurStageNum, unsigned PhiNum,
0232 MachineInstr *Phi, unsigned OldReg,
0233 unsigned NewReg, unsigned PrevReg = 0);
0234 bool isLoopCarried(MachineInstr &Phi);
0235
0236
0237
0238 unsigned getStagesForReg(int Reg, unsigned CurStage) {
0239 std::pair<unsigned, bool> Stages = RegToStageDiff[Reg];
0240 if ((int)CurStage > Schedule.getNumStages() - 1 && Stages.first == 0 &&
0241 Stages.second)
0242 return 1;
0243 return Stages.first;
0244 }
0245
0246
0247
0248
0249
0250
0251
0252 unsigned getStagesForPhi(int Reg) {
0253 std::pair<unsigned, bool> Stages = RegToStageDiff[Reg];
0254 if (Stages.second)
0255 return Stages.first;
0256 return Stages.first - 1;
0257 }
0258
0259 public:
0260
0261
0262
0263
0264
0265 ModuloScheduleExpander(MachineFunction &MF, ModuloSchedule &S,
0266 LiveIntervals &LIS, InstrChangesTy InstrChanges)
0267 : Schedule(S), MF(MF), ST(MF.getSubtarget()), MRI(MF.getRegInfo()),
0268 TII(ST.getInstrInfo()), LIS(LIS),
0269 InstrChanges(std::move(InstrChanges)) {}
0270
0271
0272 void expand();
0273
0274 void cleanup();
0275
0276
0277
0278 MachineBasicBlock *getRewrittenKernel() { return NewKernel; }
0279 };
0280
0281
0282
0283 class PeelingModuloScheduleExpander {
0284 public:
0285 PeelingModuloScheduleExpander(MachineFunction &MF, ModuloSchedule &S,
0286 LiveIntervals *LIS)
0287 : Schedule(S), MF(MF), ST(MF.getSubtarget()), MRI(MF.getRegInfo()),
0288 TII(ST.getInstrInfo()), LIS(LIS) {}
0289
0290 void expand();
0291
0292
0293
0294 void validateAgainstModuloScheduleExpander();
0295
0296 protected:
0297 ModuloSchedule &Schedule;
0298 MachineFunction &MF;
0299 const TargetSubtargetInfo &ST;
0300 MachineRegisterInfo &MRI;
0301 const TargetInstrInfo *TII = nullptr;
0302 LiveIntervals *LIS = nullptr;
0303
0304
0305 MachineBasicBlock *BB = nullptr;
0306
0307 MachineBasicBlock *Preheader = nullptr;
0308
0309 SmallVector<MachineBasicBlock *, 4> Prologs, Epilogs;
0310
0311 DenseMap<MachineBasicBlock *, BitVector> LiveStages;
0312
0313
0314
0315 DenseMap<MachineBasicBlock *, BitVector> AvailableStages;
0316
0317
0318 DenseMap<MachineInstr *, unsigned> PhiNodeLoopIteration;
0319
0320
0321
0322 DenseMap<MachineInstr *, MachineInstr *> CanonicalMIs;
0323 DenseMap<std::pair<MachineBasicBlock *, MachineInstr *>, MachineInstr *>
0324 BlockMIs;
0325
0326
0327 std::deque<MachineBasicBlock *> PeeledFront, PeeledBack;
0328
0329 SmallVector<MachineInstr *, 4> IllegalPhisToDelete;
0330
0331
0332
0333 void rewriteKernel();
0334
0335
0336
0337 MachineBasicBlock *peelKernel(LoopPeelDirection LPD);
0338
0339
0340 void filterInstructions(MachineBasicBlock *MB, int MinStage);
0341
0342
0343 void moveStageBetweenBlocks(MachineBasicBlock *DestBB,
0344 MachineBasicBlock *SourceBB, unsigned Stage);
0345
0346
0347 void peelPrologAndEpilogs();
0348
0349
0350 Register getEquivalentRegisterIn(Register Reg, MachineBasicBlock *BB);
0351
0352
0353 void rewriteUsesOf(MachineInstr *MI);
0354
0355 void fixupBranches();
0356
0357
0358
0359 MachineBasicBlock *CreateLCSSAExitingBlock();
0360
0361 unsigned getStage(MachineInstr *MI) {
0362 if (auto It = CanonicalMIs.find(MI); It != CanonicalMIs.end())
0363 MI = It->second;
0364 return Schedule.getStage(MI);
0365 }
0366
0367
0368 Register getPhiCanonicalReg(MachineInstr* CanonicalPhi, MachineInstr* Phi);
0369
0370 std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo> LoopInfo;
0371 };
0372
0373
0374
0375 class ModuloScheduleExpanderMVE {
0376 private:
0377 using ValueMapTy = DenseMap<unsigned, unsigned>;
0378 using MBBVectorTy = SmallVectorImpl<MachineBasicBlock *>;
0379 using InstrMapTy = DenseMap<MachineInstr *, MachineInstr *>;
0380
0381 ModuloSchedule &Schedule;
0382 MachineFunction &MF;
0383 const TargetSubtargetInfo &ST;
0384 MachineRegisterInfo &MRI;
0385 const TargetInstrInfo *TII = nullptr;
0386 LiveIntervals &LIS;
0387
0388 MachineBasicBlock *OrigKernel = nullptr;
0389 MachineBasicBlock *OrigPreheader = nullptr;
0390 MachineBasicBlock *OrigExit = nullptr;
0391 MachineBasicBlock *Check = nullptr;
0392 MachineBasicBlock *Prolog = nullptr;
0393 MachineBasicBlock *NewKernel = nullptr;
0394 MachineBasicBlock *Epilog = nullptr;
0395 MachineBasicBlock *NewPreheader = nullptr;
0396 MachineBasicBlock *NewExit = nullptr;
0397 std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo> LoopInfo;
0398
0399
0400
0401 int NumUnroll;
0402
0403 void calcNumUnroll();
0404 void generatePipelinedLoop();
0405 void generateProlog(SmallVectorImpl<ValueMapTy> &VRMap);
0406 void generatePhi(MachineInstr *OrigMI, int UnrollNum,
0407 SmallVectorImpl<ValueMapTy> &PrologVRMap,
0408 SmallVectorImpl<ValueMapTy> &KernelVRMap,
0409 SmallVectorImpl<ValueMapTy> &PhiVRMap);
0410 void generateKernel(SmallVectorImpl<ValueMapTy> &PrologVRMap,
0411 SmallVectorImpl<ValueMapTy> &KernelVRMap,
0412 InstrMapTy &LastStage0Insts);
0413 void generateEpilog(SmallVectorImpl<ValueMapTy> &KernelVRMap,
0414 SmallVectorImpl<ValueMapTy> &EpilogVRMap,
0415 InstrMapTy &LastStage0Insts);
0416 void mergeRegUsesAfterPipeline(Register OrigReg, Register NewReg);
0417
0418 MachineInstr *cloneInstr(MachineInstr *OldMI);
0419
0420 void updateInstrDef(MachineInstr *NewMI, ValueMapTy &VRMap, bool LastDef);
0421
0422 void generateKernelPhi(Register OrigLoopVal, Register NewLoopVal,
0423 unsigned UnrollNum,
0424 SmallVectorImpl<ValueMapTy> &VRMapProlog,
0425 SmallVectorImpl<ValueMapTy> &VRMapPhi);
0426 void updateInstrUse(MachineInstr *MI, int StageNum, int PhaseNum,
0427 SmallVectorImpl<ValueMapTy> &CurVRMap,
0428 SmallVectorImpl<ValueMapTy> *PrevVRMap);
0429
0430 void insertCondBranch(MachineBasicBlock &MBB, int RequiredTC,
0431 InstrMapTy &LastStage0Insts,
0432 MachineBasicBlock &GreaterThan,
0433 MachineBasicBlock &Otherwise);
0434
0435 public:
0436 ModuloScheduleExpanderMVE(MachineFunction &MF, ModuloSchedule &S,
0437 LiveIntervals &LIS)
0438 : Schedule(S), MF(MF), ST(MF.getSubtarget()), MRI(MF.getRegInfo()),
0439 TII(ST.getInstrInfo()), LIS(LIS) {}
0440
0441 void expand();
0442 static bool canApply(MachineLoop &L);
0443 };
0444
0445
0446
0447
0448
0449
0450
0451 class ModuloScheduleTestAnnotater {
0452 MachineFunction &MF;
0453 ModuloSchedule &S;
0454
0455 public:
0456 ModuloScheduleTestAnnotater(MachineFunction &MF, ModuloSchedule &S)
0457 : MF(MF), S(S) {}
0458
0459
0460 void annotate();
0461 };
0462
0463 }
0464
0465 #endif