From da8bc76b4bf7d1a7b025d6c8ef5809551467dcc7 Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Sun, 9 Aug 2026 13:23:48 +0800 Subject: [CodeGen] Implement RV64GC frame lowering --- backend/lib/CodeGen/FrameIndexElimination.cpp | 61 +++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 backend/lib/CodeGen/FrameIndexElimination.cpp (limited to 'backend/lib/CodeGen/FrameIndexElimination.cpp') diff --git a/backend/lib/CodeGen/FrameIndexElimination.cpp b/backend/lib/CodeGen/FrameIndexElimination.cpp new file mode 100644 index 0000000..53c64e1 --- /dev/null +++ b/backend/lib/CodeGen/FrameIndexElimination.cpp @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "rcc/CodeGen/FrameIndexElimination.h" + +#include "rcc/CodeGen/MachineBasicBlock.h" +#include "rcc/CodeGen/MachineFunction.h" +#include "rcc/CodeGen/MachineInstr.h" +#include "rcc/CodeGen/MachineMemOperand.h" +#include "rcc/CodeGen/MachineOperand.h" +#include "rcc/CodeGen/RegisterScavenger.h" +#include "rcc/CodeGen/TargetFrameLowering.h" + +#include +#include + +namespace rcc { + +Expected eliminateFrameIndices(MachineFunction &Function, const TargetDescription &Target, + const TargetFrameLowering &FrameLowering, + RegisterScavenger &Scavenger) { + bool Changed = false; + for (MachineBasicBlock *Block = Function.firstBlock(); Block != nullptr; Block = Block->next()) { + for (MachineInstr *Instruction = Block->firstInstruction(); Instruction != nullptr;) { + MachineInstr *Next = Instruction->next(); + for (std::size_t Index = 0; Index < Instruction->operandCount(); ++Index) { + if (Instruction->operandAt(Index)->kind() != MachineOperand::Kind::FrameIndex) + continue; + auto Eliminated = + FrameLowering.eliminateFrameIndex(*Instruction, Index, Function, Target, Scavenger); + if (!Eliminated) + return std::unexpected(Eliminated.error()); + Changed = true; + } + + for (std::size_t Index = 0; Index < Instruction->memOperands().size(); ++Index) { + const MachineMemOperand *Memory = Instruction->memOperands()[Index]; + const auto Frame = Memory->description().Base.frameIndex(); + if (!Frame) + continue; + auto Reference = FrameLowering.getFrameIndexReference(Function, *Instruction, *Frame, + Memory->description().Offset); + if (!Reference) + return std::unexpected(Reference.error()); + MachineMemOperandDesc Description = Memory->description(); + Description.Base = MemoryBase::stack(); + Description.Offset = Reference->Offset; + auto Replacement = Function.createMemOperand(std::move(Description)); + if (!Replacement) + return std::unexpected(Replacement.error()); + auto Replaced = Instruction->replaceMemOperand(Index, **Replacement); + if (!Replaced) + return std::unexpected(Replaced.error()); + Changed = true; + } + Instruction = Next; + } + } + return Changed; +} + +} // namespace rcc -- cgit v1.2.3