Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
213799 views
1
#include "CIRGenBuilder.h"
2
#include "CIRGenFunction.h"
3
4
#include "clang/AST/StmtVisitor.h"
5
6
using namespace clang;
7
using namespace clang::CIRGen;
8
9
namespace {
10
class ComplexExprEmitter : public StmtVisitor<ComplexExprEmitter, mlir::Value> {
11
CIRGenFunction &cgf;
12
CIRGenBuilderTy &builder;
13
14
public:
15
explicit ComplexExprEmitter(CIRGenFunction &cgf)
16
: cgf(cgf), builder(cgf.getBuilder()) {}
17
18
//===--------------------------------------------------------------------===//
19
// Utilities
20
//===--------------------------------------------------------------------===//
21
22
LValue emitBinAssignLValue(const BinaryOperator *e, mlir::Value &val);
23
24
mlir::Value emitCast(CastKind ck, Expr *op, QualType destTy);
25
26
mlir::Value emitConstant(const CIRGenFunction::ConstantEmission &constant,
27
Expr *e);
28
29
/// Given an expression with complex type that represents a value l-value,
30
/// this method emits the address of the l-value, then loads and returns the
31
/// result.
32
mlir::Value emitLoadOfLValue(const Expr *e) {
33
return emitLoadOfLValue(cgf.emitLValue(e), e->getExprLoc());
34
}
35
36
mlir::Value emitLoadOfLValue(LValue lv, SourceLocation loc);
37
/// Store the specified real/imag parts into the
38
/// specified value pointer.
39
void emitStoreOfComplex(mlir::Location loc, mlir::Value val, LValue lv,
40
bool isInit);
41
42
mlir::Value
43
VisitAbstractConditionalOperator(const AbstractConditionalOperator *e);
44
mlir::Value VisitArraySubscriptExpr(Expr *e);
45
mlir::Value VisitBinAssign(const BinaryOperator *e);
46
mlir::Value VisitBinComma(const BinaryOperator *e);
47
mlir::Value VisitCallExpr(const CallExpr *e);
48
mlir::Value VisitCastExpr(CastExpr *e);
49
mlir::Value VisitChooseExpr(ChooseExpr *e);
50
mlir::Value VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *e);
51
mlir::Value VisitDeclRefExpr(DeclRefExpr *e);
52
mlir::Value VisitGenericSelectionExpr(GenericSelectionExpr *e);
53
mlir::Value VisitImplicitCastExpr(ImplicitCastExpr *e);
54
mlir::Value VisitInitListExpr(const InitListExpr *e);
55
mlir::Value VisitImaginaryLiteral(const ImaginaryLiteral *il);
56
mlir::Value VisitParenExpr(ParenExpr *e);
57
mlir::Value
58
VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *e);
59
mlir::Value VisitUnaryDeref(const Expr *e);
60
61
struct BinOpInfo {
62
mlir::Location loc;
63
mlir::Value lhs{};
64
mlir::Value rhs{};
65
QualType ty{}; // Computation Type.
66
FPOptions fpFeatures{};
67
};
68
69
BinOpInfo emitBinOps(const BinaryOperator *e,
70
QualType promotionTy = QualType());
71
72
mlir::Value emitPromoted(const Expr *e, QualType promotionTy);
73
74
mlir::Value emitPromotedComplexOperand(const Expr *e, QualType promotionTy);
75
76
mlir::Value emitBinAdd(const BinOpInfo &op);
77
mlir::Value emitBinSub(const BinOpInfo &op);
78
79
QualType getPromotionType(QualType ty, bool isDivOpCode = false) {
80
if (auto *complexTy = ty->getAs<ComplexType>()) {
81
QualType elementTy = complexTy->getElementType();
82
if (isDivOpCode && elementTy->isFloatingType() &&
83
cgf.getLangOpts().getComplexRange() ==
84
LangOptions::ComplexRangeKind::CX_Promoted) {
85
cgf.cgm.errorNYI("HigherPrecisionTypeForComplexArithmetic");
86
return QualType();
87
}
88
89
if (elementTy.UseExcessPrecision(cgf.getContext()))
90
return cgf.getContext().getComplexType(cgf.getContext().FloatTy);
91
}
92
93
if (ty.UseExcessPrecision(cgf.getContext()))
94
return cgf.getContext().FloatTy;
95
return QualType();
96
}
97
98
#define HANDLEBINOP(OP) \
99
mlir::Value VisitBin##OP(const BinaryOperator *e) { \
100
QualType promotionTy = getPromotionType( \
101
e->getType(), e->getOpcode() == BinaryOperatorKind::BO_Div); \
102
mlir::Value result = emitBin##OP(emitBinOps(e, promotionTy)); \
103
if (!promotionTy.isNull()) \
104
cgf.cgm.errorNYI("Binop emitUnPromotedValue"); \
105
return result; \
106
}
107
108
HANDLEBINOP(Add)
109
HANDLEBINOP(Sub)
110
#undef HANDLEBINOP
111
};
112
} // namespace
113
114
static const ComplexType *getComplexType(QualType type) {
115
type = type.getCanonicalType();
116
if (const ComplexType *comp = dyn_cast<ComplexType>(type))
117
return comp;
118
return cast<ComplexType>(cast<AtomicType>(type)->getValueType());
119
}
120
121
LValue ComplexExprEmitter::emitBinAssignLValue(const BinaryOperator *e,
122
mlir::Value &value) {
123
assert(cgf.getContext().hasSameUnqualifiedType(e->getLHS()->getType(),
124
e->getRHS()->getType()) &&
125
"Invalid assignment");
126
127
// Emit the RHS. __block variables need the RHS evaluated first.
128
value = Visit(e->getRHS());
129
130
// Compute the address to store into.
131
LValue lhs = cgf.emitLValue(e->getLHS());
132
133
// Store the result value into the LHS lvalue.
134
emitStoreOfComplex(cgf.getLoc(e->getExprLoc()), value, lhs, /*isInit*/ false);
135
return lhs;
136
}
137
138
mlir::Value ComplexExprEmitter::emitCast(CastKind ck, Expr *op,
139
QualType destTy) {
140
switch (ck) {
141
case CK_NoOp:
142
case CK_LValueToRValue:
143
return Visit(op);
144
default:
145
break;
146
}
147
cgf.cgm.errorNYI("ComplexType Cast");
148
return {};
149
}
150
151
mlir::Value ComplexExprEmitter::emitConstant(
152
const CIRGenFunction::ConstantEmission &constant, Expr *e) {
153
assert(constant && "not a constant");
154
if (constant.isReference())
155
return emitLoadOfLValue(constant.getReferenceLValue(cgf, e),
156
e->getExprLoc());
157
158
mlir::TypedAttr valueAttr = constant.getValue();
159
return builder.getConstant(cgf.getLoc(e->getSourceRange()), valueAttr);
160
}
161
162
mlir::Value ComplexExprEmitter::emitLoadOfLValue(LValue lv,
163
SourceLocation loc) {
164
assert(lv.isSimple() && "non-simple complex l-value?");
165
if (lv.getType()->isAtomicType())
166
cgf.cgm.errorNYI(loc, "emitLoadOfLValue with Atomic LV");
167
168
const Address srcAddr = lv.getAddress();
169
return builder.createLoad(cgf.getLoc(loc), srcAddr);
170
}
171
172
void ComplexExprEmitter::emitStoreOfComplex(mlir::Location loc, mlir::Value val,
173
LValue lv, bool isInit) {
174
if (lv.getType()->isAtomicType() ||
175
(!isInit && cgf.isLValueSuitableForInlineAtomic(lv))) {
176
cgf.cgm.errorNYI(loc, "StoreOfComplex with Atomic LV");
177
return;
178
}
179
180
const Address destAddr = lv.getAddress();
181
builder.createStore(loc, val, destAddr);
182
}
183
184
mlir::Value ComplexExprEmitter::VisitAbstractConditionalOperator(
185
const AbstractConditionalOperator *e) {
186
mlir::Value condValue = Visit(e->getCond());
187
mlir::Location loc = cgf.getLoc(e->getSourceRange());
188
189
return builder
190
.create<cir::TernaryOp>(
191
loc, condValue,
192
/*thenBuilder=*/
193
[&](mlir::OpBuilder &b, mlir::Location loc) {
194
mlir::Value trueValue = Visit(e->getTrueExpr());
195
b.create<cir::YieldOp>(loc, trueValue);
196
},
197
/*elseBuilder=*/
198
[&](mlir::OpBuilder &b, mlir::Location loc) {
199
mlir::Value falseValue = Visit(e->getFalseExpr());
200
b.create<cir::YieldOp>(loc, falseValue);
201
})
202
.getResult();
203
}
204
205
mlir::Value ComplexExprEmitter::VisitArraySubscriptExpr(Expr *e) {
206
return emitLoadOfLValue(e);
207
}
208
209
mlir::Value ComplexExprEmitter::VisitBinAssign(const BinaryOperator *e) {
210
mlir::Value value;
211
LValue lv = emitBinAssignLValue(e, value);
212
213
// The result of an assignment in C is the assigned r-value.
214
if (!cgf.getLangOpts().CPlusPlus)
215
return value;
216
217
// If the lvalue is non-volatile, return the computed value of the
218
// assignment.
219
if (!lv.isVolatile())
220
return value;
221
222
return emitLoadOfLValue(lv, e->getExprLoc());
223
}
224
225
mlir::Value ComplexExprEmitter::VisitBinComma(const BinaryOperator *e) {
226
cgf.emitIgnoredExpr(e->getLHS());
227
return Visit(e->getRHS());
228
}
229
230
mlir::Value ComplexExprEmitter::VisitCallExpr(const CallExpr *e) {
231
if (e->getCallReturnType(cgf.getContext())->isReferenceType())
232
return emitLoadOfLValue(e);
233
234
return cgf.emitCallExpr(e).getValue();
235
}
236
237
mlir::Value ComplexExprEmitter::VisitCastExpr(CastExpr *e) {
238
if (const auto *ece = dyn_cast<ExplicitCastExpr>(e)) {
239
// Bind VLAs in the cast type.
240
if (ece->getType()->isVariablyModifiedType()) {
241
cgf.cgm.errorNYI("VisitCastExpr Bind VLAs in the cast type");
242
return {};
243
}
244
}
245
246
if (e->changesVolatileQualification())
247
return emitLoadOfLValue(e);
248
249
return emitCast(e->getCastKind(), e->getSubExpr(), e->getType());
250
}
251
252
mlir::Value ComplexExprEmitter::VisitChooseExpr(ChooseExpr *e) {
253
return Visit(e->getChosenSubExpr());
254
}
255
256
mlir::Value
257
ComplexExprEmitter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *e) {
258
mlir::Location loc = cgf.getLoc(e->getExprLoc());
259
mlir::Type complexTy = cgf.convertType(e->getType());
260
return builder.getNullValue(complexTy, loc);
261
}
262
263
mlir::Value ComplexExprEmitter::VisitDeclRefExpr(DeclRefExpr *e) {
264
if (CIRGenFunction::ConstantEmission constant = cgf.tryEmitAsConstant(e))
265
return emitConstant(constant, e);
266
return emitLoadOfLValue(e);
267
}
268
269
mlir::Value
270
ComplexExprEmitter::VisitGenericSelectionExpr(GenericSelectionExpr *e) {
271
return Visit(e->getResultExpr());
272
}
273
274
mlir::Value ComplexExprEmitter::VisitImplicitCastExpr(ImplicitCastExpr *e) {
275
// Unlike for scalars, we don't have to worry about function->ptr demotion
276
// here.
277
if (e->changesVolatileQualification())
278
return emitLoadOfLValue(e);
279
return emitCast(e->getCastKind(), e->getSubExpr(), e->getType());
280
}
281
282
mlir::Value ComplexExprEmitter::VisitInitListExpr(const InitListExpr *e) {
283
mlir::Location loc = cgf.getLoc(e->getExprLoc());
284
if (e->getNumInits() == 2) {
285
mlir::Value real = cgf.emitScalarExpr(e->getInit(0));
286
mlir::Value imag = cgf.emitScalarExpr(e->getInit(1));
287
return builder.createComplexCreate(loc, real, imag);
288
}
289
290
if (e->getNumInits() == 1) {
291
cgf.cgm.errorNYI("Create Complex with InitList with size 1");
292
return {};
293
}
294
295
assert(e->getNumInits() == 0 && "Unexpected number of inits");
296
mlir::Type complexTy = cgf.convertType(e->getType());
297
return builder.getNullValue(complexTy, loc);
298
}
299
300
mlir::Value
301
ComplexExprEmitter::VisitImaginaryLiteral(const ImaginaryLiteral *il) {
302
auto ty = mlir::cast<cir::ComplexType>(cgf.convertType(il->getType()));
303
mlir::Type elementTy = ty.getElementType();
304
mlir::Location loc = cgf.getLoc(il->getExprLoc());
305
306
mlir::TypedAttr realValueAttr;
307
mlir::TypedAttr imagValueAttr;
308
309
if (mlir::isa<cir::IntType>(elementTy)) {
310
llvm::APInt imagValue = cast<IntegerLiteral>(il->getSubExpr())->getValue();
311
realValueAttr = cir::IntAttr::get(elementTy, 0);
312
imagValueAttr = cir::IntAttr::get(elementTy, imagValue);
313
} else {
314
assert(mlir::isa<cir::FPTypeInterface>(elementTy) &&
315
"Expected complex element type to be floating-point");
316
317
llvm::APFloat imagValue =
318
cast<FloatingLiteral>(il->getSubExpr())->getValue();
319
realValueAttr = cir::FPAttr::get(
320
elementTy, llvm::APFloat::getZero(imagValue.getSemantics()));
321
imagValueAttr = cir::FPAttr::get(elementTy, imagValue);
322
}
323
324
auto complexAttr = cir::ConstComplexAttr::get(realValueAttr, imagValueAttr);
325
return builder.create<cir::ConstantOp>(loc, complexAttr);
326
}
327
328
mlir::Value ComplexExprEmitter::VisitParenExpr(ParenExpr *e) {
329
return Visit(e->getSubExpr());
330
}
331
332
mlir::Value ComplexExprEmitter::VisitSubstNonTypeTemplateParmExpr(
333
SubstNonTypeTemplateParmExpr *e) {
334
return Visit(e->getReplacement());
335
}
336
337
mlir::Value ComplexExprEmitter::VisitUnaryDeref(const Expr *e) {
338
return emitLoadOfLValue(e);
339
}
340
341
mlir::Value ComplexExprEmitter::emitPromoted(const Expr *e,
342
QualType promotionTy) {
343
e = e->IgnoreParens();
344
if (const auto *bo = dyn_cast<BinaryOperator>(e)) {
345
switch (bo->getOpcode()) {
346
#define HANDLE_BINOP(OP) \
347
case BO_##OP: \
348
return emitBin##OP(emitBinOps(bo, promotionTy));
349
HANDLE_BINOP(Add)
350
HANDLE_BINOP(Sub)
351
#undef HANDLE_BINOP
352
default:
353
break;
354
}
355
} else if (isa<UnaryOperator>(e)) {
356
cgf.cgm.errorNYI("emitPromoted UnaryOperator");
357
return {};
358
}
359
360
mlir::Value result = Visit(const_cast<Expr *>(e));
361
if (!promotionTy.isNull())
362
cgf.cgm.errorNYI("emitPromoted emitPromotedValue");
363
364
return result;
365
}
366
367
mlir::Value
368
ComplexExprEmitter::emitPromotedComplexOperand(const Expr *e,
369
QualType promotionTy) {
370
if (e->getType()->isAnyComplexType()) {
371
if (!promotionTy.isNull())
372
return cgf.emitPromotedComplexExpr(e, promotionTy);
373
return Visit(const_cast<Expr *>(e));
374
}
375
376
cgf.cgm.errorNYI("emitPromotedComplexOperand non-complex type");
377
return {};
378
}
379
380
ComplexExprEmitter::BinOpInfo
381
ComplexExprEmitter::emitBinOps(const BinaryOperator *e, QualType promotionTy) {
382
BinOpInfo binOpInfo{cgf.getLoc(e->getExprLoc())};
383
binOpInfo.lhs = emitPromotedComplexOperand(e->getLHS(), promotionTy);
384
binOpInfo.rhs = emitPromotedComplexOperand(e->getRHS(), promotionTy);
385
binOpInfo.ty = promotionTy.isNull() ? e->getType() : promotionTy;
386
binOpInfo.fpFeatures = e->getFPFeaturesInEffect(cgf.getLangOpts());
387
return binOpInfo;
388
}
389
390
mlir::Value ComplexExprEmitter::emitBinAdd(const BinOpInfo &op) {
391
assert(!cir::MissingFeatures::fastMathFlags());
392
assert(!cir::MissingFeatures::cgFPOptionsRAII());
393
return builder.create<cir::ComplexAddOp>(op.loc, op.lhs, op.rhs);
394
}
395
396
mlir::Value ComplexExprEmitter::emitBinSub(const BinOpInfo &op) {
397
assert(!cir::MissingFeatures::fastMathFlags());
398
assert(!cir::MissingFeatures::cgFPOptionsRAII());
399
return builder.create<cir::ComplexSubOp>(op.loc, op.lhs, op.rhs);
400
}
401
402
LValue CIRGenFunction::emitComplexAssignmentLValue(const BinaryOperator *e) {
403
assert(e->getOpcode() == BO_Assign && "Expected assign op");
404
405
mlir::Value value; // ignored
406
LValue lvalue = ComplexExprEmitter(*this).emitBinAssignLValue(e, value);
407
if (getLangOpts().OpenMP)
408
cgm.errorNYI("emitComplexAssignmentLValue OpenMP");
409
410
return lvalue;
411
}
412
413
mlir::Value CIRGenFunction::emitComplexExpr(const Expr *e) {
414
assert(e && getComplexType(e->getType()) &&
415
"Invalid complex expression to emit");
416
417
return ComplexExprEmitter(*this).Visit(const_cast<Expr *>(e));
418
}
419
420
void CIRGenFunction::emitStoreOfComplex(mlir::Location loc, mlir::Value v,
421
LValue dest, bool isInit) {
422
ComplexExprEmitter(*this).emitStoreOfComplex(loc, v, dest, isInit);
423
}
424
425
mlir::Value CIRGenFunction::emitPromotedComplexExpr(const Expr *e,
426
QualType promotionType) {
427
return ComplexExprEmitter(*this).emitPromoted(e, promotionType);
428
}
429
430