[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