<div dir="ltr">Can we diff the tablegen outputs before and after the change?</div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Dec 3, 2014 at 3:57 PM, Duncan P. N. Exon Smith <span dir="ltr"><<a href="mailto:dexonsmith@apple.com" target="_blank">dexonsmith@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I looked into test/CodeGen/X86/compact-unwind.ll.  llvm-mc was giving<br>
different results.  Given that you changed `tablegen`, I frankly gave<br>
up on figuring out exactly why.<br>
<br>
I went back and reviewed the patch for changed semantics, and took a<br>
shot in the dark.  The `sort()` at the end is different from the<br>
old `sort()`, because items have been front-loaded instead of back-<br>
loaded.<br>
<br>
The fix is to sort it backwards and then reverse the list.  This passes<br>
`check` for me.<br>
<br>
I don't know why this is platform-specific... I can't think of why<br>
that makes sense.<br>
<br>
<br><br>
> On 2014-Dec-03, at 14:39, David Blaikie <<a href="mailto:dblaikie@gmail.com">dblaikie@gmail.com</a>> wrote:<br>
><br>
><br>
><br>
> On Fri, Nov 28, 2014 at 3:04 PM, Duncan P. N. Exon Smith <<a href="mailto:dexonsmith@apple.com">dexonsmith@apple.com</a>> wrote:<br>
> I reverted this (and the follow-up in r222938) in r222943.<br>
><br>
> Skimming the commit, I suspect the failures are caused by front-loading<br>
> the sequence instead of back-loading, but I didn't have a chance to<br>
> investigate.<br>
><br>
> Let me know if the failures don't reproduce for you and I can help you<br>
> dig into it.<br>
><br>
> Wouldn't mind a little help here - some of the tests failing (just taking the first one as a random example, test/CodeGen/X86/compact-unwind.ll) have hardcoded triples for darwin, so it doesn't seem like it's a matter of the target, so much as the host - I don't have a build setup on macos, so I'm not sure if there's anything more I can do to reproduce these failures...<br>
><br>
> - David<br>
><br>
><br>
> > On 2014 Nov 28, at 14:38, Duncan P. N. Exon Smith <<a href="mailto:dexonsmith@apple.com">dexonsmith@apple.com</a>> wrote:<br>
> ><br>
> > Our public incremental builder started failing with this commit:<br>
> > <a href="http://lab.llvm.org:8080/green/job/clang-stage1-cmake-RA-incremental/1391/" target="_blank">http://lab.llvm.org:8080/green/job/clang-stage1-cmake-RA-incremental/1391/</a><br>
> ><br>
> > Previous build was r222933, and was clean:<br>
> > <a href="http://lab.llvm.org:8080/green/job/clang-stage1-cmake-RA-incremental/1390/" target="_blank">http://lab.llvm.org:8080/green/job/clang-stage1-cmake-RA-incremental/1390/</a><br>
> ><br>
> > (r222934 was formatting-only.)<br>
> ><br>
> > Our non-incremental builder started failing around then as well:<br>
> > <a href="http://lab.llvm.org:8080/green/job/clang-stage1-configure-RA/1251/" target="_blank">http://lab.llvm.org:8080/green/job/clang-stage1-configure-RA/1251/</a><br>
> ><br>
> > Here's the failure:<br>
> ><br>
> > Failing Tests (34):<br>
> >    LLVM :: CodeGen/X86/compact-unwind.ll<br>
> >    LLVM :: CodeGen/X86/no-compact-unwind.ll<br>
> >    LLVM :: ExecutionEngine/RuntimeDyld/X86/MachO_i386_eh_frame.s<br>
> >    LLVM :: MC/ARM/basic-arm-instructions.s<br>
> >    LLVM :: MC/ARM/basic-thumb-instructions.s<br>
> >    LLVM :: MC/ARM/thumb-diagnostics.s<br>
> >    LLVM :: MC/ARM/v8_IT_manual.s<br>
> >    LLVM :: MC/COFF/seh-align3.s<br>
> >    LLVM :: MC/COFF/seh-section.s<br>
> >    LLVM :: MC/COFF/seh.s<br>
> >    LLVM :: MC/ELF/relax-all-flag.s<br>
> >    LLVM :: MC/ELF/relax.s<br>
> >    LLVM :: MC/ELF/subsection.s<br>
> >    LLVM :: MC/MachO/ARM/llvm-objdump-macho.s<br>
> >    LLVM :: MC/MachO/ARM/long-call-branch-island-relocation.s<br>
> >    LLVM :: MC/MachO/darwin-x86_64-diff-relocs.s<br>
> >    LLVM :: MC/MachO/darwin-x86_64-nobase-relocs.s<br>
> >    LLVM :: MC/MachO/direction_labels.s<br>
> >    LLVM :: MC/MachO/jcc.s<br>
> >    LLVM :: MC/MachO/relax-recompute-align.s<br>
> >    LLVM :: MC/MachO/reloc.s<br>
> >    LLVM :: MC/Mips/micromips-16-bit-instructions.s<br>
> >    LLVM :: MC/Mips/micromips-control-instructions.s<br>
> >    LLVM :: MC/X86/AlignedBundling/long-nop-pad.s<br>
> >    LLVM :: MC/X86/AlignedBundling/relax-at-bundle-end.s<br>
> >    LLVM :: MC/X86/AlignedBundling/relax-in-bundle-group.s<br>
> >    LLVM :: MC/X86/AlignedBundling/single-inst-bundling.s<br>
> >    LLVM :: MC/X86/avx512-encodings.s<br>
> >    LLVM :: MC/X86/intel-syntax-encoding.s<br>
> >    LLVM :: MC/X86/stackmap-nops.ll<br>
> >    LLVM :: MC/X86/x86-64-avx512bw.s<br>
> >    LLVM :: MC/X86/x86-64-avx512bw_vl.s<br>
> >    LLVM :: MC/X86/x86-64-avx512f_vl.s<br>
> >    LLVM :: MC/X86/x86-64.s<br>
> ><br>
> > Let me know if you need help reproducing.<br>
> ><br>
> >> On 2014 Nov 28, at 13:20, David Blaikie <<a href="mailto:dblaikie@gmail.com">dblaikie@gmail.com</a>> wrote:<br>
> >><br>
> >> Author: dblaikie<br>
> >> Date: Fri Nov 28 15:20:24 2014<br>
> >> New Revision: 222935<br>
> >><br>
> >> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=222935&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=222935&view=rev</a><br>
> >> Log:<br>
> >> Simplify some more ownership using forward_list<T> rather than vector<unique_ptr<T>><br>
> >><br>
> >> Modified:<br>
> >>   llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp<br>
> >><br>
> >> Modified: llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp<br>
> >> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp?rev=222935&r1=222934&r2=222935&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp?rev=222935&r1=222934&r2=222935&view=diff</a><br>
> >> ==============================================================================<br>
> >> --- llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp (original)<br>
> >> +++ llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp Fri Nov 28 15:20:24 2014<br>
> >> @@ -616,7 +616,7 @@ public:<br>
> >>  std::forward_list<ClassInfo> Classes;<br>
> >><br>
> >>  /// The information on the matchables to match.<br>
> >> -  std::vector<std::unique_ptr<MatchableInfo>> Matchables;<br>
> >> +  std::forward_list<MatchableInfo> Matchables;<br>
> >><br>
> >>  /// Info for custom matching operands by user defined methods.<br>
> >>  std::vector<OperandMatchEntry> OperandMatchInfo;<br>
> >> @@ -1285,8 +1285,8 @@ void AsmMatcherInfo::buildOperandMatchIn<br>
> >><br>
> >>    // Keep track of all operands of this instructions which belong to the<br>
> >>    // same class.<br>
> >> -    for (unsigned i = 0, e = MI->AsmOperands.size(); i != e; ++i) {<br>
> >> -      const MatchableInfo::AsmOperand &Op = MI->AsmOperands[i];<br>
> >> +    for (unsigned i = 0, e = MI.AsmOperands.size(); i != e; ++i) {<br>
> >> +      const MatchableInfo::AsmOperand &Op = MI.AsmOperands[i];<br>
> >>      if (Op.Class->ParserMethod.empty())<br>
> >>        continue;<br>
> >>      unsigned &OperandMask = OpClassMask[Op.Class];<br>
> >> @@ -1297,8 +1297,7 @@ void AsmMatcherInfo::buildOperandMatchIn<br>
> >>    for (const auto &OCM : OpClassMask) {<br>
> >>      unsigned OpMask = OCM.second;<br>
> >>      ClassInfo *CI = OCM.first;<br>
> >> -      OperandMatchInfo.push_back(OperandMatchEntry::create(MI.get(), CI,<br>
> >> -                                                           OpMask));<br>
> >> +      OperandMatchInfo.push_back(OperandMatchEntry::create(&MI, CI, OpMask));<br>
> >>    }<br>
> >>  }<br>
> >> }<br>
> >> @@ -1345,16 +1344,15 @@ void AsmMatcherInfo::buildInfo() {<br>
> >>      if (CGI->TheDef->getValueAsBit("isCodeGenOnly"))<br>
> >>        continue;<br>
> >><br>
> >> -      std::unique_ptr<MatchableInfo> II(new MatchableInfo(*CGI));<br>
> >> +      Matchables.emplace_front(*CGI);<br>
> >> +      MatchableInfo *II = &Matchables.front();<br>
> >><br>
> >>      II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix);<br>
> >><br>
> >>      // Ignore instructions which shouldn't be matched and diagnose invalid<br>
> >>      // instruction definitions with an error.<br>
> >>      if (!II->validate(CommentDelimiter, true))<br>
> >> -        continue;<br>
> >> -<br>
> >> -      Matchables.push_back(std::move(II));<br>
> >> +        Matchables.pop_front();<br>
> >>    }<br>
> >><br>
> >>    // Parse all of the InstAlias definitions and stick them in the list of<br>
> >> @@ -1372,14 +1370,13 @@ void AsmMatcherInfo::buildInfo() {<br>
> >>            .startswith( MatchPrefix))<br>
> >>        continue;<br>
> >><br>
> >> -      std::unique_ptr<MatchableInfo> II(new MatchableInfo(Alias));<br>
> >> +      Matchables.emplace_front(Alias);<br>
> >> +      MatchableInfo *II = &Matchables.front();<br>
> >><br>
> >>      II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix);<br>
> >><br>
> >>      // Validate the alias definitions.<br>
> >>      II->validate(CommentDelimiter, false);<br>
> >> -<br>
> >> -      Matchables.push_back(std::move(II));<br>
> >>    }<br>
> >>  }<br>
> >><br>
> >> @@ -1391,17 +1388,17 @@ void AsmMatcherInfo::buildInfo() {<br>
> >><br>
> >>  // Build the information about matchables, now that we have fully formed<br>
> >>  // classes.<br>
> >> -  std::vector<std::unique_ptr<MatchableInfo>> NewMatchables;<br>
> >> +  std::forward_list<MatchableInfo> NewMatchables;<br>
> >>  for (auto &II : Matchables) {<br>
> >>    // Parse the tokens after the mnemonic.<br>
> >>    // Note: buildInstructionOperandReference may insert new AsmOperands, so<br>
> >>    // don't precompute the loop bound.<br>
> >> -    for (unsigned i = 0; i != II->AsmOperands.size(); ++i) {<br>
> >> -      MatchableInfo::AsmOperand &Op = II->AsmOperands[i];<br>
> >> +    for (unsigned i = 0; i != II.AsmOperands.size(); ++i) {<br>
> >> +      MatchableInfo::AsmOperand &Op = II.AsmOperands[i];<br>
> >>      StringRef Token = Op.Token;<br>
> >><br>
> >>      // Check for singleton registers.<br>
> >> -      if (Record *RegRecord = II->AsmOperands[i].SingletonReg) {<br>
> >> +      if (Record *RegRecord = II.AsmOperands[i].SingletonReg) {<br>
> >>        Op.Class = RegisterClasses[RegRecord];<br>
> >>        assert(Op.Class && Op.Class->Registers.size() == 1 &&<br>
> >>               "Unexpected class for singleton register");<br>
> >> @@ -1426,35 +1423,30 @@ void AsmMatcherInfo::buildInfo() {<br>
> >>      else<br>
> >>        OperandName = Token.substr(1);<br>
> >><br>
> >> -      if (II->DefRec.is<const CodeGenInstruction*>())<br>
> >> -        buildInstructionOperandReference(II.get(), OperandName, i);<br>
> >> +      if (<a href="http://II.DefRec.is" target="_blank">II.DefRec.is</a><const CodeGenInstruction *>())<br>
> >> +        buildInstructionOperandReference(&II, OperandName, i);<br>
> >>      else<br>
> >> -        buildAliasOperandReference(II.get(), OperandName, Op);<br>
> >> +        buildAliasOperandReference(&II, OperandName, Op);<br>
> >>    }<br>
> >><br>
> >> -    if (II->DefRec.is<const CodeGenInstruction*>()) {<br>
> >> -      II->buildInstructionResultOperands();<br>
> >> +    if (<a href="http://II.DefRec.is" target="_blank">II.DefRec.is</a><const CodeGenInstruction *>()) {<br>
> >> +      II.buildInstructionResultOperands();<br>
> >>      // If the instruction has a two-operand alias, build up the<br>
> >>      // matchable here. We'll add them in bulk at the end to avoid<br>
> >>      // confusing this loop.<br>
> >>      std::string Constraint =<br>
> >> -        II->TheDef->getValueAsString("TwoOperandAliasConstraint");<br>
> >> +          II.TheDef->getValueAsString("TwoOperandAliasConstraint");<br>
> >>      if (Constraint != "") {<br>
> >>        // Start by making a copy of the original matchable.<br>
> >> -        std::unique_ptr<MatchableInfo> AliasII(new MatchableInfo(*II));<br>
> >> +        NewMatchables.emplace_front(II);<br>
> >><br>
> >>        // Adjust it to be a two-operand alias.<br>
> >> -        AliasII->formTwoOperandAlias(Constraint);<br>
> >> -<br>
> >> -        // Add the alias to the matchables list.<br>
> >> -        NewMatchables.push_back(std::move(AliasII));<br>
> >> +        NewMatchables.front().formTwoOperandAlias(Constraint);<br>
> >>      }<br>
> >>    } else<br>
> >> -      II->buildAliasResultOperands();<br>
> >> +      II.buildAliasResultOperands();<br>
> >>  }<br>
> >> -  if (!NewMatchables.empty())<br>
> >> -    std::move(NewMatchables.begin(), NewMatchables.end(),<br>
> >> -              std::back_inserter(Matchables));<br>
> >> +  Matchables.splice_after(Matchables.before_begin(), NewMatchables);<br>
> >><br>
> >>  // Process token alias definitions and set up the associated superclass<br>
> >>  // information.<br>
> >> @@ -1679,9 +1671,8 @@ static unsigned getConverterOperandID(co<br>
> >>  return ID;<br>
> >> }<br>
> >><br>
> >> -<br>
> >> static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,<br>
> >> -                             std::vector<std::unique_ptr<MatchableInfo>> &Infos,<br>
> >> +                             std::forward_list<MatchableInfo> &Infos,<br>
> >>                             raw_ostream &OS) {<br>
> >>  SetVector<std::string> OperandConversionKinds;<br>
> >>  SetVector<std::string> InstructionConversionKinds;<br>
> >> @@ -1748,10 +1739,10 @@ static void emitConvertFuncs(CodeGenTarg<br>
> >>  for (auto &II : Infos) {<br>
> >>    // Check if we have a custom match function.<br>
> >>    std::string AsmMatchConverter =<br>
> >> -      II->getResultInst()->TheDef->getValueAsString("AsmMatchConverter");<br>
> >> +        II.getResultInst()->TheDef->getValueAsString("AsmMatchConverter");<br>
> >>    if (!AsmMatchConverter.empty()) {<br>
> >>      std::string Signature = "ConvertCustom_" + AsmMatchConverter;<br>
> >> -      II->ConversionFnKind = Signature;<br>
> >> +      II.ConversionFnKind = Signature;<br>
> >><br>
> >>      // Check if we have already generated this signature.<br>
> >>      if (!InstructionConversionKinds.insert(Signature))<br>
> >> @@ -1783,17 +1774,17 @@ static void emitConvertFuncs(CodeGenTarg<br>
> >>    std::vector<uint8_t> ConversionRow;<br>
> >><br>
> >>    // Compute the convert enum and the case body.<br>
> >> -    MaxRowLength = std::max(MaxRowLength, II->ResOperands.size()*2 + 1 );<br>
> >> +    MaxRowLength = std::max(MaxRowLength, II.ResOperands.size() * 2 + 1);<br>
> >><br>
> >> -    for (unsigned i = 0, e = II->ResOperands.size(); i != e; ++i) {<br>
> >> -      const MatchableInfo::ResOperand &OpInfo = II->ResOperands[i];<br>
> >> +    for (unsigned i = 0, e = II.ResOperands.size(); i != e; ++i) {<br>
> >> +      const MatchableInfo::ResOperand &OpInfo = II.ResOperands[i];<br>
> >><br>
> >>      // Generate code to populate each result operand.<br>
> >>      switch (OpInfo.Kind) {<br>
> >>      case MatchableInfo::ResOperand::RenderAsmOperand: {<br>
> >>        // This comes from something we parsed.<br>
> >>        const MatchableInfo::AsmOperand &Op =<br>
> >> -          II->AsmOperands[OpInfo.AsmOperandNum];<br>
> >> +            II.AsmOperands[OpInfo.AsmOperandNum];<br>
> >><br>
> >>        // Registers are always converted the same, don't duplicate the<br>
> >>        // conversion function based on them.<br>
> >> @@ -1916,7 +1907,7 @@ static void emitConvertFuncs(CodeGenTarg<br>
> >>    if (Signature == "Convert")<br>
> >>      Signature += "_NoOperands";<br>
> >><br>
> >> -    II->ConversionFnKind = Signature;<br>
> >> +    II.ConversionFnKind = Signature;<br>
> >><br>
> >>    // Save the signature. If we already have it, don't add a new row<br>
> >>    // to the table.<br>
> >> @@ -2602,23 +2593,21 @@ void AsmMatcherEmitter::run(raw_ostream<br>
> >>  // Sort the instruction table using the partial order on classes. We use<br>
> >>  // stable_sort to ensure that ambiguous instructions are still<br>
> >>  // deterministically ordered.<br>
> >> -  std::stable_sort(Info.Matchables.begin(), Info.Matchables.end(),<br>
> >> -                   [](const std::unique_ptr<MatchableInfo> &a,<br>
> >> -                      const std::unique_ptr<MatchableInfo> &b){<br>
> >> -                     return *a < *b;});<br>
> >> +  Info.Matchables.sort();<br>
> >><br>
> >>  DEBUG_WITH_TYPE("instruction_info", {<br>
> >>      for (const auto &MI : Info.Matchables)<br>
> >> -        MI->dump();<br>
> >> +        MI.dump();<br>
> >>    });<br>
> >><br>
> >>  // Check for ambiguous matchables.<br>
> >>  DEBUG_WITH_TYPE("ambiguous_instrs", {<br>
> >>    unsigned NumAmbiguous = 0;<br>
> >> -    for (unsigned i = 0, e = Info.Matchables.size(); i != e; ++i) {<br>
> >> -      for (unsigned j = i + 1; j != e; ++j) {<br>
> >> -        const MatchableInfo &A = *Info.Matchables[i];<br>
> >> -        const MatchableInfo &B = *Info.Matchables[j];<br>
> >> +    for (auto I = Info.Matchables.begin(), E = Info.Matchables.end(); I != E;<br>
> >> +         ++I) {<br>
> >> +      for (auto J = std::next(I); J != E; ++J) {<br>
> >> +        const MatchableInfo &A = *I;<br>
> >> +        const MatchableInfo &B = *J;<br>
> >><br>
> >>        if (A.couldMatchAmbiguouslyWith(B)) {<br>
> >>          errs() << "warning: ambiguous matchables:\n";<br>
> >> @@ -2739,11 +2728,11 @@ void AsmMatcherEmitter::run(raw_ostream<br>
> >>  unsigned MaxMnemonicIndex = 0;<br>
> >>  bool HasDeprecation = false;<br>
> >>  for (const auto &MI : Info.Matchables) {<br>
> >> -    MaxNumOperands = std::max(MaxNumOperands, MI->AsmOperands.size());<br>
> >> -    HasDeprecation |= MI->HasDeprecation;<br>
> >> +    MaxNumOperands = std::max(MaxNumOperands, MI.AsmOperands.size());<br>
> >> +    HasDeprecation |= MI.HasDeprecation;<br>
> >><br>
> >>    // Store a pascal-style length byte in the mnemonic.<br>
> >> -    std::string LenMnemonic = char(MI->Mnemonic.size()) + MI->Mnemonic.str();<br>
> >> +    std::string LenMnemonic = char(MI.Mnemonic.size()) + MI.Mnemonic.str();<br>
> >>    MaxMnemonicIndex = std::max(MaxMnemonicIndex,<br>
> >>                        StringTable.GetOrAddStringOffset(LenMnemonic, false));<br>
> >>  }<br>
> >> @@ -2767,8 +2756,9 @@ void AsmMatcherEmitter::run(raw_ostream<br>
> >>  OS << "    " << getMinimalTypeForRange(MaxMnemonicIndex)<br>
> >>               << " Mnemonic;\n";<br>
> >>  OS << "    uint16_t Opcode;\n";<br>
> >> -  OS << "    " << getMinimalTypeForRange(Info.Matchables.size())<br>
> >> -               << " ConvertFn;\n";<br>
> >> +  OS << "    " << getMinimalTypeForRange(std::distance(Info.Matchables.begin(),<br>
> >> +                                                       Info.Matchables.end()))<br>
> >> +     << " ConvertFn;\n";<br>
> >>  OS << "    " << getMinimalRequiredFeaturesType(Info)<br>
> >>               << " RequiredFeatures;\n";<br>
> >>  OS << "    " << getMinimalTypeForRange(<br>
> >> @@ -2803,29 +2793,28 @@ void AsmMatcherEmitter::run(raw_ostream<br>
> >>    OS << "static const MatchEntry MatchTable" << VC << "[] = {\n";<br>
> >><br>
> >>    for (const auto &MI : Info.Matchables) {<br>
> >> -      if (MI->AsmVariantID != AsmVariantNo)<br>
> >> +      if (MI.AsmVariantID != AsmVariantNo)<br>
> >>        continue;<br>
> >><br>
> >>      // Store a pascal-style length byte in the mnemonic.<br>
> >> -      std::string LenMnemonic = char(MI->Mnemonic.size()) + MI->Mnemonic.str();<br>
> >> +      std::string LenMnemonic = char(MI.Mnemonic.size()) + MI.Mnemonic.str();<br>
> >>      OS << "  { " << StringTable.GetOrAddStringOffset(LenMnemonic, false)<br>
> >> -         << " /* " << MI->Mnemonic << " */, "<br>
> >> -         << Target.getName() << "::"<br>
> >> -         << MI->getResultInst()->TheDef->getName() << ", "<br>
> >> -         << MI->ConversionFnKind << ", ";<br>
> >> +         << " /* " << MI.Mnemonic << " */, " << Target.getName()<br>
> >> +         << "::" << MI.getResultInst()->TheDef->getName() << ", "<br>
> >> +         << MI.ConversionFnKind << ", ";<br>
> >><br>
> >>      // Write the required features mask.<br>
> >> -      if (!MI->RequiredFeatures.empty()) {<br>
> >> -        for (unsigned i = 0, e = MI->RequiredFeatures.size(); i != e; ++i) {<br>
> >> +      if (!MI.RequiredFeatures.empty()) {<br>
> >> +        for (unsigned i = 0, e = MI.RequiredFeatures.size(); i != e; ++i) {<br>
> >>          if (i) OS << "|";<br>
> >> -          OS << MI->RequiredFeatures[i]->getEnumName();<br>
> >> +          OS << MI.RequiredFeatures[i]->getEnumName();<br>
> >>        }<br>
> >>      } else<br>
> >>        OS << "0";<br>
> >><br>
> >>      OS << ", { ";<br>
> >> -      for (unsigned i = 0, e = MI->AsmOperands.size(); i != e; ++i) {<br>
> >> -        const MatchableInfo::AsmOperand &Op = MI->AsmOperands[i];<br>
> >> +      for (unsigned i = 0, e = MI.AsmOperands.size(); i != e; ++i) {<br>
> >> +        const MatchableInfo::AsmOperand &Op = MI.AsmOperands[i];<br>
> >><br>
> >>        if (i) OS << ", ";<br>
> >>        OS << Op.Class->Name;<br>
> >><br>
> >><br>
> >> _______________________________________________<br>
> >> llvm-commits mailing list<br>
> >> <a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
> >> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
> ><br>
<br>
<br>_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
<br></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature">~Craig</div>
</div>