From db8980903717e1127463f00a34cae9bd29f82a91 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Wed, 14 Jul 2010 01:22:19 +0000 Subject: [PATCH] Teach ProcessImplicitDefs to transform more COPY instructions into IMPLICIT_DEF (and subsequently eliminate them). This allows machine LICM to hoist IMPLICIT_DEF's. PR7620. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@108304 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/ProcessImplicitDefs.h | 4 +- lib/CodeGen/MachineLICM.cpp | 9 ++-- lib/CodeGen/ProcessImplicitDefs.cpp | 54 ++++++++++++++----- test/CodeGen/X86/2009-02-26-MachineLICMBug.ll | 2 +- 4 files changed, 47 insertions(+), 22 deletions(-) diff --git a/include/llvm/CodeGen/ProcessImplicitDefs.h b/include/llvm/CodeGen/ProcessImplicitDefs.h index cec867f9e6b..30477b9b80b 100644 --- a/include/llvm/CodeGen/ProcessImplicitDefs.h +++ b/include/llvm/CodeGen/ProcessImplicitDefs.h @@ -12,6 +12,7 @@ #define LLVM_CODEGEN_PROCESSIMPLICITDEFS_H #include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/ADT/SmallSet.h" namespace llvm { @@ -24,7 +25,8 @@ namespace llvm { private: bool CanTurnIntoImplicitDef(MachineInstr *MI, unsigned Reg, - unsigned OpIdx, const TargetInstrInfo *tii_); + unsigned OpIdx, const TargetInstrInfo *tii_, + SmallSet &ImpDefRegs); public: static char ID; diff --git a/lib/CodeGen/MachineLICM.cpp b/lib/CodeGen/MachineLICM.cpp index 956d21c0b34..4c054f51f3a 100644 --- a/lib/CodeGen/MachineLICM.cpp +++ b/lib/CodeGen/MachineLICM.cpp @@ -497,11 +497,6 @@ void MachineLICM::HoistRegion(MachineDomTreeNode *N) { /// candidate for LICM. e.g. If the instruction is a call, then it's obviously /// not safe to hoist it. bool MachineLICM::IsLICMCandidate(MachineInstr &I) { - // It is not profitable to hoist implicitdefs. FIXME: Why not? what if they - // are an argument to some other otherwise-hoistable instruction? - if (I.isImplicitDef()) - return false; - // Check if it's safe to move the instruction. bool DontMoveAcrossStore = true; if (!I.isSafeToMove(TII, AA, DontMoveAcrossStore)) @@ -717,7 +712,9 @@ MachineLICM::LookForDuplicate(const MachineInstr *MI, bool MachineLICM::EliminateCSE(MachineInstr *MI, DenseMap >::iterator &CI) { - if (CI == CSEMap.end()) + // Do not CSE implicit_def so ProcessImplicitDefs can properly propagate + // the undef property onto uses. + if (CI == CSEMap.end() || MI->isImplicitDef()) return false; if (const MachineInstr *Dup = LookForDuplicate(MI, CI->second)) { diff --git a/lib/CodeGen/ProcessImplicitDefs.cpp b/lib/CodeGen/ProcessImplicitDefs.cpp index ca4c4771687..2e31908f9fe 100644 --- a/lib/CodeGen/ProcessImplicitDefs.cpp +++ b/lib/CodeGen/ProcessImplicitDefs.cpp @@ -41,21 +41,51 @@ void ProcessImplicitDefs::getAnalysisUsage(AnalysisUsage &AU) const { MachineFunctionPass::getAnalysisUsage(AU); } -bool ProcessImplicitDefs::CanTurnIntoImplicitDef(MachineInstr *MI, - unsigned Reg, unsigned OpIdx, - const TargetInstrInfo *tii_) { +bool +ProcessImplicitDefs::CanTurnIntoImplicitDef(MachineInstr *MI, + unsigned Reg, unsigned OpIdx, + const TargetInstrInfo *tii_, + SmallSet &ImpDefRegs) { unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; if (tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg) && - Reg == SrcReg && DstSubReg == 0) + Reg == SrcReg && + (DstSubReg == 0 || ImpDefRegs.count(DstReg))) return true; switch(OpIdx) { - case 1: return MI->isCopy() && MI->getOperand(0).getSubReg() == 0; - case 2: return MI->isSubregToReg() && MI->getOperand(0).getSubReg() == 0; - default: return false; + case 1: + return MI->isCopy() && (MI->getOperand(0).getSubReg() == 0 || + ImpDefRegs.count(MI->getOperand(0).getReg())); + case 2: + return MI->isSubregToReg() && (MI->getOperand(0).getSubReg() == 0 || + ImpDefRegs.count(MI->getOperand(0).getReg())); + default: return false; } } +static bool isUndefCopy(MachineInstr *MI, unsigned Reg, + const TargetInstrInfo *tii_, + SmallSet &ImpDefRegs) { + if (MI->isCopy()) { + MachineOperand &MO0 = MI->getOperand(0); + MachineOperand &MO1 = MI->getOperand(1); + if (MO1.getReg() != Reg) + return false; + if (!MO0.getSubReg() || ImpDefRegs.count(MO0.getReg())) + return true; + return false; + } + + unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; + if (tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg)) { + if (Reg != SrcReg) + return false; + if (DstSubReg == 0 || ImpDefRegs.count(DstReg)) + return true; + } + return false; +} + /// processImplicitDefs - Process IMPLICIT_DEF instructions and make sure /// there is one implicit_def for each use. Add isUndef marker to /// implicit_def defs and their uses. @@ -104,7 +134,7 @@ bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) { // Eliminate %reg1032:sub = COPY undef. if (MI->isCopy() && MI->getOperand(0).getSubReg()) { MachineOperand &MO = MI->getOperand(1); - if (ImpDefRegs.count(MO.getReg())) { + if (MO.isUndef() || ImpDefRegs.count(MO.getReg())) { if (MO.isKill()) { LiveVariables::VarInfo& vi = lv_->getVarInfo(MO.getReg()); vi.removeKill(MI); @@ -126,7 +156,7 @@ bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) { if (!ImpDefRegs.count(Reg)) continue; // Use is a copy, just turn it into an implicit_def. - if (CanTurnIntoImplicitDef(MI, Reg, i, tii_)) { + if (CanTurnIntoImplicitDef(MI, Reg, i, tii_, ImpDefRegs)) { bool isKill = MO.isKill(); MI->setDesc(tii_->get(TargetOpcode::IMPLICIT_DEF)); for (int j = MI->getNumOperands() - 1, ee = 0; j > ee; --j) @@ -223,11 +253,7 @@ bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) { MachineInstr *RMI = RUses[i]; // Turn a copy use into an implicit_def. - unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; - if ((RMI->isCopy() && RMI->getOperand(1).getReg() == Reg && - RMI->getOperand(0).getSubReg() == 0) || - (tii_->isMoveInstr(*RMI, SrcReg, DstReg, SrcSubReg, DstSubReg) && - Reg == SrcReg && DstSubReg == 0)) { + if (isUndefCopy(RMI, Reg, tii_, ImpDefRegs)) { RMI->setDesc(tii_->get(TargetOpcode::IMPLICIT_DEF)); bool isKill = false; diff --git a/test/CodeGen/X86/2009-02-26-MachineLICMBug.ll b/test/CodeGen/X86/2009-02-26-MachineLICMBug.ll index d9655fd19b3..de2610dae22 100644 --- a/test/CodeGen/X86/2009-02-26-MachineLICMBug.ll +++ b/test/CodeGen/X86/2009-02-26-MachineLICMBug.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86-64 -mattr=+sse3 -stats |& grep {2 machine-licm} +; RUN: llc < %s -march=x86-64 -mattr=+sse3 -stats |& grep {7 machine-licm} ; RUN: llc < %s -march=x86-64 -mattr=+sse3 | FileCheck %s ; rdar://6627786 ; rdar://7792037