From f6fdfb8d484b4e52cdb24a94a31b0f00d41a5eb7 Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Sat, 15 Aug 2026 00:38:20 +0800 Subject: [GlobalISel] Match LLVM CSE builder result semantics --- backend/include/rcc/CodeGen/GlobalISel/CSEInfo.h | 114 +++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 backend/include/rcc/CodeGen/GlobalISel/CSEInfo.h (limited to 'backend/include/rcc/CodeGen/GlobalISel/CSEInfo.h') diff --git a/backend/include/rcc/CodeGen/GlobalISel/CSEInfo.h b/backend/include/rcc/CodeGen/GlobalISel/CSEInfo.h new file mode 100644 index 0000000..27bc2a3 --- /dev/null +++ b/backend/include/rcc/CodeGen/GlobalISel/CSEInfo.h @@ -0,0 +1,114 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef RCC_CODEGEN_GLOBALISEL_CSEINFO_H +#define RCC_CODEGEN_GLOBALISEL_CSEINFO_H + +#include "rcc/ADT/APInt.h" +#include "rcc/CodeGen/CSEConfigBase.h" +#include "rcc/CodeGen/CommandFlags.h" +#include "rcc/CodeGen/GlobalISel/GISelChangeObserver.h" +#include "rcc/CodeGen/GlobalISel/GISelWorkList.h" +#include "rcc/CodeGen/LowLevelType.h" +#include "rcc/CodeGen/MachineIRTypes.h" +#include "rcc/CodeGen/Register.h" +#include "rcc/Support/Error.h" + +#include +#include +#include +#include +#include +#include + +namespace rcc { + +class MachineBasicBlock; +class MachineFunction; +class MachineInstr; +class MachineIRBuilderResult; + +class CSEConfigFull final : public CSEConfigBase { +public: + [[nodiscard]] bool shouldCSEOpcode(Opcode InstructionOpcode) const noexcept override; +}; + +class CSEConfigConstantOnly final : public CSEConfigBase { +public: + [[nodiscard]] bool shouldCSEOpcode(Opcode InstructionOpcode) const noexcept override; +}; + +[[nodiscard]] std::unique_ptr getStandardCSEConfigForOpt(OptimizationLevel Level); + +class GISelCSEInfo final : public GISelChangeObserver { +public: + GISelCSEInfo() = default; + GISelCSEInfo(const GISelCSEInfo &) = delete; + GISelCSEInfo &operator=(const GISelCSEInfo &) = delete; + ~GISelCSEInfo() override = default; + + void setCSEConfig(std::unique_ptr Config) noexcept; + [[nodiscard]] bool shouldCSE(Opcode InstructionOpcode) const noexcept; + [[nodiscard]] Expected analyze(MachineFunction &Function); + [[nodiscard]] Expected verify(); + void releaseMemory() noexcept; + + void erasingInstr(MachineInstr &Instruction) override; + void createdInstr(MachineInstr &Instruction) override; + void changingInstr(MachineInstr &Instruction) override; + void changedInstr(MachineInstr &Instruction) override; + +private: + struct CSEKey final { + const MachineBasicBlock *Block = nullptr; + Opcode InstructionOpcode; + std::vector Profile; + + friend bool operator==(const CSEKey &, const CSEKey &) = default; + }; + + struct CSEKeyHash final { + [[nodiscard]] std::size_t operator()(const CSEKey &Key) const noexcept; + }; + + [[nodiscard]] Expected appendRegisterProfile(std::vector &Profile, + Register Reg, bool IsDefinition) const; + [[nodiscard]] Expected appendResultProfile(std::vector &Profile, + const MachineIRBuilderResult &Result) const; + [[nodiscard]] Expected profileInstruction(const MachineInstr &Instruction) const; + [[nodiscard]] Expected profileBuilderInstruction( + Opcode InstructionOpcode, std::span Destinations, + std::span Sources, std::span Immediates, + MachineInstrFlags Flags, const MachineBasicBlock &Block) const; + [[nodiscard]] Expected profileConstant(const MachineIRBuilderResult &Destination, + const APInt &Value, + const MachineBasicBlock &Block) const; + + void recordNewInstruction(MachineInstr &Instruction); + [[nodiscard]] Expected handleRecordedInstruction(MachineInstr &Instruction); + [[nodiscard]] Expected handleRecordedInstructions(); + void handleRemoveInstruction(MachineInstr &Instruction) noexcept; + [[nodiscard]] Expected insertInstruction(MachineInstr &Instruction); + + [[nodiscard]] Expected getMachineInstrIfExists( + Opcode InstructionOpcode, std::span Destinations, + std::span Sources, std::span Immediates, + MachineInstrFlags Flags, MachineBasicBlock &Block); + [[nodiscard]] Expected + getConstantIfExists(const MachineIRBuilderResult &Destination, const APInt &Value, + MachineBasicBlock &Block); + void countOpcodeHit(Opcode InstructionOpcode) noexcept; + + MachineFunction *Function = nullptr; + std::unique_ptr Config; + std::unordered_map CSEMap; + std::unordered_map InstructionMapping; + GISelWorkList<8> TemporaryInstructions; + std::unordered_map OpcodeHitTable; + bool HandlingRecordedInstructions = false; + + friend class CSEMIRBuilder; +}; + +} // namespace rcc + +#endif // RCC_CODEGEN_GLOBALISEL_CSEINFO_H -- cgit v1.2.3