diff options
| author | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-08 04:14:34 +0800 |
|---|---|---|
| committer | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-08 04:14:34 +0800 |
| commit | 77884c967d1cbc48afcbaef7e5a35adcb3c5da1b (patch) | |
| tree | 8cc31c1c5115ed909ec9f8751964bfdc96fbd4ad /backend/lib/CodeGen/GenericOpcodes.cpp | |
| parent | 10b7e69448f866bcd6893b21d7f78d766252eb11 (diff) | |
| download | rcc-project-77884c967d1cbc48afcbaef7e5a35adcb3c5da1b.tar.gz rcc-project-77884c967d1cbc48afcbaef7e5a35adcb3c5da1b.tar.xz | |
[CodeGen] Implement machine SSA exit
Diffstat (limited to 'backend/lib/CodeGen/GenericOpcodes.cpp')
| -rw-r--r-- | backend/lib/CodeGen/GenericOpcodes.cpp | 53 |
1 files changed, 33 insertions, 20 deletions
diff --git a/backend/lib/CodeGen/GenericOpcodes.cpp b/backend/lib/CodeGen/GenericOpcodes.cpp index 0b0e0fe..1394507 100644 --- a/backend/lib/CodeGen/GenericOpcodes.cpp +++ b/backend/lib/CodeGen/GenericOpcodes.cpp @@ -102,7 +102,7 @@ using GO = GenericOpcode; OperandDescriptor Result; Result.Kinds = {MachineOperand::Kind::Register}; Result.RegisterRole = Role; - Result.TypeConstraint = OperandTypeConstraint{std::move(Kinds), Group}; + Result.TypeConstraint = OperandTypeConstraint{Kinds, Group}; return Result; } @@ -146,6 +146,11 @@ using GO = GenericOpcode; return Descriptor; } +[[nodiscard]] OperandDescriptor registeredTargetFlags(OperandDescriptor Descriptor) { + Descriptor.AllowAnyTargetFlags = true; + return Descriptor; +} + class DescriptorRegistry final { public: DescriptorRegistry() { @@ -158,7 +163,7 @@ public: #undef RCC_CORE_OPCODE } - void configure(std::initializer_list<GO> Opcodes, std::vector<OperandDescriptor> Operands, + void configure(std::initializer_list<GO> Opcodes, const std::vector<OperandDescriptor> &Operands, std::size_t NumDefs, std::initializer_list<InstructionFlag> Flags = {}, bool Variadic = false, std::size_t MinimumRepetitions = 0, bool RequiresMemoryOperands = false, PseudoOwner Owner = PseudoOwner::None, @@ -322,9 +327,10 @@ private: auto Info = RegInfo.virtualRegisterInfo(*Reg); if (!Info) return std::unexpected(Info.error()); - if (!Info->get().Type) + const std::optional<LLT> &Type = Info->get().Type; + if (!Type) return semanticError("generic virtual register is missing its LLT"); - Types[Index] = *Info->get().Type; + Types[Index] = Type.value(); } const auto TypeAt = [&Types](std::size_t Index) -> LLT { return *Types[Index]; }; @@ -773,7 +779,7 @@ private: } case GO::G_INTRINSIC_FPTRUNC_ROUND: { const auto Rounding = plainImmediate(Operands[2]); - if (!Rounding || !((*Rounding >= 0 && *Rounding <= 4) || *Rounding == 7)) + if (!Rounding || *Rounding < 0 || (*Rounding > 4 && *Rounding != 7)) return semanticError("floating truncation rounding mode is invalid"); return VerifyWidthChange(false); } @@ -980,14 +986,17 @@ private: void configureCoreOpcodes(DescriptorRegistry &Registry) { const auto RegDef = untypedRegister(RegisterOperandRole::Def); const auto RegUse = untypedRegister(RegisterOperandRole::Use); + const auto TransferDef = registeredTargetFlags(RegDef); + const auto TransferUse = registeredTargetFlags(RegUse); const auto Any = anyOperand(); const auto VariadicAny = repeated(Any); const auto VariadicUse = repeated(RegUse); - Registry.configure({GO::PHI}, - {RegDef, VariadicUse, repeated(kind(MachineOperand::Kind::BasicBlock))}, 1, - {InstructionFlag::Phi}, true, 1, false, PseudoOwner::PhiElimination, - PipelineStage::SSAEliminated); + Registry.configure( + {GO::PHI}, + {TransferDef, repeated(TransferUse), repeated(kind(MachineOperand::Kind::BasicBlock))}, 1, + {InstructionFlag::Phi}, true, 1, false, PseudoOwner::PhiElimination, + PipelineStage::SSAEliminated); Registry.configure({GO::INLINEASM}, {VariadicAny}, 0, {InstructionFlag::ProducesCode, InstructionFlag::TerminalEmission, InstructionFlag::UnmodeledSideEffects}, @@ -1004,10 +1013,11 @@ void configureCoreOpcodes(DescriptorRegistry &Registry) { Registry.configure({GO::KILL}, {VariadicUse}, 0, {InstructionFlag::Meta}, true); Registry.configure({GO::EXTRACT_SUBREG}, {RegDef, RegUse, immediate()}, 1, {}, false, 0, false, PseudoOwner::PostRAExpansion, PipelineStage::PostRAFinalized); - Registry.configure({GO::INSERT_SUBREG}, {RegDef, RegUse, RegUse, immediate()}, 1, {}, false, 0, - false, PseudoOwner::TwoAddressRewrite, PipelineStage::TiedOpsRewritten); + Registry.configure({GO::INSERT_SUBREG}, {TransferDef, TransferUse, TransferUse, immediate()}, 1, + {}, false, 0, false, PseudoOwner::TwoAddressRewrite, + PipelineStage::TiedOpsRewritten); Registry.tie(GO::INSERT_SUBREG, 0, 1); - Registry.configure({GO::IMPLICIT_DEF}, {RegDef}, 1, + Registry.configure({GO::IMPLICIT_DEF}, {TransferDef}, 1, {InstructionFlag::Meta, InstructionFlag::Rematerializable}); Registry.configure({GO::INIT_UNDEF}, {RegDef}, 1, {}, false, 0, false, PseudoOwner::RegisterAllocator, PipelineStage::RegisterAllocated); @@ -1019,10 +1029,10 @@ void configureCoreOpcodes(DescriptorRegistry &Registry) { {VariadicAny}, 0, {InstructionFlag::Meta}, true); Registry.configure({GO::DBG_LABEL}, {kind(MachineOperand::Kind::Metadata)}, 0, {InstructionFlag::Meta}); - Registry.configure({GO::REG_SEQUENCE}, {RegDef, repeated(RegUse), repeated(immediate())}, 1, {}, - true, 1, false, PseudoOwner::TwoAddressRewrite, - PipelineStage::TiedOpsRewritten); - Registry.configure({GO::COPY}, {RegDef, RegUse}, 1, {}, false, 0, false, + Registry.configure({GO::REG_SEQUENCE}, + {TransferDef, repeated(TransferUse), repeated(immediate())}, 1, {}, true, 1, + false, PseudoOwner::TwoAddressRewrite, PipelineStage::TiedOpsRewritten); + Registry.configure({GO::COPY}, {TransferDef, TransferUse}, 1, {}, false, 0, false, PseudoOwner::PostRAExpansion, PipelineStage::PostRAFinalized); Registry.configure({GO::COPY_LANEMASK}, {RegDef, RegUse, kind(MachineOperand::Kind::LaneMask)}, 1, {}, false, 0, false, PseudoOwner::PostRAExpansion, @@ -1170,10 +1180,13 @@ void configureGenericOpcodes(DescriptorRegistry &Registry) { InstructionFlag::Commutable); Registry.configure({GO::G_SDIVREM, GO::G_UDIVREM}, {IntDef0, IntDef0, IntUse0, IntUse0}, 2); - Registry.configure({GO::G_IMPLICIT_DEF}, {AnyDef0}, 1); - Registry.configure({GO::G_PHI}, - {AnyDef0, repeated(AnyUse0), repeated(kind(MachineOperand::Kind::BasicBlock))}, - 1, {InstructionFlag::Phi}, true, 1); + const auto TransferDef0 = registeredTargetFlags(AnyDef0); + const auto TransferUse0 = registeredTargetFlags(AnyUse0); + Registry.configure({GO::G_IMPLICIT_DEF}, {TransferDef0}, 1); + Registry.configure( + {GO::G_PHI}, + {TransferDef0, repeated(TransferUse0), repeated(kind(MachineOperand::Kind::BasicBlock))}, 1, + {InstructionFlag::Phi}, true, 1); Registry.configure({GO::G_FRAME_INDEX}, {ScalarPointerDef0, kind(MachineOperand::Kind::FrameIndex)}, 1); Registry.configure({GO::G_GLOBAL_VALUE}, |
