[CodeGen] Generate TBAA info for reference loads

Differential Revision: https://reviews.llvm.org/D39177

llvm-svn: 316896
This commit is contained in:
Ivan A. Kosarev 2017-10-30 11:49:31 +00:00
parent f5142bf97f
commit 9f9d157517
6 changed files with 81 additions and 69 deletions

View File

@ -1189,8 +1189,8 @@ Address CodeGenFunction::GetAddrOfBlockDecl(const VarDecl *variable,
variable->getName());
}
if (auto refType = capture.fieldType()->getAs<ReferenceType>())
addr = EmitLoadOfReference(addr, refType);
if (capture.fieldType()->isReferenceType())
addr = EmitLoadOfReference(MakeAddrLValue(addr, capture.fieldType()));
return addr;
}

View File

@ -2160,22 +2160,30 @@ static LValue EmitThreadPrivateVarDeclLValue(
return CGF.MakeAddrLValue(Addr, T, AlignmentSource::Decl);
}
Address CodeGenFunction::EmitLoadOfReference(Address Addr,
const ReferenceType *RefTy,
LValueBaseInfo *BaseInfo,
TBAAAccessInfo *TBAAInfo) {
llvm::Value *Ptr = Builder.CreateLoad(Addr);
return Address(Ptr, getNaturalTypeAlignment(RefTy->getPointeeType(),
BaseInfo, TBAAInfo,
/* forPointeeType= */ true));
Address
CodeGenFunction::EmitLoadOfReference(LValue RefLVal,
LValueBaseInfo *PointeeBaseInfo,
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);
CharUnits Align = getNaturalTypeAlignment(RefLVal.getType()->getPointeeType(),
PointeeBaseInfo, PointeeTBAAInfo,
/* forPointeeType= */ true);
return Address(Load, Align);
}
LValue CodeGenFunction::EmitLoadOfReferenceLValue(Address RefAddr,
const ReferenceType *RefTy) {
LValueBaseInfo BaseInfo;
TBAAAccessInfo TBAAInfo;
Address Addr = EmitLoadOfReference(RefAddr, RefTy, &BaseInfo, &TBAAInfo);
return MakeAddrLValue(Addr, RefTy->getPointeeType(), BaseInfo, TBAAInfo);
LValue CodeGenFunction::EmitLoadOfReferenceLValue(LValue RefLVal) {
LValueBaseInfo PointeeBaseInfo;
TBAAAccessInfo PointeeTBAAInfo;
Address PointeeAddr = EmitLoadOfReference(RefLVal, &PointeeBaseInfo,
&PointeeTBAAInfo);
return MakeAddrLValue(PointeeAddr, RefLVal.getType()->getPointeeType(),
PointeeBaseInfo, PointeeTBAAInfo);
}
Address CodeGenFunction::EmitLoadOfPointer(Address Ptr,
@ -2210,17 +2218,15 @@ static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF,
V = EmitBitCastOfLValueToProperType(CGF, V, RealVarTy);
CharUnits Alignment = CGF.getContext().getDeclAlign(VD);
Address Addr(V, Alignment);
LValue LV;
// Emit reference to the private copy of the variable if it is an OpenMP
// threadprivate variable.
if (CGF.getLangOpts().OpenMP && VD->hasAttr<OMPThreadPrivateDeclAttr>())
return EmitThreadPrivateVarDeclLValue(CGF, VD, T, Addr, RealVarTy,
E->getExprLoc());
if (auto RefTy = VD->getType()->getAs<ReferenceType>()) {
LV = CGF.EmitLoadOfReferenceLValue(Addr, RefTy);
} else {
LV = CGF.MakeAddrLValue(Addr, T, AlignmentSource::Decl);
}
LValue LV = VD->getType()->isReferenceType() ?
CGF.EmitLoadOfReferenceLValue(Addr, VD->getType(),
AlignmentSource::Decl) :
CGF.MakeAddrLValue(Addr, T, AlignmentSource::Decl);
setObjCGCLValueClass(CGF.getContext(), E, LV);
return LV;
}
@ -2338,8 +2344,9 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
else if (CapturedStmtInfo) {
auto I = LocalDeclMap.find(VD);
if (I != LocalDeclMap.end()) {
if (auto RefTy = VD->getType()->getAs<ReferenceType>())
return EmitLoadOfReferenceLValue(I->second, RefTy);
if (VD->getType()->isReferenceType())
return EmitLoadOfReferenceLValue(I->second, VD->getType(),
AlignmentSource::Decl);
return MakeAddrLValue(I->second, T);
}
LValue CapLVal =
@ -2410,12 +2417,9 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
}
// Drill into reference types.
LValue LV;
if (auto RefTy = VD->getType()->getAs<ReferenceType>()) {
LV = EmitLoadOfReferenceLValue(addr, RefTy);
} else {
LV = MakeAddrLValue(addr, T, AlignmentSource::Decl);
}
LValue LV = VD->getType()->isReferenceType() ?
EmitLoadOfReferenceLValue(addr, VD->getType(), AlignmentSource::Decl) :
MakeAddrLValue(addr, T, AlignmentSource::Decl);
bool isLocalStorage = VD->hasLocalStorage();
@ -3748,7 +3752,7 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
}
Address addr = base.getAddress();
unsigned cvr = base.getVRQualifiers();
unsigned RecordCVR = base.getVRQualifiers();
if (rec->isUnion()) {
// For unions, there is no pointer adjustment.
assert(!FieldType->isReferenceType() && "union has reference member");
@ -3763,22 +3767,16 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
addr = emitAddrOfFieldStorage(*this, addr, field);
// If this is a reference field, load the reference right now.
if (const ReferenceType *refType = FieldType->getAs<ReferenceType>()) {
llvm::LoadInst *load = Builder.CreateLoad(addr, "ref");
if (cvr & Qualifiers::Volatile) load->setVolatile(true);
if (FieldType->isReferenceType()) {
LValue RefLVal = MakeAddrLValue(addr, FieldType, FieldBaseInfo,
FieldTBAAInfo);
if (RecordCVR & Qualifiers::Volatile)
RefLVal.getQuals().setVolatile(true);
addr = EmitLoadOfReference(RefLVal, &FieldBaseInfo, &FieldTBAAInfo);
CGM.DecorateInstructionWithTBAA(load, FieldTBAAInfo);
FieldType = refType->getPointeeType();
CharUnits Align = getNaturalTypeAlignment(FieldType, &FieldBaseInfo,
&FieldTBAAInfo,
/* forPointeeType= */ true);
addr = Address(load, Align);
// Qualifiers on the struct don't apply to the referencee, and
// we'll pick up CVR from the actual type later, so reset these
// additional qualifiers now.
cvr = 0;
// Qualifiers on the struct don't apply to the referencee.
RecordCVR = 0;
FieldType = FieldType->getPointeeType();
}
}
@ -3793,7 +3791,7 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
addr = EmitFieldAnnotations(field, addr);
LValue LV = MakeAddrLValue(addr, FieldType, FieldBaseInfo, FieldTBAAInfo);
LV.getQuals().addCVRQualifiers(cvr);
LV.getQuals().addCVRQualifiers(RecordCVR);
// __weak attribute on a field is ignored.
if (LV.getQuals().getObjCGCAttr() == Qualifiers::Weak)

View File

@ -1037,8 +1037,8 @@ static LValue loadToBegin(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy,
if (auto *PtrTy = BaseTy->getAs<PointerType>())
BaseLV = CGF.EmitLoadOfPointerLValue(BaseLV.getAddress(), PtrTy);
else {
BaseLV = CGF.EmitLoadOfReferenceLValue(BaseLV.getAddress(),
BaseTy->castAs<ReferenceType>());
LValue RefLVal = CGF.MakeAddrLValue(BaseLV.getAddress(), BaseTy);
BaseLV = CGF.EmitLoadOfReferenceLValue(RefLVal);
}
BaseTy = BaseTy->getPointeeType();
}

View File

@ -417,8 +417,7 @@ static llvm::Function *emitOutlinedFunctionPrologue(
Address ArgAddr = ArgLVal.getAddress();
if (!VarTy->isReferenceType()) {
if (ArgLVal.getType()->isLValueReferenceType()) {
ArgAddr = CGF.EmitLoadOfReference(
ArgAddr, ArgLVal.getType()->castAs<ReferenceType>());
ArgAddr = CGF.EmitLoadOfReference(ArgLVal);
} else if (!VarTy->isVariablyModifiedType() || !VarTy->isPointerType()) {
assert(ArgLVal.getType()->isPointerType());
ArgAddr = CGF.EmitLoadOfPointer(

View File

@ -1952,10 +1952,17 @@ public:
LValueBaseInfo *BaseInfo = nullptr,
TBAAAccessInfo *TBAAInfo = nullptr);
Address EmitLoadOfReference(Address Ref, const ReferenceType *RefTy,
LValueBaseInfo *BaseInfo = nullptr,
TBAAAccessInfo *TBAAInfo = nullptr);
LValue EmitLoadOfReferenceLValue(Address Ref, const ReferenceType *RefTy);
Address EmitLoadOfReference(LValue RefLVal,
LValueBaseInfo *PointeeBaseInfo = nullptr,
TBAAAccessInfo *PointeeTBAAInfo = nullptr);
LValue EmitLoadOfReferenceLValue(LValue RefLVal);
LValue EmitLoadOfReferenceLValue(Address RefAddr, QualType RefTy,
AlignmentSource Source =
AlignmentSource::Type) {
LValue RefLVal = MakeAddrLValue(RefAddr, RefTy, LValueBaseInfo(Source),
CGM.getTBAAAccessInfo(RefTy));
return EmitLoadOfReferenceLValue(RefLVal);
}
Address EmitLoadOfPointer(Address Ptr, const PointerType *PtrTy,
LValueBaseInfo *BaseInfo = nullptr,

View File

@ -6,24 +6,32 @@ struct S;
struct B {
S &s;
B(S &s) : s(s) {}
void bar();
B(S &s);
S &get();
};
void foo(S &s) {
B b(s);
b.bar();
B::B(S &s) : s(s) {
// CHECK-LABEL: _ZN1BC2ER1S
// Check initialization of the reference parameter.
// CHECK: store %struct.S* {{.*}}, %struct.S** {{.*}}, !tbaa [[TAG_pointer:!.*]]
// Check loading of the reference parameter.
// CHECK: load %struct.S*, %struct.S** {{.*}}, !tbaa [[TAG_pointer]]
// Check initialization of the reference member.
// CHECK: store %struct.S* {{.*}}, %struct.S** {{.*}}, !tbaa [[TAG_pointer]]
}
S &B::get() {
// CHECK-LABEL: _ZN1B3getEv
// Check that we access the reference as a structure member.
// CHECK: load %struct.S*, %struct.S** {{.*}}, !tbaa [[TAG_B_s:!.*]]
return s;
}
// CHECK-LABEL: _Z3fooR1S
// Check initialization of the reference parameter in foo().
// CHECK: store %struct.S* {{.*}}, %struct.S** {{.*}}, !tbaa [[TAG_pointer:!.*]]
//
// CHECK-LABEL: _ZN1BC2ER1S
// TODO: Check loading of the reference parameter in B::B(S&).
// Check initialization of B::s in B::B(S&).
// CHECK: store %struct.S* {{.*}}, %struct.S** {{.*}}, !tbaa [[TAG_pointer]]
//
// CHECK-DAG: [[TAG_pointer]] = !{[[TYPE_pointer:!.*]], [[TYPE_pointer]], i64 0}
// CHECK-DAG: [[TAG_B_s]] = !{[[TYPE_B:!.*]], [[TYPE_pointer]], i64 0}
//
// CHECK-DAG: [[TYPE_B]] = !{!"_ZTS1B", [[TYPE_pointer]], i64 0}
// CHECK-DAG: [[TYPE_pointer]] = !{!"any pointer", [[TYPE_char:!.*]], i64 0}
// CHECK-DAG: [[TYPE_char]] = !{!"omnipotent char", {{!.*}}, i64 0}