1
1
#include " CIRGenTBAA.h"
2
- #include " CIRGenCXXABI.h"
3
2
#include " CIRGenTypes.h"
4
3
#include " mlir/IR/BuiltinAttributes.h"
5
4
#include " mlir/IR/MLIRContext.h"
6
5
#include " mlir/Interfaces/DataLayoutInterfaces.h"
7
6
#include " clang/AST/ASTContext.h"
8
7
#include " clang/AST/RecordLayout.h"
8
+ #include " clang/CIR/Dialect/IR/CIRTypes.h"
9
+ #include " clang/CIR/MissingFeatures.h"
9
10
#include " llvm/Support/ErrorHandling.h"
10
11
namespace clang ::CIRGen {
11
12
@@ -21,44 +22,159 @@ CIRGenTBAA::CIRGenTBAA(mlir::MLIRContext *mlirContext,
21
22
: mlirContext(mlirContext), astContext(astContext), types(types),
22
23
moduleOp (moduleOp), codeGenOpts(codeGenOpts), features(features) {}
23
24
25
+ cir::TBAAAttr CIRGenTBAA::getChar () {
26
+ return cir::TBAAScalarAttr::get (mlirContext,
27
+ cir::IntType::get (mlirContext, 1 , true ));
28
+ }
29
+
30
+ static bool typeHasMayAlias (clang::QualType qty) {
31
+ // Tagged types have declarations, and therefore may have attributes.
32
+ if (auto *td = qty->getAsTagDecl ())
33
+ if (td->hasAttr <MayAliasAttr>())
34
+ return true ;
35
+
36
+ // Also look for may_alias as a declaration attribute on a typedef.
37
+ // FIXME: We should follow GCC and model may_alias as a type attribute
38
+ // rather than as a declaration attribute.
39
+ while (auto *tt = qty->getAs <TypedefType>()) {
40
+ if (tt->getDecl ()->hasAttr <MayAliasAttr>())
41
+ return true ;
42
+ qty = tt->desugar ();
43
+ }
44
+ return false ;
45
+ }
46
+
47
+ // / Check if the given type is a valid base type to be used in access tags.
48
+ static bool isValidBaseType (clang::QualType qty) {
49
+ if (const clang::RecordType *tty = qty->getAs <clang::RecordType>()) {
50
+ const clang::RecordDecl *rd = tty->getDecl ()->getDefinition ();
51
+ // Incomplete types are not valid base access types.
52
+ if (!rd)
53
+ return false ;
54
+ if (rd->hasFlexibleArrayMember ())
55
+ return false ;
56
+ // rd can be struct, union, class, interface or enum.
57
+ // For now, we only handle struct and class.
58
+ if (rd->isStruct () || rd->isClass ())
59
+ return true ;
60
+ }
61
+ return false ;
62
+ }
63
+
24
64
cir::TBAAAttr CIRGenTBAA::getTypeInfo (clang::QualType qty) {
25
- return tbaa_NYI (mlirContext);
65
+ // At -O0 or relaxed aliasing, TBAA is not emitted for regular types.
66
+ if (codeGenOpts.OptimizationLevel == 0 || codeGenOpts.RelaxedAliasing ) {
67
+ return nullptr ;
68
+ }
69
+
70
+ // If the type has the may_alias attribute (even on a typedef), it is
71
+ // effectively in the general char alias class.
72
+ if (typeHasMayAlias (qty)) {
73
+ assert (!cir::MissingFeatures::tbaaMayAlias ());
74
+ return getChar ();
75
+ }
76
+ // We need this function to not fall back to returning the "omnipotent char"
77
+ // type node for aggregate and union types. Otherwise, any dereference of an
78
+ // aggregate will result into the may-alias access descriptor, meaning all
79
+ // subsequent accesses to direct and indirect members of that aggregate will
80
+ // be considered may-alias too.
81
+ // function.
82
+ if (isValidBaseType (qty)) {
83
+ // TODO(cir): support TBAA with struct
84
+ return tbaa_NYI (mlirContext);
85
+ }
86
+
87
+ const clang::Type *ty = astContext.getCanonicalType (qty).getTypePtr ();
88
+ if (metadataCache.contains (ty)) {
89
+ return metadataCache[ty];
90
+ }
91
+
92
+ // Note that the following helper call is allowed to add new nodes to the
93
+ // cache, which invalidates all its previously obtained iterators. So we
94
+ // first generate the node for the type and then add that node to the
95
+ // cache.
96
+ auto typeNode = cir::TBAAScalarAttr::get (mlirContext, types.ConvertType (qty));
97
+ return metadataCache[ty] = typeNode;
26
98
}
27
99
28
100
TBAAAccessInfo CIRGenTBAA::getAccessInfo (clang::QualType accessType) {
29
- return TBAAAccessInfo ();
101
+ // Pointee values may have incomplete types, but they shall never be
102
+ // dereferenced.
103
+ if (accessType->isIncompleteType ()) {
104
+ assert (!cir::MissingFeatures::tbaaIncompleteType ());
105
+ return TBAAAccessInfo::getIncompleteInfo ();
106
+ }
107
+
108
+ if (typeHasMayAlias (accessType)) {
109
+ assert (!cir::MissingFeatures::tbaaMayAlias ());
110
+ return TBAAAccessInfo::getMayAliasInfo ();
111
+ }
112
+
113
+ uint64_t size = astContext.getTypeSizeInChars (accessType).getQuantity ();
114
+ return TBAAAccessInfo (getTypeInfo (accessType), size);
30
115
}
31
116
32
117
TBAAAccessInfo CIRGenTBAA::getVTablePtrAccessInfo (mlir::Type vtablePtrType) {
118
+ // TODO(cir): support vtable ptr
119
+ assert (!cir::MissingFeatures::tbaaVTablePtr ());
33
120
return TBAAAccessInfo ();
34
121
}
35
122
36
123
mlir::ArrayAttr CIRGenTBAA::getTBAAStructInfo (clang::QualType qty) {
37
- return mlir::ArrayAttr::get (mlirContext, {});
124
+ assert (!cir::MissingFeatures::tbaaStruct () && " tbaa.struct NYI" );
125
+ return mlir::ArrayAttr ();
38
126
}
39
127
40
128
cir::TBAAAttr CIRGenTBAA::getBaseTypeInfo (clang::QualType qty) {
41
129
return tbaa_NYI (mlirContext);
42
130
}
43
131
44
- mlir::ArrayAttr CIRGenTBAA::getAccessTagInfo (TBAAAccessInfo tbaaInfo) {
45
- return mlir::ArrayAttr::get (mlirContext, {tbaa_NYI (mlirContext)});
132
+ cir::TBAAAttr CIRGenTBAA::getAccessTagInfo (TBAAAccessInfo tbaaInfo) {
133
+ assert (!tbaaInfo.isIncomplete () &&
134
+ " Access to an object of an incomplete type!" );
135
+
136
+ if (tbaaInfo.isMayAlias ()) {
137
+ assert (!cir::MissingFeatures::tbaaMayAlias ());
138
+ tbaaInfo = TBAAAccessInfo (getChar (), tbaaInfo.size );
139
+ }
140
+ if (!tbaaInfo.accessType ) {
141
+ return nullptr ;
142
+ }
143
+
144
+ if (!codeGenOpts.StructPathTBAA )
145
+ tbaaInfo = TBAAAccessInfo (tbaaInfo.accessType , tbaaInfo.size );
146
+
147
+ if (!tbaaInfo.baseType ) {
148
+ tbaaInfo.baseType = tbaaInfo.accessType ;
149
+ assert (!tbaaInfo.offset &&
150
+ " Nonzero offset for an access with no base type!" );
151
+ }
152
+ if (codeGenOpts.NewStructPathTBAA ) {
153
+ llvm_unreachable (" NYI" );
154
+ }
155
+ if (tbaaInfo.baseType == tbaaInfo.accessType ) {
156
+ return tbaaInfo.accessType ;
157
+ }
158
+ return tbaa_NYI (mlirContext);
46
159
}
47
160
48
161
TBAAAccessInfo CIRGenTBAA::mergeTBAAInfoForCast (TBAAAccessInfo sourceInfo,
49
162
TBAAAccessInfo targetInfo) {
163
+ assert (!cir::MissingFeatures::tbaaMergeTBAAInfo ());
50
164
return TBAAAccessInfo ();
51
165
}
52
166
53
167
TBAAAccessInfo
54
168
CIRGenTBAA::mergeTBAAInfoForConditionalOperator (TBAAAccessInfo infoA,
55
169
TBAAAccessInfo infoB) {
170
+ assert (!cir::MissingFeatures::tbaaMergeTBAAInfo ());
56
171
return TBAAAccessInfo ();
57
172
}
58
173
59
174
TBAAAccessInfo
60
175
CIRGenTBAA::mergeTBAAInfoForMemoryTransfer (TBAAAccessInfo destInfo,
61
176
TBAAAccessInfo srcInfo) {
177
+ assert (!cir::MissingFeatures::tbaaMergeTBAAInfo ());
62
178
return TBAAAccessInfo ();
63
179
}
64
180
0 commit comments