summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/CMakeLists.txt2
-rw-r--r--llvm/lib/CodeGen/LLVMBuild.txt2
-rw-r--r--llvm/lib/CodeGen/LLVMTargetMachine.cpp7
-rw-r--r--llvm/lib/CodeGen/MIRParser/CMakeLists.txt5
-rw-r--r--llvm/lib/CodeGen/MIRParser/LLVMBuild.txt22
-rw-r--r--llvm/lib/CodeGen/MIRParser/MIRParser.cpp90
-rw-r--r--llvm/lib/CodeGen/MIRParser/Makefile13
-rw-r--r--llvm/lib/CodeGen/MIRPrintingPass.cpp85
-rw-r--r--llvm/lib/CodeGen/Makefile2
-rw-r--r--llvm/lib/Support/YAMLTraits.cpp4
10 files changed, 224 insertions, 8 deletions
diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt
index 9fc3e0bcec9..6d2af900350 100644
--- a/llvm/lib/CodeGen/CMakeLists.txt
+++ b/llvm/lib/CodeGen/CMakeLists.txt
@@ -71,6 +71,7 @@ add_llvm_library(LLVMCodeGen
MachineSink.cpp
MachineTraceMetrics.cpp
MachineVerifier.cpp
+ MIRPrintingPass.cpp
OcamlGC.cpp
OptimizePHIs.cpp
PHIElimination.cpp
@@ -129,3 +130,4 @@ add_dependencies(LLVMCodeGen intrinsics_gen)
add_subdirectory(SelectionDAG)
add_subdirectory(AsmPrinter)
+add_subdirectory(MIRParser)
diff --git a/llvm/lib/CodeGen/LLVMBuild.txt b/llvm/lib/CodeGen/LLVMBuild.txt
index fee0347ea65..05905d04dab 100644
--- a/llvm/lib/CodeGen/LLVMBuild.txt
+++ b/llvm/lib/CodeGen/LLVMBuild.txt
@@ -16,7 +16,7 @@
;===------------------------------------------------------------------------===;
[common]
-subdirectories = AsmPrinter SelectionDAG
+subdirectories = AsmPrinter SelectionDAG MIRParser
[component_0]
type = Library
diff --git a/llvm/lib/CodeGen/LLVMTargetMachine.cpp b/llvm/lib/CodeGen/LLVMTargetMachine.cpp
index 610c9f47bac..ff5205801bc 100644
--- a/llvm/lib/CodeGen/LLVMTargetMachine.cpp
+++ b/llvm/lib/CodeGen/LLVMTargetMachine.cpp
@@ -150,12 +150,7 @@ bool LLVMTargetMachine::addPassesToEmitFile(
return true;
if (StopAfter) {
- // FIXME: The intent is that this should eventually write out a YAML file,
- // containing the LLVM IR, the machine-level IR (when stopping after a
- // machine-level pass), and whatever other information is needed to
- // deserialize the code and resume compilation. For now, just write the
- // LLVM IR.
- PM.add(createPrintModulePass(Out));
+ PM.add(createPrintMIRPass(outs()));
return false;
}
diff --git a/llvm/lib/CodeGen/MIRParser/CMakeLists.txt b/llvm/lib/CodeGen/MIRParser/CMakeLists.txt
new file mode 100644
index 00000000000..468f072ed7f
--- /dev/null
+++ b/llvm/lib/CodeGen/MIRParser/CMakeLists.txt
@@ -0,0 +1,5 @@
+add_llvm_library(LLVMMIRParser
+ MIRParser.cpp
+ )
+
+add_dependencies(LLVMMIRParser intrinsics_gen)
diff --git a/llvm/lib/CodeGen/MIRParser/LLVMBuild.txt b/llvm/lib/CodeGen/MIRParser/LLVMBuild.txt
new file mode 100644
index 00000000000..04ae72290f9
--- /dev/null
+++ b/llvm/lib/CodeGen/MIRParser/LLVMBuild.txt
@@ -0,0 +1,22 @@
+;===- ./lib/CodeGen/MIRParser/LLVMBuild.txt --------------------*- Conf -*--===;
+;
+; The LLVM Compiler Infrastructure
+;
+; This file is distributed under the University of Illinois Open Source
+; License. See LICENSE.TXT for details.
+;
+;===------------------------------------------------------------------------===;
+;
+; This is an LLVMBuild description file for the components in this subdirectory.
+;
+; For more information on the LLVMBuild system, please see:
+;
+; http://llvm.org/docs/LLVMBuild.html
+;
+;===------------------------------------------------------------------------===;
+
+[component_0]
+type = Library
+name = MIRParser
+parent = CodeGen
+required_libraries = Core Support Target AsmParser CodeGen
diff --git a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
new file mode 100644
index 00000000000..8a048c1dfb8
--- /dev/null
+++ b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
@@ -0,0 +1,90 @@
+//===- MIRParser.cpp - MIR serialization format parser implementation -----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the class that parses the optional LLVM IR and machine
+// functions that are stored in MIR files.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/MIRParser/MIRParser.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/AsmParser/Parser.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/SMLoc.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/YAMLTraits.h"
+#include <memory>
+
+using namespace llvm;
+
+namespace {
+
+/// This class implements the parsing of LLVM IR that's embedded inside a MIR
+/// file.
+class MIRParserImpl {
+ SourceMgr SM;
+ StringRef Filename;
+ LLVMContext &Context;
+
+public:
+ MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents, StringRef Filename,
+ LLVMContext &Context);
+
+ /// Try to parse the optional LLVM module in the MIR file.
+ ///
+ /// Return null if an error occurred while parsing the LLVM module.
+ std::unique_ptr<Module> parseLLVMModule(SMDiagnostic &Error);
+};
+
+} // end anonymous namespace
+
+MIRParserImpl::MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents,
+ StringRef Filename, LLVMContext &Context)
+ : SM(), Filename(Filename), Context(Context) {
+ SM.AddNewSourceBuffer(std::move(Contents), SMLoc());
+}
+
+std::unique_ptr<Module> MIRParserImpl::parseLLVMModule(SMDiagnostic &Error) {
+ yaml::Input In(SM.getMemoryBuffer(SM.getMainFileID())->getBuffer());
+
+ // Parse the block scalar manually so that we can return unique pointer
+ // without having to go trough YAML traits.
+ if (In.setCurrentDocument()) {
+ if (const auto *BSN =
+ dyn_cast_or_null<yaml::BlockScalarNode>(In.getCurrentNode())) {
+ return parseAssembly(MemoryBufferRef(BSN->getValue(), Filename), Error,
+ Context);
+ }
+ }
+
+ // Create an new, empty module.
+ return llvm::make_unique<Module>(Filename, Context);
+}
+
+std::unique_ptr<Module> llvm::parseMIRFile(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 parseMIR(std::move(FileOrErr.get()), Error, Context);
+}
+
+std::unique_ptr<Module> llvm::parseMIR(std::unique_ptr<MemoryBuffer> Contents,
+ SMDiagnostic &Error,
+ LLVMContext &Context) {
+ auto Filename = Contents->getBufferIdentifier();
+ MIRParserImpl Parser(std::move(Contents), Filename, Context);
+ return Parser.parseLLVMModule(Error);
+}
diff --git a/llvm/lib/CodeGen/MIRParser/Makefile b/llvm/lib/CodeGen/MIRParser/Makefile
new file mode 100644
index 00000000000..c02d18806a9
--- /dev/null
+++ b/llvm/lib/CodeGen/MIRParser/Makefile
@@ -0,0 +1,13 @@
+##===- lib/CodeGen/MIRParser/Makefile ----------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../..
+LIBRARYNAME = LLVMMIRParser
+
+include $(LEVEL)/Makefile.common
diff --git a/llvm/lib/CodeGen/MIRPrintingPass.cpp b/llvm/lib/CodeGen/MIRPrintingPass.cpp
new file mode 100644
index 00000000000..c66658cc977
--- /dev/null
+++ b/llvm/lib/CodeGen/MIRPrintingPass.cpp
@@ -0,0 +1,85 @@
+//===- MIRPrintingPass.cpp - Pass that prints out using the MIR format ----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a pass that prints out the LLVM module using the MIR
+// serialization format.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/YAMLTraits.h"
+
+using namespace llvm;
+
+namespace llvm {
+namespace yaml {
+
+/// This struct serializes the LLVM IR module.
+template <> struct BlockScalarTraits<Module> {
+ static void output(const Module &Mod, void *Ctxt, raw_ostream &OS) {
+ Mod.print(OS, nullptr);
+ }
+ static StringRef input(StringRef Str, void *Ctxt, Module &Mod) {
+ llvm_unreachable("LLVM Module is supposed to be parsed separately");
+ return "";
+ }
+};
+
+} // end namespace yaml
+} // end namespace llvm
+
+namespace {
+
+/// This pass prints out the LLVM IR to an output stream using the MIR
+/// serialization format.
+struct MIRPrintingPass : public MachineFunctionPass {
+ static char ID;
+ raw_ostream &OS;
+
+ MIRPrintingPass() : MachineFunctionPass(ID), OS(dbgs()) {}
+ MIRPrintingPass(raw_ostream &OS) : MachineFunctionPass(ID), OS(OS) {}
+
+ const char *getPassName() const override { return "MIR Printing Pass"; }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesAll();
+ MachineFunctionPass::getAnalysisUsage(AU);
+ }
+
+ virtual bool runOnMachineFunction(MachineFunction &MF) override {
+ // TODO: Print out the machine function.
+ return false;
+ }
+
+ virtual bool doFinalization(Module &M) override {
+ yaml::Output Out(OS);
+ Out << M;
+ return false;
+ }
+};
+
+char MIRPrintingPass::ID = 0;
+
+} // end anonymous namespace
+
+char &llvm::MIRPrintingPassID = MIRPrintingPass::ID;
+INITIALIZE_PASS(MIRPrintingPass, "mir-printer", "MIR Printer", false, false)
+
+namespace llvm {
+
+MachineFunctionPass *createPrintMIRPass(raw_ostream &OS) {
+ return new MIRPrintingPass(OS);
+}
+
+} // end namespace llvm
diff --git a/llvm/lib/CodeGen/Makefile b/llvm/lib/CodeGen/Makefile
index 4ab3e3c0013..96f7ca58513 100644
--- a/llvm/lib/CodeGen/Makefile
+++ b/llvm/lib/CodeGen/Makefile
@@ -9,7 +9,7 @@
LEVEL = ../..
LIBRARYNAME = LLVMCodeGen
-PARALLEL_DIRS = SelectionDAG AsmPrinter
+PARALLEL_DIRS = SelectionDAG AsmPrinter MIRParser
BUILD_ARCHIVE = 1
include $(LEVEL)/Makefile.common
diff --git a/llvm/lib/Support/YAMLTraits.cpp b/llvm/lib/Support/YAMLTraits.cpp
index 90f34f6e232..0d47f37edbd 100644
--- a/llvm/lib/Support/YAMLTraits.cpp
+++ b/llvm/lib/Support/YAMLTraits.cpp
@@ -97,6 +97,10 @@ bool Input::nextDocument() {
return ++DocIterator != Strm->end();
}
+const Node *Input::getCurrentNode() const {
+ return CurrentNode ? CurrentNode->_node : nullptr;
+}
+
bool Input::mapTag(StringRef Tag, bool Default) {
std::string foundTag = CurrentNode->_node->getVerbatimTag();
if (foundTag.empty()) {
OpenPOWER on IntegriCloud