Compute and cache information about the storage size and layout
authorVikram S. Adve <vadve@cs.uiuc.edu>
Fri, 20 Jul 2001 21:09:17 +0000 (21:09 +0000)
committerVikram S. Adve <vadve@cs.uiuc.edu>
Fri, 20 Jul 2001 21:09:17 +0000 (21:09 +0000)
of structures.  This information is machine-dependent.

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

include/llvm/DerivedTypes.h
lib/VMCore/Type.cpp

index 31a35b618486b1fe9b6e1e85114fb73d35a8983d..b5eba1114756c6d63e973b0bcda0b10d25bc1bdc 100644 (file)
 #define LLVM_DERIVED_TYPES_H
 
 #include "llvm/Type.h"
-#include <vector>
+#include "llvm/Codegen/TargetMachine.h"
+#include "vector"
+
+class TargetMachine;
+
 
 // Future derived types: SIMD packed format
 
@@ -81,12 +85,20 @@ public:
 class StructType : public Type {
 public:
   typedef vector<const Type*> ElementTypes;
+
 private:
   ElementTypes ETypes;
-
+  struct StructSizeAndOffsetInfo {
+    int storageSize;                   // -1 until the value is computd
+    vector<int> memberOffsets;         // -1 until values are computed 
+    const TargetMachine* targetInfo;
+  }
+  *layoutCache;
+  
+private:
   StructType(const StructType &);                   // Do not implement
   const StructType &operator=(const StructType &);  // Do not implement
-
+  
 protected:
   // This should really be private, but it squelches a bogus warning
   // from GCC to make them protected:  warning: `class StructType' only 
@@ -94,6 +106,10 @@ protected:
 
   // Private ctor - Only can be created by a static member...
   StructType(const vector<const Type*> &Types, const string &Name);
+  
+  // Reset cached info so it will be computed when first requested
+  void ResetCachedInfo() const;
+  
 public:
 
   inline const ElementTypes &getElementTypes() const { return ETypes; }
@@ -101,9 +117,65 @@ public:
   static const StructType *get(const ElementTypes &Params) {
     return getStructType(Params);
   }
+  unsigned int            getStorageSize(const TargetMachine& tmi) const;
+  unsigned int            getElementOffset(int i, const TargetMachine& tmi) const;
 };
 
 
+inline unsigned int
+StructType::getStorageSize(const TargetMachine& tmi) const
+{
+  if (layoutCache->targetInfo != NULL && ! (* layoutCache->targetInfo == tmi))
+    {// target machine has changed (hey it could happen). discard cached info.
+      ResetCachedInfo();
+      layoutCache->targetInfo = &tmi;
+    }
+  
+  if (layoutCache->storageSize < 0)
+    {
+      layoutCache->storageSize = tmi.findOptimalStorageSize(this);
+      assert(layoutCache->storageSize >= 0);
+    }
+  
+  return layoutCache->storageSize;
+}
+
+
+inline unsigned int
+StructType::getElementOffset(int i, const TargetMachine& tmi) const
+{
+  if (layoutCache->targetInfo != NULL && ! (* layoutCache->targetInfo == tmi))
+    {// target machine has changed (hey it could happen). discard cached info.
+      ResetCachedInfo();
+    }
+  
+  if (layoutCache->memberOffsets[i] < 0)
+    {
+      layoutCache->targetInfo = &tmi;  // remember which target was used
+      
+      unsigned int* offsetVec = tmi.findOptimalMemberOffsets(this);
+      for (unsigned i=0, N=layoutCache->memberOffsets.size(); i < N; i++)
+       {
+         layoutCache->memberOffsets[i] = offsetVec[i];
+         assert(layoutCache->memberOffsets[i] >= 0);
+       }
+      delete[] offsetVec; 
+    }
+  
+  return layoutCache->memberOffsets[i];
+}
+
+
+inline void
+StructType::ResetCachedInfo() const
+{
+  layoutCache->storageSize = -1;
+  layoutCache->memberOffsets.insert(layoutCache->memberOffsets.begin(),
+                                   ETypes.size(), -1);
+  layoutCache->targetInfo = NULL;
+}
+
+
 class PointerType : public Type {
 private:
   const Type *ValueType;
index 0b272f0bb57e48370a6b140fee6e2f291caa194c..ef6a892135d67471853ab242defc689e18785e6b 100644 (file)
@@ -143,7 +143,11 @@ ArrayType::ArrayType(const Type *ElType, int NumEl, const string &Name)
 }
 
 StructType::StructType(const vector<const Type*> &Types, const string &Name) 
-  : Type(Name, StructTyID), ETypes(Types) {
+  : Type(Name, StructTyID),
+    ETypes(Types),
+    layoutCache(new StructSizeAndOffsetInfo) 
+{
+  ResetCachedInfo();
 }
 
 PointerType::PointerType(const Type *E)