[llvm-commits] [llvm] r97635 - /llvm/trunk/lib/CodeGen/MachineCSE.cpp

Evan Cheng evan.cheng at apple.com
Tue Mar 2 18:48:20 PST 2010


Author: evancheng
Date: Tue Mar  2 20:48:20 2010
New Revision: 97635

URL: http://llvm.org/viewvc/llvm-project?rev=97635&view=rev
Log:
Work in progress. Finding some cse now.

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

Modified: llvm/trunk/lib/CodeGen/MachineCSE.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineCSE.cpp?rev=97635&r1=97634&r2=97635&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineCSE.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineCSE.cpp Tue Mar  2 20:48:20 2010
@@ -17,6 +17,8 @@
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/CodeGen/MachineDominators.h"
 #include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/Target/TargetInstrInfo.h"
 #include "llvm/ADT/ScopedHashTable.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/Support/Debug.h"
@@ -41,6 +43,8 @@
         switch (MO.getType()) {
         default: break;
         case MachineOperand::MO_Register:
+          if (MO.isDef() && TargetRegisterInfo::isVirtualRegister(MO.getReg()))
+            continue;  // Skip virtual register defs.
           Key |= MO.getReg();
           break;
         case MachineOperand::MO_Immediate:
@@ -76,18 +80,24 @@
 
     static bool isEqual(const MachineInstr* const &LHS,
                         const MachineInstr* const &RHS) {
-      return LHS->isIdenticalTo(RHS);
+      if (RHS == getEmptyKey() || RHS == getTombstoneKey() ||
+          LHS == getEmptyKey() || LHS == getTombstoneKey())
+        return LHS == RHS;
+      return LHS->isIdenticalTo(RHS, MachineInstr::IgnoreVRegDefs);
     }
   };
 } // end llvm namespace
 
 namespace {
   class MachineCSE : public MachineFunctionPass {
-    ScopedHashTable<MachineInstr*, unsigned> VNT;
+    const TargetInstrInfo *TII;
+    MachineRegisterInfo  *MRI;
     MachineDominatorTree *DT;
+    ScopedHashTable<MachineInstr*, unsigned> VNT;
+    unsigned CurrVN;
   public:
     static char ID; // Pass identification
-    MachineCSE() : MachineFunctionPass(&ID) {}
+    MachineCSE() : MachineFunctionPass(&ID), CurrVN(0) {}
 
     virtual bool runOnMachineFunction(MachineFunction &MF);
     
@@ -99,6 +109,7 @@
     }
 
   private:
+    bool PerformTrivialCoalescing(MachineInstr *MI, MachineBasicBlock *MBB);
     bool ProcessBlock(MachineDomTreeNode *Node);
   };
 } // end anonymous namespace
@@ -109,16 +120,89 @@
 
 FunctionPass *llvm::createMachineCSEPass() { return new MachineCSE(); }
 
+bool MachineCSE::PerformTrivialCoalescing(MachineInstr *MI,
+                                          MachineBasicBlock *MBB) {
+  bool Changed = false;
+  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+    MachineOperand &MO = MI->getOperand(i);
+    if (MO.isReg() && MO.isUse()) {
+      unsigned Reg = MO.getReg();
+      if (!Reg || TargetRegisterInfo::isPhysicalRegister(Reg))
+        continue;
+      MachineInstr *DefMI = MRI->getVRegDef(Reg);
+      if (DefMI->getParent() == MBB) {
+        unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
+        if (TII->isMoveInstr(*DefMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) &&
+            TargetRegisterInfo::isVirtualRegister(SrcReg) &&
+            !SrcSubIdx && !DstSubIdx) {
+          MO.setReg(SrcReg);
+          Changed = true;
+        }
+      }
+    }
+  }
+
+  return Changed;
+}
+
+static bool hasLivePhysRegDefUse(MachineInstr *MI) {
+  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+    MachineOperand &MO = MI->getOperand(i);
+    if (!MO.isReg())
+      continue;
+    unsigned Reg = MO.getReg();
+    if (!Reg)
+      continue;
+    if (TargetRegisterInfo::isPhysicalRegister(Reg) &&
+        !(MO.isDef() && MO.isDead()))
+      return true;
+  }
+  return false;
+}
+
 bool MachineCSE::ProcessBlock(MachineDomTreeNode *Node) {
+  bool Changed = false;
+
   ScopedHashTableScope<MachineInstr*, unsigned> VNTS(VNT);
   MachineBasicBlock *MBB = Node->getBlock();
   for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E;
        ++I) {
+    MachineInstr *MI = &*I;
+    bool SawStore = false;
+    if (!MI->isSafeToMove(TII, 0, SawStore))
+      continue;
+    // Ignore copies or instructions that read / write physical registers
+    // (except for dead defs of physical registers).
+    unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
+    if (TII->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx))
+      continue;
+    if (hasLivePhysRegDefUse(MI))
+      continue;
+
+    bool FoundCSE = VNT.count(MI);
+    if (!FoundCSE) {
+      // Look for trivial copy coalescing opportunities.
+      if (PerformTrivialCoalescing(MI, MBB))
+        FoundCSE = VNT.count(MI);
+    }
+
+    if (FoundCSE)
+      DEBUG(dbgs() << "Found a common subexpression: " << *MI);
+    else
+      VNT.insert(MI, ++CurrVN);
   }
-  return false;
+
+  // Recursively call ProcessBlock with childred.
+  const std::vector<MachineDomTreeNode*> &Children = Node->getChildren();
+  for (unsigned i = 0, e = Children.size(); i != e; ++i)
+    Changed |= ProcessBlock(Children[i]);
+
+  return Changed;
 }
 
 bool MachineCSE::runOnMachineFunction(MachineFunction &MF) {
+  TII = MF.getTarget().getInstrInfo();
+  MRI = &MF.getRegInfo();
   DT = &getAnalysis<MachineDominatorTree>();
   return ProcessBlock(DT->getRootNode());
 }





More information about the llvm-commits mailing list