From 9a85975267691078299516ea143972ff893728ad Mon Sep 17 00:00:00 2001 From: Nathan Lanza Date: Wed, 18 Sep 2024 22:48:10 -0400 Subject: [PATCH] [CIR][CodeGen][NFC] Add TBAAAccessInfo stubbed out and many usages of it (#859) --- clang/lib/CIR/CodeGen/CIRGenAtomic.cpp | 4 +- clang/lib/CIR/CodeGen/CIRGenExpr.cpp | 259 ++++++++++++----------- clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp | 2 +- clang/lib/CIR/CodeGen/CIRGenFunction.cpp | 24 ++- clang/lib/CIR/CodeGen/CIRGenFunction.h | 80 ++++--- clang/lib/CIR/CodeGen/CIRGenModule.cpp | 16 +- clang/lib/CIR/CodeGen/CIRGenModule.h | 16 +- clang/lib/CIR/CodeGen/CIRGenTBAA.h | 28 +++ clang/lib/CIR/CodeGen/CIRGenValue.h | 51 +++-- 9 files changed, 283 insertions(+), 197 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp index e4e5c718c16b..f852af7ca979 100644 --- a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp @@ -17,14 +17,12 @@ #include "CIRGenOpenMPRuntime.h" #include "TargetInfo.h" #include "clang/AST/ASTContext.h" -#include "clang/AST/StmtVisitor.h" #include "clang/CIR/Dialect/IR/CIRAttrs.h" #include "clang/CIR/Dialect/IR/CIRDataLayout.h" #include "clang/CIR/Dialect/IR/CIRDialect.h" #include "clang/CIR/Dialect/IR/CIROpsEnums.h" #include "clang/CIR/Dialect/IR/CIRTypes.h" #include "clang/CIR/MissingFeatures.h" -#include "clang/CodeGen/CGFunctionInfo.h" #include "clang/Frontend/FrontendDiagnostic.h" #include "llvm/Support/ErrorHandling.h" #include @@ -179,7 +177,7 @@ class AtomicInfo { llvm_unreachable("NYI"); return LValue::makeAddr(addr, getValueType(), CGF.getContext(), - LVal.getBaseInfo()); + LVal.getBaseInfo(), LVal.getTBAAInfo()); } /// Emits atomic load. diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp index a8263332be5e..db2d82c00dfb 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp @@ -15,6 +15,7 @@ #include "CIRGenFunction.h" #include "CIRGenModule.h" #include "CIRGenOpenMPRuntime.h" +#include "CIRGenTBAA.h" #include "CIRGenValue.h" #include "EHScopeStack.h" #include "TargetInfo.h" @@ -111,19 +112,20 @@ static bool hasAnyVptr(const QualType Type, const ASTContext &Context) { return false; } -static Address buildPointerWithAlignment(const Expr *E, - LValueBaseInfo *BaseInfo, - KnownNonNull_t IsKnownNonNull, - CIRGenFunction &CGF) { +static Address buildPointerWithAlignment(const Expr *expr, + LValueBaseInfo *baseInfo, + TBAAAccessInfo *tbaaInfo, + KnownNonNull_t isKnownNonNull, + CIRGenFunction &cgf) { // We allow this with ObjC object pointers because of fragile ABIs. - assert(E->getType()->isPointerType() || - E->getType()->isObjCObjectPointerType()); - E = E->IgnoreParens(); + assert(expr->getType()->isPointerType() || + expr->getType()->isObjCObjectPointerType()); + expr = expr->IgnoreParens(); // Casts: - if (const CastExpr *CE = dyn_cast(E)) { + if (const CastExpr *CE = dyn_cast(expr)) { if (const auto *ECE = dyn_cast(CE)) - CGF.CGM.buildExplicitCastExprType(ECE, &CGF); + cgf.CGM.buildExplicitCastExprType(ECE, &cgf); switch (CE->getCastKind()) { default: { @@ -140,44 +142,44 @@ static Address buildPointerWithAlignment(const Expr *E, break; assert(!MissingFeatures::tbaa()); - LValueBaseInfo InnerBaseInfo; - Address Addr = CGF.buildPointerWithAlignment( - CE->getSubExpr(), &InnerBaseInfo, IsKnownNonNull); - if (BaseInfo) - *BaseInfo = InnerBaseInfo; + LValueBaseInfo innerBaseInfo; + Address addr = cgf.buildPointerWithAlignment( + CE->getSubExpr(), &innerBaseInfo, tbaaInfo, isKnownNonNull); + if (baseInfo) + *baseInfo = innerBaseInfo; if (isa(CE)) { assert(!MissingFeatures::tbaa()); LValueBaseInfo TargetTypeBaseInfo; - CharUnits Align = CGF.CGM.getNaturalPointeeTypeAlignment( - E->getType(), &TargetTypeBaseInfo); + CharUnits Align = cgf.CGM.getNaturalPointeeTypeAlignment( + expr->getType(), &TargetTypeBaseInfo); // If the source l-value is opaque, honor the alignment of the // casted-to type. - if (InnerBaseInfo.getAlignmentSource() != AlignmentSource::Decl) { - if (BaseInfo) - BaseInfo->mergeForCast(TargetTypeBaseInfo); - Addr = Address(Addr.getPointer(), Addr.getElementType(), Align, - IsKnownNonNull); + if (innerBaseInfo.getAlignmentSource() != AlignmentSource::Decl) { + if (baseInfo) + baseInfo->mergeForCast(TargetTypeBaseInfo); + addr = Address(addr.getPointer(), addr.getElementType(), Align, + isKnownNonNull); } } - if (CGF.SanOpts.has(SanitizerKind::CFIUnrelatedCast) && + if (cgf.SanOpts.has(SanitizerKind::CFIUnrelatedCast) && CE->getCastKind() == CK_BitCast) { - if (auto PT = E->getType()->getAs()) + if (auto PT = expr->getType()->getAs()) llvm_unreachable("NYI"); } auto ElemTy = - CGF.getTypes().convertTypeForMem(E->getType()->getPointeeType()); - Addr = CGF.getBuilder().createElementBitCast( - CGF.getLoc(E->getSourceRange()), Addr, ElemTy); + cgf.getTypes().convertTypeForMem(expr->getType()->getPointeeType()); + addr = cgf.getBuilder().createElementBitCast( + cgf.getLoc(expr->getSourceRange()), addr, ElemTy); if (CE->getCastKind() == CK_AddressSpaceConversion) { assert(!MissingFeatures::addressSpace()); llvm_unreachable("NYI"); } - return Addr; + return addr; } break; @@ -189,7 +191,7 @@ static Address buildPointerWithAlignment(const Expr *E, // Array-to-pointer decay. TODO(cir): BaseInfo and TBAAInfo. case CK_ArrayToPointerDecay: - return CGF.buildArrayToPointerDecay(CE->getSubExpr()); + return cgf.buildArrayToPointerDecay(CE->getSubExpr()); case CK_UncheckedDerivedToBase: case CK_DerivedToBase: { @@ -197,29 +199,29 @@ static Address buildPointerWithAlignment(const Expr *E, // conservatively pretend that the complete object is of the base class // type. assert(!MissingFeatures::tbaa()); - Address Addr = CGF.buildPointerWithAlignment(CE->getSubExpr(), BaseInfo); + Address Addr = cgf.buildPointerWithAlignment(CE->getSubExpr(), baseInfo); auto Derived = CE->getSubExpr()->getType()->getPointeeCXXRecordDecl(); - return CGF.getAddressOfBaseClass( + return cgf.getAddressOfBaseClass( Addr, Derived, CE->path_begin(), CE->path_end(), - CGF.shouldNullCheckClassCastValue(CE), CE->getExprLoc()); + cgf.shouldNullCheckClassCastValue(CE), CE->getExprLoc()); } } } // Unary &. - if (const UnaryOperator *UO = dyn_cast(E)) { + if (const UnaryOperator *UO = dyn_cast(expr)) { // TODO(cir): maybe we should use cir.unary for pointers here instead. if (UO->getOpcode() == UO_AddrOf) { - LValue LV = CGF.buildLValue(UO->getSubExpr()); - if (BaseInfo) - *BaseInfo = LV.getBaseInfo(); + LValue LV = cgf.buildLValue(UO->getSubExpr()); + if (baseInfo) + *baseInfo = LV.getBaseInfo(); assert(!MissingFeatures::tbaa()); return LV.getAddress(); } } // std::addressof and variants. - if (auto *Call = dyn_cast(E)) { + if (auto *Call = dyn_cast(expr)) { switch (Call->getBuiltinCallee()) { default: break; @@ -234,9 +236,9 @@ static Address buildPointerWithAlignment(const Expr *E, // TODO: conditional operators, comma. // Otherwise, use the alignment of the type. - return CGF.makeNaturalAddressForPointer( - CGF.buildScalarExpr(E), E->getType()->getPointeeType(), CharUnits(), - /*ForPointeeType=*/true, BaseInfo, IsKnownNonNull); + return cgf.makeNaturalAddressForPointer( + cgf.buildScalarExpr(expr), expr->getType()->getPointeeType(), CharUnits(), + /*ForPointeeType=*/true, baseInfo, tbaaInfo, isKnownNonNull); } /// Helper method to check if the underlying ABI is AAPCS @@ -293,8 +295,9 @@ LValue CIRGenFunction::buildLValueForBitField(LValue base, QualType fieldType = field->getType().withCVRQualifiers(base.getVRQualifiers()); assert(!MissingFeatures::tbaa() && "NYI TBAA for bit fields"); - LValueBaseInfo FieldBaseInfo(BaseInfo.getAlignmentSource()); - return LValue::MakeBitfield(Addr, info, fieldType, FieldBaseInfo); + LValueBaseInfo fieldBaseInfo(BaseInfo.getAlignmentSource()); + return LValue::MakeBitfield(Addr, info, fieldType, fieldBaseInfo, + TBAAAccessInfo()); } LValue CIRGenFunction::buildLValueForField(LValue base, @@ -584,45 +587,48 @@ mlir::Value CIRGenFunction::buildToMemory(mlir::Value Value, QualType Ty) { void CIRGenFunction::buildStoreOfScalar(mlir::Value value, LValue lvalue) { // TODO: constant matrix type, no init, non temporal, TBAA buildStoreOfScalar(value, lvalue.getAddress(), lvalue.isVolatile(), - lvalue.getType(), lvalue.getBaseInfo(), false, false); + lvalue.getType(), lvalue.getBaseInfo(), + lvalue.getTBAAInfo(), false, false); } -void CIRGenFunction::buildStoreOfScalar(mlir::Value Value, Address Addr, - bool Volatile, QualType Ty, - LValueBaseInfo BaseInfo, bool isInit, +void CIRGenFunction::buildStoreOfScalar(mlir::Value value, Address addr, + bool isVolatile, QualType ty, + LValueBaseInfo baseInfo, + TBAAAccessInfo tbaaInfo, bool isInit, bool isNontemporal) { - Value = buildToMemory(Value, Ty); + value = buildToMemory(value, ty); - LValue AtomicLValue = LValue::makeAddr(Addr, Ty, getContext(), BaseInfo); - if (Ty->isAtomicType() || - (!isInit && LValueIsSuitableForInlineAtomic(AtomicLValue))) { - buildAtomicStore(RValue::get(Value), AtomicLValue, isInit); + LValue atomicLValue = + LValue::makeAddr(addr, ty, getContext(), baseInfo, tbaaInfo); + if (ty->isAtomicType() || + (!isInit && LValueIsSuitableForInlineAtomic(atomicLValue))) { + buildAtomicStore(RValue::get(value), atomicLValue, isInit); return; } - mlir::Type SrcTy = Value.getType(); - if (const auto *ClangVecTy = Ty->getAs()) { + mlir::Type SrcTy = value.getType(); + if (const auto *ClangVecTy = ty->getAs()) { auto VecTy = dyn_cast(SrcTy); if (!CGM.getCodeGenOpts().PreserveVec3Type && ClangVecTy->getNumElements() == 3) { // Handle vec3 special. if (VecTy && VecTy.getSize() == 3) { // Our source is a vec3, do a shuffle vector to make it a vec4. - Value = builder.createVecShuffle(Value.getLoc(), Value, + value = builder.createVecShuffle(value.getLoc(), value, ArrayRef{0, 1, 2, -1}); SrcTy = mlir::cir::VectorType::get(VecTy.getContext(), VecTy.getEltType(), 4); } - if (Addr.getElementType() != SrcTy) { - Addr = Addr.withElementType(SrcTy); + if (addr.getElementType() != SrcTy) { + addr = addr.withElementType(SrcTy); } } } // Update the alloca with more info on initialization. - assert(Addr.getPointer() && "expected pointer to exist"); + assert(addr.getPointer() && "expected pointer to exist"); auto SrcAlloca = - dyn_cast_or_null(Addr.getPointer().getDefiningOp()); + dyn_cast_or_null(addr.getPointer().getDefiningOp()); if (currVarDecl && SrcAlloca) { const VarDecl *VD = currVarDecl; assert(VD && "VarDecl expected"); @@ -631,7 +637,7 @@ void CIRGenFunction::buildStoreOfScalar(mlir::Value Value, Address Addr, } assert(currSrcLoc && "must pass in source location"); - builder.createStore(*currSrcLoc, Value, Addr, Volatile); + builder.createStore(*currSrcLoc, value, addr, isVolatile); if (isNontemporal) { llvm_unreachable("NYI"); @@ -648,8 +654,8 @@ void CIRGenFunction::buildStoreOfScalar(mlir::Value value, LValue lvalue, } buildStoreOfScalar(value, lvalue.getAddress(), lvalue.isVolatile(), - lvalue.getType(), lvalue.getBaseInfo(), isInit, - lvalue.isNontemporal()); + lvalue.getType(), lvalue.getBaseInfo(), + lvalue.getTBAAInfo(), isInit, lvalue.isNontemporal()); } /// Given an expression that represents a value lvalue, this @@ -1126,7 +1132,7 @@ CIRGenFunction::buildPointerToDataMemberBinaryExpr(const BinaryOperator *E) { LValue CIRGenFunction::buildExtVectorElementExpr(const ExtVectorElementExpr *E) { // Emit the base vector as an l-value. - LValue Base; + LValue base; // ExtVectorElementExpr's base can either be a vector or pointer to vector. if (E->isArrow()) { @@ -1137,13 +1143,13 @@ CIRGenFunction::buildExtVectorElementExpr(const ExtVectorElementExpr *E) { assert(!MissingFeatures::tbaa()); Address Ptr = buildPointerWithAlignment(E->getBase(), &BaseInfo); const auto *PT = E->getBase()->getType()->castAs(); - Base = makeAddrLValue(Ptr, PT->getPointeeType(), BaseInfo); - Base.getQuals().removeObjCGCAttr(); + base = makeAddrLValue(Ptr, PT->getPointeeType(), BaseInfo); + base.getQuals().removeObjCGCAttr(); } else if (E->getBase()->isGLValue()) { // Otherwise, if the base is an lvalue ( as in the case of foo.x.x), // emit the base as an lvalue. assert(E->getBase()->getType()->isVectorType()); - Base = buildLValue(E->getBase()); + base = buildLValue(E->getBase()); } else { // Otherwise, the base is a normal rvalue (as in (V+V).x), emit it as such. assert(E->getBase()->getType()->isVectorType() && @@ -1154,28 +1160,28 @@ CIRGenFunction::buildExtVectorElementExpr(const ExtVectorElementExpr *E) { QualType BaseTy = E->getBase()->getType(); Address VecMem = CreateMemTemp(BaseTy, Vec.getLoc(), "tmp"); builder.createStore(Vec.getLoc(), Vec, VecMem); - Base = makeAddrLValue(VecMem, BaseTy, AlignmentSource::Decl); + base = makeAddrLValue(VecMem, BaseTy, AlignmentSource::Decl); } QualType type = - E->getType().withCVRQualifiers(Base.getQuals().getCVRQualifiers()); + E->getType().withCVRQualifiers(base.getQuals().getCVRQualifiers()); // Encode the element access list into a vector of unsigned indices. SmallVector indices; E->getEncodedElementAccess(indices); - if (Base.isSimple()) { + if (base.isSimple()) { SmallVector attrElts; for (uint32_t i : indices) { attrElts.push_back(static_cast(i)); } auto elts = builder.getI64ArrayAttr(attrElts); - return LValue::MakeExtVectorElt(Base.getAddress(), elts, type, - Base.getBaseInfo()); + return LValue::MakeExtVectorElt(base.getAddress(), elts, type, + base.getBaseInfo(), base.getTBAAInfo()); } - assert(Base.isExtVectorElt() && "Can only subscript lvalue vec elts here!"); + assert(base.isExtVectorElt() && "Can only subscript lvalue vec elts here!"); - mlir::ArrayAttr baseElts = Base.getExtVectorElts(); + mlir::ArrayAttr baseElts = base.getExtVectorElts(); // Composite the two indices SmallVector attrElts; @@ -1184,8 +1190,8 @@ CIRGenFunction::buildExtVectorElementExpr(const ExtVectorElementExpr *E) { } auto elts = builder.getI64ArrayAttr(attrElts); - return LValue::MakeExtVectorElt(Base.getExtVectorAddress(), elts, type, - Base.getBaseInfo()); + return LValue::MakeExtVectorElt(base.getExtVectorAddress(), elts, type, + base.getBaseInfo(), base.getTBAAInfo()); } LValue CIRGenFunction::buildBinaryOperatorLValue(const BinaryOperator *E) { @@ -1236,12 +1242,13 @@ LValue CIRGenFunction::buildBinaryOperatorLValue(const BinaryOperator *E) { /// Given an expression of pointer type, try to /// derive a more accurate bound on the alignment of the pointer. Address CIRGenFunction::buildPointerWithAlignment( - const Expr *E, LValueBaseInfo *BaseInfo, KnownNonNull_t IsKnownNonNull) { - Address Addr = - ::buildPointerWithAlignment(E, BaseInfo, IsKnownNonNull, *this); - if (IsKnownNonNull && !Addr.isKnownNonNull()) - Addr.setKnownNonNull(); - return Addr; + const Expr *expr, LValueBaseInfo *baseInfo, TBAAAccessInfo *tbaaInfo, + KnownNonNull_t isKnownNonNull) { + Address addr = ::buildPointerWithAlignment(expr, baseInfo, tbaaInfo, + isKnownNonNull, *this); + if (isKnownNonNull && !addr.isKnownNonNull()) + addr.setKnownNonNull(); + return addr; } /// Perform the usual unary conversions on the specified @@ -1748,10 +1755,11 @@ LValue CIRGenFunction::buildArraySubscriptExpr(const ArraySubscriptExpr *E, // with this subscript. if (E->getBase()->getType()->isVectorType() && !isa(E->getBase())) { - LValue LHS = buildLValue(E->getBase()); - auto Index = EmitIdxAfterBase(/*Promote=*/false); - return LValue::MakeVectorElt(LHS.getAddress(), Index, - E->getBase()->getType(), LHS.getBaseInfo()); + LValue lhs = buildLValue(E->getBase()); + auto index = EmitIdxAfterBase(/*Promote=*/false); + return LValue::MakeVectorElt(lhs.getAddress(), index, + E->getBase()->getType(), lhs.getBaseInfo(), + lhs.getTBAAInfo()); } // All the other cases basically behave like simple offsetting. @@ -2564,11 +2572,11 @@ LValue CIRGenFunction::buildLValue(const Expr *E) { if (LV.isSimple()) { // Defend against branches out of gnu statement expressions // surrounded by cleanups. - Address Addr = LV.getAddress(); - auto V = Addr.getPointer(); - LV = LValue::makeAddr(Addr.withPointer(V, NotKnownNonNull), - LV.getType(), getContext(), - LV.getBaseInfo() /*TODO(cir):TBAA*/); + Address addr = LV.getAddress(); + auto v = addr.getPointer(); + LV = LValue::makeAddr(addr.withPointer(v, NotKnownNonNull), + LV.getType(), getContext(), LV.getBaseInfo(), + LV.getTBAAInfo()); } }); @@ -2817,17 +2825,17 @@ mlir::Value CIRGenFunction::buildAlloca(StringRef name, QualType ty, } mlir::Value CIRGenFunction::buildLoadOfScalar(LValue lvalue, - SourceLocation Loc) { + SourceLocation loc) { return buildLoadOfScalar(lvalue.getAddress(), lvalue.isVolatile(), - lvalue.getType(), getLoc(Loc), lvalue.getBaseInfo(), - lvalue.isNontemporal()); + lvalue.getType(), getLoc(loc), lvalue.getBaseInfo(), + lvalue.getTBAAInfo(), lvalue.isNontemporal()); } mlir::Value CIRGenFunction::buildLoadOfScalar(LValue lvalue, - mlir::Location Loc) { + mlir::Location loc) { return buildLoadOfScalar(lvalue.getAddress(), lvalue.isVolatile(), - lvalue.getType(), Loc, lvalue.getBaseInfo(), - lvalue.isNontemporal()); + lvalue.getType(), loc, lvalue.getBaseInfo(), + lvalue.getTBAAInfo(), lvalue.isNontemporal()); } mlir::Value CIRGenFunction::buildFromMemory(mlir::Value Value, QualType Ty) { @@ -2838,54 +2846,57 @@ mlir::Value CIRGenFunction::buildFromMemory(mlir::Value Value, QualType Ty) { return Value; } -mlir::Value CIRGenFunction::buildLoadOfScalar(Address Addr, bool Volatile, - QualType Ty, SourceLocation Loc, - LValueBaseInfo BaseInfo, +mlir::Value CIRGenFunction::buildLoadOfScalar(Address addr, bool isVolatile, + QualType ty, SourceLocation loc, + LValueBaseInfo baseInfo, + TBAAAccessInfo tbaaInfo, bool isNontemporal) { - return buildLoadOfScalar(Addr, Volatile, Ty, getLoc(Loc), BaseInfo, - isNontemporal); + return buildLoadOfScalar(addr, isVolatile, ty, getLoc(loc), baseInfo, + tbaaInfo, isNontemporal); } -mlir::Value CIRGenFunction::buildLoadOfScalar(Address Addr, bool Volatile, - QualType Ty, mlir::Location Loc, - LValueBaseInfo BaseInfo, +mlir::Value CIRGenFunction::buildLoadOfScalar(Address addr, bool isVolatile, + QualType ty, mlir::Location loc, + LValueBaseInfo baseInfo, + TBAAAccessInfo tbaaInfo, bool isNontemporal) { // Atomic operations have to be done on integral types - LValue AtomicLValue = LValue::makeAddr(Addr, Ty, getContext(), BaseInfo); - if (Ty->isAtomicType() || LValueIsSuitableForInlineAtomic(AtomicLValue)) { + LValue atomicLValue = + LValue::makeAddr(addr, ty, getContext(), baseInfo, tbaaInfo); + if (ty->isAtomicType() || LValueIsSuitableForInlineAtomic(atomicLValue)) { llvm_unreachable("NYI"); } - auto ElemTy = Addr.getElementType(); + auto ElemTy = addr.getElementType(); - if (const auto *ClangVecTy = Ty->getAs()) { + if (const auto *ClangVecTy = ty->getAs()) { // Handle vectors of size 3 like size 4 for better performance. const auto VTy = cast(ElemTy); if (!CGM.getCodeGenOpts().PreserveVec3Type && ClangVecTy->getNumElements() == 3) { - auto loc = Addr.getPointer().getLoc(); + auto loc = addr.getPointer().getLoc(); auto vec4Ty = mlir::cir::VectorType::get(VTy.getContext(), VTy.getEltType(), 4); - Address Cast = Addr.withElementType(vec4Ty); + Address Cast = addr.withElementType(vec4Ty); // Now load value. mlir::Value V = builder.createLoad(loc, Cast); // Shuffle vector to get vec3. V = builder.createVecShuffle(loc, V, ArrayRef{0, 1, 2}); - return buildFromMemory(V, Ty); + return buildFromMemory(V, ty); } } - auto Ptr = Addr.getPointer(); + auto Ptr = addr.getPointer(); if (mlir::isa(ElemTy)) { ElemTy = mlir::cir::IntType::get(builder.getContext(), 8, true); auto ElemPtrTy = mlir::cir::PointerType::get(builder.getContext(), ElemTy); - Ptr = builder.create(Loc, ElemPtrTy, + Ptr = builder.create(loc, ElemPtrTy, mlir::cir::CastKind::bitcast, Ptr); } - mlir::Value Load = builder.CIRBaseBuilderTy::createLoad(Loc, Ptr, Volatile); + mlir::Value Load = builder.CIRBaseBuilderTy::createLoad(loc, Ptr, isVolatile); if (isNontemporal) { llvm_unreachable("NYI"); @@ -2894,7 +2905,7 @@ mlir::Value CIRGenFunction::buildLoadOfScalar(Address Addr, bool Volatile, assert(!MissingFeatures::tbaa() && "NYI"); assert(!MissingFeatures::emitScalarRangeCheck() && "NYI"); - return buildFromMemory(Load, Ty); + return buildFromMemory(Load, ty); } // Note: this function also emit constructor calls to support a MSVC extensions @@ -2936,20 +2947,22 @@ RValue CIRGenFunction::buildReferenceBindingToExpr(const Expr *E) { return RValue::get(Value); } -Address CIRGenFunction::buildLoadOfReference(LValue RefLVal, mlir::Location Loc, - LValueBaseInfo *PointeeBaseInfo) { - assert(!RefLVal.isVolatile() && "NYI"); - mlir::cir::LoadOp Load = builder.create( - Loc, RefLVal.getAddress().getElementType(), - RefLVal.getAddress().getPointer()); +Address CIRGenFunction::buildLoadOfReference(LValue refLVal, mlir::Location loc, + LValueBaseInfo *pointeeBaseInfo, + TBAAAccessInfo *pointeeTBAAInfo) { + assert(!refLVal.isVolatile() && "NYI"); + mlir::cir::LoadOp load = builder.create( + loc, refLVal.getAddress().getElementType(), + refLVal.getAddress().getPointer()); // TODO(cir): DecorateInstructionWithTBAA relevant for us? assert(!MissingFeatures::tbaa()); - QualType PointeeType = RefLVal.getType()->getPointeeType(); - CharUnits Align = CGM.getNaturalTypeAlignment(PointeeType, PointeeBaseInfo, - /* forPointeeType= */ true); - return Address(Load, getTypes().convertTypeForMem(PointeeType), Align); + QualType pointeeType = refLVal.getType()->getPointeeType(); + CharUnits align = + CGM.getNaturalTypeAlignment(pointeeType, pointeeBaseInfo, pointeeTBAAInfo, + /* forPointeeType= */ true); + return Address(load, getTypes().convertTypeForMem(pointeeType), align); } LValue CIRGenFunction::buildLoadOfReferenceLValue(LValue RefLVal, diff --git a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp index 89f60f52f34d..63a18c328fa8 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp @@ -119,7 +119,7 @@ CIRGenFunction::buildCXXMemberPointerCallExpr(const CXXMemberCallExpr *E, // Emit the 'this' pointer. Address This = Address::invalid(); if (BO->getOpcode() == BO_PtrMemI) - This = buildPointerWithAlignment(BaseExpr, nullptr, KnownNonNull); + This = buildPointerWithAlignment(BaseExpr, nullptr, nullptr, KnownNonNull); else This = buildLValue(BaseExpr).getAddress(); diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp index e011e1f83558..e686c7b0e63b 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp @@ -25,6 +25,7 @@ #include "clang/CIR/Dialect/IR/FPEnv.h" #include "clang/Frontend/FrontendDiagnostic.h" +#include "CIRGenTBAA.h" #include "mlir/Dialect/Func/IR/FuncOps.h" #include "mlir/Support/LogicalResult.h" @@ -890,22 +891,25 @@ void CIRGenFunction::buildConstructorBody(FunctionArgList &Args) { /// Given a value of type T* that may not be to a complete object, construct /// an l-vlaue withi the natural pointee alignment of T. -LValue CIRGenFunction::MakeNaturalAlignPointeeAddrLValue(mlir::Value V, - QualType T) { +LValue CIRGenFunction::MakeNaturalAlignPointeeAddrLValue(mlir::Value val, + QualType ty) { // FIXME(cir): is it safe to assume Op->getResult(0) is valid? Perhaps // assert on the result type first. - LValueBaseInfo BaseInfo; - CharUnits Align = CGM.getNaturalTypeAlignment(T, &BaseInfo, + LValueBaseInfo baseInfo; + TBAAAccessInfo tbaaInfo; + CharUnits align = CGM.getNaturalTypeAlignment(ty, &baseInfo, &tbaaInfo, /* for PointeeType= */ true); - return makeAddrLValue(Address(V, Align), T, BaseInfo); + return makeAddrLValue(Address(val, align), ty, baseInfo); } -LValue CIRGenFunction::MakeNaturalAlignAddrLValue(mlir::Value V, QualType T) { - LValueBaseInfo BaseInfo; +LValue CIRGenFunction::MakeNaturalAlignAddrLValue(mlir::Value val, + QualType ty) { + LValueBaseInfo baseInfo; + TBAAAccessInfo tbaaInfo; assert(!MissingFeatures::tbaa()); - CharUnits Alignment = CGM.getNaturalTypeAlignment(T, &BaseInfo); - Address Addr(V, getTypes().convertTypeForMem(T), Alignment); - return LValue::makeAddr(Addr, T, getContext(), BaseInfo); + CharUnits alignment = CGM.getNaturalTypeAlignment(ty, &baseInfo, &tbaaInfo); + Address addr(val, getTypes().convertTypeForMem(ty), alignment); + return LValue::makeAddr(addr, ty, getContext(), baseInfo, tbaaInfo); } // Map the LangOption for exception behavior into the corresponding enum in diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h index da8543e068b9..c581e4ba9e35 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.h +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h @@ -16,6 +16,7 @@ #include "CIRGenBuilder.h" #include "CIRGenCall.h" #include "CIRGenModule.h" +#include "CIRGenTBAA.h" #include "CIRGenTypeCache.h" #include "CIRGenValue.h" #include "EHScopeStack.h" @@ -816,12 +817,15 @@ class CIRGenFunction : public CIRGenTypeCache { /// the address of the lvalue, then loads the result as an rvalue, /// returning the rvalue. RValue buildLoadOfLValue(LValue LV, SourceLocation Loc); - mlir::Value buildLoadOfScalar(Address Addr, bool Volatile, clang::QualType Ty, - clang::SourceLocation Loc, - LValueBaseInfo BaseInfo, + mlir::Value buildLoadOfScalar(Address addr, bool isVolatile, + clang::QualType ty, clang::SourceLocation loc, + LValueBaseInfo baseInfo, + TBAAAccessInfo tbaaInfo, bool isNontemporal = false); - mlir::Value buildLoadOfScalar(Address Addr, bool Volatile, clang::QualType Ty, - mlir::Location Loc, LValueBaseInfo BaseInfo, + mlir::Value buildLoadOfScalar(Address addr, bool isVolatile, + clang::QualType ty, mlir::Location loc, + LValueBaseInfo baseInfo, + TBAAAccessInfo tbaaInfo, bool isNontemporal = false); int64_t getAccessedFieldNo(unsigned idx, const mlir::ArrayAttr elts); @@ -834,12 +838,12 @@ class CIRGenFunction : public CIRGenTypeCache { /// Load a scalar value from an address, taking care to appropriately convert /// from the memory representation to CIR value representation. - mlir::Value buildLoadOfScalar(Address Addr, bool Volatile, clang::QualType Ty, - clang::SourceLocation Loc, - AlignmentSource Source = AlignmentSource::Type, + mlir::Value buildLoadOfScalar(Address addr, bool isVolatile, + clang::QualType ty, clang::SourceLocation loc, + AlignmentSource source = AlignmentSource::Type, bool isNontemporal = false) { - return buildLoadOfScalar(Addr, Volatile, Ty, Loc, LValueBaseInfo(Source), - isNontemporal); + return buildLoadOfScalar(addr, isVolatile, ty, loc, LValueBaseInfo(source), + CGM.getTBAAAccessInfo(ty), isNontemporal); } /// Load a scalar value from an address, taking care to appropriately convert @@ -851,8 +855,9 @@ class CIRGenFunction : public CIRGenTypeCache { /// Load a complex number from the specified l-value. mlir::Value buildLoadOfComplex(LValue src, SourceLocation loc); - Address buildLoadOfReference(LValue RefLVal, mlir::Location Loc, - LValueBaseInfo *PointeeBaseInfo = nullptr); + Address buildLoadOfReference(LValue refLVal, mlir::Location loc, + LValueBaseInfo *pointeeBaseInfo = nullptr, + TBAAAccessInfo *pointeeTBAAInfo = nullptr); LValue buildLoadOfReferenceLValue(LValue RefLVal, mlir::Location Loc); LValue buildLoadOfReferenceLValue(Address RefAddr, mlir::Location Loc, @@ -1275,9 +1280,17 @@ class CIRGenFunction : public CIRGenTypeCache { clang::QualType::DestructionKind dtorKind); void buildStoreOfScalar(mlir::Value value, LValue lvalue); - void buildStoreOfScalar(mlir::Value Value, Address Addr, bool Volatile, - clang::QualType Ty, LValueBaseInfo BaseInfo, - bool isInit = false, bool isNontemporal = false); + void buildStoreOfScalar(mlir::Value value, Address addr, bool isVolatile, + clang::QualType ty, LValueBaseInfo baseInfo, + TBAAAccessInfo tbaaInfo, bool isInit = false, + bool isNontemporal = false); + void buildStoreOfScalar(mlir::Value value, Address addr, bool isVolatile, + QualType ty, + AlignmentSource source = AlignmentSource::Type, + bool isInit = false, bool isNontemporal = false) { + buildStoreOfScalar(value, addr, isVolatile, ty, LValueBaseInfo(source), + CGM.getTBAAAccessInfo(ty), isInit, isNontemporal); + } void buildStoreOfScalar(mlir::Value value, LValue lvalue, bool isInit); mlir::Value buildToMemory(mlir::Value Value, clang::QualType Ty); @@ -1352,9 +1365,10 @@ class CIRGenFunction : public CIRGenTypeCache { /// reasonable to just ignore the returned alignment when it isn't from an /// explicit source. Address - buildPointerWithAlignment(const clang::Expr *E, - LValueBaseInfo *BaseInfo = nullptr, - KnownNonNull_t IsKnownNonNull = NotKnownNonNull); + buildPointerWithAlignment(const clang::Expr *expr, + LValueBaseInfo *baseInfo = nullptr, + TBAAAccessInfo *tbaaInfo = nullptr, + KnownNonNull_t isKnownNonNull = NotKnownNonNull); LValue buildConditionalOperatorLValue(const AbstractConditionalOperator *expr); @@ -1534,19 +1548,21 @@ class CIRGenFunction : public CIRGenTypeCache { }; LValue MakeNaturalAlignPointeeAddrLValue(mlir::Value V, clang::QualType T); - LValue MakeNaturalAlignAddrLValue(mlir::Value V, QualType T); + LValue MakeNaturalAlignAddrLValue(mlir::Value val, QualType ty); /// Construct an address with the natural alignment of T. If a pointer to T /// is expected to be signed, the pointer passed to this function must have /// been signed, and the returned Address will have the pointer authentication /// information needed to authenticate the signed pointer. Address makeNaturalAddressForPointer( - mlir::Value Ptr, QualType T, CharUnits Alignment = CharUnits::Zero(), - bool ForPointeeType = false, LValueBaseInfo *BaseInfo = nullptr, - KnownNonNull_t IsKnownNonNull = NotKnownNonNull) { - if (Alignment.isZero()) - Alignment = CGM.getNaturalTypeAlignment(T, BaseInfo, ForPointeeType); - return Address(Ptr, convertTypeForMem(T), Alignment, IsKnownNonNull); + mlir::Value ptr, QualType t, CharUnits alignment = CharUnits::Zero(), + bool forPointeeType = false, LValueBaseInfo *baseInfo = nullptr, + TBAAAccessInfo *tbaaInfo = nullptr, + KnownNonNull_t isKnownNonNull = NotKnownNonNull) { + if (alignment.isZero()) + alignment = + CGM.getNaturalTypeAlignment(t, baseInfo, tbaaInfo, forPointeeType); + return Address(ptr, convertTypeForMem(t), alignment, isKnownNonNull); } /// Load the value for 'this'. This function is only valid while generating @@ -1590,14 +1606,16 @@ class CIRGenFunction : public CIRGenTypeCache { QualType DstTy, SourceLocation Loc); - LValue makeAddrLValue(Address Addr, clang::QualType T, - LValueBaseInfo BaseInfo) { - return LValue::makeAddr(Addr, T, getContext(), BaseInfo); + LValue makeAddrLValue(Address addr, clang::QualType ty, + LValueBaseInfo baseInfo) { + return LValue::makeAddr(addr, ty, getContext(), baseInfo, + CGM.getTBAAAccessInfo(ty)); } - LValue makeAddrLValue(Address Addr, clang::QualType T, - AlignmentSource Source = AlignmentSource::Type) { - return LValue::makeAddr(Addr, T, getContext(), LValueBaseInfo(Source)); + LValue makeAddrLValue(Address addr, clang::QualType ty, + AlignmentSource source = AlignmentSource::Type) { + return LValue::makeAddr(addr, ty, getContext(), LValueBaseInfo(source), + CGM.getTBAAAccessInfo(ty)); } void initializeVTablePointers(mlir::Location loc, diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index a92f34f2face..e4b670e613dc 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -16,6 +16,7 @@ #include "CIRGenCstEmitter.h" #include "CIRGenFunction.h" #include "CIRGenOpenMPRuntime.h" +#include "CIRGenTBAA.h" #include "CIRGenTypes.h" #include "CIRGenValue.h" #include "TargetInfo.h" @@ -243,11 +244,9 @@ CharUnits CIRGenModule::getClassPointerAlignment(const CXXRecordDecl *RD) { /// FIXME: this could likely be a common helper and not necessarily related /// with codegen. -/// TODO: Add TBAAAccessInfo -CharUnits -CIRGenModule::getNaturalPointeeTypeAlignment(QualType T, - LValueBaseInfo *BaseInfo) { - return getNaturalTypeAlignment(T->getPointeeType(), BaseInfo, +CharUnits CIRGenModule::getNaturalPointeeTypeAlignment( + QualType ty, LValueBaseInfo *baseInfo, TBAAAccessInfo *tbaaInfo) { + return getNaturalTypeAlignment(ty->getPointeeType(), baseInfo, tbaaInfo, /* forPointeeType= */ true); } @@ -256,6 +255,7 @@ CIRGenModule::getNaturalPointeeTypeAlignment(QualType T, /// TODO: Add TBAAAccessInfo CharUnits CIRGenModule::getNaturalTypeAlignment(QualType T, LValueBaseInfo *BaseInfo, + TBAAAccessInfo *tbaaInfo, bool forPointeeType) { // FIXME: This duplicates logic in ASTContext::getTypeAlignIfKnown. But // that doesn't return the information we need to compute BaseInfo. @@ -3377,3 +3377,9 @@ void CIRGenModule::buildGlobalAnnotations() { } deferredAnnotations.clear(); } + +TBAAAccessInfo CIRGenModule::getTBAAAccessInfo(QualType accessType) { + if (!tbaa) + return TBAAAccessInfo(); + llvm_unreachable("NYI"); +} diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.h b/clang/lib/CIR/CodeGen/CIRGenModule.h index 41126978422c..1f55a83a767c 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.h +++ b/clang/lib/CIR/CodeGen/CIRGenModule.h @@ -17,6 +17,7 @@ #include "CIRGenBuilder.h" #include "CIRGenCall.h" #include "CIRGenOpenCLRuntime.h" +#include "CIRGenTBAA.h" #include "CIRGenTypeCache.h" #include "CIRGenTypes.h" #include "CIRGenVTables.h" @@ -95,6 +96,8 @@ class CIRGenModule : public CIRGenTypeCache { std::unique_ptr ABI; + std::unique_ptr tbaa; + /// Used for `UniqueInternalLinkageNames` option std::string ModuleNameHash = ""; @@ -442,15 +445,16 @@ class CIRGenModule : public CIRGenTypeCache { /// FIXME: this could likely be a common helper and not necessarily related /// with codegen. - /// TODO: Add TBAAAccessInfo - clang::CharUnits getNaturalPointeeTypeAlignment(clang::QualType T, - LValueBaseInfo *BaseInfo); + clang::CharUnits + getNaturalPointeeTypeAlignment(clang::QualType ty, + LValueBaseInfo *baseInfo = nullptr, + TBAAAccessInfo *tbaaInfo = nullptr); /// FIXME: this could likely be a common helper and not necessarily related /// with codegen. - /// TODO: Add TBAAAccessInfo clang::CharUnits getNaturalTypeAlignment(clang::QualType T, LValueBaseInfo *BaseInfo = nullptr, + TBAAAccessInfo *tbaaInfo = nullptr, bool forPointeeType = false); /// TODO: Add TBAAAccessInfo @@ -482,6 +486,10 @@ class CIRGenModule : public CIRGenTypeCache { return VTables.getItaniumVTableContext(); } + /// getTBAAAccessInfo - Gte TBAA information that describes an access to an + /// object of the given type. + TBAAAccessInfo getTBAAAccessInfo(QualType accessType); + /// This contains all the decls which have definitions but which are deferred /// for emission and therefore should only be output if they are actually /// used. If a decl is in this, then it is known to have not been referenced diff --git a/clang/lib/CIR/CodeGen/CIRGenTBAA.h b/clang/lib/CIR/CodeGen/CIRGenTBAA.h index e69de29bb2d1..ab5ac9b575c0 100644 --- a/clang/lib/CIR/CodeGen/CIRGenTBAA.h +++ b/clang/lib/CIR/CodeGen/CIRGenTBAA.h @@ -0,0 +1,28 @@ +//===--- CIRGenTBAA.h - TBAA information for LLVM CIRGen --------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This is the code that manages TBAA information and defines the TBAA policy +// for the optimizer to use. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENTBAA_H +#define LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENTBAA_H + +namespace cir { + +// TBAAAccessInfo - Describes a memory access in terms of TBAA. +struct TBAAAccessInfo {}; + +/// CIRGenTBAA - This class organizes the cross-module state that is used while +/// lowering AST types to LLVM types. +class CIRGenTBAA {}; + +} // namespace cir + +#endif diff --git a/clang/lib/CIR/CodeGen/CIRGenValue.h b/clang/lib/CIR/CodeGen/CIRGenValue.h index 37acf60457c9..50a925eabdbd 100644 --- a/clang/lib/CIR/CodeGen/CIRGenValue.h +++ b/clang/lib/CIR/CodeGen/CIRGenValue.h @@ -16,6 +16,7 @@ #include "Address.h" #include "CIRGenRecordLayout.h" +#include "CIRGenTBAA.h" #include "clang/AST/ASTContext.h" #include "clang/AST/CharUnits.h" @@ -175,9 +176,12 @@ class LValue { // this lvalue. bool Nontemporal : 1; + TBAAAccessInfo tbaaInfo; + private: void Initialize(clang::QualType Type, clang::Qualifiers Quals, - clang::CharUnits Alignment, LValueBaseInfo BaseInfo) { + clang::CharUnits Alignment, LValueBaseInfo BaseInfo, + TBAAAccessInfo tbaaInfo) { assert((!Alignment.isZero() || Type->isIncompleteType()) && "initializing l-value with zero alignment!"); if (isGlobalReg()) @@ -194,6 +198,7 @@ class LValue { assert(this->Alignment == Alignment.getQuantity() && "Alignment exceeds allowed max!"); this->BaseInfo = BaseInfo; + this->tbaaInfo = tbaaInfo; // TODO: ObjC flags // Initialize Objective-C flags. @@ -270,7 +275,7 @@ class LValue { R.V = address.getPointer(); R.ElementType = address.getElementType(); R.Initialize(T, T.getQualifiers(), address.getAlignment(), - LValueBaseInfo(Source)); + LValueBaseInfo(Source), TBAAAccessInfo()); return R; } @@ -281,25 +286,28 @@ class LValue { R.LVType = Simple; R.V = address.getPointer(); R.ElementType = address.getElementType(); - R.Initialize(T, T.getQualifiers(), address.getAlignment(), LBI); + R.Initialize(T, T.getQualifiers(), address.getAlignment(), LBI, + TBAAAccessInfo()); return R; } static LValue makeAddr(Address address, clang::QualType type, - clang::ASTContext &Context, LValueBaseInfo BaseInfo) { + clang::ASTContext &context, LValueBaseInfo baseInfo, + TBAAAccessInfo tbaaInfo) { clang::Qualifiers qs = type.getQualifiers(); - qs.setObjCGCAttr(Context.getObjCGCAttrKind(type)); + qs.setObjCGCAttr(context.getObjCGCAttrKind(type)); LValue R; R.LVType = Simple; assert(mlir::cast(address.getPointer().getType())); R.V = address.getPointer(); R.ElementType = address.getElementType(); - R.Initialize(type, qs, address.getAlignment(), - BaseInfo); // TODO: TBAAInfo); + R.Initialize(type, qs, address.getAlignment(), baseInfo, tbaaInfo); return R; } + TBAAAccessInfo getTBAAInfo() const { return tbaaInfo; } + const clang::Qualifiers &getQuals() const { return Quals; } clang::Qualifiers &getQuals() { return Quals; } @@ -330,28 +338,29 @@ class LValue { return mlir::cast(VectorElts); } - static LValue MakeVectorElt(Address vecAddress, mlir::Value Index, - clang::QualType type, LValueBaseInfo BaseInfo) { + static LValue MakeVectorElt(Address vecAddress, mlir::Value index, + clang::QualType type, LValueBaseInfo baseInfo, + TBAAAccessInfo tbaaInfo) { LValue R; R.LVType = VectorElt; R.V = vecAddress.getPointer(); R.ElementType = vecAddress.getElementType(); - R.VectorIdx = Index; + R.VectorIdx = index; R.Initialize(type, type.getQualifiers(), vecAddress.getAlignment(), - BaseInfo); + baseInfo, tbaaInfo); return R; } static LValue MakeExtVectorElt(Address vecAddress, mlir::ArrayAttr elts, - clang::QualType type, - LValueBaseInfo baseInfo) { + clang::QualType type, LValueBaseInfo baseInfo, + TBAAAccessInfo tbaaInfo) { LValue R; R.LVType = ExtVectorElt; R.V = vecAddress.getPointer(); R.ElementType = vecAddress.getElementType(); R.VectorElts = elts; R.Initialize(type, type.getQualifiers(), vecAddress.getAlignment(), - baseInfo); + baseInfo, tbaaInfo); return R; } @@ -376,14 +385,16 @@ class LValue { /// bit-field refers to. /// \param Info - The information describing how to perform the bit-field /// access. - static LValue MakeBitfield(Address Addr, const CIRGenBitFieldInfo &Info, - clang::QualType type, LValueBaseInfo BaseInfo) { + static LValue MakeBitfield(Address addr, const CIRGenBitFieldInfo &info, + clang::QualType type, LValueBaseInfo baseInfo, + TBAAAccessInfo tbaaInfo) { LValue R; R.LVType = BitField; - R.V = Addr.getPointer(); - R.ElementType = Addr.getElementType(); - R.BitFieldInfo = &Info; - R.Initialize(type, type.getQualifiers(), Addr.getAlignment(), BaseInfo); + R.V = addr.getPointer(); + R.ElementType = addr.getElementType(); + R.BitFieldInfo = &info; + R.Initialize(type, type.getQualifiers(), addr.getAlignment(), baseInfo, + tbaaInfo); return R; } };