[llvm-commits] CVS: llvm/lib/VMCore/Constants.cpp

Chris Lattner lattner at cs.uiuc.edu
Sat Feb 14 23:54:17 PST 2004


Changes in directory llvm/lib/VMCore:

Constants.cpp updated: 1.78 -> 1.79

---
Log message:

Add a new ConstantAggregateZero class, to fix PR239.  This makes zero
initializers for constant structs and arrays take constant space, instead of
space proportinal to the number of elements.  This reduces the memory usage of
the LLVM compiler by hundreds of megabytes when compiling some nasty SPEC95
benchmarks.


---
Diffs of the changes:  (+70 -36)

Index: llvm/lib/VMCore/Constants.cpp
diff -u llvm/lib/VMCore/Constants.cpp:1.78 llvm/lib/VMCore/Constants.cpp:1.79
--- llvm/lib/VMCore/Constants.cpp:1.78	Sat Feb 14 22:14:47 2004
+++ llvm/lib/VMCore/Constants.cpp	Sat Feb 14 23:53:04 2004
@@ -64,8 +64,6 @@
   delete this;
 }
 
-static std::map<const Type *, Constant*> NullValues;
-
 // Static constructor to create a '0' constant of arbitrary type...
 Constant *Constant::getNullValue(const Type *Ty) {
   switch (Ty->getPrimitiveID()) {
@@ -118,35 +116,9 @@
   case Type::PointerTyID: 
     return ConstantPointerNull::get(cast<PointerType>(Ty));
 
-  case Type::StructTyID: {
-    if (!Ty->isAbstract())
-      if (Constant *V = NullValues[Ty])
-        return V;
-
-    const StructType *ST = cast<StructType>(Ty);
-    std::vector<Constant*> Elements;
-    Elements.resize(ST->getNumElements());
-    for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i)
-      Elements[i] = Constant::getNullValue(ST->getElementType(i));
-    Constant *Ret = ConstantStruct::get(ST, Elements);
-    if (!Ty->isAbstract())
-      NullValues[Ty] = Ret;
-    return Ret;
-  }
-  case Type::ArrayTyID: {
-    if (!Ty->isAbstract())
-      if (Constant *V = NullValues[Ty])
-        return V;
-
-    const ArrayType *AT = cast<ArrayType>(Ty);
-    Constant *El = Constant::getNullValue(AT->getElementType());
-    unsigned NumElements = AT->getNumElements();
-    Constant *Ret = ConstantArray::get(AT,
-                                       std::vector<Constant*>(NumElements, El));
-    if (!Ty->isAbstract())
-      NullValues[Ty] = Ret;
-    return Ret;
-  }
+  case Type::StructTyID:
+  case Type::ArrayTyID:
+    return ConstantAggregateZero::get(Ty);
   default:
     // Function, Type, Label, or Opaque type?
     assert(0 && "Cannot create a null constant of that type!");
@@ -347,11 +319,15 @@
   return ((Ty == Type::FloatTy || Ty == Type::DoubleTy) &&
           !isa<ConstantExpr>(CPV));
 }
+bool ConstantAggregateZero::classof(const Constant *CPV) {
+  return (isa<ArrayType>(CPV->getType()) || isa<StructType>(CPV->getType())) &&
+         CPV->isNullValue();
+}
 bool ConstantArray::classof(const Constant *CPV) {
-  return isa<ArrayType>(CPV->getType()) && !isa<ConstantExpr>(CPV);
+  return isa<ArrayType>(CPV->getType()) && !CPV->isNullValue();
 }
 bool ConstantStruct::classof(const Constant *CPV) {
-  return isa<StructType>(CPV->getType()) && !isa<ConstantExpr>(CPV);
+  return isa<StructType>(CPV->getType()) && !CPV->isNullValue();
 }
 
 bool ConstantPointerNull::classof(const Constant *CPV) {
@@ -765,6 +741,50 @@
   }
 }
 
+//---- ConstantAggregateZero::get() implementation...
+//
+namespace llvm {
+  // ConstantAggregateZero does not take extra "value" argument...
+  template<class ValType>
+  struct ConstantCreator<ConstantAggregateZero, Type, ValType> {
+    static ConstantAggregateZero *create(const Type *Ty, const ValType &V){
+      return new ConstantAggregateZero(Ty);
+    }
+  };
+
+  template<>
+  struct ConvertConstantType<ConstantAggregateZero, Type> {
+    static void convert(ConstantAggregateZero *OldC, const Type *NewTy) {
+      // Make everyone now use a constant of the new type...
+      Constant *New = ConstantAggregateZero::get(NewTy);
+      assert(New != OldC && "Didn't replace constant??");
+      OldC->uncheckedReplaceAllUsesWith(New);
+      OldC->destroyConstant();     // This constant is now dead, destroy it.
+    }
+  };
+}
+
+static ValueMap<char, Type, ConstantAggregateZero> AggZeroConstants;
+
+Constant *ConstantAggregateZero::get(const Type *Ty) {
+  return AggZeroConstants.getOrCreate(Ty, 0);
+}
+
+// destroyConstant - Remove the constant from the constant table...
+//
+void ConstantAggregateZero::destroyConstant() {
+  AggZeroConstants.remove(this);
+  destroyConstantImpl();
+}
+
+void ConstantAggregateZero::replaceUsesOfWithOnConstant(Value *From, Value *To,
+                                                        bool DisableChecking) {
+  assert(0 && "No uses!");
+  abort();
+}
+
+
+
 //---- ConstantArray::get() implementation...
 //
 namespace llvm {
@@ -787,8 +807,17 @@
                 ConstantArray> ArrayConstants;
 
 Constant *ConstantArray::get(const ArrayType *Ty,
-                                  const std::vector<Constant*> &V) {
-  return ArrayConstants.getOrCreate(Ty, V);
+                             const std::vector<Constant*> &V) {
+  // If this is an all-zero array, return a ConstantAggregateZero object
+  if (!V.empty()) {
+    Constant *C = V[0];
+    if (!C->isNullValue())
+      return ArrayConstants.getOrCreate(Ty, V);
+    for (unsigned i = 1, e = V.size(); i != e; ++i)
+      if (V[i] != C)
+        return ArrayConstants.getOrCreate(Ty, V);
+  }
+  return ConstantAggregateZero::get(Ty);
 }
 
 // destroyConstant - Remove the constant from the constant table...
@@ -868,7 +897,12 @@
 
 Constant *ConstantStruct::get(const StructType *Ty,
                               const std::vector<Constant*> &V) {
-  return StructConstants.getOrCreate(Ty, V);
+  // Create a ConstantAggregateZero value if all elements are zeros...
+  for (unsigned i = 0, e = V.size(); i != e; ++i)
+    if (!V[i]->isNullValue())
+      return StructConstants.getOrCreate(Ty, V);
+
+  return ConstantAggregateZero::get(Ty);
 }
 
 // destroyConstant - Remove the constant from the constant table...





More information about the llvm-commits mailing list