If these blocks are empty, there is no reason to even emit the bytecode blocks.
authorChris Lattner <sabre@nondot.org>
Thu, 15 Jan 2004 21:06:57 +0000 (21:06 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 15 Jan 2004 21:06:57 +0000 (21:06 +0000)
This saves about 15K in 176.gcc, coupled with another patch that I'm working on.

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

lib/Bytecode/Writer/Writer.cpp
lib/Bytecode/Writer/WriterInternals.h

index 5675b2af4913b1a7369c84a140c72ed2a6970c72..6467921d05320524df688b4a162805254359d5e7 100644 (file)
@@ -164,7 +164,8 @@ void BytecodeWriter::outputConstantsInPlane(const std::vector<const Value*>
 void BytecodeWriter::outputConstants(bool isFunction) {
   ConstantTotalBytes -= Out.size();
   if (isFunction) FunctionConstantTotalBytes -= Out.size();
-  BytecodeBlock CPool(BytecodeFormat::ConstantPool, Out);
+  BytecodeBlock CPool(BytecodeFormat::ConstantPool, Out,
+                      true  /* Elide block if empty */);
 
   unsigned NumPlanes = Table.getNumPlanes();
 
@@ -286,7 +287,8 @@ void BytecodeWriter::outputSymbolTable(const SymbolTable &MST) {
 
   SymTabBytes -= Out.size();
   
-  BytecodeBlock SymTabBlock(BytecodeFormat::SymbolTable, Out);
+  BytecodeBlock SymTabBlock(BytecodeFormat::SymbolTable, Out,
+                            true/* ElideIfEmpty*/);
 
   for (SymbolTable::const_iterator TI = MST.begin(); TI != MST.end(); ++TI) {
     SymbolTable::type_const_iterator I = MST.type_begin(TI->first);
index 51ec362d846acb68b1720d2b0247a0d2e32527c9..15dbeffc8698ccdf9b35fb69884ab159e5ad8283 100644 (file)
@@ -50,27 +50,41 @@ private:
 
 
 
-// BytecodeBlock - Little helper class that helps us do backpatching of bytecode
-// block sizes really easily.  It backpatches when it goes out of scope.
-//
+/// BytecodeBlock - Little helper class is used by the bytecode writer to help
+/// do backpatching of bytecode block sizes really easily.  It backpatches when
+/// it goes out of scope.
+///
 class BytecodeBlock {
   unsigned Loc;
   std::deque<unsigned char> &Out;
 
+  /// ElideIfEmpty - If this is true and the bytecode block ends up being empty,
+  /// the block can remove itself from the output stream entirely.
+  bool ElideIfEmpty;
+
   BytecodeBlock(const BytecodeBlock &);   // do not implement
   void operator=(const BytecodeBlock &);  // do not implement
 public:
-  inline BytecodeBlock(unsigned ID, std::deque<unsigned char> &o) : Out(o) {
+  inline BytecodeBlock(unsigned ID, std::deque<unsigned char> &o,
+                       bool elideIfEmpty = false)
+    : Out(o), ElideIfEmpty(elideIfEmpty) {
     output(ID, Out);
-    output((unsigned)0, Out);         // Reserve the space for the block size...
+    output(0U, Out);         // Reserve the space for the block size...
     Loc = Out.size();
   }
 
   inline ~BytecodeBlock() {           // Do backpatch when block goes out
                                       // of scope...
+    if (Loc == Out.size() && ElideIfEmpty) {
+      // If the block is empty, and we are allowed to, do not emit the block at
+      // all!
+      Out.resize(Out.size()-8);
+      return;
+    }
+
     //cerr << "OldLoc = " << Loc << " NewLoc = " << NewLoc << " diff = "
     //     << (NewLoc-Loc) << endl;
-    output((unsigned)(Out.size()-Loc), Out, (int)Loc-4);
+    output(unsigned(Out.size()-Loc), Out, int(Loc-4));
     align32(Out);  // Blocks must ALWAYS be aligned
   }
 };