diff options
| author | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-17 02:30:52 +0800 |
|---|---|---|
| committer | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-17 02:30:52 +0800 |
| commit | 125bee29ffbc64a5f8dc488d04cecf10ed26f98e (patch) | |
| tree | 2e72a0a67ba79a6a7d9594663092f8ad665828b9 /backend/lib/CodeGen/GlobalISel/InstructionSelect.cpp | |
| parent | f6a3a06de3d32eaeba1f3c8bbc5faa5ffaeb1128 (diff) | |
| download | rcc-project-125bee29ffbc64a5f8dc488d04cecf10ed26f98e.tar.gz rcc-project-125bee29ffbc64a5f8dc488d04cecf10ed26f98e.tar.xz | |
[GlobalISel] Remove redundant virtual copies after selection
Diffstat (limited to 'backend/lib/CodeGen/GlobalISel/InstructionSelect.cpp')
| -rw-r--r-- | backend/lib/CodeGen/GlobalISel/InstructionSelect.cpp | 44 |
1 files changed, 42 insertions, 2 deletions
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<void> InstructionSelector::propagateSelectionFlags(MachineInstr &Output Expected<void> 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<MachinePassResult> 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<Register>(); + const Register *Destination = + DestinationOperand == nullptr ? nullptr : DestinationOperand->getIf<Register>(); + 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(), |
