[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