[llvm-commits] [llvm] r108304 - in /llvm/trunk: include/llvm/CodeGen/ProcessImplicitDefs.h lib/CodeGen/MachineLICM.cpp lib/CodeGen/ProcessImplicitDefs.cpp test/CodeGen/X86/2009-02-26-MachineLICMBug.ll

Evan Cheng evan.cheng at apple.com
Tue Jul 13 18:22:19 PDT 2010


Author: evancheng
Date: Tue Jul 13 20:22:19 2010
New Revision: 108304

URL: http://llvm.org/viewvc/llvm-project?rev=108304&view=rev
Log:
Teach ProcessImplicitDefs to transform more COPY instructions into IMPLICIT_DEF (and subsequently eliminate them). This allows machine LICM to hoist IMPLICIT_DEF's. PR7620.

Modified:
    llvm/trunk/include/llvm/CodeGen/ProcessImplicitDefs.h
    llvm/trunk/lib/CodeGen/MachineLICM.cpp
    llvm/trunk/lib/CodeGen/ProcessImplicitDefs.cpp
    llvm/trunk/test/CodeGen/X86/2009-02-26-MachineLICMBug.ll

Modified: llvm/trunk/include/llvm/CodeGen/ProcessImplicitDefs.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ProcessImplicitDefs.h?rev=108304&r1=108303&r2=108304&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/ProcessImplicitDefs.h (original)
+++ llvm/trunk/include/llvm/CodeGen/ProcessImplicitDefs.h Tue Jul 13 20:22:19 2010
@@ -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 @@
   private:
 
     bool CanTurnIntoImplicitDef(MachineInstr *MI, unsigned Reg,
-                                unsigned OpIdx, const TargetInstrInfo *tii_);
+                                unsigned OpIdx, const TargetInstrInfo *tii_,
+                                SmallSet<unsigned, 8> &ImpDefRegs);
 
   public:
     static char ID;

Modified: llvm/trunk/lib/CodeGen/MachineLICM.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineLICM.cpp?rev=108304&r1=108303&r2=108304&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineLICM.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineLICM.cpp Tue Jul 13 20:22:19 2010
@@ -497,11 +497,6 @@
 /// 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 @@
 
 bool MachineLICM::EliminateCSE(MachineInstr *MI,
           DenseMap<unsigned, std::vector<const MachineInstr*> >::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)) {

Modified: llvm/trunk/lib/CodeGen/ProcessImplicitDefs.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ProcessImplicitDefs.cpp?rev=108304&r1=108303&r2=108304&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/ProcessImplicitDefs.cpp (original)
+++ llvm/trunk/lib/CodeGen/ProcessImplicitDefs.cpp Tue Jul 13 20:22:19 2010
@@ -41,21 +41,51 @@
   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<unsigned, 8> &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<unsigned, 8> &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 @@
       // Eliminate %reg1032:sub<def> = 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 @@
         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 @@
         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;

Modified: llvm/trunk/test/CodeGen/X86/2009-02-26-MachineLICMBug.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2009-02-26-MachineLICMBug.ll?rev=108304&r1=108303&r2=108304&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/2009-02-26-MachineLICMBug.ll (original)
+++ llvm/trunk/test/CodeGen/X86/2009-02-26-MachineLICMBug.ll Tue Jul 13 20:22:19 2010
@@ -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





More information about the llvm-commits mailing list