File indexing completed on 2026-05-10 08:43:34
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_CODEGEN_SCHEDULEDAGINSTRS_H
0015 #define LLVM_CODEGEN_SCHEDULEDAGINSTRS_H
0016
0017 #include "llvm/ADT/DenseMap.h"
0018 #include "llvm/ADT/PointerIntPair.h"
0019 #include "llvm/ADT/SmallVector.h"
0020 #include "llvm/ADT/SparseMultiSet.h"
0021 #include "llvm/ADT/identity.h"
0022 #include "llvm/Analysis/AliasAnalysis.h"
0023 #include "llvm/CodeGen/LiveRegUnits.h"
0024 #include "llvm/CodeGen/MachineBasicBlock.h"
0025 #include "llvm/CodeGen/ScheduleDAG.h"
0026 #include "llvm/CodeGen/TargetRegisterInfo.h"
0027 #include "llvm/CodeGen/TargetSchedule.h"
0028 #include "llvm/MC/LaneBitmask.h"
0029 #include <cassert>
0030 #include <cstdint>
0031 #include <list>
0032 #include <string>
0033 #include <utility>
0034 #include <vector>
0035
0036 namespace llvm {
0037
0038 class AAResults;
0039 class LiveIntervals;
0040 class MachineFrameInfo;
0041 class MachineFunction;
0042 class MachineInstr;
0043 class MachineLoopInfo;
0044 class MachineOperand;
0045 struct MCSchedClassDesc;
0046 class PressureDiffs;
0047 class PseudoSourceValue;
0048 class RegPressureTracker;
0049 class UndefValue;
0050 class Value;
0051
0052
0053 struct VReg2SUnit {
0054 unsigned VirtReg;
0055 LaneBitmask LaneMask;
0056 SUnit *SU;
0057
0058 VReg2SUnit(unsigned VReg, LaneBitmask LaneMask, SUnit *SU)
0059 : VirtReg(VReg), LaneMask(LaneMask), SU(SU) {}
0060
0061 unsigned getSparseSetIndex() const {
0062 return Register::virtReg2Index(VirtReg);
0063 }
0064 };
0065
0066
0067 struct VReg2SUnitOperIdx : public VReg2SUnit {
0068 unsigned OperandIndex;
0069
0070 VReg2SUnitOperIdx(unsigned VReg, LaneBitmask LaneMask,
0071 unsigned OperandIndex, SUnit *SU)
0072 : VReg2SUnit(VReg, LaneMask, SU), OperandIndex(OperandIndex) {}
0073 };
0074
0075
0076
0077 struct PhysRegSUOper {
0078 SUnit *SU;
0079 int OpIdx;
0080 unsigned RegUnit;
0081
0082 PhysRegSUOper(SUnit *su, int op, unsigned R)
0083 : SU(su), OpIdx(op), RegUnit(R) {}
0084
0085 unsigned getSparseSetIndex() const { return RegUnit; }
0086 };
0087
0088
0089
0090
0091 using RegUnit2SUnitsMap =
0092 SparseMultiSet<PhysRegSUOper, identity<unsigned>, uint16_t>;
0093
0094
0095
0096
0097 using VReg2SUnitMultiMap = SparseMultiSet<VReg2SUnit, VirtReg2IndexFunctor>;
0098
0099 using VReg2SUnitOperIdxMultiMap =
0100 SparseMultiSet<VReg2SUnitOperIdx, VirtReg2IndexFunctor>;
0101
0102 using ValueType = PointerUnion<const Value *, const PseudoSourceValue *>;
0103
0104 struct UnderlyingObject : PointerIntPair<ValueType, 1, bool> {
0105 UnderlyingObject(ValueType V, bool MayAlias)
0106 : PointerIntPair<ValueType, 1, bool>(V, MayAlias) {}
0107
0108 ValueType getValue() const { return getPointer(); }
0109 bool mayAlias() const { return getInt(); }
0110 };
0111
0112 using UnderlyingObjectsVector = SmallVector<UnderlyingObject, 4>;
0113
0114
0115 class ScheduleDAGInstrs : public ScheduleDAG {
0116 protected:
0117 const MachineLoopInfo *MLI = nullptr;
0118 const MachineFrameInfo &MFI;
0119
0120
0121 TargetSchedModel SchedModel;
0122
0123
0124
0125 bool RemoveKillFlags;
0126
0127
0128
0129
0130
0131
0132 bool CanHandleTerminators = false;
0133
0134
0135 bool TrackLaneMasks = false;
0136
0137
0138
0139
0140
0141 MachineBasicBlock *BB = nullptr;
0142
0143
0144 MachineBasicBlock::iterator RegionBegin;
0145
0146
0147 MachineBasicBlock::iterator RegionEnd;
0148
0149
0150 unsigned NumRegionInstrs = 0;
0151
0152
0153
0154 DenseMap<MachineInstr*, SUnit*> MISUnitMap;
0155
0156
0157
0158
0159
0160
0161
0162
0163 RegUnit2SUnitsMap Defs;
0164 RegUnit2SUnitsMap Uses;
0165
0166
0167
0168
0169 VReg2SUnitMultiMap CurrentVRegDefs;
0170
0171 VReg2SUnitOperIdxMultiMap CurrentVRegUses;
0172
0173 mutable std::optional<BatchAAResults> AAForDep;
0174
0175
0176
0177
0178 SUnit *BarrierChain = nullptr;
0179
0180 public:
0181
0182
0183
0184
0185
0186 using SUList = std::list<SUnit *>;
0187
0188
0189 enum DumpDirection {
0190 TopDown,
0191 BottomUp,
0192 Bidirectional,
0193 NotSet,
0194 };
0195
0196 void setDumpDirection(DumpDirection D) { DumpDir = D; }
0197
0198 protected:
0199 DumpDirection DumpDir = NotSet;
0200
0201
0202
0203 class Value2SUsMap;
0204
0205
0206 BatchAAResults *getAAForDep() const {
0207 if (AAForDep.has_value())
0208 return &AAForDep.value();
0209 return nullptr;
0210 }
0211
0212
0213
0214
0215
0216 void reduceHugeMemNodeMaps(Value2SUsMap &stores,
0217 Value2SUsMap &loads, unsigned N);
0218
0219
0220
0221 void addChainDependency(SUnit *SUa, SUnit *SUb,
0222 unsigned Latency = 0);
0223
0224
0225 void addChainDependencies(SUnit *SU, SUList &SUs, unsigned Latency) {
0226 for (SUnit *Entry : SUs)
0227 addChainDependency(SU, Entry, Latency);
0228 }
0229
0230
0231 void addChainDependencies(SUnit *SU, Value2SUsMap &Val2SUsMap);
0232
0233
0234 void addChainDependencies(SUnit *SU, Value2SUsMap &Val2SUsMap,
0235 ValueType V);
0236
0237
0238
0239
0240
0241
0242 void addBarrierChain(Value2SUsMap &map);
0243
0244
0245
0246
0247
0248 void insertBarrierChain(Value2SUsMap &map);
0249
0250
0251 UndefValue *UnknownValue;
0252
0253
0254
0255
0256 ScheduleDAGTopologicalSort Topo;
0257
0258 using DbgValueVector =
0259 std::vector<std::pair<MachineInstr *, MachineInstr *>>;
0260
0261
0262
0263 DbgValueVector DbgValues;
0264 MachineInstr *FirstDbgValue = nullptr;
0265
0266
0267 LiveRegUnits LiveRegs;
0268
0269 public:
0270 explicit ScheduleDAGInstrs(MachineFunction &mf,
0271 const MachineLoopInfo *mli,
0272 bool RemoveKillFlags = false);
0273
0274 ~ScheduleDAGInstrs() override = default;
0275
0276
0277 const TargetSchedModel *getSchedModel() const { return &SchedModel; }
0278
0279
0280 const MCSchedClassDesc *getSchedClass(SUnit *SU) const {
0281 if (!SU->SchedClass && SchedModel.hasInstrSchedModel())
0282 SU->SchedClass = SchedModel.resolveSchedClass(SU->getInstr());
0283 return SU->SchedClass;
0284 }
0285
0286
0287 bool IsReachable(SUnit *SU, SUnit *TargetSU) {
0288 return Topo.IsReachable(SU, TargetSU);
0289 }
0290
0291
0292 MachineBasicBlock::iterator begin() const { return RegionBegin; }
0293
0294
0295 MachineBasicBlock::iterator end() const { return RegionEnd; }
0296
0297
0298 SUnit *newSUnit(MachineInstr *MI);
0299
0300
0301 SUnit *getSUnit(MachineInstr *MI) const;
0302
0303
0304
0305
0306 virtual bool doMBBSchedRegionsTopDown() const { return false; }
0307
0308
0309 virtual void startBlock(MachineBasicBlock *BB);
0310
0311
0312 virtual void finishBlock();
0313
0314
0315
0316
0317
0318 virtual void enterRegion(MachineBasicBlock *bb,
0319 MachineBasicBlock::iterator begin,
0320 MachineBasicBlock::iterator end,
0321 unsigned regioninstrs);
0322
0323
0324 virtual void exitRegion();
0325
0326
0327
0328
0329
0330 void buildSchedGraph(AAResults *AA,
0331 RegPressureTracker *RPTracker = nullptr,
0332 PressureDiffs *PDiffs = nullptr,
0333 LiveIntervals *LIS = nullptr,
0334 bool TrackLaneMasks = false);
0335
0336
0337
0338
0339
0340
0341
0342
0343 void addSchedBarrierDeps();
0344
0345
0346
0347
0348
0349 virtual void schedule() = 0;
0350
0351
0352
0353 virtual void finalizeSchedule() {}
0354
0355 void dumpNode(const SUnit &SU) const override;
0356 void dump() const override;
0357
0358
0359 std::string getGraphNodeLabel(const SUnit *SU) const override;
0360
0361
0362 std::string getDAGName() const override;
0363
0364
0365 void fixupKills(MachineBasicBlock &MBB);
0366
0367
0368
0369 bool canAddEdge(SUnit *SuccSU, SUnit *PredSU);
0370
0371
0372
0373
0374
0375
0376 bool addEdge(SUnit *SuccSU, const SDep &PredDep);
0377
0378 protected:
0379 void initSUnits();
0380 void addPhysRegDataDeps(SUnit *SU, unsigned OperIdx);
0381 void addPhysRegDeps(SUnit *SU, unsigned OperIdx);
0382 void addVRegDefDeps(SUnit *SU, unsigned OperIdx);
0383 void addVRegUseDeps(SUnit *SU, unsigned OperIdx);
0384
0385
0386
0387 LaneBitmask getLaneMaskForMO(const MachineOperand &MO) const;
0388
0389
0390 bool deadDefHasNoUse(const MachineOperand &MO);
0391 };
0392
0393
0394 inline SUnit *ScheduleDAGInstrs::newSUnit(MachineInstr *MI) {
0395 #ifndef NDEBUG
0396 const SUnit *Addr = SUnits.empty() ? nullptr : &SUnits[0];
0397 #endif
0398 SUnits.emplace_back(MI, (unsigned)SUnits.size());
0399 assert((Addr == nullptr || Addr == &SUnits[0]) &&
0400 "SUnits std::vector reallocated on the fly!");
0401 return &SUnits.back();
0402 }
0403
0404
0405 inline SUnit *ScheduleDAGInstrs::getSUnit(MachineInstr *MI) const {
0406 return MISUnitMap.lookup(MI);
0407 }
0408
0409 }
0410
0411 #endif