// SPDX-License-Identifier: GPL-3.0-or-later #ifndef RCC_CODEGEN_TARGETCODEGEN_H #define RCC_CODEGEN_TARGETCODEGEN_H #include "rcc/CodeGen/MachineIRTypes.h" #include "rcc/CodeGen/Register.h" #include "rcc/Support/Error.h" #include #include #include namespace rcc { class MachineFunction; class MachineBasicBlock; class MachineInstr; class MachineRegisterInfo; class TargetDescription; struct VirtualRegisterInfo; enum class LegalizationAction : std::uint8_t { Legal, Unsupported, Custom, Lower, Libcall, WidenScalar, NarrowScalar, MoreElements, FewerElements, Bitcast, ChangeElementType, ChangeAddressSpace, }; class TargetLegalizerInfo { public: virtual ~TargetLegalizerInfo() = default; [[nodiscard]] virtual Expected classify(const MachineInstr &Instruction, const MachineFunction &Function, const TargetDescription &Target) const = 0; [[nodiscard]] virtual Expected lower(MachineInstr &Instruction, MachineFunction &Function, const TargetDescription &Target, LegalizationAction Action) const = 0; // This hook performs read-only target checks before a lowering mutation is committed. [[nodiscard]] virtual Expected validateLowering(const MachineInstr &, const MachineFunction &, const TargetDescription &, LegalizationAction) const { return {}; } }; class TargetRegisterBankInfo { public: virtual ~TargetRegisterBankInfo() = default; [[nodiscard]] virtual Expected selectBank(const MachineFunction &Function, Register Reg, const VirtualRegisterInfo &Info, const MachineInstr *Context, const TargetDescription &Target) const = 0; [[nodiscard]] virtual Expected constrainInstruction(MachineInstr &Instruction, MachineFunction &Function, const TargetDescription &Target) const = 0; // This hook must not mutate MachineIR. It allows the pass to reject a bad mapping // before publishing any bank or class assignment. [[nodiscard]] virtual Expected validateInstruction(const MachineInstr &, const MachineFunction &, const TargetDescription &) const { return {}; } }; class TargetInstructionSelector { public: virtual ~TargetInstructionSelector() = default; [[nodiscard]] virtual Expected select(MachineInstr &Instruction, MachineFunction &Function, const TargetDescription &Target) const = 0; // Selection matching is read-only and must complete before select() mutates MachineIR. [[nodiscard]] virtual Expected canSelect(const MachineInstr &, const MachineFunction &, const TargetDescription &) const { return {}; } [[nodiscard]] virtual Expected constrainSelectedInstruction(MachineInstr &, MachineFunction &, const TargetDescription &) const { return {}; } }; class TargetSSAInfo { public: virtual ~TargetSSAInfo() = default; [[nodiscard]] virtual Expected isFallthroughEdge(const MachineBasicBlock &From, const MachineBasicBlock &To, const MachineFunction &Function, const TargetDescription &Target) const = 0; [[nodiscard]] virtual Expected rewriteBranchTarget(MachineBasicBlock &Block, MachineBasicBlock &OldTarget, MachineBasicBlock &NewTarget, MachineFunction &Function, const TargetDescription &Target) const = 0; [[nodiscard]] virtual Expected insertUnconditionalBranch(MachineBasicBlock &Block, MachineBasicBlock &Target, MachineFunction &Function, const TargetDescription &TargetDescription) const = 0; [[nodiscard]] virtual Expected validateCopy(Register Destination, SubRegIndex DestinationSubReg, Register Source, SubRegIndex SourceSubReg, const MachineFunction &Function, const TargetDescription &Target) const = 0; [[nodiscard]] virtual Expected tryConvertToThreeAddress(MachineInstr &, std::size_t, std::size_t, MachineFunction &, const TargetDescription &) const { return false; } }; } // namespace rcc #endif // RCC_CODEGEN_TARGETCODEGEN_H