Skip to content

Commit

Permalink
[CodeGen] Introduce generic TBAA access descriptors
Browse files Browse the repository at this point in the history
With this patch we implement a concept of TBAA access descriptors
that are capable of representing both scalar and struct-path
accesses in a generic way.

This is part of D37826 reworked to be a separate patch to
simplify review.

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

llvm-svn: 314780
  • Loading branch information
Ivan A. Kosarev committed Oct 3, 2017
1 parent e093bad commit a511ed7
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 83 deletions.
42 changes: 18 additions & 24 deletions clang/lib/CodeGen/CGExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1375,9 +1375,7 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(LValue lvalue,
SourceLocation Loc) {
return EmitLoadOfScalar(lvalue.getAddress(), lvalue.isVolatile(),
lvalue.getType(), Loc, lvalue.getBaseInfo(),
lvalue.getTBAAAccessType(),
lvalue.getTBAABaseType(), lvalue.getTBAAOffset(),
lvalue.isNontemporal());
lvalue.getTBAAInfo(), lvalue.isNontemporal());
}

static bool hasBooleanRepresentation(QualType Ty) {
Expand Down Expand Up @@ -1487,9 +1485,7 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile,
QualType Ty,
SourceLocation Loc,
LValueBaseInfo BaseInfo,
llvm::MDNode *TBAAAccessType,
QualType TBAABaseType,
uint64_t TBAAOffset,
TBAAAccessInfo TBAAInfo,
bool isNontemporal) {
if (!CGM.getCodeGenOpts().PreserveVec3Type) {
// For better performance, handle vector loads differently.
Expand Down Expand Up @@ -1518,7 +1514,7 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile,

// Atomic operations have to be done on integral types.
LValue AtomicLValue =
LValue::MakeAddr(Addr, Ty, getContext(), BaseInfo, TBAAAccessType);
LValue::MakeAddr(Addr, Ty, getContext(), BaseInfo, TBAAInfo.AccessType);
if (Ty->isAtomicType() || LValueIsSuitableForInlineAtomic(AtomicLValue)) {
return EmitAtomicLoad(AtomicLValue, Loc).getScalarVal();
}
Expand All @@ -1529,11 +1525,11 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile,
Load->getContext(), llvm::ConstantAsMetadata::get(Builder.getInt32(1)));
Load->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node);
}
if (TBAAAccessType) {
if (TBAAInfo.AccessType) {
bool MayAlias = BaseInfo.getMayAlias();
llvm::MDNode *TBAA = MayAlias
? CGM.getTBAAMayAliasTypeInfo()
: CGM.getTBAAStructTagInfo(TBAABaseType, TBAAAccessType, TBAAOffset);
: CGM.getTBAAStructTagInfo(TBAAInfo);
if (TBAA)
CGM.DecorateInstructionWithTBAA(Load, TBAA, MayAlias);
}
Expand Down Expand Up @@ -1576,11 +1572,8 @@ llvm::Value *CodeGenFunction::EmitFromMemory(llvm::Value *Value, QualType Ty) {
void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, Address Addr,
bool Volatile, QualType Ty,
LValueBaseInfo BaseInfo,
llvm::MDNode *TBAAAccessType,
bool isInit, QualType TBAABaseType,
uint64_t TBAAOffset,
bool isNontemporal) {

TBAAAccessInfo TBAAInfo,
bool isInit, bool isNontemporal) {
if (!CGM.getCodeGenOpts().PreserveVec3Type) {
// Handle vectors differently to get better performance.
if (Ty->isVectorType()) {
Expand All @@ -1606,7 +1599,7 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, Address Addr,
Value = EmitToMemory(Value, Ty);

LValue AtomicLValue =
LValue::MakeAddr(Addr, Ty, getContext(), BaseInfo, TBAAAccessType);
LValue::MakeAddr(Addr, Ty, getContext(), BaseInfo, TBAAInfo.AccessType);
if (Ty->isAtomicType() ||
(!isInit && LValueIsSuitableForInlineAtomic(AtomicLValue))) {
EmitAtomicStore(RValue::get(Value), AtomicLValue, isInit);
Expand All @@ -1620,11 +1613,11 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, Address Addr,
llvm::ConstantAsMetadata::get(Builder.getInt32(1)));
Store->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node);
}
if (TBAAAccessType) {
if (TBAAInfo.AccessType) {
bool MayAlias = BaseInfo.getMayAlias();
llvm::MDNode *TBAA = MayAlias
? CGM.getTBAAMayAliasTypeInfo()
: CGM.getTBAAStructTagInfo(TBAABaseType, TBAAAccessType, TBAAOffset);
: CGM.getTBAAStructTagInfo(TBAAInfo);
if (TBAA)
CGM.DecorateInstructionWithTBAA(Store, TBAA, MayAlias);
}
Expand All @@ -1634,9 +1627,7 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *value, LValue lvalue,
bool isInit) {
EmitStoreOfScalar(value, lvalue.getAddress(), lvalue.isVolatile(),
lvalue.getType(), lvalue.getBaseInfo(),
lvalue.getTBAAAccessType(), isInit,
lvalue.getTBAABaseType(), lvalue.getTBAAOffset(),
lvalue.isNontemporal());
lvalue.getTBAAInfo(), isInit, lvalue.isNontemporal());
}

/// EmitLoadOfLValue - Given an expression that represents a value lvalue, this
Expand Down Expand Up @@ -3776,10 +3767,13 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
getContext().getASTRecordLayout(field->getParent());
// Set the base type to be the base type of the base LValue and
// update offset to be relative to the base type.
LV.setTBAABaseType(mayAlias ? getContext().CharTy : base.getTBAABaseType());
LV.setTBAAOffset(mayAlias ? 0 : base.getTBAAOffset() +
Layout.getFieldOffset(field->getFieldIndex()) /
getContext().getCharWidth());
unsigned CharWidth = getContext().getCharWidth();
TBAAAccessInfo TBAAInfo = mayAlias ?
TBAAAccessInfo(CGM.getTBAAMayAliasTypeInfo()) :
TBAAAccessInfo(base.getTBAAInfo().BaseType, CGM.getTBAATypeInfo(type),
base.getTBAAInfo().Offset + Layout.getFieldOffset(
field->getFieldIndex()) / CharWidth);
LV.setTBAAInfo(TBAAInfo);
}

// __weak attribute on a field is ignored.
Expand Down
28 changes: 7 additions & 21 deletions clang/lib/CodeGen/CGValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "llvm/IR/Value.h"
#include "llvm/IR/Type.h"
#include "Address.h"
#include "CodeGenTBAA.h"

namespace llvm {
class Constant;
Expand Down Expand Up @@ -220,22 +221,14 @@ class LValue {
bool ImpreciseLifetime : 1;

LValueBaseInfo BaseInfo;
TBAAAccessInfo TBAAInfo;

// This flag shows if a nontemporal load/stores should be used when accessing
// this lvalue.
bool Nontemporal : 1;

Expr *BaseIvarExp;

/// TBAABaseType - The base access type used by TBAA.
QualType TBAABaseType;

/// TBAAOffset - Access offset used by TBAA.
uint64_t TBAAOffset;

/// TBAAInfo - The final access type used by TBAA.
llvm::MDNode *TBAAAccessType;

private:
void Initialize(QualType Type, Qualifiers Quals,
CharUnits Alignment, LValueBaseInfo BaseInfo,
Expand All @@ -248,18 +241,14 @@ class LValue {
assert(this->Alignment == Alignment.getQuantity() &&
"Alignment exceeds allowed max!");
this->BaseInfo = BaseInfo;
this->TBAAInfo = TBAAAccessInfo(Type, TBAAAccessType, /* Offset= */ 0);

// Initialize Objective-C flags.
this->Ivar = this->ObjIsArray = this->NonGC = this->GlobalObjCRef = false;
this->ImpreciseLifetime = false;
this->Nontemporal = false;
this->ThreadLocalRef = false;
this->BaseIvarExp = nullptr;

// Initialize fields for TBAA.
this->TBAABaseType = Type;
this->TBAAOffset = 0;
this->TBAAAccessType = TBAAAccessType;
}

public:
Expand Down Expand Up @@ -319,14 +308,11 @@ class LValue {
Expr *getBaseIvarExp() const { return BaseIvarExp; }
void setBaseIvarExp(Expr *V) { BaseIvarExp = V; }

QualType getTBAABaseType() const { return TBAABaseType; }
void setTBAABaseType(QualType T) { TBAABaseType = T; }

uint64_t getTBAAOffset() const { return TBAAOffset; }
void setTBAAOffset(uint64_t O) { TBAAOffset = O; }
TBAAAccessInfo getTBAAInfo() const { return TBAAInfo; }
void setTBAAInfo(TBAAAccessInfo Info) { TBAAInfo = Info; }

llvm::MDNode *getTBAAAccessType() const { return TBAAAccessType; }
void setTBAAAccessType(llvm::MDNode *N) { TBAAAccessType = N; }
llvm::MDNode *getTBAAAccessType() const { return TBAAInfo.AccessType; }
void setTBAAAccessType(llvm::MDNode *N) { TBAAInfo.AccessType = N; }

const Qualifiers &getQuals() const { return Quals; }
Qualifiers &getQuals() { return Quals; }
Expand Down
9 changes: 3 additions & 6 deletions clang/lib/CodeGen/CodeGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -3056,9 +3056,7 @@ class CodeGenFunction : public CodeGenTypeCache {
SourceLocation Loc,
LValueBaseInfo BaseInfo =
LValueBaseInfo(AlignmentSource::Type),
llvm::MDNode *TBAAAccessType = nullptr,
QualType TBAABaseTy = QualType(),
uint64_t TBAAOffset = 0,
TBAAAccessInfo TBAAInfo = TBAAAccessInfo(),
bool isNontemporal = false);

/// EmitLoadOfScalar - Load a scalar value from an address, taking
Expand All @@ -3074,9 +3072,8 @@ class CodeGenFunction : public CodeGenTypeCache {
bool Volatile, QualType Ty,
LValueBaseInfo BaseInfo =
LValueBaseInfo(AlignmentSource::Type),
llvm::MDNode *TBAAAccessType = nullptr,
bool isInit = false, QualType TBAABaseTy = QualType(),
uint64_t TBAAOffset = 0, bool isNontemporal = false);
TBAAAccessInfo TBAAInfo = TBAAAccessInfo(),
bool isInit = false, bool isNontemporal = false);

/// EmitStoreOfScalar - Store a scalar value to an address, taking
/// care to appropriately convert from the memory representation to
Expand Down
7 changes: 2 additions & 5 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
#include "CGOpenMPRuntimeNVPTX.h"
#include "CodeGenFunction.h"
#include "CodeGenPGO.h"
#include "CodeGenTBAA.h"
#include "ConstantEmitter.h"
#include "CoverageMappingGen.h"
#include "TargetInfo.h"
Expand Down Expand Up @@ -591,12 +590,10 @@ llvm::MDNode *CodeGenModule::getTBAAStructInfo(QualType QTy) {
return TBAA->getTBAAStructInfo(QTy);
}

llvm::MDNode *CodeGenModule::getTBAAStructTagInfo(QualType BaseTy,
llvm::MDNode *AccessN,
uint64_t O) {
llvm::MDNode *CodeGenModule::getTBAAStructTagInfo(TBAAAccessInfo Info) {
if (!TBAA)
return nullptr;
return TBAA->getTBAAStructTagInfo(BaseTy, AccessN, O);
return TBAA->getTBAAStructTagInfo(Info);
}

llvm::MDNode *CodeGenModule::getTBAAMayAliasTypeInfo() {
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/CodeGen/CodeGenModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -658,9 +658,9 @@ class CodeGenModule : public CodeGenTypeCache {

llvm::MDNode *getTBAAInfoForVTablePtr();
llvm::MDNode *getTBAAStructInfo(QualType QTy);
/// Return the path-aware tag for given base type, access node and offset.
llvm::MDNode *getTBAAStructTagInfo(QualType BaseTy, llvm::MDNode *AccessN,
uint64_t O);

/// Get path-aware TBAA tag for a given memory access.
llvm::MDNode *getTBAAStructTagInfo(TBAAAccessInfo Info);

/// getTBAAMayAliasTypeInfo - Get TBAA information that represents
/// may-alias accesses.
Expand Down
22 changes: 10 additions & 12 deletions clang/lib/CodeGen/CodeGenTBAA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -290,30 +290,28 @@ CodeGenTBAA::getTBAAStructTypeInfo(QualType QTy) {
return StructMetadataCache[Ty] = nullptr;
}

/// Return a TBAA tag node for both scalar TBAA and struct-path aware TBAA.
llvm::MDNode *
CodeGenTBAA::getTBAAStructTagInfo(QualType BaseQTy, llvm::MDNode *AccessNode,
uint64_t Offset) {
if (!AccessNode)
llvm::MDNode *CodeGenTBAA::getTBAAStructTagInfo(TBAAAccessInfo Info) {
if (!Info.AccessType)
return nullptr;

if (!CodeGenOpts.StructPathTBAA)
return getTBAAScalarTagInfo(AccessNode);
return getTBAAScalarTagInfo(Info.AccessType);

const Type *BTy = Context.getCanonicalType(BaseQTy).getTypePtr();
TBAAPathTag PathTag = TBAAPathTag(BTy, AccessNode, Offset);
const Type *BTy = Context.getCanonicalType(Info.BaseType).getTypePtr();
TBAAPathTag PathTag = TBAAPathTag(BTy, Info.AccessType, Info.Offset);
if (llvm::MDNode *N = StructTagMetadataCache[PathTag])
return N;

llvm::MDNode *BNode = nullptr;
if (isTBAAPathStruct(BaseQTy))
BNode = getTBAAStructTypeInfo(BaseQTy);
if (isTBAAPathStruct(Info.BaseType))
BNode = getTBAAStructTypeInfo(Info.BaseType);
if (!BNode)
return StructTagMetadataCache[PathTag] =
MDHelper.createTBAAStructTagNode(AccessNode, AccessNode, 0);
MDHelper.createTBAAStructTagNode(Info.AccessType, Info.AccessType,
/* Offset= */ 0);

return StructTagMetadataCache[PathTag] =
MDHelper.createTBAAStructTagNode(BNode, AccessNode, Offset);
MDHelper.createTBAAStructTagNode(BNode, Info.AccessType, Info.Offset);
}

llvm::MDNode *
Expand Down
51 changes: 39 additions & 12 deletions clang/lib/CodeGen/CodeGenTBAA.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,43 @@ namespace clang {
class Type;

namespace CodeGen {
class CGRecordLayout;
class CGRecordLayout;

struct TBAAPathTag {
TBAAPathTag(const Type *B, const llvm::MDNode *A, uint64_t O)
: BaseT(B), AccessN(A), Offset(O) {}
const Type *BaseT;
const llvm::MDNode *AccessN;
uint64_t Offset;
};

// TBAAAccessInfo - Describes a memory access in terms of TBAA.
struct TBAAAccessInfo {
TBAAAccessInfo(QualType BaseType, llvm::MDNode *AccessType, uint64_t Offset)
: BaseType(BaseType), AccessType(AccessType), Offset(Offset)
{}

explicit TBAAAccessInfo(llvm::MDNode *AccessType)
: TBAAAccessInfo(/* BaseType= */ QualType(), AccessType, /* Offset= */ 0)
{}

TBAAAccessInfo()
: TBAAAccessInfo(/* AccessType= */ nullptr)
{}

struct TBAAPathTag {
TBAAPathTag(const Type *B, const llvm::MDNode *A, uint64_t O)
: BaseT(B), AccessN(A), Offset(O) {}
const Type *BaseT;
const llvm::MDNode *AccessN;
uint64_t Offset;
};
/// 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.
QualType BaseType;

/// AccessType - The final access type. May be null if there is no TBAA
/// information available about this access.
llvm::MDNode *AccessType;

/// Offset - The byte offset of the final access within the base one. Must be
/// zero if the base access type is not specified.
uint64_t Offset;
};

/// CodeGenTBAA - This class organizes the cross-module state that is used
/// while lowering AST types to LLVM types.
Expand Down Expand Up @@ -109,10 +137,9 @@ class CodeGenTBAA {

/// Get the MDNode in the type DAG for given struct type QType.
llvm::MDNode *getTBAAStructTypeInfo(QualType QType);
/// Get the tag MDNode for a given base type, the actual scalar access MDNode
/// and offset into the base type.
llvm::MDNode *getTBAAStructTagInfo(QualType BaseQType,
llvm::MDNode *AccessNode, uint64_t Offset);

/// Get path-aware TBAA tag for a given memory access.
llvm::MDNode *getTBAAStructTagInfo(TBAAAccessInfo Info);

/// Get the scalar tag MDNode for a given scalar type.
llvm::MDNode *getTBAAScalarTagInfo(llvm::MDNode *AccessNode);
Expand Down

0 comments on commit a511ed7

Please sign in to comment.