fix computation of ambiguous instructions to not ignore the mnemonic.
[oota-llvm.git] / utils / TableGen / AsmMatcherEmitter.cpp
index d4fe6beca3bd10227148c7caf87c0ddff8b1a492..532a7b5f175790e873849d3b242dffe125a4072e 100644 (file)
@@ -320,15 +320,18 @@ public:
   }
 };
 
-/// InstructionInfo - Helper class for storing the necessary information for an
-/// instruction which is capable of being matched.
-struct InstructionInfo {
+/// MatchableInfo - Helper class for storing the necessary information for an
+/// instruction or alias which is capable of being matched.
+struct MatchableInfo {
   struct Operand {
     /// The unique class instance this operand should match.
     ClassInfo *Class;
 
     /// The original operand this corresponds to, if any.
     const CGIOperandList::OperandInfo *OperandInfo;
+    
+    Operand(ClassInfo *C, const CGIOperandList::OperandInfo *OpInfo)
+      : Class(C), OperandInfo(OpInfo) {}
   };
 
   /// InstrName - The target name for this instruction.
@@ -355,34 +358,36 @@ struct InstructionInfo {
   /// function.
   std::string ConversionFnKind;
   
-  InstructionInfo(const CodeGenInstruction &CGI, StringRef CommentDelimiter)
-    : TheDef(CGI.TheDef), OperandList(CGI.Operands) {
+  MatchableInfo(const CodeGenInstruction &CGI)
+    : TheDef(CGI.TheDef), OperandList(CGI.Operands), AsmString(CGI.AsmString) {
     InstrName = TheDef->getName();
-    // TODO: Eventually support asmparser for Variant != 0.
-    AsmString = CGI.FlattenAsmStringVariants(CGI.AsmString, 0);
-    
-    // Remove comments from the asm string.  We know that the asmstring only
-    // has one line.
-    if (!CommentDelimiter.empty()) {
-      size_t Idx = StringRef(AsmString).find(CommentDelimiter);
-      if (Idx != StringRef::npos)
-        AsmString = AsmString.substr(0, Idx);
-    }
-    
-    TokenizeAsmString(AsmString, Tokens);
   }
 
-  /// isAssemblerInstruction - Return true if this matchable is a valid thing to
-  /// match against.
-  bool isAssemblerInstruction() const;
+  MatchableInfo(const CodeGenInstAlias *Alias)
+    : TheDef(Alias->TheDef), OperandList(Alias->Operands),
+      AsmString(Alias->AsmString) {
+        
+    // FIXME: Huge hack.
+    DefInit *DI = dynamic_cast<DefInit*>(Alias->Result->getOperator());
+    assert(DI);
+        
+    InstrName = DI->getDef()->getName();
+  }
+  
+  void Initialize(const AsmMatcherInfo &Info,
+                  SmallPtrSet<Record*, 16> &SingletonRegisters);
+  
+  /// Validate - Return true if this matchable is a valid thing to match against
+  /// and perform a bunch of validity checking.
+  bool Validate(StringRef CommentDelimiter, bool Hack) const;
   
   /// getSingletonRegisterForToken - If the specified token is a singleton
   /// register, return the Record for it, otherwise return null.
   Record *getSingletonRegisterForToken(unsigned i,
                                        const AsmMatcherInfo &Info) const;  
 
-  /// operator< - Compare two instructions.
-  bool operator<(const InstructionInfo &RHS) const {
+  /// operator< - Compare two matchables.
+  bool operator<(const MatchableInfo &RHS) const {
     // The primary comparator is the instruction mnemonic.
     if (Tokens[0] != RHS.Tokens[0])
       return Tokens[0] < RHS.Tokens[0];
@@ -402,10 +407,14 @@ struct InstructionInfo {
     return false;
   }
 
-  /// CouldMatchAmiguouslyWith - Check whether this instruction could
+  /// CouldMatchAmiguouslyWith - Check whether this matchable could
   /// ambiguously match the same set of operands as \arg RHS (without being a
   /// strictly superior match).
-  bool CouldMatchAmiguouslyWith(const InstructionInfo &RHS) {
+  bool CouldMatchAmiguouslyWith(const MatchableInfo &RHS) {
+    // The primary comparator is the instruction mnemonic.
+    if (Tokens[0] != RHS.Tokens[0])
+      return false;
+    
     // The number of operands is unambiguous.
     if (Operands.size() != RHS.Operands.size())
       return false;
@@ -465,17 +474,14 @@ public:
   /// Target - The target information.
   CodeGenTarget &Target;
 
-  /// The AsmParser "CommentDelimiter" value.
-  std::string CommentDelimiter;
-
   /// The AsmParser "RegisterPrefix" value.
   std::string RegisterPrefix;
 
   /// The classes which are needed for matching.
   std::vector<ClassInfo*> Classes;
 
-  /// The information on the instruction to match.
-  std::vector<InstructionInfo*> Instructions;
+  /// The information on the matchables to match.
+  std::vector<MatchableInfo*> Matchables;
 
   /// Map of Register records to their class information.
   std::map<Record*, ClassInfo*> RegisterClasses;
@@ -527,7 +533,7 @@ public:
 
 }
 
-void InstructionInfo::dump() {
+void MatchableInfo::dump() {
   errs() << InstrName << " -- " << "flattened:\"" << AsmString << '\"'
          << ", tokens:[";
   for (unsigned i = 0, e = Tokens.size(); i != e; ++i) {
@@ -556,6 +562,28 @@ void InstructionInfo::dump() {
   }
 }
 
+void MatchableInfo::Initialize(const AsmMatcherInfo &Info,
+                               SmallPtrSet<Record*, 16> &SingletonRegisters) {
+  // TODO: Eventually support asmparser for Variant != 0.
+  AsmString = CodeGenInstruction::FlattenAsmStringVariants(AsmString, 0);
+  
+  TokenizeAsmString(AsmString, Tokens);
+  
+  // Compute the require features.
+  std::vector<Record*> Predicates =TheDef->getValueAsListOfDefs("Predicates");
+  for (unsigned i = 0, e = Predicates.size(); i != e; ++i)
+    if (SubtargetFeatureInfo *Feature =
+        Info.getSubtargetFeature(Predicates[i]))
+      RequiredFeatures.push_back(Feature);
+  
+  // Collect singleton registers, if used.
+  for (unsigned i = 0, e = Tokens.size(); i != e; ++i) {
+    if (Record *Reg = getSingletonRegisterForToken(i, Info))
+      SingletonRegisters.insert(Reg);
+  }
+}
+
+
 /// getRegisterRecord - Get the register record for \arg name, or 0.
 static Record *getRegisterRecord(CodeGenTarget &Target, StringRef Name) {
   for (unsigned i = 0, e = Target.getRegisters().size(); i != e; ++i) {
@@ -567,22 +595,29 @@ static Record *getRegisterRecord(CodeGenTarget &Target, StringRef Name) {
   return 0;
 }
 
-bool InstructionInfo::isAssemblerInstruction() const {
-  StringRef Name = InstrName;
-  
-  // Reject instructions with no .s string.
+bool MatchableInfo::Validate(StringRef CommentDelimiter, bool Hack) const {
+  // Reject matchables with no .s string.
   if (AsmString.empty())
     throw TGError(TheDef->getLoc(), "instruction with empty asm string");
   
-  // Reject any instructions with a newline in them, they should be marked
+  // Reject any matchables with a newline in them, they should be marked
   // isCodeGenOnly if they are pseudo instructions.
   if (AsmString.find('\n') != std::string::npos)
     throw TGError(TheDef->getLoc(),
                   "multiline instruction is not valid for the asmparser, "
                   "mark it isCodeGenOnly");
   
-  // Reject instructions with attributes, these aren't something we can handle,
-  // the target should be refactored to use operands instead of modifiers.
+  // Remove comments from the asm string.  We know that the asmstring only
+  // has one line.
+  if (!CommentDelimiter.empty() &&
+      StringRef(AsmString).find(CommentDelimiter) != StringRef::npos)
+    throw TGError(TheDef->getLoc(),
+                  "asmstring for instruction has comment character in it, "
+                  "mark it isCodeGenOnly");
+  
+  // Reject matchables with operand modifiers, these aren't something we can
+  /// handle, the target should be refactored to use operands instead of
+  /// modifiers.
   //
   // Also, check for instructions which reference the operand multiple times;
   // this implies a constraint we would not honor.
@@ -590,16 +625,21 @@ bool InstructionInfo::isAssemblerInstruction() const {
   for (unsigned i = 1, e = Tokens.size(); i < e; ++i) {
     if (Tokens[i][0] == '$' && Tokens[i].find(':') != StringRef::npos)
       throw TGError(TheDef->getLoc(),
-                    "instruction with operand modifier '" + Tokens[i].str() +
+                    "matchable with operand modifier '" + Tokens[i].str() +
                     "' not supported by asm matcher.  Mark isCodeGenOnly!");
     
-    // FIXME: Should reject these.  The ARM backend hits this with $lane in a
-    // bunch of instructions.  It is unclear what the right answer is for this.
+    // Verify that any operand is only mentioned once.
     if (Tokens[i][0] == '$' && !OperandNames.insert(Tokens[i]).second) {
+      if (!Hack)
+        throw TGError(TheDef->getLoc(),
+                      "ERROR: matchable with tied operand '" + Tokens[i].str() +
+                      "' can never be matched!");
+      // FIXME: Should reject these.  The ARM backend hits this with $lane in a
+      // bunch of instructions.  It is unclear what the right answer is.
       DEBUG({
-        errs() << "warning: '" << Name << "': "
-        << "ignoring instruction with tied operand '"
-        << Tokens[i].str() << "'\n";
+        errs() << "warning: '" << InstrName << "': "
+               << "ignoring instruction with tied operand '"
+               << Tokens[i].str() << "'\n";
       });
       return false;
     }
@@ -611,7 +651,7 @@ bool InstructionInfo::isAssemblerInstruction() const {
 
 /// getSingletonRegisterForToken - If the specified token is a singleton
 /// register, return the register name, otherwise return a null StringRef.
-Record *InstructionInfo::
+Record *MatchableInfo::
 getSingletonRegisterForToken(unsigned i, const AsmMatcherInfo &Info) const {
   StringRef Tok = Tokens[i];
   if (!Tok.startswith(Info.RegisterPrefix))
@@ -674,10 +714,8 @@ AsmMatcherInfo::getOperandClass(StringRef Token,
   if (OI.Rec->isSubClassOf("RegisterClass")) {
     ClassInfo *CI = RegisterClassClasses[OI.Rec];
 
-    if (!CI) {
-      PrintError(OI.Rec->getLoc(), "register class has no class info!");
-      throw std::string("ERROR: Missing register class!");
-    }
+    if (!CI)
+      throw TGError(OI.Rec->getLoc(), "register class has no class info!");
 
     return CI;
   }
@@ -686,10 +724,8 @@ AsmMatcherInfo::getOperandClass(StringRef Token,
   Record *MatchClass = OI.Rec->getValueAsDef("ParserMatchClass");
   ClassInfo *CI = AsmOperandClasses[MatchClass];
 
-  if (!CI) {
-    PrintError(OI.Rec->getLoc(), "operand has no match class!");
-    throw std::string("ERROR: Missing match class!");
-  }
+  if (!CI)
+    throw TGError(OI.Rec->getLoc(), "operand has no match class!");
 
   return CI;
 }
@@ -817,8 +853,8 @@ BuildRegisterClasses(SmallPtrSet<Record*, 16> &SingletonRegisters) {
 }
 
 void AsmMatcherInfo::BuildOperandClasses() {
-  std::vector<Record*> AsmOperands;
-  AsmOperands = Records.getAllDerivedDefinitions("AsmOperandClass");
+  std::vector<Record*> AsmOperands =
+    Records.getAllDerivedDefinitions("AsmOperandClass");
 
   // Pre-populate AsmOperandClasses map.
   for (std::vector<Record*>::iterator it = AsmOperands.begin(),
@@ -876,11 +912,10 @@ void AsmMatcherInfo::BuildOperandClasses() {
 
 AsmMatcherInfo::AsmMatcherInfo(Record *asmParser, CodeGenTarget &target)
   : AsmParser(asmParser), Target(target),
-    CommentDelimiter(AsmParser->getValueAsString("CommentDelimiter")),
-    RegisterPrefix(AsmParser->getValueAsString("RegisterPrefix"))
-{
+    RegisterPrefix(AsmParser->getValueAsString("RegisterPrefix")) {
 }
 
+
 void AsmMatcherInfo::BuildInfo() {
   // Build information about all of the AssemblerPredicates.
   std::vector<Record*> AllPredicates =
@@ -891,16 +926,16 @@ void AsmMatcherInfo::BuildInfo() {
     if (!Pred->getValueAsBit("AssemblerMatcherPredicate"))
       continue;
     
-    if (Pred->getName().empty()) {
-      PrintError(Pred->getLoc(), "Predicate has no name!");
-      throw std::string("ERROR: Predicate defs must be named");
-    }
+    if (Pred->getName().empty())
+      throw TGError(Pred->getLoc(), "Predicate has no name!");
     
     unsigned FeatureNo = SubtargetFeatures.size();
     SubtargetFeatures[Pred] = new SubtargetFeatureInfo(Pred, FeatureNo);
     assert(FeatureNo < 32 && "Too many subtarget features!");
   }
 
+  StringRef CommentDelimiter = AsmParser->getValueAsString("CommentDelimiter");
+  
   // Parse the instructions; we need to do this first so that we can gather the
   // singleton register classes.
   SmallPtrSet<Record*, 16> SingletonRegisters;
@@ -917,11 +952,13 @@ void AsmMatcherInfo::BuildInfo() {
     if (CGI.TheDef->getValueAsBit("isCodeGenOnly"))
       continue;
     
-    OwningPtr<InstructionInfo> II(new InstructionInfo(CGI, CommentDelimiter));
+    OwningPtr<MatchableInfo> II(new MatchableInfo(CGI));
 
+    II->Initialize(*this, SingletonRegisters);
+    
     // Ignore instructions which shouldn't be matched and diagnose invalid
     // instruction definitions with an error.
-    if (!II->isAssemblerInstruction())
+    if (!II->Validate(CommentDelimiter, true))
       continue;
     
     // Ignore "Int_*" and "*_Int" instructions, which are internal aliases.
@@ -931,30 +968,24 @@ void AsmMatcherInfo::BuildInfo() {
         StringRef(II->InstrName).endswith("_Int"))
       continue;
     
-    // Collect singleton registers, if used.
-    for (unsigned i = 0, e = II->Tokens.size(); i != e; ++i) {
-      if (Record *Reg = II->getSingletonRegisterForToken(i, *this))
-        SingletonRegisters.insert(Reg);
-    }
-
-    // Compute the require features.
-    std::vector<Record*> Predicates =
-      CGI.TheDef->getValueAsListOfDefs("Predicates");
-    for (unsigned i = 0, e = Predicates.size(); i != e; ++i)
-      if (SubtargetFeatureInfo *Feature = getSubtargetFeature(Predicates[i]))
-        II->RequiredFeatures.push_back(Feature);
-
-    Instructions.push_back(II.take());
+     Matchables.push_back(II.take());
   }
   
-  // Parse all of the InstAlias definitions.
+  // Parse all of the InstAlias definitions and stick them in the list of
+  // matchables.
   std::vector<Record*> AllInstAliases =
     Records.getAllDerivedDefinitions("InstAlias");
   for (unsigned i = 0, e = AllInstAliases.size(); i != e; ++i) {
     CodeGenInstAlias *Alias = new CodeGenInstAlias(AllInstAliases[i]);
 
+    OwningPtr<MatchableInfo> II(new MatchableInfo(Alias));
+    
+    II->Initialize(*this, SingletonRegisters);
     
-    (void)Alias;
+    // Validate the alias definitions.
+    II->Validate(CommentDelimiter, false);
+    
+    Matchables.push_back(II.take());
   }
 
   // Build info for the register classes.
@@ -963,10 +994,10 @@ void AsmMatcherInfo::BuildInfo() {
   // Build info for the user defined assembly operand classes.
   BuildOperandClasses();
 
-  // Build the instruction information.
-  for (std::vector<InstructionInfo*>::iterator it = Instructions.begin(),
-         ie = Instructions.end(); it != ie; ++it) {
-    InstructionInfo *II = *it;
+  // Build the information about matchables.
+  for (std::vector<MatchableInfo*>::iterator it = Matchables.begin(),
+         ie = Matchables.end(); it != ie; ++it) {
+    MatchableInfo *II = *it;
 
     // The first token of the instruction is the mnemonic, which must be a
     // simple string, not a $foo variable or a singleton register.
@@ -982,9 +1013,7 @@ void AsmMatcherInfo::BuildInfo() {
 
       // Check for singleton registers.
       if (Record *RegRecord = II->getSingletonRegisterForToken(i, *this)) {
-        InstructionInfo::Operand Op;
-        Op.Class = RegisterClasses[RegRecord];
-        Op.OperandInfo = 0;
+        MatchableInfo::Operand Op(RegisterClasses[RegRecord], 0);
         assert(Op.Class && Op.Class->Registers.size() == 1 &&
                "Unexpected class for singleton register");
         II->Operands.push_back(Op);
@@ -993,10 +1022,7 @@ void AsmMatcherInfo::BuildInfo() {
 
       // Check for simple tokens.
       if (Token[0] != '$') {
-        InstructionInfo::Operand Op;
-        Op.Class = getTokenClass(Token);
-        Op.OperandInfo = 0;
-        II->Operands.push_back(Op);
+        II->Operands.push_back(MatchableInfo::Operand(getTokenClass(Token), 0));
         continue;
       }
 
@@ -1010,8 +1036,8 @@ void AsmMatcherInfo::BuildInfo() {
       // Map this token to an operand. FIXME: Move elsewhere.
       unsigned Idx;
       if (!II->OperandList.hasOperandNamed(OperandName, Idx))
-        throw std::string("error: unable to find operand: '" +
-                          OperandName.str() + "'");
+        throw TGError(II->TheDef->getLoc(), "error: unable to find operand: '" +
+                      OperandName.str() + "'");
 
       // FIXME: This is annoying, the named operand may be tied (e.g.,
       // XCHG8rm). What we want is the untied operand, which we now have to
@@ -1033,10 +1059,8 @@ void AsmMatcherInfo::BuildInfo() {
         assert(OI && "Unable to find tied operand target!");
       }
 
-      InstructionInfo::Operand Op;
-      Op.Class = getOperandClass(Token, *OI);
-      Op.OperandInfo = OI;
-      II->Operands.push_back(Op);
+      II->Operands.push_back(MatchableInfo::Operand(getOperandClass(Token,
+                                                                    *OI), OI));
     }
   }
 
@@ -1055,7 +1079,7 @@ GetTiedOperandAtIndex(SmallVectorImpl<std::pair<unsigned, unsigned> > &List,
 }
 
 static void EmitConvertToMCInst(CodeGenTarget &Target,
-                                std::vector<InstructionInfo*> &Infos,
+                                std::vector<MatchableInfo*> &Infos,
                                 raw_ostream &OS) {
   // Write the convert function to a separate stream, so we can drop it after
   // the enum.
@@ -1083,14 +1107,14 @@ static void EmitConvertToMCInst(CodeGenTarget &Target,
   // TargetOperandClass - This is the target's operand class, like X86Operand.
   std::string TargetOperandClass = Target.getName() + "Operand";
 
-  for (std::vector<InstructionInfo*>::const_iterator it = Infos.begin(),
+  for (std::vector<MatchableInfo*>::const_iterator it = Infos.begin(),
          ie = Infos.end(); it != ie; ++it) {
-    InstructionInfo &II = **it;
+    MatchableInfo &II = **it;
 
     // 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.Operands.size(); i != e; ++i) {
-      InstructionInfo::Operand &Op = II.Operands[i];
+      MatchableInfo::Operand &Op = II.Operands[i];
       if (Op.OperandInfo)
         MIOperandList.push_back(std::make_pair(Op.OperandInfo->MIOperandNo, i));
     }
@@ -1107,7 +1131,7 @@ static void EmitConvertToMCInst(CodeGenTarget &Target,
       }
     }
 
-    std::sort(MIOperandList.begin(), MIOperandList.end());
+    array_pod_sort(MIOperandList.begin(), MIOperandList.end());
 
     // Compute the total number of operands.
     unsigned NumMIOperands = 0;
@@ -1121,7 +1145,7 @@ static void EmitConvertToMCInst(CodeGenTarget &Target,
     std::string Signature = "Convert";
     unsigned CurIndex = 0;
     for (unsigned i = 0, e = MIOperandList.size(); i != e; ++i) {
-      InstructionInfo::Operand &Op = II.Operands[MIOperandList[i].second];
+      MatchableInfo::Operand &Op = II.Operands[MIOperandList[i].second];
       assert(CurIndex <= Op.OperandInfo->MIOperandNo &&
              "Duplicate match for instruction operand!");
 
@@ -1180,7 +1204,7 @@ static void EmitConvertToMCInst(CodeGenTarget &Target,
     CvtOS << "  case " << Signature << ":\n";
     CurIndex = 0;
     for (unsigned i = 0, e = MIOperandList.size(); i != e; ++i) {
-      InstructionInfo::Operand &Op = II.Operands[MIOperandList[i].second];
+      MatchableInfo::Operand &Op = II.Operands[MIOperandList[i].second];
 
       // Add the implicit operands.
       for (; CurIndex != Op.OperandInfo->MIOperandNo; ++CurIndex) {
@@ -1536,8 +1560,7 @@ static bool EmitMnemonicAliases(raw_ostream &OS, const AsmMatcherInfo &Info) {
           // We can't have two aliases from the same mnemonic with no predicate.
           PrintError(ToVec[AliasWithNoPredicate]->getLoc(),
                      "two MnemonicAliases with the same 'from' mnemonic!");
-          PrintError(R->getLoc(), "this is the other MnemonicAlias.");
-          throw std::string("ERROR: Invalid MnemonicAlias definitions!");
+          throw TGError(R->getLoc(), "this is the other MnemonicAlias.");
         }
         
         AliasWithNoPredicate = i;
@@ -1581,26 +1604,26 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
   // Sort the instruction table using the partial order on classes. We use
   // stable_sort to ensure that ambiguous instructions are still
   // deterministically ordered.
-  std::stable_sort(Info.Instructions.begin(), Info.Instructions.end(),
-                   less_ptr<InstructionInfo>());
+  std::stable_sort(Info.Matchables.begin(), Info.Matchables.end(),
+                   less_ptr<MatchableInfo>());
 
   DEBUG_WITH_TYPE("instruction_info", {
-      for (std::vector<InstructionInfo*>::iterator
-             it = Info.Instructions.begin(), ie = Info.Instructions.end();
+      for (std::vector<MatchableInfo*>::iterator
+             it = Info.Matchables.begin(), ie = Info.Matchables.end();
            it != ie; ++it)
         (*it)->dump();
     });
 
-  // Check for ambiguous instructions.
+  // Check for ambiguous matchables.
   DEBUG_WITH_TYPE("ambiguous_instrs", {
     unsigned NumAmbiguous = 0;
-    for (unsigned i = 0, e = Info.Instructions.size(); i != e; ++i) {
+    for (unsigned i = 0, e = Info.Matchables.size(); i != e; ++i) {
       for (unsigned j = i + 1; j != e; ++j) {
-        InstructionInfo &A = *Info.Instructions[i];
-        InstructionInfo &B = *Info.Instructions[j];
+        MatchableInfo &A = *Info.Matchables[i];
+        MatchableInfo &B = *Info.Matchables[j];
 
         if (A.CouldMatchAmiguouslyWith(B)) {
-          errs() << "warning: ambiguous instruction match:\n";
+          errs() << "warning: ambiguous matchables:\n";
           A.dump();
           errs() << "\nis incomparable with:\n";
           B.dump();
@@ -1611,7 +1634,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
     }
     if (NumAmbiguous)
       errs() << "warning: " << NumAmbiguous
-             << " ambiguous instructions!\n";
+             << " ambiguous matchables!\n";
   });
 
   // Write the output.
@@ -1656,7 +1679,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
   bool HasMnemonicAliases = EmitMnemonicAliases(OS, Info);
   
   // Generate the unified function to convert operands into an MCInst.
-  EmitConvertToMCInst(Target, Info.Instructions, OS);
+  EmitConvertToMCInst(Target, Info.Matchables, OS);
 
   // Emit the enumeration for classes which participate in matching.
   EmitMatchClassEnumeration(Target, Info.Classes, OS);
@@ -1675,8 +1698,8 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
 
 
   size_t MaxNumOperands = 0;
-  for (std::vector<InstructionInfo*>::const_iterator it =
-         Info.Instructions.begin(), ie = Info.Instructions.end();
+  for (std::vector<MatchableInfo*>::const_iterator it =
+         Info.Matchables.begin(), ie = Info.Matchables.end();
        it != ie; ++it)
     MaxNumOperands = std::max(MaxNumOperands, (*it)->Operands.size());
 
@@ -1716,18 +1739,18 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
   OS << "} // end anonymous namespace.\n\n";
 
   OS << "static const MatchEntry MatchTable["
-     << Info.Instructions.size() << "] = {\n";
+     << Info.Matchables.size() << "] = {\n";
 
-  for (std::vector<InstructionInfo*>::const_iterator it =
-       Info.Instructions.begin(), ie = Info.Instructions.end();
+  for (std::vector<MatchableInfo*>::const_iterator it =
+       Info.Matchables.begin(), ie = Info.Matchables.end();
        it != ie; ++it) {
-    InstructionInfo &II = **it;
+    MatchableInfo &II = **it;
 
     OS << "  { " << Target.getName() << "::" << II.InstrName
     << ", \"" << II.Tokens[0] << "\""
     << ", " << II.ConversionFnKind << ", { ";
     for (unsigned i = 0, e = II.Operands.size(); i != e; ++i) {
-      InstructionInfo::Operand &Op = II.Operands[i];
+      MatchableInfo::Operand &Op = II.Operands[i];
 
       if (i) OS << ", ";
       OS << Op.Class->Name;
@@ -1802,7 +1825,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
   OS << "  // Search the table.\n";
   OS << "  std::pair<const MatchEntry*, const MatchEntry*> MnemonicRange =\n";
   OS << "    std::equal_range(MatchTable, MatchTable+"
-     << Info.Instructions.size() << ", Mnemonic, LessOpcode());\n\n";
+     << Info.Matchables.size() << ", Mnemonic, LessOpcode());\n\n";
 
   OS << "  // Return a more specific error code if no mnemonics match.\n";
   OS << "  if (MnemonicRange.first == MnemonicRange.second)\n";