Author: Nikita Popov Date: 2021-12-21T14:16:28+01:00 New Revision: e751d97863fb48b7dd844e48c0ba564f6970b726
URL: https://github.com/llvm/llvm-project/commit/e751d97863fb48b7dd844e48c0ba564f6970b726 DIFF: https://github.com/llvm/llvm-project/commit/e751d97863fb48b7dd844e48c0ba564f6970b726.diff LOG: [CodeGen] Avoid some pointer element type accesses This avoids some pointer element type accesses when compiling C++ code. Added: Modified: clang/lib/CodeGen/Address.h clang/lib/CodeGen/CGClass.cpp clang/lib/CodeGen/CGException.cpp clang/lib/CodeGen/CGExpr.cpp clang/lib/CodeGen/CGExprCXX.cpp clang/lib/CodeGen/CodeGenFunction.cpp clang/lib/CodeGen/ItaniumCXXABI.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/Address.h b/clang/lib/CodeGen/Address.h index 0f2d7b1d9e45..37c20291c0e8 100644 --- a/clang/lib/CodeGen/Address.h +++ b/clang/lib/CodeGen/Address.h @@ -79,6 +79,18 @@ class Address { assert(isValid()); return Alignment; } + + /// Return address with diff erent pointer, but same element type and + /// alignment. + Address withPointer(llvm::Value *NewPointer) const { + return Address(NewPointer, ElementType, Alignment); + } + + /// Return address with diff erent 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 diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index 0df64d4d5d26..a9e25447a91c 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -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, diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp index aff9c77d53c7..91ecbecc843f 100644 --- a/clang/lib/CodeGen/CGException.cpp +++ b/clang/lib/CodeGen/CGException.cpp @@ -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() { diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 635ae8a70334..c3b30de31266 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -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()); diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp index 62fa0020ea93..e9943fb4e210 100644 --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/lib/CodeGen/CGExprCXX.cpp @@ -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 diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 702495df9db6..b437ba01c676 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -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); } diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 0624bba85070..1a15b09c7b2b 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -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. // _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits