summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2014-12-15 19:07:53 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2014-12-15 19:07:53 +0000
commitbe7ea19b585dc1b0d4c4358df3ca498ceb65b969 (patch)
tree6cc161b35899bfcc90e83d0f1bf47176fca9fc16 /llvm/lib
parent30e41fb4da688d9c7c4d9bc122d8f1cb9a864f75 (diff)
downloadbcm5719-llvm-be7ea19b585dc1b0d4c4358df3ca498ceb65b969.tar.gz
bcm5719-llvm-be7ea19b585dc1b0d4c4358df3ca498ceb65b969.zip
IR: Make metadata typeless in assembly
Now that `Metadata` is typeless, reflect that in the assembly. These are the matching assembly changes for the metadata/value split in r223802. - Only use the `metadata` type when referencing metadata from a call intrinsic -- i.e., only when it's used as a `Value`. - Stop pretending that `ValueAsMetadata` is wrapped in an `MDNode` when referencing it from call intrinsics. So, assembly like this: define @foo(i32 %v) { call void @llvm.foo(metadata !{i32 %v}, metadata !0) call void @llvm.foo(metadata !{i32 7}, metadata !0) call void @llvm.foo(metadata !1, metadata !0) call void @llvm.foo(metadata !3, metadata !0) call void @llvm.foo(metadata !{metadata !3}, metadata !0) ret void, !bar !2 } !0 = metadata !{metadata !2} !1 = metadata !{i32* @global} !2 = metadata !{metadata !3} !3 = metadata !{} turns into this: define @foo(i32 %v) { call void @llvm.foo(metadata i32 %v, metadata !0) call void @llvm.foo(metadata i32 7, metadata !0) call void @llvm.foo(metadata i32* @global, metadata !0) call void @llvm.foo(metadata !3, metadata !0) call void @llvm.foo(metadata !{!3}, metadata !0) ret void, !bar !2 } !0 = !{!2} !1 = !{i32* @global} !2 = !{!3} !3 = !{} I wrote an upgrade script that handled almost all of the tests in llvm and many of the tests in cfe (even handling many `CHECK` lines). I've attached it (or will attach it in a moment if you're speedy) to PR21532 to help everyone update their out-of-tree testcases. This is part of PR21532. llvm-svn: 224257
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/AsmParser/LLParser.cpp135
-rw-r--r--llvm/lib/AsmParser/LLParser.h19
-rw-r--r--llvm/lib/IR/AsmWriter.cpp7
3 files changed, 81 insertions, 80 deletions
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 9e699d1ed3f..0ac07cc89ca 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -609,13 +609,16 @@ bool LLParser::ParseStandaloneMetadata() {
Lex.Lex();
unsigned MetadataID = 0;
- LocTy TyLoc;
- Type *Ty = nullptr;
MDNode *Init;
if (ParseUInt32(MetadataID) ||
- ParseToken(lltok::equal, "expected '=' here") ||
- ParseType(Ty, TyLoc) ||
- ParseToken(lltok::exclaim, "Expected '!' here") ||
+ ParseToken(lltok::equal, "expected '=' here"))
+ return true;
+
+ // Detect common error, from old metadata syntax.
+ if (Lex.getKind() == lltok::Type)
+ return TokError("unexpected type in metadata definition");
+
+ if (ParseToken(lltok::exclaim, "Expected '!' here") ||
ParseMDNode(Init))
return true;
@@ -1705,11 +1708,11 @@ bool LLParser::ParseIndexList(SmallVectorImpl<unsigned> &Indices,
//===----------------------------------------------------------------------===//
/// ParseType - Parse a type.
-bool LLParser::ParseType(Type *&Result, bool AllowVoid) {
+bool LLParser::ParseType(Type *&Result, const Twine &Msg, bool AllowVoid) {
SMLoc TypeLoc = Lex.getLoc();
switch (Lex.getKind()) {
default:
- return TokError("expected type");
+ return TokError(Msg);
case lltok::Type:
// Type ::= 'float' | 'void' (etc)
Result = Lex.getTyVal();
@@ -1853,9 +1856,14 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
if (ParseType(ArgTy, ArgLoc))
return true;
- // Otherwise, handle normal operands.
- if (ParseOptionalParamAttrs(ArgAttrs) || ParseValue(ArgTy, V, PFS))
- return true;
+ if (ArgTy->isMetadataTy()) {
+ if (ParseMetadataAsValue(V, PFS))
+ return true;
+ } else {
+ // Otherwise, handle normal operands.
+ if (ParseOptionalParamAttrs(ArgAttrs) || ParseValue(ArgTy, V, PFS))
+ return true;
+ }
ArgList.push_back(ParamInfo(ArgLoc, V, AttributeSet::get(V->getContext(),
AttrIndex++,
ArgAttrs)));
@@ -2388,8 +2396,6 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
ID.StrVal = Lex.getStrVal();
ID.Kind = ValID::t_LocalName;
break;
- case lltok::exclaim: // !42, !{...}, or !"foo"
- return ParseMetadataAsValue(ID, PFS);
case lltok::APSInt:
ID.APSIntVal = Lex.getAPSIntVal();
ID.Kind = ValID::t_APSInt;
@@ -2931,50 +2937,76 @@ bool LLParser::ParseGlobalValueVector(SmallVectorImpl<Constant *> &Elts) {
bool LLParser::ParseMDNode(MDNode *&MD) {
SmallVector<Metadata *, 16> Elts;
- if (ParseMDNodeVector(Elts, nullptr))
+ if (ParseMDNodeVector(Elts))
return true;
MD = MDNode::get(Context, Elts);
return false;
}
-bool LLParser::ParseMDNodeOrLocal(Metadata *&MD, PerFunctionState *PFS) {
- SmallVector<Metadata *, 16> Elts;
- if (ParseMDNodeVector(Elts, PFS))
+/// ParseMetadataAsValue
+/// ::= metadata i32 %local
+/// ::= metadata i32 @global
+/// ::= metadata i32 7
+/// ::= metadata !0
+/// ::= metadata !{...}
+/// ::= metadata !"string"
+bool LLParser::ParseMetadataAsValue(Value *&V, PerFunctionState &PFS) {
+ // Note: the type 'metadata' has already been parsed.
+ Metadata *MD;
+ if (ParseMetadata(MD, &PFS))
return true;
- // Check for function-local metadata masquerading as an MDNode.
- if (PFS && Elts.size() == 1 && Elts[0] && isa<LocalAsMetadata>(Elts[0])) {
- MD = Elts[0];
- return false;
- }
-
- MD = MDNode::get(Context, Elts);
+ V = MetadataAsValue::get(Context, MD);
return false;
}
-bool LLParser::ParseMetadataAsValue(ValID &ID, PerFunctionState *PFS) {
- Metadata *MD;
- if (ParseMetadata(MD, PFS))
+/// ParseValueAsMetadata
+/// ::= i32 %local
+/// ::= i32 @global
+/// ::= i32 7
+bool LLParser::ParseValueAsMetadata(Metadata *&MD, PerFunctionState *PFS) {
+ Type *Ty;
+ LocTy Loc;
+ if (ParseType(Ty, "expected metadata operand", Loc))
return true;
+ if (Ty->isMetadataTy())
+ return Error(Loc, "invalid metadata-value-metadata roundtrip");
- ID.Kind = ValID::t_Metadata;
- ID.MetadataVal = MetadataAsValue::get(Context, MD);
+ Value *V;
+ if (ParseValue(Ty, V, PFS))
+ return true;
+
+ MD = ValueAsMetadata::get(V);
return false;
}
/// ParseMetadata
+/// ::= i32 %local
+/// ::= i32 @global
+/// ::= i32 7
/// ::= !42
/// ::= !{...}
/// ::= !"string"
bool LLParser::ParseMetadata(Metadata *&MD, PerFunctionState *PFS) {
- if (ParseToken(lltok::exclaim, "expected '!' here"))
- return true;
+ // ValueAsMetadata:
+ // <type> <value>
+ if (Lex.getKind() != lltok::exclaim)
+ return ParseValueAsMetadata(MD, PFS);
+
+ // '!'.
+ assert(Lex.getKind() == lltok::exclaim && "Expected '!' here");
+ Lex.Lex();
// MDNode:
// !{ ... }
- if (Lex.getKind() == lltok::lbrace)
- return ParseMDNodeOrLocal(MD, PFS);
+ if (Lex.getKind() == lltok::lbrace) {
+ MDNode *N;
+ if (ParseMDNode(N))
+ return true;
+ MD = N;
+ return false;
+ }
// Standalone metadata reference
// !42
@@ -3024,11 +3056,6 @@ bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V,
(ID.UIntVal>>1)&1, (InlineAsm::AsmDialect(ID.UIntVal>>2)));
return false;
}
- case ValID::t_Metadata:
- if (!Ty->isMetadataTy())
- return Error(ID.Loc, "metadata value must have metadata type");
- V = ID.MetadataVal;
- return false;
case ValID::t_GlobalName:
V = GetGlobalVal(ID.StrVal, Ty, ID.Loc);
return V == nullptr;
@@ -4684,8 +4711,7 @@ int LLParser::ParseInsertValue(Instruction *&Inst, PerFunctionState &PFS) {
/// ::= { Element (',' Element)* }
/// Element
/// ::= 'null' | TypeAndValue
-bool LLParser::ParseMDNodeVector(SmallVectorImpl<Metadata *> &Elts,
- PerFunctionState *PFS) {
+bool LLParser::ParseMDNodeVector(SmallVectorImpl<Metadata *> &Elts) {
if (ParseToken(lltok::lbrace, "expected '{' here"))
return true;
@@ -4693,42 +4719,17 @@ bool LLParser::ParseMDNodeVector(SmallVectorImpl<Metadata *> &Elts,
if (EatIfPresent(lltok::rbrace))
return false;
- bool IsLocal = false;
do {
- if (IsLocal)
- return TokError("unexpected operand after function-local metadata");
-
// Null is a special case since it is typeless.
if (EatIfPresent(lltok::kw_null)) {
Elts.push_back(nullptr);
continue;
}
- Type *Ty = nullptr;
- if (ParseType(Ty))
+ Metadata *MD;
+ if (ParseMetadata(MD, nullptr))
return true;
-
- if (Ty->isMetadataTy()) {
- // No function-local metadata here.
- Metadata *MD = nullptr;
- if (ParseMetadata(MD, nullptr))
- return true;
- Elts.push_back(MD);
- continue;
- }
-
- Value *V = nullptr;
- if (ParseValue(Ty, V, PFS))
- return true;
- assert(V && "Expected valid value");
- Elts.push_back(ValueAsMetadata::get(V));
-
- if (isa<LocalAsMetadata>(Elts.back())) {
- assert(PFS && "Unexpected function-local metadata without PFS");
- if (Elts.size() > 1)
- return TokError("unexpected function-local metadata");
- IsLocal = true;
- }
+ Elts.push_back(MD);
} while (EatIfPresent(lltok::comma));
return ParseToken(lltok::rbrace, "expected end of metadata node");
diff --git a/llvm/lib/AsmParser/LLParser.h b/llvm/lib/AsmParser/LLParser.h
index d32e58e83f8..564a1de705e 100644
--- a/llvm/lib/AsmParser/LLParser.h
+++ b/llvm/lib/AsmParser/LLParser.h
@@ -52,7 +52,6 @@ namespace llvm {
t_EmptyArray, // No value: []
t_Constant, // Value in ConstantVal.
t_InlineAsm, // Value in StrVal/StrVal2/UIntVal.
- t_Metadata, // Value in MetadataVal.
t_ConstantStruct, // Value in ConstantStructElts.
t_PackedConstantStruct // Value in ConstantStructElts.
} Kind;
@@ -63,7 +62,6 @@ namespace llvm {
APSInt APSIntVal;
APFloat APFloatVal;
Constant *ConstantVal;
- MetadataAsValue *MetadataVal;
Constant **ConstantStructElts;
ValID() : Kind(t_LocalID), APFloatVal(0.0) {}
@@ -275,7 +273,15 @@ namespace llvm {
bool inAttrGrp, LocTy &BuiltinLoc);
// Type Parsing.
- bool ParseType(Type *&Result, bool AllowVoid = false);
+ bool ParseType(Type *&Result, const Twine &Msg, bool AllowVoid = false);
+ bool ParseType(Type *&Result, bool AllowVoid = false) {
+ return ParseType(Result, "expected type", AllowVoid);
+ }
+ bool ParseType(Type *&Result, const Twine &Msg, LocTy &Loc,
+ bool AllowVoid = false) {
+ Loc = Lex.getLoc();
+ return ParseType(Result, Msg, AllowVoid);
+ }
bool ParseType(Type *&Result, LocTy &Loc, bool AllowVoid = false) {
Loc = Lex.getLoc();
return ParseType(Result, AllowVoid);
@@ -380,12 +386,11 @@ namespace llvm {
bool ParseGlobalTypeAndValue(Constant *&V);
bool ParseGlobalValueVector(SmallVectorImpl<Constant *> &Elts);
bool parseOptionalComdat(Comdat *&C);
- bool ParseMetadataAsValue(ValID &ID, PerFunctionState *PFS);
+ bool ParseMetadataAsValue(Value *&V, PerFunctionState &PFS);
+ bool ParseValueAsMetadata(Metadata *&MD, PerFunctionState *PFS);
bool ParseMetadata(Metadata *&MD, PerFunctionState *PFS);
bool ParseMDNode(MDNode *&MD);
- bool ParseMDNodeOrLocal(Metadata *&MD, PerFunctionState *PFS);
- bool ParseMDNodeVector(SmallVectorImpl<Metadata *> &,
- PerFunctionState *PFS);
+ bool ParseMDNodeVector(SmallVectorImpl<Metadata *> &MDs);
bool ParseInstructionMetadata(Instruction *Inst, PerFunctionState *PFS);
// Function Parsing.
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 8fe03c06166..6153e350e98 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -1264,7 +1264,6 @@ static void WriteMDNodeBodyInternal(raw_ostream &Out, const MDNode *Node,
Out << ' ';
WriteAsOperandInternal(Out, V, TypePrinter, Machine, Context);
} else {
- Out << "metadata ";
WriteAsOperandInternal(Out, MD, TypePrinter, Machine, Context);
}
if (mi + 1 != me)
@@ -1381,13 +1380,9 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Metadata *MD,
assert((FromValue || !isa<LocalAsMetadata>(V)) &&
"Unexpected function-local metadata outside of value argument");
- if (FromValue)
- Out << "!{";
TypePrinter->print(V->getValue()->getType(), Out);
Out << ' ';
WriteAsOperandInternal(Out, V->getValue(), TypePrinter, Machine, Context);
- if (FromValue)
- Out << "}";
}
void AssemblyWriter::init() {
@@ -2378,7 +2373,7 @@ static void WriteMDNodeComment(const MDNode *Node,
}
void AssemblyWriter::writeMDNode(unsigned Slot, const MDNode *Node) {
- Out << '!' << Slot << " = metadata ";
+ Out << '!' << Slot << " = ";
printMDNodeBody(Node);
}
OpenPOWER on IntegriCloud