Add a Debug bit to MachineOperand, for uses that
authorDale Johannesen <dalej@apple.com>
Sat, 6 Feb 2010 02:28:32 +0000 (02:28 +0000)
committerDale Johannesen <dalej@apple.com>
Sat, 6 Feb 2010 02:28:32 +0000 (02:28 +0000)
are from debug info.  Add an iterator to MachineRegisterInfo
to skip Debug operands when walking the use list.  No
functional change yet.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@95473 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/MachineInstrBuilder.h
include/llvm/CodeGen/MachineOperand.h
include/llvm/CodeGen/MachineRegisterInfo.h

index 8eb0add019203f72466357fb9cda41b9c5308f9a..a263a9710ef3b4503e4e563d55361a842d530e17 100644 (file)
@@ -32,6 +32,7 @@ namespace RegState {
     Dead           = 0x10,
     Undef          = 0x20,
     EarlyClobber   = 0x40,
+    Debug          = 0x80,
     ImplicitDefine = Implicit | Define,
     ImplicitKill   = Implicit | Kill
   };
@@ -62,7 +63,8 @@ public:
                                              flags & RegState::Dead,
                                              flags & RegState::Undef,
                                              flags & RegState::EarlyClobber,
-                                             SubReg));
+                                             SubReg,
+                                             flags & RegState::Debug));
     return *this;
   }
 
index 07d886d7d7b3745ba5a7144aa5d237b25d55d7f8..a4db391ea908f952a957b388745aabdce4f9ade2 100644 (file)
@@ -87,6 +87,10 @@ private:
   /// model the GCC inline asm '&' constraint modifier.
   bool IsEarlyClobber : 1;
 
+  /// IsDebug - True if this MO_Register 'use' operand is in a debug pseudo,
+  /// not a real instruction.  Such uses should be ignored during codegen.
+  bool IsDebug : 1;
+
   /// ParentMI - This is the instruction that this operand is embedded into. 
   /// This is valid for all operand types, when the operand is in an instr.
   MachineInstr *ParentMI;
@@ -214,6 +218,12 @@ public:
     return IsEarlyClobber;
   }
 
+  bool isDebug() const {
+    assert(isReg() && "Wrong MachineOperand accessor");
+    assert(!isDef() && "Wrong MachineOperand accessor");
+    return IsDebug;
+  }
+
   /// getNextOperandForReg - Return the next MachineOperand in the function that
   /// uses or defines this register.
   MachineOperand *getNextOperandForReg() const {
@@ -388,7 +398,8 @@ public:
                                   bool isKill = false, bool isDead = false,
                                   bool isUndef = false,
                                   bool isEarlyClobber = false,
-                                  unsigned SubReg = 0) {
+                                  unsigned SubReg = 0,
+                                  bool isDebug = false) {
     MachineOperand Op(MachineOperand::MO_Register);
     Op.IsDef = isDef;
     Op.IsImp = isImp;
@@ -396,6 +407,7 @@ public:
     Op.IsDead = isDead;
     Op.IsUndef = isUndef;
     Op.IsEarlyClobber = isEarlyClobber;
+    Op.IsDebug = isDebug;
     Op.Contents.Reg.RegNo = Reg;
     Op.Contents.Reg.Prev = 0;
     Op.Contents.Reg.Next = 0;
index c55cb3227af6d54ac7675a29c77cac8bb045d551..01dc0184e2500f5d8099835920d196e1823131cb 100644 (file)
@@ -78,12 +78,12 @@ public:
   /// reg_begin/reg_end - Provide iteration support to walk over all definitions
   /// and uses of a register within the MachineFunction that corresponds to this
   /// MachineRegisterInfo object.
-  template<bool Uses, bool Defs>
+  template<bool Uses, bool Defs, bool SkipDebug>
   class defusechain_iterator;
 
   /// reg_iterator/reg_begin/reg_end - Walk all defs and uses of the specified
   /// register.
-  typedef defusechain_iterator<true,true> reg_iterator;
+  typedef defusechain_iterator<true,true,false> reg_iterator;
   reg_iterator reg_begin(unsigned RegNo) const {
     return reg_iterator(getRegUseDefListHead(RegNo));
   }
@@ -94,7 +94,7 @@ public:
   bool reg_empty(unsigned RegNo) const { return reg_begin(RegNo) == reg_end(); }
 
   /// def_iterator/def_begin/def_end - Walk all defs of the specified register.
-  typedef defusechain_iterator<false,true> def_iterator;
+  typedef defusechain_iterator<false,true,false> def_iterator;
   def_iterator def_begin(unsigned RegNo) const {
     return def_iterator(getRegUseDefListHead(RegNo));
   }
@@ -105,7 +105,7 @@ public:
   bool def_empty(unsigned RegNo) const { return def_begin(RegNo) == def_end(); }
 
   /// use_iterator/use_begin/use_end - Walk all uses of the specified register.
-  typedef defusechain_iterator<true,false> use_iterator;
+  typedef defusechain_iterator<true,false,false> use_iterator;
   use_iterator use_begin(unsigned RegNo) const {
     return use_iterator(getRegUseDefListHead(RegNo));
   }
@@ -115,7 +115,20 @@ public:
   /// register.
   bool use_empty(unsigned RegNo) const { return use_begin(RegNo) == use_end(); }
 
+  /// use_nodbg_iterator/use_nodbg_begin/use_nodbg_end - Walk all uses of the
+  /// specified register, skipping those marked as Debug.
+  typedef defusechain_iterator<true,false,true> use_nodbg_iterator;
+  use_nodbg_iterator use_nodbg_begin(unsigned RegNo) const {
+    return use_nodbg_iterator(getRegUseDefListHead(RegNo));
+  }
+  static use_nodbg_iterator use_nodbg_end() { return use_nodbg_iterator(0); }
   
+  /// use_nodbg_empty - Return true if there are no non-Debug instructions
+  /// using the specified register.
+  bool use_nodbg_empty(unsigned RegNo) const {
+    return use_nodbg_begin(RegNo) == use_nodbg_end();
+  }
+
   /// replaceRegWith - Replace all instances of FromReg with ToReg in the
   /// machine function.  This is like llvm-level X->replaceAllUsesWith(Y),
   /// except that it also changes any definitions of the register as well.
@@ -258,8 +271,9 @@ public:
   /// operands in the function that use or define a specific register.  If
   /// ReturnUses is true it returns uses of registers, if ReturnDefs is true it
   /// returns defs.  If neither are true then you are silly and it always
-  /// returns end().
-  template<bool ReturnUses, bool ReturnDefs>
+  /// returns end().  If SkipDebug is true it skips uses marked Debug
+  /// when incrementing.
+  template<bool ReturnUses, bool ReturnDefs, bool SkipDebug>
   class defusechain_iterator
     : public std::iterator<std::forward_iterator_tag, MachineInstr, ptrdiff_t> {
     MachineOperand *Op;
@@ -268,7 +282,8 @@ public:
       // we are interested in.
       if (op) {
         if ((!ReturnUses && op->isUse()) ||
-            (!ReturnDefs && op->isDef()))
+            (!ReturnDefs && op->isDef()) ||
+            (SkipDebug && op->isDebug()))
           ++*this;
       }
     }
@@ -299,7 +314,8 @@ public:
       
       // If this is an operand we don't care about, skip it.
       while (Op && ((!ReturnUses && Op->isUse()) || 
-                    (!ReturnDefs && Op->isDef())))
+                    (!ReturnDefs && Op->isDef()) ||
+                    (SkipDebug && Op->isDebug())))
         Op = Op->getNextOperandForReg();
       
       return *this;