OSDN Git Service

For inline asm output operand that matches an input. Encode the input operand index...
authorEvan Cheng <evan.cheng@apple.com>
Fri, 20 Mar 2009 18:03:34 +0000 (18:03 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Fri, 20 Mar 2009 18:03:34 +0000 (18:03 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@67387 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/InlineAsm.h
lib/CodeGen/AsmPrinter/AsmPrinter.cpp
lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp
lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

index 879b2e8..6347cae 100644 (file)
@@ -128,6 +128,24 @@ public:
   static inline bool classof(const Value *V) {
     return V->getValueID() == Value::InlineAsmVal;
   }
+
+  /// getNumOperandRegisters - Extract the number of registers field from the
+  /// inline asm operand flag.
+  static unsigned getNumOperandRegisters(unsigned Flag) {
+    return (Flag & 0xffff) >> 3;
+  }
+
+  /// isOutputOperandTiedToUse - Return true if the flag of the inline asm
+  /// operand indicates it is an output that's matched to an input operand.
+  static bool isOutputOperandTiedToUse(unsigned Flag, unsigned &UseIdx) {
+    if (Flag & 0x80000000) {
+      UseIdx = Flag >> 16;
+      return true;
+    }
+    return false;
+  }
+
+
 };
 
 } // End llvm namespace
index b25776a..2a64524 100644 (file)
@@ -1401,7 +1401,7 @@ void AsmPrinter::printInlineAsm(const MachineInstr *MI) const {
         for (; Val; --Val) {
           if (OpNo >= MI->getNumOperands()) break;
           unsigned OpFlags = MI->getOperand(OpNo).getImm();
-          OpNo += (OpFlags >> 3) + 1;
+          OpNo += InlineAsm::getNumOperandRegisters(OpFlags) + 1;
         }
 
         if (OpNo >= MI->getNumOperands()) {
index fd08ee6..888eeda 100644 (file)
@@ -1974,7 +1974,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
 
     bool HasInFlag = Ops.back().getValueType() == MVT::Flag;
     for (unsigned i = 2, e = Ops.size()-HasInFlag; i < e; ) {
-      unsigned NumVals = cast<ConstantSDNode>(Ops[i])->getZExtValue() >> 3;
+      unsigned NumVals = InlineAsm::
+        getNumOperandRegisters(cast<ConstantSDNode>(Ops[i])->getZExtValue());
       for (++i; NumVals; ++i, --NumVals) {
         SDValue Op = LegalizeOp(Ops[i]);
         if (Op != Ops[i]) {
index b2f6ddf..7ae56d7 100644 (file)
@@ -632,7 +632,7 @@ bool ScheduleDAGRRList::DelayForLiveRegsBottomUp(SUnit *SU,
       for (unsigned i = 2; i != NumOps;) {
         unsigned Flags =
           cast<ConstantSDNode>(Node->getOperand(i))->getZExtValue();
-        unsigned NumVals = Flags >> 3;
+        unsigned NumVals = (Flags & 0xffff) >> 3;
 
         ++i; // Skip the ID value.
         if ((Flags & 7) == 2 || (Flags & 7) == 6) {
index 5dfd5c3..4ad36da 100644 (file)
@@ -561,7 +561,7 @@ void ScheduleDAGSDNodes::EmitNode(SDNode *Node, bool IsClone, bool IsCloned,
     for (unsigned i = 2; i != NumOps;) {
       unsigned Flags =
         cast<ConstantSDNode>(Node->getOperand(i))->getZExtValue();
-      unsigned NumVals = Flags >> 3;
+      unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags);
         
       MI->addOperand(MachineOperand::CreateImm(Flags));
       ++i;  // Skip the ID value.
index 0e8d9be..cbfdb79 100644 (file)
@@ -228,10 +228,11 @@ namespace llvm {
                        SDValue &Chain, SDValue *Flag) const;
 
     /// AddInlineAsmOperands - Add this value to the specified inlineasm node
-    /// operand list.  This adds the code marker and includes the number of
-    /// values added into it.
-    void AddInlineAsmOperands(unsigned Code, SelectionDAG &DAG,
-                              std::vector<SDValue> &Ops) const;
+    /// operand list.  This adds the code marker, matching input operand index
+    /// (if applicable), and includes the number of values added into it.
+    void AddInlineAsmOperands(unsigned Code,
+                              bool HasMatching, unsigned MatchingIdx,
+                              SelectionDAG &DAG, std::vector<SDValue> &Ops) const;
   };
 }
 
@@ -4659,10 +4660,16 @@ void RegsForValue::getCopyToRegs(SDValue Val, SelectionDAG &DAG, DebugLoc dl,
 /// AddInlineAsmOperands - Add this value to the specified inlineasm node
 /// operand list.  This adds the code marker and includes the number of
 /// values added into it.
-void RegsForValue::AddInlineAsmOperands(unsigned Code, SelectionDAG &DAG,
+void RegsForValue::AddInlineAsmOperands(unsigned Code,
+                                        bool HasMatching,unsigned MatchingIdx,
+                                        SelectionDAG &DAG,
                                         std::vector<SDValue> &Ops) const {
   MVT IntPtrTy = DAG.getTargetLoweringInfo().getPointerTy();
-  Ops.push_back(DAG.getTargetConstant(Code | (Regs.size() << 3), IntPtrTy));
+  assert(Regs.size() < (1 << 13) && "Too many inline asm outputs!");
+  unsigned Flag = Code | (Regs.size() << 3);
+  if (HasMatching)
+    Flag |= 0x80000000 | (MatchingIdx << 16);
+  Ops.push_back(DAG.getTargetConstant(Flag, IntPtrTy));
   for (unsigned Value = 0, Reg = 0, e = ValueVTs.size(); Value != e; ++Value) {
     unsigned NumRegs = TLI->getNumRegisters(ValueVTs[Value]);
     MVT RegisterVT = RegVTs[Value];
@@ -5230,6 +5237,8 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
       OpInfo.AssignedRegs.AddInlineAsmOperands(OpInfo.isEarlyClobber ?
                                                6 /* EARLYCLOBBER REGDEF */ :
                                                2 /* REGDEF */ ,
+                                               OpInfo.hasMatchingInput(),
+                                               OpInfo.MatchingInput,
                                                DAG, AsmNodeOperands);
       break;
     }
@@ -5246,25 +5255,26 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
         unsigned CurOp = 2;  // The first operand.
         for (; OperandNo; --OperandNo) {
           // Advance to the next operand.
-          unsigned NumOps =
+          unsigned OpFlag =
             cast<ConstantSDNode>(AsmNodeOperands[CurOp])->getZExtValue();
-          assert(((NumOps & 7) == 2 /*REGDEF*/ ||
-                  (NumOps & 7) == 6 /*EARLYCLOBBER REGDEF*/ ||
-                  (NumOps & 7) == 4 /*MEM*/) &&
+          assert(((OpFlag & 7) == 2 /*REGDEF*/ ||
+                  (OpFlag & 7) == 6 /*EARLYCLOBBER REGDEF*/ ||
+                  (OpFlag & 7) == 4 /*MEM*/) &&
                  "Skipped past definitions?");
-          CurOp += (NumOps>>3)+1;
+          CurOp += InlineAsm::getNumOperandRegisters(OpFlag)+1;
         }
 
-        unsigned NumOps =
+        unsigned OpFlag =
           cast<ConstantSDNode>(AsmNodeOperands[CurOp])->getZExtValue();
-        if ((NumOps & 7) == 2 /*REGDEF*/
-            || (NumOps & 7) == 6 /* EARLYCLOBBER REGDEF */) {
-          // Add NumOps>>3 registers to MatchedRegs.
+        if ((OpFlag & 7) == 2 /*REGDEF*/
+            || (OpFlag & 7) == 6 /* EARLYCLOBBER REGDEF */) {
+          // Add (OpFlag&0xffff)>>3 registers to MatchedRegs.
           RegsForValue MatchedRegs;
           MatchedRegs.TLI = &TLI;
           MatchedRegs.ValueVTs.push_back(InOperandVal.getValueType());
           MatchedRegs.RegVTs.push_back(AsmNodeOperands[CurOp+1].getValueType());
-          for (unsigned i = 0, e = NumOps>>3; i != e; ++i) {
+          for (unsigned i = 0, e = InlineAsm::getNumOperandRegisters(OpFlag);
+               i != e; ++i) {
             unsigned Reg =
               cast<RegisterSDNode>(AsmNodeOperands[++CurOp])->getReg();
             MatchedRegs.Regs.push_back(Reg);
@@ -5273,13 +5283,15 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
           // Use the produced MatchedRegs object to
           MatchedRegs.getCopyToRegs(InOperandVal, DAG, getCurDebugLoc(),
                                     Chain, &Flag);
-          MatchedRegs.AddInlineAsmOperands(1 /*REGUSE*/, DAG, AsmNodeOperands);
+          MatchedRegs.AddInlineAsmOperands(1 /*REGUSE*/, false, 0,
+                                           DAG, AsmNodeOperands);
           break;
         } else {
-          assert(((NumOps & 7) == 4) && "Unknown matching constraint!");
-          assert((NumOps >> 3) == 1 && "Unexpected number of operands");
+          assert(((OpFlag & 7) == 4) && "Unknown matching constraint!");
+          assert((InlineAsm::getNumOperandRegisters(OpFlag)) == 1 &&
+                 "Unexpected number of operands");
           // Add information to the INLINEASM node to know about this input.
-          AsmNodeOperands.push_back(DAG.getTargetConstant(NumOps,
+          AsmNodeOperands.push_back(DAG.getTargetConstant(OpFlag,
                                                           TLI.getPointerTy()));
           AsmNodeOperands.push_back(AsmNodeOperands[CurOp+1]);
           break;
@@ -5334,7 +5346,7 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
       OpInfo.AssignedRegs.getCopyToRegs(InOperandVal, DAG, getCurDebugLoc(),
                                         Chain, &Flag);
 
-      OpInfo.AssignedRegs.AddInlineAsmOperands(1/*REGUSE*/,
+      OpInfo.AssignedRegs.AddInlineAsmOperands(1/*REGUSE*/, false, 0,
                                                DAG, AsmNodeOperands);
       break;
     }
@@ -5343,7 +5355,7 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
       // allocator is aware that the physreg got clobbered.
       if (!OpInfo.AssignedRegs.Regs.empty())
         OpInfo.AssignedRegs.AddInlineAsmOperands(6 /* EARLYCLOBBER REGDEF */,
-                                                 DAG, AsmNodeOperands);
+                                                 false, 0, DAG,AsmNodeOperands);
       break;
     }
     }
index fd2eb06..fdabd4c 100644 (file)
@@ -1168,10 +1168,12 @@ SelectInlineAsmMemoryOperands(std::vector<SDValue> &Ops) {
     unsigned Flags = cast<ConstantSDNode>(InOps[i])->getZExtValue();
     if ((Flags & 7) != 4 /*MEM*/) {
       // Just skip over this operand, copying the operands verbatim.
-      Ops.insert(Ops.end(), InOps.begin()+i, InOps.begin()+i+(Flags >> 3) + 1);
-      i += (Flags >> 3) + 1;
+      Ops.insert(Ops.end(), InOps.begin()+i,
+                 InOps.begin()+i+InlineAsm::getNumOperandRegisters(Flags) + 1);
+      i += InlineAsm::getNumOperandRegisters(Flags) + 1;
     } else {
-      assert((Flags >> 3) == 1 && "Memory operand with multiple values?");
+      assert(InlineAsm::getNumOperandRegisters(Flags) == 1 &&
+             "Memory operand with multiple values?");
       // Otherwise, this is a memory operand.  Ask the target to select it.
       std::vector<SDValue> SelOps;
       if (SelectInlineAsmMemoryOperand(InOps[i+1], 'm', SelOps)) {