diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/CMakeLists.txt | 2 | ||||
-rw-r--r-- | llvm/lib/CodeGen/LLVMBuild.txt | 2 | ||||
-rw-r--r-- | llvm/lib/CodeGen/LLVMTargetMachine.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/CMakeLists.txt | 5 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/LLVMBuild.txt | 22 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/MIRParser.cpp | 90 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/Makefile | 13 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRPrintingPass.cpp | 85 | ||||
-rw-r--r-- | llvm/lib/CodeGen/Makefile | 2 | ||||
-rw-r--r-- | llvm/lib/Support/YAMLTraits.cpp | 4 |
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()) { |