================ @@ -355,30 +364,111 @@ class DataLayout { /// \sa DataLayout::getAddressSizeInBits unsigned getAddressSize(unsigned AS) const { return getIndexSize(AS); } - /// Return the address spaces containing non-integral pointers. Pointers in - /// this address space don't have a well-defined bitwise representation. - SmallVector<unsigned, 8> getNonIntegralAddressSpaces() const { + /// Return the address spaces with special pointer semantics (such as being + /// unstable or non-integral). + SmallVector<unsigned, 8> getNonStandardAddressSpaces() const { SmallVector<unsigned, 8> AddrSpaces; for (const PointerSpec &PS : PointerSpecs) { - if (PS.IsNonIntegral) + if (PS.HasUnstableRepresentation || PS.HasExternalState || + PS.BitWidth != PS.IndexBitWidth) AddrSpaces.push_back(PS.AddrSpace); } return AddrSpaces; } + /// Returns whether this address space has a non-integral pointer + /// representation, i.e. the pointer is not just an integer address but some + /// other bitwise representation. When true, passes cannot assume that all + /// bits of the representation map directly to the allocation address. + /// NOTE: This also returns true for "unstable" pointers where the + /// representation may be just an address, but this value can change at any + /// given time (e.g. due to copying garbage collection). + /// Examples include AMDGPU buffer descriptors with a 128-bit fat pointer + /// and a 32-bit offset or CHERI capabilities that contain bounds, permissions + /// and an out-of-band validity bit. + /// + /// In general, more specialized functions such as shouldAvoidIntToPtr(), + /// shouldAvoidPtrToInt(), or hasExternalState() should be preferred over + /// this one when reasoning about the behavior of IR analysis/transforms. + /// TODO: should remove/deprecate this once all uses have migrated. bool isNonIntegralAddressSpace(unsigned AddrSpace) const { - return getPointerSpec(AddrSpace).IsNonIntegral; + const auto &PS = getPointerSpec(AddrSpace); + return PS.BitWidth != PS.IndexBitWidth || PS.HasUnstableRepresentation || + PS.HasExternalState; + } + + /// Returns whether this address space has an "unstable" pointer + /// representation. The bitwise pattern of such pointers is allowed to change + /// in a target-specific way. For example, this could be used for copying + /// garbage collection where the garbage collector could update the pointer + /// value as part of the collection sweep. + bool hasUnstableRepresentation(unsigned AddrSpace) const { + return getPointerSpec(AddrSpace).HasUnstableRepresentation; + } + bool hasUnstableRepresentation(Type *Ty) const { + auto *PTy = dyn_cast<PointerType>(Ty->getScalarType()); + return PTy && hasUnstableRepresentation(PTy->getPointerAddressSpace()); + } + + /// Returns whether this address space has external state (implies having + /// a non-integral pointer representation). + /// These pointer types must be loaded and stored using appropriate + /// instructions and cannot use integer loads/stores as this would not + /// propagate the out-of-band state. An example of such a pointer type is a + /// CHERI capability that contain bounds, permissions and an out-of-band + /// validity bit that is invalidated whenever an integer/FP store is performed + /// to the associated memory location. + bool hasExternalState(unsigned AddrSpace) const { + return getPointerSpec(AddrSpace).HasExternalState; + } + bool hasExternalState(Type *Ty) const { + auto *PTy = dyn_cast<PointerType>(Ty->getScalarType()); + return PTy && hasExternalState(PTy->getPointerAddressSpace()); + } + + /// Returns whether passes should avoid introducing `inttoptr` instructions + /// for this address space. + /// + /// This is currently the case for non-integral pointer representations with + /// external state (hasExternalState()) since `inttoptr` cannot recreate the + /// external state bits. + /// New `inttoptr` instructions should also be avoided for "unstable" bitwise + /// representations (hasUnstableRepresentation()) unless the pass knows it is + /// within a critical section that retains the current representation. + bool shouldAvoidIntToPtr(unsigned AddrSpace) const { ---------------- nikic wrote:
I'm somewhat concerned this will cause more work if we ever add more pointer properties... https://github.com/llvm/llvm-project/pull/105735 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits