[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. /// An aligned address.
class Address { class Address {
llvm::Value *Pointer; llvm::Value *Pointer;
llvm::Type *ElementType;
CharUnits Alignment; CharUnits Alignment;
protected: protected:
Address(std::nullptr_t) : Pointer(nullptr) {} Address(std::nullptr_t) : Pointer(nullptr), ElementType(nullptr) {}
public: public:
Address(llvm::Value *pointer, CharUnits alignment) Address(llvm::Value *pointer, llvm::Type *elementType, CharUnits alignment)
: Pointer(pointer), Alignment(alignment) { : Pointer(pointer), ElementType(elementType), Alignment(alignment) {
assert(pointer != nullptr && "Pointer cannot be null"); 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"); 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); } static Address invalid() { return Address(nullptr); }
bool isValid() const { return Pointer != nullptr; } bool isValid() const { return Pointer != nullptr; }
@ -49,11 +59,9 @@ public:
} }
/// Return the type of the values stored in this address. /// 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 { llvm::Type *getElementType() const {
return getType()->getElementType(); assert(isValid());
return ElementType;
} }
/// Return the address space that this address resides in. /// Return the address space that this address resides in.
@ -79,6 +87,11 @@ class ConstantAddress : public Address {
ConstantAddress(std::nullptr_t) : Address(nullptr) {} ConstantAddress(std::nullptr_t) : Address(nullptr) {}
public: 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) ConstantAddress(llvm::Constant *pointer, CharUnits alignment)
: Address(pointer, alignment) {} : Address(pointer, alignment) {}
@ -90,13 +103,10 @@ public:
return llvm::cast<llvm::Constant>(Address::getPointer()); return llvm::cast<llvm::Constant>(Address::getPointer());
} }
ConstantAddress getBitCast(llvm::Type *ty) const { ConstantAddress getElementBitCast(llvm::Type *ElemTy) const {
return ConstantAddress(llvm::ConstantExpr::getBitCast(getPointer(), ty), llvm::Constant *BitCast = llvm::ConstantExpr::getBitCast(
getAlignment()); getPointer(), ElemTy->getPointerTo(getAddressSpace()));
} return ConstantAddress(BitCast, ElemTy, getAlignment());
ConstantAddress getElementBitCast(llvm::Type *ty) const {
return getBitCast(ty->getPointerTo(getAddressSpace()));
} }
static bool isaImpl(Address addr) { static bool isaImpl(Address addr) {
@ -104,7 +114,7 @@ public:
} }
static ConstantAddress castImpl(Address addr) { static ConstantAddress castImpl(Address addr) {
return ConstantAddress(llvm::cast<llvm::Constant>(addr.getPointer()), 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::Value *Ptr =
llvm::MetadataAsValue::get(CGM.getLLVMContext(), M->getOperand(0)); 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 /// Determine whether we can emit a reference to \p VD from the current

View File

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