forked from OSchip/llvm-project
[CodeGen] Generate TBAA info for reference loads
Differential Revision: https://reviews.llvm.org/D39177 llvm-svn: 316896
This commit is contained in:
parent
f5142bf97f
commit
9f9d157517
|
@ -1189,8 +1189,8 @@ Address CodeGenFunction::GetAddrOfBlockDecl(const VarDecl *variable,
|
||||||
variable->getName());
|
variable->getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto refType = capture.fieldType()->getAs<ReferenceType>())
|
if (capture.fieldType()->isReferenceType())
|
||||||
addr = EmitLoadOfReference(addr, refType);
|
addr = EmitLoadOfReference(MakeAddrLValue(addr, capture.fieldType()));
|
||||||
|
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2160,22 +2160,30 @@ static LValue EmitThreadPrivateVarDeclLValue(
|
||||||
return CGF.MakeAddrLValue(Addr, T, AlignmentSource::Decl);
|
return CGF.MakeAddrLValue(Addr, T, AlignmentSource::Decl);
|
||||||
}
|
}
|
||||||
|
|
||||||
Address CodeGenFunction::EmitLoadOfReference(Address Addr,
|
Address
|
||||||
const ReferenceType *RefTy,
|
CodeGenFunction::EmitLoadOfReference(LValue RefLVal,
|
||||||
LValueBaseInfo *BaseInfo,
|
LValueBaseInfo *PointeeBaseInfo,
|
||||||
TBAAAccessInfo *TBAAInfo) {
|
TBAAAccessInfo *PointeeTBAAInfo) {
|
||||||
llvm::Value *Ptr = Builder.CreateLoad(Addr);
|
llvm::LoadInst *Load = Builder.CreateLoad(RefLVal.getAddress(),
|
||||||
return Address(Ptr, getNaturalTypeAlignment(RefTy->getPointeeType(),
|
RefLVal.isVolatile());
|
||||||
BaseInfo, TBAAInfo,
|
TBAAAccessInfo RefTBAAInfo = RefLVal.getTBAAInfo();
|
||||||
/* forPointeeType= */ true));
|
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,
|
LValue CodeGenFunction::EmitLoadOfReferenceLValue(LValue RefLVal) {
|
||||||
const ReferenceType *RefTy) {
|
LValueBaseInfo PointeeBaseInfo;
|
||||||
LValueBaseInfo BaseInfo;
|
TBAAAccessInfo PointeeTBAAInfo;
|
||||||
TBAAAccessInfo TBAAInfo;
|
Address PointeeAddr = EmitLoadOfReference(RefLVal, &PointeeBaseInfo,
|
||||||
Address Addr = EmitLoadOfReference(RefAddr, RefTy, &BaseInfo, &TBAAInfo);
|
&PointeeTBAAInfo);
|
||||||
return MakeAddrLValue(Addr, RefTy->getPointeeType(), BaseInfo, TBAAInfo);
|
return MakeAddrLValue(PointeeAddr, RefLVal.getType()->getPointeeType(),
|
||||||
|
PointeeBaseInfo, PointeeTBAAInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
Address CodeGenFunction::EmitLoadOfPointer(Address Ptr,
|
Address CodeGenFunction::EmitLoadOfPointer(Address Ptr,
|
||||||
|
@ -2210,17 +2218,15 @@ static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF,
|
||||||
V = EmitBitCastOfLValueToProperType(CGF, V, RealVarTy);
|
V = EmitBitCastOfLValueToProperType(CGF, V, RealVarTy);
|
||||||
CharUnits Alignment = CGF.getContext().getDeclAlign(VD);
|
CharUnits Alignment = CGF.getContext().getDeclAlign(VD);
|
||||||
Address Addr(V, Alignment);
|
Address Addr(V, Alignment);
|
||||||
LValue LV;
|
|
||||||
// Emit reference to the private copy of the variable if it is an OpenMP
|
// Emit reference to the private copy of the variable if it is an OpenMP
|
||||||
// threadprivate variable.
|
// threadprivate variable.
|
||||||
if (CGF.getLangOpts().OpenMP && VD->hasAttr<OMPThreadPrivateDeclAttr>())
|
if (CGF.getLangOpts().OpenMP && VD->hasAttr<OMPThreadPrivateDeclAttr>())
|
||||||
return EmitThreadPrivateVarDeclLValue(CGF, VD, T, Addr, RealVarTy,
|
return EmitThreadPrivateVarDeclLValue(CGF, VD, T, Addr, RealVarTy,
|
||||||
E->getExprLoc());
|
E->getExprLoc());
|
||||||
if (auto RefTy = VD->getType()->getAs<ReferenceType>()) {
|
LValue LV = VD->getType()->isReferenceType() ?
|
||||||
LV = CGF.EmitLoadOfReferenceLValue(Addr, RefTy);
|
CGF.EmitLoadOfReferenceLValue(Addr, VD->getType(),
|
||||||
} else {
|
AlignmentSource::Decl) :
|
||||||
LV = CGF.MakeAddrLValue(Addr, T, AlignmentSource::Decl);
|
CGF.MakeAddrLValue(Addr, T, AlignmentSource::Decl);
|
||||||
}
|
|
||||||
setObjCGCLValueClass(CGF.getContext(), E, LV);
|
setObjCGCLValueClass(CGF.getContext(), E, LV);
|
||||||
return LV;
|
return LV;
|
||||||
}
|
}
|
||||||
|
@ -2338,8 +2344,9 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
|
||||||
else if (CapturedStmtInfo) {
|
else if (CapturedStmtInfo) {
|
||||||
auto I = LocalDeclMap.find(VD);
|
auto I = LocalDeclMap.find(VD);
|
||||||
if (I != LocalDeclMap.end()) {
|
if (I != LocalDeclMap.end()) {
|
||||||
if (auto RefTy = VD->getType()->getAs<ReferenceType>())
|
if (VD->getType()->isReferenceType())
|
||||||
return EmitLoadOfReferenceLValue(I->second, RefTy);
|
return EmitLoadOfReferenceLValue(I->second, VD->getType(),
|
||||||
|
AlignmentSource::Decl);
|
||||||
return MakeAddrLValue(I->second, T);
|
return MakeAddrLValue(I->second, T);
|
||||||
}
|
}
|
||||||
LValue CapLVal =
|
LValue CapLVal =
|
||||||
|
@ -2410,12 +2417,9 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drill into reference types.
|
// Drill into reference types.
|
||||||
LValue LV;
|
LValue LV = VD->getType()->isReferenceType() ?
|
||||||
if (auto RefTy = VD->getType()->getAs<ReferenceType>()) {
|
EmitLoadOfReferenceLValue(addr, VD->getType(), AlignmentSource::Decl) :
|
||||||
LV = EmitLoadOfReferenceLValue(addr, RefTy);
|
MakeAddrLValue(addr, T, AlignmentSource::Decl);
|
||||||
} else {
|
|
||||||
LV = MakeAddrLValue(addr, T, AlignmentSource::Decl);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isLocalStorage = VD->hasLocalStorage();
|
bool isLocalStorage = VD->hasLocalStorage();
|
||||||
|
|
||||||
|
@ -3748,7 +3752,7 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
|
||||||
}
|
}
|
||||||
|
|
||||||
Address addr = base.getAddress();
|
Address addr = base.getAddress();
|
||||||
unsigned cvr = base.getVRQualifiers();
|
unsigned RecordCVR = base.getVRQualifiers();
|
||||||
if (rec->isUnion()) {
|
if (rec->isUnion()) {
|
||||||
// For unions, there is no pointer adjustment.
|
// For unions, there is no pointer adjustment.
|
||||||
assert(!FieldType->isReferenceType() && "union has reference member");
|
assert(!FieldType->isReferenceType() && "union has reference member");
|
||||||
|
@ -3763,22 +3767,16 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
|
||||||
addr = emitAddrOfFieldStorage(*this, addr, field);
|
addr = emitAddrOfFieldStorage(*this, addr, field);
|
||||||
|
|
||||||
// If this is a reference field, load the reference right now.
|
// If this is a reference field, load the reference right now.
|
||||||
if (const ReferenceType *refType = FieldType->getAs<ReferenceType>()) {
|
if (FieldType->isReferenceType()) {
|
||||||
llvm::LoadInst *load = Builder.CreateLoad(addr, "ref");
|
LValue RefLVal = MakeAddrLValue(addr, FieldType, FieldBaseInfo,
|
||||||
if (cvr & Qualifiers::Volatile) load->setVolatile(true);
|
FieldTBAAInfo);
|
||||||
|
if (RecordCVR & Qualifiers::Volatile)
|
||||||
|
RefLVal.getQuals().setVolatile(true);
|
||||||
|
addr = EmitLoadOfReference(RefLVal, &FieldBaseInfo, &FieldTBAAInfo);
|
||||||
|
|
||||||
CGM.DecorateInstructionWithTBAA(load, FieldTBAAInfo);
|
// Qualifiers on the struct don't apply to the referencee.
|
||||||
|
RecordCVR = 0;
|
||||||
FieldType = refType->getPointeeType();
|
FieldType = FieldType->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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3793,7 +3791,7 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
|
||||||
addr = EmitFieldAnnotations(field, addr);
|
addr = EmitFieldAnnotations(field, addr);
|
||||||
|
|
||||||
LValue LV = MakeAddrLValue(addr, FieldType, FieldBaseInfo, FieldTBAAInfo);
|
LValue LV = MakeAddrLValue(addr, FieldType, FieldBaseInfo, FieldTBAAInfo);
|
||||||
LV.getQuals().addCVRQualifiers(cvr);
|
LV.getQuals().addCVRQualifiers(RecordCVR);
|
||||||
|
|
||||||
// __weak attribute on a field is ignored.
|
// __weak attribute on a field is ignored.
|
||||||
if (LV.getQuals().getObjCGCAttr() == Qualifiers::Weak)
|
if (LV.getQuals().getObjCGCAttr() == Qualifiers::Weak)
|
||||||
|
|
|
@ -1037,8 +1037,8 @@ static LValue loadToBegin(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy,
|
||||||
if (auto *PtrTy = BaseTy->getAs<PointerType>())
|
if (auto *PtrTy = BaseTy->getAs<PointerType>())
|
||||||
BaseLV = CGF.EmitLoadOfPointerLValue(BaseLV.getAddress(), PtrTy);
|
BaseLV = CGF.EmitLoadOfPointerLValue(BaseLV.getAddress(), PtrTy);
|
||||||
else {
|
else {
|
||||||
BaseLV = CGF.EmitLoadOfReferenceLValue(BaseLV.getAddress(),
|
LValue RefLVal = CGF.MakeAddrLValue(BaseLV.getAddress(), BaseTy);
|
||||||
BaseTy->castAs<ReferenceType>());
|
BaseLV = CGF.EmitLoadOfReferenceLValue(RefLVal);
|
||||||
}
|
}
|
||||||
BaseTy = BaseTy->getPointeeType();
|
BaseTy = BaseTy->getPointeeType();
|
||||||
}
|
}
|
||||||
|
|
|
@ -417,8 +417,7 @@ static llvm::Function *emitOutlinedFunctionPrologue(
|
||||||
Address ArgAddr = ArgLVal.getAddress();
|
Address ArgAddr = ArgLVal.getAddress();
|
||||||
if (!VarTy->isReferenceType()) {
|
if (!VarTy->isReferenceType()) {
|
||||||
if (ArgLVal.getType()->isLValueReferenceType()) {
|
if (ArgLVal.getType()->isLValueReferenceType()) {
|
||||||
ArgAddr = CGF.EmitLoadOfReference(
|
ArgAddr = CGF.EmitLoadOfReference(ArgLVal);
|
||||||
ArgAddr, ArgLVal.getType()->castAs<ReferenceType>());
|
|
||||||
} else if (!VarTy->isVariablyModifiedType() || !VarTy->isPointerType()) {
|
} else if (!VarTy->isVariablyModifiedType() || !VarTy->isPointerType()) {
|
||||||
assert(ArgLVal.getType()->isPointerType());
|
assert(ArgLVal.getType()->isPointerType());
|
||||||
ArgAddr = CGF.EmitLoadOfPointer(
|
ArgAddr = CGF.EmitLoadOfPointer(
|
||||||
|
|
|
@ -1952,10 +1952,17 @@ public:
|
||||||
LValueBaseInfo *BaseInfo = nullptr,
|
LValueBaseInfo *BaseInfo = nullptr,
|
||||||
TBAAAccessInfo *TBAAInfo = nullptr);
|
TBAAAccessInfo *TBAAInfo = nullptr);
|
||||||
|
|
||||||
Address EmitLoadOfReference(Address Ref, const ReferenceType *RefTy,
|
Address EmitLoadOfReference(LValue RefLVal,
|
||||||
LValueBaseInfo *BaseInfo = nullptr,
|
LValueBaseInfo *PointeeBaseInfo = nullptr,
|
||||||
TBAAAccessInfo *TBAAInfo = nullptr);
|
TBAAAccessInfo *PointeeTBAAInfo = nullptr);
|
||||||
LValue EmitLoadOfReferenceLValue(Address Ref, const ReferenceType *RefTy);
|
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,
|
Address EmitLoadOfPointer(Address Ptr, const PointerType *PtrTy,
|
||||||
LValueBaseInfo *BaseInfo = nullptr,
|
LValueBaseInfo *BaseInfo = nullptr,
|
||||||
|
|
|
@ -6,24 +6,32 @@ struct S;
|
||||||
|
|
||||||
struct B {
|
struct B {
|
||||||
S &s;
|
S &s;
|
||||||
B(S &s) : s(s) {}
|
B(S &s);
|
||||||
void bar();
|
S &get();
|
||||||
};
|
};
|
||||||
|
|
||||||
void foo(S &s) {
|
B::B(S &s) : s(s) {
|
||||||
B b(s);
|
// CHECK-LABEL: _ZN1BC2ER1S
|
||||||
b.bar();
|
// 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_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_pointer]] = !{!"any pointer", [[TYPE_char:!.*]], i64 0}
|
||||||
// CHECK-DAG: [[TYPE_char]] = !{!"omnipotent char", {{!.*}}, i64 0}
|
// CHECK-DAG: [[TYPE_char]] = !{!"omnipotent char", {{!.*}}, i64 0}
|
||||||
|
|
Loading…
Reference in New Issue