<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>