[llvm-commits] [llvm] r111895 - in /llvm/trunk: lib/AsmParser/LLParser.cpp lib/AsmParser/LLParser.h lib/Bitcode/Writer/ValueEnumerator.cpp lib/Bitcode/Writer/ValueEnumerator.h test/Feature/metadata.ll

Devang Patel dpatel at apple.com
Tue Aug 24 11:21:00 PDT 2010


Dan,

I expected parser to reject following but it does not.

define void @foo(i32 %x) {
  store i32 0, i32* null, !whatever !{i32 %tmp}
  %tmp = add i32 %x, %x
  ret void
}

-
Devang
On Aug 23, 2010, at 7:24 PM, Dan Gohman wrote:

> Author: djg
> Date: Mon Aug 23 21:24:03 2010
> New Revision: 111895
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=111895&view=rev
> Log:
> Extend function-local metadata to be usable as attachments.
> 
> Modified:
>    llvm/trunk/lib/AsmParser/LLParser.cpp
>    llvm/trunk/lib/AsmParser/LLParser.h
>    llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp
>    llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h
>    llvm/trunk/test/Feature/metadata.ll
> 
> Modified: llvm/trunk/lib/AsmParser/LLParser.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=111895&r1=111894&r2=111895&view=diff
> ==============================================================================
> --- llvm/trunk/lib/AsmParser/LLParser.cpp (original)
> +++ llvm/trunk/lib/AsmParser/LLParser.cpp Mon Aug 23 21:24:03 2010
> @@ -1124,23 +1124,33 @@
>       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 @@
>   return false;
> }
> 
> +bool LLParser::ParseMetadataListValue(ValID &ID, PerFunctionState *PFS) {
> +  assert(Lex.getKind() == lltok::lbrace);
> +  Lex.Lex();
> +
> +  SmallVector<Value*, 16> 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 @@
> 
>   // MDNode:
>   // !{ ... }
> -  if (EatIfPresent(lltok::lbrace)) {
> -    SmallVector<Value*, 16> 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
> 
> Modified: llvm/trunk/lib/AsmParser/LLParser.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.h?rev=111895&r1=111894&r2=111895&view=diff
> ==============================================================================
> --- llvm/trunk/lib/AsmParser/LLParser.h (original)
> +++ llvm/trunk/lib/AsmParser/LLParser.h Mon Aug 23 21:24:03 2010
> @@ -307,6 +307,7 @@
>     bool ParseGlobalValue(const Type *Ty, Constant *&V);
>     bool ParseGlobalTypeAndValue(Constant *&V);
>     bool ParseGlobalValueVector(SmallVectorImpl<Constant*> &Elts);
> +    bool ParseMetadataListValue(ValID &ID, PerFunctionState *PFS);
>     bool ParseMetadataValue(ValID &ID, PerFunctionState *PFS);
>     bool ParseMDNodeVector(SmallVectorImpl<Value*> &, PerFunctionState *PFS);
>     bool ParseInstructionMetadata(Instruction *Inst, PerFunctionState *PFS);
> 
> Modified: llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp?rev=111895&r1=111894&r2=111895&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp (original)
> +++ llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp Mon Aug 23 21:24:03 2010
> @@ -220,8 +220,35 @@
>     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<MDNode>(V) || isa<MDString>(V))
> +        EnumerateMetadata(V);
> +      else if (!isa<Instruction>(V) && !isa<Argument>(V))
> +        EnumerateValue(V);
> +    } else
> +      EnumerateType(Type::getVoidTy(N->getContext()));
> +  }
> +}
> +
> void ValueEnumerator::EnumerateMetadata(const Value *MD) {
>   assert((isa<MDNode>(MD) || isa<MDString>(MD)) && "Invalid metadata kind");
> +
> +  // Enumerate the type of this value.
> +  EnumerateType(MD->getType());
> +
> +  const MDNode *N = dyn_cast<MDNode>(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 @@
>     MDValues[MDValueID-1].second++;
>     return;
>   }
> +  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(MD->getType());
> +  EnumerateType(N->getType());
> 
> -  if (const MDNode *N = dyn_cast<MDNode>(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);
> +  // Check to see if it's already in!
> +  unsigned &MDValueID = MDValueMap[N];
> +  if (MDValueID) {
> +    // Increment use count.
> +    MDValues[MDValueID-1].second++;
>     return;
>   }
> -  
> -  // Add the value.
> -  assert(isa<MDString>(MD) && "Unknown metadata kind");
> -  MDValues.push_back(std::make_pair(MD, 1U));
> +  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<MDNode>(V))
> +        if (O->isFunctionLocal() && O->getFunction())
> +          EnumerateFunctionLocalMetadata(O);
> +      else if (isa<Instruction>(V) || isa<Argument>(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<MDNode>(V) || isa<MDString>(V))
> -    return EnumerateMetadata(V);
> +  assert(!isa<MDNode>(V) && !isa<MDString>(V) &&
> +         "EnumerateValue doesn't handle Metadata!");
> 
>   // Check to see if it's already in!
>   unsigned &ValueID = ValueMap[V];
> @@ -370,6 +414,7 @@
> 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 @@
>             // Enumerate metadata after the instructions they might refer to.
>             FnLocalMDVector.push_back(MD);
>       }
> +
> +      SmallVector<std::pair<unsigned, MDNode*>, 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 @@
> 
>   // 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();
> }
> 
> 
> Modified: llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h?rev=111895&r1=111894&r2=111895&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h (original)
> +++ llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h Mon Aug 23 21:24:03 2010
> @@ -72,6 +72,11 @@
>   /// 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 @@
> 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);
> 
> Modified: llvm/trunk/test/Feature/metadata.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Feature/metadata.ll?rev=111895&r1=111894&r2=111895&view=diff
> ==============================================================================
> --- llvm/trunk/test/Feature/metadata.ll (original)
> +++ llvm/trunk/test/Feature/metadata.ll Mon Aug 23 21:24:03 2010
> @@ -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
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits





More information about the llvm-commits mailing list