summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorAlex Lorenz <arphaman@gmail.com>2015-05-21 20:54:45 +0000
committerAlex Lorenz <arphaman@gmail.com>2015-05-21 20:54:45 +0000
commitc37baf82a92ab6c1359a137862734c3dfe129472 (patch)
tree3c9897868b3768e241acf84b9887bdff6c1ea830 /llvm/lib
parente034a04e4fbfd9a1919d21600cb61eee0112a511 (diff)
downloadbcm5719-llvm-c37baf82a92ab6c1359a137862734c3dfe129472.tar.gz
bcm5719-llvm-c37baf82a92ab6c1359a137862734c3dfe129472.zip
Resubmit r237708 (MIR Serialization: print and parse LLVM IR using MIR format).
This commit is a 2nd attempt at committing the initial MIR serialization patch. The first commit (r237708) made the incremental buildbots unstable and was reverted in r237730. The original commit didn't add a terminating null character to the LLVM IR source which was passed to LLParser, and this sometimes caused the test 'llvmIR.mir' to fail with a parsing error because the LLVM IR source didn't have a null character immediately after the end and thus LLLexer encountered some garbage characters that ultimately caused the error. This commit also includes the other test fixes I committed in r237712 (llc path fix) and r237723 (remove target triple) which also got reverted in r237730. --Original Commit Message-- MIR Serialization: print and parse LLVM IR using MIR format. This commit is the initial commit for the MIR serialization project. It creates a new library under CodeGen called 'MIR'. This new library adds a new machine function pass that prints out the LLVM IR using the MIR format. This pass is then added as a last pass when a 'stop-after' option is used in llc. The new library adds the initial functionality for parsing of MIR files as well. This commit also extends the llc tool so that it can recognize and parse MIR input files. Reviewers: Duncan P. N. Exon Smith, Matthias Braun, Philip Reames Differential Revision: http://reviews.llvm.org/D9616 llvm-svn: 237954
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/CMakeLists.txt1
-rw-r--r--llvm/lib/CodeGen/LLVMBuild.txt4
-rw-r--r--llvm/lib/CodeGen/LLVMTargetMachine.cpp7
-rw-r--r--llvm/lib/CodeGen/MIR/CMakeLists.txt7
-rw-r--r--llvm/lib/CodeGen/MIR/LLVMBuild.txt22
-rw-r--r--llvm/lib/CodeGen/MIR/MIRParser.cpp90
-rw-r--r--llvm/lib/CodeGen/MIR/MIRPrinter.cpp66
-rw-r--r--llvm/lib/CodeGen/MIR/MIRPrinter.h29
-rw-r--r--llvm/lib/CodeGen/MIR/MIRPrintingPass.cpp66
-rw-r--r--llvm/lib/CodeGen/MIR/Makefile13
-rw-r--r--llvm/lib/CodeGen/Makefile2
-rw-r--r--llvm/lib/Support/YAMLTraits.cpp4
12 files changed, 302 insertions, 9 deletions
diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt
index 9fc3e0bcec9..59ce702995d 100644
--- a/llvm/lib/CodeGen/CMakeLists.txt
+++ b/llvm/lib/CodeGen/CMakeLists.txt
@@ -129,3 +129,4 @@ add_dependencies(LLVMCodeGen intrinsics_gen)
add_subdirectory(SelectionDAG)
add_subdirectory(AsmPrinter)
+add_subdirectory(MIR)
diff --git a/llvm/lib/CodeGen/LLVMBuild.txt b/llvm/lib/CodeGen/LLVMBuild.txt
index fee0347ea65..02be11af05a 100644
--- a/llvm/lib/CodeGen/LLVMBuild.txt
+++ b/llvm/lib/CodeGen/LLVMBuild.txt
@@ -16,10 +16,10 @@
;===------------------------------------------------------------------------===;
[common]
-subdirectories = AsmPrinter SelectionDAG
+subdirectories = AsmPrinter SelectionDAG MIR
[component_0]
type = Library
name = CodeGen
parent = Libraries
-required_libraries = Analysis Core MC Scalar Support Target TransformUtils
+required_libraries = Analysis Core MC Scalar Support Target TransformUtils MIR
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/MIR/CMakeLists.txt b/llvm/lib/CodeGen/MIR/CMakeLists.txt
new file mode 100644
index 00000000000..52b64f3f826
--- /dev/null
+++ b/llvm/lib/CodeGen/MIR/CMakeLists.txt
@@ -0,0 +1,7 @@
+add_llvm_library(LLVMMIR
+ MIRPrinter.cpp
+ MIRPrintingPass.cpp
+ MIRParser.cpp
+ )
+
+add_dependencies(LLVMMIR intrinsics_gen)
diff --git a/llvm/lib/CodeGen/MIR/LLVMBuild.txt b/llvm/lib/CodeGen/MIR/LLVMBuild.txt
new file mode 100644
index 00000000000..71aeaffb9bb
--- /dev/null
+++ b/llvm/lib/CodeGen/MIR/LLVMBuild.txt
@@ -0,0 +1,22 @@
+;===- ./lib/CodeGen/MIR/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 = MIR
+parent = CodeGen
+required_libraries = Core Support Target AsmParser
diff --git a/llvm/lib/CodeGen/MIR/MIRParser.cpp b/llvm/lib/CodeGen/MIR/MIRParser.cpp
new file mode 100644
index 00000000000..e484046b23b
--- /dev/null
+++ b/llvm/lib/CodeGen/MIR/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/MIR/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/MIR/MIRPrinter.cpp b/llvm/lib/CodeGen/MIR/MIRPrinter.cpp
new file mode 100644
index 00000000000..fae22286d61
--- /dev/null
+++ b/llvm/lib/CodeGen/MIR/MIRPrinter.cpp
@@ -0,0 +1,66 @@
+//===- MIRPrinter.cpp - MIR serialization format printer ------------------===//
+//
+// 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 prints out the LLVM IR and machine
+// functions using the MIR serialization format.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MIRPrinter.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/YAMLTraits.h"
+
+using namespace llvm;
+
+namespace {
+
+/// This class prints out the LLVM IR using the MIR serialization format and
+/// YAML I/O.
+class MIRPrinter {
+ raw_ostream &OS;
+
+public:
+ MIRPrinter(raw_ostream &OS);
+
+ void printModule(const Module &Mod);
+};
+
+} // end anonymous namespace
+
+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
+
+MIRPrinter::MIRPrinter(raw_ostream &OS) : OS(OS) {}
+
+void MIRPrinter::printModule(const Module &Mod) {
+ yaml::Output Out(OS);
+ Out << const_cast<Module &>(Mod);
+}
+
+void llvm::printMIR(raw_ostream &OS, const Module &Mod) {
+ MIRPrinter Printer(OS);
+ Printer.printModule(Mod);
+}
diff --git a/llvm/lib/CodeGen/MIR/MIRPrinter.h b/llvm/lib/CodeGen/MIR/MIRPrinter.h
new file mode 100644
index 00000000000..2e6d645af71
--- /dev/null
+++ b/llvm/lib/CodeGen/MIR/MIRPrinter.h
@@ -0,0 +1,29 @@
+//===- MIRPrinter.h - MIR serialization format printer --------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the function that prints out the LLVM IR using the MIR
+// serialization format.
+// TODO: Print out machine functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_CODEGEN_MIR_MIRPRINTER_H
+#define LLVM_LIB_CODEGEN_MIR_MIRPRINTER_H
+
+namespace llvm {
+
+class Module;
+class raw_ostream;
+
+/// Print LLVM IR using the MIR serialization format to the given output stream.
+void printMIR(raw_ostream &OS, const Module &Mod);
+
+} // end namespace llvm
+
+#endif
diff --git a/llvm/lib/CodeGen/MIR/MIRPrintingPass.cpp b/llvm/lib/CodeGen/MIR/MIRPrintingPass.cpp
new file mode 100644
index 00000000000..f5a67d9e315
--- /dev/null
+++ b/llvm/lib/CodeGen/MIR/MIRPrintingPass.cpp
@@ -0,0 +1,66 @@
+//===- 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 "MIRPrinter.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+
+using 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 {
+ printMIR(OS, 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/MIR/Makefile b/llvm/lib/CodeGen/MIR/Makefile
new file mode 100644
index 00000000000..72f581c6cfb
--- /dev/null
+++ b/llvm/lib/CodeGen/MIR/Makefile
@@ -0,0 +1,13 @@
+##===- lib/CodeGen/MIR/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 = LLVMMIR
+
+include $(LEVEL)/Makefile.common
diff --git a/llvm/lib/CodeGen/Makefile b/llvm/lib/CodeGen/Makefile
index 4ab3e3c0013..867a5cf3d0f 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 MIR
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