#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
namespace llvm {
class MachineFunction;
+class MachineFunctionInitializer;
class TargetMachine;
/// MachineFunctionAnalysis - This class is a Pass that manages a
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; }
--- /dev/null
+//===- 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
class Twine;
class Value;
class DebugLoc;
+class SMDiagnostic;
/// \brief Defines the different supported severity of a diagnostic.
enum DiagnosticSeverity {
DK_OptimizationRemarkMissed,
DK_OptimizationRemarkAnalysis,
DK_OptimizationFailure,
+ DK_MIRParser,
DK_FirstPluginKind
};
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)
// Forward declarations.
class Module;
class raw_ostream;
+class SMDiagnostic;
class StringRef;
class Twine;
class Value;
// 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.
// 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
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
class InstrItineraryData;
class GlobalValue;
class Mangler;
+class MachineFunctionInitializer;
class MCAsmInfo;
class MCCodeGenInfo;
class MCContext;
/// 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;
}
/// 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
}
/// 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()));
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 ||
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;
#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"
using namespace llvm;
-namespace {
+namespace llvm {
/// This class implements the parsing of LLVM IR that's embedded inside a MIR
/// file.
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 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<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.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);
// 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();
}
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;
}
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));
}
#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"
#define DEBUG_TYPE "codegen"
+void MachineFunctionInitializer::anchor() {}
+
//===----------------------------------------------------------------------===//
// MachineFunction implementation
//===----------------------------------------------------------------------===//
#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());
}
assert(!MF && "MachineFunctionAnalysis already initialized!");
MF = new MachineFunction(&F, TM, NextFnNum++,
getAnalysis<MachineModuleInfo>());
+ if (MFInitializer)
+ MFInitializer->initializeMachineFunction(*MF);
return false;
}
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) {
#include "llvm/IR/Module.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/SourceMgr.h"
using namespace llvm;
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;
+}
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) {
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) {
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();
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';
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);
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;
--- /dev/null
+# 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
+ }
+
+...
--- |
- ; 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
}
...
+---
+name: foo
+...
...
---
-# CHECK: [[@LINE+1]]:1: error: missing required key 'name'
+# CHECK: [[@LINE+1]]:1: missing required key 'name'
nme: foo
...
---
// Load the module to be compiled...
SMDiagnostic Err;
std::unique_ptr<Module> M;
+ std::unique_ptr<MIRParser> MIR;
Triple TheTriple;
bool SkipModule = MCPU == "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());
// 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;