From 377552607e51dc1d3e6ff33833f9620bcfe815ac Mon Sep 17 00:00:00 2001
From: rdivacky <rdivacky@FreeBSD.org>
Date: Tue, 4 May 2010 20:50:39 +0000
Subject: Update LLVM to r103052.

---
 lib/CodeGen/PHIElimination.cpp | 81 ++++++++++++++++++++++++++++++++++++------
 1 file changed, 71 insertions(+), 10 deletions(-)

(limited to 'lib/CodeGen/PHIElimination.cpp')

diff --git a/lib/CodeGen/PHIElimination.cpp b/lib/CodeGen/PHIElimination.cpp
index f0057ce..1651719 100644
--- a/lib/CodeGen/PHIElimination.cpp
+++ b/lib/CodeGen/PHIElimination.cpp
@@ -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;
@@ -52,22 +53,22 @@ void llvm::PHIElimination::getAnalysisUsage(AnalysisUsage &AU) const {
   MachineFunctionPass::getAnalysisUsage(AU);
 }
 
-bool llvm::PHIElimination::runOnMachineFunction(MachineFunction &Fn) {
-  MRI = &Fn.getRegInfo();
+bool llvm::PHIElimination::runOnMachineFunction(MachineFunction &MF) {
+  MRI = &MF.getRegInfo();
 
   bool Changed = false;
 
   // Split critical edges to help the coalescer
   if (LiveVariables *LV = getAnalysisIfAvailable<LiveVariables>())
-    for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
-      Changed |= SplitPHIEdges(Fn, *I, *LV);
+    for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I)
+      Changed |= SplitPHIEdges(MF, *I, *LV);
 
   // Populate VRegPHIUseCount
-  analyzePHINodes(Fn);
+  analyzePHINodes(MF);
 
   // Eliminate PHI instructions by inserting copies into predecessor blocks.
-  for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
-    Changed |= EliminatePHINodes(Fn, *I);
+  for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I)
+    Changed |= EliminatePHINodes(MF, *I);
 
   // Remove dead IMPLICIT_DEF instructions.
   for (SmallPtrSet<MachineInstr*, 4>::iterator I = ImpDefs.begin(),
@@ -81,11 +82,16 @@ bool llvm::PHIElimination::runOnMachineFunction(MachineFunction &Fn) {
   // Clean up the lowered PHI instructions.
   for (LoweredPHIMap::iterator I = LoweredPHIs.begin(), E = LoweredPHIs.end();
        I != E; ++I)
-    Fn.DeleteMachineInstr(I->first);
+    MF.DeleteMachineInstr(I->first);
 
   LoweredPHIs.clear();
   ImpDefs.clear();
   VRegPHIUseCount.clear();
+
+  // Eliminate REG_SEQUENCE instructions. Their whole purpose was to preseve
+  // SSA form.
+  Changed |= EliminateRegSequences(MF);
+
   return Changed;
 }
 
@@ -364,8 +370,8 @@ void llvm::PHIElimination::LowerAtomicPHINode(
 /// used in a PHI node. We map that to the BB the vreg is coming from. This is
 /// used later to determine when the vreg is killed in the BB.
 ///
-void llvm::PHIElimination::analyzePHINodes(const MachineFunction& Fn) {
-  for (MachineFunction::const_iterator I = Fn.begin(), E = Fn.end();
+void llvm::PHIElimination::analyzePHINodes(const MachineFunction& MF) {
+  for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
        I != E; ++I)
     for (MachineBasicBlock::const_iterator BBI = I->begin(), BBE = I->end();
          BBI != BBE && BBI->isPHI(); ++BBI)
@@ -443,3 +449,58 @@ MachineBasicBlock *PHIElimination::SplitCriticalEdge(MachineBasicBlock *A,
 
   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;
+}
-- 
cgit v1.1