mirror of
https://github.com/RPCSX/llvm.git
synced 2025-02-18 03:59:15 +00:00
Support stand alone metadata syntax.
!0 = constant metadata !{i32 21, i32 22} @llvm.blah = constant metadata !{i32 1000, i16 200, metadata !0} git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74630 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
6d9148ce3d
commit
923078c65d
@ -109,6 +109,7 @@ bool LLParser::ParseTopLevelEntities() {
|
||||
case lltok::StringConstant: // FIXME: REMOVE IN LLVM 3.0
|
||||
case lltok::LocalVar: if (ParseNamedType()) return true; break;
|
||||
case lltok::GlobalVar: if (ParseNamedGlobal()) return true; break;
|
||||
case lltok::Metadata: if (ParseStandaloneMetadata()) return true; break;
|
||||
|
||||
// The Global variable production with no name can have many different
|
||||
// optional leading prefixes, the production is:
|
||||
@ -355,6 +356,34 @@ bool LLParser::ParseNamedGlobal() {
|
||||
return ParseAlias(Name, NameLoc, Visibility);
|
||||
}
|
||||
|
||||
/// ParseStandaloneMetadata:
|
||||
/// !42 = !{...}
|
||||
bool LLParser::ParseStandaloneMetadata() {
|
||||
assert(Lex.getKind() == lltok::Metadata);
|
||||
Lex.Lex();
|
||||
unsigned MetadataID = 0;
|
||||
if (ParseUInt32(MetadataID))
|
||||
return true;
|
||||
if (MetadataCache.find(MetadataID) != MetadataCache.end())
|
||||
return TokError("Metadata id is already used");
|
||||
if (ParseToken(lltok::equal, "expected '=' here"))
|
||||
return true;
|
||||
|
||||
LocTy TyLoc;
|
||||
bool IsConstant;
|
||||
PATypeHolder Ty(Type::VoidTy);
|
||||
if (ParseGlobalType(IsConstant) ||
|
||||
ParseType(Ty, TyLoc))
|
||||
return true;
|
||||
|
||||
Constant *Init = 0;
|
||||
if (ParseGlobalValue(Ty, Init))
|
||||
return true;
|
||||
|
||||
MetadataCache[MetadataID] = Init;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// ParseAlias:
|
||||
/// ::= GlobalVar '=' OptionalVisibility 'alias' OptionalLinkage Aliasee
|
||||
/// Aliasee
|
||||
@ -1596,6 +1625,17 @@ bool LLParser::ParseValID(ValID &ID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Standalone metadata reference
|
||||
// !{ ..., !42, ... }
|
||||
unsigned MID = 0;
|
||||
if (!ParseUInt32(MID)) {
|
||||
std::map<unsigned, Constant *>::iterator I = MetadataCache.find(MID);
|
||||
if (I == MetadataCache.end())
|
||||
return TokError("Unknown metadata reference");
|
||||
ID.ConstantVal = I->second;
|
||||
return false;
|
||||
}
|
||||
|
||||
// MDString:
|
||||
// ::= '!' STRINGCONSTANT
|
||||
std::string Str;
|
||||
|
@ -43,7 +43,8 @@ namespace llvm {
|
||||
std::map<std::string, std::pair<PATypeHolder, LocTy> > ForwardRefTypes;
|
||||
std::map<unsigned, std::pair<PATypeHolder, LocTy> > ForwardRefTypeIDs;
|
||||
std::vector<PATypeHolder> NumberedTypes;
|
||||
|
||||
/// MetadataCache - This map keeps track of parsed metadata constants.
|
||||
std::map<unsigned, Constant *> MetadataCache;
|
||||
struct UpRefRecord {
|
||||
/// Loc - This is the location of the upref.
|
||||
LocTy Loc;
|
||||
@ -139,6 +140,7 @@ namespace llvm {
|
||||
bool ParseGlobal(const std::string &Name, LocTy Loc, unsigned Linkage,
|
||||
bool HasLinkage, unsigned Visibility);
|
||||
bool ParseAlias(const std::string &Name, LocTy Loc, unsigned Visibility);
|
||||
bool ParseStandaloneMetadata();
|
||||
|
||||
// Type Parsing.
|
||||
bool ParseType(PATypeHolder &Result, bool AllowVoid = false);
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <map>
|
||||
using namespace llvm;
|
||||
|
||||
// Make virtual table appear in this compilation unit.
|
||||
@ -945,25 +946,6 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV,
|
||||
return;
|
||||
}
|
||||
|
||||
if (const MDNode *N = dyn_cast<MDNode>(CV)) {
|
||||
Out << "!{";
|
||||
for (MDNode::const_elem_iterator I = N->elem_begin(), E = N->elem_end();
|
||||
I != E;) {
|
||||
if (!*I) {
|
||||
Out << "null";
|
||||
} else {
|
||||
TypePrinter.print((*I)->getType(), Out);
|
||||
Out << ' ';
|
||||
WriteAsOperandInternal(Out, *I, TypePrinter, Machine);
|
||||
}
|
||||
|
||||
if (++I != E)
|
||||
Out << ", ";
|
||||
}
|
||||
Out << "}";
|
||||
return;
|
||||
}
|
||||
|
||||
if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
|
||||
Out << CE->getOpcodeName();
|
||||
if (CE->isCompare())
|
||||
@ -1092,10 +1074,14 @@ class AssemblyWriter {
|
||||
TypePrinting TypePrinter;
|
||||
AssemblyAnnotationWriter *AnnotationWriter;
|
||||
std::vector<const Type*> NumberedTypes;
|
||||
|
||||
// Each MDNode is assigned unique MetadataIDNo.
|
||||
std::map<const MDNode *, unsigned> MDNodes;
|
||||
unsigned MetadataIDNo;
|
||||
public:
|
||||
inline AssemblyWriter(raw_ostream &o, SlotTracker &Mac, const Module *M,
|
||||
AssemblyAnnotationWriter *AAW)
|
||||
: Out(o), Machine(Mac), TheModule(M), AnnotationWriter(AAW) {
|
||||
: Out(o), Machine(Mac), TheModule(M), AnnotationWriter(AAW), MetadataIDNo(0) {
|
||||
AddModuleTypesToPrinter(TypePrinter, NumberedTypes, M);
|
||||
}
|
||||
|
||||
@ -1124,6 +1110,7 @@ private:
|
||||
void printModule(const Module *M);
|
||||
void printTypeSymbolTable(const TypeSymbolTable &ST);
|
||||
void printGlobal(const GlobalVariable *GV);
|
||||
void printMDNode(const MDNode *Node, bool StandAlone);
|
||||
void printAlias(const GlobalAlias *GV);
|
||||
void printFunction(const Function *F);
|
||||
void printArgument(const Argument *FA, Attributes Attrs);
|
||||
@ -1264,6 +1251,28 @@ static void PrintVisibility(GlobalValue::VisibilityTypes Vis,
|
||||
}
|
||||
|
||||
void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
|
||||
if (GV->hasInitializer())
|
||||
// If GV is initialized using Metadata then separate out metadata
|
||||
// operands used by the initializer. Note, MDNodes are not cyclic.
|
||||
if (MDNode *N = dyn_cast<MDNode>(GV->getInitializer())) {
|
||||
SmallVector<const MDNode *, 4> WorkList;
|
||||
// Collect MDNodes used by the initializer.
|
||||
for (MDNode::const_elem_iterator I = N->elem_begin(), E = N->elem_end();
|
||||
I != E; ++I) {
|
||||
const Value *TV = *I;
|
||||
if (TV)
|
||||
if (const MDNode *NN = dyn_cast<MDNode>(TV))
|
||||
WorkList.push_back(NN);
|
||||
}
|
||||
|
||||
// Print MDNodes used by the initializer.
|
||||
while (!WorkList.empty()) {
|
||||
const MDNode *N = WorkList.back(); WorkList.pop_back();
|
||||
printMDNode(N, true);
|
||||
Out << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
if (GV->hasName()) {
|
||||
PrintLLVMName(Out, GV);
|
||||
Out << " = ";
|
||||
@ -1283,7 +1292,10 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
|
||||
|
||||
if (GV->hasInitializer()) {
|
||||
Out << ' ';
|
||||
writeOperand(GV->getInitializer(), false);
|
||||
if (MDNode *N = dyn_cast<MDNode>(GV->getInitializer()))
|
||||
printMDNode(N, false);
|
||||
else
|
||||
writeOperand(GV->getInitializer(), false);
|
||||
}
|
||||
|
||||
if (GV->hasSection())
|
||||
@ -1295,6 +1307,42 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
|
||||
Out << '\n';
|
||||
}
|
||||
|
||||
void AssemblyWriter::printMDNode(const MDNode *Node,
|
||||
bool StandAlone) {
|
||||
std::map<const MDNode *, unsigned>::iterator MI = MDNodes.find(Node);
|
||||
// If this node is already printed then just refer it using its Metadata
|
||||
// id number.
|
||||
if (MI != MDNodes.end()) {
|
||||
Out << "metadata !" << MI->second;
|
||||
return;
|
||||
}
|
||||
|
||||
if (StandAlone) {
|
||||
// Print standalone MDNode.
|
||||
// !42 = !{ ... }
|
||||
Out << "!" << MetadataIDNo << " = ";
|
||||
Out << "constant metadata ";
|
||||
}
|
||||
Out << "!{";
|
||||
for (MDNode::const_elem_iterator I = Node->elem_begin(), E = Node->elem_end();
|
||||
I != E;) {
|
||||
const Value *TV = *I;
|
||||
if (!TV)
|
||||
Out << "null";
|
||||
else if (const MDNode *N = dyn_cast<MDNode>(TV))
|
||||
printMDNode(N, StandAlone);
|
||||
else if (!*I)
|
||||
Out << "null";
|
||||
else
|
||||
writeOperand(*I, true);
|
||||
if (++I != E)
|
||||
Out << ", ";
|
||||
}
|
||||
Out << "}";
|
||||
|
||||
MDNodes[Node] = MetadataIDNo++;
|
||||
}
|
||||
|
||||
void AssemblyWriter::printAlias(const GlobalAlias *GA) {
|
||||
// Don't crash when dumping partially built GA
|
||||
if (!GA->hasName())
|
||||
|
7
test/Feature/mdnode2.ll
Normal file
7
test/Feature/mdnode2.ll
Normal file
@ -0,0 +1,7 @@
|
||||
; RUN: llvm-as < %s | llvm-dis > %t.ll
|
||||
; RUN: grep "!0 = constant metadata !{i32 21, i32 22}" %t.ll
|
||||
; RUN: grep "!1 = constant metadata !{i32 23, i32 24}" %t.ll
|
||||
; RUN: grep "@llvm.blah = constant metadata !{i32 1000, i16 200, metadata !1, metadata !0}" %t.ll
|
||||
!0 = constant metadata !{i32 21, i32 22}
|
||||
!1 = constant metadata !{i32 23, i32 24}
|
||||
@llvm.blah = constant metadata !{i32 1000, i16 200, metadata !1, metadata !0}
|
Loading…
x
Reference in New Issue
Block a user