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());
|
||||
}
|
||||
|
||||
if (auto refType = capture.fieldType()->getAs<ReferenceType>())
|
||||
addr = EmitLoadOfReference(addr, refType);
|
||||
if (capture.fieldType()->isReferenceType())
|
||||
addr = EmitLoadOfReference(MakeAddrLValue(addr, capture.fieldType()));
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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}
|
||||
|
|
Loading…
Reference in New Issue