File indexing completed on 2026-05-10 08:43:29
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #ifndef LLVM_CODEGEN_LIVEINTERVALS_H
0020 #define LLVM_CODEGEN_LIVEINTERVALS_H
0021
0022 #include "llvm/ADT/ArrayRef.h"
0023 #include "llvm/ADT/IndexedMap.h"
0024 #include "llvm/ADT/SmallVector.h"
0025 #include "llvm/CodeGen/LiveInterval.h"
0026 #include "llvm/CodeGen/LiveIntervalCalc.h"
0027 #include "llvm/CodeGen/MachineBasicBlock.h"
0028 #include "llvm/CodeGen/MachineFunctionPass.h"
0029 #include "llvm/CodeGen/MachinePassManager.h"
0030 #include "llvm/CodeGen/SlotIndexes.h"
0031 #include "llvm/CodeGen/TargetRegisterInfo.h"
0032 #include "llvm/MC/LaneBitmask.h"
0033 #include "llvm/Support/CommandLine.h"
0034 #include "llvm/Support/Compiler.h"
0035 #include "llvm/Support/ErrorHandling.h"
0036 #include <cassert>
0037 #include <cstdint>
0038 #include <utility>
0039
0040 namespace llvm {
0041
0042 extern cl::opt<bool> UseSegmentSetForPhysRegs;
0043
0044 class BitVector;
0045 class MachineBlockFrequencyInfo;
0046 class MachineDominatorTree;
0047 class MachineFunction;
0048 class MachineInstr;
0049 class MachineRegisterInfo;
0050 class ProfileSummaryInfo;
0051 class raw_ostream;
0052 class TargetInstrInfo;
0053 class VirtRegMap;
0054
0055 class LiveIntervals {
0056 friend class LiveIntervalsAnalysis;
0057 friend class LiveIntervalsWrapperPass;
0058
0059 MachineFunction *MF = nullptr;
0060 MachineRegisterInfo *MRI = nullptr;
0061 const TargetRegisterInfo *TRI = nullptr;
0062 const TargetInstrInfo *TII = nullptr;
0063 SlotIndexes *Indexes = nullptr;
0064 MachineDominatorTree *DomTree = nullptr;
0065 std::unique_ptr<LiveIntervalCalc> LICalc;
0066
0067
0068 VNInfo::Allocator VNInfoAllocator;
0069
0070
0071 IndexedMap<LiveInterval *, VirtReg2IndexFunctor> VirtRegIntervals;
0072
0073
0074
0075 SmallVector<SlotIndex, 8> RegMaskSlots;
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088 SmallVector<const uint32_t *, 8> RegMaskBits;
0089
0090
0091
0092
0093
0094
0095 SmallVector<std::pair<unsigned, unsigned>, 8> RegMaskBlocks;
0096
0097
0098
0099 SmallVector<LiveRange *, 0> RegUnitRanges;
0100
0101
0102 LiveIntervals() = default;
0103 LiveIntervals(MachineFunction &MF, SlotIndexes &SI, MachineDominatorTree &DT)
0104 : Indexes(&SI), DomTree(&DT) {
0105 analyze(MF);
0106 }
0107
0108 void analyze(MachineFunction &MF);
0109
0110 void clear();
0111
0112 public:
0113 LiveIntervals(LiveIntervals &&) = default;
0114 ~LiveIntervals();
0115
0116 bool invalidate(MachineFunction &MF, const PreservedAnalyses &PA,
0117 MachineFunctionAnalysisManager::Invalidator &Inv);
0118
0119
0120
0121 static float getSpillWeight(bool isDef, bool isUse,
0122 const MachineBlockFrequencyInfo *MBFI,
0123 const MachineInstr &MI,
0124 ProfileSummaryInfo *PSI = nullptr);
0125
0126
0127
0128 static float getSpillWeight(bool isDef, bool isUse,
0129 const MachineBlockFrequencyInfo *MBFI,
0130 const MachineBasicBlock *MBB,
0131 ProfileSummaryInfo *PSI = nullptr);
0132
0133 LiveInterval &getInterval(Register Reg) {
0134 if (hasInterval(Reg))
0135 return *VirtRegIntervals[Reg.id()];
0136
0137 return createAndComputeVirtRegInterval(Reg);
0138 }
0139
0140 const LiveInterval &getInterval(Register Reg) const {
0141 return const_cast<LiveIntervals *>(this)->getInterval(Reg);
0142 }
0143
0144 bool hasInterval(Register Reg) const {
0145 return VirtRegIntervals.inBounds(Reg.id()) && VirtRegIntervals[Reg.id()];
0146 }
0147
0148
0149 LiveInterval &createEmptyInterval(Register Reg) {
0150 assert(!hasInterval(Reg) && "Interval already exists!");
0151 VirtRegIntervals.grow(Reg.id());
0152 VirtRegIntervals[Reg.id()] = createInterval(Reg);
0153 return *VirtRegIntervals[Reg.id()];
0154 }
0155
0156 LiveInterval &createAndComputeVirtRegInterval(Register Reg) {
0157 LiveInterval &LI = createEmptyInterval(Reg);
0158 computeVirtRegInterval(LI);
0159 return LI;
0160 }
0161
0162
0163
0164
0165 LiveInterval &getOrCreateEmptyInterval(Register Reg) {
0166 return hasInterval(Reg) ? getInterval(Reg) : createEmptyInterval(Reg);
0167 }
0168
0169
0170 void removeInterval(Register Reg) {
0171 delete VirtRegIntervals[Reg];
0172 VirtRegIntervals[Reg] = nullptr;
0173 }
0174
0175
0176
0177 LiveInterval::Segment addSegmentToEndOfBlock(Register Reg,
0178 MachineInstr &startInst);
0179
0180
0181
0182
0183
0184
0185
0186 bool shrinkToUses(LiveInterval *li,
0187 SmallVectorImpl<MachineInstr *> *dead = nullptr);
0188
0189
0190
0191
0192
0193
0194
0195 void shrinkToUses(LiveInterval::SubRange &SR, Register Reg);
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209 void extendToIndices(LiveRange &LR, ArrayRef<SlotIndex> Indices,
0210 ArrayRef<SlotIndex> Undefs);
0211
0212 void extendToIndices(LiveRange &LR, ArrayRef<SlotIndex> Indices) {
0213 extendToIndices(LR, Indices, {});
0214 }
0215
0216
0217
0218
0219
0220
0221
0222
0223 void pruneValue(LiveRange &LR, SlotIndex Kill,
0224 SmallVectorImpl<SlotIndex> *EndPoints);
0225
0226
0227
0228
0229
0230 LLVM_ATTRIBUTE_UNUSED void pruneValue(LiveInterval &, SlotIndex,
0231 SmallVectorImpl<SlotIndex> *) {
0232 llvm_unreachable(
0233 "Use pruneValue on the main LiveRange and on each subrange");
0234 }
0235
0236 SlotIndexes *getSlotIndexes() const { return Indexes; }
0237
0238
0239
0240 bool isNotInMIMap(const MachineInstr &Instr) const {
0241 return !Indexes->hasIndex(Instr);
0242 }
0243
0244
0245 SlotIndex getInstructionIndex(const MachineInstr &Instr) const {
0246 return Indexes->getInstructionIndex(Instr);
0247 }
0248
0249
0250 MachineInstr *getInstructionFromIndex(SlotIndex index) const {
0251 return Indexes->getInstructionFromIndex(index);
0252 }
0253
0254
0255 SlotIndex getMBBStartIdx(const MachineBasicBlock *mbb) const {
0256 return Indexes->getMBBStartIdx(mbb);
0257 }
0258
0259
0260 SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const {
0261 return Indexes->getMBBEndIdx(mbb);
0262 }
0263
0264 bool isLiveInToMBB(const LiveRange &LR, const MachineBasicBlock *mbb) const {
0265 return LR.liveAt(getMBBStartIdx(mbb));
0266 }
0267
0268 bool isLiveOutOfMBB(const LiveRange &LR, const MachineBasicBlock *mbb) const {
0269 return LR.liveAt(getMBBEndIdx(mbb).getPrevSlot());
0270 }
0271
0272 MachineBasicBlock *getMBBFromIndex(SlotIndex index) const {
0273 return Indexes->getMBBFromIndex(index);
0274 }
0275
0276 void insertMBBInMaps(MachineBasicBlock *MBB) {
0277 Indexes->insertMBBInMaps(MBB);
0278 assert(unsigned(MBB->getNumber()) == RegMaskBlocks.size() &&
0279 "Blocks must be added in order.");
0280 RegMaskBlocks.push_back(std::make_pair(RegMaskSlots.size(), 0));
0281 }
0282
0283 SlotIndex InsertMachineInstrInMaps(MachineInstr &MI) {
0284 return Indexes->insertMachineInstrInMaps(MI);
0285 }
0286
0287 void InsertMachineInstrRangeInMaps(MachineBasicBlock::iterator B,
0288 MachineBasicBlock::iterator E) {
0289 for (MachineBasicBlock::iterator I = B; I != E; ++I)
0290 Indexes->insertMachineInstrInMaps(*I);
0291 }
0292
0293 void RemoveMachineInstrFromMaps(MachineInstr &MI) {
0294 Indexes->removeMachineInstrFromMaps(MI);
0295 }
0296
0297 SlotIndex ReplaceMachineInstrInMaps(MachineInstr &MI, MachineInstr &NewMI) {
0298 return Indexes->replaceMachineInstrInMaps(MI, NewMI);
0299 }
0300
0301 VNInfo::Allocator &getVNInfoAllocator() { return VNInfoAllocator; }
0302
0303
0304 void print(raw_ostream &O) const;
0305 void dump() const;
0306
0307
0308 void reanalyze(MachineFunction &MF) {
0309 clear();
0310 analyze(MF);
0311 }
0312
0313 MachineDominatorTree &getDomTree() { return *DomTree; }
0314
0315
0316
0317 MachineBasicBlock *intervalIsInOneMBB(const LiveInterval &LI) const;
0318
0319
0320
0321 bool hasPHIKill(const LiveInterval &LI, const VNInfo *VNI) const;
0322
0323
0324 void addKillFlags(const VirtRegMap *);
0325
0326
0327
0328
0329
0330
0331 void handleMove(MachineInstr &MI, bool UpdateFlags = false);
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341 void handleMoveIntoNewBundle(MachineInstr &BundleStart,
0342 bool UpdateFlags = false);
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353 void repairIntervalsInRange(MachineBasicBlock *MBB,
0354 MachineBasicBlock::iterator Begin,
0355 MachineBasicBlock::iterator End,
0356 ArrayRef<Register> OrigRegs);
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371 ArrayRef<SlotIndex> getRegMaskSlots() const { return RegMaskSlots; }
0372
0373
0374
0375 ArrayRef<SlotIndex> getRegMaskSlotsInBlock(unsigned MBBNum) const {
0376 std::pair<unsigned, unsigned> P = RegMaskBlocks[MBBNum];
0377 return getRegMaskSlots().slice(P.first, P.second);
0378 }
0379
0380
0381
0382 ArrayRef<const uint32_t *> getRegMaskBits() const { return RegMaskBits; }
0383
0384
0385
0386 ArrayRef<const uint32_t *> getRegMaskBitsInBlock(unsigned MBBNum) const {
0387 std::pair<unsigned, unsigned> P = RegMaskBlocks[MBBNum];
0388 return getRegMaskBits().slice(P.first, P.second);
0389 }
0390
0391
0392
0393
0394
0395
0396
0397 bool checkRegMaskInterference(const LiveInterval &LI, BitVector &UsableRegs);
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412 LiveRange &getRegUnit(unsigned Unit) {
0413 LiveRange *LR = RegUnitRanges[Unit];
0414 if (!LR) {
0415
0416
0417 RegUnitRanges[Unit] = LR = new LiveRange(UseSegmentSetForPhysRegs);
0418 computeRegUnitRange(*LR, Unit);
0419 }
0420 return *LR;
0421 }
0422
0423
0424
0425 LiveRange *getCachedRegUnit(unsigned Unit) { return RegUnitRanges[Unit]; }
0426
0427 const LiveRange *getCachedRegUnit(unsigned Unit) const {
0428 return RegUnitRanges[Unit];
0429 }
0430
0431
0432
0433 void removeRegUnit(unsigned Unit) {
0434 delete RegUnitRanges[Unit];
0435 RegUnitRanges[Unit] = nullptr;
0436 }
0437
0438
0439
0440
0441
0442 void removeAllRegUnitsForPhysReg(MCRegister Reg) {
0443 for (MCRegUnit Unit : TRI->regunits(Reg))
0444 removeRegUnit(Unit);
0445 }
0446
0447
0448
0449
0450 void removePhysRegDefAt(MCRegister Reg, SlotIndex Pos);
0451
0452
0453
0454 void removeVRegDefAt(LiveInterval &LI, SlotIndex Pos);
0455
0456
0457 void splitSeparateComponents(LiveInterval &LI,
0458 SmallVectorImpl<LiveInterval *> &SplitLIs);
0459
0460
0461
0462
0463 void constructMainRangeFromSubranges(LiveInterval &LI);
0464
0465 private:
0466
0467 void computeVirtRegs();
0468
0469
0470 void computeRegMasks();
0471
0472
0473
0474
0475
0476
0477
0478
0479 bool computeDeadValues(LiveInterval &LI,
0480 SmallVectorImpl<MachineInstr *> *dead);
0481
0482 static LiveInterval *createInterval(Register Reg);
0483
0484 void printInstrs(raw_ostream &O) const;
0485 void dumpInstrs() const;
0486
0487 void computeLiveInRegUnits();
0488 void computeRegUnitRange(LiveRange &, unsigned Unit);
0489 bool computeVirtRegInterval(LiveInterval &);
0490
0491 using ShrinkToUsesWorkList = SmallVector<std::pair<SlotIndex, VNInfo *>, 16>;
0492 void extendSegmentsToUses(LiveRange &Segments, ShrinkToUsesWorkList &WorkList,
0493 Register Reg, LaneBitmask LaneMask);
0494
0495
0496
0497
0498
0499 void repairOldRegInRange(MachineBasicBlock::iterator Begin,
0500 MachineBasicBlock::iterator End,
0501 const SlotIndex endIdx, LiveRange &LR, Register Reg,
0502 LaneBitmask LaneMask = LaneBitmask::getAll());
0503
0504 class HMEditor;
0505 };
0506
0507 class LiveIntervalsAnalysis : public AnalysisInfoMixin<LiveIntervalsAnalysis> {
0508 friend AnalysisInfoMixin<LiveIntervalsAnalysis>;
0509 static AnalysisKey Key;
0510
0511 public:
0512 using Result = LiveIntervals;
0513 Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM);
0514 };
0515
0516 class LiveIntervalsPrinterPass
0517 : public PassInfoMixin<LiveIntervalsPrinterPass> {
0518 raw_ostream &OS;
0519
0520 public:
0521 explicit LiveIntervalsPrinterPass(raw_ostream &OS) : OS(OS) {}
0522 PreservedAnalyses run(MachineFunction &MF,
0523 MachineFunctionAnalysisManager &MFAM);
0524 static bool isRequired() { return true; }
0525 };
0526
0527 class LiveIntervalsWrapperPass : public MachineFunctionPass {
0528 LiveIntervals LIS;
0529
0530 public:
0531 static char ID;
0532
0533 LiveIntervalsWrapperPass();
0534
0535 void getAnalysisUsage(AnalysisUsage &AU) const override;
0536 void releaseMemory() override { LIS.clear(); }
0537
0538
0539 bool runOnMachineFunction(MachineFunction &) override;
0540
0541
0542 void print(raw_ostream &O, const Module * = nullptr) const override {
0543 LIS.print(O);
0544 }
0545
0546 LiveIntervals &getLIS() { return LIS; }
0547 };
0548
0549 }
0550
0551 #endif