diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 15 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/MIRParser/MILexer.cpp | 1 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/MIRParser/MILexer.h | 1 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/MIRParser/MIParser.cpp | 64 | ||||
| -rw-r--r-- | llvm/lib/IR/AsmWriter.cpp | 22 |
5 files changed, 93 insertions, 10 deletions
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 828f873d37b..a5f4dd73d30 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -643,11 +643,18 @@ bool LLParser::ParseNamedMetadata() { NamedMDNode *NMD = M->getOrInsertNamedMetadata(Name); if (Lex.getKind() != lltok::rbrace) do { - if (ParseToken(lltok::exclaim, "Expected '!' here")) - return true; - MDNode *N = nullptr; - if (ParseMDNodeID(N)) return true; + // Parse DIExpressions inline as a special case. They are still MDNodes, + // so they can still appear in named metadata. Remove this logic if they + // become plain Metadata. + if (Lex.getKind() == lltok::MetadataVar && + Lex.getStrVal() == "DIExpression") { + if (ParseDIExpression(N, /*IsDistinct=*/false)) + return true; + } else if (ParseToken(lltok::exclaim, "Expected '!' here") || + ParseMDNodeID(N)) { + return true; + } NMD->addOperand(N); } while (EatIfPresent(lltok::comma)); diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.cpp b/llvm/lib/CodeGen/MIRParser/MILexer.cpp index 58a655a4dee..25f48368af5 100644 --- a/llvm/lib/CodeGen/MIRParser/MILexer.cpp +++ b/llvm/lib/CodeGen/MIRParser/MILexer.cpp @@ -490,6 +490,7 @@ static MIToken::TokenKind getMetadataKeywordKind(StringRef Identifier) { .Case("!alias.scope", MIToken::md_alias_scope) .Case("!noalias", MIToken::md_noalias) .Case("!range", MIToken::md_range) + .Case("!DIExpression", MIToken::md_diexpr) .Default(MIToken::Error); } diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.h b/llvm/lib/CodeGen/MIRParser/MILexer.h index 08b82e59c4f..c203d2c4817 100644 --- a/llvm/lib/CodeGen/MIRParser/MILexer.h +++ b/llvm/lib/CodeGen/MIRParser/MILexer.h @@ -100,6 +100,7 @@ struct MIToken { md_alias_scope, md_noalias, md_range, + md_diexpr, // Identifier tokens Identifier, diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp index c68d87b15a3..5d68d4463a6 100644 --- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp +++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp @@ -39,6 +39,7 @@ #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DebugLoc.h" #include "llvm/IR/Function.h" #include "llvm/IR/InstrTypes.h" @@ -209,6 +210,7 @@ public: bool parseJumpTableIndexOperand(MachineOperand &Dest); bool parseExternalSymbolOperand(MachineOperand &Dest); bool parseMDNode(MDNode *&Node); + bool parseDIExpression(MDNode *&Node); bool parseMetadataOperand(MachineOperand &Dest); bool parseCFIOffset(int &Offset); bool parseCFIRegister(unsigned &Reg); @@ -854,10 +856,14 @@ bool MIParser::parseStandaloneStackObject(int &FI) { bool MIParser::parseStandaloneMDNode(MDNode *&Node) { lex(); - if (Token.isNot(MIToken::exclaim)) + if (Token.is(MIToken::exclaim)) { + if (parseMDNode(Node)) + return true; + } else if (Token.is(MIToken::md_diexpr)) { + if (parseDIExpression(Node)) + return true; + } else return error("expected a metadata node"); - if (parseMDNode(Node)) - return true; if (Token.isNot(MIToken::Eof)) return error("expected end of string after the metadata node"); return false; @@ -1492,6 +1498,7 @@ bool MIParser::parseSubRegisterIndexOperand(MachineOperand &Dest) { bool MIParser::parseMDNode(MDNode *&Node) { assert(Token.is(MIToken::exclaim)); + auto Loc = Token.location(); lex(); if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned()) @@ -1507,10 +1514,56 @@ bool MIParser::parseMDNode(MDNode *&Node) { return false; } +bool MIParser::parseDIExpression(MDNode *&Expr) { + assert(Token.is(MIToken::md_diexpr)); + lex(); + + // FIXME: Share this parsing with the IL parser. + SmallVector<uint64_t, 8> Elements; + + if (expectAndConsume(MIToken::lparen)) + return true; + + if (Token.isNot(MIToken::rparen)) { + do { + if (Token.is(MIToken::Identifier)) { + if (unsigned Op = dwarf::getOperationEncoding(Token.stringValue())) { + lex(); + Elements.push_back(Op); + continue; + } + return error(Twine("invalid DWARF op '") + Token.stringValue() + "'"); + } + + if (Token.isNot(MIToken::IntegerLiteral) || + Token.integerValue().isSigned()) + return error("expected unsigned integer"); + + auto &U = Token.integerValue(); + if (U.ugt(UINT64_MAX)) + return error("element too large, limit is " + Twine(UINT64_MAX)); + Elements.push_back(U.getZExtValue()); + lex(); + + } while (consumeIfPresent(MIToken::comma)); + } + + if (expectAndConsume(MIToken::rparen)) + return true; + + Expr = DIExpression::get(MF.getFunction()->getContext(), Elements); + return false; +} + bool MIParser::parseMetadataOperand(MachineOperand &Dest) { MDNode *Node = nullptr; - if (parseMDNode(Node)) - return true; + if (Token.is(MIToken::exclaim)) { + if (parseMDNode(Node)) + return true; + } else if (Token.is(MIToken::md_diexpr)) { + if (parseDIExpression(Node)) + return true; + } Dest = MachineOperand::CreateMetadata(Node); return false; } @@ -1851,6 +1904,7 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest, return parseExternalSymbolOperand(Dest); case MIToken::SubRegisterIndex: return parseSubRegisterIndexOperand(Dest); + case MIToken::md_diexpr: case MIToken::exclaim: return parseMetadataOperand(Dest); case MIToken::kw_cfi_same_value: diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 170bc544d53..1cd6dd0ddff 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -1046,6 +1046,10 @@ void SlotTracker::CreateFunctionSlot(const Value *V) { void SlotTracker::CreateMetadataSlot(const MDNode *N) { assert(N && "Can't insert a null Value into SlotTracker!"); + // Don't make slots for DIExpressions. We just print them inline everywhere. + if (isa<DIExpression>(N)) + return; + unsigned DestSlot = mdnNext; if (!mdnMap.insert(std::make_pair(N, DestSlot)).second) return; @@ -2073,6 +2077,13 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Metadata *MD, TypePrinting *TypePrinter, SlotTracker *Machine, const Module *Context, bool FromValue) { + // Write DIExpressions inline when used as a value. Improves readability of + // debug info intrinsics. + if (const DIExpression *Expr = dyn_cast<DIExpression>(MD)) { + writeDIExpression(Out, Expr, TypePrinter, Machine, Context); + return; + } + if (const MDNode *N = dyn_cast<MDNode>(MD)) { std::unique_ptr<SlotTracker> MachineStorage; if (!Machine) { @@ -2424,7 +2435,16 @@ void AssemblyWriter::printNamedMDNode(const NamedMDNode *NMD) { for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { if (i) Out << ", "; - int Slot = Machine.getMetadataSlot(NMD->getOperand(i)); + + // Write DIExpressions inline. + // FIXME: Ban DIExpressions in NamedMDNodes, they will serve no purpose. + MDNode *Op = NMD->getOperand(i); + if (auto *Expr = dyn_cast<DIExpression>(Op)) { + writeDIExpression(Out, Expr, nullptr, nullptr, nullptr); + continue; + } + + int Slot = Machine.getMetadataSlot(Op); if (Slot == -1) Out << "<badref>"; else |

