Bitcode: Simplify emission of METADATA_BLOCK
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>
Mon, 12 Jan 2015 22:30:34 +0000 (22:30 +0000)
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>
Mon, 12 Jan 2015 22:30:34 +0000 (22:30 +0000)
Refactor logic so that we know up-front whether to open a block and
whether we need an MDString abbreviation.

This is almost NFC, but will start emitting `MDString` abbreviations
when the first record is not an `MDString`.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225712 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Bitcode/Writer/BitcodeWriter.cpp
lib/Bitcode/Writer/ValueEnumerator.cpp
lib/Bitcode/Writer/ValueEnumerator.h

index 8152799bbcefe2c5cb0164eff929a12da74e4f2d..1741d0363b20d45778dcd549b8807db05e750271 100644 (file)
@@ -783,52 +783,44 @@ static void WriteModuleMetadata(const Module *M,
                                 const ValueEnumerator &VE,
                                 BitstreamWriter &Stream) {
   const auto &MDs = VE.getMDs();
-  bool StartedMetadataBlock = false;
+  if (MDs.empty() && M->named_metadata_empty())
+    return;
+
+  Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
+
   unsigned MDSAbbrev = 0;
+  if (VE.hasMDString()) {
+    // Abbrev for METADATA_STRING.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_STRING));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));
+    MDSAbbrev = Stream.EmitAbbrev(Abbv);
+  }
+
   SmallVector<uint64_t, 64> Record;
   for (unsigned i = 0, e = MDs.size(); i != e; ++i) {
     if (const MDNode *N = dyn_cast<MDNode>(MDs[i])) {
-      if (!StartedMetadataBlock) {
-        Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
-        StartedMetadataBlock = true;
-      }
       WriteMDNode(N, VE, Stream, Record);
-    } else if (const auto *MDC = dyn_cast<ConstantAsMetadata>(MDs[i])) {
-      if (!StartedMetadataBlock) {
-        Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
-        StartedMetadataBlock = true;
-      }
+      continue;
+    }
+    if (const auto *MDC = dyn_cast<ConstantAsMetadata>(MDs[i])) {
       WriteValueAsMetadata(MDC, VE, Stream, Record);
-    } else if (const MDString *MDS = dyn_cast<MDString>(MDs[i])) {
-      if (!StartedMetadataBlock) {
-        Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
-
-        // Abbrev for METADATA_STRING.
-        BitCodeAbbrev *Abbv = new BitCodeAbbrev();
-        Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_STRING));
-        Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
-        Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));
-        MDSAbbrev = Stream.EmitAbbrev(Abbv);
-        StartedMetadataBlock = true;
-      }
-
-      // Code: [strchar x N]
-      Record.append(MDS->bytes_begin(), MDS->bytes_end());
-
-      // Emit the finished record.
-      Stream.EmitRecord(bitc::METADATA_STRING, Record, MDSAbbrev);
-      Record.clear();
+      continue;
     }
+    const MDString *MDS = cast<MDString>(MDs[i]);
+    // Code: [strchar x N]
+    Record.append(MDS->bytes_begin(), MDS->bytes_end());
+
+    // Emit the finished record.
+    Stream.EmitRecord(bitc::METADATA_STRING, Record, MDSAbbrev);
+    Record.clear();
   }
 
   // Write named metadata.
   for (Module::const_named_metadata_iterator I = M->named_metadata_begin(),
        E = M->named_metadata_end(); I != E; ++I) {
     const NamedMDNode *NMD = I;
-    if (!StartedMetadataBlock)  {
-      Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
-      StartedMetadataBlock = true;
-    }
 
     // Write name.
     StringRef Str = NMD->getName();
@@ -844,8 +836,7 @@ static void WriteModuleMetadata(const Module *M,
     Record.clear();
   }
 
-  if (StartedMetadataBlock)
-    Stream.ExitBlock();
+  Stream.ExitBlock();
 }
 
 static void WriteFunctionLocalMetadata(const Function &F,
index 2c0fdc00ba4ac0d482669adb500db509ca39509e..b117d7bb49ac76abc383dd6a42f99c9fed5d6d63 100644 (file)
@@ -282,7 +282,7 @@ static bool isIntOrIntVectorValue(const std::pair<const Value*, unsigned> &V) {
   return V.first->getType()->isIntOrIntVectorTy();
 }
 
-ValueEnumerator::ValueEnumerator(const Module &M) {
+ValueEnumerator::ValueEnumerator(const Module &M) : HasMDString(false) {
   if (shouldPreserveBitcodeUseListOrder())
     UseListOrders = predictUseListOrder(M);
 
@@ -546,6 +546,8 @@ void ValueEnumerator::EnumerateMetadata(const Metadata *MD) {
   else if (auto *C = dyn_cast<ConstantAsMetadata>(MD))
     EnumerateValue(C->getValue());
 
+  HasMDString |= isa<MDString>(MD);
+
   // Replace the dummy ID inserted above with the correct one.  MDValueMap may
   // have changed by inserting operands, so we need a fresh lookup here.
   MDs.push_back(MD);
index 3b1b3137e39f01b4e70dca02405c32a734a8aed8..e63394fefa5a306d69dd2b4bf27ff33fd6fe73db 100644 (file)
@@ -64,6 +64,7 @@ private:
   SmallVector<const LocalAsMetadata *, 8> FunctionLocalMDs;
   typedef DenseMap<const Metadata *, unsigned> MetadataMapType;
   MetadataMapType MDValueMap;
+  bool HasMDString;
 
   typedef DenseMap<AttributeSet, unsigned> AttributeGroupMapType;
   AttributeGroupMapType AttributeGroupMap;
@@ -109,6 +110,8 @@ public:
   unsigned getValueID(const Value *V) const;
   unsigned getMetadataID(const Metadata *V) const;
 
+  bool hasMDString() const { return HasMDString; }
+
   unsigned getTypeID(Type *T) const {
     TypeMapType::const_iterator I = TypeMap.find(T);
     assert(I != TypeMap.end() && "Type not in ValueEnumerator!");