diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/CMakeLists.txt | 1 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/MIParser.cpp | 106 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/MIParser.h | 31 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/MIRParser.cpp | 18 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRPrinter.cpp | 32 |
5 files changed, 185 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/MIRParser/CMakeLists.txt b/llvm/lib/CodeGen/MIRParser/CMakeLists.txt index 468f072ed7f..d9cf3d8893e 100644 --- a/llvm/lib/CodeGen/MIRParser/CMakeLists.txt +++ b/llvm/lib/CodeGen/MIRParser/CMakeLists.txt @@ -1,4 +1,5 @@ add_llvm_library(LLVMMIRParser + MIParser.cpp MIRParser.cpp ) diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp new file mode 100644 index 00000000000..9427de4f015 --- /dev/null +++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp @@ -0,0 +1,106 @@ +//===- MIParser.cpp - Machine instructions 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 parsing of machine instructions. +// +//===----------------------------------------------------------------------===// + +#include "MIParser.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/SourceMgr.h" +#include "llvm/Target/TargetSubtargetInfo.h" +#include "llvm/Target/TargetInstrInfo.h" + +using namespace llvm; + +namespace { + +class MIParser { + SourceMgr &SM; + MachineFunction &MF; + SMDiagnostic &Error; + StringRef Source; + /// Maps from instruction names to op codes. + StringMap<unsigned> Names2InstrOpCodes; + +public: + MIParser(SourceMgr &SM, MachineFunction &MF, SMDiagnostic &Error, + StringRef Source); + + /// Report an error at the current location with the given message. + /// + /// This function always return true. + bool error(const Twine &Msg); + + MachineInstr *parse(); + +private: + void initNames2InstrOpCodes(); + + /// Try to convert an instruction name to an opcode. Return true if the + /// instruction name is invalid. + bool parseInstrName(StringRef InstrName, unsigned &OpCode); +}; + +} // end anonymous namespace + +MIParser::MIParser(SourceMgr &SM, MachineFunction &MF, SMDiagnostic &Error, + StringRef Source) + : SM(SM), MF(MF), Error(Error), Source(Source) {} + +bool MIParser::error(const Twine &Msg) { + // TODO: Get the proper location in the MIR file, not just a location inside + // the string. + Error = + SMDiagnostic(SM, SMLoc(), SM.getMemoryBuffer(SM.getMainFileID()) + ->getBufferIdentifier(), + 1, 0, SourceMgr::DK_Error, Msg.str(), Source, None, None); + return true; +} + +MachineInstr *MIParser::parse() { + StringRef InstrName = Source; + unsigned OpCode; + if (parseInstrName(InstrName, OpCode)) { + error(Twine("unknown machine instruction name '") + InstrName + "'"); + return nullptr; + } + + // TODO: Parse the rest of instruction - machine operands, etc. + const auto &MCID = MF.getSubtarget().getInstrInfo()->get(OpCode); + auto *MI = MF.CreateMachineInstr(MCID, DebugLoc()); + return MI; +} + +void MIParser::initNames2InstrOpCodes() { + if (!Names2InstrOpCodes.empty()) + return; + const auto *TII = MF.getSubtarget().getInstrInfo(); + assert(TII && "Expected target instruction info"); + for (unsigned I = 0, E = TII->getNumOpcodes(); I < E; ++I) + Names2InstrOpCodes.insert(std::make_pair(StringRef(TII->getName(I)), I)); +} + +bool MIParser::parseInstrName(StringRef InstrName, unsigned &OpCode) { + initNames2InstrOpCodes(); + auto InstrInfo = Names2InstrOpCodes.find(InstrName); + if (InstrInfo == Names2InstrOpCodes.end()) + return true; + OpCode = InstrInfo->getValue(); + return false; +} + +MachineInstr *llvm::parseMachineInstr(SourceMgr &SM, MachineFunction &MF, + StringRef Src, SMDiagnostic &Error) { + return MIParser(SM, MF, Error, Src).parse(); +} diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.h b/llvm/lib/CodeGen/MIRParser/MIParser.h new file mode 100644 index 00000000000..b55d70a199b --- /dev/null +++ b/llvm/lib/CodeGen/MIRParser/MIParser.h @@ -0,0 +1,31 @@ +//===- MIParser.h - Machine Instructions Parser ---------------------------===// +// +// 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 parses the machine instructions. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_CODEGEN_MIRPARSER_MIPARSER_H +#define LLVM_LIB_CODEGEN_MIRPARSER_MIPARSER_H + +#include "llvm/ADT/StringRef.h" + +namespace llvm { + +class MachineInstr; +class MachineFunction; +class SMDiagnostic; +class SourceMgr; + +MachineInstr *parseMachineInstr(SourceMgr &SM, MachineFunction &MF, + StringRef Src, SMDiagnostic &Error); + +} // end namespace llvm + +#endif diff --git a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp index 1fef3f6dcb3..1ba7f1f1df2 100644 --- a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp +++ b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "llvm/CodeGen/MIRParser/MIRParser.h" +#include "MIParser.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/STLExtras.h" @@ -79,7 +80,7 @@ public: /// Initialize the machine basic block using it's YAML representation. /// /// Return true if an error occurred. - bool initializeMachineBasicBlock(MachineBasicBlock &MBB, + bool initializeMachineBasicBlock(MachineFunction &MF, MachineBasicBlock &MBB, const yaml::MachineBasicBlock &YamlMBB); private: @@ -218,18 +219,29 @@ bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) { } auto *MBB = MF.CreateMachineBasicBlock(BB); MF.insert(MF.end(), MBB); - if (initializeMachineBasicBlock(*MBB, YamlMBB)) + if (initializeMachineBasicBlock(MF, *MBB, YamlMBB)) return true; } return false; } bool MIRParserImpl::initializeMachineBasicBlock( - MachineBasicBlock &MBB, const yaml::MachineBasicBlock &YamlMBB) { + MachineFunction &MF, MachineBasicBlock &MBB, + const yaml::MachineBasicBlock &YamlMBB) { MBB.setAlignment(YamlMBB.Alignment); if (YamlMBB.AddressTaken) MBB.setHasAddressTaken(); MBB.setIsLandingPad(YamlMBB.IsLandingPad); + // Parse the instructions. + for (const auto &MISource : YamlMBB.Instructions) { + SMDiagnostic Error; + if (auto *MI = parseMachineInstr(SM, MF, MISource, Error)) { + MBB.insert(MBB.end(), MI); + continue; + } + reportDiagnostic(Error); + return true; + } return false; } diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp index bbf163a759e..7aa1b69a78b 100644 --- a/llvm/lib/CodeGen/MIRPrinter.cpp +++ b/llvm/lib/CodeGen/MIRPrinter.cpp @@ -21,6 +21,8 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/YAMLTraits.h" +#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetSubtargetInfo.h" using namespace llvm; @@ -39,6 +41,17 @@ public: void convert(yaml::MachineBasicBlock &YamlMBB, const MachineBasicBlock &MBB); }; +/// This class prints out the machine instructions using the MIR serialization +/// format. +class MIPrinter { + raw_ostream &OS; + +public: + MIPrinter(raw_ostream &OS) : OS(OS) {} + + void print(const MachineInstr &MI); +}; + } // end anonymous namespace namespace llvm { @@ -83,6 +96,25 @@ void MIRPrinter::convert(yaml::MachineBasicBlock &YamlMBB, YamlMBB.Alignment = MBB.getAlignment(); YamlMBB.AddressTaken = MBB.hasAddressTaken(); YamlMBB.IsLandingPad = MBB.isLandingPad(); + + // Print the machine instructions. + YamlMBB.Instructions.reserve(MBB.size()); + std::string Str; + for (const auto &MI : MBB) { + raw_string_ostream StrOS(Str); + MIPrinter(StrOS).print(MI); + YamlMBB.Instructions.push_back(StrOS.str()); + Str.clear(); + } +} + +void MIPrinter::print(const MachineInstr &MI) { + const auto &SubTarget = MI.getParent()->getParent()->getSubtarget(); + const auto *TII = SubTarget.getInstrInfo(); + assert(TII && "Expected target instruction info"); + + OS << TII->getName(MI.getOpcode()); + // TODO: Print the instruction flags, machine operands, machine mem operands. } void llvm::printMIR(raw_ostream &OS, const Module &M) { |