[llvm-commits] [llvm] r118104 - in /llvm/trunk/utils/TableGen: AsmMatcherEmitter.cpp CodeGenInstruction.h

Chris Lattner sabre at nondot.org
Tue Nov 2 15:55:03 PDT 2010


Author: lattner
Date: Tue Nov  2 17:55:03 2010
New Revision: 118104

URL: http://llvm.org/viewvc/llvm-project?rev=118104&view=rev
Log:
rewrite EmitConvertToMCInst to iterate over the MCInst operands,
filling them in one at a time.  Previously this iterated over the
asmoperands, which left the problem of "holes".  The new approach
simplifies things.

Modified:
    llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp
    llvm/trunk/utils/TableGen/CodeGenInstruction.h

Modified: llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp?rev=118104&r1=118103&r2=118104&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp Tue Nov  2 17:55:03 2010
@@ -1040,13 +1040,12 @@
       // grovel for. Only worry about this for single entry operands, we have to
       // clean this up anyway.
       const CGIOperandList::OperandInfo *OI = &II->OperandList[Idx];
-      if (OI->Constraints[0].isTied()) {
-        unsigned TiedOp = OI->Constraints[0].getTiedOperand();
-
+      int OITied = OI->getTiedRegister();
+      if (OITied != -1) {
         // The tied operand index is an MIOperand index, find the operand that
         // contains it.
         for (unsigned i = 0, e = II->OperandList.size(); i != e; ++i) {
-          if (II->OperandList[i].MIOperandNo == TiedOp) {
+          if (II->OperandList[i].MIOperandNo == unsigned(OITied)) {
             OI = &II->OperandList[i];
             break;
           }
@@ -1064,16 +1063,6 @@
   std::sort(Classes.begin(), Classes.end(), less_ptr<ClassInfo>());
 }
 
-static std::pair<unsigned, unsigned> *
-GetTiedOperandAtIndex(SmallVectorImpl<std::pair<unsigned, unsigned> > &List,
-                      unsigned Index) {
-  for (unsigned i = 0, e = List.size(); i != e; ++i)
-    if (Index == List[i].first)
-      return &List[i];
-
-  return 0;
-}
-
 static void EmitConvertToMCInst(CodeGenTarget &Target,
                                 std::vector<MatchableInfo*> &Infos,
                                 raw_ostream &OS) {
@@ -1103,111 +1092,88 @@
   // TargetOperandClass - This is the target's operand class, like X86Operand.
   std::string TargetOperandClass = Target.getName() + "Operand";
 
+  /// OperandMap - This is a mapping from the MCInst operands (specified by the
+  /// II.OperandList operands) to the AsmOperands that they filled in from.
+  SmallVector<int, 16> OperandMap;
+  
   for (std::vector<MatchableInfo*>::const_iterator it = Infos.begin(),
          ie = Infos.end(); it != ie; ++it) {
     MatchableInfo &II = **it;
 
+    OperandMap.clear();
+    OperandMap.resize(II.OperandList.size(), -1);
+    
     // Order the (class) operands by the order to convert them into an MCInst.
-    SmallVector<std::pair<unsigned, unsigned>, 4> MIOperandList;
     for (unsigned i = 0, e = II.AsmOperands.size(); i != e; ++i) {
       MatchableInfo::Operand &Op = II.AsmOperands[i];
-      if (Op.OperandInfo)
-        MIOperandList.push_back(std::make_pair(Op.OperandInfo->MIOperandNo, i));
-    }
-
-    // Find any tied operands.
-    SmallVector<std::pair<unsigned, unsigned>, 4> TiedOperands;
-    for (unsigned i = 0, e = II.OperandList.size(); i != e; ++i) {
-      const CGIOperandList::OperandInfo &OpInfo = II.OperandList[i];
-      for (unsigned j = 0, e = OpInfo.Constraints.size(); j != e; ++j) {
-        const CGIOperandList::ConstraintInfo &CI = OpInfo.Constraints[j];
-        if (!CI.isTied()) continue;
-        TiedOperands.push_back(std::make_pair(OpInfo.MIOperandNo,
-                                              CI.getTiedOperand()));
-      }
-    }
-
-    array_pod_sort(MIOperandList.begin(), MIOperandList.end());
-
-    // Compute the total number of operands.
-    unsigned NumMIOperands = 0;
-    for (unsigned i = 0, e = II.OperandList.size(); i != e; ++i) {
-      const CGIOperandList::OperandInfo &OI = II.OperandList[i];
-      NumMIOperands = std::max(NumMIOperands, OI.MIOperandNo+OI.MINumOperands);
+      if (!Op.OperandInfo) continue;
+      
+      unsigned LogicalOpNum = Op.OperandInfo - &II.OperandList[0];
+      assert(LogicalOpNum < OperandMap.size() && "Invalid operand number");
+      OperandMap[LogicalOpNum] = i;
     }
 
     // Build the conversion function signature.
     std::string Signature = "Convert";
-    unsigned CurIndex = 0;
-    
     std::string CaseBody;
     raw_string_ostream CaseOS(CaseBody);
     
     // Compute the convert enum and the case body.
-    for (unsigned i = 0, e = MIOperandList.size(); i != e; ++i) {
-      MatchableInfo::Operand &Op = II.AsmOperands[MIOperandList[i].second];
-      assert(CurIndex <= Op.OperandInfo->MIOperandNo &&
-             "Duplicate match for instruction operand!");
-
-      // Add the implicit operands.
-      for (; CurIndex != Op.OperandInfo->MIOperandNo; ++CurIndex) {
-        // See if this is a tied operand.
-        std::pair<unsigned, unsigned> *Tie = GetTiedOperandAtIndex(TiedOperands,
-                                                                   CurIndex);
+    for (unsigned i = 0, e = II.OperandList.size(); i != e; ++i) {
+      const CGIOperandList::OperandInfo &OpInfo = II.OperandList[i];
+
+      // Find out what operand from the asmparser that this MCInst operand comes
+      // from.
+      int SrcOperand = OperandMap[i];
+      if (SrcOperand != -1) {
+        // Otherwise, this comes from something we parsed.
+        MatchableInfo::Operand &Op = II.AsmOperands[SrcOperand];
         
-        if (!Tie) {
-          // If not, this is some implicit operand. Just assume it is a register
-          // for now.
-          CaseOS << "    Inst.addOperand(MCOperand::CreateReg(0));\n";
-          Signature += "__Imp";
-        } else {
-          // Copy the tied operand.
-          assert(Tie->first>Tie->second && "Tied operand preceeds its target!");
-          CaseOS << "    Inst.addOperand(Inst.getOperand("
-                 << Tie->second << "));\n";
-          Signature += "__Tie" + utostr(Tie->second);
-        }
+        // Registers are always converted the same, don't duplicate the
+        // conversion function based on them.
+        //
+        // FIXME: We could generalize this based on the render method, if it
+        // mattered.
+        Signature += "__";
+        if (Op.Class->isRegisterClass())
+          Signature += "Reg";
+        else
+          Signature += Op.Class->ClassName;
+        Signature += utostr(Op.OperandInfo->MINumOperands);
+        Signature += "_" + itostr(SrcOperand);
+        
+        CaseOS << "    ((" << TargetOperandClass << "*)Operands["
+               << SrcOperand << "+1])->" << Op.Class->RenderMethod
+               << "(Inst, " << Op.OperandInfo->MINumOperands << ");\n";
+        continue;
       }
       
-      // Registers are always converted the same, don't duplicate the conversion
-      // function based on them.
-      //
-      // FIXME: We could generalize this based on the render method, if it
-      // mattered.
-      Signature += "__";
-      if (Op.Class->isRegisterClass())
-        Signature += "Reg";
-      else
-        Signature += Op.Class->ClassName;
-      Signature += utostr(Op.OperandInfo->MINumOperands);
-      Signature += "_" + utostr(MIOperandList[i].second);
-      
-      
-      CaseOS << "    ((" << TargetOperandClass << "*)Operands["
-             << MIOperandList[i].second << "+1])->" << Op.Class->RenderMethod
-             << "(Inst, " << Op.OperandInfo->MINumOperands << ");\n";
-      CurIndex += Op.OperandInfo->MINumOperands;
-    }
-    
-    // And add trailing implicit operands.
-    for (; CurIndex != NumMIOperands; ++CurIndex) {
-      std::pair<unsigned, unsigned> *Tie = GetTiedOperandAtIndex(TiedOperands,
-                                                                 CurIndex);
-      
-      if (!Tie) {
-        // If not, this is some implicit operand. Just assume it is a register
-        // for now.
-        CaseOS << "    Inst.addOperand(MCOperand::CreateReg(0));\n";
-        Signature += "__Imp";
-      } else {
+
+      // If this operand is tied to a previous one, just copy the MCInst operand
+      // from the earlier one.
+      int TiedOp = OpInfo.getTiedRegister();
+      if (TiedOp != -1) {
         // Copy the tied operand.
-        assert(Tie->first>Tie->second && "Tied operand preceeds its target!");
-        CaseOS << "    Inst.addOperand(Inst.getOperand("
-               << Tie->second << "));\n";
-        Signature += "__Tie" + utostr(Tie->second);
+        // FIXME: What if the operand has multiple MINumOperands?  This happens
+        // in ARM.
+        //assert(OpInfo.MINumOperands == 1);
+        
+        assert(i > unsigned(TiedOp) && "Tied operand preceeds its target!");
+        CaseOS << "    Inst.addOperand(Inst.getOperand(" << TiedOp << "));\n";
+        Signature += "__Tie" + itostr(TiedOp);
+        continue;
       }
-    }
 
+      // Otherwise this is some sort of dummy operand that is mentioned in the
+      // ins/outs list but not mentioned in the asmstring, brutalize a dummy
+      // value into the operand.
+      // FIXME: This is a terrible hack: If an MCInst operand doesn't occur in
+      // the asmstring, there is no way to parse something meaningful.
+      // Just assume it is a zero register for now.
+      CaseOS << "    Inst.addOperand(MCOperand::CreateReg(0));\n";
+      Signature += "__Imp";
+    }
+    
     II.ConversionFnKind = Signature;
 
     // Check if we have already generated this signature.

Modified: llvm/trunk/utils/TableGen/CodeGenInstruction.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenInstruction.h?rev=118104&r1=118103&r2=118104&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenInstruction.h (original)
+++ llvm/trunk/utils/TableGen/CodeGenInstruction.h Tue Nov  2 17:55:03 2010
@@ -102,7 +102,18 @@
                   const std::string &EMN, unsigned MION, unsigned MINO,
                   DagInit *MIOI)
       : Rec(R), Name(N), PrinterMethodName(PMN), EncoderMethodName(EMN),
-      MIOperandNo(MION), MINumOperands(MINO), MIOperandInfo(MIOI) {}
+        MIOperandNo(MION), MINumOperands(MINO), MIOperandInfo(MIOI) {}
+      
+      
+      /// getTiedOperand - If this operand is tied to another one, return the
+      /// other operand number.  Otherwise, return -1.
+      int getTiedRegister() const {
+        for (unsigned j = 0, e = Constraints.size(); j != e; ++j) {
+          const CGIOperandList::ConstraintInfo &CI = Constraints[j];
+          if (CI.isTied()) return CI.getTiedOperand();
+        }
+        return -1;
+      }
     };
     
     CGIOperandList(Record *D);





More information about the llvm-commits mailing list