}]>;
def fir_NamedAllocateOpBuilder : OpBuilderDAG<(ins
- "Type":$inType,
- "StringRef":$name,
- CArg<"ValueRange", "{}">:$lenParams,
- CArg<"ValueRange", "{}">:$sizes,
- CArg<"ArrayRef<NamedAttribute>", "{}">:$attributes),
+ "mlir::Type":$inType,
+ "llvm::StringRef":$name,
+ CArg<"mlir::ValueRange", "{}">:$lenParams,
+ CArg<"mlir::ValueRange","{}">:$sizes,
+ CArg<"llvm::ArrayRef<mlir::NamedAttribute>", "{}">:$attributes),
[{
$_state.addTypes(getRefTy(inType));
$_state.addAttribute("in_type", TypeAttr::get(inType));
- $_state.addAttribute("name", $_builder.getStringAttr(name));
+ if (!name.empty())
+ $_state.addAttribute("name", $_builder.getStringAttr(name));
$_state.addOperands(sizes);
$_state.addAttributes(attributes);
}]>;
def fir_OneResultOpBuilder : OpBuilderDAG<(ins
- "Type":$resultType,
- "ValueRange":$operands,
- CArg<"ArrayRef<NamedAttribute>", "{}">:$attributes),
+ "mlir::Type":$resultType,
+ "mlir::ValueRange":$operands,
+ CArg<"llvm::ArrayRef<mlir::NamedAttribute>", "{}">:$attributes),
[{
if (resultType)
$_state.addTypes(resultType);
);
}
-class fir_AllocatableOp<string mnemonic, list<OpTrait> traits = []> :
+class fir_AllocatableOp<string mnemonic, Resource resource,
+ list<OpTrait> traits = []> :
fir_AllocatableBaseOp<mnemonic,
- !listconcat(traits, [MemoryEffects<[MemAlloc]>])>,
+ !listconcat(traits, [MemoryEffects<[MemAlloc<resource>]>])>,
fir_TwoBuilders<fir_AllocateOpBuilder, fir_NamedAllocateOpBuilder>,
Arguments<(ins TypeAttr:$in_type, Variadic<AnyIntegerType>:$args)> {
// Memory SSA operations
//===----------------------------------------------------------------------===//
-def fir_AllocaOp : fir_AllocatableOp<"alloca"> {
+def fir_AllocaOp :
+ fir_AllocatableOp<"alloca", AutomaticAllocationScopeResource> {
let summary = "allocate storage for a temporary on the stack given a type";
let description = [{
This primitive operation is used to allocate an object on the stack. A
mlir::Type outType = getType();
if (!outType.isa<fir::ReferenceType>())
return emitOpError("must be a !fir.ref type");
+ if (fir::isa_unknown_size_box(fir::dyn_cast_ptrEleTy(outType)))
+ return emitOpError("cannot allocate !fir.box of unknown rank or type");
return mlir::success();
}];
}];
}
-def fir_LoadOp : fir_OneResultOp<"load", [MemoryEffects<[MemRead]>]> {
+def fir_LoadOp : fir_OneResultOp<"load"> {
let summary = "load a value from a memory reference";
let description = [{
Load a value from a memory reference into an ssa-value (virtual register).
or null.
}];
- let arguments = (ins AnyReferenceLike:$memref);
+ let arguments = (ins Arg<AnyReferenceLike, "", [MemRead]>:$memref);
- let builders = [
- OpBuilderDAG<(ins "Value":$refVal),
+ let builders = [OpBuilderDAG<(ins "mlir::Value":$refVal),
[{
if (!refVal) {
mlir::emitError($_state.location, "LoadOp has null argument");
return;
}
- auto refTy = refVal.getType().cast<fir::ReferenceType>();
+ auto eleTy = fir::dyn_cast_ptrEleTy(refVal.getType());
+ if (!eleTy) {
+ mlir::emitError($_state.location, "not a memory reference type");
+ return;
+ }
$_state.addOperands(refVal);
- $_state.addTypes(refTy.getEleTy());
- }]>];
+ $_state.addTypes(eleTy);
+ }]
+ >];
let parser = [{
mlir::Type type;
}];
}
-def fir_StoreOp : fir_Op<"store", [MemoryEffects<[MemWrite]>]> {
+def fir_StoreOp : fir_Op<"store", []> {
let summary = "store an SSA-value to a memory location";
let description = [{
`%p`, is undefined or null.
}];
- let arguments = (ins AnyType:$value, AnyReferenceLike:$memref);
+ let arguments = (ins AnyType:$value,
+ Arg<AnyReferenceLike, "", [MemWrite]>:$memref);
let parser = [{
mlir::Type type;
let verifier = [{
if (value().getType() != fir::dyn_cast_ptrEleTy(memref().getType()))
return emitOpError("store value type must match memory reference type");
+ if (fir::isa_unknown_size_box(value().getType()))
+ return emitOpError("cannot store !fir.box of unknown rank or type");
return mlir::success();
}];
}];
}
-def fir_AllocMemOp : fir_AllocatableOp<"allocmem"> {
+def fir_ZeroOp : fir_OneResultOp<"zero_bits", [NoSideEffect]> {
+ let summary = "explicit polymorphic zero value of some type";
+ let description = [{
+ Constructs an ssa-value of the specified type with a value of zero for all
+ bits.
+
+ ```mlir
+ %a = fir.zero_bits !fir.box<!fir.array<10 x !fir.type<T>>>
+ ```
+
+ The example creates a value of type box where all bits are zero.
+ }];
+
+ let results = (outs AnyType:$intype);
+
+ let assemblyFormat = "type($intype) attr-dict";
+}
+
+def fir_AllocMemOp : fir_AllocatableOp<"allocmem", DefaultResource> {
let summary = "allocate storage on the heap for an object of a given type";
let description = [{
mlir::Type outType = getType();
if (!outType.dyn_cast<fir::HeapType>())
return emitOpError("must be a !fir.heap type");
+ if (fir::isa_unknown_size_box(fir::dyn_cast_ptrEleTy(outType)))
+ return emitOpError("cannot allocate !fir.box of unknown rank or type");
return mlir::success();
}];
```
}];
- let arguments = (ins fir_HeapType:$heapref);
+ let arguments = (ins Arg<fir_HeapType, "", [MemFree]>:$heapref);
let assemblyFormat = "$heapref attr-dict `:` type($heapref)";
}
list<OpTrait> traits = []> : fir_SwitchTerminatorOp<mnemonic, traits> {
let skipDefaultBuilders = 1;
- let builders = [
- OpBuilderDAG<(ins "Value":$selector, "ArrayRef<int64_t>":$compareOperands,
- "ArrayRef<Block *>":$destinations,
- CArg<"ArrayRef<ValueRange>", "{}">:$destOperands,
- CArg<"ArrayRef<NamedAttribute>", "{}">:$attributes),
+ let builders = [OpBuilderDAG<(ins "mlir::Value":$selector,
+ "llvm::ArrayRef<int64_t>":$compareOperands,
+ "llvm::ArrayRef<mlir::Block *>":$destinations,
+ CArg<"llvm::ArrayRef<mlir::ValueRange>", "{}">:$destOperands,
+ CArg<"llvm::ArrayRef<mlir::NamedAttribute>", "{}">:$attributes),
[{
$_state.addOperands(selector);
llvm::SmallVector<mlir::Attribute, 8> ivalues;
}
}
$_state.addAttribute(getOperandSegmentSizeAttr(),
- $_builder.getI32VectorAttr({1, 0, sumArgs}));
+ $_builder.getI32VectorAttr({1, 0, sumArgs}));
$_state.addAttribute(getTargetOffsetAttr(),
- $_builder.getI32VectorAttr(argOffs));
+ $_builder.getI32VectorAttr(argOffs));
$_state.addAttributes(attributes);
- }]>];
+ }]
+ >];
let parser = [{
mlir::OpAsmParser::OperandType selector;
let skipDefaultBuilders = 1;
let builders = [
- OpBuilderDAG<(ins "Value":$selector,
- "ArrayRef<mlir::Attribute>":$compareAttrs,
- "ArrayRef<ValueRange>":$cmpOperands, "ArrayRef<Block *>":$destinations,
- CArg<"ArrayRef<ValueRange>", "{}">:$destOperands,
- CArg<"ArrayRef<NamedAttribute>", "{}">:$attributes)>,
- OpBuilderDAG<(ins "Value":$selector,
- "ArrayRef<mlir::Attribute>":$compareAttrs, "ArrayRef<Value>":$cmpOpList,
- "ArrayRef<Block *>":$destinations,
- CArg<"ArrayRef<ValueRange>", "{}">:$destOperands,
- CArg<"ArrayRef<NamedAttribute>", "{}">:$attributes)>];
+ OpBuilderDAG<(ins "mlir::Value":$selector,
+ "llvm::ArrayRef<mlir::Attribute>":$compareAttrs,
+ "llvm::ArrayRef<mlir::ValueRange>":$cmpOperands,
+ "llvm::ArrayRef<mlir::Block *>":$destinations,
+ CArg<"llvm::ArrayRef<mlir::ValueRange>", "{}">:$destOperands,
+ CArg<"llvm::ArrayRef<mlir::NamedAttribute>", "{}">:$attributes)>,
+ OpBuilderDAG<(ins "mlir::Value":$selector,
+ "llvm::ArrayRef<mlir::Attribute>":$compareAttrs,
+ "llvm::ArrayRef<mlir::Value>":$cmpOpList,
+ "llvm::ArrayRef<mlir::Block *>":$destinations,
+ CArg<"llvm::ArrayRef<mlir::ValueRange>", "{}">:$destOperands,
+ CArg<"llvm::ArrayRef<mlir::NamedAttribute>", "{}">:$attributes)>];
let parser = "return parseSelectCase(parser, result);";
}];
let skipDefaultBuilders = 1;
- let builders = [
- OpBuilderDAG<(ins "Value":$selector,
- "ArrayRef<mlir::Attribute>":$typeOperands,
- "ArrayRef<Block *>":$destinations,
- CArg<"ArrayRef<ValueRange>", "{}">:$destOperands,
- CArg<"ArrayRef<NamedAttribute>", "{}">:$attributes),
+ let builders = [OpBuilderDAG<(ins "mlir::Value":$selector,
+ "llvm::ArrayRef<mlir::Attribute>":$typeOperands,
+ "llvm::ArrayRef<mlir::Block *>":$destinations,
+ CArg<"llvm::ArrayRef<mlir::ValueRange>", "{}">:$destOperands,
+ CArg<"llvm::ArrayRef<mlir::NamedAttribute>", "{}">:$attributes),
[{
$_state.addOperands(selector);
- $_state.addAttribute(getCasesAttr(), $_builder.getArrayAttr(typeOperands));
+ $_state.addAttribute(getCasesAttr(),
+ $_builder.getArrayAttr(typeOperands));
const auto count = destinations.size();
for (auto d : destinations)
$_state.addSuccessors(d);
}
}
$_state.addAttribute(getOperandSegmentSizeAttr(),
- $_builder.getI32VectorAttr({1, 0, sumArgs}));
+ $_builder.getI32VectorAttr({1, 0, sumArgs}));
$_state.addAttribute(getTargetOffsetAttr(),
- $_builder.getI32VectorAttr(argOffs));
+ $_builder.getI32VectorAttr(argOffs));
$_state.addAttributes(attributes);
- }]>];
+ }]
+ >];
let parser = "return parseSelectType(parser, result);";
```mlir
%40 = ... : !fir.box<!fir.type<T>>
- %41:6 = fir.unbox %40 : (!fir.box<!fir.type<T>>) -> (!fir.ref<!fir.type<T>>, i32, i32, !fir.tdesc<!fir.type<T>>, i32, !fir.dims<4>)
+ %41:6 = fir.unbox %40 : (!fir.box<!fir.type<T>>) -> (!fir.ref<!fir.type<T>>, i32, i32, !fir.tdesc<!fir.type<T>>, i32, !fir.array<? x index>)
```
}];
```mlir
%c1 = constant 0 : i32
- %52:3 = fir.box_dims %40, %c1 : (!fir.box<!fir.array<*:f64>>, i32) -> (i32, i32, i32)
+ %52:3 = fir.box_dims %40, %c1 : (!fir.box<!fir.array<*:f64>>, i32) -> (index, index, index)
```
The above is a request to return the left most row (at index 0) triple from
- the box. The triple will be the lower bound, upper bound, and stride.
+ the box. The triple will be the lower bound, extent, and byte-stride, which
+ are the values encoded in a standard descriptor.
}];
let arguments = (ins fir_BoxType:$val, AnyIntegerLike:$dim);
- let results = (outs AnyIntegerLike, AnyIntegerLike, AnyIntegerLike);
+ let results = (outs Index, Index, Index);
let assemblyFormat = [{
$val `,` $dim attr-dict `:` functional-type(operands, results)
let description = [{
Determine if the boxed value has a positive (> 0) rank. This will return
true if the originating box value was from a fir.embox with a memory
- reference value that had the type !fir.array<T> and/or a dims argument.
+ reference value that had the type !fir.array<T> and/or a shape argument.
```mlir
%r = ... : !fir.ref<i64>
- %d = fir.gendims(1, 100, 1) : (i32, i32, i32) -> !fir.dims<1>
- %b = fir.embox %r, %d : (!fir.ref<i64>, !fir.dims<1>) -> !fir.box<i64>
+ %c_100 = constant 100 : index
+ %d = fir.shape %c_100 : (index) -> !fir.shape<1>
+ %b = fir.embox %r(%d) : (!fir.ref<i64>, !fir.shape<1>) -> !fir.box<i64>
%a = fir.box_isarray %b : (!fir.box<i64>) -> i1 // true
```
}];