diff options
author | Ivan A. Kosarev <ikosarev@accesssoftek.com> | 2017-11-30 09:26:39 +0000 |
---|---|---|
committer | Ivan A. Kosarev <ikosarev@accesssoftek.com> | 2017-11-30 09:26:39 +0000 |
commit | da34247a6aac509f994c57b727a60daf23023e29 (patch) | |
tree | e47ab9c5b4b262f3e01482a54331da8cfb4942d2 /clang/lib/CodeGen/CodeGenTBAA.h | |
parent | 1c14e86a268595ceaa7a28cf8a210931714c1401 (diff) | |
download | bcm5719-llvm-da34247a6aac509f994c57b727a60daf23023e29.tar.gz bcm5719-llvm-da34247a6aac509f994c57b727a60daf23023e29.zip |
[CodeGen] Add initial support for union members in TBAA
The basic idea behind this patch is that since in strict aliasing
mode all accesses to union members require their outermost
enclosing union objects to be specified explicitly, then for a
couple given accesses to union members of the form
p->a.b.c...
q->x.y.z...
it is known they can only alias if both p and q point to the same
union type and offset ranges of members a.b.c... and x.y.z...
overlap. Note that the actual types of the members do not matter.
Specifically, in this patch we do the following:
* Make unions to be valid TBAA base access types. This enables
generation of TBAA type descriptors for unions.
* Encode union types as structures with a single member of a
special "union member" type. Currently we do not encode
information about sizes of types, but conceptually such union
members are considered to be of the size of the whole union.
* Encode accesses to direct and indirect union members, including
member arrays, as accesses to these special members. All
accesses to members of a union thus get the same offset, which
is the offset of the union they are part of. This means the
existing LLVM TBAA machinery is able to handle such accesses
with no changes.
While this is already an improvement comparing to the current
situation, that is, representing all union accesses as may-alias
ones, there are further changes planned to complete the support
for unions. One of them is storing information about access sizes
so we can distinct accesses to non-overlapping union members,
including accesses to different elements of member arrays.
Another change is encoding type sizes in order to make it
possible to compute offsets within constant-indexed array
elements. These enhancements will be addressed with separate
patches.
Differential Revision: https://reviews.llvm.org/D39455
llvm-svn: 319413
Diffstat (limited to 'clang/lib/CodeGen/CodeGenTBAA.h')
-rw-r--r-- | clang/lib/CodeGen/CodeGenTBAA.h | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CodeGenTBAA.h b/clang/lib/CodeGen/CodeGenTBAA.h index a5b1f66bcd1..7b3473fe63f 100644 --- a/clang/lib/CodeGen/CodeGenTBAA.h +++ b/clang/lib/CodeGen/CodeGenTBAA.h @@ -34,9 +34,10 @@ class CGRecordLayout; // TBAAAccessKind - A kind of TBAA memory access descriptor. enum class TBAAAccessKind : unsigned { - Ordinary, - MayAlias, - Incomplete, + Ordinary, // An ordinary memory access. + MayAlias, // An access that may alias with any other accesses. + Incomplete, // Used to designate pointee values of incomplete types. + UnionMember, // An access to a direct or indirect union member. }; // TBAAAccessInfo - Describes a memory access in terms of TBAA. @@ -77,6 +78,14 @@ struct TBAAAccessInfo { bool isIncomplete() const { return Kind == TBAAAccessKind::Incomplete; } + static TBAAAccessInfo getUnionMemberInfo(llvm::MDNode *BaseType, + uint64_t Offset, uint64_t Size) { + return TBAAAccessInfo(TBAAAccessKind::UnionMember, BaseType, + /* AccessType= */ nullptr, Offset, Size); + } + + bool isUnionMember() const { return Kind == TBAAAccessKind::UnionMember; } + bool operator==(const TBAAAccessInfo &Other) const { return Kind == Other.Kind && BaseType == Other.BaseType && @@ -148,6 +157,10 @@ class CodeGenTBAA { /// considered to be equivalent to it. llvm::MDNode *getChar(); + /// getUnionMemberType - Get metadata that represents the type of union + /// members. + llvm::MDNode *getUnionMemberType(uint64_t Size); + /// CollectFields - Collect information about the fields of a type for /// !tbaa.struct metadata formation. Return false for an unsupported type. bool CollectFields(uint64_t BaseOffset, |