File indexing completed on 2026-05-10 08:43:23
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef LLVM_CODEGEN_GLOBALISEL_CSEINFO_H
0013 #define LLVM_CODEGEN_GLOBALISEL_CSEINFO_H
0014
0015 #include "llvm/ADT/FoldingSet.h"
0016 #include "llvm/CodeGen/CSEConfigBase.h"
0017 #include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
0018 #include "llvm/CodeGen/GlobalISel/GISelWorkList.h"
0019 #include "llvm/CodeGen/MachineFunctionPass.h"
0020 #include "llvm/CodeGen/MachineRegisterInfo.h"
0021 #include "llvm/Support/Allocator.h"
0022 #include "llvm/Support/CodeGen.h"
0023
0024 namespace llvm {
0025 class MachineBasicBlock;
0026
0027
0028
0029
0030 class UniqueMachineInstr : public FoldingSetNode {
0031 friend class GISelCSEInfo;
0032 const MachineInstr *MI;
0033 explicit UniqueMachineInstr(const MachineInstr *MI) : MI(MI) {}
0034
0035 public:
0036 void Profile(FoldingSetNodeID &ID);
0037 };
0038
0039
0040 class CSEConfigFull : public CSEConfigBase {
0041 public:
0042 virtual ~CSEConfigFull() = default;
0043 bool shouldCSEOpc(unsigned Opc) override;
0044 };
0045
0046
0047 class CSEConfigConstantOnly : public CSEConfigBase {
0048 public:
0049 virtual ~CSEConfigConstantOnly() = default;
0050 bool shouldCSEOpc(unsigned Opc) override;
0051 };
0052
0053
0054
0055
0056
0057 std::unique_ptr<CSEConfigBase>
0058 getStandardCSEConfigForOpt(CodeGenOptLevel Level);
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070 class GISelCSEInfo : public GISelChangeObserver {
0071
0072 friend class CSEMIRBuilder;
0073
0074 BumpPtrAllocator UniqueInstrAllocator;
0075 FoldingSet<UniqueMachineInstr> CSEMap;
0076 MachineRegisterInfo *MRI = nullptr;
0077 MachineFunction *MF = nullptr;
0078 std::unique_ptr<CSEConfigBase> CSEOpt;
0079
0080
0081
0082
0083 DenseMap<const MachineInstr *, UniqueMachineInstr *> InstrMapping;
0084
0085
0086
0087
0088 GISelWorkList<8> TemporaryInsts;
0089
0090
0091 DenseMap<unsigned, unsigned> OpcodeHitTable;
0092
0093 bool isUniqueMachineInstValid(const UniqueMachineInstr &UMI) const;
0094
0095 void invalidateUniqueMachineInstr(UniqueMachineInstr *UMI);
0096
0097 UniqueMachineInstr *getNodeIfExists(FoldingSetNodeID &ID,
0098 MachineBasicBlock *MBB, void *&InsertPos);
0099
0100
0101 UniqueMachineInstr *getUniqueInstrForMI(const MachineInstr *MI);
0102
0103 void insertNode(UniqueMachineInstr *UMI, void *InsertPos = nullptr);
0104
0105
0106
0107 MachineInstr *getMachineInstrIfExists(FoldingSetNodeID &ID,
0108 MachineBasicBlock *MBB,
0109 void *&InsertPos);
0110
0111
0112
0113 void insertInstr(MachineInstr *MI, void *InsertPos = nullptr);
0114
0115 bool HandlingRecordedInstrs = false;
0116
0117 public:
0118 GISelCSEInfo() = default;
0119
0120 virtual ~GISelCSEInfo();
0121
0122 void setMF(MachineFunction &MF);
0123
0124 Error verify();
0125
0126
0127
0128
0129
0130
0131 void recordNewInstruction(MachineInstr *MI);
0132
0133
0134 void handleRecordedInst(MachineInstr *MI);
0135
0136
0137
0138
0139 void handleRecordedInsts();
0140
0141
0142
0143 void handleRemoveInst(MachineInstr *MI);
0144
0145 void releaseMemory();
0146
0147 void setCSEConfig(std::unique_ptr<CSEConfigBase> Opt) {
0148 CSEOpt = std::move(Opt);
0149 }
0150
0151 bool shouldCSE(unsigned Opc) const;
0152
0153 void analyze(MachineFunction &MF);
0154
0155 void countOpcodeHit(unsigned Opc);
0156
0157 void print();
0158
0159
0160 void erasingInstr(MachineInstr &MI) override;
0161 void createdInstr(MachineInstr &MI) override;
0162 void changingInstr(MachineInstr &MI) override;
0163 void changedInstr(MachineInstr &MI) override;
0164 };
0165
0166 class TargetRegisterClass;
0167 class RegisterBank;
0168
0169
0170 class GISelInstProfileBuilder {
0171 FoldingSetNodeID &ID;
0172 const MachineRegisterInfo &MRI;
0173
0174 public:
0175 GISelInstProfileBuilder(FoldingSetNodeID &ID, const MachineRegisterInfo &MRI)
0176 : ID(ID), MRI(MRI) {}
0177
0178 const GISelInstProfileBuilder &addNodeIDOpcode(unsigned Opc) const;
0179 const GISelInstProfileBuilder &addNodeIDRegType(const LLT Ty) const;
0180 const GISelInstProfileBuilder &addNodeIDRegType(const Register) const;
0181 const GISelInstProfileBuilder &
0182 addNodeIDRegType(MachineRegisterInfo::VRegAttrs) const;
0183
0184 const GISelInstProfileBuilder &
0185 addNodeIDRegType(const TargetRegisterClass *RC) const;
0186 const GISelInstProfileBuilder &addNodeIDRegType(const RegisterBank *RB) const;
0187
0188 const GISelInstProfileBuilder &addNodeIDRegNum(Register Reg) const;
0189
0190 const GISelInstProfileBuilder &addNodeIDReg(Register Reg) const;
0191
0192 const GISelInstProfileBuilder &addNodeIDImmediate(int64_t Imm) const;
0193 const GISelInstProfileBuilder &
0194 addNodeIDMBB(const MachineBasicBlock *MBB) const;
0195
0196 const GISelInstProfileBuilder &
0197 addNodeIDMachineOperand(const MachineOperand &MO) const;
0198
0199 const GISelInstProfileBuilder &addNodeIDFlag(unsigned Flag) const;
0200 const GISelInstProfileBuilder &addNodeID(const MachineInstr *MI) const;
0201 };
0202
0203
0204
0205
0206
0207 class GISelCSEAnalysisWrapper {
0208 GISelCSEInfo Info;
0209 MachineFunction *MF = nullptr;
0210 bool AlreadyComputed = false;
0211
0212 public:
0213
0214
0215
0216
0217 GISelCSEInfo &get(std::unique_ptr<CSEConfigBase> CSEOpt,
0218 bool ReCompute = false);
0219 void setMF(MachineFunction &MFunc) { MF = &MFunc; }
0220 void setComputed(bool Computed) { AlreadyComputed = Computed; }
0221 void releaseMemory() { Info.releaseMemory(); }
0222 };
0223
0224
0225 class GISelCSEAnalysisWrapperPass : public MachineFunctionPass {
0226 GISelCSEAnalysisWrapper Wrapper;
0227
0228 public:
0229 static char ID;
0230 GISelCSEAnalysisWrapperPass();
0231
0232 void getAnalysisUsage(AnalysisUsage &AU) const override;
0233
0234 const GISelCSEAnalysisWrapper &getCSEWrapper() const { return Wrapper; }
0235 GISelCSEAnalysisWrapper &getCSEWrapper() { return Wrapper; }
0236
0237 bool runOnMachineFunction(MachineFunction &MF) override;
0238
0239 void releaseMemory() override {
0240 Wrapper.releaseMemory();
0241 Wrapper.setComputed(false);
0242 }
0243 };
0244
0245 }
0246
0247 #endif