Fix a regression that I introduced yesterday. :(
[oota-llvm.git] / lib / Bytecode / Writer / SlotCalculator.cpp
index f4414a5921d84e4f5a1f3ed5c091b08d5443b2db..b40d94ea2403391b1fbe84afe4c456a4751bec78 100644 (file)
@@ -97,6 +97,24 @@ void SlotCalculator::processModule() {
     if (I->hasInitializer())
       getOrCreateSlot(I->getInitializer());
 
+#if 0
+  // FIXME: Empirically, this causes the bytecode files to get BIGGER, because
+  // it explodes the operand size numbers to be bigger than can be handled
+  // compactly, which offsets the ~40% savings in constant sizes.  Whoops.
+
+  // If we are emitting a bytecode file, scan all of the functions for their
+  // constants, which allows us to emit more compact modules.  This is optional,
+  // and is just used to compactify the constants used by different functions
+  // together.
+  if (!IgnoreNamedNodes) {
+    SC_DEBUG("Inserting function constants:\n");
+    for (Module::const_iterator F = TheModule->begin(), E = TheModule->end();
+         F != E; ++F)
+      for_each(constant_begin(F), constant_end(F),
+               bind_obj(this, &SlotCalculator::getOrCreateSlot));
+  }
+#endif
+
   // Insert constants that are named at module level into the slot pool so that
   // the module symbol table can refer to them...
   //
@@ -105,6 +123,46 @@ void SlotCalculator::processModule() {
     processSymbolTable(&TheModule->getSymbolTable());
   }
 
+  // Now that we have collected together all of the information relevant to the
+  // module, compactify the type table if it is particularly big and outputting
+  // a bytecode file.  The basic problem we run into is that some programs have
+  // a large number of types, which causes the type field to overflow its size,
+  // which causes instructions to explode in size (particularly call
+  // instructions).  To avoid this behavior, we "sort" the type table so that
+  // all non-value types are pushed to the end of the type table, giving nice
+  // low numbers to the types that can be used by instructions, thus reducing
+  // the amount of explodage we suffer.
+  if (!IgnoreNamedNodes && Table[Type::TypeTyID].size() >= 0/*64*/) {
+    // Scan through the type table moving value types to the start of the table.
+    TypePlane *Types = &Table[Type::TypeTyID];
+    unsigned FirstNonValueTypeID = 0;
+    for (unsigned i = 0, e = Types->size(); i != e; ++i)
+      if (cast<Type>((*Types)[i])->isFirstClassType() ||
+          cast<Type>((*Types)[i])->isPrimitiveType()) {
+        // Check to see if we have to shuffle this type around.  If not, don't
+        // do anything.
+        if (i != FirstNonValueTypeID) {
+          assert(i != Type::TypeTyID && FirstNonValueTypeID != Type::TypeTyID &&
+                 "Cannot move around the type plane!");
+
+          // Swap the type ID's.
+          std::swap((*Types)[i], (*Types)[FirstNonValueTypeID]);
+
+          // Keep the NodeMap up to date.
+          NodeMap[(*Types)[i]] = i;
+          NodeMap[(*Types)[FirstNonValueTypeID]] = FirstNonValueTypeID;
+
+          // When we move a type, make sure to move its value plane as needed.
+          if (Table.size() > FirstNonValueTypeID) {
+            if (Table.size() <= i) Table.resize(i+1);
+            std::swap(Table[i], Table[FirstNonValueTypeID]);
+            Types = &Table[Type::TypeTyID];
+          }
+        }
+        ++FirstNonValueTypeID;
+      }
+  }
+
   SC_DEBUG("end processModule!\n");
 }
 
@@ -162,7 +220,7 @@ void SlotCalculator::incorporateFunction(const Function *F) {
     // If there is a symbol table, it is possible that the user has names for
     // constants that are not being used.  In this case, we will have problems
     // if we don't emit the constants now, because otherwise we will get 
-    // symboltable references to constants not in the output.  Scan for these
+    // symbol table references to constants not in the output.  Scan for these
     // constants now.
     //
     processSymbolTableConstants(&F->getSymbolTable());