aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/MachineCopyPropagation.cpp
diff options
context:
space:
mode:
authorPhilip Reames <preames@rivosinc.com>2025-06-02 11:21:41 -0700
committerGitHub <noreply@github.com>2025-06-02 11:21:41 -0700
commite723e15db1184824eda53184e1fe7fbf54d42763 (patch)
tree9635232aab8277506c7fd6cc27cd4afb5ec07dbb /llvm/lib/CodeGen/MachineCopyPropagation.cpp
parente38375310ea921315bb384457d4ae3271913141a (diff)
downloadllvm-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.cpp99
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();