aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/MachineCopyPropagation.cpp
diff options
context:
space:
mode:
authorKai Luo <lkail@cn.ibm.com>2019-09-09 02:32:42 +0000
committerKai Luo <lkail@cn.ibm.com>2019-09-09 02:32:42 +0000
commit9115c477bb6e1b686f12941d150e992649646321 (patch)
tree97fd0e09e5e240f821a99e81d34954ff314bcf7b /llvm/lib/CodeGen/MachineCopyPropagation.cpp
parentfb1e77505ae6d91a04cd22624b861b391c5f8b35 (diff)
downloadllvm-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.cpp65
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