Skip to content

Commit e818efa

Browse files
committed
[MIRParser] Add machine metadata.
- Add standalone metadata parsing support so that machine metadata nodes could be populated before and accessed during MIR is parsed. Reviewed By: arsenm Differential Revision: https://reviews.llvm.org/D103282
1 parent 31eb696 commit e818efa

20 files changed

+932
-2
lines changed

llvm/include/llvm/CodeGen/MIRParser/MIParser.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include "llvm/CodeGen/MachineMemOperand.h"
1919
#include "llvm/CodeGen/Register.h"
2020
#include "llvm/Support/Allocator.h"
21+
#include "llvm/Support/SMLoc.h"
22+
#include <utility>
2123

2224
namespace llvm {
2325

@@ -164,6 +166,9 @@ struct PerFunctionMIParsingState {
164166
const SlotMapping &IRSlots;
165167
PerTargetMIParsingState &Target;
166168

169+
std::map<unsigned, TrackingMDNodeRef> MachineMetadataNodes;
170+
std::map<unsigned, std::pair<TempMDTuple, SMLoc>> MachineForwardRefMDNodes;
171+
167172
DenseMap<unsigned, MachineBasicBlock *> MBBSlots;
168173
DenseMap<Register, VRegInfo *> VRegInfos;
169174
StringMap<VRegInfo *> VRegInfosNamed;
@@ -233,6 +238,9 @@ bool parseStackObjectReference(PerFunctionMIParsingState &PFS, int &FI,
233238
bool parseMDNode(PerFunctionMIParsingState &PFS, MDNode *&Node, StringRef Src,
234239
SMDiagnostic &Error);
235240

241+
bool parseMachineMetadata(PerFunctionMIParsingState &PFS, StringRef Src,
242+
SMRange SourceRange, SMDiagnostic &Error);
243+
236244
} // end namespace llvm
237245

238246
#endif // LLVM_CODEGEN_MIRPARSER_MIPARSER_H

llvm/lib/CodeGen/MIRParser/MILexer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,7 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
273273
.Case("bbsections", MIToken::kw_bbsections)
274274
.Case("unknown-size", MIToken::kw_unknown_size)
275275
.Case("unknown-address", MIToken::kw_unknown_address)
276+
.Case("distinct", MIToken::kw_distinct)
276277
.Default(MIToken::Identifier);
277278
}
278279

llvm/lib/CodeGen/MIRParser/MILexer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,9 @@ struct MIToken {
129129
kw_unknown_size,
130130
kw_unknown_address,
131131

132+
// Metadata types.
133+
kw_distinct,
134+
132135
// Named metadata keywords
133136
md_tbaa,
134137
md_alias_scope,

llvm/lib/CodeGen/MIRParser/MIParser.cpp

Lines changed: 157 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ class MIParser {
395395
MachineFunction &MF;
396396
SMDiagnostic &Error;
397397
StringRef Source, CurrentSource;
398+
SMRange SourceRange;
398399
MIToken Token;
399400
PerFunctionMIParsingState &PFS;
400401
/// Maps from slot numbers to function's unnamed basic blocks.
@@ -403,6 +404,8 @@ class MIParser {
403404
public:
404405
MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error,
405406
StringRef Source);
407+
MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error,
408+
StringRef Source, SMRange SourceRange);
406409

407410
/// \p SkipChar gives the number of characters to skip before looking
408411
/// for the next token.
@@ -428,6 +431,10 @@ class MIParser {
428431
bool parseStandaloneRegister(Register &Reg);
429432
bool parseStandaloneStackObject(int &FI);
430433
bool parseStandaloneMDNode(MDNode *&Node);
434+
bool parseMachineMetadata();
435+
bool parseMDTuple(MDNode *&MD, bool IsDistinct);
436+
bool parseMDNodeVector(SmallVectorImpl<Metadata *> &Elts);
437+
bool parseMetadata(Metadata *&MD);
431438

432439
bool
433440
parseBasicBlockDefinition(DenseMap<unsigned, MachineBasicBlock *> &MBBSlots);
@@ -550,6 +557,10 @@ class MIParser {
550557
/// parseStringConstant
551558
/// ::= StringConstant
552559
bool parseStringConstant(std::string &Result);
560+
561+
/// Map the location in the MI string to the corresponding location specified
562+
/// in `SourceRange`.
563+
SMLoc mapSMLoc(StringRef::iterator Loc);
553564
};
554565

555566
} // end anonymous namespace
@@ -559,6 +570,11 @@ MIParser::MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error,
559570
: MF(PFS.MF), Error(Error), Source(Source), CurrentSource(Source), PFS(PFS)
560571
{}
561572

573+
MIParser::MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error,
574+
StringRef Source, SMRange SourceRange)
575+
: MF(PFS.MF), Error(Error), Source(Source), CurrentSource(Source),
576+
SourceRange(SourceRange), PFS(PFS) {}
577+
562578
void MIParser::lex(unsigned SkipChar) {
563579
CurrentSource = lexMIToken(
564580
CurrentSource.slice(SkipChar, StringRef::npos), Token,
@@ -584,6 +600,13 @@ bool MIParser::error(StringRef::iterator Loc, const Twine &Msg) {
584600
return true;
585601
}
586602

603+
SMLoc MIParser::mapSMLoc(StringRef::iterator Loc) {
604+
assert(SourceRange.isValid() && "Invalid source range");
605+
assert(Loc >= Source.data() && Loc <= (Source.data() + Source.size()));
606+
return SMLoc::getFromPointer(SourceRange.Start.getPointer() +
607+
(Loc - Source.data()));
608+
}
609+
587610
typedef function_ref<bool(StringRef::iterator Loc, const Twine &)>
588611
ErrorCallbackType;
589612

@@ -1172,6 +1195,130 @@ bool MIParser::parseStandaloneMDNode(MDNode *&Node) {
11721195
return false;
11731196
}
11741197

1198+
bool MIParser::parseMachineMetadata() {
1199+
lex();
1200+
if (Token.isNot(MIToken::exclaim))
1201+
return error("expected a metadata node");
1202+
1203+
lex();
1204+
if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned())
1205+
return error("expected metadata id after '!'");
1206+
unsigned ID = 0;
1207+
if (getUnsigned(ID))
1208+
return true;
1209+
lex();
1210+
if (expectAndConsume(MIToken::equal))
1211+
return true;
1212+
bool IsDistinct = Token.is(MIToken::kw_distinct);
1213+
if (IsDistinct)
1214+
lex();
1215+
if (Token.isNot(MIToken::exclaim))
1216+
return error("expected a metadata node");
1217+
lex();
1218+
1219+
MDNode *MD;
1220+
if (parseMDTuple(MD, IsDistinct))
1221+
return true;
1222+
1223+
auto FI = PFS.MachineForwardRefMDNodes.find(ID);
1224+
if (FI != PFS.MachineForwardRefMDNodes.end()) {
1225+
FI->second.first->replaceAllUsesWith(MD);
1226+
PFS.MachineForwardRefMDNodes.erase(FI);
1227+
1228+
assert(PFS.MachineMetadataNodes[ID] == MD && "Tracking VH didn't work");
1229+
} else {
1230+
if (PFS.MachineMetadataNodes.count(ID))
1231+
return error("Metadata id is already used");
1232+
PFS.MachineMetadataNodes[ID].reset(MD);
1233+
}
1234+
1235+
return false;
1236+
}
1237+
1238+
bool MIParser::parseMDTuple(MDNode *&MD, bool IsDistinct) {
1239+
SmallVector<Metadata *, 16> Elts;
1240+
if (parseMDNodeVector(Elts))
1241+
return true;
1242+
MD = (IsDistinct ? MDTuple::getDistinct
1243+
: MDTuple::get)(MF.getFunction().getContext(), Elts);
1244+
return false;
1245+
}
1246+
1247+
bool MIParser::parseMDNodeVector(SmallVectorImpl<Metadata *> &Elts) {
1248+
if (Token.isNot(MIToken::lbrace))
1249+
return error("expected '{' here");
1250+
lex();
1251+
1252+
if (Token.is(MIToken::rbrace)) {
1253+
lex();
1254+
return false;
1255+
}
1256+
1257+
do {
1258+
Metadata *MD;
1259+
if (parseMetadata(MD))
1260+
return true;
1261+
1262+
Elts.push_back(MD);
1263+
1264+
if (Token.isNot(MIToken::comma))
1265+
break;
1266+
lex();
1267+
} while (true);
1268+
1269+
if (Token.isNot(MIToken::rbrace))
1270+
return error("expected end of metadata node");
1271+
lex();
1272+
1273+
return false;
1274+
}
1275+
1276+
// ::= !42
1277+
// ::= !"string"
1278+
bool MIParser::parseMetadata(Metadata *&MD) {
1279+
if (Token.isNot(MIToken::exclaim))
1280+
return error("expected '!' here");
1281+
lex();
1282+
1283+
if (Token.is(MIToken::StringConstant)) {
1284+
std::string Str;
1285+
if (parseStringConstant(Str))
1286+
return true;
1287+
MD = MDString::get(MF.getFunction().getContext(), Str);
1288+
return false;
1289+
}
1290+
1291+
if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned())
1292+
return error("expected metadata id after '!'");
1293+
1294+
SMLoc Loc = mapSMLoc(Token.location());
1295+
1296+
unsigned ID = 0;
1297+
if (getUnsigned(ID))
1298+
return true;
1299+
lex();
1300+
1301+
auto NodeInfo = PFS.IRSlots.MetadataNodes.find(ID);
1302+
if (NodeInfo != PFS.IRSlots.MetadataNodes.end()) {
1303+
MD = NodeInfo->second.get();
1304+
return false;
1305+
}
1306+
// Check machine metadata.
1307+
NodeInfo = PFS.MachineMetadataNodes.find(ID);
1308+
if (NodeInfo != PFS.MachineMetadataNodes.end()) {
1309+
MD = NodeInfo->second.get();
1310+
return false;
1311+
}
1312+
// Forward reference.
1313+
auto &FwdRef = PFS.MachineForwardRefMDNodes[ID];
1314+
FwdRef = std::make_pair(
1315+
MDTuple::getTemporary(MF.getFunction().getContext(), None), Loc);
1316+
PFS.MachineMetadataNodes[ID].reset(FwdRef.first.get());
1317+
MD = FwdRef.first.get();
1318+
1319+
return false;
1320+
}
1321+
11751322
static const char *printImplicitRegisterFlag(const MachineOperand &MO) {
11761323
assert(MO.isImplicit());
11771324
return MO.isDef() ? "implicit-def" : "implicit";
@@ -2014,8 +2161,11 @@ bool MIParser::parseMDNode(MDNode *&Node) {
20142161
if (getUnsigned(ID))
20152162
return true;
20162163
auto NodeInfo = PFS.IRSlots.MetadataNodes.find(ID);
2017-
if (NodeInfo == PFS.IRSlots.MetadataNodes.end())
2018-
return error(Loc, "use of undefined metadata '!" + Twine(ID) + "'");
2164+
if (NodeInfo == PFS.IRSlots.MetadataNodes.end()) {
2165+
NodeInfo = PFS.MachineMetadataNodes.find(ID);
2166+
if (NodeInfo == PFS.MachineMetadataNodes.end())
2167+
return error(Loc, "use of undefined metadata '!" + Twine(ID) + "'");
2168+
}
20192169
lex();
20202170
Node = NodeInfo->second.get();
20212171
return false;
@@ -3281,6 +3431,11 @@ bool llvm::parseMDNode(PerFunctionMIParsingState &PFS,
32813431
return MIParser(PFS, Error, Src).parseStandaloneMDNode(Node);
32823432
}
32833433

3434+
bool llvm::parseMachineMetadata(PerFunctionMIParsingState &PFS, StringRef Src,
3435+
SMRange SrcRange, SMDiagnostic &Error) {
3436+
return MIParser(PFS, Error, Src, SrcRange).parseMachineMetadata();
3437+
}
3438+
32843439
bool MIRFormatter::parseIRValue(StringRef Src, MachineFunction &MF,
32853440
PerFunctionMIParsingState &PFS, const Value *&V,
32863441
ErrorCallbackType ErrorCallback) {

llvm/lib/CodeGen/MIRParser/MIRParser.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,10 @@ class MIRParserImpl {
143143
bool initializeJumpTableInfo(PerFunctionMIParsingState &PFS,
144144
const yaml::MachineJumpTable &YamlJTI);
145145

146+
bool parseMachineMetadataNodes(PerFunctionMIParsingState &PFS,
147+
MachineFunction &MF,
148+
const yaml::MachineFunction &YMF);
149+
146150
private:
147151
bool parseMDNode(PerFunctionMIParsingState &PFS, MDNode *&Node,
148152
const yaml::StringValue &Source);
@@ -151,6 +155,9 @@ class MIRParserImpl {
151155
MachineBasicBlock *&MBB,
152156
const yaml::StringValue &Source);
153157

158+
bool parseMachineMetadata(PerFunctionMIParsingState &PFS,
159+
const yaml::StringValue &Source);
160+
154161
/// Return a MIR diagnostic converted from an MI string diagnostic.
155162
SMDiagnostic diagFromMIStringDiag(const SMDiagnostic &Error,
156163
SMRange SourceRange);
@@ -457,6 +464,9 @@ MIRParserImpl::initializeMachineFunction(const yaml::MachineFunction &YamlMF,
457464
if (initializeConstantPool(PFS, *ConstantPool, YamlMF))
458465
return true;
459466
}
467+
if (!YamlMF.MachineMetadataNodes.empty() &&
468+
parseMachineMetadataNodes(PFS, MF, YamlMF))
469+
return true;
460470

461471
StringRef BlockStr = YamlMF.Body.Value.Value;
462472
SMDiagnostic Error;
@@ -920,6 +930,29 @@ bool MIRParserImpl::parseMBBReference(PerFunctionMIParsingState &PFS,
920930
return false;
921931
}
922932

933+
bool MIRParserImpl::parseMachineMetadata(PerFunctionMIParsingState &PFS,
934+
const yaml::StringValue &Source) {
935+
SMDiagnostic Error;
936+
if (llvm::parseMachineMetadata(PFS, Source.Value, Source.SourceRange, Error))
937+
return error(Error, Source.SourceRange);
938+
return false;
939+
}
940+
941+
bool MIRParserImpl::parseMachineMetadataNodes(
942+
PerFunctionMIParsingState &PFS, MachineFunction &MF,
943+
const yaml::MachineFunction &YMF) {
944+
for (auto &MDS : YMF.MachineMetadataNodes) {
945+
if (parseMachineMetadata(PFS, MDS))
946+
return true;
947+
}
948+
// Report missing definitions from forward referenced nodes.
949+
if (!PFS.MachineForwardRefMDNodes.empty())
950+
return error(PFS.MachineForwardRefMDNodes.begin()->second.second,
951+
"use of undefined metadata '!" +
952+
Twine(PFS.MachineForwardRefMDNodes.begin()->first) + "'");
953+
return false;
954+
}
955+
923956
SMDiagnostic MIRParserImpl::diagFromMIStringDiag(const SMDiagnostic &Error,
924957
SMRange SourceRange) {
925958
assert(SourceRange.isValid() && "Invalid source range");
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# RUN: not llc -run-pass none -o /dev/null %s 2>&1 | FileCheck %s
2+
# This test ensures that the MIR parser detects errors when parsing machine
3+
# metadata.
4+
--- |
5+
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
6+
target triple = "aarch64-unknown-linux-gnu"
7+
8+
define i32 @test_memcpy(i32* nocapture %p, i32* nocapture readonly %q) {
9+
ret i32 0
10+
}
11+
...
12+
---
13+
name: test_memcpy
14+
machineMetadataNodes:
15+
- '!9 = distinct !{!9, !7, !"Dst"}'
16+
- '!10 = !{!9}'
17+
- '!6 = distinct !{!6, !7, !"Src"}'
18+
- '!5 = !{!6}'
19+
- '!7 = distinct !{!7, !"MemcpyLoweringDomain"}'
20+
body: |
21+
bb.0 (%ir-block.0):
22+
; CHECK: [[@LINE+1]]:78: use of undefined metadata '!11'
23+
%2:fpr128 = LDRQui %0, 1 :: (load 16, align 4, !alias.scope !5, !noalias !11)
24+
25+
...

0 commit comments

Comments
 (0)