[llvm-commits] [llvm] r89176 - in /llvm/trunk: include/llvm/Target/TargetData.h lib/Target/TargetData.cpp

Bill Wendling wendling at apple.com
Tue Nov 17 17:07:52 PST 2009


The nature of this problem doesn't lend itself to a testcase,  
unfortunately. For instance, the testcase I got (from clang code)  
*passed* if I removed blank lines from the file.

-bw

On Nov 17, 2009, at 5:03 PM, Bill Wendling wrote:

> Author: void
> Date: Tue Nov 17 19:03:56 2009
> New Revision: 89176
>
> URL: http://llvm.org/viewvc/llvm-project?rev=89176&view=rev
> Log:
> The llvm-gcc front-end and the pass manager use two separate  
> TargetData objects.
> This is probably not confined to *just* these two things.
>
> Anyway, the llvm-gcc front-end may look up the structure layout  
> information for
> an abstract type. That information will be stored into a table with  
> the FE's
> TD. Instruction combine can come along and also ask for information  
> on that
> abstract type, but for a separate TD (the one associated with the  
> pass manager).
>
> After the type is refined, the old structure layout information in  
> the pass
> manager's TD file is out of date. If a new type is allocated in the  
> same space
> as the old-unrefined type, then the structure type information in  
> the pass
> manager's TD file will be wrong, but won't know it.
>
> Fix this by making the TD's structure type information an abstract  
> type user.
>
> Modified:
>    llvm/trunk/include/llvm/Target/TargetData.h
>    llvm/trunk/lib/Target/TargetData.cpp
>
> Modified: llvm/trunk/include/llvm/Target/TargetData.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetData.h?rev=89176&r1=89175&r2=89176&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/include/llvm/Target/TargetData.h (original)
> +++ llvm/trunk/include/llvm/Target/TargetData.h Tue Nov 17 19:03:56  
> 2009
> @@ -30,6 +30,7 @@
> class IntegerType;
> class StructType;
> class StructLayout;
> +class StructLayoutMap;
> class GlobalVariable;
> class LLVMContext;
>
> @@ -84,8 +85,8 @@
>   /// type and bit width were not found in the SmallVector.
>   static const TargetAlignElem InvalidAlignmentElem;
>
> -  // Opaque pointer for the StructType -> StructLayout map.
> -  mutable void *LayoutMap;
> +  // The StructType -> StructLayout map.
> +  mutable StructLayoutMap *LayoutMap;
>
>   //! Set/initialize target alignments
>   void setAlignment(AlignTypeEnum align_type, unsigned char abi_align,
>
> Modified: llvm/trunk/lib/Target/TargetData.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetData.cpp?rev=89176&r1=89175&r2=89176&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/Target/TargetData.cpp (original)
> +++ llvm/trunk/lib/Target/TargetData.cpp Tue Nov 17 19:03:56 2009
> @@ -17,9 +17,9 @@
> // 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
>
> #include "llvm/Target/TargetData.h"
> -#include "llvm/Module.h"
> -#include "llvm/DerivedTypes.h"
> #include "llvm/Constants.h"
> +#include "llvm/DerivedTypes.h"
> +#include "llvm/Module.h"
> #include "llvm/Support/GetElementPtrTypeIterator.h"
> #include "llvm/Support/MathExtras.h"
> #include "llvm/Support/ManagedStatic.h"
> @@ -323,37 +323,130 @@
>                  : Alignments[BestMatchIdx].PrefAlign;
> }
>
> -typedef DenseMap<const StructType*, StructLayout*>LayoutInfoTy;
> +typedef DenseMap<const StructType*, StructLayout*> LayoutInfoTy;
>
> -TargetData::~TargetData() {
> -  if (!LayoutMap)
> -    return;
> -
> -  // Remove any layouts for this TD.
> -  LayoutInfoTy &TheMap = *static_cast<LayoutInfoTy*>(LayoutMap);
> -  for (LayoutInfoTy::iterator I = TheMap.begin(), E = TheMap.end();  
> I != E; ) {
> -    I->second->~StructLayout();
> -    free(I->second);
> -    TheMap.erase(I++);
> +namespace llvm {
> +
> +class StructLayoutMap : public AbstractTypeUser {
> +  LayoutInfoTy LayoutInfo;
> +
> +  /// refineAbstractType - The callback method invoked when an  
> abstract type is
> +  /// resolved to another type.  An object must override this  
> method to update
> +  /// its internal state to reference NewType instead of OldType.
> +  ///
> +  virtual void refineAbstractType(const DerivedType *OldTy,
> +                                  const Type *) {
> +    const StructType *STy = dyn_cast<const StructType>(OldTy);
> +    if (!STy) {
> +      OldTy->removeAbstractTypeUser(this);
> +      return;
> +    }
> +
> +    StructLayout *SL = LayoutInfo[STy];
> +    if (SL) {
> +      SL->~StructLayout();
> +      free(SL);
> +      LayoutInfo[STy] = NULL;
> +    }
> +
> +    OldTy->removeAbstractTypeUser(this);
>   }
> -
> -  delete static_cast<LayoutInfoTy*>(LayoutMap);
> +
> +  /// typeBecameConcrete - The other case which AbstractTypeUsers  
> must be aware
> +  /// of is when a type makes the transition from being abstract  
> (where it has
> +  /// clients on its AbstractTypeUsers list) to concrete (where it  
> does not).
> +  /// This method notifies ATU's when this occurs for a type.
> +  ///
> +  virtual void typeBecameConcrete(const DerivedType *AbsTy) {
> +    const StructType *STy = dyn_cast<const StructType>(AbsTy);
> +    if (!STy) {
> +      AbsTy->removeAbstractTypeUser(this);
> +      return;
> +    }
> +
> +    StructLayout *SL = LayoutInfo[STy];
> +    if (SL) {
> +      SL->~StructLayout();
> +      free(SL);
> +      LayoutInfo[STy] = NULL;
> +    }
> +
> +    AbsTy->removeAbstractTypeUser(this);
> +  }
> +
> +  bool insert(const Type *Ty) {
> +    if (Ty->isAbstract())
> +      Ty->addAbstractTypeUser(this);
> +    return true;
> +  }
> +
> +public:
> +  virtual ~StructLayoutMap() {
> +    // Remove any layouts.
> +    for (LayoutInfoTy::iterator
> +           I = LayoutInfo.begin(), E = LayoutInfo.end(); I != E; ++I)
> +      if (StructLayout *SL = I->second) {
> +        SL->~StructLayout();
> +        free(SL);
> +      }
> +  }
> +
> +  inline LayoutInfoTy::iterator begin() {
> +    return LayoutInfo.begin();
> +  }
> +  inline LayoutInfoTy::iterator end() {
> +    return LayoutInfo.end();
> +  }
> +  inline LayoutInfoTy::const_iterator begin() const {
> +    return LayoutInfo.begin();
> +  }
> +  inline LayoutInfoTy::const_iterator end() const {
> +    return LayoutInfo.end();
> +  }
> +
> +  LayoutInfoTy::iterator find(const StructType *&Val) {
> +    return LayoutInfo.find(Val);
> +  }
> +  LayoutInfoTy::const_iterator find(const StructType *&Val) const {
> +    return LayoutInfo.find(Val);
> +  }
> +
> +  bool erase(const StructType *&Val) {
> +    return LayoutInfo.erase(Val);
> +  }
> +  bool erase(LayoutInfoTy::iterator I) {
> +    return LayoutInfo.erase(I);
> +  }
> +
> +  StructLayout *&operator[](const Type *Key) {
> +    const StructType *STy = dyn_cast<const StructType>(Key);
> +    assert(STy && "Trying to access the struct layout map with a  
> non-struct!");
> +    insert(STy);
> +    return LayoutInfo[STy];
> +  }
> +
> +  // for debugging...
> +  virtual void dump() const {}
> +};
> +
> +} // end namespace llvm
> +
> +TargetData::~TargetData() {
> +  delete LayoutMap;
> }
>
> const StructLayout *TargetData::getStructLayout(const StructType  
> *Ty) const {
>   if (!LayoutMap)
> -    LayoutMap = static_cast<void*>(new LayoutInfoTy());
> -
> -  LayoutInfoTy &TheMap = *static_cast<LayoutInfoTy*>(LayoutMap);
> +    LayoutMap = new StructLayoutMap();
>
> -  StructLayout *&SL = TheMap[Ty];
> +  StructLayout *&SL = (*LayoutMap)[Ty];
>   if (SL) return SL;
>
>   // Otherwise, create the struct layout.  Because it is variable  
> length, we
>   // malloc it, then use placement new.
>   int NumElts = Ty->getNumElements();
>   StructLayout *L =
> -    (StructLayout *)malloc(sizeof(StructLayout)+(NumElts-1)*sizeof 
> (uint64_t));
> +    (StructLayout *)malloc(sizeof(StructLayout)+(NumElts-1) * sizeof 
> (uint64_t));
>
>   // Set SL before calling StructLayout's ctor.  The ctor could  
> cause other
>   // entries to be added to TheMap, invalidating our reference.
> @@ -370,13 +463,12 @@
> void TargetData::InvalidateStructLayoutInfo(const StructType *Ty)  
> const {
>   if (!LayoutMap) return;  // No cache.
>
> -  LayoutInfoTy* LayoutInfo = static_cast<LayoutInfoTy*>(LayoutMap);
> -  LayoutInfoTy::iterator I = LayoutInfo->find(Ty);
> -  if (I == LayoutInfo->end()) return;
> +  DenseMap<const StructType*, StructLayout*>::iterator I =  
> LayoutMap->find(Ty);
> +  if (I == LayoutMap->end()) return;
>
>   I->second->~StructLayout();
>   free(I->second);
> -  LayoutInfo->erase(I);
> +  LayoutMap->erase(I);
> }
>
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list