[llvm-commits] [llvm] r82259 - in /llvm/trunk: include/llvm/Bitcode/LLVMBitCodes.h include/llvm/Metadata.h lib/Bitcode/Reader/BitcodeReader.cpp lib/Bitcode/Reader/BitcodeReader.h lib/Bitcode/Writer/BitcodeWriter.cpp lib/Bitcode/Writer/ValueEnumerator.cpp lib/Bitcode/Writer/ValueEnumerator.h lib/VMCore/Metadata.cpp test/Feature/md_on_instruction2.ll tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp

Devang Patel dpatel at apple.com
Fri Sep 18 12:26:43 PDT 2009


Author: dpatel
Date: Fri Sep 18 14:26:43 2009
New Revision: 82259

URL: http://llvm.org/viewvc/llvm-project?rev=82259&view=rev
Log:
Write and read metadata attachments.

Added:
    llvm/trunk/test/Feature/md_on_instruction2.ll
Modified:
    llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h
    llvm/trunk/include/llvm/Metadata.h
    llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
    llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h
    llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
    llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp
    llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h
    llvm/trunk/lib/VMCore/Metadata.cpp
    llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp

Modified: llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h?rev=82259&r1=82258&r2=82259&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h (original)
+++ llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h Fri Sep 18 14:26:43 2009
@@ -34,7 +34,8 @@
     FUNCTION_BLOCK_ID,
     TYPE_SYMTAB_BLOCK_ID,
     VALUE_SYMTAB_BLOCK_ID,
-    METADATA_BLOCK_ID
+    METADATA_BLOCK_ID,
+    METADATA_ATTACHMENT_ID
   };
 
 
@@ -111,7 +112,9 @@
     METADATA_STRING        = 1,   // MDSTRING:      [values]
     METADATA_NODE          = 2,   // MDNODE:        [n x (type num, value num)]
     METADATA_NAME          = 3,   // STRING:        [values]
-    METADATA_NAMED_NODE    = 4    // NAMEDMDNODE:   [n x mdnodes]
+    METADATA_NAMED_NODE    = 4,   // NAMEDMDNODE:   [n x mdnodes]
+    METADATA_KIND          = 5,   // [n x [id, name]]
+    METADATA_ATTACHMENT    = 6    // [m x [value, [n x [id, mdnode]]]
   };
   // The constants block (CONSTANTS_BLOCK_ID) describes emission for each
   // constant and maintains an implicit current type value.

Modified: llvm/trunk/include/llvm/Metadata.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Metadata.h?rev=82259&r1=82258&r2=82259&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Metadata.h (original)
+++ llvm/trunk/include/llvm/Metadata.h Fri Sep 18 14:26:43 2009
@@ -311,13 +311,14 @@
 /// MDKindID - This id identifies metadata kind the metadata store. Valid
 /// ID values are 1 or higher. This ID is set by RegisterMDKind.
 typedef unsigned MDKindID;
+
 class Metadata {
 public:
   typedef std::pair<MDKindID, WeakVH> MDPairTy;
   typedef SmallVector<MDPairTy, 2> MDMapTy;
-
-private:
   typedef DenseMap<const Instruction *, MDMapTy> MDStoreTy;
+  friend class BitcodeReader;
+private:
 
   /// MetadataStore - Collection of metadata used in this context.
   MDStoreTy MetadataStore;
@@ -344,6 +345,10 @@
   /// setMD - Attach the metadata of given kind with an Instruction.
   void setMD(MDKindID Kind, MDNode *Node, Instruction *Inst);
   
+  /// getHandlerNames - Get handler names. This is used by bitcode
+  /// writer.
+  const StringMap<unsigned> *getHandlerNames();
+
   /// ValueIsDeleted - This handler is used to update metadata store
   /// when a value is deleted.
   void ValueIsDeleted(Value *V) {}

Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=82259&r1=82258&r2=82259&view=diff

==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Fri Sep 18 14:26:43 2009
@@ -830,6 +830,22 @@
       MDValueList.AssignValue(V, NextValueNo++);
       break;
     }
+    case bitc::METADATA_KIND: {
+      unsigned RecordLength = Record.size();
+      if (Record.empty() || RecordLength < 2)
+	return Error("Invalid METADATA_KIND record");
+      SmallString<8> Name;
+      Name.resize(RecordLength-1);
+      MDKindID Kind = Record[0];
+      for (unsigned i = 1; i != RecordLength; ++i)
+	Name[i-1] = Record[i];
+      Metadata &TheMetadata = Context.getMetadata();
+      assert(TheMetadata.MDHandlerNames.find(Name.str()) 
+	     == TheMetadata.MDHandlerNames.end() &&
+	     "Already registered MDKind!");
+      TheMetadata.MDHandlerNames[Name.str()] = Kind;
+      break;
+    }
     }
   }
 }
@@ -1535,6 +1551,45 @@
   return false;
 }
 
+/// ParseMetadataAttachment - Parse metadata attachments.
+bool BitcodeReader::ParseMetadataAttachment() {
+  if (Stream.EnterSubBlock(bitc::METADATA_ATTACHMENT_ID))
+    return Error("Malformed block record");
+  
+  Metadata &TheMetadata = Context.getMetadata();
+  SmallVector<uint64_t, 64> Record;
+  while(1) {
+    unsigned Code = Stream.ReadCode();
+    if (Code == bitc::END_BLOCK) {
+      if (Stream.ReadBlockEnd())
+	return Error("Error at end of PARAMATTR block");
+      break;
+    }
+    if (Code == bitc::DEFINE_ABBREV) {
+      Stream.ReadAbbrevRecord();
+      continue;
+    }
+    // Read a metadata attachment record.
+    Record.clear();
+    switch (Stream.ReadRecord(Code, Record)) {
+    default:  // Default behavior: ignore.
+      break;
+    case bitc::METADATA_ATTACHMENT: {
+      unsigned RecordLength = Record.size();
+      if (Record.empty() || (RecordLength - 1) % 2 == 1)
+	return Error ("Invalid METADATA_ATTACHMENT reader!");
+      Instruction *Inst = InstructionList[Record[0]];
+      for (unsigned i = 1; i != RecordLength; i = i+2) {
+	MDKindID Kind = Record[i];
+	Value *Node = MDValueList.getValueFwdRef(Record[i+1]);
+	TheMetadata.setMD(Kind, cast<MDNode>(Node), Inst);
+      }
+      break;
+    }
+    }
+  }
+  return false;
+}
 
 /// ParseFunctionBody - Lazily parse the specified function body block.
 bool BitcodeReader::ParseFunctionBody(Function *F) {
@@ -1574,6 +1629,9 @@
       case bitc::VALUE_SYMTAB_BLOCK_ID:
         if (ParseValueSymbolTable()) return true;
         break;
+      case bitc::METADATA_ATTACHMENT_ID:
+	if (ParseMetadataAttachment()) return true;
+	break;
       }
       continue;
     }
@@ -1611,6 +1669,7 @@
       int Opc = GetDecodedBinaryOpcode(Record[OpNum++], LHS->getType());
       if (Opc == -1) return Error("Invalid BINOP record");
       I = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS);
+      InstructionList.push_back(I);
       if (OpNum < Record.size()) {
         if (Opc == Instruction::Add ||
             Opc == Instruction::Sub ||
@@ -1638,6 +1697,7 @@
       if (Opc == -1 || ResTy == 0)
         return Error("Invalid CAST record");
       I = CastInst::Create((Instruction::CastOps)Opc, Op, ResTy);
+      InstructionList.push_back(I);
       break;
     }
     case bitc::FUNC_CODE_INST_INBOUNDS_GEP:
@@ -1656,6 +1716,7 @@
       }
 
       I = GetElementPtrInst::Create(BasePtr, GEPIdx.begin(), GEPIdx.end());
+      InstructionList.push_back(I);
       if (BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP)
         cast<GetElementPtrInst>(I)->setIsInBounds(true);
       break;
@@ -1679,6 +1740,7 @@
 
       I = ExtractValueInst::Create(Agg,
                                    EXTRACTVALIdx.begin(), EXTRACTVALIdx.end());
+      InstructionList.push_back(I);
       break;
     }
       
@@ -1703,6 +1765,7 @@
 
       I = InsertValueInst::Create(Agg, Val,
                                   INSERTVALIdx.begin(), INSERTVALIdx.end());
+      InstructionList.push_back(I);
       break;
     }
       
@@ -1717,6 +1780,7 @@
         return Error("Invalid SELECT record");
       
       I = SelectInst::Create(Cond, TrueVal, FalseVal);
+      InstructionList.push_back(I);
       break;
     }
       
@@ -1743,6 +1807,7 @@
       } 
       
       I = SelectInst::Create(Cond, TrueVal, FalseVal);
+      InstructionList.push_back(I);
       break;
     }
       
@@ -1753,6 +1818,7 @@
           getValue(Record, OpNum, Type::getInt32Ty(Context), Idx))
         return Error("Invalid EXTRACTELT record");
       I = ExtractElementInst::Create(Vec, Idx);
+      InstructionList.push_back(I);
       break;
     }
       
@@ -1765,6 +1831,7 @@
           getValue(Record, OpNum, Type::getInt32Ty(Context), Idx))
         return Error("Invalid INSERTELT record");
       I = InsertElementInst::Create(Vec, Elt, Idx);
+      InstructionList.push_back(I);
       break;
     }
       
@@ -1778,6 +1845,7 @@
       if (getValueTypePair(Record, OpNum, NextValueNo, Mask))
         return Error("Invalid SHUFFLEVEC record");
       I = new ShuffleVectorInst(Vec1, Vec2, Mask);
+      InstructionList.push_back(I);
       break;
     }
 
@@ -1799,6 +1867,7 @@
         I = new FCmpInst((FCmpInst::Predicate)Record[OpNum], LHS, RHS);
       else
         I = new ICmpInst((ICmpInst::Predicate)Record[OpNum], LHS, RHS);
+      InstructionList.push_back(I);
       break;
     }
 
@@ -1810,6 +1879,7 @@
       getValueTypePair(Record, OpNum, NextValueNo, Op);
       unsigned Index = Record[1];
       I = ExtractValueInst::Create(Op, Index);
+      InstructionList.push_back(I);
       break;
     }
     
@@ -1818,6 +1888,7 @@
         unsigned Size = Record.size();
         if (Size == 0) {
           I = ReturnInst::Create(Context);
+	  InstructionList.push_back(I);
           break;
         }
 
@@ -1837,15 +1908,18 @@
           Value *RV = UndefValue::get(ReturnType);
           for (unsigned i = 0, e = Vs.size(); i != e; ++i) {
             I = InsertValueInst::Create(RV, Vs[i], i, "mrv");
+	    InstructionList.push_back(I);
             CurBB->getInstList().push_back(I);
             ValueList.AssignValue(I, NextValueNo++);
             RV = I;
           }
           I = ReturnInst::Create(Context, RV);
+	  InstructionList.push_back(I);
           break;
         }
 
         I = ReturnInst::Create(Context, Vs[0]);
+	InstructionList.push_back(I);
         break;
       }
     case bitc::FUNC_CODE_INST_BR: { // BR: [bb#, bb#, opval] or [bb#]
@@ -1855,14 +1929,17 @@
       if (TrueDest == 0)
         return Error("Invalid BR record");
 
-      if (Record.size() == 1)
+      if (Record.size() == 1) {
         I = BranchInst::Create(TrueDest);
+	InstructionList.push_back(I);
+      }
       else {
         BasicBlock *FalseDest = getBasicBlock(Record[1]);
         Value *Cond = getFnValueByID(Record[2], Type::getInt1Ty(Context));
         if (FalseDest == 0 || Cond == 0)
           return Error("Invalid BR record");
         I = BranchInst::Create(TrueDest, FalseDest, Cond);
+	InstructionList.push_back(I);
       }
       break;
     }
@@ -1876,6 +1953,7 @@
         return Error("Invalid SWITCH record");
       unsigned NumCases = (Record.size()-3)/2;
       SwitchInst *SI = SwitchInst::Create(Cond, Default, NumCases);
+      InstructionList.push_back(SI);
       for (unsigned i = 0, e = NumCases; i != e; ++i) {
         ConstantInt *CaseVal = 
           dyn_cast_or_null<ConstantInt>(getFnValueByID(Record[3+i*2], OpTy));
@@ -1933,6 +2011,7 @@
       
       I = InvokeInst::Create(Callee, NormalBB, UnwindBB,
                              Ops.begin(), Ops.end());
+      InstructionList.push_back(I);
       cast<InvokeInst>(I)->setCallingConv(
         static_cast<CallingConv::ID>(CCInfo));
       cast<InvokeInst>(I)->setAttributes(PAL);
@@ -1940,9 +2019,11 @@
     }
     case bitc::FUNC_CODE_INST_UNWIND: // UNWIND
       I = new UnwindInst(Context);
+      InstructionList.push_back(I);
       break;
     case bitc::FUNC_CODE_INST_UNREACHABLE: // UNREACHABLE
       I = new UnreachableInst(Context);
+      InstructionList.push_back(I);
       break;
     case bitc::FUNC_CODE_INST_PHI: { // PHI: [ty, val0,bb0, ...]
       if (Record.size() < 1 || ((Record.size()-1)&1))
@@ -1951,6 +2032,7 @@
       if (!Ty) return Error("Invalid PHI record");
       
       PHINode *PN = PHINode::Create(Ty);
+      InstructionList.push_back(PN);
       PN->reserveOperandSpace((Record.size()-1)/2);
       
       for (unsigned i = 0, e = Record.size()-1; i != e; i += 2) {
@@ -1972,6 +2054,7 @@
       unsigned Align = Record[2];
       if (!Ty || !Size) return Error("Invalid MALLOC record");
       I = new MallocInst(Ty->getElementType(), Size, (1 << Align) >> 1);
+      InstructionList.push_back(I);
       break;
     }
     case bitc::FUNC_CODE_INST_FREE: { // FREE: [op, opty]
@@ -1981,6 +2064,7 @@
           OpNum != Record.size())
         return Error("Invalid FREE record");
       I = new FreeInst(Op);
+      InstructionList.push_back(I);
       break;
     }
     case bitc::FUNC_CODE_INST_ALLOCA: { // ALLOCA: [instty, op, align]
@@ -1992,6 +2076,7 @@
       unsigned Align = Record[2];
       if (!Ty || !Size) return Error("Invalid ALLOCA record");
       I = new AllocaInst(Ty->getElementType(), Size, (1 << Align) >> 1);
+      InstructionList.push_back(I);
       break;
     }
     case bitc::FUNC_CODE_INST_LOAD: { // LOAD: [opty, op, align, vol]
@@ -2002,6 +2087,7 @@
         return Error("Invalid LOAD record");
       
       I = new LoadInst(Op, "", Record[OpNum+1], (1 << Record[OpNum]) >> 1);
+      InstructionList.push_back(I);
       break;
     }
     case bitc::FUNC_CODE_INST_STORE2: { // STORE2:[ptrty, ptr, val, align, vol]
@@ -2014,6 +2100,7 @@
         return Error("Invalid STORE record");
       
       I = new StoreInst(Val, Ptr, Record[OpNum+1], (1 << Record[OpNum]) >> 1);
+      InstructionList.push_back(I);
       break;
     }
     case bitc::FUNC_CODE_INST_STORE: { // STORE:[val, valty, ptr, align, vol]
@@ -2027,6 +2114,7 @@
         return Error("Invalid STORE record");
       
       I = new StoreInst(Val, Ptr, Record[OpNum+1], (1 << Record[OpNum]) >> 1);
+      InstructionList.push_back(I);
       break;
     }
     case bitc::FUNC_CODE_INST_CALL: {
@@ -2072,6 +2160,7 @@
       }
       
       I = CallInst::Create(Callee, Args.begin(), Args.end());
+      InstructionList.push_back(I);
       cast<CallInst>(I)->setCallingConv(
         static_cast<CallingConv::ID>(CCInfo>>1));
       cast<CallInst>(I)->setTailCall(CCInfo & 1);
@@ -2087,6 +2176,7 @@
       if (!OpTy || !Op || !ResTy)
         return Error("Invalid VAARG record");
       I = new VAArgInst(Op, ResTy);
+      InstructionList.push_back(I);
       break;
     }
     }

Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h?rev=82259&r1=82258&r2=82259&view=diff

==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h (original)
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h Fri Sep 18 14:26:43 2009
@@ -132,6 +132,8 @@
   std::vector<PATypeHolder> TypeList;
   BitcodeReaderValueList ValueList;
   BitcodeReaderMDValueList MDValueList;
+  SmallVector<Instruction *, 64> InstructionList;
+
   std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
   std::vector<std::pair<GlobalAlias*, unsigned> > AliasInits;
   
@@ -250,6 +252,7 @@
   bool ParseFunctionBody(Function *F);
   bool ResolveGlobalAndAliasInits();
   bool ParseMetadata();
+  bool ParseMetadataAttachment();
 };
   
 } // End llvm namespace

Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=82259&r1=82258&r2=82259&view=diff

==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original)
+++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Fri Sep 18 14:26:43 2009
@@ -551,7 +551,74 @@
   }
   
   if (StartedMetadataBlock)
-    Stream.ExitBlock();    
+    Stream.ExitBlock();
+}
+
+static void WriteMetadataAttachment(const Function &F,
+				    const ValueEnumerator &VE,
+				    BitstreamWriter &Stream) {
+  bool StartedMetadataBlock = false;
+  SmallVector<uint64_t, 64> Record;
+  
+  // Write metadata attachments
+  // METADATA_ATTACHMENT - [m x [value, [n x [id, mdnode]]]
+  Metadata &TheMetadata = F.getContext().getMetadata();
+  for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
+    for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
+         I != E; ++I) {
+      const Metadata::MDMapTy *P = TheMetadata.getMDs(I);
+      if (!P) continue;
+      bool RecordedInstruction = false;
+      for (Metadata::MDMapTy::const_iterator PI = P->begin(), PE = P->end();
+	   PI != PE; ++PI) {
+	if (MDNode *ND = dyn_cast_or_null<MDNode>(PI->second)) {
+	  if (RecordedInstruction == false) {
+	    Record.push_back(VE.getInstructionID(I));
+	    RecordedInstruction = true;
+	  }
+	  Record.push_back(PI->first);
+	  Record.push_back(VE.getValueID(ND));
+	}
+      }
+      if (!StartedMetadataBlock)  {
+	Stream.EnterSubblock(bitc::METADATA_ATTACHMENT_ID, 3);
+	StartedMetadataBlock = true;
+      }
+      Stream.EmitRecord(bitc::METADATA_ATTACHMENT, Record, 0);
+      Record.clear();
+    }
+
+  if (StartedMetadataBlock) 
+    Stream.ExitBlock();
+}
+
+static void WriteModuleMetadataStore(const Module *M,
+				     const ValueEnumerator &VE,
+				     BitstreamWriter &Stream) {
+  
+  bool StartedMetadataBlock = false;
+  SmallVector<uint64_t, 64> Record;
+  
+  // Write metadata kinds
+  // METADATA_KIND - [n x [id, name]]
+  Metadata &TheMetadata = M->getContext().getMetadata();
+  const StringMap<unsigned> *Kinds = TheMetadata.getHandlerNames();
+  for (StringMap<unsigned>::const_iterator 
+	 I = Kinds->begin(), E = Kinds->end(); I != E; ++I) {
+    Record.push_back(I->second);
+    StringRef KName = I->first();
+    for (unsigned i = 0, e = KName.size(); i != e; ++i)
+      Record.push_back(KName[i]);
+    if (!StartedMetadataBlock)  {
+      Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
+      StartedMetadataBlock = true;
+    }
+    Stream.EmitRecord(bitc::METADATA_KIND, Record, 0);
+    Record.clear();
+  }
+
+  if (StartedMetadataBlock) 
+    Stream.ExitBlock();
 }
 
 static void WriteConstants(unsigned FirstVal, unsigned LastVal,
@@ -833,6 +900,7 @@
                              SmallVector<unsigned, 64> &Vals) {
   unsigned Code = 0;
   unsigned AbbrevToUse = 0;
+  VE.setInstructionID(&I);
   switch (I.getOpcode()) {
   default:
     if (Instruction::isCast(I.getOpcode())) {
@@ -1146,7 +1214,8 @@
   
   // Emit names for all the instructions etc.
   WriteValueSymbolTable(F.getValueSymbolTable(), VE, Stream);
-    
+
+  WriteMetadataAttachment(F, VE, Stream);
   VE.purgeFunction();
   Stream.ExitBlock();
 }
@@ -1390,6 +1459,9 @@
   for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I)
     if (!I->isDeclaration())
       WriteFunction(*I, VE, Stream);
+
+  // Emit metadata.
+  WriteModuleMetadataStore(M, VE, Stream);
   
   // Emit the type symbol table information.
   WriteTypeSymbolTable(M->getTypeSymbolTable(), VE, Stream);

Modified: llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp?rev=82259&r1=82258&r2=82259&view=diff

==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp (original)
+++ llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp Fri Sep 18 14:26:43 2009
@@ -40,6 +40,8 @@
 
 /// ValueEnumerator - Enumerate module-level information.
 ValueEnumerator::ValueEnumerator(const Module *M) {
+  InstructionCount = 0;
+
   // Enumerate the global variables.
   for (Module::const_global_iterator I = M->global_begin(),
          E = M->global_end(); I != E; ++I)
@@ -83,7 +85,8 @@
     for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end();
          I != E; ++I)
       EnumerateType(I->getType());
-    
+
+    Metadata &TheMetadata = F->getContext().getMetadata();    
     for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
       for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E;++I){
         for (User::const_op_iterator OI = I->op_begin(), E = I->op_end(); 
@@ -94,6 +97,14 @@
           EnumerateAttributes(CI->getAttributes());
         else if (const InvokeInst *II = dyn_cast<InvokeInst>(I))
           EnumerateAttributes(II->getAttributes());
+
+	// Enumerate metadata attached with this instruction.
+	const Metadata::MDMapTy *MDs = TheMetadata.getMDs(I);
+	if (MDs)
+	  for (Metadata::MDMapTy::const_iterator MI = MDs->begin(), 
+		 ME = MDs->end(); MI != ME; ++MI)
+	    if (MDNode *MDN = dyn_cast_or_null<MDNode>(MI->second))
+	      EnumerateMetadata(MDN);
       }
   }
   
@@ -114,6 +125,16 @@
     TypeMap[Types[i].first] = i+1;
 }
 
+unsigned ValueEnumerator::getInstructionID(const Instruction *Inst) const {
+  InstructionMapType::const_iterator I = InstructionMap.find(Inst);
+  assert (I != InstructionMap.end() && "Instruction is not mapped!");
+    return I->second;
+}  
+
+void ValueEnumerator::setInstructionID(const Instruction *I) {
+  InstructionMap[I] = InstructionCount++;
+}
+
 unsigned ValueEnumerator::getValueID(const Value *V) const {
   if (isa<MetadataBase>(V)) {
     ValueMapType::const_iterator I = MDValueMap.find(V);

Modified: llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h?rev=82259&r1=82258&r2=82259&view=diff

==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h (original)
+++ llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h Fri Sep 18 14:26:43 2009
@@ -22,6 +22,7 @@
 
 class Type;
 class Value;
+class Instruction;
 class BasicBlock;
 class Function;
 class Module;
@@ -47,11 +48,15 @@
   ValueList Values;
   ValueList MDValues;
   ValueMapType MDValueMap;
-
+  
   typedef DenseMap<void*, unsigned> AttributeMapType;
   AttributeMapType AttributeMap;
   std::vector<AttrListPtr> Attributes;
   
+  typedef DenseMap<const Instruction*, unsigned> InstructionMapType;
+  InstructionMapType InstructionMap;
+  unsigned InstructionCount;
+
   /// BasicBlocks - This contains all the basic blocks for the currently
   /// incorporated function.  Their reverse mapping is stored in ValueMap.
   std::vector<const BasicBlock*> BasicBlocks;
@@ -74,7 +79,10 @@
     assert(I != TypeMap.end() && "Type not in ValueEnumerator!");
     return I->second-1;
   }
-  
+
+  unsigned getInstructionID(const Instruction *I) const;
+  void setInstructionID(const Instruction *I);
+
   unsigned getAttributeID(const AttrListPtr &PAL) const {
     if (PAL.isEmpty()) return 0;  // Null maps to zero.
     AttributeMapType::const_iterator I = AttributeMap.find(PAL.getRawPointer());

Modified: llvm/trunk/lib/VMCore/Metadata.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Metadata.cpp?rev=82259&r1=82258&r2=82259&view=diff

==============================================================================
--- llvm/trunk/lib/VMCore/Metadata.cpp (original)
+++ llvm/trunk/lib/VMCore/Metadata.cpp Fri Sep 18 14:26:43 2009
@@ -317,6 +317,12 @@
   return &(I->second);
 }
 
+/// getHandlerNames - Get handler names. This is used by bitcode
+/// writer.
+const StringMap<unsigned> *Metadata::getHandlerNames() {
+  return &MDHandlerNames;
+}
+
 /// ValueIsDeleted - This handler is used to update metadata store
 /// when a value is deleted.
 void Metadata::ValueIsDeleted(const Instruction *Inst) {

Added: llvm/trunk/test/Feature/md_on_instruction2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Feature/md_on_instruction2.ll?rev=82259&view=auto

==============================================================================
--- llvm/trunk/test/Feature/md_on_instruction2.ll (added)
+++ llvm/trunk/test/Feature/md_on_instruction2.ll Fri Sep 18 14:26:43 2009
@@ -0,0 +1,22 @@
+; RUN: llvm-as < %s | llvm-dis | grep " dbg " | count 4
+define i32 @foo() nounwind ssp {
+entry:
+  %retval = alloca i32                            ; <i32*> [#uses=2]
+  call void @llvm.dbg.func.start(metadata !0)
+  store i32 42, i32* %retval, dbg !3
+  br label %0, dbg !3
+
+; <label>:0                                       ; preds = %entry
+  call void @llvm.dbg.region.end(metadata !0)
+  %1 = load i32* %retval, dbg !3                  ; <i32> [#uses=1]
+  ret i32 %1, dbg !3
+}
+
+declare void @llvm.dbg.func.start(metadata) nounwind readnone
+
+declare void @llvm.dbg.region.end(metadata) nounwind readnone
+
+!0 = metadata !{i32 458798, i32 0, metadata !1, metadata !"foo", metadata !"foo", metadata !"foo", metadata !1, i32 1, metadata !2, i1 false, i1 true}
+!1 = metadata !{i32 458769, i32 0, i32 12, metadata !"foo.c", metadata !"/tmp", metadata !"clang 1.0", i1 true, i1 false, metadata !"", i32 0}
+!2 = metadata !{i32 458788, metadata !1, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5}
+!3 = metadata !{i32 1, i32 13, metadata !1, metadata !1}

Modified: llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp?rev=82259&r1=82258&r2=82259&view=diff

==============================================================================
--- llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp (original)
+++ llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp Fri Sep 18 14:26:43 2009
@@ -92,15 +92,16 @@
   if (CurStreamType != LLVMIRBitstream) return 0;
   
   switch (BlockID) {
-  default:                          return 0;
-  case bitc::MODULE_BLOCK_ID:       return "MODULE_BLOCK";
-  case bitc::PARAMATTR_BLOCK_ID:    return "PARAMATTR_BLOCK";
-  case bitc::TYPE_BLOCK_ID:         return "TYPE_BLOCK";
-  case bitc::CONSTANTS_BLOCK_ID:    return "CONSTANTS_BLOCK";
-  case bitc::FUNCTION_BLOCK_ID:     return "FUNCTION_BLOCK";
-  case bitc::TYPE_SYMTAB_BLOCK_ID:  return "TYPE_SYMTAB";
-  case bitc::VALUE_SYMTAB_BLOCK_ID: return "VALUE_SYMTAB";
-  case bitc::METADATA_BLOCK_ID:     return "METADATA_BLOCK";
+  default:                           return 0;
+  case bitc::MODULE_BLOCK_ID:        return "MODULE_BLOCK";
+  case bitc::PARAMATTR_BLOCK_ID:     return "PARAMATTR_BLOCK";
+  case bitc::TYPE_BLOCK_ID:          return "TYPE_BLOCK";
+  case bitc::CONSTANTS_BLOCK_ID:     return "CONSTANTS_BLOCK";
+  case bitc::FUNCTION_BLOCK_ID:      return "FUNCTION_BLOCK";
+  case bitc::TYPE_SYMTAB_BLOCK_ID:   return "TYPE_SYMTAB";
+  case bitc::VALUE_SYMTAB_BLOCK_ID:  return "VALUE_SYMTAB";
+  case bitc::METADATA_BLOCK_ID:      return "METADATA_BLOCK";
+  case bitc::METADATA_ATTACHMENT_ID: return "METADATA_ATTACHMENT_BLOCK";
   }
 }
 
@@ -245,6 +246,11 @@
     case bitc::VST_CODE_ENTRY: return "ENTRY";
     case bitc::VST_CODE_BBENTRY: return "BBENTRY";
     }
+  case bitc::METADATA_ATTACHMENT_ID:
+    switch(CodeID) {
+    default:return 0;
+    case bitc::METADATA_ATTACHMENT:  return "METADATA_ATTACHMENT";
+    }
   case bitc::METADATA_BLOCK_ID:
     switch(CodeID) {
     default:return 0;
@@ -252,6 +258,7 @@
     case bitc::METADATA_NODE:        return "MDNODE";
     case bitc::METADATA_NAME:        return "METADATA_NAME";
     case bitc::METADATA_NAMED_NODE:  return "NAMEDMDNODE";
+    case bitc::METADATA_KIND:        return "METADATA_KIND";
     }
   }
 }





More information about the llvm-commits mailing list