From 540c73a2f450af3d0aec6e039fab054471efdbb1 Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Mon, 24 Aug 2026 16:37:25 +0800 Subject: [RISCV] Match LLVM frame lowering semantics --- backend/lib/Target/RISCV/RISCV.h | 2 +- backend/lib/Target/RISCV/RISCVFrameLowering.cpp | 195 +++++++++++---------- .../lib/Target/RISCV/RISCVOptimizationPipeline.cpp | 2 +- backend/lib/Target/RISCV/RISCVPipeline.cpp | 4 +- backend/lib/Target/RISCV/RISCVSubtarget.cpp | 13 +- 5 files changed, 121 insertions(+), 95 deletions(-) (limited to 'backend/lib/Target') diff --git a/backend/lib/Target/RISCV/RISCV.h b/backend/lib/Target/RISCV/RISCV.h index 4eeaf64..a2212d4 100644 --- a/backend/lib/Target/RISCV/RISCV.h +++ b/backend/lib/Target/RISCV/RISCV.h @@ -26,7 +26,7 @@ class RISCVSubtarget; createRISCVInstructionSelector(const RISCVSubtarget &Subtarget, const RISCVRegisterBankInfo &RegisterBanks); [[nodiscard]] const TargetRegisterAllocationInfo ®isterAllocationInfo() noexcept; -[[nodiscard]] const TargetFrameLowering &frameLowering() noexcept; +[[nodiscard]] const TargetFrameLowering &frameLowering(RISCVABI ABI = RISCVABI::LP64D) noexcept; [[nodiscard]] std::unique_ptr createSchedulingHooks(const RISCVSubtargetFeatures &Features); [[nodiscard]] Expected diff --git a/backend/lib/Target/RISCV/RISCVFrameLowering.cpp b/backend/lib/Target/RISCV/RISCVFrameLowering.cpp index 9e921f0..df30c50 100644 --- a/backend/lib/Target/RISCV/RISCVFrameLowering.cpp +++ b/backend/lib/Target/RISCV/RISCVFrameLowering.cpp @@ -311,22 +311,34 @@ struct CallFrameRequirement final { return Function.frameInfo().setMaxCallFrameSize(Maximum); } -[[nodiscard]] std::array saveOrder() noexcept { - return { - PhysicalRegisterID::X1, PhysicalRegisterID::X8, PhysicalRegisterID::X9, - PhysicalRegisterID::X18, PhysicalRegisterID::X19, PhysicalRegisterID::X20, - PhysicalRegisterID::X21, PhysicalRegisterID::X22, PhysicalRegisterID::X23, - PhysicalRegisterID::X24, PhysicalRegisterID::X25, PhysicalRegisterID::X26, - PhysicalRegisterID::X27, PhysicalRegisterID::F8_D, PhysicalRegisterID::F9_D, - PhysicalRegisterID::F18_D, PhysicalRegisterID::F19_D, PhysicalRegisterID::F20_D, - PhysicalRegisterID::F21_D, PhysicalRegisterID::F22_D, PhysicalRegisterID::F23_D, - PhysicalRegisterID::F24_D, PhysicalRegisterID::F25_D, PhysicalRegisterID::F26_D, - PhysicalRegisterID::F27_D, - }; +constexpr std::array LP64SaveOrder{ + PhysicalRegisterID::X1, PhysicalRegisterID::X8, PhysicalRegisterID::X9, + PhysicalRegisterID::X18, PhysicalRegisterID::X19, PhysicalRegisterID::X20, + PhysicalRegisterID::X21, PhysicalRegisterID::X22, PhysicalRegisterID::X23, + PhysicalRegisterID::X24, PhysicalRegisterID::X25, PhysicalRegisterID::X26, + PhysicalRegisterID::X27, +}; + +constexpr std::array LP64DSaveOrder{ + PhysicalRegisterID::X1, PhysicalRegisterID::X8, PhysicalRegisterID::X9, + PhysicalRegisterID::X18, PhysicalRegisterID::X19, PhysicalRegisterID::X20, + PhysicalRegisterID::X21, PhysicalRegisterID::X22, PhysicalRegisterID::X23, + PhysicalRegisterID::X24, PhysicalRegisterID::X25, PhysicalRegisterID::X26, + PhysicalRegisterID::X27, PhysicalRegisterID::F8_D, PhysicalRegisterID::F9_D, + PhysicalRegisterID::F18_D, PhysicalRegisterID::F19_D, PhysicalRegisterID::F20_D, + PhysicalRegisterID::F21_D, PhysicalRegisterID::F22_D, PhysicalRegisterID::F23_D, + PhysicalRegisterID::F24_D, PhysicalRegisterID::F25_D, PhysicalRegisterID::F26_D, + PhysicalRegisterID::F27_D, +}; + +[[nodiscard]] std::span saveOrder(RISCVABI ABI) noexcept { + return ABI == RISCVABI::LP64D ? std::span(LP64DSaveOrder) + : std::span(LP64SaveOrder); } [[nodiscard]] Expected> -modifiedCalleeSavedRegisters(const MachineFunction &Function, const TargetDescription &Target) { +modifiedCalleeSavedRegisters(const MachineFunction &Function, const TargetDescription &Target, + RISCVABI ABI) { std::unordered_set Modified; for (const StackObject &Object : Function.frameInfo().objects()) { if (!Object.isTombstone() && !Object.description()->IsDead && @@ -344,7 +356,7 @@ modifiedCalleeSavedRegisters(const MachineFunction &Function, const TargetDescri return makeUnexpected(ErrorCode::VerificationError, "RISC-V callee-save analysis found a null register mask"); } - for (const PhysicalRegisterID ID : saveOrder()) { + for (const PhysicalRegisterID ID : saveOrder(ABI)) { auto Reg = physicalRegister(ID); if (!Reg) return std::unexpected(Reg.error()); @@ -363,7 +375,7 @@ modifiedCalleeSavedRegisters(const MachineFunction &Function, const TargetDescri } std::vector Result; - for (const PhysicalRegisterID ID : saveOrder()) { + for (const PhysicalRegisterID ID : saveOrder(ABI)) { auto Reg = physicalRegister(ID); if (!Reg) return std::unexpected(Reg.error()); @@ -403,11 +415,13 @@ modifiedCalleeSavedRegisters(const MachineFunction &Function, const TargetDescri createStackMemory(MachineFunction &Function, FrameIndex Index, MemoryAccessFlag Access) { auto Size = MemorySize::fixed(8); auto Align = Alignment::create(8); - if (!Size || !Align) + auto Type = LowLevelType::makeCategoryNeutralScalar(64); + if (!Size || !Align || !Type) return makeUnexpected(ErrorCode::InternalError, "RISC-V spill facts are invalid"); MachineMemOperandDesc Description; Description.Accesses = {Access}; Description.Size = *Size; + Description.MemoryType = *Type; Description.Align = *Align; Description.Base = MemoryBase::frameIndex(Index); return Function.createMemOperand(std::move(Description)); @@ -417,11 +431,13 @@ createStackMemory(MachineFunction &Function, FrameIndex Index, MemoryAccessFlag createResolvedStackMemory(MachineFunction &Function, MemoryAccessFlag Access, std::int64_t Offset) { auto Size = MemorySize::fixed(8); auto Align = Alignment::create(8); - if (!Size || !Align) + auto Type = LowLevelType::makeCategoryNeutralScalar(64); + if (!Size || !Align || !Type) return makeUnexpected(ErrorCode::InternalError, "RISC-V spill facts are invalid"); MachineMemOperandDesc Description; Description.Accesses = {Access}; Description.Size = *Size; + Description.MemoryType = *Type; Description.Align = *Align; Description.Base = MemoryBase::stack(); Description.Offset = Offset; @@ -474,7 +490,8 @@ createResolvedStackMemory(MachineFunction &Function, MemoryAccessFlag Access, st return DwarfRegisterNumber::fromValue(*Number); } -[[nodiscard]] Expected emitCFI(MachineIRBuilder &Builder, MachineCFIInstruction Instruction) { +[[nodiscard]] Expected emitCFI(MachineIRBuilder &Builder, MachineCFIInstruction Instruction, + MachineInstrFlag Flag) { auto Index = Builder.function().cfiInfo().addInstruction(std::move(Instruction)); if (!Index) return std::unexpected(Index.error()); @@ -483,6 +500,8 @@ createResolvedStackMemory(MachineFunction &Function, MemoryAccessFlag Access, st return std::unexpected(Pending.error()); if (auto Result = Pending->addCFIInstruction(*Index); !Result) return std::unexpected(Result.error()); + if (auto Result = setFrameFlag(*Pending, Flag); !Result) + return std::unexpected(Result.error()); auto Built = Pending->build(); if (!Built) return std::unexpected(Built.error()); @@ -514,13 +533,13 @@ void appendSLEB128(std::vector &Bytes, std::int64_t Value) { [[nodiscard]] Expected emitSavedRegisterCFI(MachineIRBuilder &Builder, const TargetDescription &Target, - PhysicalRegister Reg, std::int64_t Offset, + PhysicalRegister Reg, std::int64_t Offset, MachineInstrFlag Flag, std::optional ExpressionBase = std::nullopt) { auto DwarfReg = dwarfRegister(Target, Reg); if (!DwarfReg) return std::unexpected(DwarfReg.error()); if (!ExpressionBase) - return emitCFI(Builder, MachineCFIInstruction::offset(*DwarfReg, Offset)); + return emitCFI(Builder, MachineCFIInstruction::offset(*DwarfReg, Offset), Flag); auto DwarfBase = dwarfRegister(Target, *ExpressionBase); if (!DwarfBase) @@ -541,24 +560,30 @@ emitSavedRegisterCFI(MachineIRBuilder &Builder, const TargetDescription &Target, auto Rule = MachineCFIInstruction::escape(std::move(Escape)); if (!Rule) return std::unexpected(Rule.error()); - return emitCFI(Builder, std::move(*Rule)); + return emitCFI(Builder, std::move(*Rule), Flag); } [[nodiscard]] Expected emitRestoreRegisterCFI(MachineIRBuilder &Builder, const TargetDescription &Target, - PhysicalRegister Reg) { + PhysicalRegister Reg, MachineInstrFlag Flag) { auto DwarfReg = dwarfRegister(Target, Reg); if (!DwarfReg) return std::unexpected(DwarfReg.error()); - return emitCFI(Builder, MachineCFIInstruction::restore(*DwarfReg)); + return emitCFI(Builder, MachineCFIInstruction::restore(*DwarfReg), Flag); } [[nodiscard]] Expected emitDefCFI(MachineIRBuilder &Builder, const TargetDescription &Target, - PhysicalRegister Reg, std::int64_t Offset) { + PhysicalRegister Reg, std::int64_t Offset, + MachineInstrFlag Flag) { auto DwarfReg = dwarfRegister(Target, Reg); if (!DwarfReg) return std::unexpected(DwarfReg.error()); - return emitCFI(Builder, MachineCFIInstruction::defCFA(*DwarfReg, Offset)); + return emitCFI(Builder, MachineCFIInstruction::defCFA(*DwarfReg, Offset), Flag); +} + +[[nodiscard]] Expected emitDefCFAOffset(MachineIRBuilder &Builder, std::int64_t Offset, + MachineInstrFlag Flag) { + return emitCFI(Builder, MachineCFIInstruction::defCFAOffset(Offset), Flag); } [[nodiscard]] Expected emitConstant(MachineIRBuilder &Builder, PhysicalRegister Destination, @@ -825,17 +850,17 @@ emitSavedRegisterCFI(MachineIRBuilder &Builder, const TargetDescription &Target, if (!Aligned) return std::unexpected(Aligned.error()); Cursor = *Aligned; + if (Description.Size.value_or(0) > std::numeric_limits::max() - Cursor) { + return makeUnexpected(ErrorCode::FrameLayoutFailed, "RISC-V frame size overflows uint64"); + } + Cursor += Description.Size.value_or(0); if (Cursor > static_cast(std::numeric_limits::max())) { return makeUnexpected(ErrorCode::FrameLayoutFailed, "RISC-V frame offset exceeds signed 64-bit range"); } - auto Set = Frame.setObjectOffset(Object->index(), static_cast(Cursor)); + auto Set = Frame.setObjectOffset(Object->index(), -static_cast(Cursor)); if (!Set) return std::unexpected(Set.error()); - if (Description.Size.value_or(0) > std::numeric_limits::max() - Cursor) { - return makeUnexpected(ErrorCode::FrameLayoutFailed, "RISC-V frame size overflows uint64"); - } - Cursor += Description.Size.value_or(0); } return {}; }; @@ -850,14 +875,18 @@ emitSavedRegisterCFI(MachineIRBuilder &Builder, const TargetDescription &Target, for (const StackObject *Object : PreallocatedLocals) { const std::uint64_t LocalOffset = static_cast(*Object->description()->LocalOffset); - if (BlobStart > static_cast(std::numeric_limits::max()) || - LocalOffset > - static_cast(std::numeric_limits::max()) - BlobStart) { + const std::uint64_t Size = Object->description()->Size.value_or(0); + if (BlobStart > std::numeric_limits::max() - LocalOffset || + BlobStart + LocalOffset > std::numeric_limits::max() - Size) { + return makeUnexpected(ErrorCode::FrameLayoutFailed, + "RISC-V local frame offset overflows uint64"); + } + const std::uint64_t End = BlobStart + LocalOffset + Size; + if (End > static_cast(std::numeric_limits::max())) { return makeUnexpected(ErrorCode::FrameLayoutFailed, "RISC-V local frame offset exceeds int64"); } - auto Set = Frame.setObjectOffset(Object->index(), - static_cast(BlobStart + LocalOffset)); + auto Set = Frame.setObjectOffset(Object->index(), -static_cast(End)); if (!Set) return std::unexpected(Set.error()); } @@ -939,15 +968,15 @@ emitSavedRegisterCFI(MachineIRBuilder &Builder, const TargetDescription &Target, return std::unexpected(Added.error()); BaseOffset = *Added; } - } else if (!requiresStackRealignment(Function) && HasFP && - !Instruction.flags().has(MachineInstrFlag::FrameSetup)) { + } else if (!HasFP || requiresBasePointer(Function) || + Instruction.flags().has(MachineInstrFlag::FrameSetup)) { if (Function.frameInfo().state().StackSize > static_cast(std::numeric_limits::max())) { return makeUnexpected(ErrorCode::FrameLayoutFailed, "RISC-V stack size exceeds signed 64-bit range"); } auto Added = - checkedAdd(BaseOffset, -static_cast(Function.frameInfo().state().StackSize)); + checkedAdd(BaseOffset, static_cast(Function.frameInfo().state().StackSize)); if (!Added) return std::unexpected(Added.error()); BaseOffset = *Added; @@ -963,17 +992,21 @@ emitSavedRegisterCFI(MachineIRBuilder &Builder, const TargetDescription &Target, } PhysicalRegisterID BaseID = PhysicalRegisterID::X2; std::int64_t Offset = *Object.Offset; + bool UsesPostAllocationBase = true; if (requiresBasePointer(Function)) { BaseID = PhysicalRegisterID::X9; } else if (requiresFramePointer(Function)) { BaseID = PhysicalRegisterID::X8; + UsesPostAllocationBase = false; + } + if (UsesPostAllocationBase) { if (Function.frameInfo().state().StackSize > static_cast(std::numeric_limits::max())) { return makeUnexpected(ErrorCode::FrameLayoutFailed, "RISC-V stack size exceeds signed 64-bit range"); } auto Adjusted = - checkedAdd(Offset, -static_cast(Function.frameInfo().state().StackSize)); + checkedAdd(Offset, static_cast(Function.frameInfo().state().StackSize)); if (!Adjusted) return std::unexpected(Adjusted.error()); Offset = *Adjusted; @@ -1029,8 +1062,8 @@ emitCalleeSave(MachineIRBuilder &Builder, PhysicalRegister Reg, FrameIndex Index return std::nullopt; } -[[nodiscard]] bool isABIStackSaveRegister(PhysicalRegister Reg) { - return std::ranges::any_of(saveOrder(), [Reg](PhysicalRegisterID ID) { +[[nodiscard]] bool isABIStackSaveRegister(PhysicalRegister Reg, RISCVABI ABI) { + return std::ranges::any_of(saveOrder(ABI), [Reg](PhysicalRegisterID ID) { auto Candidate = physicalRegister(ID); return Candidate && *Candidate == Reg; }); @@ -1038,7 +1071,7 @@ emitCalleeSave(MachineIRBuilder &Builder, PhysicalRegister Reg, FrameIndex Index [[nodiscard]] Expected validateCalleeSaveObjects(const MachineFunction &Function, - std::span SavedRegisters) { + std::span SavedRegisters, RISCVABI ABI) { std::unordered_set Slots; for (const StackObject &Object : Function.frameInfo().objects()) { if (Object.isTombstone() || Object.description()->IsDead || @@ -1047,7 +1080,7 @@ validateCalleeSaveObjects(const MachineFunction &Function, } const StackObjectDesc &Description = *Object.description(); const PhysicalRegister Reg = *Description.CalleeSavedRegister; - if (!isABIStackSaveRegister(Reg)) { + if (!isABIStackSaveRegister(Reg, ABI)) { return makeUnexpected(ErrorCode::VerificationError, "RISC-V callee-save object names a caller-saved register"); } @@ -1133,10 +1166,12 @@ calleeSaveOperations(MachineBasicBlock &Block, const MachineFunction &Function, class RISCVFrameLowering final : public TargetFrameLowering { public: + explicit RISCVFrameLowering(RISCVABI ABI) noexcept : ABI(ABI) {} + [[nodiscard]] bool isCalleeSavedRegister(PhysicalRegister Reg, const MachineFunction &, const TargetDescription &Target) const noexcept override { - return std::ranges::any_of(saveOrder(), [&](PhysicalRegisterID ID) { + return std::ranges::any_of(saveOrder(ABI), [&](PhysicalRegisterID ID) { const auto Candidate = physicalRegister(ID); return Candidate && Target.registers().regsOverlap(Reg, *Candidate); }); @@ -1174,10 +1209,10 @@ public: if (!FrameRegisters) return std::unexpected(FrameRegisters.error()); - auto SavedRegisters = modifiedCalleeSavedRegisters(Function, Target); + auto SavedRegisters = modifiedCalleeSavedRegisters(Function, Target, ABI); if (!SavedRegisters) return std::unexpected(SavedRegisters.error()); - auto ExistingSlots = validateCalleeSaveObjects(Function, *SavedRegisters); + auto ExistingSlots = validateCalleeSaveObjects(Function, *SavedRegisters, ABI); if (!ExistingSlots) return std::unexpected(ExistingSlots.error()); auto Align8 = Alignment::create(8); @@ -1195,7 +1230,7 @@ public: if (!Created) return std::unexpected(Created.error()); } - auto CompleteSlots = validateCalleeSaveObjects(Function, *SavedRegisters); + auto CompleteSlots = validateCalleeSaveObjects(Function, *SavedRegisters, ABI); if (!CompleteSlots) return std::unexpected(CompleteSlots.error()); @@ -1524,7 +1559,7 @@ public: auto CaptureIncomingSP = emitAddImmediate(Builder, *FP, *SP, 0, MachineInstrFlag::FrameSetup); if (!CaptureIncomingSP) return std::unexpected(CaptureIncomingSP.error()); - auto CFA = emitDefCFI(Builder, Target, *FP, 0); + auto CFA = emitDefCFI(Builder, Target, *FP, 0, MachineInstrFlag::FrameSetup); if (!CFA) return std::unexpected(CFA.error()); } @@ -1549,7 +1584,8 @@ public: return std::unexpected(Adjust.error()); } if (!Realign) { - auto CFA = emitDefCFI(Builder, Target, *SP, static_cast(StackSize)); + auto CFA = emitDefCFAOffset(Builder, static_cast(StackSize), + MachineInstrFlag::FrameSetup); if (!CFA) return std::unexpected(CFA.error()); } @@ -1588,8 +1624,8 @@ public: return makeUnexpected(ErrorCode::InternalError, "RISC-V realigned CFI slot is incomplete"); } - auto CFI = - emitSavedRegisterCFI(AfterSaves, Target, Reg, *Object->description()->Offset, *BP); + auto CFI = emitSavedRegisterCFI(AfterSaves, Target, Reg, *Object->description()->Offset, + MachineInstrFlag::FrameSetup, *BP); if (!CFI) return std::unexpected(CFI.error()); } @@ -1604,15 +1640,12 @@ public: return makeUnexpected(ErrorCode::InternalError, "RISC-V callee-save CFI slot is incomplete"); } - auto Offset = - checkedAdd(*Object->description()->Offset, -static_cast(StackSize)); - if (!Offset) - return std::unexpected(Offset.error()); MachineIRBuilder AfterSave(Function, Target); auto PointAfterSave = AfterSave.setInsertPointAfter(*Save.Instruction); if (!PointAfterSave) return std::unexpected(PointAfterSave.error()); - auto CFI = emitSavedRegisterCFI(AfterSave, Target, Save.Reg, *Offset); + auto CFI = emitSavedRegisterCFI(AfterSave, Target, Save.Reg, *Object->description()->Offset, + MachineInstrFlag::FrameSetup); if (!CFI) return std::unexpected(CFI.error()); if (Index + 1U != Saves.size() || !requiresFramePointer(Function)) @@ -1630,7 +1663,7 @@ public: if (!Set) return std::unexpected(Set.error()); } - auto CFA = emitDefCFI(AfterSave, Target, *FP, 0); + auto CFA = emitDefCFI(AfterSave, Target, *FP, 0, MachineInstrFlag::FrameSetup); if (!CFA) return std::unexpected(CFA.error()); } @@ -1648,7 +1681,7 @@ public: if (!Set) return std::unexpected(Set.error()); } - auto CFA = emitDefCFI(Builder, Target, *FP, 0); + auto CFA = emitDefCFI(Builder, Target, *FP, 0, MachineInstrFlag::FrameSetup); if (!CFA) return std::unexpected(CFA.error()); } @@ -1678,7 +1711,6 @@ public: const bool HasFP = requiresFramePointer(Function); const bool Realign = requiresStackRealignment(Function); const std::uint64_t StackSize = Function.frameInfo().state().StackSize; - const bool HasFrameCFI = StackSize != 0 || !Function.records().calleeSavedRegisters().empty(); const std::vector BlockRestores = calleeSaveOperations(Block, Function, true); @@ -1700,18 +1732,6 @@ public: "RISC-V epilogue has an incomplete callee-restore sequence"); } - if (HasFrameCFI) { - MachineIRBuilder RememberBuilder(Function, Target); - auto Point = Restores.empty() - ? RememberBuilder.setInsertPointBefore(Terminator) - : RememberBuilder.setInsertPointBefore(*Restores.front().Instruction); - if (!Point) - return std::unexpected(Point.error()); - auto Remember = emitCFI(RememberBuilder, MachineCFIInstruction::rememberState()); - if (!Remember) - return std::unexpected(Remember.error()); - } - for (const CalleeSaveOperation &Restore : Restores) { if ((HasFP && Restore.Reg == *FP) || (Realign && Restore.Reg == *BP)) continue; @@ -1719,7 +1739,8 @@ public: auto Point = AfterRestore.setInsertPointAfter(*Restore.Instruction); if (!Point) return std::unexpected(Point.error()); - auto CFI = emitRestoreRegisterCFI(AfterRestore, Target, Restore.Reg); + auto CFI = + emitRestoreRegisterCFI(AfterRestore, Target, Restore.Reg, MachineInstrFlag::FrameDestroy); if (!CFI) return std::unexpected(CFI.error()); } @@ -1738,7 +1759,7 @@ public: auto RestoreSP = emitAddImmediate(Teardown, *SP, *FP, 0, MachineInstrFlag::FrameDestroy); if (!RestoreSP) return std::unexpected(RestoreSP.error()); - auto CFA = emitDefCFI(Teardown, Target, *SP, 0); + auto CFA = emitDefCFI(Teardown, Target, *SP, 0, MachineInstrFlag::FrameDestroy); if (!CFA) return std::unexpected(CFA.error()); if (FPRestore != Restores.end()) { @@ -1746,7 +1767,7 @@ public: auto After = AfterFP.setInsertPointAfter(*FPRestore->Instruction); if (!After) return std::unexpected(After.error()); - auto FPCFI = emitRestoreRegisterCFI(AfterFP, Target, *FP); + auto FPCFI = emitRestoreRegisterCFI(AfterFP, Target, *FP, MachineInstrFlag::FrameDestroy); if (!FPCFI) return std::unexpected(FPCFI.error()); } @@ -1755,7 +1776,7 @@ public: auto After = AfterBP.setInsertPointAfter(*BPRestore->Instruction); if (!After) return std::unexpected(After.error()); - auto BPCFI = emitRestoreRegisterCFI(AfterBP, Target, *BP); + auto BPCFI = emitRestoreRegisterCFI(AfterBP, Target, *BP, MachineInstrFlag::FrameDestroy); if (!BPCFI) return std::unexpected(BPCFI.error()); } @@ -1770,7 +1791,7 @@ public: auto RestoreSP = emitAddImmediate(Teardown, *SP, *FP, 0, MachineInstrFlag::FrameDestroy); if (!RestoreSP) return std::unexpected(RestoreSP.error()); - auto CFA = emitDefCFI(Teardown, Target, *SP, 0); + auto CFA = emitDefCFI(Teardown, Target, *SP, 0, MachineInstrFlag::FrameDestroy); if (!CFA) return std::unexpected(CFA.error()); if (FPRestore != Restores.end()) { @@ -1778,7 +1799,7 @@ public: auto After = AfterFP.setInsertPointAfter(*FPRestore->Instruction); if (!After) return std::unexpected(After.error()); - auto FPCFI = emitRestoreRegisterCFI(AfterFP, Target, *FP); + auto FPCFI = emitRestoreRegisterCFI(AfterFP, Target, *FP, MachineInstrFlag::FrameDestroy); if (!FPCFI) return std::unexpected(FPCFI.error()); } @@ -1816,19 +1837,10 @@ public: if (!Adjust) return std::unexpected(Adjust.error()); } - auto CFA = emitDefCFI(Teardown, Target, *SP, 0); + auto CFA = emitDefCFAOffset(Teardown, 0, MachineInstrFlag::FrameDestroy); if (!CFA) return std::unexpected(CFA.error()); } - if (HasFrameCFI) { - MachineIRBuilder RestoreBuilder(Function, Target); - auto After = RestoreBuilder.setInsertPointAfter(Terminator); - if (!After) - return std::unexpected(After.error()); - auto Restore = emitCFI(RestoreBuilder, MachineCFIInstruction::restoreState()); - if (!Restore) - return std::unexpected(Restore.error()); - } return {}; } @@ -2039,13 +2051,16 @@ private: return std::unexpected(Built.error()); return {}; } + + RISCVABI ABI; }; } // namespace -const TargetFrameLowering &frameLowering() noexcept { - static const RISCVFrameLowering Info; - return Info; +const TargetFrameLowering &frameLowering(RISCVABI ABI) noexcept { + static const RISCVFrameLowering LP64Info(RISCVABI::LP64); + static const RISCVFrameLowering LP64DInfo(RISCVABI::LP64D); + return ABI == RISCVABI::LP64D ? LP64DInfo : LP64Info; } } // namespace rcc::riscv diff --git a/backend/lib/Target/RISCV/RISCVOptimizationPipeline.cpp b/backend/lib/Target/RISCV/RISCVOptimizationPipeline.cpp index 7571832..cfc5583 100644 --- a/backend/lib/Target/RISCV/RISCVOptimizationPipeline.cpp +++ b/backend/lib/Target/RISCV/RISCVOptimizationPipeline.cpp @@ -11,7 +11,7 @@ optimizationPipelineInfo(const RISCVSubtarget &Subtarget, bool EmitSchedulerDebu .InstrInfo = instrInfo(), .Combiner = machineCombinerInfo(), .MemoryFolding = memoryFoldingInfo(), - .FrameLowering = frameLowering(), + .FrameLowering = frameLowering(Subtarget.targetABI()), .PseudoExpansion = pseudoExpansionInfo(), .SchedulingModel = Subtarget.schedulingModel(), .SchedulerOptions = {.EmitDebugOutput = EmitSchedulerDebugOutput}, diff --git a/backend/lib/Target/RISCV/RISCVPipeline.cpp b/backend/lib/Target/RISCV/RISCVPipeline.cpp index 2af1d43..cfa09d0 100644 --- a/backend/lib/Target/RISCV/RISCVPipeline.cpp +++ b/backend/lib/Target/RISCV/RISCVPipeline.cpp @@ -29,7 +29,9 @@ namespace rcc::riscv { namespace { [[nodiscard]] LibcallLoweringInfo libcallLoweringInfo(const RISCVSubtarget &Subtarget) { - return {Subtarget.getCallLowering(), callingConventionID(CallingConvention::LP64)}; + const CallingConvention Convention = + Subtarget.targetABI() == RISCVABI::LP64D ? CallingConvention::LP64D : CallingConvention::LP64; + return {Subtarget.getCallLowering(), callingConventionID(Convention)}; } template diff --git a/backend/lib/Target/RISCV/RISCVSubtarget.cpp b/backend/lib/Target/RISCV/RISCVSubtarget.cpp index c30c898..499219b 100644 --- a/backend/lib/Target/RISCV/RISCVSubtarget.cpp +++ b/backend/lib/Target/RISCV/RISCVSubtarget.cpp @@ -102,6 +102,15 @@ constexpr std::array OptionNames{ } // namespace +Expected parseRISCVABI(std::string_view Name) { + if (Name == "lp64") + return RISCVABI::LP64; + if (Name == "lp64d") + return RISCVABI::LP64D; + return makeUnexpected(ErrorCode::InvalidInvocation, + "RISC-V backend does not support target ABI '" + std::string(Name) + "'"); +} + Expected RISCVSubtargetFeatures::fromFeatureList(std::span Features) { std::uint16_t Enabled = extensionBit(RISCVExtension::I); @@ -185,8 +194,8 @@ bool RISCVSubtargetFeatures::hasFeature(std::string_view Feature) const noexcept } RISCVSubtarget::RISCVSubtarget(RISCVSubtargetFeatures Features, RelocationModel Relocation, - CodeModel Code) - : Features(Features), Relocation(Relocation), Code(Code), + CodeModel Code, RISCVABI ABI) + : Features(Features), Relocation(Relocation), Code(Code), ABI(ABI), SchedulingHooks(createSchedulingHooks(Features)) { auto Model = createSchedulingModel(*SchedulingHooks); if (!Model) -- cgit v1.2.3