diff options
author | Philip Reames <preames@rivosinc.com> | 2025-06-02 11:21:41 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-06-02 11:21:41 -0700 |
commit | e723e15db1184824eda53184e1fe7fbf54d42763 (patch) | |
tree | 9635232aab8277506c7fd6cc27cd4afb5ec07dbb /llvm/lib/CodeGen/MachineCopyPropagation.cpp | |
parent | e38375310ea921315bb384457d4ae3271913141a (diff) | |
download | llvm-e723e15db1184824eda53184e1fe7fbf54d42763.zip llvm-e723e15db1184824eda53184e1fe7fbf54d42763.tar.gz llvm-e723e15db1184824eda53184e1fe7fbf54d42763.tar.bz2 |
[MCP] Handle iterative simplification during forward copy prop (#140267)
This is the follow up I mentioned doing in the review of 52b345d. That
change introduced an API for performing instruction simplifications
following copy propagation (e.g. things like recognizing ORI a0, a1,
zero is just a move). As noted in that review, we should be able to
perform iterative simplification as we move forward through the block,
but weren't because of the code structure.
The majority of this code is just deleting the special casing for
constant source and destination tracking, and merging the copy handling
with the main path. By assumption, the properties of copies (in terms of
register reads and writes), must be a subset of general instructions.
Once we do that, the iterative bit basically falls out from having the
tracking performed for copies which are recognized *after* we forward
prior uses.
Diffstat (limited to 'llvm/lib/CodeGen/MachineCopyPropagation.cpp')
-rw-r--r-- | llvm/lib/CodeGen/MachineCopyPropagation.cpp | 99 |
1 files changed, 35 insertions, 64 deletions
diff --git a/llvm/lib/CodeGen/MachineCopyPropagation.cpp b/llvm/lib/CodeGen/MachineCopyPropagation.cpp index 49d62e9..742de11 100644 --- a/llvm/lib/CodeGen/MachineCopyPropagation.cpp +++ b/llvm/lib/CodeGen/MachineCopyPropagation.cpp @@ -872,12 +872,6 @@ void MachineCopyPropagation::forwardUses(MachineInstr &MI) { ++NumCopyForwards; Changed = true; } - // Attempt to canonicalize/optimize the instruction now its arguments have - // been mutated. - if (TII->simplifyInstruction(MI)) { - Changed = true; - LLVM_DEBUG(dbgs() << "MCP: After optimizeInstruction: " << MI); - } } void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) { @@ -889,10 +883,8 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) { std::optional<DestSourcePair> CopyOperands = isCopyInstr(MI, *TII, UseCopyInstr); if (CopyOperands) { - Register RegSrc = CopyOperands->Source->getReg(); Register RegDef = CopyOperands->Destination->getReg(); - if (!TRI->regsOverlap(RegDef, RegSrc)) { assert(RegDef.isPhysical() && RegSrc.isPhysical() && "MachineCopyPropagation should be run after register allocation!"); @@ -917,51 +909,6 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) { // %ecx = COPY %eax if (eraseIfRedundant(MI, Def, Src) || eraseIfRedundant(MI, Src, Def)) continue; - - forwardUses(MI); - - // Src may have been changed by forwardUses() - CopyOperands = isCopyInstr(MI, *TII, UseCopyInstr); - Src = CopyOperands->Source->getReg().asMCReg(); - - // If Src is defined by a previous copy, the previous copy cannot be - // eliminated. - ReadRegister(Src, MI, RegularUse); - for (const MachineOperand &MO : MI.implicit_operands()) { - if (!MO.isReg() || !MO.readsReg()) - continue; - MCRegister Reg = MO.getReg().asMCReg(); - if (!Reg) - continue; - ReadRegister(Reg, MI, RegularUse); - } - - LLVM_DEBUG(dbgs() << "MCP: Copy is a deletion candidate: "; MI.dump()); - - // Copy is now a candidate for deletion. - if (!MRI->isReserved(Def)) - MaybeDeadCopies.insert(&MI); - - // If 'Def' is previously source of another copy, then this earlier copy's - // source is no longer available. e.g. - // %xmm9 = copy %xmm2 - // ... - // %xmm2 = copy %xmm0 - // ... - // %xmm2 = copy %xmm9 - Tracker.clobberRegister(Def, *TRI, *TII, UseCopyInstr); - for (const MachineOperand &MO : MI.implicit_operands()) { - if (!MO.isReg() || !MO.isDef()) - continue; - MCRegister Reg = MO.getReg().asMCReg(); - if (!Reg) - continue; - Tracker.clobberRegister(Reg, *TRI, *TII, UseCopyInstr); - } - - Tracker.trackCopy(&MI, *TRI, *TII, UseCopyInstr); - - continue; } } @@ -979,20 +926,36 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) { forwardUses(MI); - // It's possible that the previous transformation has resulted in a no-op - // register move (i.e. one where source and destination registers are the - // same and are not referring to a reserved register). If so, delete it. - CopyOperands = isCopyInstr(MI, *TII, UseCopyInstr); - if (CopyOperands && - CopyOperands->Source->getReg() == CopyOperands->Destination->getReg() && - !MRI->isReserved(CopyOperands->Source->getReg())) { - MI.eraseFromParent(); - NumDeletes++; + // Attempt to canonicalize/optimize the instruction now its arguments have + // been mutated. This may convert MI from a non-copy to a copy instruction. + if (TII->simplifyInstruction(MI)) { Changed = true; - continue; + LLVM_DEBUG(dbgs() << "MCP: After simplifyInstruction: " << MI); + } + + CopyOperands = isCopyInstr(MI, *TII, UseCopyInstr); + if (CopyOperands) { + Register RegSrc = CopyOperands->Source->getReg(); + Register RegDef = CopyOperands->Destination->getReg(); + // It's possible that the previous transformations have resulted in a + // no-op register move (i.e. one where source and destination registers + // are the same and are not referring to a reserved register). If so, + // delete it. + if (RegSrc == RegDef && !MRI->isReserved(RegSrc)) { + MI.eraseFromParent(); + NumDeletes++; + Changed = true; + continue; + } + + if (!TRI->regsOverlap(RegDef, RegSrc)) { + // Copy is now a candidate for deletion. + MCRegister Def = RegDef.asMCReg(); + if (!MRI->isReserved(Def)) + MaybeDeadCopies.insert(&MI); + } } - // Not a copy. SmallVector<Register, 4> Defs; const MachineOperand *RegMask = nullptr; for (const MachineOperand &MO : MI.operands()) { @@ -1072,6 +1035,14 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) { // Any previous copy definition or reading the Defs is no longer available. for (MCRegister Reg : Defs) Tracker.clobberRegister(Reg, *TRI, *TII, UseCopyInstr); + + if (CopyOperands) { + Register RegSrc = CopyOperands->Source->getReg(); + Register RegDef = CopyOperands->Destination->getReg(); + if (!TRI->regsOverlap(RegDef, RegSrc)) { + Tracker.trackCopy(&MI, *TRI, *TII, UseCopyInstr); + } + } } bool TracksLiveness = MRI->tracksLiveness(); |