[llvm-commits] [llvm] r90432 - /llvm/trunk/lib/CodeGen/TailDuplication.cpp

Evan Cheng evan.cheng at apple.com
Thu Dec 3 00:43:53 PST 2009


Author: evancheng
Date: Thu Dec  3 02:43:53 2009
New Revision: 90432

URL: http://llvm.org/viewvc/llvm-project?rev=90432&view=rev
Log:
Teach tail duplication to update SSA form. Work in progress.

Modified:
    llvm/trunk/lib/CodeGen/TailDuplication.cpp

Modified: llvm/trunk/lib/CodeGen/TailDuplication.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TailDuplication.cpp?rev=90432&r1=90431&r2=90432&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/TailDuplication.cpp (original)
+++ llvm/trunk/lib/CodeGen/TailDuplication.cpp Thu Dec  3 02:43:53 2009
@@ -17,6 +17,8 @@
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/MachineSSAUpdater.h"
 #include "llvm/Target/TargetInstrInfo.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
@@ -36,11 +38,21 @@
                   cl::desc("Maximum instructions to consider tail duplicating"),
                   cl::init(2), cl::Hidden);
 
+typedef std::vector<unsigned> AvailableValsTy;
+
 namespace {
   /// TailDuplicatePass - Perform tail duplication.
   class TailDuplicatePass : public MachineFunctionPass {
     const TargetInstrInfo *TII;
     MachineModuleInfo *MMI;
+    MachineRegisterInfo *MRI;
+
+    // SSAUpdateVRs - A list of virtual registers for which to update SSA form.
+    SmallVector<unsigned, 16> SSAUpdateVRs;
+
+    // SSAUpdateVals - For each virtual register in SSAUpdateVals keep a list of
+    // source virtual registers.
+    DenseMap<unsigned, AvailableValsTy> SSAUpdateVals;
 
   public:
     static char ID;
@@ -50,6 +62,7 @@
     virtual const char *getPassName() const { return "Tail Duplication"; }
 
   private:
+    void AddSSAUpdateEntry(unsigned OrigReg, unsigned NewReg);
     bool TailDuplicateBlocks(MachineFunction &MF);
     bool TailDuplicate(MachineBasicBlock *TailBB, MachineFunction &MF);
     void RemoveDeadBlock(MachineBasicBlock *MBB);
@@ -64,6 +77,7 @@
 
 bool TailDuplicatePass::runOnMachineFunction(MachineFunction &MF) {
   TII = MF.getTarget().getInstrInfo();
+  MRI = &MF.getRegInfo();
   MMI = getAnalysisIfAvailable<MachineModuleInfo>();
 
   bool MadeChange = false;
@@ -83,6 +97,9 @@
 bool TailDuplicatePass::TailDuplicateBlocks(MachineFunction &MF) {
   bool MadeChange = false;
 
+  SSAUpdateVRs.clear();
+  SSAUpdateVals.clear();
+
   for (MachineFunction::iterator I = ++MF.begin(), E = MF.end(); I != E; ) {
     MachineBasicBlock *MBB = I++;
 
@@ -100,13 +117,83 @@
       ++NumDeadBlocks;
     }
   }
+
+  if (!SSAUpdateVRs.empty()) {
+    // Update SSA form.
+    MachineSSAUpdater SSAUpdate(MF);
+
+    for (unsigned i = 0, e = SSAUpdateVRs.size(); i != e; ++i) {
+      unsigned VReg = SSAUpdateVRs[i];
+      SSAUpdate.Initialize(VReg);
+
+      // If the original definition is still around, add it as an available
+      // value.
+      MachineInstr *DefMI = MRI->getVRegDef(VReg);
+      MachineBasicBlock *DefBB = 0;
+      if (DefMI) {
+        DefBB = DefMI->getParent();
+        SSAUpdate.AddAvailableValue(DefBB, VReg);
+      }
+
+      // Add the new vregs as available values.
+      DenseMap<unsigned, AvailableValsTy>::iterator LI =
+        SSAUpdateVals.find(VReg);  
+      for (unsigned j = 0, ee = LI->second.size(); j != ee; ++j) {
+        unsigned NewReg = LI->second[j];
+        MachineInstr *DefMI = MRI->getVRegDef(NewReg);
+        SSAUpdate.AddAvailableValue(DefMI->getParent(), NewReg);
+      }
+
+      // Rewrite uses that are outside of the original def's block.
+      for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(VReg),
+             UE = MRI->use_end(); UI != UE; ++UI) {
+        MachineInstr *UseMI = &*UI;
+        if (UseMI->getParent() != DefBB)
+          SSAUpdate.RewriteUse(UI.getOperand());
+      }
+    }
+  }
+
   return MadeChange;
 }
 
+static bool isDefLiveOut(unsigned Reg, MachineBasicBlock *BB,
+                         const MachineRegisterInfo *MRI) {
+  for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(Reg),
+         UE = MRI->use_end(); UI != UE; ++UI) {
+    MachineInstr *UseMI = &*UI;
+    if (UseMI->getParent() != BB)
+      return true;
+  }
+  return false;
+}
+
+static unsigned getPHISrcRegOpIdx(MachineInstr *MI, MachineBasicBlock *SrcBB) {
+  for (unsigned i = 1, e = MI->getNumOperands(); i != e; i += 2)
+    if (MI->getOperand(i+1).getMBB() == SrcBB)
+      return i;
+  return 0;
+}
+
+/// AddSSAUpdateEntry - Add a definition and source virtual registers pair for
+/// SSA update.
+void TailDuplicatePass::AddSSAUpdateEntry(unsigned OrigReg, unsigned NewReg) {
+  DenseMap<unsigned, AvailableValsTy>::iterator LI =
+    SSAUpdateVals.find(OrigReg);
+  if (LI != SSAUpdateVals.end())
+    LI->second.push_back(NewReg);
+  else {
+    AvailableValsTy Vals;
+    Vals.push_back(NewReg);
+    SSAUpdateVals.insert(std::make_pair(OrigReg, Vals));
+    SSAUpdateVRs.push_back(OrigReg);
+  }
+}
+
 /// TailDuplicate - If it is profitable, duplicate TailBB's contents in each
 /// of its predecessors.
 bool TailDuplicatePass::TailDuplicate(MachineBasicBlock *TailBB,
-                                        MachineFunction &MF) {
+                                      MachineFunction &MF) {
   // Don't try to tail-duplicate single-block loops.
   if (TailBB->isSuccessor(TailBB))
     return false;
@@ -179,10 +266,54 @@
 
     // Remove PredBB's unconditional branch.
     TII->RemoveBranch(*PredBB);
+
     // Clone the contents of TailBB into PredBB.
-    for (MachineBasicBlock::iterator I = TailBB->begin(), E = TailBB->end();
-         I != E; ++I) {
+    DenseMap<unsigned, unsigned> LocalVRMap;
+    MachineBasicBlock::iterator I = TailBB->begin();
+    MachineBasicBlock::iterator NI;
+    for (MachineBasicBlock::iterator E = TailBB->end(); I != E; I = NI) {
+      NI = next(I);
+      if (I->getOpcode() == TargetInstrInfo::PHI) {
+        // Replace the uses of the def of the PHI with the register coming
+        // from PredBB.
+        unsigned DefReg = I->getOperand(0).getReg();
+        unsigned SrcOpIdx = getPHISrcRegOpIdx(I, PredBB);
+        unsigned SrcReg = I->getOperand(SrcOpIdx).getReg();
+        LocalVRMap.insert(std::make_pair(DefReg, SrcReg));
+        if (isDefLiveOut(DefReg, TailBB, MRI))
+          AddSSAUpdateEntry(DefReg, SrcReg);
+
+        // Remove PredBB from the PHI node.
+        I->RemoveOperand(SrcOpIdx+1);
+        I->RemoveOperand(SrcOpIdx);
+        if (I->getNumOperands() == 1)
+          I->eraseFromParent();
+        continue;
+      }
+
+      // Replace def of virtual registers with new registers, and update uses
+      // with PHI source register or the new registers.
       MachineInstr *NewMI = MF.CloneMachineInstr(I);
+      for (unsigned i = 0, e = NewMI->getNumOperands(); i != e; ++i) {
+        MachineOperand &MO = NewMI->getOperand(i);
+        if (!MO.isReg())
+          continue;
+        unsigned Reg = MO.getReg();
+        if (!Reg || TargetRegisterInfo::isPhysicalRegister(Reg))
+          continue;
+        if (MO.isDef()) {
+          const TargetRegisterClass *RC = MRI->getRegClass(Reg);
+          unsigned NewReg = MRI->createVirtualRegister(RC);
+          MO.setReg(NewReg);
+          LocalVRMap.insert(std::make_pair(Reg, NewReg));
+          if (isDefLiveOut(Reg, TailBB, MRI))
+            AddSSAUpdateEntry(Reg, NewReg);
+        } else {
+          DenseMap<unsigned, unsigned>::iterator VI = LocalVRMap.find(Reg);
+          if (VI != LocalVRMap.end())
+            MO.setReg(VI->second);
+        }
+      }
       PredBB->insert(PredBB->end(), NewMI);
     }
     NumInstrDups += TailBB->size() - 1; // subtract one for removed branch





More information about the llvm-commits mailing list