11
11
///
12
12
//===----------------------------------------------------------------------===//
13
13
14
- #ifndef FIR_DIALECT_FIR_OPS
15
- #define FIR_DIALECT_FIR_OPS
14
+ #ifndef FORTRAN_DIALECT_FIR_OPS
15
+ #define FORTRAN_DIALECT_FIR_OPS
16
16
17
17
include "mlir/IR/SymbolInterfaces.td"
18
+ include "mlir/Interfaces/CallInterfaces.td"
18
19
include "mlir/Interfaces/ControlFlowInterfaces.td"
19
20
include "mlir/Interfaces/LoopLikeInterface.td"
20
21
include "mlir/Interfaces/SideEffectInterfaces.td"
@@ -144,20 +145,23 @@ class fir_SimpleOp<string mnemonic, list<OpTrait> traits>
144
145
}
145
146
146
147
// Base builder for allocate operations
147
- def fir_AllocateOpBuilder :
148
- OpBuilderDAG<(ins "Type":$inType, CArg<"ValueRange", "{}">:$lenParams,
149
- CArg<"ValueRange", "{}">:$sizes,
150
- CArg<"ArrayRef<NamedAttribute>", "{}">:$attributes),
148
+ def fir_AllocateOpBuilder : OpBuilderDAG<(ins
149
+ "mlir::Type":$inType,
150
+ CArg<"mlir::ValueRange", "{}">:$lenParams,
151
+ CArg<"mlir::ValueRange", "{}">:$sizes,
152
+ CArg<"llvm::ArrayRef<mlir::NamedAttribute>", "{}">:$attributes),
151
153
[{
152
154
$_state.addTypes(getRefTy(inType));
153
155
$_state.addAttribute("in_type", TypeAttr::get(inType));
154
156
$_state.addOperands(sizes);
155
157
$_state.addAttributes(attributes);
156
158
}]>;
157
159
158
- def fir_NamedAllocateOpBuilder :
159
- OpBuilderDAG<(ins "Type":$inType, "StringRef":$name,
160
- CArg<"ValueRange", "{}">:$lenParams, CArg<"ValueRange", "{}">:$sizes,
160
+ def fir_NamedAllocateOpBuilder : OpBuilderDAG<(ins
161
+ "Type":$inType,
162
+ "StringRef":$name,
163
+ CArg<"ValueRange", "{}">:$lenParams,
164
+ CArg<"ValueRange", "{}">:$sizes,
161
165
CArg<"ArrayRef<NamedAttribute>", "{}">:$attributes),
162
166
[{
163
167
$_state.addTypes(getRefTy(inType));
@@ -167,8 +171,9 @@ def fir_NamedAllocateOpBuilder :
167
171
$_state.addAttributes(attributes);
168
172
}]>;
169
173
170
- def fir_OneResultOpBuilder :
171
- OpBuilderDAG<(ins "Type":$resultType, "ValueRange":$operands,
174
+ def fir_OneResultOpBuilder : OpBuilderDAG<(ins
175
+ "Type":$resultType,
176
+ "ValueRange":$operands,
172
177
CArg<"ArrayRef<NamedAttribute>", "{}">:$attributes),
173
178
[{
174
179
if (resultType)
@@ -340,6 +345,39 @@ def fir_AllocaOp : fir_AllocatableOp<"alloca"> {
340
345
(`len1`, `len2`) to the type `PT`.
341
346
342
347
Finally, the operation is undefined if the ssa-value `%c` is negative.
348
+
349
+ Fortran Semantics:
350
+ There is no language mechanism in Fortran to allocate space on the stack
351
+ like C's `alloca()` function. Therefore fir.alloca is not control-flow
352
+ dependent. However, the lifetime of a stack allocation is often limited to
353
+ a small region and a legal implementation may reuse stack storage in other
354
+ regions when there is no conflict. For example, take the following code
355
+ fragment.
356
+
357
+ ```fortran
358
+ CALL foo(1)
359
+ CALL foo(2)
360
+ CALL foo(3)
361
+ ```
362
+
363
+ A legal implementation can allocate a stack slot and initialize it with the
364
+ constant `1`, then pass that by reference to foo. Likewise for the second
365
+ and third calls to foo, each stack slot being initialized accordingly. It is
366
+ also a conforming implementation to reuse the same stack slot for all three
367
+ calls, just initializing each in turn. This is possible as the lifetime of
368
+ the copy of each constant need not exceed that of the CALL statement.
369
+ Indeed, a user would likely expect a good Fortran compiler to perform such
370
+ an optimization.
371
+
372
+ Until Fortran 2018, procedures defaulted to non-recursive. A legal
373
+ implementation could therefore convert stack allocations to global
374
+ allocations. Such a conversion effectively adds the SAVE attribute to all
375
+ variables.
376
+
377
+ Some temporary entities (large arrays) probably should not be stack
378
+ allocated as stack space can often be limited. A legal implementation can
379
+ convert these large stack allocations to heap allocations regardless of
380
+ whether the procedure is recursive or not.
343
381
}];
344
382
345
383
let results = (outs fir_ReferenceType);
0 commit comments