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 #ifndef LLVM_CODEGEN_REACHINGDEFANALYSIS_H
0022 #define LLVM_CODEGEN_REACHINGDEFANALYSIS_H
0023
0024 #include "llvm/ADT/DenseMap.h"
0025 #include "llvm/ADT/SmallVector.h"
0026 #include "llvm/ADT/TinyPtrVector.h"
0027 #include "llvm/CodeGen/LoopTraversal.h"
0028 #include "llvm/CodeGen/MachineFunctionPass.h"
0029 #include "llvm/InitializePasses.h"
0030
0031 namespace llvm {
0032
0033 class MachineBasicBlock;
0034 class MachineInstr;
0035
0036
0037
0038
0039
0040 class ReachingDef {
0041 uintptr_t Encoded;
0042 friend struct PointerLikeTypeTraits<ReachingDef>;
0043 explicit ReachingDef(uintptr_t Encoded) : Encoded(Encoded) {}
0044
0045 public:
0046 ReachingDef(std::nullptr_t) : Encoded(0) {}
0047 ReachingDef(int Instr) : Encoded(((uintptr_t) Instr << 2) | 2) {}
0048 operator int() const { return ((int) Encoded) >> 2; }
0049 };
0050
0051 template<>
0052 struct PointerLikeTypeTraits<ReachingDef> {
0053 static constexpr int NumLowBitsAvailable = 1;
0054
0055 static inline void *getAsVoidPointer(const ReachingDef &RD) {
0056 return reinterpret_cast<void *>(RD.Encoded);
0057 }
0058
0059 static inline ReachingDef getFromVoidPointer(void *P) {
0060 return ReachingDef(reinterpret_cast<uintptr_t>(P));
0061 }
0062
0063 static inline ReachingDef getFromVoidPointer(const void *P) {
0064 return ReachingDef(reinterpret_cast<uintptr_t>(P));
0065 }
0066 };
0067
0068
0069 class MBBReachingDefsInfo {
0070 public:
0071 void init(unsigned NumBlockIDs) { AllReachingDefs.resize(NumBlockIDs); }
0072
0073 unsigned numBlockIDs() const { return AllReachingDefs.size(); }
0074
0075 void startBasicBlock(unsigned MBBNumber, unsigned NumRegUnits) {
0076 AllReachingDefs[MBBNumber].resize(NumRegUnits);
0077 }
0078
0079 void append(unsigned MBBNumber, unsigned Unit, int Def) {
0080 AllReachingDefs[MBBNumber][Unit].push_back(Def);
0081 }
0082
0083 void prepend(unsigned MBBNumber, unsigned Unit, int Def) {
0084 auto &Defs = AllReachingDefs[MBBNumber][Unit];
0085 Defs.insert(Defs.begin(), Def);
0086 }
0087
0088 void replaceFront(unsigned MBBNumber, unsigned Unit, int Def) {
0089 assert(!AllReachingDefs[MBBNumber][Unit].empty());
0090 *AllReachingDefs[MBBNumber][Unit].begin() = Def;
0091 }
0092
0093 void clear() { AllReachingDefs.clear(); }
0094
0095 ArrayRef<ReachingDef> defs(unsigned MBBNumber, unsigned Unit) const {
0096 if (AllReachingDefs[MBBNumber].empty())
0097
0098 return ArrayRef<ReachingDef>();
0099 return AllReachingDefs[MBBNumber][Unit];
0100 }
0101
0102 private:
0103
0104 using MBBRegUnitDefs = TinyPtrVector<ReachingDef>;
0105
0106 using MBBDefsInfo = std::vector<MBBRegUnitDefs>;
0107
0108
0109 SmallVector<MBBDefsInfo, 4> AllReachingDefs;
0110 };
0111
0112
0113 class ReachingDefAnalysis : public MachineFunctionPass {
0114 private:
0115 MachineFunction *MF = nullptr;
0116 const TargetRegisterInfo *TRI = nullptr;
0117 LoopTraversal::TraversalOrder TraversedMBBOrder;
0118 unsigned NumRegUnits = 0;
0119
0120
0121
0122
0123 using LiveRegsDefInfo = std::vector<int>;
0124 LiveRegsDefInfo LiveRegs;
0125
0126
0127
0128
0129 using OutRegsInfoMap = SmallVector<LiveRegsDefInfo, 4>;
0130 OutRegsInfoMap MBBOutRegsInfos;
0131
0132
0133
0134 int CurInstr = -1;
0135
0136
0137
0138 DenseMap<MachineInstr *, int> InstIds;
0139
0140 MBBReachingDefsInfo MBBReachingDefs;
0141
0142
0143 const int ReachingDefDefaultVal = -(1 << 21);
0144
0145 using InstSet = SmallPtrSetImpl<MachineInstr*>;
0146 using BlockSet = SmallPtrSetImpl<MachineBasicBlock*>;
0147
0148 public:
0149 static char ID;
0150
0151 ReachingDefAnalysis() : MachineFunctionPass(ID) {
0152 initializeReachingDefAnalysisPass(*PassRegistry::getPassRegistry());
0153 }
0154 void releaseMemory() override;
0155
0156 void getAnalysisUsage(AnalysisUsage &AU) const override {
0157 AU.setPreservesAll();
0158 MachineFunctionPass::getAnalysisUsage(AU);
0159 }
0160
0161 bool runOnMachineFunction(MachineFunction &MF) override;
0162
0163 MachineFunctionProperties getRequiredProperties() const override {
0164 return MachineFunctionProperties().set(
0165 MachineFunctionProperties::Property::NoVRegs).set(
0166 MachineFunctionProperties::Property::TracksLiveness);
0167 }
0168
0169
0170 void reset();
0171
0172
0173 void init();
0174
0175
0176 void traverse();
0177
0178
0179
0180 int getReachingDef(MachineInstr *MI, Register Reg) const;
0181
0182
0183 bool hasSameReachingDef(MachineInstr *A, MachineInstr *B, Register Reg) const;
0184
0185
0186
0187 bool isReachingDefLiveOut(MachineInstr *MI, Register Reg) const;
0188
0189
0190
0191 MachineInstr *getLocalLiveOutMIDef(MachineBasicBlock *MBB,
0192 Register Reg) const;
0193
0194
0195
0196 MachineInstr *getUniqueReachingMIDef(MachineInstr *MI, Register Reg) const;
0197
0198
0199
0200 MachineInstr *getMIOperand(MachineInstr *MI, unsigned Idx) const;
0201
0202
0203
0204 MachineInstr *getMIOperand(MachineInstr *MI, MachineOperand &MO) const;
0205
0206
0207
0208 bool hasLocalDefBefore(MachineInstr *MI, Register Reg) const;
0209
0210
0211
0212 bool isRegUsedAfter(MachineInstr *MI, Register Reg) const;
0213
0214
0215 bool isRegDefinedAfter(MachineInstr *MI, Register Reg) const;
0216
0217
0218
0219 int getClearance(MachineInstr *MI, Register Reg) const;
0220
0221
0222
0223 void getReachingLocalUses(MachineInstr *MI, Register Reg,
0224 InstSet &Uses) const;
0225
0226
0227
0228 void getLiveOuts(MachineBasicBlock *MBB, Register Reg, InstSet &Defs,
0229 BlockSet &VisitedBBs) const;
0230 void getLiveOuts(MachineBasicBlock *MBB, Register Reg, InstSet &Defs) const;
0231
0232
0233
0234
0235 bool getLiveInUses(MachineBasicBlock *MBB, Register Reg, InstSet &Uses) const;
0236
0237
0238
0239 void getGlobalUses(MachineInstr *MI, Register Reg, InstSet &Uses) const;
0240
0241
0242
0243 void getGlobalReachingDefs(MachineInstr *MI, Register Reg,
0244 InstSet &Defs) const;
0245
0246
0247 bool isSafeToMoveForwards(MachineInstr *From, MachineInstr *To) const;
0248
0249
0250 bool isSafeToMoveBackwards(MachineInstr *From, MachineInstr *To) const;
0251
0252
0253
0254 void collectKilledOperands(MachineInstr *MI, InstSet &Dead) const;
0255
0256
0257
0258 bool isSafeToRemove(MachineInstr *MI, InstSet &ToRemove) const;
0259
0260
0261
0262
0263 bool isSafeToRemove(MachineInstr *MI, InstSet &ToRemove,
0264 InstSet &Ignore) const;
0265
0266
0267
0268 bool isSafeToDefRegAt(MachineInstr *MI, Register Reg) const;
0269
0270
0271
0272
0273 bool isSafeToDefRegAt(MachineInstr *MI, Register Reg, InstSet &Ignore) const;
0274
0275 private:
0276
0277 void enterBasicBlock(MachineBasicBlock *MBB);
0278
0279
0280 void leaveBasicBlock(MachineBasicBlock *MBB);
0281
0282
0283 void processBasicBlock(const LoopTraversal::TraversedMBBInfo &TraversedMBB);
0284
0285
0286 void reprocessBasicBlock(MachineBasicBlock *MBB);
0287
0288
0289
0290 void processDefs(MachineInstr *);
0291
0292
0293 template<typename Iterator>
0294 bool isSafeToMove(MachineInstr *From, MachineInstr *To) const;
0295
0296
0297
0298
0299 bool isSafeToRemove(MachineInstr *MI, InstSet &Visited,
0300 InstSet &ToRemove, InstSet &Ignore) const;
0301
0302
0303
0304 MachineInstr *getInstFromId(MachineBasicBlock *MBB, int InstId) const;
0305
0306
0307
0308 MachineInstr *getReachingLocalMIDef(MachineInstr *MI, Register Reg) const;
0309 };
0310
0311 }
0312
0313 #endif