[PATCH] MIR Serialization: Connect the machine function analysis pass to MIR parser.

Justin Bogner mail at justinbogner.com
Mon Jun 15 12:02:57 PDT 2015


Alex Lorenz <arphaman at gmail.com> writes:
> The updated patch removes the special printing behavior for MIR
> diagnostics from the LLVMContext.

LGTM.

> REPOSITORY
>   rL LLVM
>
> http://reviews.llvm.org/D9928
>
> Files:
>   include/llvm/CodeGen/MIRParser/MIRParser.h
>   include/llvm/CodeGen/MachineFunctionAnalysis.h
>   include/llvm/CodeGen/MachineFunctionInitializer.h
>   include/llvm/IR/DiagnosticInfo.h
>   include/llvm/IR/DiagnosticPrinter.h
>   include/llvm/Support/SourceMgr.h
>   include/llvm/Target/TargetMachine.h
>   lib/CodeGen/LLVMTargetMachine.cpp
>   lib/CodeGen/MIRParser/MIRParser.cpp
>   lib/CodeGen/MachineFunction.cpp
>   lib/CodeGen/MachineFunctionAnalysis.cpp
>   lib/IR/DiagnosticInfo.cpp
>   lib/IR/DiagnosticPrinter.cpp
>   lib/IR/LLVMContext.cpp
>   lib/Support/SourceMgr.cpp
>   lib/Target/CppBackend/CPPBackend.cpp
>   lib/Target/CppBackend/CPPTargetMachine.h
>   test/CodeGen/MIR/function-missing-machine-function.mir
>   test/CodeGen/MIR/llvmIR.mir
>   tools/llc/llc.cpp
>
> EMAIL PREFERENCES
>   http://reviews.llvm.org/settings/panel/emailpreferences/
> Index: include/llvm/CodeGen/MIRParser/MIRParser.h
> ===================================================================
> --- include/llvm/CodeGen/MIRParser/MIRParser.h
> +++ include/llvm/CodeGen/MIRParser/MIRParser.h
> @@ -19,33 +19,62 @@
>  #define LLVM_CODEGEN_MIRPARSER_MIRPARSER_H
>  
>  #include "llvm/ADT/StringRef.h"
> +#include "llvm/CodeGen/MachineFunctionInitializer.h"
>  #include "llvm/IR/Module.h"
>  #include "llvm/Support/MemoryBuffer.h"
>  #include <memory>
>  
>  namespace llvm {
>  
> +class MIRParserImpl;
>  class SMDiagnostic;
>  
> +/// This class initializes machine functions by applying the state loaded from
> +/// a MIR file.
> +class MIRParser : public MachineFunctionInitializer {
> +  std::unique_ptr<MIRParserImpl> Impl;
> +
> +public:
> +  MIRParser(std::unique_ptr<MIRParserImpl> Impl);
> +  MIRParser(const MIRParser &) = delete;
> +  ~MIRParser();
> +
> +  /// Parse the optional LLVM IR module that's embedded in the MIR file.
> +  ///
> +  /// A new, empty module is created if the LLVM IR isn't present.
> +  /// Returns null if a parsing error occurred.
> +  std::unique_ptr<Module> parseLLVMModule();
> +
> +  /// Initialize the machine function to the state that's described in the MIR
> +  /// file.
> +  ///
> +  /// Return true if error occurred.
> +  bool initializeMachineFunction(MachineFunction &MF) override;
> +};
> +
>  /// This function is the main interface to the MIR serialization format parser.
>  ///
> -/// It reads a YAML file that has an optional LLVM IR and returns an LLVM
> -/// module.
> +/// It reads in a MIR file and returns a MIR parser that can parse the embedded
> +/// LLVM IR module and initialize the machine functions by parsing the machine
> +/// function's state.
> +///
>  /// \param Filename - The name of the file to parse.
>  /// \param Error - Error result info.
> -/// \param Context - Context in which to allocate globals info.
> -std::unique_ptr<Module> parseMIRFile(StringRef Filename, SMDiagnostic &Error,
> -                                     LLVMContext &Context);
> +/// \param Context - Context which will be used for the parsed LLVM IR module.
> +std::unique_ptr<MIRParser> createMIRParserFromFile(StringRef Filename,
> +                                                   SMDiagnostic &Error,
> +                                                   LLVMContext &Context);
>  
>  /// This function is another interface to the MIR serialization format parser.
>  ///
> -/// It parses the optional LLVM IR in the given buffer, and returns an LLVM
> -/// module.
> +/// It returns a MIR parser that works with the given memory buffer and that can
> +/// parse the embedded LLVM IR module and initialize the machine functions by
> +/// parsing the machine function's state.
> +///
>  /// \param Contents - The MemoryBuffer containing the machine level IR.
> -/// \param Error - Error result info.
> -/// \param Context - Context in which to allocate globals info.
> -std::unique_ptr<Module> parseMIR(std::unique_ptr<MemoryBuffer> Contents,
> -                                 SMDiagnostic &Error, LLVMContext &Context);
> +/// \param Context - Context which will be used for the parsed LLVM IR module.
> +std::unique_ptr<MIRParser>
> +createMIRParser(std::unique_ptr<MemoryBuffer> Contents, LLVMContext &Context);
>  
>  } // end namespace llvm
>  
> Index: include/llvm/CodeGen/MachineFunctionAnalysis.h
> ===================================================================
> --- include/llvm/CodeGen/MachineFunctionAnalysis.h
> +++ include/llvm/CodeGen/MachineFunctionAnalysis.h
> @@ -19,6 +19,7 @@
>  namespace llvm {
>  
>  class MachineFunction;
> +class MachineFunctionInitializer;
>  class TargetMachine;
>  
>  /// MachineFunctionAnalysis - This class is a Pass that manages a
> @@ -28,9 +29,12 @@
>    const TargetMachine &TM;
>    MachineFunction *MF;
>    unsigned NextFnNum;
> +  MachineFunctionInitializer *MFInitializer;
> +
>  public:
>    static char ID;
> -  explicit MachineFunctionAnalysis(const TargetMachine &tm);
> +  explicit MachineFunctionAnalysis(const TargetMachine &tm,
> +                                   MachineFunctionInitializer *MFInitializer);
>    ~MachineFunctionAnalysis() override;
>  
>    MachineFunction &getMF() const { return *MF; }
> Index: include/llvm/CodeGen/MachineFunctionInitializer.h
> ===================================================================
> --- /dev/null
> +++ include/llvm/CodeGen/MachineFunctionInitializer.h
> @@ -0,0 +1,38 @@
> +//===- MachineFunctionInitalizer.h - machine function initializer ---------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +//
> +// This file declares an interface that allows custom machine function
> +// initialization.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef LLVM_CODEGEN_MACHINEFUNCTIONINITIALIZER_H
> +#define LLVM_CODEGEN_MACHINEFUNCTIONINITIALIZER_H
> +
> +namespace llvm {
> +
> +class MachineFunction;
> +
> +/// This interface provides a way to initialize machine functions after they are
> +/// created by the machine function analysis pass.
> +class MachineFunctionInitializer {
> +  virtual void anchor();
> +
> +public:
> +  virtual ~MachineFunctionInitializer() {}
> +
> +  /// Initialize the machine function.
> +  ///
> +  /// Return true if error occurred.
> +  virtual bool initializeMachineFunction(MachineFunction &MF) = 0;
> +};
> +
> +} // end namespace llvm
> +
> +#endif
> Index: include/llvm/IR/DiagnosticInfo.h
> ===================================================================
> --- include/llvm/IR/DiagnosticInfo.h
> +++ include/llvm/IR/DiagnosticInfo.h
> @@ -32,6 +32,7 @@
>  class Twine;
>  class Value;
>  class DebugLoc;
> +class SMDiagnostic;
>  
>  /// \brief Defines the different supported severity of a diagnostic.
>  enum DiagnosticSeverity {
> @@ -56,6 +57,7 @@
>    DK_OptimizationRemarkMissed,
>    DK_OptimizationRemarkAnalysis,
>    DK_OptimizationFailure,
> +  DK_MIRParser,
>    DK_FirstPluginKind
>  };
>  
> @@ -386,6 +388,24 @@
>    bool isEnabled() const override;
>  };
>  
> +/// Diagnostic information for machine IR parser.
> +class DiagnosticInfoMIRParser : public DiagnosticInfo {
> +  const SMDiagnostic &Diagnostic;
> +
> +public:
> +  DiagnosticInfoMIRParser(DiagnosticSeverity Severity,
> +                          const SMDiagnostic &Diagnostic)
> +      : DiagnosticInfo(DK_MIRParser, Severity), Diagnostic(Diagnostic) {}
> +
> +  const SMDiagnostic &getDiagnostic() const { return Diagnostic; }
> +
> +  void print(DiagnosticPrinter &DP) const override;
> +
> +  static bool classof(const DiagnosticInfo *DI) {
> +    return DI->getKind() == DK_MIRParser;
> +  }
> +};
> +
>  // Create wrappers for C Binding types (see CBindingWrapping.h).
>  DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo, LLVMDiagnosticInfoRef)
>  
> Index: include/llvm/IR/DiagnosticPrinter.h
> ===================================================================
> --- include/llvm/IR/DiagnosticPrinter.h
> +++ include/llvm/IR/DiagnosticPrinter.h
> @@ -22,6 +22,7 @@
>  // Forward declarations.
>  class Module;
>  class raw_ostream;
> +class SMDiagnostic;
>  class StringRef;
>  class Twine;
>  class Value;
> @@ -51,6 +52,9 @@
>    // IR related types.
>    virtual DiagnosticPrinter &operator<<(const Value &V) = 0;
>    virtual DiagnosticPrinter &operator<<(const Module &M) = 0;
> +
> +  // Other types.
> +  virtual DiagnosticPrinter &operator<<(const SMDiagnostic &Diag) = 0;
>  };
>  
>  /// \brief Basic diagnostic printer that uses an underlying raw_ostream.
> @@ -81,6 +85,9 @@
>    // IR related types.
>    DiagnosticPrinter &operator<<(const Value &V) override;
>    DiagnosticPrinter &operator<<(const Module &M) override;
> +
> +  // Other types.
> +  DiagnosticPrinter &operator<<(const SMDiagnostic &Diag) override;
>  };
>  } // End namespace llvm
>  
> Index: include/llvm/Support/SourceMgr.h
> ===================================================================
> --- include/llvm/Support/SourceMgr.h
> +++ include/llvm/Support/SourceMgr.h
> @@ -276,8 +276,8 @@
>      return FixIts;
>    }
>  
> -  void print(const char *ProgName, raw_ostream &S,
> -             bool ShowColors = true) const;
> +  void print(const char *ProgName, raw_ostream &S, bool ShowColors = true,
> +             bool ShowKindLabel = true) const;
>  };
>  
>  }  // end llvm namespace
> Index: include/llvm/Target/TargetMachine.h
> ===================================================================
> --- include/llvm/Target/TargetMachine.h
> +++ include/llvm/Target/TargetMachine.h
> @@ -28,6 +28,7 @@
>  class InstrItineraryData;
>  class GlobalValue;
>  class Mangler;
> +class MachineFunctionInitializer;
>  class MCAsmInfo;
>  class MCCodeGenInfo;
>  class MCContext;
> @@ -210,11 +211,11 @@
>    /// emitted.  Typically this will involve several steps of code generation.
>    /// This method should return true if emission of this file type is not
>    /// supported, or false on success.
> -  virtual bool addPassesToEmitFile(PassManagerBase &, raw_pwrite_stream &,
> -                                   CodeGenFileType,
> -                                   bool /*DisableVerify*/ = true,
> -                                   AnalysisID /*StartAfter*/ = nullptr,
> -                                   AnalysisID /*StopAfter*/ = nullptr) {
> +  virtual bool addPassesToEmitFile(
> +      PassManagerBase &, raw_pwrite_stream &, CodeGenFileType,
> +      bool /*DisableVerify*/ = true, AnalysisID /*StartAfter*/ = nullptr,
> +      AnalysisID /*StopAfter*/ = nullptr,
> +      MachineFunctionInitializer * /*MFInitializer*/ = nullptr) {
>      return true;
>    }
>  
> @@ -258,10 +259,11 @@
>  
>    /// Add passes to the specified pass manager to get the specified file
>    /// emitted.  Typically this will involve several steps of code generation.
> -  bool addPassesToEmitFile(PassManagerBase &PM, raw_pwrite_stream &Out,
> -                           CodeGenFileType FileType, bool DisableVerify = true,
> -                           AnalysisID StartAfter = nullptr,
> -                           AnalysisID StopAfter = nullptr) override;
> +  bool addPassesToEmitFile(
> +      PassManagerBase &PM, raw_pwrite_stream &Out, CodeGenFileType FileType,
> +      bool DisableVerify = true, AnalysisID StartAfter = nullptr,
> +      AnalysisID StopAfter = nullptr,
> +      MachineFunctionInitializer *MFInitializer = nullptr) override;
>  
>    /// Add passes to the specified pass manager to get machine code emitted with
>    /// the MCJIT. This method returns true if machine code is not supported. It
> Index: lib/CodeGen/LLVMTargetMachine.cpp
> ===================================================================
> --- lib/CodeGen/LLVMTargetMachine.cpp
> +++ lib/CodeGen/LLVMTargetMachine.cpp
> @@ -87,11 +87,11 @@
>  }
>  
>  /// addPassesToX helper drives creation and initialization of TargetPassConfig.
> -static MCContext *addPassesToGenerateCode(LLVMTargetMachine *TM,
> -                                          PassManagerBase &PM,
> -                                          bool DisableVerify,
> -                                          AnalysisID StartAfter,
> -                                          AnalysisID StopAfter) {
> +static MCContext *
> +addPassesToGenerateCode(LLVMTargetMachine *TM, PassManagerBase &PM,
> +                        bool DisableVerify, AnalysisID StartAfter,
> +                        AnalysisID StopAfter,
> +                        MachineFunctionInitializer *MFInitializer = nullptr) {
>  
>    // Add internal analysis passes from the target machine.
>    PM.add(createTargetTransformInfoWrapperPass(TM->getTargetIRAnalysis()));
> @@ -121,7 +121,7 @@
>    PM.add(MMI);
>  
>    // Set up a MachineFunction for the rest of CodeGen to work on.
> -  PM.add(new MachineFunctionAnalysis(*TM));
> +  PM.add(new MachineFunctionAnalysis(*TM, MFInitializer));
>  
>    // Enable FastISel with -fast, but allow that to be overridden.
>    if (EnableFastISelOption == cl::BOU_TRUE ||
> @@ -142,10 +142,11 @@
>  
>  bool LLVMTargetMachine::addPassesToEmitFile(
>      PassManagerBase &PM, raw_pwrite_stream &Out, CodeGenFileType FileType,
> -    bool DisableVerify, AnalysisID StartAfter, AnalysisID StopAfter) {
> +    bool DisableVerify, AnalysisID StartAfter, AnalysisID StopAfter,
> +    MachineFunctionInitializer *MFInitializer) {
>    // Add common CodeGen passes.
> -  MCContext *Context = addPassesToGenerateCode(this, PM, DisableVerify,
> -                                               StartAfter, StopAfter);
> +  MCContext *Context = addPassesToGenerateCode(
> +      this, PM, DisableVerify, StartAfter, StopAfter, MFInitializer);
>    if (!Context)
>      return true;
>  
> Index: lib/CodeGen/MIRParser/MIRParser.cpp
> ===================================================================
> --- lib/CodeGen/MIRParser/MIRParser.cpp
> +++ lib/CodeGen/MIRParser/MIRParser.cpp
> @@ -14,9 +14,13 @@
>  
>  #include "llvm/CodeGen/MIRParser/MIRParser.h"
>  #include "llvm/ADT/StringRef.h"
> +#include "llvm/ADT/StringMap.h"
>  #include "llvm/ADT/STLExtras.h"
>  #include "llvm/AsmParser/Parser.h"
> +#include "llvm/CodeGen/MachineFunction.h"
>  #include "llvm/CodeGen/MIRYamlMapping.h"
> +#include "llvm/IR/DiagnosticInfo.h"
> +#include "llvm/IR/LLVMContext.h"
>  #include "llvm/IR/Module.h"
>  #include "llvm/Support/LineIterator.h"
>  #include "llvm/Support/SMLoc.h"
> @@ -27,54 +31,90 @@
>  
>  using namespace llvm;
>  
> -namespace {
> +namespace llvm {
>  
>  /// This class implements the parsing of LLVM IR that's embedded inside a MIR
>  /// file.
>  class MIRParserImpl {
>    SourceMgr SM;
>    StringRef Filename;
>    LLVMContext &Context;
> +  StringMap<std::unique_ptr<yaml::MachineFunction>> Functions;
>  
>  public:
>    MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents, StringRef Filename,
>                  LLVMContext &Context);
>  
> +  void reportDiagnostic(const SMDiagnostic &Diag);
> +
> +  /// Report an error at the given message.
> +  ///
> +  /// Always returns true.
> +  bool error(const Twine &Message);
> +
>    /// Try to parse the optional LLVM module and the machine functions in the MIR
>    /// file.
>    ///
>    /// Return null if an error occurred.
> -  std::unique_ptr<Module> parse(SMDiagnostic &Error);
> +  std::unique_ptr<Module> parse();
>  
>    /// Parse the machine function in the current YAML document.
>    ///
>    /// Return true if an error occurred.
>    bool parseMachineFunction(yaml::Input &In);
>  
> +  /// Initialize the machine function to the state that's described in the MIR
> +  /// file.
> +  ///
> +  /// Return true if error occurred.
> +  bool initializeMachineFunction(MachineFunction &MF);
> +
>  private:
>    /// Return a MIR diagnostic converted from an LLVM assembly diagnostic.
>    SMDiagnostic diagFromLLVMAssemblyDiag(const SMDiagnostic &Error,
>                                          SMRange SourceRange);
>  };
>  
> -} // end anonymous namespace
> +} // end namespace llvm
>  
>  MIRParserImpl::MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents,
>                               StringRef Filename, LLVMContext &Context)
>      : SM(), Filename(Filename), Context(Context) {
>    SM.AddNewSourceBuffer(std::move(Contents), SMLoc());
>  }
>  
> +bool MIRParserImpl::error(const Twine &Message) {
> +  Context.diagnose(DiagnosticInfoMIRParser(
> +      DS_Error, SMDiagnostic(Filename, SourceMgr::DK_Error, Message.str())));
> +  return true;
> +}
> +
> +void MIRParserImpl::reportDiagnostic(const SMDiagnostic &Diag) {
> +  DiagnosticSeverity Kind;
> +  switch (Diag.getKind()) {
> +  case SourceMgr::DK_Error:
> +    Kind = DS_Error;
> +    break;
> +  case SourceMgr::DK_Warning:
> +    Kind = DS_Warning;
> +    break;
> +  case SourceMgr::DK_Note:
> +    Kind = DS_Note;
> +    break;
> +  }
> +  Context.diagnose(DiagnosticInfoMIRParser(Kind, Diag));
> +}
> +
>  static void handleYAMLDiag(const SMDiagnostic &Diag, void *Context) {
> -  *reinterpret_cast<SMDiagnostic *>(Context) = Diag;
> +  reinterpret_cast<MIRParserImpl *>(Context)->reportDiagnostic(Diag);
>  }
>  
> -std::unique_ptr<Module> MIRParserImpl::parse(SMDiagnostic &Error) {
> +std::unique_ptr<Module> MIRParserImpl::parse() {
>    yaml::Input In(SM.getMemoryBuffer(SM.getMainFileID())->getBuffer(),
> -                 /*Ctxt=*/nullptr, handleYAMLDiag, &Error);
> +                 /*Ctxt=*/nullptr, handleYAMLDiag, this);
>  
>    if (!In.setCurrentDocument()) {
> -    if (!Error.getMessage().empty())
> +    if (In.error())
>        return nullptr;
>      // Create an empty module when the MIR file is empty.
>      return llvm::make_unique<Module>(Filename, Context);
> @@ -85,10 +125,11 @@
>    // without having to go trough YAML traits.
>    if (const auto *BSN =
>            dyn_cast_or_null<yaml::BlockScalarNode>(In.getCurrentNode())) {
> +    SMDiagnostic Error;
>      M = parseAssembly(MemoryBufferRef(BSN->getValue(), Filename), Error,
>                        Context);
>      if (!M) {
> -      Error = diagFromLLVMAssemblyDiag(Error, BSN->getSourceRange());
> +      reportDiagnostic(diagFromLLVMAssemblyDiag(Error, BSN->getSourceRange()));
>        return M;
>      }
>      In.nextDocument();
> @@ -110,12 +151,21 @@
>  }
>  
>  bool MIRParserImpl::parseMachineFunction(yaml::Input &In) {
> -  yaml::MachineFunction MF;
> -  yaml::yamlize(In, MF, false);
> +  auto MF = llvm::make_unique<yaml::MachineFunction>();
> +  yaml::yamlize(In, *MF, false);
>    if (In.error())
>      return true;
> -  // TODO: Initialize the real machine function with the state in the yaml
> -  // machine function later on.
> +  auto FunctionName = MF->Name;
> +  Functions.insert(std::make_pair(FunctionName, std::move(MF)));
> +  return false;
> +}
> +
> +bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) {
> +  auto It = Functions.find(MF.getName());
> +  if (It == Functions.end())
> +    return error(Twine("no machine function information for function '") +
> +                 MF.getName() + "' in the MIR file");
> +  // TODO: Recreate the machine function.
>    return false;
>  }
>  
> @@ -150,22 +200,33 @@
>                        Error.getFixIts());
>  }
>  
> -std::unique_ptr<Module> llvm::parseMIRFile(StringRef Filename,
> -                                           SMDiagnostic &Error,
> -                                           LLVMContext &Context) {
> +MIRParser::MIRParser(std::unique_ptr<MIRParserImpl> Impl)
> +    : Impl(std::move(Impl)) {}
> +
> +MIRParser::~MIRParser() {}
> +
> +std::unique_ptr<Module> MIRParser::parseLLVMModule() { return Impl->parse(); }
> +
> +bool MIRParser::initializeMachineFunction(MachineFunction &MF) {
> +  return Impl->initializeMachineFunction(MF);
> +}
> +
> +std::unique_ptr<MIRParser> llvm::createMIRParserFromFile(StringRef Filename,
> +                                                         SMDiagnostic &Error,
> +                                                         LLVMContext &Context) {
>    auto FileOrErr = MemoryBuffer::getFile(Filename);
>    if (std::error_code EC = FileOrErr.getError()) {
>      Error = SMDiagnostic(Filename, SourceMgr::DK_Error,
>                           "Could not open input file: " + EC.message());
> -    return std::unique_ptr<Module>();
> +    return nullptr;
>    }
> -  return parseMIR(std::move(FileOrErr.get()), Error, Context);
> +  return createMIRParser(std::move(FileOrErr.get()), Context);
>  }
>  
> -std::unique_ptr<Module> llvm::parseMIR(std::unique_ptr<MemoryBuffer> Contents,
> -                                       SMDiagnostic &Error,
> -                                       LLVMContext &Context) {
> +std::unique_ptr<MIRParser>
> +llvm::createMIRParser(std::unique_ptr<MemoryBuffer> Contents,
> +                      LLVMContext &Context) {
>    auto Filename = Contents->getBufferIdentifier();
> -  MIRParserImpl Parser(std::move(Contents), Filename, Context);
> -  return Parser.parse(Error);
> +  return llvm::make_unique<MIRParser>(
> +      llvm::make_unique<MIRParserImpl>(std::move(Contents), Filename, Context));
>  }
> Index: lib/CodeGen/MachineFunction.cpp
> ===================================================================
> --- lib/CodeGen/MachineFunction.cpp
> +++ lib/CodeGen/MachineFunction.cpp
> @@ -19,6 +19,7 @@
>  #include "llvm/Analysis/ConstantFolding.h"
>  #include "llvm/CodeGen/MachineConstantPool.h"
>  #include "llvm/CodeGen/MachineFrameInfo.h"
> +#include "llvm/CodeGen/MachineFunctionInitializer.h"
>  #include "llvm/CodeGen/MachineFunctionPass.h"
>  #include "llvm/CodeGen/MachineInstr.h"
>  #include "llvm/CodeGen/MachineJumpTableInfo.h"
> @@ -41,6 +42,8 @@
>  
>  #define DEBUG_TYPE "codegen"
>  
> +void MachineFunctionInitializer::anchor() {}
> +
>  //===----------------------------------------------------------------------===//
>  // MachineFunction implementation
>  //===----------------------------------------------------------------------===//
> Index: lib/CodeGen/MachineFunctionAnalysis.cpp
> ===================================================================
> --- lib/CodeGen/MachineFunctionAnalysis.cpp
> +++ lib/CodeGen/MachineFunctionAnalysis.cpp
> @@ -15,12 +15,14 @@
>  #include "llvm/CodeGen/GCMetadata.h"
>  #include "llvm/CodeGen/MachineFunction.h"
>  #include "llvm/CodeGen/MachineModuleInfo.h"
> +#include "llvm/CodeGen/MachineFunctionInitializer.h"
>  using namespace llvm;
>  
>  char MachineFunctionAnalysis::ID = 0;
>  
> -MachineFunctionAnalysis::MachineFunctionAnalysis(const TargetMachine &tm) :
> -  FunctionPass(ID), TM(tm), MF(nullptr) {
> +MachineFunctionAnalysis::MachineFunctionAnalysis(
> +    const TargetMachine &tm, MachineFunctionInitializer *MFInitializer)
> +    : FunctionPass(ID), TM(tm), MF(nullptr), MFInitializer(MFInitializer) {
>    initializeMachineModuleInfoPass(*PassRegistry::getPassRegistry());
>  }
>  
> @@ -47,6 +49,8 @@
>    assert(!MF && "MachineFunctionAnalysis already initialized!");
>    MF = new MachineFunction(&F, TM, NextFnNum++,
>                             getAnalysis<MachineModuleInfo>());
> +  if (MFInitializer)
> +    MFInitializer->initializeMachineFunction(*MF);
>    return false;
>  }
>  
> Index: lib/IR/DiagnosticInfo.cpp
> ===================================================================
> --- lib/IR/DiagnosticInfo.cpp
> +++ lib/IR/DiagnosticInfo.cpp
> @@ -24,6 +24,7 @@
>  #include "llvm/IR/Module.h"
>  #include "llvm/Support/CommandLine.h"
>  #include "llvm/Support/Regex.h"
> +#include "llvm/Support/SourceMgr.h"
>  #include <atomic>
>  #include <string>
>  
> @@ -170,6 +171,10 @@
>           PassRemarksAnalysisOptLoc.Pattern->match(getPassName());
>  }
>  
> +void DiagnosticInfoMIRParser::print(DiagnosticPrinter &DP) const {
> +  DP << Diagnostic;
> +}
> +
>  void llvm::emitOptimizationRemark(LLVMContext &Ctx, const char *PassName,
>                                    const Function &Fn, const DebugLoc &DLoc,
>                                    const Twine &Msg) {
> Index: lib/IR/DiagnosticPrinter.cpp
> ===================================================================
> --- lib/IR/DiagnosticPrinter.cpp
> +++ lib/IR/DiagnosticPrinter.cpp
> @@ -16,6 +16,7 @@
>  #include "llvm/IR/Module.h"
>  #include "llvm/IR/Value.h"
>  #include "llvm/Support/raw_ostream.h"
> +#include "llvm/Support/SourceMgr.h"
>  
>  using namespace llvm;
>  
> @@ -105,3 +106,12 @@
>    Stream << M.getModuleIdentifier();
>    return *this;
>  }
> +
> +// Other types.
> +DiagnosticPrinter &DiagnosticPrinterRawOStream::
> +operator<<(const SMDiagnostic &Diag) {
> +  // We don't have to print the SMDiagnostic kind, as the diagnostic severity
> +  // is printed by the diagnostic handler.
> +  Diag.print("", Stream, /*ShowColors=*/true, /*ShowKindLabel=*/false);
> +  return *this;
> +}
> Index: lib/IR/LLVMContext.cpp
> ===================================================================
> --- lib/IR/LLVMContext.cpp
> +++ lib/IR/LLVMContext.cpp
> @@ -199,6 +199,19 @@
>    return true;
>  }
>  
> +static const char *getDiagnosticMessagePrefix(DiagnosticSeverity Severity) {
> +  switch (Severity) {
> +  case DS_Error:
> +    return "error";
> +  case DS_Warning:
> +    return "warning";
> +  case DS_Remark:
> +    return "remark";
> +  case DS_Note:
> +    return "note";
> +  }
> +}
> +
>  void LLVMContext::diagnose(const DiagnosticInfo &DI) {
>    // If there is a report handler, use it.
>    if (pImpl->DiagnosticHandler) {
> @@ -210,26 +223,13 @@
>    if (!isDiagnosticEnabled(DI))
>      return;
>  
> -  // Otherwise, print the message with a prefix based on the severity.
> -  std::string MsgStorage;
> -  raw_string_ostream Stream(MsgStorage);
> -  DiagnosticPrinterRawOStream DP(Stream);
> +  // Otherwise, print the message with an optional prefix based on the severity.
> +  DiagnosticPrinterRawOStream DP(errs());
> +  errs() << getDiagnosticMessagePrefix(DI.getSeverity()) << ": ";
>    DI.print(DP);
> -  Stream.flush();
> -  switch (DI.getSeverity()) {
> -  case DS_Error:
> -    errs() << "error: " << MsgStorage << "\n";
> +  errs() << "\n";
> +  if (DI.getSeverity() == DS_Error)
>      exit(1);
> -  case DS_Warning:
> -    errs() << "warning: " << MsgStorage << "\n";
> -    break;
> -  case DS_Remark:
> -    errs() << "remark: " << MsgStorage << "\n";
> -    break;
> -  case DS_Note:
> -    errs() << "note: " << MsgStorage << "\n";
> -    break;
> -  }
>  }
>  
>  void LLVMContext::emitError(unsigned LocCookie, const Twine &ErrorStr) {
> Index: lib/Support/SourceMgr.cpp
> ===================================================================
> --- lib/Support/SourceMgr.cpp
> +++ lib/Support/SourceMgr.cpp
> @@ -332,8 +332,8 @@
>    return c & 0x80;
>  }
>  
> -void SMDiagnostic::print(const char *ProgName, raw_ostream &S,
> -                         bool ShowColors) const {
> +void SMDiagnostic::print(const char *ProgName, raw_ostream &S, bool ShowColors,
> +                         bool ShowKindLabel) const {
>    // Display colors only if OS supports colors.
>    ShowColors &= S.has_colors();
>  
> @@ -357,27 +357,29 @@
>      S << ": ";
>    }
>  
> -  switch (Kind) {
> -  case SourceMgr::DK_Error:
> -    if (ShowColors)
> -      S.changeColor(raw_ostream::RED, true);
> -    S << "error: ";
> -    break;
> -  case SourceMgr::DK_Warning:
> -    if (ShowColors)
> -      S.changeColor(raw_ostream::MAGENTA, true);
> -    S << "warning: ";
> -    break;
> -  case SourceMgr::DK_Note:
> -    if (ShowColors)
> -      S.changeColor(raw_ostream::BLACK, true);
> -    S << "note: ";
> -    break;
> -  }
> +  if (ShowKindLabel) {
> +    switch (Kind) {
> +    case SourceMgr::DK_Error:
> +      if (ShowColors)
> +        S.changeColor(raw_ostream::RED, true);
> +      S << "error: ";
> +      break;
> +    case SourceMgr::DK_Warning:
> +      if (ShowColors)
> +        S.changeColor(raw_ostream::MAGENTA, true);
> +      S << "warning: ";
> +      break;
> +    case SourceMgr::DK_Note:
> +      if (ShowColors)
> +        S.changeColor(raw_ostream::BLACK, true);
> +      S << "note: ";
> +      break;
> +    }
>  
> -  if (ShowColors) {
> -    S.resetColor();
> -    S.changeColor(raw_ostream::SAVEDCOLOR, true);
> +    if (ShowColors) {
> +      S.resetColor();
> +      S.changeColor(raw_ostream::SAVEDCOLOR, true);
> +    }
>    }
>  
>    S << Message << '\n';
> Index: lib/Target/CppBackend/CPPBackend.cpp
> ===================================================================
> --- lib/Target/CppBackend/CPPBackend.cpp
> +++ lib/Target/CppBackend/CPPBackend.cpp
> @@ -2148,7 +2148,8 @@
>  
>  bool CPPTargetMachine::addPassesToEmitFile(
>      PassManagerBase &PM, raw_pwrite_stream &o, CodeGenFileType FileType,
> -    bool DisableVerify, AnalysisID StartAfter, AnalysisID StopAfter) {
> +    bool DisableVerify, AnalysisID StartAfter, AnalysisID StopAfter,
> +    MachineFunctionInitializer *MFInitializer) {
>    if (FileType != TargetMachine::CGFT_AssemblyFile)
>      return true;
>    auto FOut = llvm::make_unique<formatted_raw_ostream>(o);
> Index: lib/Target/CppBackend/CPPTargetMachine.h
> ===================================================================
> --- lib/Target/CppBackend/CPPTargetMachine.h
> +++ lib/Target/CppBackend/CPPTargetMachine.h
> @@ -31,8 +31,8 @@
>  public:
>    bool addPassesToEmitFile(PassManagerBase &PM, raw_pwrite_stream &Out,
>                             CodeGenFileType FileType, bool DisableVerify,
> -                           AnalysisID StartAfter,
> -                           AnalysisID StopAfter) override;
> +                           AnalysisID StartAfter, AnalysisID StopAfter,
> +                           MachineFunctionInitializer *MFInitializer) override;
>  };
>  
>  extern Target TheCppBackendTarget;
> Index: test/CodeGen/MIR/function-missing-machine-function.mir
> ===================================================================
> --- /dev/null
> +++ test/CodeGen/MIR/function-missing-machine-function.mir
> @@ -0,0 +1,13 @@
> +# RUN: not llc -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
> +# This test verifies that an error is reported when a MIR file has some
> +# function but is missing a corresponding machine function.
> +
> +# CHECK: no machine function information for function 'foo' in the MIR file
> +
> +--- |
> +
> +  define i32 @foo() {
> +    ret i32 0
> +  }
> +
> +...
> Index: test/CodeGen/MIR/llvmIR.mir
> ===================================================================
> --- test/CodeGen/MIR/llvmIR.mir
> +++ test/CodeGen/MIR/llvmIR.mir
> @@ -30,3 +30,6 @@
>    }
>    
>  ...
> +---
> +name: foo
> +...
> Index: tools/llc/llc.cpp
> ===================================================================
> --- tools/llc/llc.cpp
> +++ tools/llc/llc.cpp
> @@ -22,6 +22,7 @@
>  #include "llvm/CodeGen/LinkAllCodegenComponents.h"
>  #include "llvm/CodeGen/MIRParser/MIRParser.h"
>  #include "llvm/IR/DataLayout.h"
> +#include "llvm/IR/DiagnosticInfo.h"
>  #include "llvm/IR/IRPrintingPasses.h"
>  #include "llvm/IR/LLVMContext.h"
>  #include "llvm/IR/LegacyPassManager.h"
> @@ -210,16 +211,21 @@
>    // Load the module to be compiled...
>    SMDiagnostic Err;
>    std::unique_ptr<Module> M;
> +  std::unique_ptr<MIRParser> MIR;
>    Triple TheTriple;
>  
>    bool SkipModule = MCPU == "help" ||
>                      (!MAttrs.empty() && MAttrs.front() == "help");
>  
>    // If user just wants to list available options, skip module loading
>    if (!SkipModule) {
> -    if (StringRef(InputFilename).endswith_lower(".mir"))
> -      M = parseMIRFile(InputFilename, Err, Context);
> -    else
> +    if (StringRef(InputFilename).endswith_lower(".mir")) {
> +      MIR = createMIRParserFromFile(InputFilename, Err, Context);
> +      if (MIR) {
> +        M = MIR->parseLLVMModule();
> +        assert(M && "parseLLVMModule should exit on failure");
> +      }
> +    } else
>        M = parseIRFile(InputFilename, Err, Context);
>      if (!M) {
>        Err.print(argv[0], errs());
> @@ -350,7 +356,7 @@
>  
>      // Ask the target to add backend passes as necessary.
>      if (Target->addPassesToEmitFile(PM, *OS, FileType, NoVerify, StartAfterID,
> -                                    StopAfterID)) {
> +                                    StopAfterID, MIR.get())) {
>        errs() << argv[0] << ": target does not support generation of this"
>               << " file type!\n";
>        return 1;



More information about the llvm-commits mailing list