diff options
author | Kai Luo <lkail@cn.ibm.com> | 2019-09-09 02:32:42 +0000 |
---|---|---|
committer | Kai Luo <lkail@cn.ibm.com> | 2019-09-09 02:32:42 +0000 |
commit | 9115c477bb6e1b686f12941d150e992649646321 (patch) | |
tree | 97fd0e09e5e240f821a99e81d34954ff314bcf7b /llvm/lib/CodeGen/MachineCopyPropagation.cpp | |
parent | fb1e77505ae6d91a04cd22624b861b391c5f8b35 (diff) | |
download | llvm-9115c477bb6e1b686f12941d150e992649646321.zip llvm-9115c477bb6e1b686f12941d150e992649646321.tar.gz llvm-9115c477bb6e1b686f12941d150e992649646321.tar.bz2 |
[MachineCopyPropagation] Remove redundant copies after TailDup via machine-cp
Summary:
After tailduplication, we have redundant copies. We can remove these
copies in machine-cp if it's safe to, i.e.
```
$reg0 = OP ...
... <<< No read or clobber of $reg0 and $reg1
$reg1 = COPY $reg0 <<< $reg0 is killed
...
<RET>
```
will be transformed to
```
$reg1 = OP ...
...
<RET>
```
Differential Revision: https://reviews.llvm.org/D65267
llvm-svn: 371359
Diffstat (limited to 'llvm/lib/CodeGen/MachineCopyPropagation.cpp')
-rw-r--r-- | llvm/lib/CodeGen/MachineCopyPropagation.cpp | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/MachineCopyPropagation.cpp b/llvm/lib/CodeGen/MachineCopyPropagation.cpp index ebe76e3..aa9d733 100644 --- a/llvm/lib/CodeGen/MachineCopyPropagation.cpp +++ b/llvm/lib/CodeGen/MachineCopyPropagation.cpp @@ -68,6 +68,7 @@ using namespace llvm; STATISTIC(NumDeletes, "Number of dead copies deleted"); STATISTIC(NumCopyForwards, "Number of copy uses forwarded"); +STATISTIC(NumCopyBackwardPropagated, "Number of copy defs backward propagated"); DEBUG_COUNTER(FwdCounter, "machine-cp-fwd", "Controls which register COPYs are forwarded"); @@ -211,11 +212,13 @@ private: void ReadRegister(unsigned Reg, MachineInstr &Reader, DebugType DT); void CopyPropagateBlock(MachineBasicBlock &MBB); + bool eraseIfRedundant(MachineInstr &Copy); bool eraseIfRedundant(MachineInstr &Copy, unsigned Src, unsigned Def); void forwardUses(MachineInstr &MI); bool isForwardableRegClassCopy(const MachineInstr &Copy, const MachineInstr &UseI, unsigned UseIdx); bool hasImplicitOverlap(const MachineInstr &MI, const MachineOperand &Use); + bool isSafeBackwardCopyPropagation(MachineInstr &Copy, MachineInstr &SrcMI); /// Candidates for deletion. SmallSetVector<MachineInstr *, 8> MaybeDeadCopies; @@ -274,6 +277,57 @@ static bool isNopCopy(const MachineInstr &PreviousCopy, unsigned Src, return SubIdx == TRI->getSubRegIndex(PreviousDef, Def); } +bool MachineCopyPropagation::isSafeBackwardCopyPropagation( + MachineInstr &Copy, MachineInstr &SrcMI) { + MachineOperand &SrcOp = SrcMI.getOperand(0); + if (!(SrcOp.isReg() && SrcOp.isDef() && + SrcOp.getReg() == Copy.getOperand(1).getReg() && SrcOp.isRenamable() && + !SrcOp.isTied() && !SrcOp.isImplicit() && + !MRI->isReserved(SrcOp.getReg()))) + return false; + if (const TargetRegisterClass *URC = SrcMI.getRegClassConstraint(0, TII, TRI)) + return URC->contains(Copy.getOperand(0).getReg()); + return false; +} + +/// In a terminal BB, remove instruction \p Copy if \p Copy's src and dst are +/// not used or defined between \p Copy and definition point of \p Copy's src. +/// \p Copy's dst will be backward propagated to where \p Copy's src is defined. +bool MachineCopyPropagation::eraseIfRedundant(MachineInstr &Copy) { + // Only take terminal BBs into account. + if (!Copy.getParent()->succ_empty()) + return false; + if (!Copy.getOperand(1).isRenamable() || !Copy.getOperand(1).isKill()) + return false; + unsigned Def = Copy.getOperand(0).getReg(); + unsigned Src = Copy.getOperand(1).getReg(); + if (MRI->isReserved(Src) || MRI->isReserved(Def)) + return false; + MachineBasicBlock::reverse_iterator E = Copy.getParent()->rend(), It = Copy; + It++; + MachineInstr *SrcMI = nullptr; + for (; It != E; ++It) { + if (It->readsRegister(Src, TRI) || It->readsRegister(Def, TRI)) + return false; + if (It->modifiesRegister(Def, TRI)) + return false; + if (It->modifiesRegister(Src, TRI)) { + SrcMI = &*It; + break; + } + } + if (!SrcMI) + return false; + if (!isSafeBackwardCopyPropagation(Copy, *SrcMI)) + return false; + SrcMI->getOperand(0).setReg(Def); + SrcMI->getOperand(0).setIsRenamable(Copy.getOperand(0).isRenamable()); + Copy.eraseFromParent(); + ++NumCopyBackwardPropagated; + ++NumDeletes; + return true; +} + /// Remove instruction \p Copy if there exists a previous copy that copies the /// register \p Src to the register \p Def; This may happen indirectly by /// copying the super registers. @@ -475,6 +529,17 @@ void MachineCopyPropagation::CopyPropagateBlock(MachineBasicBlock &MBB) { !Register::isVirtualRegister(Src) && "MachineCopyPropagation should be run after register allocation!"); + // In a terminal BB, + // $reg0 = OP ... + // ... <<< No uses of $reg0 and $reg1, no defs of $reg0 and $reg1 + // $reg1 = COPY $reg0 <<< $reg0 is killed + // => + // $reg1 = OP ... + // ... + // <RET> + if (eraseIfRedundant(*MI)) + continue; + // The two copies cancel out and the source of the first copy // hasn't been overridden, eliminate the second one. e.g. // %ecx = COPY %eax |