[CodeGen] Avoid some pointer element type accesses

This avoids some pointer element type accesses when compiling
C++ code.
This commit is contained in:
Nikita Popov 2021-12-20 16:17:27 +01:00
parent f2f6d09185
commit e751d97863
7 changed files with 51 additions and 33 deletions

View File

@ -79,6 +79,18 @@ public:
assert(isValid());
return Alignment;
}
/// Return address with different pointer, but same element type and
/// alignment.
Address withPointer(llvm::Value *NewPointer) const {
return Address(NewPointer, ElementType, Alignment);
}
/// Return address with different alignment, but same pointer and element
/// type.
Address withAlignment(CharUnits NewAlignment) const {
return Address(Pointer, ElementType, NewAlignment);
}
};
/// A specialization of Address that requires the address to be an

View File

@ -326,9 +326,9 @@ Address CodeGenFunction::GetAddressOfBaseClass(
}
// Get the base pointer type.
llvm::Type *BaseValueTy = ConvertType((PathEnd[-1])->getType());
llvm::Type *BasePtrTy =
ConvertType((PathEnd[-1])->getType())
->getPointerTo(Value.getType()->getPointerAddressSpace());
BaseValueTy->getPointerTo(Value.getType()->getPointerAddressSpace());
QualType DerivedTy = getContext().getRecordType(Derived);
CharUnits DerivedAlign = CGM.getClassPointerAlignment(Derived);
@ -342,7 +342,7 @@ Address CodeGenFunction::GetAddressOfBaseClass(
EmitTypeCheck(TCK_Upcast, Loc, Value.getPointer(),
DerivedTy, DerivedAlign, SkippedChecks);
}
return Builder.CreateBitCast(Value, BasePtrTy);
return Builder.CreateElementBitCast(Value, BaseValueTy);
}
llvm::BasicBlock *origBB = nullptr;
@ -379,7 +379,7 @@ Address CodeGenFunction::GetAddressOfBaseClass(
VirtualOffset, Derived, VBase);
// Cast to the destination type.
Value = Builder.CreateBitCast(Value, BasePtrTy);
Value = Builder.CreateElementBitCast(Value, BaseValueTy);
// Build a phi if we needed a null check.
if (NullCheckValue) {
@ -406,16 +406,16 @@ CodeGenFunction::GetAddressOfDerivedClass(Address BaseAddr,
QualType DerivedTy =
getContext().getCanonicalType(getContext().getTagDeclType(Derived));
unsigned AddrSpace =
BaseAddr.getPointer()->getType()->getPointerAddressSpace();
llvm::Type *DerivedPtrTy = ConvertType(DerivedTy)->getPointerTo(AddrSpace);
unsigned AddrSpace = BaseAddr.getAddressSpace();
llvm::Type *DerivedValueTy = ConvertType(DerivedTy);
llvm::Type *DerivedPtrTy = DerivedValueTy->getPointerTo(AddrSpace);
llvm::Value *NonVirtualOffset =
CGM.GetNonVirtualBaseClassOffset(Derived, PathBegin, PathEnd);
if (!NonVirtualOffset) {
// No offset, we can just cast back.
return Builder.CreateBitCast(BaseAddr, DerivedPtrTy);
return Builder.CreateElementBitCast(BaseAddr, DerivedValueTy);
}
llvm::BasicBlock *CastNull = nullptr;
@ -453,7 +453,7 @@ CodeGenFunction::GetAddressOfDerivedClass(Address BaseAddr,
Value = PHI;
}
return Address(Value, CGM.getClassPointerAlignment(Derived));
return Address(Value, DerivedValueTy, CGM.getClassPointerAlignment(Derived));
}
llvm::Value *CodeGenFunction::GetVTTParameter(GlobalDecl GD,

View File

@ -400,8 +400,8 @@ void CodeGenFunction::EmitAnyExprToExn(const Expr *e, Address addr) {
// __cxa_allocate_exception returns a void*; we need to cast this
// to the appropriate type for the object.
llvm::Type *ty = ConvertTypeForMem(e->getType())->getPointerTo();
Address typedAddr = Builder.CreateBitCast(addr, ty);
llvm::Type *ty = ConvertTypeForMem(e->getType());
Address typedAddr = Builder.CreateElementBitCast(addr, ty);
// FIXME: this isn't quite right! If there's a final unelided call
// to a copy constructor, then according to [except.terminate]p1 we
@ -421,13 +421,13 @@ void CodeGenFunction::EmitAnyExprToExn(const Expr *e, Address addr) {
Address CodeGenFunction::getExceptionSlot() {
if (!ExceptionSlot)
ExceptionSlot = CreateTempAlloca(Int8PtrTy, "exn.slot");
return Address(ExceptionSlot, getPointerAlign());
return Address(ExceptionSlot, Int8PtrTy, getPointerAlign());
}
Address CodeGenFunction::getEHSelectorSlot() {
if (!EHSelectorSlot)
EHSelectorSlot = CreateTempAlloca(Int32Ty, "ehselector.slot");
return Address(EHSelectorSlot, CharUnits::fromQuantity(4));
return Address(EHSelectorSlot, Int32Ty, CharUnits::fromQuantity(4));
}
llvm::Value *CodeGenFunction::getExceptionFromSlot() {

View File

@ -1345,10 +1345,11 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
if (LV.isSimple()) {
// Defend against branches out of gnu statement expressions surrounded by
// cleanups.
llvm::Value *V = LV.getPointer(*this);
Address Addr = LV.getAddress(*this);
llvm::Value *V = Addr.getPointer();
Scope.ForceCleanup({&V});
return LValue::MakeAddr(Address(V, LV.getAlignment()), LV.getType(),
getContext(), LV.getBaseInfo(), LV.getTBAAInfo());
return LValue::MakeAddr(Addr.withPointer(V), LV.getType(), getContext(),
LV.getBaseInfo(), LV.getTBAAInfo());
}
// FIXME: Is it possible to create an ExprWithCleanups that produces a
// bitfield lvalue or some other non-simple lvalue?
@ -2476,10 +2477,11 @@ CodeGenFunction::EmitLoadOfReference(LValue RefLVal,
Builder.CreateLoad(RefLVal.getAddress(*this), RefLVal.isVolatile());
CGM.DecorateInstructionWithTBAA(Load, RefLVal.getTBAAInfo());
QualType PointeeType = RefLVal.getType()->getPointeeType();
CharUnits Align = CGM.getNaturalTypeAlignment(
RefLVal.getType()->getPointeeType(), PointeeBaseInfo, PointeeTBAAInfo,
PointeeType, PointeeBaseInfo, PointeeTBAAInfo,
/* forPointeeType= */ true);
return Address(Load, Align);
return Address(Load, ConvertTypeForMem(PointeeType), Align);
}
LValue CodeGenFunction::EmitLoadOfReferenceLValue(LValue RefLVal) {
@ -4541,10 +4543,10 @@ EmitConditionalOperatorLValue(const AbstractConditionalOperator *expr) {
// because it can't be used.
if (auto *ThrowExpr = dyn_cast<CXXThrowExpr>(live->IgnoreParens())) {
EmitCXXThrowExpr(ThrowExpr);
llvm::Type *Ty =
llvm::PointerType::getUnqual(ConvertType(dead->getType()));
llvm::Type *ElemTy = ConvertType(dead->getType());
llvm::Type *Ty = llvm::PointerType::getUnqual(ElemTy);
return MakeAddrLValue(
Address(llvm::UndefValue::get(Ty), CharUnits::One()),
Address(llvm::UndefValue::get(Ty), ElemTy, CharUnits::One()),
dead->getType());
}
return EmitLValue(live);
@ -4586,11 +4588,13 @@ EmitConditionalOperatorLValue(const AbstractConditionalOperator *expr) {
EmitBlock(contBlock);
if (lhs && rhs) {
llvm::PHINode *phi =
Builder.CreatePHI(lhs->getPointer(*this)->getType(), 2, "cond-lvalue");
phi->addIncoming(lhs->getPointer(*this), lhsBlock);
phi->addIncoming(rhs->getPointer(*this), rhsBlock);
Address result(phi, std::min(lhs->getAlignment(), rhs->getAlignment()));
Address lhsAddr = lhs->getAddress(*this);
Address rhsAddr = rhs->getAddress(*this);
llvm::PHINode *phi = Builder.CreatePHI(lhsAddr.getType(), 2, "cond-lvalue");
phi->addIncoming(lhsAddr.getPointer(), lhsBlock);
phi->addIncoming(rhsAddr.getPointer(), rhsBlock);
Address result(phi, lhsAddr.getElementType(),
std::min(lhsAddr.getAlignment(), rhsAddr.getAlignment()));
AlignmentSource alignSource =
std::max(lhs->getBaseInfo().getAlignmentSource(),
rhs->getBaseInfo().getAlignmentSource());

View File

@ -1594,7 +1594,7 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
// In these cases, discard the computed alignment and use the
// formal alignment of the allocated type.
if (BaseInfo.getAlignmentSource() != AlignmentSource::Decl)
allocation = Address(allocation.getPointer(), allocAlign);
allocation = allocation.withAlignment(allocAlign);
// Set up allocatorArgs for the call to operator delete if it's not
// the reserved global operator.
@ -1664,7 +1664,7 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
allocationAlign, getContext().toCharUnitsFromBits(AllocatorAlign));
}
allocation = Address(RV.getScalarVal(), allocationAlign);
allocation = Address(RV.getScalarVal(), Int8Ty, allocationAlign);
}
// Emit a null check on the allocation result if the allocation
@ -1725,8 +1725,8 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
// of optimization level.
if (CGM.getCodeGenOpts().StrictVTablePointers &&
allocator->isReservedGlobalPlacementOperator())
result = Address(Builder.CreateLaunderInvariantGroup(result.getPointer()),
result.getAlignment());
result = result.withPointer(
Builder.CreateLaunderInvariantGroup(result.getPointer()));
// Emit sanitizer checks for pointer value now, so that in the case of an
// array it was checked only once and not at each constructor call. We may

View File

@ -200,7 +200,8 @@ CodeGenFunction::MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T) {
TBAAAccessInfo TBAAInfo;
CharUnits Align = CGM.getNaturalTypeAlignment(T, &BaseInfo, &TBAAInfo,
/* forPointeeType= */ true);
return MakeAddrLValue(Address(V, Align), T, BaseInfo, TBAAInfo);
Address Addr(V, ConvertTypeForMem(T), Align);
return MakeAddrLValue(Addr, T, BaseInfo, TBAAInfo);
}

View File

@ -1345,7 +1345,8 @@ void ItaniumCXXABI::emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) {
AllocExceptionFn, llvm::ConstantInt::get(SizeTy, TypeSize), "exception");
CharUnits ExnAlign = CGF.getContext().getExnObjectAlignment();
CGF.EmitAnyExprToExn(E->getSubExpr(), Address(ExceptionPtr, ExnAlign));
CGF.EmitAnyExprToExn(
E->getSubExpr(), Address(ExceptionPtr, CGM.Int8Ty, ExnAlign));
// Now throw the exception.
llvm::Constant *TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType,
@ -2465,7 +2466,7 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
CGM.setStaticLocalDeclGuardAddress(&D, guard);
}
Address guardAddr = Address(guard, guardAlignment);
Address guardAddr = Address(guard, guard->getValueType(), guardAlignment);
// Test whether the variable has completed initialization.
//