[CodeGen] Store ElementType in Address

Explicitly track the pointer element type in Address, rather than
deriving it from the pointer type, which will no longer be possible
with opaque pointers. This just adds the basic facility, for now
everything is still going through the deprecated constructors.

I had to adjust one place in the LValue implementation to satisfy
the new assertions: Global registers are represented as a
MetadataAsValue, which does not have a pointer type. We should
avoid using Address in this case.

This implements a part of D103465.

Differential Revision: https://reviews.llvm.org/D115725
This commit is contained in:
Nikita Popov 2021-12-14 14:37:23 +01:00
parent 5816f1855c
commit abbc2e997b
3 changed files with 31 additions and 20 deletions

View File

@ -23,18 +23,28 @@ namespace CodeGen {
/// An aligned address.
class Address {
llvm::Value *Pointer;
llvm::Type *ElementType;
CharUnits Alignment;
protected:
Address(std::nullptr_t) : Pointer(nullptr) {}
Address(std::nullptr_t) : Pointer(nullptr), ElementType(nullptr) {}
public:
Address(llvm::Value *pointer, CharUnits alignment)
: Pointer(pointer), Alignment(alignment) {
Address(llvm::Value *pointer, llvm::Type *elementType, CharUnits alignment)
: Pointer(pointer), ElementType(elementType), Alignment(alignment) {
assert(pointer != nullptr && "Pointer cannot be null");
assert(elementType != nullptr && "Element type cannot be null");
assert(llvm::cast<llvm::PointerType>(pointer->getType())
->isOpaqueOrPointeeTypeMatches(elementType) &&
"Incorrect pointer element type");
assert(!alignment.isZero() && "Alignment cannot be zero");
}
// Deprecated: Use constructor with explicit element type instead.
Address(llvm::Value *Pointer, CharUnits Alignment)
: Address(Pointer, Pointer->getType()->getPointerElementType(),
Alignment) {}
static Address invalid() { return Address(nullptr); }
bool isValid() const { return Pointer != nullptr; }
@ -49,11 +59,9 @@ public:
}
/// Return the type of the values stored in this address.
///
/// When IR pointer types lose their element type, we should simply
/// store it in Address instead for the convenience of writing code.
llvm::Type *getElementType() const {
return getType()->getElementType();
assert(isValid());
return ElementType;
}
/// Return the address space that this address resides in.
@ -79,8 +87,13 @@ class ConstantAddress : public Address {
ConstantAddress(std::nullptr_t) : Address(nullptr) {}
public:
ConstantAddress(llvm::Constant *pointer, llvm::Type *elementType,
CharUnits alignment)
: Address(pointer, elementType, alignment) {}
// Deprecated: Use constructor with explicit element type instead.
ConstantAddress(llvm::Constant *pointer, CharUnits alignment)
: Address(pointer, alignment) {}
: Address(pointer, alignment) {}
static ConstantAddress invalid() {
return ConstantAddress(nullptr);
@ -90,13 +103,10 @@ public:
return llvm::cast<llvm::Constant>(Address::getPointer());
}
ConstantAddress getBitCast(llvm::Type *ty) const {
return ConstantAddress(llvm::ConstantExpr::getBitCast(getPointer(), ty),
getAlignment());
}
ConstantAddress getElementBitCast(llvm::Type *ty) const {
return getBitCast(ty->getPointerTo(getAddressSpace()));
ConstantAddress getElementBitCast(llvm::Type *ElemTy) const {
llvm::Constant *BitCast = llvm::ConstantExpr::getBitCast(
getPointer(), ElemTy->getPointerTo(getAddressSpace()));
return ConstantAddress(BitCast, ElemTy, getAlignment());
}
static bool isaImpl(Address addr) {
@ -104,7 +114,7 @@ public:
}
static ConstantAddress castImpl(Address addr) {
return ConstantAddress(llvm::cast<llvm::Constant>(addr.getPointer()),
addr.getAlignment());
addr.getElementType(), addr.getAlignment());
}
};

View File

@ -2610,7 +2610,7 @@ static LValue EmitGlobalNamedRegister(const VarDecl *VD, CodeGenModule &CGM) {
llvm::Value *Ptr =
llvm::MetadataAsValue::get(CGM.getLLVMContext(), M->getOperand(0));
return LValue::MakeGlobalReg(Address(Ptr, Alignment), VD->getType());
return LValue::MakeGlobalReg(Ptr, Alignment, VD->getType());
}
/// Determine whether we can emit a reference to \p VD from the current

View File

@ -441,11 +441,12 @@ public:
return R;
}
static LValue MakeGlobalReg(Address Reg, QualType type) {
static LValue MakeGlobalReg(llvm::Value *V, CharUnits alignment,
QualType type) {
LValue R;
R.LVType = GlobalReg;
R.V = Reg.getPointer();
R.Initialize(type, type.getQualifiers(), Reg.getAlignment(),
R.V = V;
R.Initialize(type, type.getQualifiers(), alignment,
LValueBaseInfo(AlignmentSource::Decl), TBAAAccessInfo());
return R;
}