[llvm-commits] [llvm] r103039 - in /llvm/trunk/lib/CodeGen: LiveIntervalAnalysis.cpp PHIElimination.cpp PHIElimination.h

Evan Cheng evan.cheng at apple.com
Tue May 4 13:26:52 PDT 2010


Author: evancheng
Date: Tue May  4 15:26:52 2010
New Revision: 103039

URL: http://llvm.org/viewvc/llvm-project?rev=103039&view=rev
Log:
Teach PHI elimination to remove REG_SEQUENCE instructions and update references of the source operands with references of the destination with subreg indices. e.g.
%reg1029<def>, %reg1030<def> = VLD1q16 %reg1024<kill>, ...
%reg1031<def> = REG_SEQUENCE %reg1029<kill>, 5, %reg1030<kill>, 6
=>
%reg1031:5<def>, %reg1031:6<def> = VLD1q16 %reg1024<kill>, ...

PHI elimination now does more than phi elimination. It is really a de-SSA pass.

Modified:
    llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp
    llvm/trunk/lib/CodeGen/PHIElimination.cpp
    llvm/trunk/lib/CodeGen/PHIElimination.h

Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=103039&r1=103038&r2=103039&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original)
+++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Tue May  4 15:26:52 2010
@@ -262,6 +262,23 @@
 }
 #endif
 
+static
+bool MultipleDefsByMI(const MachineInstr &MI, unsigned MOIdx) {
+  unsigned Reg = MI.getOperand(MOIdx).getReg();
+  for (unsigned i = MOIdx+1, e = MI.getNumOperands(); i < e; ++i) {
+    const MachineOperand &MO = MI.getOperand(i);
+    if (!MO.isReg())
+      continue;
+    if (MO.getReg() == Reg && MO.isDef()) {
+      assert(MI.getOperand(MOIdx).getSubReg() != MO.getSubReg() &&
+             MI.getOperand(MOIdx).getSubReg() &&
+             MO.getSubReg());
+      return true;
+    }
+  }
+  return false;
+}
+
 void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
                                              MachineBasicBlock::iterator mi,
                                              SlotIndex MIIdx,
@@ -372,6 +389,13 @@
     }
 
   } else {
+    if (MultipleDefsByMI(*mi, MOIdx))
+      // Mutple defs of the same virtual register by the same instruction. e.g.
+      // %reg1031:5<def>, %reg1031:6<def> = VLD1q16 %reg1024<kill>, ...
+      // This is likely due to elimination of REG_SEQUENCE instructions. Return
+      // here since there is nothing to do.
+      return;
+
     // If this is the second time we see a virtual register definition, it
     // must be due to phi elimination or two addr elimination.  If this is
     // the result of two address elimination, then the vreg is one of the

Modified: llvm/trunk/lib/CodeGen/PHIElimination.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PHIElimination.cpp?rev=103039&r1=103038&r2=103039&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/PHIElimination.cpp (original)
+++ llvm/trunk/lib/CodeGen/PHIElimination.cpp Tue May  4 15:26:52 2010
@@ -30,6 +30,7 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
 #include <algorithm>
 #include <map>
 using namespace llvm;
@@ -87,6 +88,10 @@
   ImpDefs.clear();
   VRegPHIUseCount.clear();
 
+  // Eliminate REG_SEQUENCE instructions. Their whole purpose was to preseve
+  // SSA form.
+  Changed |= EliminateRegSequences(MF);
+
   return Changed;
 }
 
@@ -444,3 +449,58 @@
 
   return NMBB;
 }
+
+static void UpdateRegSequenceSrcs(unsigned SrcReg,
+                                  unsigned DstReg, unsigned SrcIdx,
+                                  MachineRegisterInfo *MRI) {
+  for (MachineRegisterInfo::reg_iterator RI = MRI->reg_begin(SrcReg),
+         UE = MRI->reg_end(); RI != UE; ) {
+    MachineOperand &MO = RI.getOperand();
+    ++RI;
+    MO.setReg(DstReg);
+    MO.setSubReg(SrcIdx);
+  }
+}
+
+/// EliminateRegSequences - Eliminate REG_SEQUENCE instructions as second part
+/// of de-ssa process. This replaces sources of REG_SEQUENCE as sub-register
+/// references of the register defined by REG_SEQUENCE. e.g.
+///
+/// %reg1029<def>, %reg1030<def> = VLD1q16 %reg1024<kill>, ...
+/// %reg1031<def> = REG_SEQUENCE %reg1029<kill>, 5, %reg1030<kill>, 6
+/// =>
+/// %reg1031:5<def>, %reg1031:6<def> = VLD1q16 %reg1024<kill>, ...
+bool PHIElimination::EliminateRegSequences(MachineFunction &MF) {
+  bool Changed = false;
+
+  for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I)
+    for (MachineBasicBlock::iterator BBI = I->begin(), BBE = I->end();
+         BBI != BBE; ) {
+      MachineInstr &MI = *BBI;
+      ++BBI;
+      if (MI.getOpcode() != TargetOpcode::REG_SEQUENCE)
+        continue;
+      unsigned DstReg = MI.getOperand(0).getReg();
+      if (MI.getOperand(0).getSubReg() ||
+          TargetRegisterInfo::isPhysicalRegister(DstReg) ||
+          !(MI.getNumOperands() & 1)) {
+        DEBUG(dbgs() << "Illegal REG_SEQUENCE instruction:" << MI);
+        llvm_unreachable(0);
+      }
+      for (unsigned i = 1, e = MI.getNumOperands(); i < e; i += 2) {
+        unsigned SrcReg = MI.getOperand(i).getReg();
+        if (MI.getOperand(i).getSubReg() ||
+            TargetRegisterInfo::isPhysicalRegister(SrcReg)) {
+          DEBUG(dbgs() << "Illegal REG_SEQUENCE instruction:" << MI);
+          llvm_unreachable(0);
+        }
+        unsigned SrcIdx = MI.getOperand(i+1).getImm();
+        UpdateRegSequenceSrcs(SrcReg, DstReg, SrcIdx, MRI);
+      }
+
+      MI.eraseFromParent();
+      Changed = true;
+    }
+
+  return Changed;
+}

Modified: llvm/trunk/lib/CodeGen/PHIElimination.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PHIElimination.h?rev=103039&r1=103038&r2=103039&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/PHIElimination.h (original)
+++ llvm/trunk/lib/CodeGen/PHIElimination.h Tue May  4 15:26:52 2010
@@ -94,6 +94,8 @@
       return I;
     }
 
+    bool EliminateRegSequences(MachineFunction &MF);
+
     typedef std::pair<unsigned, unsigned> BBVRegPair;
     typedef DenseMap<BBVRegPair, unsigned> VRegPHIUse;
 





More information about the llvm-commits mailing list