Index: llvm/trunk/include/llvm/CodeGen/MIRParser/MIRParser.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/MIRParser/MIRParser.h +++ llvm/trunk/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 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 Impl; + +public: + MIRParser(std::unique_ptr 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 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 parseMIRFile(StringRef Filename, SMDiagnostic &Error, - LLVMContext &Context); +/// \param Context - Context which will be used for the parsed LLVM IR module. +std::unique_ptr 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 parseMIR(std::unique_ptr Contents, - SMDiagnostic &Error, LLVMContext &Context); +/// \param Context - Context which will be used for the parsed LLVM IR module. +std::unique_ptr +createMIRParser(std::unique_ptr Contents, LLVMContext &Context); } // end namespace llvm Index: llvm/trunk/include/llvm/CodeGen/MachineFunctionAnalysis.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineFunctionAnalysis.h +++ llvm/trunk/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: llvm/trunk/include/llvm/CodeGen/MachineFunctionInitializer.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineFunctionInitializer.h +++ llvm/trunk/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: llvm/trunk/include/llvm/IR/DiagnosticInfo.h =================================================================== --- llvm/trunk/include/llvm/IR/DiagnosticInfo.h +++ llvm/trunk/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: llvm/trunk/include/llvm/IR/DiagnosticPrinter.h =================================================================== --- llvm/trunk/include/llvm/IR/DiagnosticPrinter.h +++ llvm/trunk/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: llvm/trunk/include/llvm/Support/SourceMgr.h =================================================================== --- llvm/trunk/include/llvm/Support/SourceMgr.h +++ llvm/trunk/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: llvm/trunk/include/llvm/Target/TargetMachine.h =================================================================== --- llvm/trunk/include/llvm/Target/TargetMachine.h +++ llvm/trunk/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: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp =================================================================== --- llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp +++ llvm/trunk/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: llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp =================================================================== --- llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp +++ llvm/trunk/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,7 +31,7 @@ using namespace llvm; -namespace { +namespace llvm { /// This class implements the parsing of LLVM IR that's embedded inside a MIR /// file. @@ -35,29 +39,43 @@ SourceMgr SM; StringRef Filename; LLVMContext &Context; + StringMap> Functions; public: MIRParserImpl(std::unique_ptr Contents, StringRef Filename, LLVMContext &Context); + void reportDiagnostic(const SMDiagnostic &Diag); + + /// Report an error with the given message at unknown location. + /// + /// 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 parse(SMDiagnostic &Error); + std::unique_ptr 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 Contents, StringRef Filename, LLVMContext &Context) @@ -65,16 +83,38 @@ 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(Context) = Diag; + reinterpret_cast(Context)->reportDiagnostic(Diag); } -std::unique_ptr MIRParserImpl::parse(SMDiagnostic &Error) { +std::unique_ptr 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(Filename, Context); @@ -85,10 +125,11 @@ // without having to go trough YAML traits. if (const auto *BSN = dyn_cast_or_null(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::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 llvm::parseMIRFile(StringRef Filename, - SMDiagnostic &Error, - LLVMContext &Context) { +MIRParser::MIRParser(std::unique_ptr Impl) + : Impl(std::move(Impl)) {} + +MIRParser::~MIRParser() {} + +std::unique_ptr MIRParser::parseLLVMModule() { return Impl->parse(); } + +bool MIRParser::initializeMachineFunction(MachineFunction &MF) { + return Impl->initializeMachineFunction(MF); +} + +std::unique_ptr 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(); + return nullptr; } - return parseMIR(std::move(FileOrErr.get()), Error, Context); + return createMIRParser(std::move(FileOrErr.get()), Context); } -std::unique_ptr llvm::parseMIR(std::unique_ptr Contents, - SMDiagnostic &Error, - LLVMContext &Context) { +std::unique_ptr +llvm::createMIRParser(std::unique_ptr Contents, + LLVMContext &Context) { auto Filename = Contents->getBufferIdentifier(); - MIRParserImpl Parser(std::move(Contents), Filename, Context); - return Parser.parse(Error); + return llvm::make_unique( + llvm::make_unique(std::move(Contents), Filename, Context)); } Index: llvm/trunk/lib/CodeGen/MachineFunction.cpp =================================================================== --- llvm/trunk/lib/CodeGen/MachineFunction.cpp +++ llvm/trunk/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: llvm/trunk/lib/CodeGen/MachineFunctionAnalysis.cpp =================================================================== --- llvm/trunk/lib/CodeGen/MachineFunctionAnalysis.cpp +++ llvm/trunk/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()); + if (MFInitializer) + MFInitializer->initializeMachineFunction(*MF); return false; } Index: llvm/trunk/lib/IR/DiagnosticInfo.cpp =================================================================== --- llvm/trunk/lib/IR/DiagnosticInfo.cpp +++ llvm/trunk/lib/IR/DiagnosticInfo.cpp @@ -170,6 +170,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: llvm/trunk/lib/IR/DiagnosticPrinter.cpp =================================================================== --- llvm/trunk/lib/IR/DiagnosticPrinter.cpp +++ llvm/trunk/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: llvm/trunk/lib/IR/LLVMContext.cpp =================================================================== --- llvm/trunk/lib/IR/LLVMContext.cpp +++ llvm/trunk/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) { @@ -211,25 +224,12 @@ return; // Otherwise, print the message with a prefix based on the severity. - std::string MsgStorage; - raw_string_ostream Stream(MsgStorage); - DiagnosticPrinterRawOStream DP(Stream); + 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: llvm/trunk/lib/Support/SourceMgr.cpp =================================================================== --- llvm/trunk/lib/Support/SourceMgr.cpp +++ llvm/trunk/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: llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp =================================================================== --- llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp +++ llvm/trunk/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(o); Index: llvm/trunk/lib/Target/CppBackend/CPPTargetMachine.h =================================================================== --- llvm/trunk/lib/Target/CppBackend/CPPTargetMachine.h +++ llvm/trunk/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: llvm/trunk/test/CodeGen/MIR/function-missing-machine-function.mir =================================================================== --- llvm/trunk/test/CodeGen/MIR/function-missing-machine-function.mir +++ llvm/trunk/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: llvm/trunk/test/CodeGen/MIR/llvm-ir-error-reported.mir =================================================================== --- llvm/trunk/test/CodeGen/MIR/llvm-ir-error-reported.mir +++ llvm/trunk/test/CodeGen/MIR/llvm-ir-error-reported.mir @@ -4,7 +4,7 @@ --- | - ; CHECK: [[@LINE+3]]:15: error: use of undefined value '%a' + ; CHECK: [[@LINE+3]]:15: use of undefined value '%a' define i32 @foo(i32 %x, i32 %y) { %z = alloca i32, align 4 store i32 %a, i32* %z, align 4 Index: llvm/trunk/test/CodeGen/MIR/llvmIR.mir =================================================================== --- llvm/trunk/test/CodeGen/MIR/llvmIR.mir +++ llvm/trunk/test/CodeGen/MIR/llvmIR.mir @@ -30,3 +30,6 @@ } ... +--- +name: foo +... Index: llvm/trunk/test/CodeGen/MIR/machine-function-missing-name.mir =================================================================== --- llvm/trunk/test/CodeGen/MIR/machine-function-missing-name.mir +++ llvm/trunk/test/CodeGen/MIR/machine-function-missing-name.mir @@ -14,7 +14,7 @@ ... --- -# CHECK: [[@LINE+1]]:1: error: missing required key 'name' +# CHECK: [[@LINE+1]]:1: missing required key 'name' nme: foo ... --- Index: llvm/trunk/tools/llc/llc.cpp =================================================================== --- llvm/trunk/tools/llc/llc.cpp +++ llvm/trunk/tools/llc/llc.cpp @@ -210,6 +210,7 @@ // Load the module to be compiled... SMDiagnostic Err; std::unique_ptr M; + std::unique_ptr MIR; Triple TheTriple; bool SkipModule = MCPU == "help" || @@ -217,9 +218,13 @@ // 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 +355,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;