<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">2015-06-09 13:30 GMT-07:00 Justin Bogner <span dir="ltr"><<a href="mailto:mail@justinbogner.com" target="_blank">mail@justinbogner.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">Alex Lorenz <<a href="mailto:arphaman@gmail.com">arphaman@gmail.com</a>> writes:<br>
> Rebase on master.<br>
><br>
> REPOSITORY<br>
>   rL LLVM<br>
><br>
> <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__reviews.llvm.org_D9928&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=qRUxkZZsOp_ChwZtCBW1ilL3WXav_wsF1_8OhUOdQ2c&s=OwxnB5XsPCSBI0l_WJCB8RYHs8gAVmijLQmybZKgKhg&e=" target="_blank">http://reviews.llvm.org/D9928</a><br>
><br>
> Files:<br>
>   include/llvm/CodeGen/MIRMachineFunctionInitializer.h<br>
>   include/llvm/CodeGen/MIRParser/MIRParser.h<br>
>   include/llvm/CodeGen/MachineFunctionAnalysis.h<br>
>   include/llvm/Target/TargetMachine.h<br>
>   lib/CodeGen/LLVMTargetMachine.cpp<br>
>   lib/CodeGen/MIRParser/MIRParser.cpp<br>
>   lib/CodeGen/MachineFunctionAnalysis.cpp<br>
>   lib/Target/CppBackend/CPPBackend.cpp<br>
>   lib/Target/CppBackend/CPPTargetMachine.h<br>
>   test/CodeGen/MIR/function-missing-machine-function.mir<br>
>   test/CodeGen/MIR/llvmIR.mir<br>
>   tools/llc/llc.cpp<br>
><br>
> EMAIL PREFERENCES<br>
>   <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__reviews.llvm.org_settings_panel_emailpreferences_&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=qRUxkZZsOp_ChwZtCBW1ilL3WXav_wsF1_8OhUOdQ2c&s=RkAw6PKA4mIuWSBmFycRgxOzWn82ywhDAKO6U1BaANg&e=" target="_blank">http://reviews.llvm.org/settings/panel/emailpreferences/</a><br>
><br>
</div></div>> Index: include/llvm/CodeGen/MIRMachineFunctionInitializer.h<br>
> ===================================================================<br>
> --- /dev/null<br>
> +++ include/llvm/CodeGen/MIRMachineFunctionInitializer.h<br>
> @@ -0,0 +1,40 @@<br>
> +//===- MIRMachineFunctionInitalizer.h - MIR machine function initializer  -===//<br>
> +//<br>
> +//                     The LLVM Compiler Infrastructure<br>
> +//<br>
> +// This file is distributed under the University of Illinois Open Source<br>
> +// License. See LICENSE.TXT for details.<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +//<br>
> +// This MIR serialization library is currently a work in progress. It can't<br>
> +// serialize machine functions at this time.<br>
> +//<br>
> +// This file declares an interface that initializes the machine functions by<br>
> +// applying the state loaded from a MIR file.<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +<br>
> +#ifndef LLVM_CODEGEN_MIRMACHINEFUNCTIONINITIALIZER_H<br>
> +#define LLVM_CODEGEN_MIRMACHINEFUNCTIONINITIALIZER_H<br>
><br>
> +<br>
> +namespace llvm {<br>
> +<br>
> +class MachineFunction;<br>
> +<br>
> +/// This interface initializes machine functions by applying the state loaded<br>
> +/// from a MIR file.<br>
> +class MIRMachineFunctionInitializer {<br>
><br>
> +public:<br>
> +  virtual ~MIRMachineFunctionInitializer() {}<br>
> +<br>
> +  /// Initialize the machine function to the state that's described in the MIR<br>
> +  /// file.<br>
> +  ///<br>
> +  /// Return true if error occurred.<br>
> +  virtual bool initializeMachineFunction(MachineFunction &MF) = 0;<br>
<br>
If this is all that's going to end up in this interface, it really<br>
doesn't have anything to do with MIR, right? Maybe it should just be<br>
called MachineFunctionInitializer?<br>
<br>
On that note, most of the comments here are written as if they're for<br>
MIRParser - this class really knows nothing about MIR or files or<br>
anything.<br>
<br>
> +};<br>
> +<br>
> +} // end namespace llvm<br>
> +<br>
> +#endif<br>
> Index: include/llvm/CodeGen/MIRParser/MIRParser.h<br>
> ===================================================================<br>
> --- include/llvm/CodeGen/MIRParser/MIRParser.h<br>
> +++ include/llvm/CodeGen/MIRParser/MIRParser.h<br>
> @@ -19,33 +19,63 @@<br>
>  #define LLVM_CODEGEN_MIRPARSER_MIRPARSER_H<br>
><br>
>  #include "llvm/ADT/StringRef.h"<br>
> +#include "llvm/CodeGen/MIRMachineFunctionInitializer.h"<br>
>  #include "llvm/IR/Module.h"<br>
>  #include "llvm/Support/MemoryBuffer.h"<br>
> +#include "llvm/Support/SourceMgr.h"<br>
>  #include <memory><br>
><br>
>  namespace llvm {<br>
><br>
> -class SMDiagnostic;<br>
> +class MachineFunction;<br>
> +class MIRParserImpl;<br>
> +<br>
> +/// This class initializes machine functions by applying the state loaded from<br>
> +/// a MIR file.<br>
> +class MIRParser : public MIRMachineFunctionInitializer {<br>
> +  std::unique_ptr<MIRParserImpl> Impl;<br>
> +  SMDiagnostic Error;<br>
> +<br>
> +public:<br>
> +  MIRParser(std::unique_ptr<MIRParserImpl> Impl);<br>
> +  MIRParser(const MIRParser &) = delete;<br>
> +  ~MIRParser();<br>
> +<br>
> +  /// Initialize the machine function to the state that's described in the MIR<br>
> +  /// file.<br>
> +  ///<br>
> +  /// Return true if error occurred.<br>
> +  bool initializeMachineFunction(MachineFunction &MF) override;<br>
> +<br>
> +  /// Return true if the machine function initialization failed during the<br>
> +  /// machine function analysis pass.<br>
> +  bool failed() const { return !Error.getMessage().empty(); }<br>
> +<br>
> +  const SMDiagnostic &error() const { return Error; }<br>
<br>
It depends a bit on exactly what kind of errors we're expecting out of<br>
this, but I suspect this isn't the best model for error handling in this<br>
class. As is, you'll only be able to report exactly one issue, and it<br>
can't be fatal.<br>
<br>
Have you looked at DiagnosticInfo/LLVMContext::diagnose at all?  As long<br>
as your errors are fairly structured it might give you more flexibility.<br></blockquote><div><br></div><div>Thanks, I wasn't aware of DiagnosticInfo. My updated patch now uses it.</div><div><br></div><div>It's not really a perfect fit, as I still use SMDiagnostics with it but it works better</div><div>than the previous system as llc can now exit on the first error, and other users</div><div>of the MIRParser library can get multiple errors if they want.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Otherwise, if you think the single SMDiagnostic model will work well for<br>
you going forward, please call these hasError and getError, for<br>
consistency with other interfaces. </blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
> +};<br>
> +<br>
> +typedef std::pair<std::unique_ptr<Module>, std::unique_ptr<MIRParser>><br>
> +    MIRParseResult;<br>
><br>
>  /// This function is the main interface to the MIR serialization format parser.<br>
>  ///<br>
>  /// It reads a YAML file that has an optional LLVM IR and returns an LLVM<br>
>  /// module.<br>
>  /// \param Filename - The name of the file to parse.<br>
>  /// \param Error - Error result info.<br>
>  /// \param Context - Context in which to allocate globals info.<br>
> -std::unique_ptr<Module> parseMIRFile(StringRef Filename, SMDiagnostic &Error,<br>
> -                                     LLVMContext &Context);<br>
> +MIRParseResult parseMIRFile(StringRef Filename, SMDiagnostic &Error,<br>
> +                            LLVMContext &Context);<br>
><br>
>  /// This function is another interface to the MIR serialization format parser.<br>
>  ///<br>
>  /// It parses the optional LLVM IR in the given buffer, and returns an LLVM<br>
>  /// module.<br>
>  /// \param Contents - The MemoryBuffer containing the machine level IR.<br>
>  /// \param Error - Error result info.<br>
>  /// \param Context - Context in which to allocate globals info.<br>
> -std::unique_ptr<Module> parseMIR(std::unique_ptr<MemoryBuffer> Contents,<br>
> -                                 SMDiagnostic &Error, LLVMContext &Context);<br>
> +MIRParseResult parseMIR(std::unique_ptr<MemoryBuffer> Contents,<br>
> +                        SMDiagnostic &Error, LLVMContext &Context);<br>
><br>
><br>
>  } // end namespace llvm<br>
><br>
> Index: include/llvm/CodeGen/MachineFunctionAnalysis.h<br>
> ===================================================================<br>
> --- include/llvm/CodeGen/MachineFunctionAnalysis.h<br>
> +++ include/llvm/CodeGen/MachineFunctionAnalysis.h<br>
> @@ -19,6 +19,7 @@<br>
>  namespace llvm {<br>
><br>
>  class MachineFunction;<br>
> +class MIRMachineFunctionInitializer;<br>
>  class TargetMachine;<br>
><br>
>  /// MachineFunctionAnalysis - This class is a Pass that manages a<br>
> @@ -28,9 +29,12 @@<br>
>    const TargetMachine &TM;<br>
>    MachineFunction *MF;<br>
>    unsigned NextFnNum;<br>
> +  MIRMachineFunctionInitializer *MFInitializer;<br>
> +<br>
>  public:<br>
>    static char ID;<br>
> -  explicit MachineFunctionAnalysis(const TargetMachine &tm);<br>
> +  explicit MachineFunctionAnalysis(<br>
> +      const TargetMachine &tm, MIRMachineFunctionInitializer *MFInitializer);<br>
>    ~MachineFunctionAnalysis() override;<br>
><br>
>    MachineFunction &getMF() const { return *MF; }<br>
> Index: include/llvm/Target/TargetMachine.h<br>
> ===================================================================<br>
> --- include/llvm/Target/TargetMachine.h<br>
> +++ include/llvm/Target/TargetMachine.h<br>
> @@ -27,6 +27,7 @@<br>
>  class InstrItineraryData;<br>
>  class GlobalValue;<br>
>  class Mangler;<br>
> +class MIRMachineFunctionInitializer;<br>
>  class MCAsmInfo;<br>
>  class MCCodeGenInfo;<br>
>  class MCContext;<br>
> @@ -208,11 +209,11 @@<br>
>    /// emitted.  Typically this will involve several steps of code generation.<br>
>    /// This method should return true if emission of this file type is not<br>
>    /// supported, or false on success.<br>
> -  virtual bool addPassesToEmitFile(PassManagerBase &, raw_pwrite_stream &,<br>
> -                                   CodeGenFileType,<br>
> -                                   bool /*DisableVerify*/ = true,<br>
> -                                   AnalysisID /*StartAfter*/ = nullptr,<br>
> -                                   AnalysisID /*StopAfter*/ = nullptr) {<br>
> +  virtual bool addPassesToEmitFile(<br>
> +      PassManagerBase &, raw_pwrite_stream &, CodeGenFileType,<br>
> +      bool /*DisableVerify*/ = true, AnalysisID /*StartAfter*/ = nullptr,<br>
> +      AnalysisID /*StopAfter*/ = nullptr,<br>
> +      MIRMachineFunctionInitializer * /*MFInitializer*/ = nullptr) {<br>
>      return true;<br>
>    }<br>
><br>
> @@ -256,10 +257,11 @@<br>
><br>
>    /// Add passes to the specified pass manager to get the specified file<br>
>    /// emitted.  Typically this will involve several steps of code generation.<br>
> -  bool addPassesToEmitFile(PassManagerBase &PM, raw_pwrite_stream &Out,<br>
> -                           CodeGenFileType FileType, bool DisableVerify = true,<br>
> -                           AnalysisID StartAfter = nullptr,<br>
> -                           AnalysisID StopAfter = nullptr) override;<br>
> +  bool addPassesToEmitFile(<br>
> +      PassManagerBase &PM, raw_pwrite_stream &Out, CodeGenFileType FileType,<br>
> +      bool DisableVerify = true, AnalysisID StartAfter = nullptr,<br>
> +      AnalysisID StopAfter = nullptr,<br>
> +      MIRMachineFunctionInitializer *MFInitializer = nullptr) override;<br>
><br>
>    /// Add passes to the specified pass manager to get machine code emitted with<br>
>    /// the MCJIT. This method returns true if machine code is not supported. It<br>
> Index: lib/CodeGen/LLVMTargetMachine.cpp<br>
> ===================================================================<br>
> --- lib/CodeGen/LLVMTargetMachine.cpp<br>
> +++ lib/CodeGen/LLVMTargetMachine.cpp<br>
> @@ -87,11 +87,10 @@<br>
>  }<br>
><br>
>  /// addPassesToX helper drives creation and initialization of TargetPassConfig.<br>
> -static MCContext *addPassesToGenerateCode(LLVMTargetMachine *TM,<br>
> -                                          PassManagerBase &PM,<br>
> -                                          bool DisableVerify,<br>
> -                                          AnalysisID StartAfter,<br>
> -                                          AnalysisID StopAfter) {<br>
> +static MCContext *addPassesToGenerateCode(<br>
> +    LLVMTargetMachine *TM, PassManagerBase &PM, bool DisableVerify,<br>
> +    AnalysisID StartAfter, AnalysisID StopAfter,<br>
> +    MIRMachineFunctionInitializer *MFInitializer = nullptr) {<br>
><br>
>    // Add internal analysis passes from the target machine.<br>
>    PM.add(createTargetTransformInfoWrapperPass(TM->getTargetIRAnalysis()));<br>
> @@ -121,7 +120,7 @@<br>
>    PM.add(MMI);<br>
><br>
>    // Set up a MachineFunction for the rest of CodeGen to work on.<br>
> -  PM.add(new MachineFunctionAnalysis(*TM));<br>
> +  PM.add(new MachineFunctionAnalysis(*TM, MFInitializer));<br>
><br>
>    // Enable FastISel with -fast, but allow that to be overridden.<br>
>    if (EnableFastISelOption == cl::BOU_TRUE ||<br>
> @@ -142,10 +141,11 @@<br>
><br>
>  bool LLVMTargetMachine::addPassesToEmitFile(<br>
>      PassManagerBase &PM, raw_pwrite_stream &Out, CodeGenFileType FileType,<br>
> -    bool DisableVerify, AnalysisID StartAfter, AnalysisID StopAfter) {<br>
> +    bool DisableVerify, AnalysisID StartAfter, AnalysisID StopAfter,<br>
> +    MIRMachineFunctionInitializer *MFInitializer) {<br>
>    // Add common CodeGen passes.<br>
> -  MCContext *Context = addPassesToGenerateCode(this, PM, DisableVerify,<br>
> -                                               StartAfter, StopAfter);<br>
> +  MCContext *Context = addPassesToGenerateCode(<br>
> +      this, PM, DisableVerify, StartAfter, StopAfter, MFInitializer);<br>
>    if (!Context)<br>
>      return true;<br>
><br>
> Index: lib/CodeGen/MIRParser/MIRParser.cpp<br>
> ===================================================================<br>
> --- lib/CodeGen/MIRParser/MIRParser.cpp<br>
> +++ lib/CodeGen/MIRParser/MIRParser.cpp<br>
> @@ -14,8 +14,10 @@<br>
><br>
>  #include "llvm/CodeGen/MIRParser/MIRParser.h"<br>
>  #include "llvm/ADT/StringRef.h"<br>
> +#include "llvm/ADT/StringMap.h"<br>
>  #include "llvm/ADT/STLExtras.h"<br>
>  #include "llvm/AsmParser/Parser.h"<br>
> +#include "llvm/CodeGen/MachineFunction.h"<br>
>  #include "llvm/CodeGen/MIRYamlMapping.h"<br>
>  #include "llvm/IR/Module.h"<br>
>  #include "llvm/Support/LineIterator.h"<br>
> @@ -27,14 +29,15 @@<br>
><br>
>  using namespace llvm;<br>
><br>
> -namespace {<br>
> +namespace llvm {<br>
><br>
>  /// This class implements the parsing of LLVM IR that's embedded inside a MIR<br>
>  /// file.<br>
>  class MIRParserImpl {<br>
>    SourceMgr SM;<br>
>    StringRef Filename;<br>
>    LLVMContext &Context;<br>
> +  StringMap<std::unique_ptr<yaml::MachineFunction>> Functions;<br>
><br>
>  public:<br>
>    MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents, StringRef Filename,<br>
> @@ -51,13 +54,19 @@<br>
>    /// Return true if an error occurred.<br>
>    bool parseMachineFunction(yaml::Input &In);<br>
><br>
> +  /// Initialize the machine function to the state that's described in the MIR<br>
> +  /// file.<br>
> +  ///<br>
> +  /// Return true if error occurred.<br>
> +  bool initializeMachineFunction(MachineFunction &MF, SMDiagnostic &Error);<br>
> +<br>
>  private:<br>
>    /// Return a MIR diagnostic converted from an LLVM assembly diagnostic.<br>
>    SMDiagnostic diagFromLLVMAssemblyDiag(const SMDiagnostic &Error,<br>
>                                          SMRange SourceRange);<br>
>  };<br>
><br>
> -} // end anonymous namespace<br>
> +} // end namespace llvm<br>
><br>
>  MIRParserImpl::MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents,<br>
>                               StringRef Filename, LLVMContext &Context)<br>
> @@ -110,12 +119,26 @@<br>
>  }<br>
><br>
>  bool MIRParserImpl::parseMachineFunction(yaml::Input &In) {<br>
> -  yaml::MachineFunction MF;<br>
> -  yaml::yamlize(In, MF, false);<br>
> +  auto MF = llvm::make_unique<yaml::MachineFunction>();<br>
> +  yaml::yamlize(In, *MF, false);<br>
>    if (In.error())<br>
>      return true;<br>
> -  // TODO: Initialize the real machine function with the state in the yaml<br>
> -  // machine function later on.<br>
> +  auto FunctionName = MF->Name;<br>
> +  Functions.insert(std::make_pair(FunctionName, std::move(MF)));<br>
> +  return false;<br>
> +}<br>
> +<br>
> +bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF,<br>
> +                                              SMDiagnostic &Error) {<br>
> +  auto It = Functions.find(MF.getName());<br>
> +  if (It == Functions.end()) {<br>
> +    auto Message = (Twine("No machine function information for function '") +<br>
> +                    MF.getName() + "' in the MIR file")<br>
> +                       .str();<br>
> +    Error = SMDiagnostic(Filename, SourceMgr::DK_Error, Message);<br>
> +    return true;<br>
> +  }<br>
> +  // TODO: Recreate the machine function.<br>
>    return false;<br>
>  }<br>
><br>
> @@ -150,22 +173,34 @@<br>
>                        Error.getFixIts());<br>
>  }<br>
><br>
> -std::unique_ptr<Module> llvm::parseMIRFile(StringRef Filename,<br>
> -                                           SMDiagnostic &Error,<br>
> -                                           LLVMContext &Context) {<br>
> +MIRParser::MIRParser(std::unique_ptr<MIRParserImpl> Impl)<br>
> +    : Impl(std::move(Impl)) {}<br>
> +<br>
> +MIRParser::~MIRParser() {}<br>
> +<br>
> +bool MIRParser::initializeMachineFunction(MachineFunction &MF) {<br>
> +  return Impl->initializeMachineFunction(MF, Error);<br>
> +}<br>
> +<br>
> +MIRParseResult llvm::parseMIRFile(StringRef Filename, SMDiagnostic &Error,<br>
> +                                  LLVMContext &Context) {<br>
>    auto FileOrErr = MemoryBuffer::getFile(Filename);<br>
>    if (std::error_code EC = FileOrErr.getError()) {<br>
>      Error = SMDiagnostic(Filename, SourceMgr::DK_Error,<br>
>                           "Could not open input file: " + EC.message());<br>
> -    return std::unique_ptr<Module>();<br>
> +    return MIRParseResult();<br>
>    }<br>
>    return parseMIR(std::move(FileOrErr.get()), Error, Context);<br>
>  }<br>
><br>
> -std::unique_ptr<Module> llvm::parseMIR(std::unique_ptr<MemoryBuffer> Contents,<br>
> -                                       SMDiagnostic &Error,<br>
> -                                       LLVMContext &Context) {<br>
> +MIRParseResult llvm::parseMIR(std::unique_ptr<MemoryBuffer> Contents,<br>
> +                              SMDiagnostic &Error, LLVMContext &Context) {<br>
>    auto Filename = Contents->getBufferIdentifier();<br>
> -  MIRParserImpl Parser(std::move(Contents), Filename, Context);<br>
> -  return Parser.parse(Error);<br>
> +  auto Parser =<br>
> +      llvm::make_unique<MIRParserImpl>(std::move(Contents), Filename, Context);<br>
> +  auto Mod = Parser->parse(Error);<br>
> +  if (!Mod)<br>
> +    return MIRParseResult();<br>
<br>
I find MIRParseResult and how we're returning this pretty awkward. Note<br>
here that both parseMIRFile and parseMIR create the parser first, then<br>
just call parse. More below.<br>
<br>
> +  return std::make_pair(std::move(Mod),<br>
> +                        llvm::make_unique<MIRParser>(std::move(Parser)));<br>
>  }<br>
> Index: lib/CodeGen/MachineFunctionAnalysis.cpp<br>
> ===================================================================<br>
> --- lib/CodeGen/MachineFunctionAnalysis.cpp<br>
> +++ lib/CodeGen/MachineFunctionAnalysis.cpp<br>
> @@ -15,12 +15,14 @@<br>
>  #include "llvm/CodeGen/GCMetadata.h"<br>
>  #include "llvm/CodeGen/MachineFunction.h"<br>
>  #include "llvm/CodeGen/MachineModuleInfo.h"<br>
> +#include "llvm/CodeGen/MIRMachineFunctionInitializer.h"<br>
>  using namespace llvm;<br>
><br>
>  char MachineFunctionAnalysis::ID = 0;<br>
><br>
> -MachineFunctionAnalysis::MachineFunctionAnalysis(const TargetMachine &tm) :<br>
> -  FunctionPass(ID), TM(tm), MF(nullptr) {<br>
> +MachineFunctionAnalysis::MachineFunctionAnalysis(<br>
> +    const TargetMachine &tm, MIRMachineFunctionInitializer *MFInitializer)<br>
> +    : FunctionPass(ID), TM(tm), MF(nullptr), MFInitializer(MFInitializer) {<br>
>    initializeMachineModuleInfoPass(*PassRegistry::getPassRegistry());<br>
>  }<br>
><br>
> @@ -47,6 +49,8 @@<br>
>    assert(!MF && "MachineFunctionAnalysis already initialized!");<br>
>    MF = new MachineFunction(&F, TM, NextFnNum++,<br>
>                             getAnalysis<MachineModuleInfo>());<br>
> +  if (MFInitializer)<br>
> +    MFInitializer->initializeMachineFunction(*MF);<br>
>    return false;<br>
>  }<br>
><br>
> Index: lib/Target/CppBackend/CPPBackend.cpp<br>
> ===================================================================<br>
> --- lib/Target/CppBackend/CPPBackend.cpp<br>
> +++ lib/Target/CppBackend/CPPBackend.cpp<br>
> @@ -2148,7 +2148,8 @@<br>
><br>
>  bool CPPTargetMachine::addPassesToEmitFile(<br>
>      PassManagerBase &PM, raw_pwrite_stream &o, CodeGenFileType FileType,<br>
> -    bool DisableVerify, AnalysisID StartAfter, AnalysisID StopAfter) {<br>
> +    bool DisableVerify, AnalysisID StartAfter, AnalysisID StopAfter,<br>
> +    MIRMachineFunctionInitializer *MFInitializer) {<br>
>    if (FileType != TargetMachine::CGFT_AssemblyFile)<br>
>      return true;<br>
>    auto FOut = llvm::make_unique<formatted_raw_ostream>(o);<br>
> Index: lib/Target/CppBackend/CPPTargetMachine.h<br>
> ===================================================================<br>
> --- lib/Target/CppBackend/CPPTargetMachine.h<br>
> +++ lib/Target/CppBackend/CPPTargetMachine.h<br>
> @@ -29,10 +29,11 @@<br>
>        : TargetMachine(T, "", TT, CPU, FS, Options) {}<br>
><br>
>  public:<br>
> -  bool addPassesToEmitFile(PassManagerBase &PM, raw_pwrite_stream &Out,<br>
> -                           CodeGenFileType FileType, bool DisableVerify,<br>
> -                           AnalysisID StartAfter,<br>
> -                           AnalysisID StopAfter) override;<br>
> +  bool<br>
> +  addPassesToEmitFile(PassManagerBase &PM, raw_pwrite_stream &Out,<br>
> +                      CodeGenFileType FileType, bool DisableVerify,<br>
> +                      AnalysisID StartAfter, AnalysisID StopAfter,<br>
> +                      MIRMachineFunctionInitializer *MFInitializer) override;<br>
>  };<br>
><br>
>  extern Target TheCppBackendTarget;<br>
> Index: test/CodeGen/MIR/function-missing-machine-function.mir<br>
> ===================================================================<br>
> --- /dev/null<br>
> +++ test/CodeGen/MIR/function-missing-machine-function.mir<br>
> @@ -0,0 +1,13 @@<br>
> +# RUN: not llc -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s<br>
> +# This test verifies that an error is reported when a MIR file has some<br>
> +# function but is missing a corresponding machine function.<br>
> +<br>
> +# CHECK: No machine function information for function 'foo' in the MIR file<br>
> +<br>
> +--- |<br>
> +<br>
> +  define i32 @foo() {<br>
> +    ret i32 0<br>
> +  }<br>
> +<br>
> +...<br>
> Index: test/CodeGen/MIR/llvmIR.mir<br>
> ===================================================================<br>
> --- test/CodeGen/MIR/llvmIR.mir<br>
> +++ test/CodeGen/MIR/llvmIR.mir<br>
> @@ -30,3 +30,6 @@<br>
>    }<br>
><br>
>  ...<br>
> +---<br>
> +name: foo<br>
> +...<br>
> Index: tools/llc/llc.cpp<br>
> ===================================================================<br>
> --- tools/llc/llc.cpp<br>
> +++ tools/llc/llc.cpp<br>
> @@ -210,16 +210,19 @@<br>
>    // Load the module to be compiled...<br>
>    SMDiagnostic Err;<br>
>    std::unique_ptr<Module> M;<br>
> +  std::unique_ptr<MIRParser> MIR;<br>
>    Triple TheTriple;<br>
><br>
>    bool SkipModule = MCPU == "help" ||<br>
>                      (!MAttrs.empty() && MAttrs.front() == "help");<br>
><br>
>    // If user just wants to list available options, skip module loading<br>
>    if (!SkipModule) {<br>
> -    if (StringRef(InputFilename).endswith_lower(".mir"))<br>
> -      M = parseMIRFile(InputFilename, Err, Context);<br>
> -    else<br>
> +    if (StringRef(InputFilename).endswith_lower(".mir")) {<br>
> +      auto ParseResult = parseMIRFile(InputFilename, Err, Context);<br>
> +      M = std::move(ParseResult.first);<br>
> +      MIR = std::move(ParseResult.second);<br>
<br>
So it's pretty confusing here as a user of parseMIRFile. It would be<br>
simpler to create the MIRParser and parse the module as separate<br>
steps. Something along the lines of:<br>
<br>
  MIR = createMIRParserFromFile(InputFilename, Err, Context);<br>
  if (MIR)<br>
    M = MIR->parse()<br>
<br>
This avoids having to dig into .first and .second, is pretty much the<br>
same amount of code, and would make it easier if we needed to change<br>
from unique_ptr to ErrorOr or something in the future.<br>
<br>
> +    } else<br>
>        M = parseIRFile(InputFilename, Err, Context);<br>
>      if (!M) {<br>
>        Err.print(argv[0], errs());<br>
> @@ -350,7 +353,7 @@<br>
><br>
>      // Ask the target to add backend passes as necessary.<br>
>      if (Target->addPassesToEmitFile(PM, *OS, FileType, NoVerify, StartAfterID,<br>
> -                                    StopAfterID)) {<br>
> +                                    StopAfterID, MIR.get())) {<br>
>        errs() << argv[0] << ": target does not support generation of this"<br>
>               << " file type!\n";<br>
>        return 1;<br>
> @@ -362,6 +365,13 @@<br>
>      PM.run(*M);<br>
>    }<br>
><br>
> +  // Check if machine function loading failed in the machine function analysis<br>
> +  // pass.<br>
> +  if (MIR && MIR->failed()) {<br>
> +    MIR->error().print(argv[0], errs());<br>
> +    return 1;<br>
> +  }<br>
> +<br>
>    // Declare success.<br>
>    Out->keep();<br>
><br>
</blockquote></div><br></div></div>