<div dir="ltr"><br><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:<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></blockquote><div><br>Any preferences on this approach, versus using std::list (paying an extra pointer per element) and pushing onto the end instead? (hmm, or maybe we can keep an iterator to the tail end of the list and just use that as an insert hint while still using std::forward_list...  - not sure if that's worth it)<br><br>Also - did you happen to verify that your change causes the diffs on the AsmMatcher.inc files you mentioned to go away entirely, or were there other remaining changes I should hunt for/verify?<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
I don't know why this is platform-specific... I can't think of why<br>
that makes sense.<br></blockquote><div><br>Yeah, that's still rather confusing.<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<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></blockquote></div></div></div>