diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 028c2bbd5b1..0eb1b70c3f2 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -1124,23 +1124,33 @@ bool LLParser::ParseInstructionMetadata(Instruction *Inst, return TokError("expected metadata after comma"); std::string Name = Lex.getStrVal(); + unsigned MDK = M->getMDKindID(Name.c_str()); Lex.Lex(); MDNode *Node; unsigned NodeID; SMLoc Loc = Lex.getLoc(); - if (ParseToken(lltok::exclaim, "expected '!' here") || - ParseMDNodeID(Node, NodeID)) + + if (ParseToken(lltok::exclaim, "expected '!' here")) return true; - unsigned MDK = M->getMDKindID(Name.c_str()); - if (Node) { - // If we got the node, add it to the instruction. - Inst->setMetadata(MDK, Node); + if (Lex.getKind() == lltok::lbrace) { + ValID ID; + if (ParseMetadataListValue(ID, PFS)) + return true; + assert(ID.Kind == ValID::t_MDNode); + Inst->setMetadata(MDK, ID.MDNodeVal); } else { - MDRef R = { Loc, MDK, NodeID }; - // Otherwise, remember that this should be resolved later. - ForwardRefInstMetadata[Inst].push_back(R); + if (ParseMDNodeID(Node, NodeID)) + return true; + if (Node) { + // If we got the node, add it to the instruction. + Inst->setMetadata(MDK, Node); + } else { + MDRef R = { Loc, MDK, NodeID }; + // Otherwise, remember that this should be resolved later. + ForwardRefInstMetadata[Inst].push_back(R); + } } // If this is the end of the list, we're done. @@ -2505,6 +2515,20 @@ bool LLParser::ParseGlobalValueVector(SmallVectorImpl &Elts) { return false; } +bool LLParser::ParseMetadataListValue(ValID &ID, PerFunctionState *PFS) { + assert(Lex.getKind() == lltok::lbrace); + Lex.Lex(); + + SmallVector Elts; + if (ParseMDNodeVector(Elts, PFS) || + ParseToken(lltok::rbrace, "expected end of metadata node")) + return true; + + ID.MDNodeVal = MDNode::get(Context, Elts.data(), Elts.size()); + ID.Kind = ValID::t_MDNode; + return false; +} + /// ParseMetadataValue /// ::= !42 /// ::= !{...} @@ -2515,16 +2539,8 @@ bool LLParser::ParseMetadataValue(ValID &ID, PerFunctionState *PFS) { // MDNode: // !{ ... } - if (EatIfPresent(lltok::lbrace)) { - SmallVector Elts; - if (ParseMDNodeVector(Elts, PFS) || - ParseToken(lltok::rbrace, "expected end of metadata node")) - return true; - - ID.MDNodeVal = MDNode::get(Context, Elts.data(), Elts.size()); - ID.Kind = ValID::t_MDNode; - return false; - } + if (Lex.getKind() == lltok::lbrace) + return ParseMetadataListValue(ID, PFS); // Standalone metadata reference // !42 diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h index 848430e8952..444bae2390e 100644 --- a/lib/AsmParser/LLParser.h +++ b/lib/AsmParser/LLParser.h @@ -307,6 +307,7 @@ namespace llvm { bool ParseGlobalValue(const Type *Ty, Constant *&V); bool ParseGlobalTypeAndValue(Constant *&V); bool ParseGlobalValueVector(SmallVectorImpl &Elts); + bool ParseMetadataListValue(ValID &ID, PerFunctionState *PFS); bool ParseMetadataValue(ValID &ID, PerFunctionState *PFS); bool ParseMDNodeVector(SmallVectorImpl &, PerFunctionState *PFS); bool ParseInstructionMetadata(Instruction *Inst, PerFunctionState *PFS); diff --git a/lib/Bitcode/Writer/ValueEnumerator.cpp b/lib/Bitcode/Writer/ValueEnumerator.cpp index 043a65de3b6..69789c006a4 100644 --- a/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -220,8 +220,35 @@ void ValueEnumerator::EnumerateNamedMDNode(const NamedMDNode *MD) { EnumerateMetadata(MD->getOperand(i)); } +/// EnumerateMDNodeOperands - Enumerate all non-function-local values +/// and types referenced by the given MDNode. +void ValueEnumerator::EnumerateMDNodeOperands(const MDNode *N) { + for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { + if (Value *V = N->getOperand(i)) { + if (isa(V) || isa(V)) + EnumerateMetadata(V); + else if (!isa(V) && !isa(V)) + EnumerateValue(V); + } else + EnumerateType(Type::getVoidTy(N->getContext())); + } +} + void ValueEnumerator::EnumerateMetadata(const Value *MD) { assert((isa(MD) || isa(MD)) && "Invalid metadata kind"); + + // Enumerate the type of this value. + EnumerateType(MD->getType()); + + const MDNode *N = dyn_cast(MD); + + // In the module-level pass, skip function-local nodes themselves, but + // do walk their operands. + if (N && N->isFunctionLocal() && N->getFunction()) { + EnumerateMDNodeOperands(N); + return; + } + // Check to see if it's already in! unsigned &MDValueID = MDValueMap[MD]; if (MDValueID) { @@ -229,35 +256,52 @@ void ValueEnumerator::EnumerateMetadata(const Value *MD) { MDValues[MDValueID-1].second++; return; } - - // Enumerate the type of this value. - EnumerateType(MD->getType()); - - if (const MDNode *N = dyn_cast(MD)) { - MDValues.push_back(std::make_pair(MD, 1U)); - MDValueMap[MD] = MDValues.size(); - MDValueID = MDValues.size(); - for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { - if (Value *V = N->getOperand(i)) - EnumerateValue(V); - else - EnumerateType(Type::getVoidTy(MD->getContext())); - } - if (N->isFunctionLocal() && N->getFunction()) - FunctionLocalMDs.push_back(N); - return; - } - - // Add the value. - assert(isa(MD) && "Unknown metadata kind"); MDValues.push_back(std::make_pair(MD, 1U)); MDValueID = MDValues.size(); + + // Enumerate all non-function-local operands. + if (N) + EnumerateMDNodeOperands(N); +} + +/// EnumerateFunctionLocalMetadataa - Incorporate function-local metadata +/// information reachable from the given MDNode. +void ValueEnumerator::EnumerateFunctionLocalMetadata(const MDNode *N) { + assert(N->isFunctionLocal() && N->getFunction() && + "EnumerateFunctionLocalMetadata called on non-function-local mdnode!"); + + // Enumerate the type of this value. + EnumerateType(N->getType()); + + // Check to see if it's already in! + unsigned &MDValueID = MDValueMap[N]; + if (MDValueID) { + // Increment use count. + MDValues[MDValueID-1].second++; + return; + } + MDValues.push_back(std::make_pair(N, 1U)); + MDValueID = MDValues.size(); + + // To incoroporate function-local information visit all function-local + // MDNodes and all function-local values they reference. + for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) + if (Value *V = N->getOperand(i)) { + if (MDNode *O = dyn_cast(V)) + if (O->isFunctionLocal() && O->getFunction()) + EnumerateFunctionLocalMetadata(O); + else if (isa(V) || isa(V)) + EnumerateValue(V); + } + + // Also, collect all function-local MDNodes for easy access. + FunctionLocalMDs.push_back(N); } void ValueEnumerator::EnumerateValue(const Value *V) { assert(!V->getType()->isVoidTy() && "Can't insert void values!"); - if (isa(V) || isa(V)) - return EnumerateMetadata(V); + assert(!isa(V) && !isa(V) && + "EnumerateValue doesn't handle Metadata!"); // Check to see if it's already in! unsigned &ValueID = ValueMap[V]; @@ -370,6 +414,7 @@ void ValueEnumerator::EnumerateAttributes(const AttrListPtr &PAL) { void ValueEnumerator::incorporateFunction(const Function &F) { InstructionCount = 0; NumModuleValues = Values.size(); + NumModuleMDValues = MDValues.size(); // Adding function arguments to the value table. for (Function::const_arg_iterator I = F.arg_begin(), E = F.arg_end(); @@ -412,6 +457,15 @@ void ValueEnumerator::incorporateFunction(const Function &F) { // Enumerate metadata after the instructions they might refer to. FnLocalMDVector.push_back(MD); } + + SmallVector, 8> MDs; + I->getAllMetadataOtherThanDebugLoc(MDs); + for (unsigned i = 0, e = MDs.size(); i != e; ++i) { + MDNode *N = MDs[i].second; + if (N->isFunctionLocal() && N->getFunction()) + FnLocalMDVector.push_back(N); + } + if (!I->getType()->isVoidTy()) EnumerateValue(I); } @@ -419,17 +473,20 @@ void ValueEnumerator::incorporateFunction(const Function &F) { // Add all of the function-local metadata. for (unsigned i = 0, e = FnLocalMDVector.size(); i != e; ++i) - EnumerateOperandType(FnLocalMDVector[i]); + EnumerateFunctionLocalMetadata(FnLocalMDVector[i]); } void ValueEnumerator::purgeFunction() { /// Remove purged values from the ValueMap. for (unsigned i = NumModuleValues, e = Values.size(); i != e; ++i) ValueMap.erase(Values[i].first); + for (unsigned i = NumModuleMDValues, e = MDValues.size(); i != e; ++i) + MDValueMap.erase(MDValues[i].first); for (unsigned i = 0, e = BasicBlocks.size(); i != e; ++i) ValueMap.erase(BasicBlocks[i]); Values.resize(NumModuleValues); + MDValues.resize(NumModuleMDValues); BasicBlocks.clear(); } diff --git a/lib/Bitcode/Writer/ValueEnumerator.h b/lib/Bitcode/Writer/ValueEnumerator.h index 2453b7263ce..cd1d2371b70 100644 --- a/lib/Bitcode/Writer/ValueEnumerator.h +++ b/lib/Bitcode/Writer/ValueEnumerator.h @@ -72,6 +72,11 @@ private: /// When a function is incorporated, this is the size of the Values list /// before incorporation. unsigned NumModuleValues; + + /// When a function is incorporated, this is the size of the MDValues list + /// before incorporation. + unsigned NumModuleMDValues; + unsigned FirstFuncConstantID; unsigned FirstInstID; @@ -132,7 +137,9 @@ public: private: void OptimizeConstants(unsigned CstStart, unsigned CstEnd); + void EnumerateMDNodeOperands(const MDNode *N); void EnumerateMetadata(const Value *MD); + void EnumerateFunctionLocalMetadata(const MDNode *N); void EnumerateNamedMDNode(const NamedMDNode *NMD); void EnumerateValue(const Value *V); void EnumerateType(const Type *T); diff --git a/test/Feature/metadata.ll b/test/Feature/metadata.ll index d43815be46a..9856b375495 100644 --- a/test/Feature/metadata.ll +++ b/test/Feature/metadata.ll @@ -1,9 +1,11 @@ ; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis ; PR7105 -define void @foo() { +define void @foo(i32 %x) { call void @llvm.zonk(metadata !1, i64 0, metadata !1) - ret void + store i32 0, i32* null, !whatever !0, !whatever_else !{}, !more !{metadata !"hello"} + store i32 0, i32* null, !whatever !{i32 %x, metadata !"hello", metadata !1, metadata !{}, metadata !2} + ret void, !whatever !{i32 %x} } declare void @llvm.zonk(metadata, i64, metadata) nounwind readnone