summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorDaniel Sanders <daniel_l_sanders@apple.com>2018-12-13 14:25:27 +0000
committerDaniel Sanders <daniel_l_sanders@apple.com>2018-12-13 14:25:27 +0000
commit9f3cf55e63ca48d2ee2c1428674170e5943cd272 (patch)
tree7d87ebda692c9aae73debd14d8da971a088e9993 /llvm/lib/CodeGen
parent320fd7383fee67af4217bf002e983246afc9cd28 (diff)
downloadbcm5719-llvm-9f3cf55e63ca48d2ee2c1428674170e5943cd272.tar.gz
bcm5719-llvm-9f3cf55e63ca48d2ee2c1428674170e5943cd272.zip
[mir] Serialize DILocation inline when not possible to use a metadata reference
Summary: Sometimes MIR-level passes create DILocations that were not present in the LLVM-IR. For example, it may merge two DILocations together to produce a DILocation that points to line 0. Previously, the address of these DILocations were printed which prevented the MIR from being read back into LLVM. With this patch, DILocations will use metadata references where possible and fall back on serializing them inline like so: MOV32mr %stack.0.x.addr, 1, _, 0, _, %0, debug-location !DILocation(line: 1, scope: !15) Reviewers: aprantl, vsk, arphaman Reviewed By: aprantl Subscribers: probinson, llvm-commits Tags: #debug-info Differential Revision: https://reviews.llvm.org/D55243 llvm-svn: 349035
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/MIRParser/MILexer.cpp1
-rw-r--r--llvm/lib/CodeGen/MIRParser/MILexer.h1
-rw-r--r--llvm/lib/CodeGen/MIRParser/MIParser.cpp119
3 files changed, 117 insertions, 4 deletions
diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.cpp b/llvm/lib/CodeGen/MIRParser/MILexer.cpp
index f7cc94e34a5..6d6d5517379 100644
--- a/llvm/lib/CodeGen/MIRParser/MILexer.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MILexer.cpp
@@ -576,6 +576,7 @@ static MIToken::TokenKind getMetadataKeywordKind(StringRef Identifier) {
.Case("!noalias", MIToken::md_noalias)
.Case("!range", MIToken::md_range)
.Case("!DIExpression", MIToken::md_diexpr)
+ .Case("!DILocation", MIToken::md_dilocation)
.Default(MIToken::Error);
}
diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.h b/llvm/lib/CodeGen/MIRParser/MILexer.h
index dffa4f74544..a52f6206fb7 100644
--- a/llvm/lib/CodeGen/MIRParser/MILexer.h
+++ b/llvm/lib/CodeGen/MIRParser/MILexer.h
@@ -126,6 +126,7 @@ struct MIToken {
md_noalias,
md_range,
md_diexpr,
+ md_dilocation,
// Identifier tokens
Identifier,
diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
index 1a6174bf9ee..16cade09f21 100644
--- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
@@ -226,6 +226,7 @@ public:
bool parseMCSymbolOperand(MachineOperand &Dest);
bool parseMDNode(MDNode *&Node);
bool parseDIExpression(MDNode *&Expr);
+ bool parseDILocation(MDNode *&Expr);
bool parseMetadataOperand(MachineOperand &Dest);
bool parseCFIOffset(int &Offset);
bool parseCFIRegister(unsigned &Reg);
@@ -776,11 +777,15 @@ bool MIParser::parse(MachineInstr *&MI) {
DebugLoc DebugLocation;
if (Token.is(MIToken::kw_debug_location)) {
lex();
- if (Token.isNot(MIToken::exclaim))
- return error("expected a metadata node after 'debug-location'");
MDNode *Node = nullptr;
- if (parseMDNode(Node))
- return true;
+ if (Token.is(MIToken::exclaim)) {
+ if (parseMDNode(Node))
+ return true;
+ } else if (Token.is(MIToken::md_dilocation)) {
+ if (parseDILocation(Node))
+ return true;
+ } else
+ return error("expected a metadata node after 'debug-location'");
if (!isa<DILocation>(Node))
return error("referenced metadata is not a DILocation");
DebugLocation = DebugLoc(Node);
@@ -898,6 +903,9 @@ bool MIParser::parseStandaloneMDNode(MDNode *&Node) {
} else if (Token.is(MIToken::md_diexpr)) {
if (parseDIExpression(Node))
return true;
+ } else if (Token.is(MIToken::md_dilocation)) {
+ if (parseDILocation(Node))
+ return true;
} else
return error("expected a metadata node");
if (Token.isNot(MIToken::Eof))
@@ -1684,6 +1692,109 @@ bool MIParser::parseDIExpression(MDNode *&Expr) {
return false;
}
+bool MIParser::parseDILocation(MDNode *&Loc) {
+ assert(Token.is(MIToken::md_dilocation));
+ lex();
+
+ bool HaveLine = false;
+ unsigned Line = 0;
+ unsigned Column = 0;
+ MDNode *Scope = nullptr;
+ MDNode *InlinedAt = nullptr;
+ bool ImplicitCode;
+
+ if (expectAndConsume(MIToken::lparen))
+ return true;
+
+ if (Token.isNot(MIToken::rparen)) {
+ do {
+ if (Token.is(MIToken::Identifier)) {
+ if (Token.stringValue() == "line") {
+ lex();
+ if (expectAndConsume(MIToken::colon))
+ return true;
+ if (Token.isNot(MIToken::IntegerLiteral) ||
+ Token.integerValue().isSigned())
+ return error("expected unsigned integer");
+ Line = Token.integerValue().getZExtValue();
+ HaveLine = true;
+ lex();
+ continue;
+ }
+ if (Token.stringValue() == "column") {
+ lex();
+ if (expectAndConsume(MIToken::colon))
+ return true;
+ if (Token.isNot(MIToken::IntegerLiteral) ||
+ Token.integerValue().isSigned())
+ return error("expected unsigned integer");
+ Column = Token.integerValue().getZExtValue();
+ lex();
+ continue;
+ }
+ if (Token.stringValue() == "scope") {
+ lex();
+ if (expectAndConsume(MIToken::colon))
+ return true;
+ if (parseMDNode(Scope))
+ return error("expected metadata node");
+ if (!isa<DIScope>(Scope))
+ return error("expected DIScope node");
+ continue;
+ }
+ if (Token.stringValue() == "inlinedAt") {
+ lex();
+ if (expectAndConsume(MIToken::colon))
+ return true;
+ if (Token.is(MIToken::exclaim)) {
+ if (parseMDNode(InlinedAt))
+ return true;
+ } else if (Token.is(MIToken::md_dilocation)) {
+ if (parseDILocation(InlinedAt))
+ return true;
+ } else
+ return error("expected metadata node");
+ if (!isa<DILocation>(InlinedAt))
+ return error("expected DILocation node");
+ continue;
+ }
+ if (Token.stringValue() == "isImplicitCode") {
+ lex();
+ if (expectAndConsume(MIToken::colon))
+ return true;
+ if (!Token.is(MIToken::Identifier))
+ return error("expected true/false");
+ // As far as I can see, we don't have any existing need for parsing
+ // true/false in MIR yet. Do it ad-hoc until there's something else
+ // that needs it.
+ if (Token.stringValue() == "true")
+ ImplicitCode = true;
+ else if (Token.stringValue() == "false")
+ ImplicitCode = false;
+ else
+ return error("expected true/false");
+ lex();
+ continue;
+ }
+ }
+ return error(Twine("invalid DILocation argument '") +
+ Token.stringValue() + "'");
+ } while (consumeIfPresent(MIToken::comma));
+ }
+
+ if (expectAndConsume(MIToken::rparen))
+ return true;
+
+ if (!HaveLine)
+ return error("DILocation requires line number");
+ if (!Scope)
+ return error("DILocation requires a scope");
+
+ Loc = DILocation::get(MF.getFunction().getContext(), Line, Column, Scope,
+ InlinedAt, ImplicitCode);
+ return false;
+}
+
bool MIParser::parseMetadataOperand(MachineOperand &Dest) {
MDNode *Node = nullptr;
if (Token.is(MIToken::exclaim)) {
OpenPOWER on IntegriCloud