diff options
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/MILexer.cpp | 21 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/MILexer.h | 5 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/MIParser.cpp | 51 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/MIParser.h | 3 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/MIRParser.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRPrinter.cpp | 20 |
6 files changed, 93 insertions, 14 deletions
diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.cpp b/llvm/lib/CodeGen/MIRParser/MILexer.cpp index 57e5ffe4353..d15b6909f1c 100644 --- a/llvm/lib/CodeGen/MIRParser/MILexer.cpp +++ b/llvm/lib/CodeGen/MIRParser/MILexer.cpp @@ -106,6 +106,25 @@ static Cursor lexPercent(Cursor C, MIToken &Token) { return C; } +static Cursor lexGlobalValue(Cursor C, MIToken &Token) { + auto Range = C; + C.advance(); // Skip the '@' + // TODO: add support for quoted names. + if (!isdigit(C.peek())) { + while (isIdentifierChar(C.peek())) + C.advance(); + Token = MIToken(MIToken::NamedGlobalValue, Range.upto(C), + /*StringOffset=*/1); // Drop the '@' + return C; + } + auto NumberRange = C; + while (isdigit(C.peek())) + C.advance(); + Token = + MIToken(MIToken::GlobalValue, Range.upto(C), APSInt(NumberRange.upto(C))); + return C; +} + static Cursor lexIntegerLiteral(Cursor C, MIToken &Token) { auto Range = C; C.advance(); @@ -151,6 +170,8 @@ StringRef llvm::lexMIToken( return lexMachineBasicBlock(C, Token, ErrorCallback).remaining(); return lexPercent(C, Token).remaining(); } + if (Char == '@') + return lexGlobalValue(C, Token).remaining(); if (isdigit(Char) || (Char == '-' && isdigit(C.peek(1)))) return lexIntegerLiteral(C, Token).remaining(); MIToken::TokenKind Kind = symbolToken(Char); diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.h b/llvm/lib/CodeGen/MIRParser/MILexer.h index adfe0e20192..c28935f3890 100644 --- a/llvm/lib/CodeGen/MIRParser/MILexer.h +++ b/llvm/lib/CodeGen/MIRParser/MILexer.h @@ -40,6 +40,8 @@ struct MIToken { Identifier, NamedRegister, MachineBasicBlock, + NamedGlobalValue, + GlobalValue, // Other tokens IntegerLiteral @@ -78,7 +80,8 @@ public: const APSInt &integerValue() const { return IntVal; } bool hasIntegerValue() const { - return Kind == IntegerLiteral || Kind == MachineBasicBlock; + return Kind == IntegerLiteral || Kind == MachineBasicBlock || + Kind == GlobalValue; } }; diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp index 61a7dfc68b5..f30b1143a49 100644 --- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp +++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp @@ -14,9 +14,11 @@ #include "MIParser.h" #include "MILexer.h" #include "llvm/ADT/StringMap.h" +#include "llvm/AsmParser/SlotMapping.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstr.h" +#include "llvm/IR/Module.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Target/TargetSubtargetInfo.h" @@ -34,6 +36,8 @@ class MIParser { MIToken Token; /// Maps from basic block numbers to MBBs. const DenseMap<unsigned, MachineBasicBlock *> &MBBSlots; + /// Maps from indices to unnamed global values and metadata nodes. + const SlotMapping &IRSlots; /// Maps from instruction names to op codes. StringMap<unsigned> Names2InstrOpCodes; /// Maps from register names to registers. @@ -42,7 +46,8 @@ class MIParser { public: MIParser(SourceMgr &SM, MachineFunction &MF, SMDiagnostic &Error, StringRef Source, - const DenseMap<unsigned, MachineBasicBlock *> &MBBSlots); + const DenseMap<unsigned, MachineBasicBlock *> &MBBSlots, + const SlotMapping &IRSlots); void lex(); @@ -62,6 +67,7 @@ public: bool parseRegisterOperand(MachineOperand &Dest, bool IsDef = false); bool parseImmediateOperand(MachineOperand &Dest); bool parseMBBOperand(MachineOperand &Dest); + bool parseGlobalAddressOperand(MachineOperand &Dest); bool parseMachineOperand(MachineOperand &Dest); private: @@ -89,9 +95,11 @@ private: MIParser::MIParser(SourceMgr &SM, MachineFunction &MF, SMDiagnostic &Error, StringRef Source, - const DenseMap<unsigned, MachineBasicBlock *> &MBBSlots) + const DenseMap<unsigned, MachineBasicBlock *> &MBBSlots, + const SlotMapping &IRSlots) : SM(SM), MF(MF), Error(Error), Source(Source), CurrentSource(Source), - Token(MIToken::Error, StringRef()), MBBSlots(MBBSlots) {} + Token(MIToken::Error, StringRef()), MBBSlots(MBBSlots), IRSlots(IRSlots) { +} void MIParser::lex() { CurrentSource = lexMIToken( @@ -250,6 +258,36 @@ bool MIParser::parseMBBOperand(MachineOperand &Dest) { return false; } +bool MIParser::parseGlobalAddressOperand(MachineOperand &Dest) { + switch (Token.kind()) { + case MIToken::NamedGlobalValue: { + auto Name = Token.stringValue(); + const Module *M = MF.getFunction()->getParent(); + if (const auto *GV = M->getNamedValue(Name)) { + Dest = MachineOperand::CreateGA(GV, /*Offset=*/0); + break; + } + return error(Twine("use of undefined global value '@") + Name + "'"); + } + case MIToken::GlobalValue: { + unsigned GVIdx; + if (getUnsigned(GVIdx)) + return true; + if (GVIdx >= IRSlots.GlobalValues.size()) + return error(Twine("use of undefined global value '@") + Twine(GVIdx) + + "'"); + Dest = MachineOperand::CreateGA(IRSlots.GlobalValues[GVIdx], + /*Offset=*/0); + break; + } + default: + llvm_unreachable("The current token should be a global value"); + } + // TODO: Parse offset and target flags. + lex(); + return false; +} + bool MIParser::parseMachineOperand(MachineOperand &Dest) { switch (Token.kind()) { case MIToken::underscore: @@ -259,6 +297,9 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest) { return parseImmediateOperand(Dest); case MIToken::MachineBasicBlock: return parseMBBOperand(Dest); + case MIToken::GlobalValue: + case MIToken::NamedGlobalValue: + return parseGlobalAddressOperand(Dest); case MIToken::Error: return true; default: @@ -314,6 +355,6 @@ bool MIParser::getRegisterByName(StringRef RegName, unsigned &Reg) { MachineInstr * llvm::parseMachineInstr(SourceMgr &SM, MachineFunction &MF, StringRef Src, const DenseMap<unsigned, MachineBasicBlock *> &MBBSlots, - SMDiagnostic &Error) { - return MIParser(SM, MF, Error, Src, MBBSlots).parse(); + const SlotMapping &IRSlots, SMDiagnostic &Error) { + return MIParser(SM, MF, Error, Src, MBBSlots, IRSlots).parse(); } diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.h b/llvm/lib/CodeGen/MIRParser/MIParser.h index 5bb0570856c..8211e28cd4e 100644 --- a/llvm/lib/CodeGen/MIRParser/MIParser.h +++ b/llvm/lib/CodeGen/MIRParser/MIParser.h @@ -22,13 +22,14 @@ namespace llvm { class MachineBasicBlock; class MachineInstr; class MachineFunction; +struct SlotMapping; class SMDiagnostic; class SourceMgr; MachineInstr * parseMachineInstr(SourceMgr &SM, MachineFunction &MF, StringRef Src, const DenseMap<unsigned, MachineBasicBlock *> &MBBSlots, - SMDiagnostic &Error); + const SlotMapping &IRSlots, SMDiagnostic &Error); } // end namespace llvm diff --git a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp index 79b2ee6c948..cb05b1d3069 100644 --- a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp +++ b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp @@ -19,6 +19,7 @@ #include "llvm/ADT/StringMap.h" #include "llvm/ADT/STLExtras.h" #include "llvm/AsmParser/Parser.h" +#include "llvm/AsmParser/SlotMapping.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/MIRYamlMapping.h" @@ -46,6 +47,7 @@ class MIRParserImpl { StringRef Filename; LLVMContext &Context; StringMap<std::unique_ptr<yaml::MachineFunction>> Functions; + SlotMapping IRSlots; public: MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents, StringRef Filename, @@ -157,7 +159,7 @@ std::unique_ptr<Module> MIRParserImpl::parse() { dyn_cast_or_null<yaml::BlockScalarNode>(In.getCurrentNode())) { SMDiagnostic Error; M = parseAssembly(MemoryBufferRef(BSN->getValue(), Filename), Error, - Context); + Context, &IRSlots); if (!M) { reportDiagnostic(diagFromLLVMAssemblyDiag(Error, BSN->getSourceRange())); return M; @@ -263,7 +265,8 @@ bool MIRParserImpl::initializeMachineBasicBlock( // Parse the instructions. for (const auto &MISource : YamlMBB.Instructions) { SMDiagnostic Error; - if (auto *MI = parseMachineInstr(SM, MF, MISource.Value, MBBSlots, Error)) { + if (auto *MI = parseMachineInstr(SM, MF, MISource.Value, MBBSlots, IRSlots, + Error)) { MBB.insert(MBB.end(), MI); continue; } diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp index 9446849ffd2..5e7871e7ee8 100644 --- a/llvm/lib/CodeGen/MIRPrinter.cpp +++ b/llvm/lib/CodeGen/MIRPrinter.cpp @@ -40,16 +40,18 @@ public: void print(const MachineFunction &MF); void convert(yaml::MachineFunction &MF, const MachineRegisterInfo &RegInfo); - void convert(yaml::MachineBasicBlock &YamlMBB, const MachineBasicBlock &MBB); + void convert(const Module &M, yaml::MachineBasicBlock &YamlMBB, + const MachineBasicBlock &MBB); }; /// This class prints out the machine instructions using the MIR serialization /// format. class MIPrinter { + const Module &M; raw_ostream &OS; public: - MIPrinter(raw_ostream &OS) : OS(OS) {} + MIPrinter(const Module &M, raw_ostream &OS) : M(M), OS(OS) {} void print(const MachineInstr &MI); void print(const MachineOperand &Op, const TargetRegisterInfo *TRI); @@ -83,6 +85,7 @@ void MIRPrinter::print(const MachineFunction &MF) { convert(YamlMF, MF.getRegInfo()); int I = 0; + const auto &M = *MF.getFunction()->getParent(); for (const auto &MBB : MF) { // TODO: Allow printing of non sequentially numbered MBBs. // This is currently needed as the basic block references get their index @@ -92,7 +95,7 @@ void MIRPrinter::print(const MachineFunction &MF) { "Can't print MBBs that aren't sequentially numbered"); (void)I; yaml::MachineBasicBlock YamlMBB; - convert(YamlMBB, MBB); + convert(M, YamlMBB, MBB); YamlMF.BasicBlocks.push_back(YamlMBB); } yaml::Output Out(OS); @@ -106,7 +109,7 @@ void MIRPrinter::convert(yaml::MachineFunction &MF, MF.TracksSubRegLiveness = RegInfo.subRegLivenessEnabled(); } -void MIRPrinter::convert(yaml::MachineBasicBlock &YamlMBB, +void MIRPrinter::convert(const Module &M, yaml::MachineBasicBlock &YamlMBB, const MachineBasicBlock &MBB) { assert(MBB.getNumber() >= 0 && "Invalid MBB number"); YamlMBB.ID = (unsigned)MBB.getNumber(); @@ -124,7 +127,7 @@ void MIRPrinter::convert(yaml::MachineBasicBlock &YamlMBB, std::string Str; for (const auto &MI : MBB) { raw_string_ostream StrOS(Str); - MIPrinter(StrOS).print(MI); + MIPrinter(M, StrOS).print(MI); YamlMBB.Instructions.push_back(StrOS.str()); Str.clear(); } @@ -191,6 +194,13 @@ void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) { OS << '.' << BB->getName(); } break; + case MachineOperand::MO_GlobalAddress: + // FIXME: Make this faster - print as operand will create a slot tracker to + // print unnamed values for the whole module every time it's called, which + // is inefficient. + Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, &M); + // TODO: Print offset and target flags. + break; default: // TODO: Print the other machine operands. llvm_unreachable("Can't print this machine operand at the moment"); |