clang 22.0.0git
CIRGenValue.h
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// These classes implement wrappers around mlir::Value in order to fully
10// represent the range of values for C L- and R- values.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef CLANG_LIB_CIR_CIRGENVALUE_H
15#define CLANG_LIB_CIR_CIRGENVALUE_H
16
17#include "Address.h"
18
19#include "clang/AST/CharUnits.h"
20#include "clang/AST/Type.h"
21
22#include "CIRGenRecordLayout.h"
23#include "mlir/IR/Value.h"
24
26
27namespace clang::CIRGen {
28
29/// This trivial value class is used to represent the result of an
30/// expression that is evaluated. It can be one of three things: either a
31/// simple MLIR SSA value, a pair of SSA values for complex numbers, or the
32/// address of an aggregate value in memory.
33class RValue {
34 enum Flavor { Scalar, Complex, Aggregate };
35
36 union {
37 mlir::Value value;
38
39 // Stores aggregate address.
41 };
42
43 unsigned isVolatile : 1;
44 unsigned flavor : 2;
45
46public:
47 RValue() : value(nullptr), flavor(Scalar) {}
48
49 bool isScalar() const { return flavor == Scalar; }
50 bool isComplex() const { return flavor == Complex; }
51 bool isAggregate() const { return flavor == Aggregate; }
52
53 bool isVolatileQualified() const { return isVolatile; }
54
55 /// Return the value of this scalar value.
56 mlir::Value getValue() const {
57 assert(isScalar() && "Not a scalar!");
58 return value;
59 }
60
61 /// Return the value of this complex value.
62 mlir::Value getComplexValue() const {
63 assert(isComplex() && "Not a complex!");
64 return value;
65 }
66
67 /// Return the value of the address of the aggregate.
69 assert(isAggregate() && "Not an aggregate!");
70 return aggregateAddr;
71 }
72
73 mlir::Value getAggregatePointer(QualType pointeeType) const {
75 }
76
77 static RValue getIgnored() {
78 // FIXME: should we make this a more explicit state?
79 return get(nullptr);
80 }
81
82 static RValue get(mlir::Value v) {
83 RValue er;
84 er.value = v;
85 er.flavor = Scalar;
86 er.isVolatile = false;
87 return er;
88 }
89
90 static RValue getComplex(mlir::Value v) {
91 RValue er;
92 er.value = v;
93 er.flavor = Complex;
94 er.isVolatile = false;
95 return er;
96 }
97
98 // volatile or not. Remove default to find all places that probably get this
99 // wrong.
100
101 /// Convert an Address to an RValue. If the Address is not
102 /// signed, create an RValue using the unsigned address. Otherwise, resign the
103 /// address using the provided type.
104 static RValue getAggregate(Address addr, bool isVolatile = false) {
105 RValue er;
106 er.aggregateAddr = addr;
107 er.flavor = Aggregate;
108 er.isVolatile = isVolatile;
109 return er;
110 }
111};
112
113/// The source of the alignment of an l-value; an expression of
114/// confidence in the alignment actually matching the estimate.
115enum class AlignmentSource {
116 /// The l-value was an access to a declared entity or something
117 /// equivalently strong, like the address of an array allocated by a
118 /// language runtime.
119 Decl,
120
121 /// The l-value was considered opaque, so the alignment was
122 /// determined from a type, but that type was an explicitly-aligned
123 /// typedef.
125
126 /// The l-value was considered opaque, so the alignment was
127 /// determined from a type.
128 Type
129};
130
131/// Given that the base address has the given alignment source, what's
132/// our confidence in the alignment of the field?
134 // For now, we don't distinguish fields of opaque pointers from
135 // top-level declarations, but maybe we should.
137}
138
140 AlignmentSource alignSource;
141
142public:
144 : alignSource(source) {}
145 AlignmentSource getAlignmentSource() const { return alignSource; }
146 void setAlignmentSource(AlignmentSource source) { alignSource = source; }
147
148 void mergeForCast(const LValueBaseInfo &info) {
150 }
151};
152
153class LValue {
154 enum {
155 Simple, // This is a normal l-value, use getAddress().
156 VectorElt, // This is a vector element l-value (V[i]), use getVector*
157 BitField, // This is a bitfield l-value, use getBitfield*.
158 ExtVectorElt, // This is an extended vector subset, use getExtVectorComp
159 GlobalReg, // This is a register l-value, use getGlobalReg()
160 MatrixElt // This is a matrix element, use getVector*
161 } lvType;
162 clang::QualType type;
163 clang::Qualifiers quals;
164
165 // The alignment to use when accessing this lvalue. (For vector elements,
166 // this is the alignment of the whole vector)
167 unsigned alignment;
168 mlir::Value v;
169 mlir::Value vectorIdx; // Index for vector subscript
170 mlir::Type elementType;
171 LValueBaseInfo baseInfo;
172 const CIRGenBitFieldInfo *bitFieldInfo{nullptr};
173
174 void initialize(clang::QualType type, clang::Qualifiers quals,
175 clang::CharUnits alignment, LValueBaseInfo baseInfo) {
176 assert((!alignment.isZero() || type->isIncompleteType()) &&
177 "initializing l-value with zero alignment!");
178 this->type = type;
179 this->quals = quals;
180 const unsigned maxAlign = 1U << 31;
181 this->alignment = alignment.getQuantity() <= maxAlign
182 ? alignment.getQuantity()
183 : maxAlign;
184 assert(this->alignment == alignment.getQuantity() &&
185 "Alignment exceeds allowed max!");
186 this->baseInfo = baseInfo;
187 }
188
189public:
190 bool isSimple() const { return lvType == Simple; }
191 bool isVectorElt() const { return lvType == VectorElt; }
192 bool isBitField() const { return lvType == BitField; }
193 bool isGlobalReg() const { return lvType == GlobalReg; }
194 bool isVolatile() const { return quals.hasVolatile(); }
195
196 bool isVolatileQualified() const { return quals.hasVolatile(); }
197
198 unsigned getVRQualifiers() const {
200 }
201
202 clang::QualType getType() const { return type; }
203
204 mlir::Value getPointer() const { return v; }
205
207 return clang::CharUnits::fromQuantity(alignment);
208 }
209 void setAlignment(clang::CharUnits a) { alignment = a.getQuantity(); }
210
212 return Address(getPointer(), elementType, getAlignment());
213 }
214
215 void setAddress(Address address) {
216 assert(isSimple());
217 v = address.getPointer();
218 elementType = address.getElementType();
219 alignment = address.getAlignment().getQuantity();
221 }
222
223 const clang::Qualifiers &getQuals() const { return quals; }
224 clang::Qualifiers &getQuals() { return quals; }
225
226 LValueBaseInfo getBaseInfo() const { return baseInfo; }
227 void setBaseInfo(LValueBaseInfo info) { baseInfo = info; }
228
230 LValueBaseInfo baseInfo) {
231 // Classic codegen sets the objc gc qualifier here. That requires an
232 // ASTContext, which is passed in from CIRGenFunction::makeAddrLValue.
234
235 LValue r;
236 r.lvType = Simple;
237 r.v = address.getPointer();
238 r.elementType = address.getElementType();
239 r.initialize(t, t.getQualifiers(), address.getAlignment(), baseInfo);
240 return r;
241 }
242
244 return Address(getVectorPointer(), elementType, getAlignment());
245 }
246
247 mlir::Value getVectorPointer() const {
248 assert(isVectorElt());
249 return v;
250 }
251
252 mlir::Value getVectorIdx() const {
253 assert(isVectorElt());
254 return vectorIdx;
255 }
256
257 static LValue makeVectorElt(Address vecAddress, mlir::Value index,
258 clang::QualType t, LValueBaseInfo baseInfo) {
259 LValue r;
260 r.lvType = VectorElt;
261 r.v = vecAddress.getPointer();
262 r.elementType = vecAddress.getElementType();
263 r.vectorIdx = index;
264 r.initialize(t, t.getQualifiers(), vecAddress.getAlignment(), baseInfo);
265 return r;
266 }
267
268 // bitfield lvalue
270 return Address(getBitFieldPointer(), elementType, getAlignment());
271 }
272
273 mlir::Value getBitFieldPointer() const {
274 assert(isBitField());
275 return v;
276 }
277
279 assert(isBitField());
280 return *bitFieldInfo;
281 }
282
283 /// Create a new object to represent a bit-field access.
284 ///
285 /// \param Addr - The base address of the bit-field sequence this
286 /// bit-field refers to.
287 /// \param Info - The information describing how to perform the bit-field
288 /// access.
290 clang::QualType type, LValueBaseInfo baseInfo) {
291 LValue r;
292 r.lvType = BitField;
293 r.v = addr.getPointer();
294 r.elementType = addr.getElementType();
295 r.bitFieldInfo = &info;
296 r.initialize(type, type.getQualifiers(), addr.getAlignment(), baseInfo);
297 return r;
298 }
299};
300
301/// An aggregate value slot.
303
304 Address addr;
305 clang::Qualifiers quals;
306
307 /// This is set to true if some external code is responsible for setting up a
308 /// destructor for the slot. Otherwise the code which constructs it should
309 /// push the appropriate cleanup.
310 LLVM_PREFERRED_TYPE(bool)
311 LLVM_ATTRIBUTE_UNUSED unsigned destructedFlag : 1;
312
313 /// This is set to true if the memory in the slot is known to be zero before
314 /// the assignment into it. This means that zero fields don't need to be set.
315 LLVM_PREFERRED_TYPE(bool)
316 unsigned zeroedFlag : 1;
317
318 /// This is set to true if the slot might be aliased and it's not undefined
319 /// behavior to access it through such an alias. Note that it's always
320 /// undefined behavior to access a C++ object that's under construction
321 /// through an alias derived from outside the construction process.
322 ///
323 /// This flag controls whether calls that produce the aggregate
324 /// value may be evaluated directly into the slot, or whether they
325 /// must be evaluated into an unaliased temporary and then memcpy'ed
326 /// over. Since it's invalid in general to memcpy a non-POD C++
327 /// object, it's important that this flag never be set when
328 /// evaluating an expression which constructs such an object.
329 LLVM_PREFERRED_TYPE(bool)
330 LLVM_ATTRIBUTE_UNUSED unsigned aliasedFlag : 1;
331
332 /// This is set to true if the tail padding of this slot might overlap
333 /// another object that may have already been initialized (and whose
334 /// value must be preserved by this initialization). If so, we may only
335 /// store up to the dsize of the type. Otherwise we can widen stores to
336 /// the size of the type.
337 LLVM_PREFERRED_TYPE(bool)
338 LLVM_ATTRIBUTE_UNUSED unsigned overlapFlag : 1;
339
340public:
345
346 /// Returns an aggregate value slot indicating that the aggregate
347 /// value is being ignored.
351 }
352
353 AggValueSlot(Address addr, clang::Qualifiers quals, bool destructedFlag,
354 bool zeroedFlag, bool aliasedFlag, bool overlapFlag)
355 : addr(addr), quals(quals), destructedFlag(destructedFlag),
356 zeroedFlag(zeroedFlag), aliasedFlag(aliasedFlag),
357 overlapFlag(overlapFlag) {}
358
360 IsDestructed_t isDestructed,
361 IsAliased_t isAliased, Overlap_t mayOverlap,
363 return AggValueSlot(addr, quals, isDestructed, isZeroed, isAliased,
364 mayOverlap);
365 }
366
367 static AggValueSlot forLValue(const LValue &LV, IsDestructed_t isDestructed,
368 IsAliased_t isAliased, Overlap_t mayOverlap,
370 return forAddr(LV.getAddress(), LV.getQuals(), isDestructed, isAliased,
371 mayOverlap, isZeroed);
372 }
373
374 clang::Qualifiers getQualifiers() const { return quals; }
375
376 Address getAddress() const { return addr; }
377
378 bool isIgnored() const { return !addr.isValid(); }
379
380 mlir::Value getPointer() const { return addr.getPointer(); }
381
382 IsZeroed_t isZeroed() const { return IsZeroed_t(zeroedFlag); }
383
384 RValue asRValue() const {
385 if (isIgnored())
386 return RValue::getIgnored();
389 }
390};
391
392} // namespace clang::CIRGen
393
394#endif // CLANG_LIB_CIR_CIRGENVALUE_H
C Language Family Type Representation.
mlir::Value getPointer() const
Definition: Address.h:81
mlir::Type getElementType() const
Definition: Address.h:101
static Address invalid()
Definition: Address.h:66
clang::CharUnits getAlignment() const
Definition: Address.h:109
bool isValid() const
Definition: Address.h:67
An aggregate value slot.
Definition: CIRGenValue.h:302
IsZeroed_t isZeroed() const
Definition: CIRGenValue.h:382
static AggValueSlot forAddr(Address addr, clang::Qualifiers quals, IsDestructed_t isDestructed, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed)
Definition: CIRGenValue.h:359
AggValueSlot(Address addr, clang::Qualifiers quals, bool destructedFlag, bool zeroedFlag, bool aliasedFlag, bool overlapFlag)
Definition: CIRGenValue.h:353
static AggValueSlot forLValue(const LValue &LV, IsDestructed_t isDestructed, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed)
Definition: CIRGenValue.h:367
Address getAddress() const
Definition: CIRGenValue.h:376
static AggValueSlot ignored()
Returns an aggregate value slot indicating that the aggregate value is being ignored.
Definition: CIRGenValue.h:348
mlir::Value getPointer() const
Definition: CIRGenValue.h:380
clang::Qualifiers getQualifiers() const
Definition: CIRGenValue.h:374
AlignmentSource getAlignmentSource() const
Definition: CIRGenValue.h:145
void mergeForCast(const LValueBaseInfo &info)
Definition: CIRGenValue.h:148
LValueBaseInfo(AlignmentSource source=AlignmentSource::Type)
Definition: CIRGenValue.h:143
void setAlignmentSource(AlignmentSource source)
Definition: CIRGenValue.h:146
mlir::Value getBitFieldPointer() const
Definition: CIRGenValue.h:273
mlir::Value getVectorPointer() const
Definition: CIRGenValue.h:247
const clang::Qualifiers & getQuals() const
Definition: CIRGenValue.h:223
mlir::Value getVectorIdx() const
Definition: CIRGenValue.h:252
bool isVectorElt() const
Definition: CIRGenValue.h:191
Address getAddress() const
Definition: CIRGenValue.h:211
static LValue makeAddr(Address address, clang::QualType t, LValueBaseInfo baseInfo)
Definition: CIRGenValue.h:229
static LValue makeVectorElt(Address vecAddress, mlir::Value index, clang::QualType t, LValueBaseInfo baseInfo)
Definition: CIRGenValue.h:257
unsigned getVRQualifiers() const
Definition: CIRGenValue.h:198
clang::QualType getType() const
Definition: CIRGenValue.h:202
static LValue makeBitfield(Address addr, const CIRGenBitFieldInfo &info, clang::QualType type, LValueBaseInfo baseInfo)
Create a new object to represent a bit-field access.
Definition: CIRGenValue.h:289
mlir::Value getPointer() const
Definition: CIRGenValue.h:204
clang::Qualifiers & getQuals()
Definition: CIRGenValue.h:224
bool isVolatileQualified() const
Definition: CIRGenValue.h:196
bool isBitField() const
Definition: CIRGenValue.h:192
void setAlignment(clang::CharUnits a)
Definition: CIRGenValue.h:209
Address getVectorAddress() const
Definition: CIRGenValue.h:243
clang::CharUnits getAlignment() const
Definition: CIRGenValue.h:206
LValueBaseInfo getBaseInfo() const
Definition: CIRGenValue.h:226
void setBaseInfo(LValueBaseInfo info)
Definition: CIRGenValue.h:227
bool isVolatile() const
Definition: CIRGenValue.h:194
bool isGlobalReg() const
Definition: CIRGenValue.h:193
const CIRGenBitFieldInfo & getBitFieldInfo() const
Definition: CIRGenValue.h:278
Address getBitFieldAddress() const
Definition: CIRGenValue.h:269
void setAddress(Address address)
Definition: CIRGenValue.h:215
bool isSimple() const
Definition: CIRGenValue.h:190
This trivial value class is used to represent the result of an expression that is evaluated.
Definition: CIRGenValue.h:33
Address getAggregateAddress() const
Return the value of the address of the aggregate.
Definition: CIRGenValue.h:68
bool isAggregate() const
Definition: CIRGenValue.h:51
static RValue get(mlir::Value v)
Definition: CIRGenValue.h:82
static RValue getAggregate(Address addr, bool isVolatile=false)
Convert an Address to an RValue.
Definition: CIRGenValue.h:104
mlir::Value getAggregatePointer(QualType pointeeType) const
Definition: CIRGenValue.h:73
static RValue getComplex(mlir::Value v)
Definition: CIRGenValue.h:90
bool isComplex() const
Definition: CIRGenValue.h:50
bool isVolatileQualified() const
Definition: CIRGenValue.h:53
mlir::Value getValue() const
Return the value of this scalar value.
Definition: CIRGenValue.h:56
bool isScalar() const
Definition: CIRGenValue.h:49
mlir::Value getComplexValue() const
Return the value of this complex value.
Definition: CIRGenValue.h:62
static RValue getIgnored()
Definition: CIRGenValue.h:77
CharUnits - This is an opaque type for sizes expressed in character units.
Definition: CharUnits.h:38
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition: CharUnits.h:185
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Definition: CharUnits.h:63
A (possibly-)qualified type.
Definition: TypeBase.h:937
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition: TypeBase.h:8383
The collection of all-type qualifiers we support.
Definition: TypeBase.h:331
unsigned getCVRQualifiers() const
Definition: TypeBase.h:488
bool hasVolatile() const
Definition: TypeBase.h:467
The base class of the type hierarchy.
Definition: TypeBase.h:1833
AlignmentSource
The source of the alignment of an l-value; an expression of confidence in the alignment actually matc...
Definition: CIRGenValue.h:115
@ AttributedType
The l-value was considered opaque, so the alignment was determined from a type, but that type was an ...
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
static AlignmentSource getFieldAlignmentSource(AlignmentSource source)
Given that the base address has the given alignment source, what's our confidence in the alignment of...
Definition: CIRGenValue.h:133
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
The JSON file list parser is used to communicate input to InstallAPI.
static bool aggValueSlot()
static bool addressIsKnownNonNull()
Record with information about how a bitfield should be accessed.