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/lib/CodeGen/MachineIRBuilder.cpp | 238 +++++++++++++++++-------------- 1 file changed, 130 insertions(+), 108 deletions(-) (limited to 'backend/lib/CodeGen/MachineIRBuilder.cpp') diff --git a/backend/lib/CodeGen/MachineIRBuilder.cpp b/backend/lib/CodeGen/MachineIRBuilder.cpp index e3ac0bf..36f697b 100644 --- a/backend/lib/CodeGen/MachineIRBuilder.cpp +++ b/backend/lib/CodeGen/MachineIRBuilder.cpp @@ -11,6 +11,8 @@ #include "rcc/CodeGen/MachineRegisterInfo.h" #include +#include +#include #include #include #include @@ -21,6 +23,34 @@ namespace rcc { +Register MachineIRBuilderResult::reg() const noexcept { + assert(ResultKind == Kind::Register && "machine IR builder result is not a register"); + return Reg; +} + +LowLevelType MachineIRBuilderResult::type() const noexcept { + assert(ResultKind == Kind::Type && "machine IR builder result is not a type"); + return Type; +} + +Expected MachineIRBuilderResult::type(const MachineRegisterInfo &MRI) const { + if (ResultKind == Kind::Type) + return Type; + return MRI.getType(Reg); +} + +Expected MachineIRBuilderResult::addDef(MachineRegisterInfo &MRI, + MachineInstrBuilder &Builder) const { + Register Definition = Reg; + if (ResultKind == Kind::Type) { + auto Created = MRI.createVirtualRegister(Type); + if (!Created) + return std::unexpected(Created.error()); + Definition = *Created; + } + return Builder.addDef(Definition); +} + MachineInstrBuilder::MachineInstrBuilder(MachineFunction &Function, const TargetDescription &Target, const InstructionDescriptor &Descriptor, MachineBasicBlock &InsertBlock, @@ -709,13 +739,24 @@ Expected MachineIRBuilder::buildInstr(Opcode InstructionOpc } Expected -MachineIRBuilder::buildInstr(Opcode InstructionOpcode, std::initializer_list Destinations, +MachineIRBuilder::buildInstr(Opcode InstructionOpcode, + std::initializer_list Destinations, std::initializer_list Sources) const { + return buildInstr( + InstructionOpcode, + std::span(Destinations.begin(), Destinations.size()), + std::span(Sources.begin(), Sources.size())); +} + +Expected +MachineIRBuilder::buildInstr(Opcode InstructionOpcode, + std::span Destinations, + std::span Sources) const { auto Pending = buildInstr(InstructionOpcode); if (!Pending) return std::unexpected(Pending.error()); - for (Register Destination : Destinations) { - if (auto Added = Pending->addDef(Destination); !Added) + for (const MachineIRBuilderResult &Destination : Destinations) { + if (auto Added = Destination.addDef(Function->registerInfo(), *Pending); !Added) return std::unexpected(Added.error()); } for (Register Source : Sources) { @@ -732,77 +773,72 @@ Expected MachineIRBuilder::registerType(Register Reg) const { auto Info = Function->registerInfo().virtualRegisterInfo(Reg); if (!Info) return std::unexpected(Info.error()); - if (!Info->get().Type) + const std::optional &Type = Info->get().Type; + if (!Type.has_value()) return makeUnexpected(ErrorCode::InvalidArgument, "generic builder operand has no LowLevelType"); - return *Info->get().Type; + return Type.value(); } Expected MachineIRBuilder::buildUnary(Opcode InstructionOpcode, - Register Destination, Register Source) const { - auto Pending = buildInstr(InstructionOpcode); - if (!Pending) - return std::unexpected(Pending.error()); - if (auto Added = Pending->addDef(Destination); !Added) - return std::unexpected(Added.error()); - if (auto Added = Pending->addUse(Source); !Added) - return std::unexpected(Added.error()); - return Pending->build(); + MachineIRBuilderResult Destination, + Register Source) const { + const std::array Destinations{Destination}; + const std::array Sources{Source}; + return buildInstr(InstructionOpcode, std::span(Destinations), + std::span(Sources)); } Expected MachineIRBuilder::buildBinary(Opcode InstructionOpcode, - Register Destination, Register Left, - Register Right) const { - auto Pending = buildInstr(InstructionOpcode); - if (!Pending) - return std::unexpected(Pending.error()); - if (auto Added = Pending->addDef(Destination); !Added) - return std::unexpected(Added.error()); - if (auto Added = Pending->addUse(Left); !Added) - return std::unexpected(Added.error()); - if (auto Added = Pending->addUse(Right); !Added) - return std::unexpected(Added.error()); - return Pending->build(); + MachineIRBuilderResult Destination, + Register Left, Register Right) const { + const std::array Destinations{Destination}; + const std::array Sources{Left, Right}; + return buildInstr(InstructionOpcode, std::span(Destinations), + std::span(Sources)); } -Expected MachineIRBuilder::buildTrunc(Register Destination, Register Source) const { +Expected MachineIRBuilder::buildTrunc(MachineIRBuilderResult Destination, + Register Source) const { return buildUnary(opcode(GenericOpcode::G_TRUNC), Destination, Source); } -Expected MachineIRBuilder::buildCopy(Register Destination, Register Source) const { +Expected MachineIRBuilder::buildCopy(MachineIRBuilderResult Destination, + Register Source) const { return buildUnary(opcode(GenericOpcode::COPY), Destination, Source); } -Expected MachineIRBuilder::buildImplicitDef(Register Destination) const { - auto Pending = buildInstr(opcode(GenericOpcode::G_IMPLICIT_DEF)); - if (!Pending) - return std::unexpected(Pending.error()); - if (auto Added = Pending->addDef(Destination); !Added) - return std::unexpected(Added.error()); - return Pending->build(); +Expected +MachineIRBuilder::buildImplicitDef(MachineIRBuilderResult Destination) const { + const std::array Destinations{Destination}; + return buildInstr(opcode(GenericOpcode::G_IMPLICIT_DEF), + std::span(Destinations), + std::span()); } -Expected MachineIRBuilder::buildAnyExt(Register Destination, +Expected MachineIRBuilder::buildAnyExt(MachineIRBuilderResult Destination, Register Source) const { return buildUnary(opcode(GenericOpcode::G_ANYEXT), Destination, Source); } -Expected MachineIRBuilder::buildZExt(Register Destination, Register Source) const { +Expected MachineIRBuilder::buildZExt(MachineIRBuilderResult Destination, + Register Source) const { return buildUnary(opcode(GenericOpcode::G_ZEXT), Destination, Source); } -Expected MachineIRBuilder::buildSExt(Register Destination, Register Source) const { +Expected MachineIRBuilder::buildSExt(MachineIRBuilderResult Destination, + Register Source) const { return buildUnary(opcode(GenericOpcode::G_SEXT), Destination, Source); } -Expected MachineIRBuilder::buildUndef(Register Destination) const { +Expected MachineIRBuilder::buildUndef(MachineIRBuilderResult Destination) const { return buildImplicitDef(Destination); } Expected MachineIRBuilder::buildExtOrTrunc(Opcode ExtensionOpcode, - Register Destination, + MachineIRBuilderResult Destination, Register Source) const { - auto DestinationType = registerType(Destination); + auto DestinationType = Destination.type(Function->registerInfo()); if (!DestinationType) return std::unexpected(DestinationType.error()); auto SourceType = registerType(Source); @@ -817,30 +853,31 @@ Expected MachineIRBuilder::buildExtOrTrunc(Opcode ExtensionOpcod return buildUnary(opcode(GenericOpcode::COPY), Destination, Source); } -Expected MachineIRBuilder::buildAnyExtOrTrunc(Register Destination, +Expected MachineIRBuilder::buildAnyExtOrTrunc(MachineIRBuilderResult Destination, Register Source) const { return buildExtOrTrunc(opcode(GenericOpcode::G_ANYEXT), Destination, Source); } -Expected MachineIRBuilder::buildSExtOrTrunc(Register Destination, +Expected MachineIRBuilder::buildSExtOrTrunc(MachineIRBuilderResult Destination, Register Source) const { return buildExtOrTrunc(opcode(GenericOpcode::G_SEXT), Destination, Source); } -Expected MachineIRBuilder::buildConstant(Register Destination, APInt Value) const { +Expected MachineIRBuilder::buildConstant(MachineIRBuilderResult Destination, + APInt Value) const { auto Pending = buildInstr(opcode(GenericOpcode::G_CONSTANT)); if (!Pending) return std::unexpected(Pending.error()); - if (auto Added = Pending->addDef(Destination); !Added) + if (auto Added = Destination.addDef(Function->registerInfo(), *Pending); !Added) return std::unexpected(Added.error()); if (auto Added = Pending->addIntegerImmediate(std::move(Value)); !Added) return std::unexpected(Added.error()); return Pending->build(); } -Expected MachineIRBuilder::buildConstant(Register Destination, +Expected MachineIRBuilder::buildConstant(MachineIRBuilderResult Destination, std::int64_t Value) const { - auto Type = registerType(Destination); + auto Type = Destination.type(Function->registerInfo()); if (!Type) return std::unexpected(Type.error()); auto Immediate = APInt::fromSigned(Type->scalarBitWidth(), Value); @@ -849,12 +886,13 @@ Expected MachineIRBuilder::buildConstant(Register Destination, return buildConstant(Destination, std::move(*Immediate)); } -Expected MachineIRBuilder::buildSExtInReg(Register Destination, Register Source, +Expected MachineIRBuilder::buildSExtInReg(MachineIRBuilderResult Destination, + Register Source, std::uint32_t Width) const { auto Pending = buildInstr(opcode(GenericOpcode::G_SEXT_INREG)); if (!Pending) return std::unexpected(Pending.error()); - if (auto Added = Pending->addDef(Destination); !Added) + if (auto Added = Destination.addDef(Function->registerInfo(), *Pending); !Added) return std::unexpected(Added.error()); if (auto Added = Pending->addUse(Source); !Added) return std::unexpected(Added.error()); @@ -863,63 +901,63 @@ Expected MachineIRBuilder::buildSExtInReg(Register Destination, return Pending->build(); } -Expected MachineIRBuilder::buildAnd(Register Destination, Register Left, - Register Right) const { +Expected MachineIRBuilder::buildAnd(MachineIRBuilderResult Destination, + Register Left, Register Right) const { return buildBinary(opcode(GenericOpcode::G_AND), Destination, Left, Right); } -Expected MachineIRBuilder::buildOr(Register Destination, Register Left, - Register Right) const { +Expected MachineIRBuilder::buildOr(MachineIRBuilderResult Destination, + Register Left, Register Right) const { return buildBinary(opcode(GenericOpcode::G_OR), Destination, Left, Right); } -Expected MachineIRBuilder::buildXor(Register Destination, Register Left, - Register Right) const { +Expected MachineIRBuilder::buildXor(MachineIRBuilderResult Destination, + Register Left, Register Right) const { return buildBinary(opcode(GenericOpcode::G_XOR), Destination, Left, Right); } -Expected MachineIRBuilder::buildAdd(Register Destination, Register Left, - Register Right) const { +Expected MachineIRBuilder::buildAdd(MachineIRBuilderResult Destination, + Register Left, Register Right) const { return buildBinary(opcode(GenericOpcode::G_ADD), Destination, Left, Right); } -Expected MachineIRBuilder::buildSub(Register Destination, Register Left, - Register Right) const { +Expected MachineIRBuilder::buildSub(MachineIRBuilderResult Destination, + Register Left, Register Right) const { return buildBinary(opcode(GenericOpcode::G_SUB), Destination, Left, Right); } -Expected MachineIRBuilder::buildShl(Register Destination, Register Left, - Register Right) const { +Expected MachineIRBuilder::buildShl(MachineIRBuilderResult Destination, + Register Left, Register Right) const { return buildBinary(opcode(GenericOpcode::G_SHL), Destination, Left, Right); } -Expected MachineIRBuilder::buildLShr(Register Destination, Register Left, - Register Right) const { +Expected MachineIRBuilder::buildLShr(MachineIRBuilderResult Destination, + Register Left, Register Right) const { return buildBinary(opcode(GenericOpcode::G_LSHR), Destination, Left, Right); } -Expected MachineIRBuilder::buildAShr(Register Destination, Register Left, - Register Right) const { +Expected MachineIRBuilder::buildAShr(MachineIRBuilderResult Destination, + Register Left, Register Right) const { return buildBinary(opcode(GenericOpcode::G_ASHR), Destination, Left, Right); } -Expected MachineIRBuilder::buildPtrToInt(Register Destination, +Expected MachineIRBuilder::buildPtrToInt(MachineIRBuilderResult Destination, Register Source) const { return buildUnary(opcode(GenericOpcode::G_PTRTOINT), Destination, Source); } -Expected MachineIRBuilder::buildIntToPtr(Register Destination, +Expected MachineIRBuilder::buildIntToPtr(MachineIRBuilderResult Destination, Register Source) const { return buildUnary(opcode(GenericOpcode::G_INTTOPTR), Destination, Source); } Expected MachineIRBuilder::buildICmp(IntegerPredicate Predicate, - Register Destination, Register Left, - Register Right) const { + MachineIRBuilderResult Destination, + Register Left, Register Right) const { auto Pending = buildInstr(opcode(GenericOpcode::G_ICMP)); if (!Pending) return std::unexpected(Pending.error()); - if (auto Added = Pending->addDef(Destination); !Added) + if (auto Added = Destination.addDef(Function->registerInfo(), *Pending); !Added) return std::unexpected(Added.error()); if (auto Added = Pending->addIntegerPredicate(Predicate); !Added) return std::unexpected(Added.error()); @@ -931,9 +969,9 @@ Expected MachineIRBuilder::buildICmp(IntegerPredicate Predicate, } Expected -MachineIRBuilder::buildMergeLikeInstr(Register Destination, +MachineIRBuilder::buildMergeLikeInstr(MachineIRBuilderResult Destination, const std::vector &Sources) const { - auto DestinationType = registerType(Destination); + auto DestinationType = Destination.type(Function->registerInfo()); if (!DestinationType) return std::unexpected(DestinationType.error()); if (!DestinationType->isVector()) @@ -946,49 +984,33 @@ MachineIRBuilder::buildMergeLikeInstr(Register Destination, return std::unexpected(SourceType.error()); const GenericOpcode MergeOpcode = SourceType->isVector() ? GenericOpcode::G_CONCAT_VECTORS : GenericOpcode::G_BUILD_VECTOR; - auto Pending = buildInstr(opcode(MergeOpcode)); - if (!Pending) - return std::unexpected(Pending.error()); - if (auto Added = Pending->addDef(Destination); !Added) - return std::unexpected(Added.error()); - for (Register Source : Sources) { - if (auto Added = Pending->addUse(Source); !Added) - return std::unexpected(Added.error()); - } - return Pending->build(); + const std::array Destinations{Destination}; + return buildInstr(opcode(MergeOpcode), std::span(Destinations), + Sources); } Expected -MachineIRBuilder::buildMergeValues(Register Destination, +MachineIRBuilder::buildMergeValues(MachineIRBuilderResult Destination, const std::vector &Sources) const { - auto Pending = buildInstr(opcode(GenericOpcode::G_MERGE_VALUES)); - if (!Pending) - return std::unexpected(Pending.error()); - if (auto Added = Pending->addDef(Destination); !Added) - return std::unexpected(Added.error()); - for (Register Source : Sources) { - if (auto Added = Pending->addUse(Source); !Added) - return std::unexpected(Added.error()); - } - return Pending->build(); + const std::array Destinations{Destination}; + return buildInstr(opcode(GenericOpcode::G_MERGE_VALUES), + std::span(Destinations), Sources); } Expected MachineIRBuilder::buildUnmergeValues(const std::vector &Destinations, Register Source) const { - auto Pending = buildInstr(opcode(GenericOpcode::G_UNMERGE_VALUES)); - if (!Pending) - return std::unexpected(Pending.error()); - for (Register Destination : Destinations) { - if (auto Added = Pending->addDef(Destination); !Added) - return std::unexpected(Added.error()); - } - if (auto Added = Pending->addUse(Source); !Added) - return std::unexpected(Added.error()); - return Pending->build(); + std::vector Results; + Results.reserve(Destinations.size()); + for (Register Destination : Destinations) + Results.emplace_back(Destination); + const std::array Sources{Source}; + return buildInstr(opcode(GenericOpcode::G_UNMERGE_VALUES), Results, + std::span(Sources)); } -Expected MachineIRBuilder::buildExtract(Register Destination, Register Source, +Expected MachineIRBuilder::buildExtract(MachineIRBuilderResult Destination, + Register Source, std::uint64_t Offset) const { if (Offset > static_cast(std::numeric_limits::max())) return makeUnexpected(ErrorCode::InvalidArgument, @@ -996,7 +1018,7 @@ Expected MachineIRBuilder::buildExtract(Register Destination, Re auto Pending = buildInstr(opcode(GenericOpcode::G_EXTRACT)); if (!Pending) return std::unexpected(Pending.error()); - if (auto Added = Pending->addDef(Destination); !Added) + if (auto Added = Destination.addDef(Function->registerInfo(), *Pending); !Added) return std::unexpected(Added.error()); if (auto Added = Pending->addUse(Source); !Added) return std::unexpected(Added.error()); @@ -1005,8 +1027,8 @@ Expected MachineIRBuilder::buildExtract(Register Destination, Re return Pending->build(); } -Expected MachineIRBuilder::buildInsert(Register Destination, Register Source, - Register Inserted, +Expected MachineIRBuilder::buildInsert(MachineIRBuilderResult Destination, + Register Source, Register Inserted, std::uint64_t Offset) const { if (Offset > static_cast(std::numeric_limits::max())) return makeUnexpected(ErrorCode::InvalidArgument, @@ -1014,7 +1036,7 @@ Expected MachineIRBuilder::buildInsert(Register Destination, Reg auto Pending = buildInstr(opcode(GenericOpcode::G_INSERT)); if (!Pending) return std::unexpected(Pending.error()); - if (auto Added = Pending->addDef(Destination); !Added) + if (auto Added = Destination.addDef(Function->registerInfo(), *Pending); !Added) return std::unexpected(Added.error()); if (auto Added = Pending->addUse(Source); !Added) return std::unexpected(Added.error()); -- cgit v1.2.3