Fixes for BreakCriticalMachineCodeEdge by Fernando.
[oota-llvm.git] / include / llvm / CodeGen / LiveVariables.h
index 5b42a71318946becc8300bcfebecad1d72253b08..5c714e308aaca046e9c13641a25f3323eef8a7f4 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
@@ -31,6 +31,7 @@
 
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/SmallVector.h"
 #include <map>
 
@@ -40,6 +41,9 @@ class MRegisterInfo;
 
 class LiveVariables : public MachineFunctionPass {
 public:
+  static char ID; // Pass identification, replacement for typeid
+  LiveVariables() : MachineFunctionPass((intptr_t)&ID) {}
+
   /// VarInfo - This represents the regions where a virtual register is live in
   /// the program.  We represent this with three different pieces of
   /// information: the instruction that uniquely defines the value, the set of
@@ -79,6 +83,10 @@ public:
     ///
     BitVector AliveBlocks;
 
+    /// UsedBlocks - Set of blocks of which this value is actually used. This
+    /// is a bit set which uses the basic block number as an index.
+    BitVector UsedBlocks;
+
     /// NumUses - Number of uses of this register across the entire function.
     ///
     unsigned NumUses;
@@ -146,14 +154,15 @@ private:   // Intermediate data structures
 
   SmallVector<unsigned, 4> *PHIVarInfo;
 
-  /// addRegisterKilled - We have determined MI kills a register. Look for the
-  /// operand that uses it and mark it as IsKill.
-  void addRegisterKilled(unsigned IncomingReg, MachineInstr *MI);
-
-  /// addRegisterDead - We have determined MI defined a register without a use.
-  /// Look for the operand that defines it and mark it as IsDead. 
-  void addRegisterDead(unsigned IncomingReg, MachineInstr *MI);
+  void addRegisterKills(unsigned Reg, MachineInstr *MI,
+                        SmallSet<unsigned, 4> &SubKills);
 
+  /// HandlePhysRegKill - Add kills of Reg and its sub-registers to the
+  /// uses. Pay special attention to the sub-register uses which may come below
+  /// the last use of the whole register.
+  bool HandlePhysRegKill(unsigned Reg, MachineInstr *MI,
+                         SmallSet<unsigned, 4> &SubKills);
+  bool HandlePhysRegKill(unsigned Reg, MachineInstr *MI);
   void HandlePhysRegUse(unsigned Reg, MachineInstr *MI);
   void HandlePhysRegDef(unsigned Reg, MachineInstr *MI);
 
@@ -189,12 +198,13 @@ public:
 
   /// addVirtualRegisterKilled - Add information about the fact that the
   /// specified register is killed after being used by the specified
-  /// instruction.
-  ///
-  void addVirtualRegisterKilled(unsigned IncomingReg, MachineInstr *MI) {
-    addRegisterKilled(IncomingReg, MI);
-    getVarInfo(IncomingReg).Kills.push_back(MI); 
- }
+  /// instruction. If AddIfNotFound is true, add a implicit operand if it's
+  /// not found.
+  void addVirtualRegisterKilled(unsigned IncomingReg, MachineInstr *MI,
+                                bool AddIfNotFound = false) {
+    if (MI->addRegisterKilled(IncomingReg, RegInfo, AddIfNotFound))
+      getVarInfo(IncomingReg).Kills.push_back(MI); 
+  }
 
   /// removeVirtualRegisterKilled - Remove the specified virtual
   /// register from the live variable information. Returns true if the
@@ -209,8 +219,8 @@ public:
     bool Removed = false;
     for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
       MachineOperand &MO = MI->getOperand(i);
-      if (MO.isReg() && MO.isUse() && MO.getReg() == reg) {
-        MO.unsetIsKill();
+      if (MO.isRegister() && MO.isKill() && MO.getReg() == reg) {
+        MO.setIsKill(false);
         Removed = true;
         break;
       }
@@ -223,13 +233,14 @@ public:
   /// removeVirtualRegistersKilled - Remove all killed info for the specified
   /// instruction.
   void removeVirtualRegistersKilled(MachineInstr *MI);
-  
+
   /// addVirtualRegisterDead - Add information about the fact that the specified
-  /// register is dead after being used by the specified instruction.
-  ///
-  void addVirtualRegisterDead(unsigned IncomingReg, MachineInstr *MI) {
-    addRegisterDead(IncomingReg, MI);
-    getVarInfo(IncomingReg).Kills.push_back(MI);
+  /// register is dead after being used by the specified instruction. If
+  /// AddIfNotFound is true, add a implicit operand if it's not found.
+  void addVirtualRegisterDead(unsigned IncomingReg, MachineInstr *MI,
+                              bool AddIfNotFound = false) {
+    if (MI->addRegisterDead(IncomingReg, RegInfo, AddIfNotFound))
+        getVarInfo(IncomingReg).Kills.push_back(MI);
   }
 
   /// removeVirtualRegisterDead - Remove the specified virtual
@@ -245,8 +256,8 @@ public:
     bool Removed = false;
     for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
       MachineOperand &MO = MI->getOperand(i);
-      if (MO.isReg() && MO.isDef() && MO.getReg() == reg) {
-        MO.unsetIsDead();
+      if (MO.isRegister() && MO.isDef() && MO.getReg() == reg) {
+        MO.setIsDead(false);
         Removed = true;
         break;
       }
@@ -271,8 +282,12 @@ public:
   /// register.
   VarInfo &getVarInfo(unsigned RegIdx);
 
-  void MarkVirtRegAliveInBlock(VarInfo &VRInfo, MachineBasicBlock *BB);
-  void HandleVirtRegUse(VarInfo &VRInfo, MachineBasicBlock *MBB,
+  void MarkVirtRegAliveInBlock(VarInfo& VRInfo, MachineBasicBlock* DefBlock,
+                               MachineBasicBlock *BB);
+  void MarkVirtRegAliveInBlock(VarInfo& VRInfo, MachineBasicBlock* DefBlock,
+                               MachineBasicBlock *BB,
+                               std::vector<MachineBasicBlock*> &WorkList);
+  void HandleVirtRegUse(unsigned reg, MachineBasicBlock *MBB,
                         MachineInstr *MI);
 };