Add MachineInstr::tieOperands, remove setIsTied().
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Fri, 31 Aug 2012 20:50:53 +0000 (20:50 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Fri, 31 Aug 2012 20:50:53 +0000 (20:50 +0000)
Manage tied operands entirely internally to MachineInstr. This makes it
possible to change the representation of tied operands, as I will do
shortly.

The constraint that tied uses and defs must be in the same order was too
restrictive.

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

include/llvm/CodeGen/MachineInstr.h
include/llvm/CodeGen/MachineOperand.h
lib/CodeGen/MachineInstr.cpp
lib/CodeGen/SelectionDAG/InstrEmitter.cpp

index d636dfd44166dddfdf5adde4d9b17f714b720ffd..67ae3f9289ae3e6081ec48ea59c62624952ded07 100644 (file)
@@ -782,6 +782,14 @@ public:
                         const TargetInstrInfo *TII,
                         const TargetRegisterInfo *TRI) const;
 
+  /// tieOperands - Add a tie between the register operands at DefIdx and
+  /// UseIdx. The tie will cause the register allocator to ensure that the two
+  /// operands are assigned the same physical register.
+  ///
+  /// Tied operands are managed automatically for explicit operands in the
+  /// MCInstrDesc. This method is for exceptional cases like inline asm.
+  void tieOperands(unsigned DefIdx, unsigned UseIdx);
+
   /// findTiedOperandIdx - Given the index of a tied register operand, find the
   /// operand it is tied to. Defs are tied to uses and vice versa. Returns the
   /// index of the tied operand which must exist.
@@ -942,9 +950,11 @@ private:
 
   /// untieRegOperand - Break any tie involving OpIdx.
   void untieRegOperand(unsigned OpIdx) {
-    const MachineOperand &MO = getOperand(OpIdx);
-    if (MO.isReg() && MO.isTied())
-      getOperand(findTiedOperandIdx(OpIdx)).setIsTied(false);
+    MachineOperand &MO = getOperand(OpIdx);
+    if (MO.isReg() && MO.isTied()) {
+      getOperand(findTiedOperandIdx(OpIdx)).IsTied = false;
+      MO.IsTied = false;
+    }
   }
 
   /// addImplicitDefUseOperands - Add all implicit def and use operands to
index 594dc276b0eb4be8af1b926f4c308ebf71205e03..baec8822c6cea07c4a22ba7b566de8409b2b14c1 100644 (file)
@@ -390,11 +390,6 @@ public:
     IsEarlyClobber = Val;
   }
 
-  void setIsTied(bool Val = true) {
-    assert(isReg() && "Wrong MachineOperand accessor");
-    IsTied = Val;
-  }
-
   void setIsDebug(bool Val = true) {
     assert(isReg() && IsDef && "Wrong MachineOperand accessor");
     IsDebug = Val;
index ae205f6d106d7e07bccc0f9bb36b7a2f973e6359..5a395fddeed5ef9fedce0c7c0d45e1065c1847d6 100644 (file)
@@ -728,12 +728,8 @@ void MachineInstr::addOperand(const MachineOperand &Op) {
       // Set the IsTied bit if MC indicates this use is tied to a def.
       if (Operands[OpNo].isUse()) {
         int DefIdx = MCID->getOperandConstraint(OpNo, MCOI::TIED_TO);
-        if (DefIdx != -1) {
-          MachineOperand &DefMO = getOperand(DefIdx);
-          assert(DefMO.isDef() && "Use tied to operand that isn't a def");
-          DefMO.IsTied = true;
-          Operands[OpNo].IsTied = true;
-        }
+        if (DefIdx != -1)
+          tieOperands(DefIdx, OpNo);
       }
       // If the register operand is flagged as early, mark the operand as such.
       if (MCID->getOperandConstraint(OpNo, MCOI::EARLY_CLOBBER) != -1)
@@ -1140,6 +1136,20 @@ int MachineInstr::findFirstPredOperandIdx() const {
   return -1;
 }
 
+/// Mark operands at DefIdx and UseIdx as tied to each other.
+void MachineInstr::tieOperands(unsigned DefIdx, unsigned UseIdx) {
+  assert(DefIdx < UseIdx && "Tied defs must precede the use");
+  MachineOperand &DefMO = getOperand(DefIdx);
+  MachineOperand &UseMO = getOperand(UseIdx);
+  assert(DefMO.isDef() && "DefIdx must be a def operand");
+  assert(UseMO.isUse() && "UseIdx must be a use operand");
+  assert(!DefMO.isTied() && "Def is already tied to another use");
+  assert(!UseMO.isTied() && "Use is already tied to another def");
+
+  DefMO.IsTied = true;
+  UseMO.IsTied = true;
+}
+
 /// Given the index of a tied register operand, find the operand it is tied to.
 /// Defs are tied to uses and vice versa. Returns the index of the tied operand
 /// which must exist.
index 5399a51557b2ccf15f4bba09cb9de40e4bce528d..46ddab0d7610db3761ef59037a9fcfc628496d44 100644 (file)
@@ -945,12 +945,8 @@ EmitSpecialNode(SDNode *Node, bool IsClone, bool IsCloned,
           if (InlineAsm::isUseOperandTiedToDef(Flags, DefGroup)) {
             unsigned DefIdx = GroupIdx[DefGroup] + 1;
             unsigned UseIdx = GroupIdx.back() + 1;
-            for (unsigned j = 0; j != NumVals; ++j) {
-              assert(!MI->getOperand(DefIdx + j).isTied() &&
-                     "Def is already tied to another use");
-              MI->getOperand(DefIdx + j).setIsTied();
-              MI->getOperand(UseIdx + j).setIsTied();
-            }
+            for (unsigned j = 0; j != NumVals; ++j)
+              MI->tieOperands(DefIdx + j, UseIdx + j);
           }
         }
         break;