[llvm-branch-commits] [llvm-branch] r96252 - in /llvm/branches/Apple/Zoidberg: lib/CodeGen/LLVMTargetMachine.cpp lib/CodeGen/OptimizePHIs.cpp test/CodeGen/Thumb2/2010-02-11-phi-cycle.ll test/CodeGen/Thumb2/thumb2-spill-q.ll test/CodeGen/X86/pre-split8.ll test/CodeGen/X86/pre-split9.ll

Bob Wilson bob.wilson at apple.com
Mon Feb 15 11:33:23 PST 2010


Author: bwilson
Date: Mon Feb 15 13:33:23 2010
New Revision: 96252

URL: http://llvm.org/viewvc/llvm-project?rev=96252&view=rev
Log:
--- Merging r96057 into '.':
U    test/CodeGen/X86/pre-split9.ll
U    test/CodeGen/X86/pre-split8.ll
U    test/CodeGen/Thumb2/thumb2-spill-q.ll
U    test/CodeGen/Thumb2/2010-02-11-phi-cycle.ll
U    lib/CodeGen/LLVMTargetMachine.cpp
U    lib/CodeGen/OptimizePHIs.cpp

Modified:
    llvm/branches/Apple/Zoidberg/lib/CodeGen/LLVMTargetMachine.cpp
    llvm/branches/Apple/Zoidberg/lib/CodeGen/OptimizePHIs.cpp
    llvm/branches/Apple/Zoidberg/test/CodeGen/Thumb2/2010-02-11-phi-cycle.ll
    llvm/branches/Apple/Zoidberg/test/CodeGen/Thumb2/thumb2-spill-q.ll
    llvm/branches/Apple/Zoidberg/test/CodeGen/X86/pre-split8.ll
    llvm/branches/Apple/Zoidberg/test/CodeGen/X86/pre-split9.ll

Modified: llvm/branches/Apple/Zoidberg/lib/CodeGen/LLVMTargetMachine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Zoidberg/lib/CodeGen/LLVMTargetMachine.cpp?rev=96252&r1=96251&r2=96252&view=diff

==============================================================================
--- llvm/branches/Apple/Zoidberg/lib/CodeGen/LLVMTargetMachine.cpp (original)
+++ llvm/branches/Apple/Zoidberg/lib/CodeGen/LLVMTargetMachine.cpp Mon Feb 15 13:33:23 2010
@@ -314,6 +314,10 @@
   printAndVerify(PM, "After Instruction Selection",
                  /* allowDoubleDefs= */ true);
 
+  // Optimize PHIs before DCE: removing dead PHI cycles may make more
+  // instructions dead.
+  if (OptLevel != CodeGenOpt::None)
+    PM.add(createOptimizePHIsPass());
 
   // Delete dead machine instructions regardless of optimization level.
   PM.add(createDeadMachineInstructionElimPass());
@@ -321,7 +325,6 @@
                  /* allowDoubleDefs= */ true);
 
   if (OptLevel != CodeGenOpt::None) {
-    PM.add(createOptimizePHIsPass());
     if (!DisableMachineLICM)
       PM.add(createMachineLICMPass());
     if (!DisableMachineSink)

Modified: llvm/branches/Apple/Zoidberg/lib/CodeGen/OptimizePHIs.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Zoidberg/lib/CodeGen/OptimizePHIs.cpp?rev=96252&r1=96251&r2=96252&view=diff

==============================================================================
--- llvm/branches/Apple/Zoidberg/lib/CodeGen/OptimizePHIs.cpp (original)
+++ llvm/branches/Apple/Zoidberg/lib/CodeGen/OptimizePHIs.cpp Mon Feb 15 13:33:23 2010
@@ -19,11 +19,12 @@
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/Target/TargetInstrInfo.h"
 #include "llvm/Function.h"
-#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/Statistic.h"
 using namespace llvm;
 
 STATISTIC(NumPHICycles, "Number of PHI cycles replaced");
+STATISTIC(NumDeadPHICycles, "Number of dead PHI cycles");
 
 namespace {
   class OptimizePHIs : public MachineFunctionPass {
@@ -42,9 +43,13 @@
     }
 
   private:
-    bool IsSingleValuePHICycle(const MachineInstr *MI, unsigned &SingleValReg,
-                               SmallSet<unsigned, 16> &RegsInCycle);
-    bool ReplacePHICycles(MachineBasicBlock &MBB);
+    typedef SmallPtrSet<MachineInstr*, 16> InstrSet;
+    typedef SmallPtrSetIterator<MachineInstr*> InstrSetIterator;
+
+    bool IsSingleValuePHICycle(MachineInstr *MI, unsigned &SingleValReg,
+                               InstrSet &PHIsInCycle);
+    bool IsDeadPHICycle(MachineInstr *MI, InstrSet &PHIsInCycle);
+    bool OptimizeBB(MachineBasicBlock &MBB);
   };
 }
 
@@ -58,12 +63,13 @@
   MRI = &Fn.getRegInfo();
   TII = Fn.getTarget().getInstrInfo();
 
-  // Find PHI cycles that can be replaced by a single value.  InstCombine
-  // does this, but DAG legalization may introduce new opportunities, e.g.,
-  // when i64 values are split up for 32-bit targets.
+  // Find dead PHI cycles and PHI cycles that can be replaced by a single
+  // value.  InstCombine does these optimizations, but DAG legalization may
+  // introduce new opportunities, e.g., when i64 values are split up for
+  // 32-bit targets.
   bool Changed = false;
   for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
-    Changed |= ReplacePHICycles(*I);
+    Changed |= OptimizeBB(*I);
 
   return Changed;
 }
@@ -71,21 +77,21 @@
 /// IsSingleValuePHICycle - Check if MI is a PHI where all the source operands
 /// are copies of SingleValReg, possibly via copies through other PHIs.  If
 /// SingleValReg is zero on entry, it is set to the register with the single
-/// non-copy value.  RegsInCycle is a set used to keep track of the PHIs that
+/// non-copy value.  PHIsInCycle is a set used to keep track of the PHIs that
 /// have been scanned.
-bool OptimizePHIs::IsSingleValuePHICycle(const MachineInstr *MI,
+bool OptimizePHIs::IsSingleValuePHICycle(MachineInstr *MI,
                                          unsigned &SingleValReg,
-                                         SmallSet<unsigned, 16> &RegsInCycle) {
+                                         InstrSet &PHIsInCycle) {
   assert(MI->getOpcode() == TargetInstrInfo::PHI &&
          "IsSingleValuePHICycle expects a PHI instruction");
   unsigned DstReg = MI->getOperand(0).getReg();
 
   // See if we already saw this register.
-  if (!RegsInCycle.insert(DstReg))
+  if (!PHIsInCycle.insert(MI))
     return true;
 
   // Don't scan crazily complex things.
-  if (RegsInCycle.size() == 16)
+  if (PHIsInCycle.size() == 16)
     return false;
 
   // Scan the PHI operands.
@@ -93,7 +99,7 @@
     unsigned SrcReg = MI->getOperand(i).getReg();
     if (SrcReg == DstReg)
       continue;
-    const MachineInstr *SrcMI = MRI->getVRegDef(SrcReg);
+    MachineInstr *SrcMI = MRI->getVRegDef(SrcReg);
 
     // Skip over register-to-register moves.
     unsigned MvSrcReg, MvDstReg, SrcSubIdx, DstSubIdx;
@@ -106,7 +112,7 @@
       return false;
 
     if (SrcMI->getOpcode() == TargetInstrInfo::PHI) {
-      if (!IsSingleValuePHICycle(SrcMI, SingleValReg, RegsInCycle))
+      if (!IsSingleValuePHICycle(SrcMI, SingleValReg, PHIsInCycle))
         return false;
     } else {
       // Fail if there is more than one non-phi/non-move register.
@@ -118,9 +124,37 @@
   return true;
 }
 
-/// ReplacePHICycles - Find PHI cycles that can be replaced by a single
-/// value and remove them.
-bool OptimizePHIs::ReplacePHICycles(MachineBasicBlock &MBB) {
+/// IsDeadPHICycle - Check if the register defined by a PHI is only used by
+/// other PHIs in a cycle.
+bool OptimizePHIs::IsDeadPHICycle(MachineInstr *MI, InstrSet &PHIsInCycle) {
+  assert(MI->getOpcode() == TargetInstrInfo::PHI &&
+         "IsDeadPHICycle expects a PHI instruction");
+  unsigned DstReg = MI->getOperand(0).getReg();
+  assert(TargetRegisterInfo::isVirtualRegister(DstReg) &&
+         "PHI destination is not a virtual register");
+
+  // See if we already saw this register.
+  if (!PHIsInCycle.insert(MI))
+    return true;
+
+  // Don't scan crazily complex things.
+  if (PHIsInCycle.size() == 16)
+    return false;
+
+  for (MachineRegisterInfo::use_iterator I = MRI->use_begin(DstReg),
+         E = MRI->use_end(); I != E; ++I) {
+    MachineInstr *UseMI = &*I;
+    if (UseMI->getOpcode() != TargetInstrInfo::PHI ||
+        !IsDeadPHICycle(UseMI, PHIsInCycle))
+      return false;
+  }
+
+  return true;
+}
+
+/// OptimizeBB - Remove dead PHI cycles and PHI cycles that can be replaced by
+/// a single value.
+bool OptimizePHIs::OptimizeBB(MachineBasicBlock &MBB) {
   bool Changed = false;
   for (MachineBasicBlock::iterator
          MII = MBB.begin(), E = MBB.end(); MII != E; ) {
@@ -128,14 +162,30 @@
     if (MI->getOpcode() != TargetInstrInfo::PHI)
       break;
 
+    // Check for single-value PHI cycles.
     unsigned SingleValReg = 0;
-    SmallSet<unsigned, 16> RegsInCycle;
-    if (IsSingleValuePHICycle(MI, SingleValReg, RegsInCycle) &&
+    InstrSet PHIsInCycle;
+    if (IsSingleValuePHICycle(MI, SingleValReg, PHIsInCycle) &&
         SingleValReg != 0) {
       MRI->replaceRegWith(MI->getOperand(0).getReg(), SingleValReg);
       MI->eraseFromParent();
       ++NumPHICycles;
       Changed = true;
+      continue;
+    }
+
+    // Check for dead PHI cycles.
+    PHIsInCycle.clear();
+    if (IsDeadPHICycle(MI, PHIsInCycle)) {
+      for (InstrSetIterator PI = PHIsInCycle.begin(), PE = PHIsInCycle.end();
+           PI != PE; ++PI) {
+        MachineInstr *PhiMI = *PI;
+        if (&*MII == PhiMI)
+          ++MII;
+        PhiMI->eraseFromParent();
+      }
+      ++NumDeadPHICycles;
+      Changed = true;
     }
   }
   return Changed;

Modified: llvm/branches/Apple/Zoidberg/test/CodeGen/Thumb2/2010-02-11-phi-cycle.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Zoidberg/test/CodeGen/Thumb2/2010-02-11-phi-cycle.ll?rev=96252&r1=96251&r2=96252&view=diff

==============================================================================
--- llvm/branches/Apple/Zoidberg/test/CodeGen/Thumb2/2010-02-11-phi-cycle.ll (original)
+++ llvm/branches/Apple/Zoidberg/test/CodeGen/Thumb2/2010-02-11-phi-cycle.ll Mon Feb 15 13:33:23 2010
@@ -29,6 +29,44 @@
   ret i32 undef
 }
 
+define arm_apcscc i32 @test_dead_cycle(i32 %n) nounwind {
+; CHECK: test_dead_cycle:
+; CHECK: blx
+; CHECK-NOT: mov
+; CHECK: blx
+entry:
+  %0 = icmp eq i32 %n, 1                          ; <i1> [#uses=1]
+  br i1 %0, label %return, label %bb.nph
+
+bb.nph:                                           ; preds = %entry
+  %tmp = add i32 %n, -1                           ; <i32> [#uses=2]
+  br label %bb
+
+bb:                                               ; preds = %bb.nph, %bb2
+  %indvar = phi i32 [ 0, %bb.nph ], [ %indvar.next, %bb2 ] ; <i32> [#uses=2]
+  %u.17 = phi i64 [ undef, %bb.nph ], [ %u.0, %bb2 ] ; <i64> [#uses=2]
+  %tmp9 = sub i32 %tmp, %indvar                   ; <i32> [#uses=1]
+  %1 = icmp sgt i32 %tmp9, 1                      ; <i1> [#uses=1]
+  br i1 %1, label %bb1, label %bb2
+
+bb1:                                              ; preds = %bb
+  %2 = tail call arm_apcscc  i32 @f() nounwind    ; <i32> [#uses=1]
+  %tmp6 = zext i32 %2 to i64                      ; <i64> [#uses=1]
+  %mask = and i64 %u.17, -4294967296              ; <i64> [#uses=1]
+  %ins = or i64 %tmp6, %mask                      ; <i64> [#uses=1]
+  tail call arm_apcscc  void @g(i64 %ins) nounwind
+  br label %bb2
+
+bb2:                                              ; preds = %bb1, %bb
+  %u.0 = phi i64 [ %ins, %bb1 ], [ %u.17, %bb ]   ; <i64> [#uses=2]
+  %indvar.next = add i32 %indvar, 1               ; <i32> [#uses=2]
+  %exitcond = icmp eq i32 %indvar.next, %tmp      ; <i1> [#uses=1]
+  br i1 %exitcond, label %return, label %bb
+
+return:                                           ; preds = %bb2, %entry
+  ret i32 undef
+}
+
 declare arm_apcscc i32 @f()
 
 declare arm_apcscc void @g(i64)

Modified: llvm/branches/Apple/Zoidberg/test/CodeGen/Thumb2/thumb2-spill-q.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Zoidberg/test/CodeGen/Thumb2/thumb2-spill-q.ll?rev=96252&r1=96251&r2=96252&view=diff

==============================================================================
--- llvm/branches/Apple/Zoidberg/test/CodeGen/Thumb2/thumb2-spill-q.ll (original)
+++ llvm/branches/Apple/Zoidberg/test/CodeGen/Thumb2/thumb2-spill-q.ll Mon Feb 15 13:33:23 2010
@@ -12,8 +12,8 @@
 define arm_apcscc void @aaa(%quuz* %this, i8* %block) {
 ; CHECK: aaa:
 ; CHECK: bic r4, r4, #15
-; CHECK: vst1.64 {{.*}}[r{{.*}}, :128]
-; CHECK: vld1.64 {{.*}}[r{{.*}}, :128]
+; CHECK: vst1.64 {{.*}}[{{.*}}, :128]
+; CHECK: vld1.64 {{.*}}[{{.*}}, :128]
 entry:
   %0 = call <4 x float> @llvm.arm.neon.vld1.v4f32(i8* undef) nounwind ; <<4 x float>> [#uses=1]
   store float 6.300000e+01, float* undef, align 4

Modified: llvm/branches/Apple/Zoidberg/test/CodeGen/X86/pre-split8.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Zoidberg/test/CodeGen/X86/pre-split8.ll?rev=96252&r1=96251&r2=96252&view=diff

==============================================================================
--- llvm/branches/Apple/Zoidberg/test/CodeGen/X86/pre-split8.ll (original)
+++ llvm/branches/Apple/Zoidberg/test/CodeGen/X86/pre-split8.ll Mon Feb 15 13:33:23 2010
@@ -20,7 +20,7 @@
 
 bb9.i:		; preds = %bb
 	%2 = fsub double %.rle4, %0		; <double> [#uses=0]
-	%3 = tail call double @asin(double 0.000000e+00) nounwind readonly		; <double> [#uses=0]
+	%3 = tail call double @asin(double %.rle4) nounwind readonly		; <double> [#uses=0]
 	%4 = fmul double 0.000000e+00, %0		; <double> [#uses=1]
 	%5 = tail call double @tan(double 0.000000e+00) nounwind readonly		; <double> [#uses=0]
 	%6 = fmul double %4, 0.000000e+00		; <double> [#uses=1]

Modified: llvm/branches/Apple/Zoidberg/test/CodeGen/X86/pre-split9.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Zoidberg/test/CodeGen/X86/pre-split9.ll?rev=96252&r1=96251&r2=96252&view=diff

==============================================================================
--- llvm/branches/Apple/Zoidberg/test/CodeGen/X86/pre-split9.ll (original)
+++ llvm/branches/Apple/Zoidberg/test/CodeGen/X86/pre-split9.ll Mon Feb 15 13:33:23 2010
@@ -22,7 +22,7 @@
 
 bb9.i:		; preds = %bb
 	%2 = fsub double %.rle4, %0		; <double> [#uses=0]
-	%3 = tail call double @asin(double 0.000000e+00) nounwind readonly		; <double> [#uses=0]
+	%3 = tail call double @asin(double %.rle4) nounwind readonly		; <double> [#uses=0]
 	%4 = tail call double @sin(double 0.000000e+00) nounwind readonly		; <double> [#uses=1]
 	%5 = fmul double %4, %0		; <double> [#uses=1]
 	%6 = tail call double @tan(double 0.000000e+00) nounwind readonly		; <double> [#uses=0]





More information about the llvm-branch-commits mailing list