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/CSEConfigBase.h | 21 +++ backend/include/rcc/CodeGen/GlobalISel/CSEInfo.h | 114 ++++++++++++++++ .../include/rcc/CodeGen/GlobalISel/CSEMIRBuilder.h | 43 ++++++ .../rcc/CodeGen/GlobalISel/GISelChangeObserver.h | 6 +- .../rcc/CodeGen/GlobalISel/GenericMachineInstrs.h | 7 +- .../GlobalISel/LegalizationArtifactCombiner.h | 28 ++-- backend/include/rcc/CodeGen/GlobalISel/Legalizer.h | 12 +- .../rcc/CodeGen/GlobalISel/LegalizerHelper.h | 4 + .../include/rcc/CodeGen/GlobalISel/LegalizerInfo.h | 1 + backend/include/rcc/CodeGen/MachineIRBuilder.h | 146 +++++++++++++++------ 10 files changed, 320 insertions(+), 62 deletions(-) create mode 100644 backend/include/rcc/CodeGen/CSEConfigBase.h create mode 100644 backend/include/rcc/CodeGen/GlobalISel/CSEInfo.h create mode 100644 backend/include/rcc/CodeGen/GlobalISel/CSEMIRBuilder.h (limited to 'backend/include/rcc/CodeGen') diff --git a/backend/include/rcc/CodeGen/CSEConfigBase.h b/backend/include/rcc/CodeGen/CSEConfigBase.h new file mode 100644 index 0000000..68aa26e --- /dev/null +++ b/backend/include/rcc/CodeGen/CSEConfigBase.h @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef RCC_CODEGEN_CSECONFIGBASE_H +#define RCC_CODEGEN_CSECONFIGBASE_H + +#include "rcc/CodeGen/MachineIRTypes.h" + +namespace rcc { + +class CSEConfigBase { +public: + virtual ~CSEConfigBase() = default; + + [[nodiscard]] virtual bool shouldCSEOpcode(Opcode) const noexcept { + return false; + } +}; + +} // namespace rcc + +#endif // RCC_CODEGEN_CSECONFIGBASE_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 diff --git a/backend/include/rcc/CodeGen/GlobalISel/CSEMIRBuilder.h b/backend/include/rcc/CodeGen/GlobalISel/CSEMIRBuilder.h new file mode 100644 index 0000000..1adf474 --- /dev/null +++ b/backend/include/rcc/CodeGen/GlobalISel/CSEMIRBuilder.h @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef RCC_CODEGEN_GLOBALISEL_CSEMIRBUILDER_H +#define RCC_CODEGEN_GLOBALISEL_CSEMIRBUILDER_H + +#include "rcc/CodeGen/MachineIRBuilder.h" + +#include +#include + +namespace rcc { + +class CSEMIRBuilder final : public MachineIRBuilder { +public: + using MachineIRBuilder::buildConstant; + using MachineIRBuilder::buildInstr; + using MachineIRBuilder::MachineIRBuilder; + + [[nodiscard]] Expected + buildInstr(Opcode InstructionOpcode, std::span Destinations, + std::span Sources) const override; + [[nodiscard]] Expected buildConstant(MachineIRBuilderResult Destination, + APInt Value) const override; + [[nodiscard]] Expected buildSExtInReg(MachineIRBuilderResult Destination, + Register Source, + std::uint32_t Width) const override; + [[nodiscard]] Expected buildExtract(MachineIRBuilderResult Destination, + Register Source, + std::uint64_t Offset) const override; + +private: + [[nodiscard]] bool canPerformCSE(Opcode InstructionOpcode) const noexcept; + [[nodiscard]] bool dominatesInsertionPoint(const MachineInstr &Instruction) const noexcept; + [[nodiscard]] Expected makeInstructionDominate(MachineInstr &Instruction) const; + [[nodiscard]] Expected + generateCopyIfRequired(const MachineIRBuilderResult &Destination, + MachineInstr &Instruction) const; + [[nodiscard]] Expected memoize(MachineInstr &Instruction) const; +}; + +} // namespace rcc + +#endif // RCC_CODEGEN_GLOBALISEL_CSEMIRBUILDER_H diff --git a/backend/include/rcc/CodeGen/GlobalISel/GISelChangeObserver.h b/backend/include/rcc/CodeGen/GlobalISel/GISelChangeObserver.h index 9538f20..cc0c5a0 100644 --- a/backend/include/rcc/CodeGen/GlobalISel/GISelChangeObserver.h +++ b/backend/include/rcc/CodeGen/GlobalISel/GISelChangeObserver.h @@ -22,8 +22,7 @@ public: virtual void changedInstr(MachineInstr &Instruction) = 0; }; -class GISelObserverWrapper final : public MachineFunction::Delegate, - public GISelChangeObserver { +class GISelObserverWrapper final : public MachineFunction::Delegate, public GISelChangeObserver { public: GISelObserverWrapper() = default; explicit GISelObserverWrapper(GISelChangeObserver &Observer) { @@ -50,8 +49,7 @@ private: class MachineFunctionDelegateInstaller final { public: - MachineFunctionDelegateInstaller(MachineFunction &Function, - MachineFunction::Delegate &Delegate); + MachineFunctionDelegateInstaller(MachineFunction &Function, MachineFunction::Delegate &Delegate); MachineFunctionDelegateInstaller(const MachineFunctionDelegateInstaller &) = delete; MachineFunctionDelegateInstaller &operator=(const MachineFunctionDelegateInstaller &) = delete; ~MachineFunctionDelegateInstaller(); diff --git a/backend/include/rcc/CodeGen/GlobalISel/GenericMachineInstrs.h b/backend/include/rcc/CodeGen/GlobalISel/GenericMachineInstrs.h index d0a176d..ea3532c 100644 --- a/backend/include/rcc/CodeGen/GlobalISel/GenericMachineInstrs.h +++ b/backend/include/rcc/CodeGen/GlobalISel/GenericMachineInstrs.h @@ -20,7 +20,9 @@ public: [[nodiscard]] Register getReg(std::size_t Index) const { const MachineOperand *Operand = operandAt(Index); assert(Operand != nullptr && Operand->isRegister()); - return *Operand->registerValue(); + const Register *Reg = Operand->getIf(); + assert(Reg != nullptr); + return *Reg; } [[nodiscard]] static bool classof(const MachineInstr *Instruction) noexcept { @@ -99,8 +101,7 @@ template } template -[[nodiscard]] const InstructionT & -castGenericMachineInstr(const MachineInstr &Instruction) { +[[nodiscard]] const InstructionT &castGenericMachineInstr(const MachineInstr &Instruction) { assert(InstructionT::classof(&Instruction)); return static_cast(Instruction); } diff --git a/backend/include/rcc/CodeGen/GlobalISel/LegalizationArtifactCombiner.h b/backend/include/rcc/CodeGen/GlobalISel/LegalizationArtifactCombiner.h index 7e2961d..c0c7be0 100644 --- a/backend/include/rcc/CodeGen/GlobalISel/LegalizationArtifactCombiner.h +++ b/backend/include/rcc/CodeGen/GlobalISel/LegalizationArtifactCombiner.h @@ -101,8 +101,11 @@ public: break; case GenericOpcode::G_TRUNC: Changed = tryCombineTrunc(Instruction, DeadInstructions, UpdatedDefs, Observer); - if (Changed && !*Changed) - UpdatedDefs.push_back(*Instruction.operandAt(0)->registerValue()); + if (Changed && !*Changed) { + const Register *Destination = Instruction.operandAt(0)->getIf(); + assert(Destination != nullptr); + UpdatedDefs.push_back(*Destination); + } break; } if (!Changed) @@ -377,11 +380,11 @@ private: } } - [[nodiscard]] Expected isInstUnsupported(LegalizationQuery Query) const { + [[nodiscard]] Expected isInstUnsupported(const LegalizationQuery &Query) const { return LI.isUnsupported(Query); } - [[nodiscard]] Expected isInstLegal(LegalizationQuery Query) const { + [[nodiscard]] Expected isInstLegal(const LegalizationQuery &Query) const { return LI.isLegal(Query); } }; @@ -438,12 +441,15 @@ inline Expected LegalizationArtifactCombiner::buildConstant(Register Desti inline Expected LegalizationArtifactCombiner::buildConstant(LowLevelType Type, APInt Value) { - auto Destination = MRI.createVirtualRegister(Type); - if (!Destination) - return std::unexpected(Destination.error()); - auto Built = buildConstant(*Destination, std::move(Value)); + auto Built = Builder.buildConstant(Type, std::move(Value)); if (!Built) return std::unexpected(Built.error()); + const MachineOperand *Definition = (*Built)->operandAt(0); + const Register *Destination = Definition == nullptr ? nullptr : Definition->getIf(); + if (Destination == nullptr || !Definition->isDef()) { + return makeUnexpected(ErrorCode::InternalError, + "constant builder returned an instruction without a register definition"); + } return *Destination; } @@ -1309,7 +1315,11 @@ inline Expected LegalizationArtifactCombiner::tryCombineUnmergeValues( Destinations.reserve(NewDefCount); for (std::size_t Index = 0; Index < NewDefCount; ++Index) Destinations.push_back(Unmerge.getReg(SourceIndex * NewDefCount + Index)); - Register SplitSource = *registerOperand(*Merge, SourceIndex + 1); + const auto SplitSourceOperand = registerOperand(*Merge, SourceIndex + 1); + if (!SplitSourceOperand) + return makeUnexpected(ErrorCode::VerificationError, + "merge source is not a register operand"); + Register SplitSource = SplitSourceOperand.value(); if (ConvertOpcode) { auto ConvertedType = divideType(*OperandType, MergeSourceCount); if (!ConvertedType) diff --git a/backend/include/rcc/CodeGen/GlobalISel/Legalizer.h b/backend/include/rcc/CodeGen/GlobalISel/Legalizer.h index dfeda22..358ed1a 100644 --- a/backend/include/rcc/CodeGen/GlobalISel/Legalizer.h +++ b/backend/include/rcc/CodeGen/GlobalISel/Legalizer.h @@ -3,6 +3,7 @@ #ifndef RCC_CODEGEN_GLOBALISEL_LEGALIZER_H #define RCC_CODEGEN_GLOBALISEL_LEGALIZER_H +#include "rcc/CodeGen/CommandFlags.h" #include "rcc/CodeGen/GlobalISel/LegalizerInfo.h" #include "rcc/CodeGen/MachinePassManager.h" @@ -12,10 +13,12 @@ namespace rcc { class Legalizer final : public MachineFunctionPass { public: - explicit Legalizer(const LegalizerInfo *Info) : Info(Info) {} - explicit Legalizer(const LegalizerInfo &Info) : Info(&Info) {} - explicit Legalizer(std::unique_ptr Info) - : OwnedInfo(std::move(Info)), Info(OwnedInfo.get()) {} + Legalizer(const LegalizerInfo *Info, OptimizationLevel Optimization) + : Info(Info), Optimization(Optimization) {} + Legalizer(const LegalizerInfo &Info, OptimizationLevel Optimization) + : Info(&Info), Optimization(Optimization) {} + Legalizer(std::unique_ptr Info, OptimizationLevel Optimization) + : OwnedInfo(std::move(Info)), Info(OwnedInfo.get()), Optimization(Optimization) {} [[nodiscard]] const MachinePassContract &contract() const noexcept override; [[nodiscard]] Expected run(MachineFunction &Function, @@ -29,6 +32,7 @@ private: std::unique_ptr OwnedInfo; const LegalizerInfo *Info = nullptr; + OptimizationLevel Optimization; }; } // namespace rcc diff --git a/backend/include/rcc/CodeGen/GlobalISel/LegalizerHelper.h b/backend/include/rcc/CodeGen/GlobalISel/LegalizerHelper.h index 0fdc89f..ece0793 100644 --- a/backend/include/rcc/CodeGen/GlobalISel/LegalizerHelper.h +++ b/backend/include/rcc/CodeGen/GlobalISel/LegalizerHelper.h @@ -70,6 +70,10 @@ private: LowLevelType NarrowType); [[nodiscard]] Expected narrowScalarExt(MachineInstr &Instruction, std::size_t TypeIndex, LowLevelType NarrowType); + [[nodiscard]] Expected widenScalarAddSubOverflow(MachineInstr &Instruction, + std::size_t TypeIndex, + LowLevelType WideType); + [[nodiscard]] Expected lowerSignedAddSubOverflow(MachineInstr &Instruction); MachineFunction &Function; MachineRegisterInfo &MRI; diff --git a/backend/include/rcc/CodeGen/GlobalISel/LegalizerInfo.h b/backend/include/rcc/CodeGen/GlobalISel/LegalizerInfo.h index 5deefd4..3433e3a 100644 --- a/backend/include/rcc/CodeGen/GlobalISel/LegalizerInfo.h +++ b/backend/include/rcc/CodeGen/GlobalISel/LegalizerInfo.h @@ -137,6 +137,7 @@ public: std::initializer_list> Types); LegalizeRuleSet &legalForTypesWithMemDesc(std::initializer_list Rules); + LegalizeRuleSet &custom(); LegalizeRuleSet &widenScalarToNextPow2(std::size_t TypeIndex, std::uint32_t MinimumBitWidth = 0); LegalizeRuleSet &minScalar(std::size_t TypeIndex, LowLevelType MinimumType); LegalizeRuleSet &minScalar(bool Enabled, std::size_t TypeIndex, LowLevelType MinimumType); diff --git a/backend/include/rcc/CodeGen/MachineIRBuilder.h b/backend/include/rcc/CodeGen/MachineIRBuilder.h index e830837..f87adfe 100644 --- a/backend/include/rcc/CodeGen/MachineIRBuilder.h +++ b/backend/include/rcc/CodeGen/MachineIRBuilder.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -24,7 +25,9 @@ class MachineBasicBlock; class MachineFunction; class MachineInstr; class MachineMemOperand; +class MachineRegisterInfo; class RegisterMask; +class GISelCSEInfo; class MachineInstrBuilder final { public: @@ -143,7 +146,32 @@ private: friend class MachineIRBuilder; }; -class MachineIRBuilder final { +class MachineIRBuilderResult final { +public: + enum class Kind : std::uint8_t { + Register, + Type, + }; + + MachineIRBuilderResult(Register Reg) noexcept : Reg(Reg), ResultKind(Kind::Register) {} + MachineIRBuilderResult(LowLevelType Type) noexcept : Type(Type), ResultKind(Kind::Type) {} + + [[nodiscard]] Kind kind() const noexcept { + return ResultKind; + } + + [[nodiscard]] Register reg() const noexcept; + [[nodiscard]] LowLevelType type() const noexcept; + [[nodiscard]] Expected type(const MachineRegisterInfo &MRI) const; + [[nodiscard]] Expected addDef(MachineRegisterInfo &MRI, MachineInstrBuilder &Builder) const; + +private: + Register Reg; + LowLevelType Type; + Kind ResultKind; +}; + +class MachineIRBuilder { public: MachineIRBuilder(MachineFunction &Function, const TargetDescription &Target) noexcept : Function(&Function), Target(&Target) {} @@ -151,12 +179,13 @@ public: MachineIRBuilder &operator=(const MachineIRBuilder &) = delete; MachineIRBuilder(MachineIRBuilder &&) = delete; MachineIRBuilder &operator=(MachineIRBuilder &&) = delete; + virtual ~MachineIRBuilder() = default; [[nodiscard]] MachineFunction &function() noexcept { return *Function; } - [[nodiscard]] const MachineFunction &function() const noexcept { + [[nodiscard]] MachineFunction &function() const noexcept { return *Function; } @@ -168,6 +197,22 @@ public: return InsertBlock; } + [[nodiscard]] MachineInstr *insertionInstruction() const noexcept { + return InsertBefore; + } + + [[nodiscard]] GISelCSEInfo *getCSEInfo() noexcept { + return CSEInfo; + } + + [[nodiscard]] GISelCSEInfo *getCSEInfo() const noexcept { + return CSEInfo; + } + + void setCSEInfo(GISelCSEInfo *Info) noexcept { + CSEInfo = Info; + } + [[nodiscard]] Expected verifyInsertPoint() const; [[nodiscard]] Expected setInsertPoint(MachineBasicBlock &Block); @@ -179,63 +224,79 @@ public: } [[nodiscard]] Expected buildInstr(Opcode InstructionOpcode) const; - [[nodiscard]] Expected buildInstr(Opcode InstructionOpcode, - std::initializer_list Destinations, - std::initializer_list Sources) const; - [[nodiscard]] Expected buildTrunc(Register Destination, Register Source) const; - [[nodiscard]] Expected buildCopy(Register Destination, Register Source) const; - [[nodiscard]] Expected buildImplicitDef(Register Destination) const; - [[nodiscard]] Expected buildAnyExt(Register Destination, Register Source) const; - [[nodiscard]] Expected buildZExt(Register Destination, Register Source) const; - [[nodiscard]] Expected buildSExt(Register Destination, Register Source) const; - [[nodiscard]] Expected buildUndef(Register Destination) const; - [[nodiscard]] Expected buildAnyExtOrTrunc(Register Destination, + [[nodiscard]] Expected + buildInstr(Opcode InstructionOpcode, std::initializer_list Destinations, + std::initializer_list Sources) const; + [[nodiscard]] virtual Expected + buildInstr(Opcode InstructionOpcode, std::span Destinations, + std::span Sources) const; + [[nodiscard]] Expected buildTrunc(MachineIRBuilderResult Destination, + Register Source) const; + [[nodiscard]] Expected buildCopy(MachineIRBuilderResult Destination, + Register Source) const; + [[nodiscard]] Expected buildImplicitDef(MachineIRBuilderResult Destination) const; + [[nodiscard]] Expected buildAnyExt(MachineIRBuilderResult Destination, + Register Source) const; + [[nodiscard]] Expected buildZExt(MachineIRBuilderResult Destination, + Register Source) const; + [[nodiscard]] Expected buildSExt(MachineIRBuilderResult Destination, + Register Source) const; + [[nodiscard]] Expected buildUndef(MachineIRBuilderResult Destination) const; + [[nodiscard]] Expected buildAnyExtOrTrunc(MachineIRBuilderResult Destination, Register Source) const; - [[nodiscard]] Expected buildSExtOrTrunc(Register Destination, + [[nodiscard]] Expected buildSExtOrTrunc(MachineIRBuilderResult Destination, Register Source) const; - [[nodiscard]] Expected buildConstant(Register Destination, APInt Value) const; - [[nodiscard]] Expected buildConstant(Register Destination, + [[nodiscard]] virtual Expected buildConstant(MachineIRBuilderResult Destination, + APInt Value) const; + [[nodiscard]] Expected buildConstant(MachineIRBuilderResult Destination, std::int64_t Value) const; - [[nodiscard]] Expected buildSExtInReg(Register Destination, Register Source, - std::uint32_t Width) const; - [[nodiscard]] Expected buildAnd(Register Destination, Register Left, + [[nodiscard]] virtual Expected + buildSExtInReg(MachineIRBuilderResult Destination, Register Source, std::uint32_t Width) const; + [[nodiscard]] Expected buildAnd(MachineIRBuilderResult Destination, Register Left, Register Right) const; - [[nodiscard]] Expected buildOr(Register Destination, Register Left, + [[nodiscard]] Expected buildOr(MachineIRBuilderResult Destination, Register Left, Register Right) const; - [[nodiscard]] Expected buildXor(Register Destination, Register Left, + [[nodiscard]] Expected buildXor(MachineIRBuilderResult Destination, Register Left, Register Right) const; - [[nodiscard]] Expected buildAdd(Register Destination, Register Left, + [[nodiscard]] Expected buildAdd(MachineIRBuilderResult Destination, Register Left, Register Right) const; - [[nodiscard]] Expected buildSub(Register Destination, Register Left, + [[nodiscard]] Expected buildSub(MachineIRBuilderResult Destination, Register Left, Register Right) const; - [[nodiscard]] Expected buildShl(Register Destination, Register Left, + [[nodiscard]] Expected buildShl(MachineIRBuilderResult Destination, Register Left, Register Right) const; - [[nodiscard]] Expected buildLShr(Register Destination, Register Left, - Register Right) const; - [[nodiscard]] Expected buildAShr(Register Destination, Register Left, - Register Right) const; - [[nodiscard]] Expected buildPtrToInt(Register Destination, Register Source) const; - [[nodiscard]] Expected buildIntToPtr(Register Destination, Register Source) const; - [[nodiscard]] Expected buildICmp(IntegerPredicate Predicate, Register Destination, + [[nodiscard]] Expected buildLShr(MachineIRBuilderResult Destination, + Register Left, Register Right) const; + [[nodiscard]] Expected buildAShr(MachineIRBuilderResult Destination, + Register Left, Register Right) const; + [[nodiscard]] Expected buildPtrToInt(MachineIRBuilderResult Destination, + Register Source) const; + [[nodiscard]] Expected buildIntToPtr(MachineIRBuilderResult Destination, + Register Source) const; + [[nodiscard]] Expected buildICmp(IntegerPredicate Predicate, + MachineIRBuilderResult Destination, Register Left, Register Right) const; [[nodiscard]] Expected - buildMergeLikeInstr(Register Destination, const std::vector &Sources) const; + buildMergeLikeInstr(MachineIRBuilderResult Destination, + const std::vector &Sources) const; [[nodiscard]] Expected - buildMergeValues(Register Destination, const std::vector &Sources) const; + buildMergeValues(MachineIRBuilderResult Destination, const std::vector &Sources) const; [[nodiscard]] Expected buildUnmergeValues(const std::vector &Destinations, Register Source) const; - [[nodiscard]] Expected buildExtract(Register Destination, Register Source, - std::uint64_t Offset) const; - [[nodiscard]] Expected buildInsert(Register Destination, Register Source, - Register Inserted, std::uint64_t Offset) const; + [[nodiscard]] virtual Expected + buildExtract(MachineIRBuilderResult Destination, Register Source, std::uint64_t Offset) const; + [[nodiscard]] Expected buildInsert(MachineIRBuilderResult Destination, + Register Source, Register Inserted, + std::uint64_t Offset) const; private: - [[nodiscard]] Expected buildUnary(Opcode InstructionOpcode, Register Destination, - Register Source) const; - [[nodiscard]] Expected buildBinary(Opcode InstructionOpcode, Register Destination, - Register Left, Register Right) const; [[nodiscard]] Expected - buildExtOrTrunc(Opcode ExtensionOpcode, Register Destination, Register Source) const; + buildUnary(Opcode InstructionOpcode, MachineIRBuilderResult Destination, Register Source) const; + [[nodiscard]] Expected buildBinary(Opcode InstructionOpcode, + MachineIRBuilderResult Destination, + Register Left, Register Right) const; + [[nodiscard]] Expected buildExtOrTrunc(Opcode ExtensionOpcode, + MachineIRBuilderResult Destination, + Register Source) const; [[nodiscard]] Expected registerType(Register Reg) const; [[nodiscard]] Expected validateBlock(const MachineBasicBlock &Block) const; [[nodiscard]] Expected validateInstruction(const MachineInstr &Instruction) const; @@ -244,6 +305,7 @@ private: const TargetDescription *Target; MachineBasicBlock *InsertBlock = nullptr; MachineInstr *InsertBefore = nullptr; + GISelCSEInfo *CSEInfo = nullptr; }; } // namespace rcc -- cgit v1.2.3