Skip to content

Commit

Permalink
[clang][TargetInfo] Use LangAS for getPointer{Width,Align}()
Browse files Browse the repository at this point in the history
Mixing LLVM and Clang address spaces can result in subtle bugs, and there
is no need for this hook to use the LLVM IR level address spaces.
Most of this change is just replacing zero with LangAS::Default,
but it also allows us to remove a few calls to getTargetAddressSpace().

This also removes a stale comment+workaround in
CGDebugInfo::CreatePointerLikeType(): ASTContext::getTypeSize() does
return the expected size for ReferenceType (and handles address spaces).

Differential Revision: https://reviews.llvm.org/D138295
  • Loading branch information
arichardson committed Nov 30, 2022
1 parent 57b1c02 commit a602f76
Show file tree
Hide file tree
Showing 34 changed files with 164 additions and 149 deletions.
35 changes: 23 additions & 12 deletions clang/include/clang/Basic/TargetInfo.h
Expand Up @@ -357,10 +357,11 @@ class TargetInfo : public virtual TransferrableTargetInfo,
IntType getUIntMaxType() const {
return getCorrespondingUnsignedType(IntMaxType);
}
IntType getPtrDiffType(unsigned AddrSpace) const {
return AddrSpace == 0 ? PtrDiffType : getPtrDiffTypeV(AddrSpace);
IntType getPtrDiffType(LangAS AddrSpace) const {
return AddrSpace == LangAS::Default ? PtrDiffType
: getPtrDiffTypeV(AddrSpace);
}
IntType getUnsignedPtrDiffType(unsigned AddrSpace) const {
IntType getUnsignedPtrDiffType(LangAS AddrSpace) const {
return getCorrespondingUnsignedType(getPtrDiffType(AddrSpace));
}
IntType getIntPtrType() const { return IntPtrType; }
Expand Down Expand Up @@ -438,11 +439,13 @@ class TargetInfo : public virtual TransferrableTargetInfo,

/// Return the width of pointers on this target, for the
/// specified address space.
uint64_t getPointerWidth(unsigned AddrSpace) const {
return AddrSpace == 0 ? PointerWidth : getPointerWidthV(AddrSpace);
uint64_t getPointerWidth(LangAS AddrSpace) const {
return AddrSpace == LangAS::Default ? PointerWidth
: getPointerWidthV(AddrSpace);
}
uint64_t getPointerAlign(unsigned AddrSpace) const {
return AddrSpace == 0 ? PointerAlign : getPointerAlignV(AddrSpace);
uint64_t getPointerAlign(LangAS AddrSpace) const {
return AddrSpace == LangAS::Default ? PointerAlign
: getPointerAlignV(AddrSpace);
}

/// Return the maximum width of pointers on this target.
Expand Down Expand Up @@ -604,7 +607,8 @@ class TargetInfo : public virtual TransferrableTargetInfo,

/// Determine whether the __int128 type is supported on this target.
virtual bool hasInt128Type() const {
return (getPointerWidth(0) >= 64) || getTargetOpts().ForceEnableInt128;
return (getPointerWidth(LangAS::Default) >= 64) ||
getTargetOpts().ForceEnableInt128;
} // FIXME

/// Determine whether the _BitInt type is supported on this target. This
Expand Down Expand Up @@ -822,7 +826,9 @@ class TargetInfo : public virtual TransferrableTargetInfo,
unsigned getProgramAddressSpace() const { return ProgramAddrSpace; }

// Return the size of unwind_word for this target.
virtual unsigned getUnwindWordWidth() const { return getPointerWidth(0); }
virtual unsigned getUnwindWordWidth() const {
return getPointerWidth(LangAS::Default);
}

/// Return the "preferred" register width on this target.
virtual unsigned getRegisterWidth() const {
Expand Down Expand Up @@ -1485,6 +1491,11 @@ class TargetInfo : public virtual TransferrableTargetInfo,
}

const LangASMap &getAddressSpaceMap() const { return *AddrSpaceMap; }
unsigned getTargetAddressSpace(LangAS AS) const {
if (isTargetAddressSpace(AS))
return toTargetAddressSpace(AS);
return getAddressSpaceMap()[(unsigned)AS];
}

/// Map from the address space field in builtin description strings to the
/// language address space.
Expand Down Expand Up @@ -1685,13 +1696,13 @@ class TargetInfo : public virtual TransferrableTargetInfo,
protected:
/// Copy type and layout related info.
void copyAuxTarget(const TargetInfo *Aux);
virtual uint64_t getPointerWidthV(unsigned AddrSpace) const {
virtual uint64_t getPointerWidthV(LangAS AddrSpace) const {
return PointerWidth;
}
virtual uint64_t getPointerAlignV(unsigned AddrSpace) const {
virtual uint64_t getPointerAlignV(LangAS AddrSpace) const {
return PointerAlign;
}
virtual enum IntType getPtrDiffTypeV(unsigned AddrSpace) const {
virtual enum IntType getPtrDiffTypeV(LangAS AddrSpace) const {
return PtrDiffType;
}
virtual ArrayRef<const char *> getGCCRegNames() const = 0;
Expand Down
36 changes: 18 additions & 18 deletions clang/lib/AST/ASTContext.cpp
Expand Up @@ -1879,7 +1879,7 @@ static getConstantArrayInfoInChars(const ASTContext &Context,
uint64_t Width = EltInfo.Width.getQuantity() * Size;
unsigned Align = EltInfo.Align.getQuantity();
if (!Context.getTargetInfo().getCXXABI().isMicrosoft() ||
Context.getTargetInfo().getPointerWidth(0) == 64)
Context.getTargetInfo().getPointerWidth(LangAS::Default) == 64)
Width = llvm::alignTo(Width, Align);
return TypeInfoChars(CharUnits::fromQuantity(Width),
CharUnits::fromQuantity(Align),
Expand Down Expand Up @@ -1990,7 +1990,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
uint64_t Width = 0;
unsigned Align = 8;
AlignRequirementKind AlignRequirement = AlignRequirementKind::None;
unsigned AS = 0;
LangAS AS = LangAS::Default;
switch (T->getTypeClass()) {
#define TYPE(Class, Base)
#define ABSTRACT_TYPE(Class, Base)
Expand Down Expand Up @@ -2025,7 +2025,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
Align = EltInfo.Align;
AlignRequirement = EltInfo.AlignRequirement;
if (!getTargetInfo().getCXXABI().isMicrosoft() ||
getTargetInfo().getPointerWidth(0) == 64)
getTargetInfo().getPointerWidth(LangAS::Default) == 64)
Width = llvm::alignTo(Width, Align);
break;
}
Expand Down Expand Up @@ -2225,14 +2225,15 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
}
break;
case BuiltinType::NullPtr:
Width = Target->getPointerWidth(0); // C++ 3.9.1p11: sizeof(nullptr_t)
Align = Target->getPointerAlign(0); // == sizeof(void*)
// C++ 3.9.1p11: sizeof(nullptr_t) == sizeof(void*)
Width = Target->getPointerWidth(LangAS::Default);
Align = Target->getPointerAlign(LangAS::Default);
break;
case BuiltinType::ObjCId:
case BuiltinType::ObjCClass:
case BuiltinType::ObjCSel:
Width = Target->getPointerWidth(0);
Align = Target->getPointerAlign(0);
Width = Target->getPointerWidth(LangAS::Default);
Align = Target->getPointerAlign(LangAS::Default);
break;
case BuiltinType::OCLSampler:
case BuiltinType::OCLEvent:
Expand All @@ -2245,8 +2246,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
case BuiltinType::Id:
#include "clang/Basic/OpenCLExtensionTypes.def"
AS = getTargetAddressSpace(
Target->getOpenCLTypeAddrSpace(getOpenCLTypeKind(T)));
AS = Target->getOpenCLTypeAddrSpace(getOpenCLTypeKind(T));
Width = Target->getPointerWidth(AS);
Align = Target->getPointerAlign(AS);
break;
Expand Down Expand Up @@ -2291,24 +2291,24 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
}
break;
case Type::ObjCObjectPointer:
Width = Target->getPointerWidth(0);
Align = Target->getPointerAlign(0);
Width = Target->getPointerWidth(LangAS::Default);
Align = Target->getPointerAlign(LangAS::Default);
break;
case Type::BlockPointer:
AS = getTargetAddressSpace(cast<BlockPointerType>(T)->getPointeeType());
AS = cast<BlockPointerType>(T)->getPointeeType().getAddressSpace();
Width = Target->getPointerWidth(AS);
Align = Target->getPointerAlign(AS);
break;
case Type::LValueReference:
case Type::RValueReference:
// alignof and sizeof should never enter this code path here, so we go
// the pointer route.
AS = getTargetAddressSpace(cast<ReferenceType>(T)->getPointeeType());
AS = cast<ReferenceType>(T)->getPointeeType().getAddressSpace();
Width = Target->getPointerWidth(AS);
Align = Target->getPointerAlign(AS);
break;
case Type::Pointer:
AS = getTargetAddressSpace(cast<PointerType>(T)->getPointeeType());
AS = cast<PointerType>(T)->getPointeeType().getAddressSpace();
Width = Target->getPointerWidth(AS);
Align = Target->getPointerAlign(AS);
break;
Expand Down Expand Up @@ -2465,8 +2465,8 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
break;

case Type::Pipe:
Width = Target->getPointerWidth(getTargetAddressSpace(LangAS::opencl_global));
Align = Target->getPointerAlign(getTargetAddressSpace(LangAS::opencl_global));
Width = Target->getPointerWidth(LangAS::opencl_global);
Align = Target->getPointerAlign(LangAS::opencl_global);
break;
}

Expand Down Expand Up @@ -5975,14 +5975,14 @@ QualType ASTContext::getUIntPtrType() const {
/// getPointerDiffType - Return the unique type for "ptrdiff_t" (C99 7.17)
/// defined in <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9).
QualType ASTContext::getPointerDiffType() const {
return getFromTargetType(Target->getPtrDiffType(0));
return getFromTargetType(Target->getPtrDiffType(LangAS::Default));
}

/// Return the unique unsigned counterpart of "ptrdiff_t"
/// integer type. The standard (C11 7.21.6.1p7) refers to this type
/// in the definition of %tu format specifier.
QualType ASTContext::getUnsignedPointerDiffType() const {
return getFromTargetType(Target->getUnsignedPtrDiffType(0));
return getFromTargetType(Target->getUnsignedPtrDiffType(LangAS::Default));
}

/// Return the unique type for "pid_t" defined in
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/AST/ItaniumCXXABI.cpp
Expand Up @@ -224,7 +224,7 @@ class ItaniumCXXABI : public CXXABI {
MemberPointerInfo
getMemberPointerInfo(const MemberPointerType *MPT) const override {
const TargetInfo &Target = Context.getTargetInfo();
TargetInfo::IntType PtrDiff = Target.getPtrDiffType(0);
TargetInfo::IntType PtrDiff = Target.getPtrDiffType(LangAS::Default);
MemberPointerInfo MPI;
MPI.Width = Target.getTypeWidth(PtrDiff);
MPI.Align = Target.getTypeAlign(PtrDiff);
Expand All @@ -251,8 +251,8 @@ class ItaniumCXXABI : public CXXABI {
return false;

const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
CharUnits PointerSize =
Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0));
CharUnits PointerSize = Context.toCharUnitsFromBits(
Context.getTargetInfo().getPointerWidth(LangAS::Default));
return Layout.getNonVirtualSize() == PointerSize;
}

Expand Down
8 changes: 4 additions & 4 deletions clang/lib/AST/Mangle.cpp
Expand Up @@ -223,18 +223,18 @@ void MangleContext::mangleName(GlobalDecl GD, raw_ostream &Out) {
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD))
if (!MD->isStatic())
++ArgWords;
uint64_t DefaultPtrWidth = TI.getPointerWidth(LangAS::Default);
for (const auto &AT : Proto->param_types()) {
// If an argument type is incomplete there is no way to get its size to
// correctly encode into the mangling scheme.
// Follow GCCs behaviour by simply breaking out of the loop.
if (AT->isIncompleteType())
break;
// Size should be aligned to pointer size.
ArgWords +=
llvm::alignTo(ASTContext.getTypeSize(AT), TI.getPointerWidth(0)) /
TI.getPointerWidth(0);
ArgWords += llvm::alignTo(ASTContext.getTypeSize(AT), DefaultPtrWidth) /
DefaultPtrWidth;
}
Out << ((TI.getPointerWidth(0) / 8) * ArgWords);
Out << ((DefaultPtrWidth / 8) * ArgWords);
}

void MangleContext::mangleMSGuidDecl(const MSGuidDecl *GD, raw_ostream &Out) {
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/AST/MicrosoftCXXABI.cpp
Expand Up @@ -303,7 +303,7 @@ CXXABI::MemberPointerInfo MicrosoftCXXABI::getMemberPointerInfo(
// The nominal struct is laid out with pointers followed by ints and aligned
// to a pointer width if any are present and an int width otherwise.
const TargetInfo &Target = Context.getTargetInfo();
unsigned PtrSize = Target.getPointerWidth(0);
unsigned PtrSize = Target.getPointerWidth(LangAS::Default);
unsigned IntSize = Target.getIntWidth();

unsigned Ptrs, Ints;
Expand All @@ -318,7 +318,7 @@ CXXABI::MemberPointerInfo MicrosoftCXXABI::getMemberPointerInfo(
if (Ptrs + Ints > 1 && Target.getTriple().isArch32Bit())
MPI.Align = 64;
else if (Ptrs)
MPI.Align = Target.getPointerAlign(0);
MPI.Align = Target.getPointerAlign(LangAS::Default);
else
MPI.Align = Target.getIntAlign();

Expand Down
14 changes: 7 additions & 7 deletions clang/lib/AST/MicrosoftMangle.cpp
Expand Up @@ -340,22 +340,22 @@ class MicrosoftCXXNameMangler {
MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_)
: Context(C), Out(Out_), Structor(nullptr), StructorType(-1),
TemplateArgStringStorage(TemplateArgStringStorageAlloc),
PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) ==
64) {}
PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(
LangAS::Default) == 64) {}

MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_,
const CXXConstructorDecl *D, CXXCtorType Type)
: Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),
TemplateArgStringStorage(TemplateArgStringStorageAlloc),
PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) ==
64) {}
PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(
LangAS::Default) == 64) {}

MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_,
const CXXDestructorDecl *D, CXXDtorType Type)
: Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),
TemplateArgStringStorage(TemplateArgStringStorageAlloc),
PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) ==
64) {}
PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(
LangAS::Default) == 64) {}

raw_ostream &getStream() const { return Out; }

Expand Down Expand Up @@ -776,7 +776,7 @@ void MicrosoftCXXNameMangler::mangleVirtualMemPtrThunk(
const CXXMethodDecl *MD, const MethodVFTableLocation &ML) {
// Get the vftable offset.
CharUnits PointerWidth = getASTContext().toCharUnitsFromBits(
getASTContext().getTargetInfo().getPointerWidth(0));
getASTContext().getTargetInfo().getPointerWidth(LangAS::Default));
uint64_t OffsetInVFTable = ML.Index * PointerWidth.getQuantity();

Out << "?_9";
Expand Down
25 changes: 10 additions & 15 deletions clang/lib/AST/RecordLayoutBuilder.cpp
Expand Up @@ -1059,10 +1059,10 @@ void ItaniumRecordLayoutBuilder::LayoutNonVirtualBases(
// primary base, add it in now.
} else if (RD->isDynamicClass()) {
assert(DataSize == 0 && "Vtable pointer must be at offset zero!");
CharUnits PtrWidth =
Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0));
CharUnits PtrAlign =
Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerAlign(0));
CharUnits PtrWidth = Context.toCharUnitsFromBits(
Context.getTargetInfo().getPointerWidth(LangAS::Default));
CharUnits PtrAlign = Context.toCharUnitsFromBits(
Context.getTargetInfo().getPointerAlign(LangAS::Default));
EnsureVTablePointerAlignment(PtrAlign);
HasOwnVFPtr = true;

Expand Down Expand Up @@ -1911,12 +1911,6 @@ void ItaniumRecordLayoutBuilder::LayoutField(const FieldDecl *D,

if (D->getType()->isIncompleteArrayType()) {
setDeclInfo(true /* IsIncompleteArrayType */);
} else if (const ReferenceType *RT = D->getType()->getAs<ReferenceType>()) {
unsigned AS = Context.getTargetAddressSpace(RT->getPointeeType());
EffectiveFieldSize = FieldSize = Context.toCharUnitsFromBits(
Context.getTargetInfo().getPointerWidth(AS));
FieldAlign = Context.toCharUnitsFromBits(
Context.getTargetInfo().getPointerAlign(AS));
} else {
setDeclInfo(false /* IsIncompleteArrayType */);

Expand Down Expand Up @@ -2768,7 +2762,8 @@ void MicrosoftRecordLayoutBuilder::initializeLayout(const RecordDecl *RD) {
// than the pointer size.
if (const MaxFieldAlignmentAttr *MFAA = RD->getAttr<MaxFieldAlignmentAttr>()){
unsigned PackedAlignment = MFAA->getAlignment();
if (PackedAlignment <= Context.getTargetInfo().getPointerWidth(0))
if (PackedAlignment <=
Context.getTargetInfo().getPointerWidth(LangAS::Default))
MaxFieldAlignment = Context.toCharUnitsFromBits(PackedAlignment);
}
// Packed attribute forces max field alignment to be 1.
Expand All @@ -2793,10 +2788,10 @@ MicrosoftRecordLayoutBuilder::initializeCXXLayout(const CXXRecordDecl *RD) {
SharedVBPtrBase = nullptr;
// Calculate pointer size and alignment. These are used for vfptr and vbprt
// injection.
PointerInfo.Size =
Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0));
PointerInfo.Alignment =
Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerAlign(0));
PointerInfo.Size = Context.toCharUnitsFromBits(
Context.getTargetInfo().getPointerWidth(LangAS::Default));
PointerInfo.Alignment = Context.toCharUnitsFromBits(
Context.getTargetInfo().getPointerAlign(LangAS::Default));
// Respect pragma pack.
if (!MaxFieldAlignment.isZero())
PointerInfo.Alignment = std::min(PointerInfo.Alignment, MaxFieldAlignment);
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/AST/VTableBuilder.cpp
Expand Up @@ -670,8 +670,9 @@ CharUnits VCallAndVBaseOffsetBuilder::getCurrentOffsetOffset() const {
// Under the relative ABI, the offset widths are 32-bit ints instead of
// pointer widths.
CharUnits OffsetWidth = Context.toCharUnitsFromBits(
VTables.isRelativeLayout() ? 32
: Context.getTargetInfo().getPointerWidth(0));
VTables.isRelativeLayout()
? 32
: Context.getTargetInfo().getPointerWidth(LangAS::Default));
CharUnits OffsetOffset = OffsetWidth * OffsetIndex;

return OffsetOffset;
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Basic/Targets/AMDGPU.cpp
Expand Up @@ -370,8 +370,8 @@ AMDGPUTargetInfo::AMDGPUTargetInfo(const llvm::Triple &Triple,
WavefrontSize = GPUFeatures & llvm::AMDGPU::FEATURE_WAVE32 ? 32 : 64;
AllowAMDGPUUnsafeFPAtomics = Opts.AllowAMDGPUUnsafeFPAtomics;

// Set pointer width and alignment for target address space 0.
PointerWidth = PointerAlign = getPointerWidthV(Generic);
// Set pointer width and alignment for the generic address space.
PointerWidth = PointerAlign = getPointerWidthV(LangAS::Default);
if (getMaxPointerWidth() == 64) {
LongWidth = LongAlign = 64;
SizeType = UnsignedLong;
Expand Down
7 changes: 4 additions & 3 deletions clang/lib/Basic/Targets/AMDGPU.h
Expand Up @@ -95,17 +95,18 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo {

void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override;

uint64_t getPointerWidthV(unsigned AddrSpace) const override {
uint64_t getPointerWidthV(LangAS AS) const override {
if (isR600(getTriple()))
return 32;
unsigned TargetAS = getTargetAddressSpace(AS);

if (AddrSpace == Private || AddrSpace == Local)
if (TargetAS == Private || TargetAS == Local)
return 32;

return 64;
}

uint64_t getPointerAlignV(unsigned AddrSpace) const override {
uint64_t getPointerAlignV(LangAS AddrSpace) const override {
return getPointerWidthV(AddrSpace);
}

Expand Down

0 comments on commit a602f76

Please sign in to comment.