From 125bee29ffbc64a5f8dc488d04cecf10ed26f98e Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Mon, 17 Aug 2026 02:30:52 +0800 Subject: [GlobalISel] Remove redundant virtual copies after selection --- .../lib/CodeGen/GlobalISel/InstructionSelect.cpp | 44 +++++++++++++++++++++- 1 file changed, 42 insertions(+), 2 deletions(-) (limited to 'backend/lib') diff --git a/backend/lib/CodeGen/GlobalISel/InstructionSelect.cpp b/backend/lib/CodeGen/GlobalISel/InstructionSelect.cpp index 2e61d8e..1048843 100644 --- a/backend/lib/CodeGen/GlobalISel/InstructionSelect.cpp +++ b/backend/lib/CodeGen/GlobalISel/InstructionSelect.cpp @@ -2,6 +2,7 @@ #include "rcc/CodeGen/GlobalISel/InstructionSelect.h" +#include "rcc/CodeGen/GenericOpcodes.h" #include "rcc/CodeGen/GlobalISel/Utils.h" #include "rcc/CodeGen/MachineBasicBlock.h" #include "rcc/CodeGen/MachineFunction.h" @@ -202,8 +203,7 @@ Expected InstructionSelector::propagateSelectionFlags(MachineInstr &Output Expected InstructionSelector::finalizeGeneratedInstruction( MachineInstr &Output, MachineFunction &Function, const TargetDescription &Target, MachineInstrFlags InputFlags, bool InputMayRaiseFPException) const { - auto Flags = - propagateSelectionFlags(Output, InputFlags, InputMayRaiseFPException, Target); + auto Flags = propagateSelectionFlags(Output, InputFlags, InputMayRaiseFPException, Target); if (!Flags) return std::unexpected(Flags.error()); return constrainSelectedInstruction(Output, Function, Target); @@ -368,6 +368,46 @@ Expected InstructionSelect::runImplementation(MachineFunction return std::unexpected( passFailure("instruction selector left a generic opcode in the function")); } + for (MachineBasicBlock *Block = Function.firstBlock(); Block != nullptr; Block = Block->next()) { + for (MachineInstr *Instruction = Block->lastInstruction(); Instruction != nullptr;) { + MachineInstr *Previous = Instruction->previous(); + if (Instruction->opcode() != opcode(GenericOpcode::COPY)) { + Instruction = Previous; + continue; + } + const MachineOperand *SourceOperand = Instruction->operandAt(1); + const MachineOperand *DestinationOperand = Instruction->operandAt(0); + const Register *Source = + SourceOperand == nullptr ? nullptr : SourceOperand->getIf(); + const Register *Destination = + DestinationOperand == nullptr ? nullptr : DestinationOperand->getIf(); + if (Source == nullptr || Destination == nullptr || !Source->isVirtual() || + !Destination->isVirtual() || SourceOperand->subReg().value() != 0) { + Instruction = Previous; + continue; + } + auto SourceInfo = Function.registerInfo().virtualRegisterInfo(*Source); + if (!SourceInfo) + return std::unexpected(SourceInfo.error()); + auto DestinationInfo = Function.registerInfo().virtualRegisterInfo(*Destination); + if (!DestinationInfo) + return std::unexpected(DestinationInfo.error()); + if (!SourceInfo->get().RegClass || + SourceInfo->get().RegClass != DestinationInfo->get().RegClass) { + Instruction = Previous; + continue; + } + auto Replaced = Function.registerInfo().replaceRegWith(*Destination, *Source); + if (!Replaced) + return std::unexpected(Replaced.error()); + auto Removed = Block->removeInstruction(*Instruction); + if (!Removed) + return std::unexpected(Removed.error()); + Result.Changed = true; + Result.Changes.add(MachinePassChange::Instructions); + Instruction = Previous; + } + } auto RegisterValidation = Target.validateRegisterInfo(Function.registerInfo()); if (!RegisterValidation) return std::unexpected(withErrorContext(RegisterValidation.error(), -- cgit v1.2.3