22
22
23
23
using namespace fir ;
24
24
25
+ namespace fir ::details {
26
+ llvm::StringRef Attributes::getIntExtensionAttrName () const {
27
+ // The attribute names are available via LLVM dialect interfaces
28
+ // like getZExtAttrName(), getByValAttrName(), etc., so we'd better
29
+ // use them than literals.
30
+ if (isZeroExt ())
31
+ return " llvm.zeroext" ;
32
+ else if (isSignExt ())
33
+ return " llvm.signext" ;
34
+ return {};
35
+ }
36
+ } // namespace fir::details
37
+
25
38
// Reduce a REAL/float type to the floating point semantics.
26
39
static const llvm::fltSemantics &floatToSemantics (const KindMapping &kindMap,
27
40
mlir::Type type) {
@@ -41,17 +54,17 @@ struct GenericTarget : public CodeGenSpecifics {
41
54
assert (fir::isa_real (eleTy));
42
55
// Use a type that will be translated into LLVM as:
43
56
// { t, t } struct of 2 eleTy
44
- mlir::TypeRange range = { eleTy, eleTy};
45
- return mlir::TupleType::get ( eleTy. getContext (), range );
57
+ return mlir::TupleType::get ( eleTy. getContext (),
58
+ mlir::TypeRange{ eleTy, eleTy} );
46
59
}
47
60
48
61
mlir::Type boxcharMemoryType (mlir::Type eleTy) const override {
49
62
auto idxTy = mlir::IntegerType::get (eleTy.getContext (), S::defaultWidth);
50
63
auto ptrTy = fir::ReferenceType::get (eleTy);
51
64
// Use a type that will be translated into LLVM as:
52
65
// { t*, index }
53
- mlir::TypeRange range = {ptrTy, idxTy};
54
- return mlir::TupleType::get (eleTy. getContext (), range );
66
+ return mlir::TupleType::get (eleTy. getContext (),
67
+ mlir::TypeRange{ptrTy, idxTy} );
55
68
}
56
69
57
70
Marshalling boxcharArgumentType (mlir::Type eleTy, bool sret) const override {
@@ -67,6 +80,46 @@ struct GenericTarget : public CodeGenSpecifics {
67
80
/* sret=*/ sret, /* append=*/ !sret});
68
81
return marshal;
69
82
}
83
+
84
+ CodeGenSpecifics::Marshalling
85
+ integerArgumentType (mlir::Location loc,
86
+ mlir::IntegerType argTy) const override {
87
+ CodeGenSpecifics::Marshalling marshal;
88
+ AT::IntegerExtension intExt = AT::IntegerExtension::None;
89
+ if (argTy.getWidth () < getCIntTypeWidth ()) {
90
+ // isSigned() and isUnsigned() branches below are dead code currently.
91
+ // If needed, we can generate calls with signed/unsigned argument types
92
+ // to more precisely match C side (e.g. for Fortran runtime functions
93
+ // with 'unsigned short' arguments).
94
+ if (argTy.isSigned ())
95
+ intExt = AT::IntegerExtension::Sign;
96
+ else if (argTy.isUnsigned ())
97
+ intExt = AT::IntegerExtension::Zero;
98
+ else if (argTy.isSignless ()) {
99
+ // Zero extend for 'i1' and sign extend for other types.
100
+ if (argTy.getWidth () == 1 )
101
+ intExt = AT::IntegerExtension::Zero;
102
+ else
103
+ intExt = AT::IntegerExtension::Sign;
104
+ }
105
+ }
106
+
107
+ marshal.emplace_back (argTy, AT{/* alignment=*/ 0 , /* byval=*/ false ,
108
+ /* sret=*/ false , /* append=*/ false ,
109
+ /* intExt=*/ intExt});
110
+ return marshal;
111
+ }
112
+
113
+ CodeGenSpecifics::Marshalling
114
+ integerReturnType (mlir::Location loc,
115
+ mlir::IntegerType argTy) const override {
116
+ return integerArgumentType (loc, argTy);
117
+ }
118
+
119
+ // Width of 'int' type is 32-bits for almost all targets, except
120
+ // for AVR and MSP430 (see TargetInfo initializations
121
+ // in clang/lib/Basic/Targets).
122
+ unsigned char getCIntTypeWidth () const override { return 32 ; }
70
123
};
71
124
} // namespace
72
125
@@ -86,8 +139,8 @@ struct TargetI386 : public GenericTarget<TargetI386> {
86
139
CodeGenSpecifics::Marshalling marshal;
87
140
// Use a type that will be translated into LLVM as:
88
141
// { t, t } struct of 2 eleTy, byval, align 4
89
- mlir::TypeRange range = {eleTy, eleTy};
90
- auto structTy = mlir::TupleType::get (eleTy.getContext (), range );
142
+ auto structTy =
143
+ mlir::TupleType::get (eleTy.getContext (), mlir::TypeRange{eleTy, eleTy} );
91
144
marshal.emplace_back (fir::ReferenceType::get (structTy),
92
145
AT{/* alignment=*/ 4 , /* byval=*/ true });
93
146
return marshal;
@@ -105,8 +158,8 @@ struct TargetI386 : public GenericTarget<TargetI386> {
105
158
} else if (sem == &llvm::APFloat::IEEEdouble ()) {
106
159
// Use a type that will be translated into LLVM as:
107
160
// { t, t } struct of 2 eleTy, sret, align 4
108
- mlir::TypeRange range = { eleTy, eleTy};
109
- auto structTy = mlir::TupleType::get ( eleTy. getContext (), range );
161
+ auto structTy = mlir::TupleType::get ( eleTy. getContext (),
162
+ mlir::TypeRange{ eleTy, eleTy} );
110
163
marshal.emplace_back (fir::ReferenceType::get (structTy),
111
164
AT{/* alignment=*/ 4 , /* byval=*/ false , /* sret=*/ true });
112
165
} else {
@@ -141,10 +194,10 @@ struct TargetX86_64 : public GenericTarget<TargetX86_64> {
141
194
} else if (sem == &llvm::APFloat::IEEEquad ()) {
142
195
// Use a type that will be translated into LLVM as:
143
196
// { fp128, fp128 } struct of 2 fp128, byval, align 16
144
- mlir::TypeRange range = {eleTy, eleTy};
145
- marshal. emplace_back ( fir::ReferenceType::get (
146
- mlir::TupleType::get ( eleTy.getContext (), range )),
147
- AT{/* align=*/ 16 , /* byval=*/ true });
197
+ marshal. emplace_back (
198
+ fir::ReferenceType::get ( mlir::TupleType ::get (
199
+ eleTy.getContext (), mlir::TypeRange{eleTy, eleTy} )),
200
+ AT{/* align=*/ 16 , /* byval=*/ true });
148
201
} else {
149
202
TODO (loc, " complex for this precision" );
150
203
}
@@ -161,16 +214,16 @@ struct TargetX86_64 : public GenericTarget<TargetX86_64> {
161
214
} else if (sem == &llvm::APFloat::IEEEdouble ()) {
162
215
// Use a type that will be translated into LLVM as:
163
216
// { double, double } struct of 2 double
164
- mlir::TypeRange range = { eleTy, eleTy};
165
- marshal. emplace_back ( mlir::TupleType::get ( eleTy. getContext (), range ),
217
+ marshal. emplace_back ( mlir::TupleType::get ( eleTy. getContext (),
218
+ mlir::TypeRange{ eleTy, eleTy} ),
166
219
AT{});
167
220
} else if (sem == &llvm::APFloat::IEEEquad ()) {
168
221
// Use a type that will be translated into LLVM as:
169
222
// { fp128, fp128 } struct of 2 fp128, sret, align 16
170
- mlir::TypeRange range = {eleTy, eleTy};
171
- marshal. emplace_back ( fir::ReferenceType::get (
172
- mlir::TupleType::get ( eleTy.getContext (), range )),
173
- AT{/* align=*/ 16 , /* byval=*/ false , /* sret=*/ true });
223
+ marshal. emplace_back (
224
+ fir::ReferenceType::get ( mlir::TupleType ::get (
225
+ eleTy.getContext (), mlir::TypeRange{eleTy, eleTy} )),
226
+ AT{/* align=*/ 16 , /* byval=*/ false , /* sret=*/ true });
174
227
} else {
175
228
TODO (loc, " complex for this precision" );
176
229
}
@@ -211,8 +264,8 @@ struct TargetAArch64 : public GenericTarget<TargetAArch64> {
211
264
sem == &llvm::APFloat::IEEEdouble ()) {
212
265
// Use a type that will be translated into LLVM as:
213
266
// { t, t } struct of 2 eleTy
214
- mlir::TypeRange range = { eleTy, eleTy};
215
- marshal. emplace_back ( mlir::TupleType::get ( eleTy. getContext (), range ),
267
+ marshal. emplace_back ( mlir::TupleType::get ( eleTy. getContext (),
268
+ mlir::TypeRange{ eleTy, eleTy} ),
216
269
AT{});
217
270
} else {
218
271
TODO (loc, " complex for this precision" );
@@ -246,8 +299,9 @@ struct TargetPPC64 : public GenericTarget<TargetPPC64> {
246
299
CodeGenSpecifics::Marshalling marshal;
247
300
// Use a type that will be translated into LLVM as:
248
301
// { t, t } struct of 2 element type
249
- mlir::TypeRange range = {eleTy, eleTy};
250
- marshal.emplace_back (mlir::TupleType::get (eleTy.getContext (), range), AT{});
302
+ marshal.emplace_back (
303
+ mlir::TupleType::get (eleTy.getContext (), mlir::TypeRange{eleTy, eleTy}),
304
+ AT{});
251
305
return marshal;
252
306
}
253
307
};
@@ -277,8 +331,9 @@ struct TargetPPC64le : public GenericTarget<TargetPPC64le> {
277
331
CodeGenSpecifics::Marshalling marshal;
278
332
// Use a type that will be translated into LLVM as:
279
333
// { t, t } struct of 2 element type
280
- mlir::TypeRange range = {eleTy, eleTy};
281
- marshal.emplace_back (mlir::TupleType::get (eleTy.getContext (), range), AT{});
334
+ marshal.emplace_back (
335
+ mlir::TupleType::get (eleTy.getContext (), mlir::TypeRange{eleTy, eleTy}),
336
+ AT{});
282
337
return marshal;
283
338
}
284
339
};
@@ -300,8 +355,8 @@ struct TargetSparc : public GenericTarget<TargetSparc> {
300
355
CodeGenSpecifics::Marshalling marshal;
301
356
// Use a type that will be translated into LLVM as:
302
357
// { t, t } struct of 2 eleTy
303
- mlir::TypeRange range = {eleTy, eleTy};
304
- auto structTy = mlir::TupleType::get (eleTy.getContext (), range );
358
+ auto structTy =
359
+ mlir::TupleType::get (eleTy.getContext (), mlir::TypeRange{eleTy, eleTy} );
305
360
marshal.emplace_back (fir::ReferenceType::get (structTy), AT{});
306
361
return marshal;
307
362
}
@@ -312,8 +367,8 @@ struct TargetSparc : public GenericTarget<TargetSparc> {
312
367
CodeGenSpecifics::Marshalling marshal;
313
368
// Use a type that will be translated into LLVM as:
314
369
// { t, t } struct of 2 eleTy, byval
315
- mlir::TypeRange range = {eleTy, eleTy};
316
- auto structTy = mlir::TupleType::get (eleTy.getContext (), range );
370
+ auto structTy =
371
+ mlir::TupleType::get (eleTy.getContext (), mlir::TypeRange{eleTy, eleTy} );
317
372
marshal.emplace_back (fir::ReferenceType::get (structTy),
318
373
AT{/* alignment=*/ 0 , /* byval=*/ true });
319
374
return marshal;
@@ -343,10 +398,10 @@ struct TargetSparcV9 : public GenericTarget<TargetSparcV9> {
343
398
} else if (sem == &llvm::APFloat::IEEEquad ()) {
344
399
// Use a type that will be translated into LLVM as:
345
400
// { fp128, fp128 } struct of 2 fp128, byval, align 16
346
- mlir::TypeRange range = {eleTy, eleTy};
347
- marshal. emplace_back ( fir::ReferenceType::get (
348
- mlir::TupleType::get ( eleTy.getContext (), range )),
349
- AT{/* align=*/ 16 , /* byval=*/ true });
401
+ marshal. emplace_back (
402
+ fir::ReferenceType::get ( mlir::TupleType ::get (
403
+ eleTy.getContext (), mlir::TypeRange{eleTy, eleTy} )),
404
+ AT{/* align=*/ 16 , /* byval=*/ true });
350
405
} else {
351
406
TODO (loc, " complex for this precision" );
352
407
}
@@ -358,8 +413,9 @@ struct TargetSparcV9 : public GenericTarget<TargetSparcV9> {
358
413
CodeGenSpecifics::Marshalling marshal;
359
414
// Use a type that will be translated into LLVM as:
360
415
// { eleTy, eleTy } struct of 2 eleTy
361
- mlir::TypeRange range = {eleTy, eleTy};
362
- marshal.emplace_back (mlir::TupleType::get (eleTy.getContext (), range), AT{});
416
+ marshal.emplace_back (
417
+ mlir::TupleType::get (eleTy.getContext (), mlir::TypeRange{eleTy, eleTy}),
418
+ AT{});
363
419
return marshal;
364
420
}
365
421
};
@@ -398,8 +454,8 @@ struct TargetRISCV64 : public GenericTarget<TargetRISCV64> {
398
454
sem == &llvm::APFloat::IEEEdouble ()) {
399
455
// Use a type that will be translated into LLVM as:
400
456
// { t, t } struct of 2 eleTy, byVal
401
- mlir::TypeRange range = { eleTy, eleTy};
402
- marshal. emplace_back ( mlir::TupleType::get ( eleTy. getContext (), range ),
457
+ marshal. emplace_back ( mlir::TupleType::get ( eleTy. getContext (),
458
+ mlir::TypeRange{ eleTy, eleTy} ),
403
459
AT{/* alignment=*/ 0 , /* byval=*/ true });
404
460
} else {
405
461
TODO (loc, " complex for this precision" );
0 commit comments