@@ -75,6 +75,28 @@ enum class AlignmentSource {
75
75
Type
76
76
};
77
77
78
+ // / Given that the base address has the given alignment source, what's
79
+ // / our confidence in the alignment of the field?
80
+ static inline AlignmentSource getFieldAlignmentSource (AlignmentSource source) {
81
+ // For now, we don't distinguish fields of opaque pointers from
82
+ // top-level declarations, but maybe we should.
83
+ return AlignmentSource::Decl;
84
+ }
85
+
86
+ class LValueBaseInfo {
87
+ AlignmentSource alignSource;
88
+
89
+ public:
90
+ explicit LValueBaseInfo (AlignmentSource source = AlignmentSource::Type)
91
+ : alignSource(source) {}
92
+ AlignmentSource getAlignmentSource () const { return alignSource; }
93
+ void setAlignmentSource (AlignmentSource source) { alignSource = source; }
94
+
95
+ void mergeForCast (const LValueBaseInfo &info) {
96
+ setAlignmentSource (info.getAlignmentSource ());
97
+ }
98
+ };
99
+
78
100
class LValue {
79
101
enum {
80
102
Simple, // This is a normal l-value, use getAddress().
@@ -87,13 +109,26 @@ class LValue {
87
109
clang::QualType type;
88
110
clang::Qualifiers quals;
89
111
112
+ // The alignment to use when accessing this lvalue. (For vector elements,
113
+ // this is the alignment of the whole vector)
114
+ unsigned alignment;
90
115
mlir::Value v;
91
116
mlir::Type elementType;
117
+ LValueBaseInfo baseInfo;
92
118
93
- void initialize (clang::QualType type, clang::Qualifiers quals) {
94
- assert (!cir::MissingFeatures::lvalueBaseInfo ());
119
+ void initialize (clang::QualType type, clang::Qualifiers quals,
120
+ clang::CharUnits alignment, LValueBaseInfo baseInfo) {
121
+ assert ((!alignment.isZero () || type->isIncompleteType ()) &&
122
+ " initializing l-value with zero alignment!" );
95
123
this ->type = type;
96
124
this ->quals = quals;
125
+ const unsigned maxAlign = 1U << 31 ;
126
+ this ->alignment = alignment.getQuantity () <= maxAlign
127
+ ? alignment.getQuantity ()
128
+ : maxAlign;
129
+ assert (this ->alignment == alignment.getQuantity () &&
130
+ " Alignment exceeds allowed max!" );
131
+ this ->baseInfo = baseInfo;
97
132
}
98
133
99
134
public:
@@ -108,23 +143,27 @@ class LValue {
108
143
mlir::Value getPointer () const { return v; }
109
144
110
145
clang::CharUnits getAlignment () const {
111
- // TODO: Handle alignment
112
- return clang::CharUnits::One ();
146
+ return clang::CharUnits::fromQuantity (alignment);
113
147
}
148
+ void setAlignment (clang::CharUnits a) { alignment = a.getQuantity (); }
114
149
115
150
Address getAddress () const {
116
151
return Address (getPointer (), elementType, getAlignment ());
117
152
}
118
153
119
154
const clang::Qualifiers &getQuals () const { return quals; }
120
155
121
- static LValue makeAddr (Address address, clang::QualType t) {
156
+ static LValue makeAddr (Address address, clang::QualType t,
157
+ LValueBaseInfo baseInfo) {
158
+ // Classic codegen sets the objc gc qualifier here. That requires an
159
+ // ASTContext, which is passed in from CIRGenFunction::makeAddrLValue.
160
+ assert (!cir::MissingFeatures::objCGC ());
161
+
122
162
LValue r;
123
163
r.lvType = Simple;
124
164
r.v = address.getPointer ();
125
165
r.elementType = address.getElementType ();
126
- r.initialize (t, t.getQualifiers ());
127
- assert (!cir::MissingFeatures::lvalueBaseInfo ());
166
+ r.initialize (t, t.getQualifiers (), address.getAlignment (), baseInfo);
128
167
return r;
129
168
}
130
169
};
0 commit comments