summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorIvan A. Kosarev <ikosarev@accesssoftek.com>2017-10-31 11:05:34 +0000
committerIvan A. Kosarev <ikosarev@accesssoftek.com>2017-10-31 11:05:34 +0000
commit210431c8134fdeff30834467022ce8c306a4c1dd (patch)
tree6c29a4446d88a50a6faf41f6ea008a5b921e877f /lib/CodeGen
parented8a16203bd96d50875a9ce3dff6ada8daa50cff (diff)
[CodeGen] Propagate may-alias'ness of lvalues with TBAA info
This patch fixes various places in clang to propagate may-alias TBAA access descriptors during construction of lvalues, thus eliminating the need for the LValueBaseInfo::MayAlias flag. This is part of D38126 reworked to be a separate patch to simplify review. Differential Revision: https://reviews.llvm.org/D39008 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@316988 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/CGExpr.cpp90
-rw-r--r--lib/CodeGen/CGObjCRuntime.cpp2
-rw-r--r--lib/CodeGen/CGOpenMPRuntime.cpp9
-rw-r--r--lib/CodeGen/CGValue.h12
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp4
-rw-r--r--lib/CodeGen/CodeGenFunction.h11
-rw-r--r--lib/CodeGen/CodeGenModule.cpp12
-rw-r--r--lib/CodeGen/CodeGenModule.h17
-rw-r--r--lib/CodeGen/CodeGenTBAA.cpp73
-rw-r--r--lib/CodeGen/CodeGenTBAA.h55
10 files changed, 173 insertions, 112 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index d3c2f47093..d3b03e556f 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -1538,8 +1538,6 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile,
Load->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node);
}
- if (BaseInfo.getMayAlias())
- TBAAInfo = CGM.getTBAAMayAliasAccessInfo();
CGM.DecorateInstructionWithTBAA(Load, TBAAInfo);
if (EmitScalarRangeCheck(Load, Ty, Loc)) {
@@ -1622,8 +1620,6 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, Address Addr,
Store->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node);
}
- if (BaseInfo.getMayAlias())
- TBAAInfo = CGM.getTBAAMayAliasAccessInfo();
CGM.DecorateInstructionWithTBAA(Store, TBAAInfo);
}
@@ -2170,10 +2166,7 @@ CodeGenFunction::EmitLoadOfReference(LValue RefLVal,
TBAAAccessInfo *PointeeTBAAInfo) {
llvm::LoadInst *Load = Builder.CreateLoad(RefLVal.getAddress(),
RefLVal.isVolatile());
- TBAAAccessInfo RefTBAAInfo = RefLVal.getTBAAInfo();
- if (RefLVal.getBaseInfo().getMayAlias())
- RefTBAAInfo = CGM.getTBAAMayAliasAccessInfo();
- CGM.DecorateInstructionWithTBAA(Load, RefTBAAInfo);
+ CGM.DecorateInstructionWithTBAA(Load, RefLVal.getTBAAInfo());
CharUnits Align = getNaturalTypeAlignment(RefLVal.getType()->getPointeeType(),
PointeeBaseInfo, PointeeTBAAInfo,
@@ -2356,11 +2349,10 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
LValue CapLVal =
EmitCapturedFieldLValue(*this, CapturedStmtInfo->lookup(VD),
CapturedStmtInfo->getContextValue());
- bool MayAlias = CapLVal.getBaseInfo().getMayAlias();
return MakeAddrLValue(
Address(CapLVal.getPointer(), getContext().getDeclAlign(VD)),
- CapLVal.getType(), LValueBaseInfo(AlignmentSource::Decl, MayAlias),
- CGM.getTBAAAccessInfo(CapLVal.getType()));
+ CapLVal.getType(), LValueBaseInfo(AlignmentSource::Decl),
+ CapLVal.getTBAAInfo());
}
assert(isa<BlockDecl>(CurCodeDecl));
@@ -2504,7 +2496,7 @@ LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) {
? emitAddrOfRealComponent(LV.getAddress(), LV.getType())
: emitAddrOfImagComponent(LV.getAddress(), LV.getType()));
LValue ElemLV = MakeAddrLValue(Component, T, LV.getBaseInfo(),
- CGM.getTBAAAccessInfo(T));
+ CGM.getTBAAInfoForSubobject(LV, T));
ElemLV.getQuals().addQualifiers(LV.getQuals());
return ElemLV;
}
@@ -3242,18 +3234,18 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
Addr = emitArraySubscriptGEP(*this, Addr, Idx, EltType, /*inbounds*/ true,
SignedIndices, E->getExprLoc());
return MakeAddrLValue(Addr, EltType, LV.getBaseInfo(),
- CGM.getTBAAAccessInfo(EltType));
+ CGM.getTBAAInfoForSubobject(LV, EltType));
}
- LValueBaseInfo BaseInfo;
- TBAAAccessInfo TBAAInfo;
+ LValueBaseInfo EltBaseInfo;
+ TBAAAccessInfo EltTBAAInfo;
Address Addr = Address::invalid();
if (const VariableArrayType *vla =
getContext().getAsVariableArrayType(E->getType())) {
// The base must be a pointer, which is not an aggregate. Emit
// it. It needs to be emitted first in case it's what captures
// the VLA bounds.
- Addr = EmitPointerWithAlignment(E->getBase(), &BaseInfo, &TBAAInfo);
+ Addr = EmitPointerWithAlignment(E->getBase(), &EltBaseInfo, &EltTBAAInfo);
auto *Idx = EmitIdxAfterBase(/*Promote*/true);
// The element count here is the total number of non-VLA elements.
@@ -3277,7 +3269,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
// Indexing over an interface, as in "NSString *P; P[4];"
// Emit the base pointer.
- Addr = EmitPointerWithAlignment(E->getBase(), &BaseInfo, &TBAAInfo);
+ Addr = EmitPointerWithAlignment(E->getBase(), &EltBaseInfo, &EltTBAAInfo);
auto *Idx = EmitIdxAfterBase(/*Promote*/true);
CharUnits InterfaceSize = getContext().getTypeSizeInChars(OIT);
@@ -3324,18 +3316,18 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
*this, ArrayLV.getAddress(), {CGM.getSize(CharUnits::Zero()), Idx},
E->getType(), !getLangOpts().isSignedOverflowDefined(), SignedIndices,
E->getExprLoc());
- BaseInfo = ArrayLV.getBaseInfo();
- TBAAInfo = CGM.getTBAAAccessInfo(E->getType());
+ EltBaseInfo = ArrayLV.getBaseInfo();
+ EltTBAAInfo = CGM.getTBAAInfoForSubobject(ArrayLV, E->getType());
} else {
// The base must be a pointer; emit it with an estimate of its alignment.
- Addr = EmitPointerWithAlignment(E->getBase(), &BaseInfo, &TBAAInfo);
+ Addr = EmitPointerWithAlignment(E->getBase(), &EltBaseInfo, &EltTBAAInfo);
auto *Idx = EmitIdxAfterBase(/*Promote*/true);
Addr = emitArraySubscriptGEP(*this, Addr, Idx, E->getType(),
!getLangOpts().isSignedOverflowDefined(),
SignedIndices, E->getExprLoc());
}
- LValue LV = MakeAddrLValue(Addr, E->getType(), BaseInfo, TBAAInfo);
+ LValue LV = MakeAddrLValue(Addr, E->getType(), EltBaseInfo, EltTBAAInfo);
if (getLangOpts().ObjC1 &&
getLangOpts().getGC() != LangOptions::NonGC) {
@@ -3374,9 +3366,12 @@ static Address emitOMPArraySectionBase(CodeGenFunction &CGF, const Expr *Base,
return CGF.Builder.CreateElementBitCast(Addr,
CGF.ConvertTypeForMem(ElTy));
}
- LValueBaseInfo TypeInfo;
- CharUnits Align = CGF.getNaturalTypeAlignment(ElTy, &TypeInfo);
- BaseInfo.mergeForCast(TypeInfo);
+ LValueBaseInfo TypeBaseInfo;
+ TBAAAccessInfo TypeTBAAInfo;
+ CharUnits Align = CGF.getNaturalTypeAlignment(ElTy, &TypeBaseInfo,
+ &TypeTBAAInfo);
+ BaseInfo.mergeForCast(TypeBaseInfo);
+ TBAAInfo = CGF.CGM.mergeTBAAInfoForCast(TBAAInfo, TypeTBAAInfo);
return Address(CGF.Builder.CreateLoad(BaseLVal.getAddress()), Align);
}
return CGF.EmitPointerWithAlignment(Base, &BaseInfo, &TBAAInfo);
@@ -3522,7 +3517,7 @@ LValue CodeGenFunction::EmitOMPArraySectionExpr(const OMPArraySectionExpr *E,
ResultExprTy, !getLangOpts().isSignedOverflowDefined(),
/*SignedIndices=*/false, E->getExprLoc());
BaseInfo = ArrayLV.getBaseInfo();
- TBAAInfo = CGM.getTBAAAccessInfo(ResultExprTy);
+ TBAAInfo = CGM.getTBAAInfoForSubobject(ArrayLV, ResultExprTy);
} else {
Address Base = emitOMPArraySectionBase(*this, E->getBase(), BaseInfo,
TBAAInfo, BaseTy, ResultExprTy,
@@ -3712,7 +3707,7 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
QualType fieldType =
field->getType().withCVRQualifiers(base.getVRQualifiers());
// TODO: Support TBAA for bit fields.
- LValueBaseInfo FieldBaseInfo(BaseInfo.getAlignmentSource(), false);
+ LValueBaseInfo FieldBaseInfo(BaseInfo.getAlignmentSource());
return LValue::MakeBitfield(Addr, Info, fieldType, FieldBaseInfo,
TBAAAccessInfo());
}
@@ -3723,16 +3718,14 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
QualType FieldType = field->getType();
const RecordDecl *rec = field->getParent();
AlignmentSource BaseAlignSource = BaseInfo.getAlignmentSource();
- LValueBaseInfo FieldBaseInfo(getFieldAlignmentSource(BaseAlignSource), false);
+ LValueBaseInfo FieldBaseInfo(getFieldAlignmentSource(BaseAlignSource));
TBAAAccessInfo FieldTBAAInfo;
- if (BaseInfo.getMayAlias() || rec->hasAttr<MayAliasAttr>() ||
- FieldType->isVectorType()) {
- FieldBaseInfo.setMayAlias(true);
- FieldTBAAInfo = CGM.getTBAAMayAliasAccessInfo();
+ if (base.getTBAAInfo().isMayAlias() ||
+ rec->hasAttr<MayAliasAttr>() || FieldType->isVectorType()) {
+ FieldTBAAInfo = TBAAAccessInfo::getMayAliasInfo();
} else if (rec->isUnion()) {
// TODO: Support TBAA for unions.
- FieldBaseInfo.setMayAlias(true);
- FieldTBAAInfo = CGM.getTBAAMayAliasAccessInfo();
+ FieldTBAAInfo = TBAAAccessInfo::getMayAliasInfo();
} else {
// If no base type been assigned for the base access, then try to generate
// one for this base lvalue.
@@ -3818,13 +3811,14 @@ CodeGenFunction::EmitLValueForFieldInitialization(LValue Base,
llvm::Type *llvmType = ConvertTypeForMem(FieldType);
V = Builder.CreateElementBitCast(V, llvmType, Field->getName());
- // TODO: access-path TBAA?
+ // TODO: Generate TBAA information that describes this access as a structure
+ // member access and not just an access to an object of the field's type. This
+ // should be similar to what we do in EmitLValueForField().
LValueBaseInfo BaseInfo = Base.getBaseInfo();
- LValueBaseInfo FieldBaseInfo(
- getFieldAlignmentSource(BaseInfo.getAlignmentSource()),
- BaseInfo.getMayAlias());
+ AlignmentSource FieldAlignSource = BaseInfo.getAlignmentSource();
+ LValueBaseInfo FieldBaseInfo(getFieldAlignmentSource(FieldAlignSource));
return MakeAddrLValue(V, FieldType, FieldBaseInfo,
- CGM.getTBAAAccessInfo(FieldType));
+ CGM.getTBAAInfoForSubobject(Base, FieldType));
}
LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr *E){
@@ -3937,11 +3931,10 @@ EmitConditionalOperatorLValue(const AbstractConditionalOperator *expr) {
AlignmentSource alignSource =
std::max(lhs->getBaseInfo().getAlignmentSource(),
rhs->getBaseInfo().getAlignmentSource());
- bool MayAlias = lhs->getBaseInfo().getMayAlias() ||
- rhs->getBaseInfo().getMayAlias();
- return MakeAddrLValue(result, expr->getType(),
- LValueBaseInfo(alignSource, MayAlias),
- CGM.getTBAAAccessInfo(expr->getType()));
+ TBAAAccessInfo TBAAInfo = CGM.mergeTBAAInfoForConditionalOperator(
+ lhs->getTBAAInfo(), rhs->getTBAAInfo());
+ return MakeAddrLValue(result, expr->getType(), LValueBaseInfo(alignSource),
+ TBAAInfo);
} else {
assert((lhs || rhs) &&
"both operands of glvalue conditional are throw-expressions?");
@@ -4039,8 +4032,11 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
This, DerivedClassDecl, E->path_begin(), E->path_end(),
/*NullCheckValue=*/false, E->getExprLoc());
+ // TODO: Support accesses to members of base classes in TBAA. For now, we
+ // conservatively pretend that the complete object is of the base class
+ // type.
return MakeAddrLValue(Base, E->getType(), LV.getBaseInfo(),
- CGM.getTBAAAccessInfo(E->getType()));
+ CGM.getTBAAInfoForSubobject(LV, E->getType()));
}
case CK_ToUnion:
return EmitAggExprToLValue(E);
@@ -4068,7 +4064,7 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
CFITCK_DerivedCast, E->getLocStart());
return MakeAddrLValue(Derived, E->getType(), LV.getBaseInfo(),
- CGM.getTBAAAccessInfo(E->getType()));
+ CGM.getTBAAInfoForSubobject(LV, E->getType()));
}
case CK_LValueBitCast: {
// This must be a reinterpret_cast (or c-style equivalent).
@@ -4085,14 +4081,14 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
CFITCK_UnrelatedCast, E->getLocStart());
return MakeAddrLValue(V, E->getType(), LV.getBaseInfo(),
- CGM.getTBAAAccessInfo(E->getType()));
+ CGM.getTBAAInfoForSubobject(LV, E->getType()));
}
case CK_ObjCObjectLValueCast: {
LValue LV = EmitLValue(E->getSubExpr());
Address V = Builder.CreateElementBitCast(LV.getAddress(),
ConvertType(E->getType()));
return MakeAddrLValue(V, E->getType(), LV.getBaseInfo(),
- CGM.getTBAAAccessInfo(E->getType()));
+ CGM.getTBAAInfoForSubobject(LV, E->getType()));
}
case CK_ZeroToOCLQueue:
llvm_unreachable("NULL to OpenCL queue lvalue cast is not valid");
diff --git a/lib/CodeGen/CGObjCRuntime.cpp b/lib/CodeGen/CGObjCRuntime.cpp
index 74b8698b6d..2f886fd82c 100644
--- a/lib/CodeGen/CGObjCRuntime.cpp
+++ b/lib/CodeGen/CGObjCRuntime.cpp
@@ -110,7 +110,7 @@ LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF,
llvm::Type::getIntNTy(CGF.getLLVMContext(),
Info->StorageSize));
return LValue::MakeBitfield(Addr, *Info, IvarTy,
- LValueBaseInfo(AlignmentSource::Decl, false),
+ LValueBaseInfo(AlignmentSource::Decl),
TBAAAccessInfo());
}
diff --git a/lib/CodeGen/CGOpenMPRuntime.cpp b/lib/CodeGen/CGOpenMPRuntime.cpp
index 0a798b8903..35929af95e 100644
--- a/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -993,7 +993,7 @@ void ReductionCodeGen::emitInitialization(
CGF.Builder.CreateElementBitCast(SharedLVal.getAddress(),
CGF.ConvertTypeForMem(SharedType)),
SharedType, SharedAddresses[N].first.getBaseInfo(),
- CGF.CGM.getTBAAAccessInfo(SharedType));
+ CGF.CGM.getTBAAInfoForSubobject(SharedAddresses[N].first, SharedType));
if (CGF.getContext().getAsArrayType(PrivateVD->getType())) {
emitAggregateInitialization(CGF, N, PrivateAddr, SharedLVal, DRD);
} else if (DRD && (DRD->getInitializer() || !PrivateVD->hasInit())) {
@@ -1046,7 +1046,7 @@ static LValue loadToBegin(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy,
CGF.Builder.CreateElementBitCast(BaseLV.getAddress(),
CGF.ConvertTypeForMem(ElTy)),
BaseLV.getType(), BaseLV.getBaseInfo(),
- CGF.CGM.getTBAAAccessInfo(BaseLV.getType()));
+ CGF.CGM.getTBAAInfoForSubobject(BaseLV, BaseLV.getType()));
}
static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy,
@@ -4084,9 +4084,8 @@ static void emitPrivatesInit(CodeGenFunction &CGF,
SharedRefLValue = CGF.MakeAddrLValue(
Address(SharedRefLValue.getPointer(), C.getDeclAlign(OriginalVD)),
SharedRefLValue.getType(),
- LValueBaseInfo(AlignmentSource::Decl,
- SharedRefLValue.getBaseInfo().getMayAlias()),
- CGF.CGM.getTBAAAccessInfo(SharedRefLValue.getType()));
+ LValueBaseInfo(AlignmentSource::Decl),
+ SharedRefLValue.getTBAAInfo());
QualType Type = OriginalVD->getType();
if (Type->isArrayType()) {
// Initialize firstprivate array.
diff --git a/lib/CodeGen/CGValue.h b/lib/CodeGen/CGValue.h
index a823ef65b6..7d07ea4516 100644
--- a/lib/CodeGen/CGValue.h
+++ b/lib/CodeGen/CGValue.h
@@ -149,20 +149,15 @@ static inline AlignmentSource getFieldAlignmentSource(AlignmentSource Source) {
class LValueBaseInfo {
AlignmentSource AlignSource;
- bool MayAlias;
public:
- explicit LValueBaseInfo(AlignmentSource Source = AlignmentSource::Type,
- bool Alias = false)
- : AlignSource(Source), MayAlias(Alias) {}
+ explicit LValueBaseInfo(AlignmentSource Source = AlignmentSource::Type)
+ : AlignSource(Source) {}
AlignmentSource getAlignmentSource() const { return AlignSource; }
void setAlignmentSource(AlignmentSource Source) { AlignSource = Source; }
- bool getMayAlias() const { return MayAlias; }
- void setMayAlias(bool Alias) { MayAlias = Alias; }
void mergeForCast(const LValueBaseInfo &Info) {
setAlignmentSource(Info.getAlignmentSource());
- setMayAlias(getMayAlias() || Info.getMayAlias());
}
};
@@ -426,8 +421,7 @@ public:
R.LVType = GlobalReg;
R.V = Reg.getPointer();
R.Initialize(type, type.getQualifiers(), Reg.getAlignment(),
- LValueBaseInfo(AlignmentSource::Decl, false),
- TBAAAccessInfo());
+ LValueBaseInfo(AlignmentSource::Decl), TBAAAccessInfo());
return R;
}
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index b6f8770f51..234d1a2849 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -137,13 +137,13 @@ CharUnits CodeGenFunction::getNaturalTypeAlignment(QualType T,
if (auto TT = T->getAs<TypedefType>()) {
if (auto Align = TT->getDecl()->getMaxAlignment()) {
if (BaseInfo)
- *BaseInfo = LValueBaseInfo(AlignmentSource::AttributedType, false);
+ *BaseInfo = LValueBaseInfo(AlignmentSource::AttributedType);
return getContext().toCharUnitsFromBits(Align);
}
}
if (BaseInfo)
- *BaseInfo = LValueBaseInfo(AlignmentSource::Type, false);
+ *BaseInfo = LValueBaseInfo(AlignmentSource::Type);
CharUnits Alignment;
if (T->isIncompleteType()) {
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 2d919876e2..e1034c129d 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -1919,8 +1919,7 @@ public:
LValue MakeAddrLValue(Address Addr, QualType T,
AlignmentSource Source = AlignmentSource::Type) {
- return LValue::MakeAddr(Addr, T, getContext(),
- LValueBaseInfo(Source, false),
+ return LValue::MakeAddr(Addr, T, getContext(), LValueBaseInfo(Source),
CGM.getTBAAAccessInfo(T));
}
@@ -1932,8 +1931,7 @@ public:
LValue MakeAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment,
AlignmentSource Source = AlignmentSource::Type) {
return LValue::MakeAddr(Address(V, Alignment), T, getContext(),
- LValueBaseInfo(Source, false),
- CGM.getTBAAAccessInfo(T));
+ LValueBaseInfo(Source), CGM.getTBAAAccessInfo(T));
}
LValue MakeAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment,
@@ -3092,8 +3090,7 @@ public:
SourceLocation Loc,
AlignmentSource Source = AlignmentSource::Type,
bool isNontemporal = false) {
- return EmitLoadOfScalar(Addr, Volatile, Ty, Loc,
- LValueBaseInfo(Source, false),
+ return EmitLoadOfScalar(Addr, Volatile, Ty, Loc, LValueBaseInfo(Source),
CGM.getTBAAAccessInfo(Ty), isNontemporal);
}
@@ -3115,7 +3112,7 @@ public:
bool Volatile, QualType Ty,
AlignmentSource Source = AlignmentSource::Type,
bool isInit = false, bool isNontemporal = false) {
- EmitStoreOfScalar(Value, Addr, Volatile, Ty, LValueBaseInfo(Source, false),
+ EmitStoreOfScalar(Value, Addr, Volatile, Ty, LValueBaseInfo(Source),
CGM.getTBAAAccessInfo(Ty), isInit, isNontemporal);
}
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 4f7d6eaed6..2254f3e70d 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -606,17 +606,19 @@ llvm::MDNode *CodeGenModule::getTBAAAccessTagInfo(TBAAAccessInfo Info) {
return TBAA->getAccessTagInfo(Info);
}
-TBAAAccessInfo CodeGenModule::getTBAAMayAliasAccessInfo() {
+TBAAAccessInfo CodeGenModule::mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo,
+ TBAAAccessInfo TargetInfo) {
if (!TBAA)
return TBAAAccessInfo();
- return TBAA->getMayAliasAccessInfo();
+ return TBAA->mergeTBAAInfoForCast(SourceInfo, TargetInfo);
}
-TBAAAccessInfo CodeGenModule::mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo,
- TBAAAccessInfo TargetInfo) {
+TBAAAccessInfo
+CodeGenModule::mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA,
+ TBAAAccessInfo InfoB) {
if (!TBAA)
return TBAAAccessInfo();
- return TBAA->mergeTBAAInfoForCast(SourceInfo, TargetInfo);
+ return TBAA->mergeTBAAInfoForConditionalOperator(InfoA, InfoB);
}
void CodeGenModule::DecorateInstructionWithTBAA(llvm::Instruction *Inst,
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index ebc1ec65cf..21bab6cfa0 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -673,15 +673,24 @@ public:
/// getTBAAAccessTagInfo - Get TBAA tag for a given memory access.
llvm::MDNode *getTBAAAccessTagInfo(TBAAAccessInfo Info);
- /// getTBAAMayAliasAccessInfo - Get TBAA information that represents
- /// may-alias accesses.
- TBAAAccessInfo getTBAAMayAliasAccessInfo();
-
/// mergeTBAAInfoForCast - Get merged TBAA information for the purposes of
/// type casts.
TBAAAccessInfo mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo,
TBAAAccessInfo TargetInfo);
+ /// mergeTBAAInfoForConditionalOperator - Get merged TBAA information for the
+ /// purposes of conditional operator.
+ TBAAAccessInfo mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA,
+ TBAAAccessInfo InfoB);
+
+ /// getTBAAInfoForSubobject - Get TBAA information for an access with a given
+ /// base lvalue.
+ TBAAAccessInfo getTBAAInfoForSubobject(LValue Base, QualType AccessType) {
+ if (Base.getTBAAInfo().isMayAlias())
+ return TBAAAccessInfo::getMayAliasInfo();
+ return getTBAAAccessInfo(AccessType);
+ }
+
bool isTypeConstant(QualType QTy, bool ExcludeCtorDtor);
bool isPaddedAtomicType(QualType type);
diff --git a/lib/CodeGen/CodeGenTBAA.cpp b/lib/CodeGen/CodeGenTBAA.cpp
index 6f9747e2f0..66fdb5f799 100644
--- a/lib/CodeGen/CodeGenTBAA.cpp
+++ b/lib/CodeGen/CodeGenTBAA.cpp
@@ -88,6 +88,25 @@ static bool TypeHasMayAlias(QualType QTy) {
return false;
}
+/// Check if the given type is a valid base type to be used in access tags.
+static bool isValidBaseType(QualType QTy) {
+ if (QTy->isReferenceType())
+ return false;
+ if (const RecordType *TTy = QTy->getAs<RecordType>()) {
+ const RecordDecl *RD = TTy->getDecl()->getDefinition();
+ // Incomplete types are not valid base access types.
+ if (!RD)
+ return false;
+ if (RD->hasFlexibleArrayMember())
+ return false;
+ // RD can be struct, union, class, interface or enum.
+ // For now, we only handle struct and class.
+ if (RD->isStruct() || RD->isClass())
+ return true;
+ }
+ return false;
+}
+
llvm::MDNode *CodeGenTBAA::getTypeInfo(QualType QTy) {
// At -O0 or relaxed aliasing, TBAA is not emitted for regular types.
if (CodeGenOpts.OptimizationLevel == 0 || CodeGenOpts.RelaxedAliasing)
@@ -98,8 +117,16 @@ llvm::MDNode *CodeGenTBAA::getTypeInfo(QualType QTy) {
if (TypeHasMayAlias(QTy))
return getChar();
- const Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
+ // We need this function to not fall back to returning the "omnipotent char"
+ // type node for aggregate and union types. Otherwise, any dereference of an
+ // aggregate will result into the may-alias access descriptor, meaning all
+ // subsequent accesses to direct and indirect members of that aggregate will
+ // be considered may-alias too.
+ // TODO: Combine getTypeInfo() and getBaseTypeInfo() into a single function.
+ if (isValidBaseType(QTy))
+ return getBaseTypeInfo(QTy);
+ const Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
if (llvm::MDNode *N = MetadataCache[Ty])
return N;
@@ -232,20 +259,6 @@ CodeGenTBAA::getTBAAStructInfo(QualType QTy) {
return StructMetadataCache[Ty] = nullptr;
}
-/// Check if the given type is a valid base type to be used in access tags.
-static bool isValidBaseType(QualType QTy) {
- if (const RecordType *TTy = QTy->getAs<RecordType>()) {
- const RecordDecl *RD = TTy->getDecl()->getDefinition();
- if (RD->hasFlexibleArrayMember())
- return false;
- // RD can be struct, union, class, interface or enum.
- // For now, we only handle struct and class.
- if (RD->isStruct() || RD->isClass())
- return true;
- }
- return false;
-}
-
llvm::MDNode *CodeGenTBAA::getBaseTypeInfo(QualType QTy) {
if (!isValidBaseType(QTy))
return nullptr;
@@ -288,6 +301,9 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfo(QualType QTy) {
}
llvm::MDNode *CodeGenTBAA::getAccessTagInfo(TBAAAccessInfo Info) {
+ if (Info.isMayAlias())
+ Info = TBAAAccessInfo(getChar());
+
if (!Info.AccessType)
return nullptr;
@@ -306,14 +322,27 @@ llvm::MDNode *CodeGenTBAA::getAccessTagInfo(TBAAAccessInfo Info) {
Info.Offset);
}
-TBAAAccessInfo CodeGenTBAA::getMayAliasAccessInfo() {
- return TBAAAccessInfo(getChar());
-}
-
TBAAAccessInfo CodeGenTBAA::mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo,
TBAAAccessInfo TargetInfo) {
- TBAAAccessInfo MayAliasInfo = getMayAliasAccessInfo();
- if (SourceInfo == MayAliasInfo || TargetInfo == MayAliasInfo)
- return MayAliasInfo;
+ if (SourceInfo.isMayAlias() || TargetInfo.isMayAlias())
+ return TBAAAccessInfo::getMayAliasInfo();
return TargetInfo;
}
+
+TBAAAccessInfo
+CodeGenTBAA::mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA,
+ TBAAAccessInfo InfoB) {
+ if (InfoA == InfoB)
+ return InfoA;
+
+ if (!InfoA || !InfoB)
+ return TBAAAccessInfo();
+
+ if (InfoA.isMayAlias() || InfoB.isMayAlias())
+ return TBAAAccessInfo::getMayAliasInfo();
+
+ // TODO: Implement the rest of the logic here. For example, two accesses
+ // with same final access types result in an access to an object of that final
+ // access type regardless of their base types.
+ return TBAAAccessInfo::getMayAliasInfo();
+}
diff --git a/lib/CodeGen/CodeGenTBAA.h b/lib/CodeGen/CodeGenTBAA.h
index 7f499daf9d..e4f459ce93 100644
--- a/lib/CodeGen/CodeGenTBAA.h
+++ b/lib/CodeGen/CodeGenTBAA.h
@@ -32,11 +32,22 @@ namespace clang {
namespace CodeGen {
class CGRecordLayout;
+// TBAAAccessKind - A kind of TBAA memory access descriptor.
+enum class TBAAAccessKind : unsigned {
+ Ordinary,
+ MayAlias,
+};
+
// TBAAAccessInfo - Describes a memory access in terms of TBAA.
struct TBAAAccessInfo {
+ TBAAAccessInfo(TBAAAccessKind Kind, llvm::MDNode *BaseType,
+ llvm::MDNode *AccessType, uint64_t Offset)
+ : Kind(Kind), BaseType(BaseType), AccessType(AccessType), Offset(Offset)
+ {}
+
TBAAAccessInfo(llvm::MDNode *BaseType, llvm::MDNode *AccessType,
uint64_t Offset)
- : BaseType(BaseType), AccessType(AccessType), Offset(Offset)
+ : TBAAAccessInfo(TBAAAccessKind::Ordinary, BaseType, AccessType, Offset)
{}
explicit TBAAAccessInfo(llvm::MDNode *AccessType)
@@ -47,12 +58,31 @@ struct TBAAAccessInfo {
: TBAAAccessInfo(/* AccessType= */ nullptr)
{}
+ static TBAAAccessInfo getMayAliasInfo() {
+ return TBAAAccessInfo(TBAAAccessKind::MayAlias, /* BaseType= */ nullptr,
+ /* AccessType= */ nullptr, /* Offset= */ 0);
+ }
+
+ bool isMayAlias() const { return Kind == TBAAAccessKind::MayAlias; }
+
bool operator==(const TBAAAccessInfo &Other) const {
- return BaseType == Other.BaseType &&
+ return Kind == Other.Kind &&
+ BaseType == Other.BaseType &&
AccessType == Other.AccessType &&
Offset == Other.Offset;
}
+ bool operator!=(const TBAAAccessInfo &Other) const {
+ return !(*this == Other);
+ }
+
+ explicit operator bool() const {
+ return *this != TBAAAccessInfo();
+ }
+
+ /// Kind - The kind of the access descriptor.
+ TBAAAccessKind Kind;
+
/// BaseType - The base/leading access type. May be null if this access
/// descriptor represents an access that is not considered to be an access
/// to an aggregate or union member.
@@ -139,14 +169,15 @@ public:
/// getAccessTagInfo - Get TBAA tag for a given memory access.
llvm::MDNode *getAccessTagInfo(TBAAAccessInfo Info);
- /// getMayAliasAccessInfo - Get TBAA information that represents may-alias
- /// accesses.
- TBAAAccessInfo getMayAliasAccessInfo();
-
/// mergeTBAAInfoForCast - Get merged TBAA information for the purpose of
/// type casts.
TBAAAccessInfo mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo,
TBAAAccessInfo TargetInfo);
+
+ /// mergeTBAAInfoForConditionalOperator - Get merged TBAA information for the
+ /// purpose of conditional operator.
+ TBAAAccessInfo mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA,
+ TBAAAccessInfo InfoB);
};
} // end namespace CodeGen
@@ -156,30 +187,34 @@ namespace llvm {
template<> struct DenseMapInfo<clang::CodeGen::TBAAAccessInfo> {
static clang::CodeGen::TBAAAccessInfo getEmptyKey() {
+ unsigned UnsignedKey = DenseMapInfo<unsigned>::getEmptyKey();
return clang::CodeGen::TBAAAccessInfo(
+ static_cast<clang::CodeGen::TBAAAccessKind>(UnsignedKey),
DenseMapInfo<MDNode *>::getEmptyKey(),
DenseMapInfo<MDNode *>::getEmptyKey(),
DenseMapInfo<uint64_t>::getEmptyKey());
}
static clang::CodeGen::TBAAAccessInfo getTombstoneKey() {
+ unsigned UnsignedKey = DenseMapInfo<unsigned>::getTombstoneKey();
return clang::CodeGen::TBAAAccessInfo(
+ static_cast<clang::CodeGen::TBAAAccessKind>(UnsignedKey),
DenseMapInfo<MDNode *>::getTombstoneKey(),
DenseMapInfo<MDNode *>::getTombstoneKey(),
DenseMapInfo<uint64_t>::getTombstoneKey());
}
static unsigned getHashValue(const clang::CodeGen::TBAAAccessInfo &Val) {
- return DenseMapInfo<MDNode *>::getHashValue(Val.BaseType) ^
+ auto KindValue = static_cast<unsigned>(Val.Kind);
+ return DenseMapInfo<unsigned>::getHashValue(KindValue) ^
+ DenseMapInfo<MDNode *>::getHashValue(Val.BaseType) ^
DenseMapInfo<MDNode *>::getHashValue(Val.AccessType) ^
DenseMapInfo<uint64_t>::getHashValue(Val.Offset);
}
static bool isEqual(const clang::CodeGen::TBAAAccessInfo &LHS,
const clang::CodeGen::TBAAAccessInfo &RHS) {
- return LHS.BaseType == RHS.BaseType &&
- LHS.AccessType == RHS.AccessType &&
- LHS.Offset == RHS.Offset;
+ return LHS == RHS;
}
};