Skip to content

Commit 3d9653b

Browse files
committed
[flang] Add optional tdesc operand to fir.embox for polymorphic entities
In some cases, it is useful to be able to embox a polymorphic entity together with its dynamic type. This patch adds an optional tdesc operand to fir.embox so the dynamic type can be provided while emboxing the entity. This will be used in follow-up patch that lowers tbp calls for element of polymorphic entities array. Reviewed By: jeanPerier Differential Revision: https://reviews.llvm.org/D135809
1 parent 7d15212 commit 3d9653b

File tree

4 files changed

+70
-4
lines changed

4 files changed

+70
-4
lines changed

flang/include/flang/Optimizer/Dialect/FIROps.td

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,7 @@ def fir_EmboxOp : fir_Op<"embox", [NoMemoryEffect, AttrSizedOperandSegments]> {
758758
Optional<AnyShapeType>:$shape,
759759
Optional<fir_SliceType>:$slice,
760760
Variadic<AnyIntegerType>:$typeparams,
761+
Optional<fir_TypeDescType>:$tdesc,
761762
OptionalAttr<AffineMapAttr>:$accessMap
762763
);
763764

@@ -767,14 +768,16 @@ def fir_EmboxOp : fir_Op<"embox", [NoMemoryEffect, AttrSizedOperandSegments]> {
767768
OpBuilder<(ins "llvm::ArrayRef<mlir::Type>":$resultTypes,
768769
"mlir::Value":$memref, CArg<"mlir::Value", "{}">:$shape,
769770
CArg<"mlir::Value", "{}">:$slice,
770-
CArg<"mlir::ValueRange", "{}">:$typeparams),
771+
CArg<"mlir::ValueRange", "{}">:$typeparams,
772+
CArg<"mlir::Value", "{}">:$tdesc),
771773
[{ return build($_builder, $_state, resultTypes, memref, shape, slice,
772-
typeparams, mlir::AffineMapAttr{}); }]>
774+
typeparams, tdesc, mlir::AffineMapAttr{}); }]>
773775
];
774776

775777
let assemblyFormat = [{
776778
$memref (`(` $shape^ `)`)? (`[` $slice^ `]`)? (`typeparams` $typeparams^)?
777-
(`map` $accessMap^)? attr-dict `:` functional-type(operands, results)
779+
(`tdesc` $tdesc^)? (`map` $accessMap^)? attr-dict `:`
780+
functional-type(operands, results)
778781
}];
779782

780783
let hasVerifier = 1;
@@ -1160,7 +1163,7 @@ def fir_BoxTypeDescOp : fir_SimpleOneResultOp<"box_tdesc", [NoMemoryEffect]> {
11601163
```
11611164
}];
11621165

1163-
let arguments = (ins fir_BoxType:$val);
1166+
let arguments = (ins BoxOrClassType:$val);
11641167

11651168
let results = (outs fir_TypeDescType);
11661169
}

flang/lib/Optimizer/Dialect/FIROps.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,6 +1145,8 @@ mlir::LogicalResult fir::EmboxOp::verify() {
11451145
return emitOpError("shape must not be provided for a scalar");
11461146
if (getSlice() && !isArray)
11471147
return emitOpError("slice must not be provided for a scalar");
1148+
if (getTdesc() && !getResult().getType().isa<fir::ClassType>())
1149+
return emitOpError("tdesc must be used with fir.class result type");
11481150
return mlir::success();
11491151
}
11501152

flang/test/Fir/fir-ops.fir

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -819,3 +819,34 @@ func.func private @dispatch(%arg0: !fir.class<!fir.type<dispatch_derived1{a:i32,
819819
// CHECK: fir.dispatch "proc3"(%[[CLASS]] : !fir.class<!fir.type<dispatch_derived1{a:i32,b:i32}>>) (%[[INTARG]], %[[CLASS]] : i32, !fir.class<!fir.type<dispatch_derived1{a:i32,b:i32}>>) {pass_arg_pos = 1 : i32}
820820
return
821821
}
822+
823+
824+
// CHECK-LABEL: func.func @embox_tdesc
825+
func.func @embox_tdesc(%arg0: !fir.class<!fir.array<10x!fir.type<derived_poly{a:i32,b:i32}>>>) {
826+
%0 = fir.alloca i32
827+
%c1_i32 = arith.constant 1 : i32
828+
%1 = fir.convert %c1_i32 : (i32) -> index
829+
%c10_i32 = arith.constant 10 : i32
830+
%2 = fir.convert %c10_i32 : (i32) -> index
831+
%c1 = arith.constant 1 : index
832+
%3 = fir.convert %1 : (index) -> i32
833+
%4:2 = fir.do_loop %arg2 = %1 to %2 step %c1 iter_args(%arg3 = %3) -> (index, i32) {
834+
fir.store %arg3 to %0 : !fir.ref<i32>
835+
%9 = fir.load %0 : !fir.ref<i32>
836+
%10 = fir.convert %9 : (i32) -> i64
837+
%c1_i64 = arith.constant 1 : i64
838+
%11 = arith.subi %10, %c1_i64 : i64
839+
%12 = fir.coordinate_of %arg0, %11 : (!fir.class<!fir.array<10x!fir.type<derived_poly{a:i32,b:i32}>>>, i64) -> !fir.ref<!fir.type<derived_poly{a:i32,b:i32}>>
840+
%tdesc = fir.box_tdesc %arg0 : (!fir.class<!fir.array<10x!fir.type<derived_poly{a:i32,b:i32}>>>) -> (!fir.tdesc<!fir.type<derived_poly{a:i32,b:i32}>>)
841+
// CHECK: %[[TDESC:.*]] = fir.box_tdesc %{{.*}} : (!fir.class<!fir.array<10x!fir.type<derived_poly{a:i32,b:i32}>>>) -> !fir.tdesc<!fir.type<derived_poly{a:i32,b:i32}>>
842+
%13 = fir.embox %12 tdesc %tdesc : (!fir.ref<!fir.type<derived_poly{a:i32,b:i32}>>, !fir.tdesc<!fir.type<derived_poly{a:i32,b:i32}>>) -> !fir.class<!fir.type<derived_poly{a:i32,b:i32}>>
843+
// CHECK: %{{.*}} = fir.embox %{{.*}} tdesc %[[TDESC]] : (!fir.ref<!fir.type<derived_poly{a:i32,b:i32}>>, !fir.tdesc<!fir.type<derived_poly{a:i32,b:i32}>>) -> !fir.class<!fir.type<derived_poly{a:i32,b:i32}>>
844+
%14 = arith.addi %arg2, %c1 : index
845+
%15 = fir.convert %c1 : (index) -> i32
846+
%16 = fir.load %0 : !fir.ref<i32>
847+
%17 = arith.addi %16, %15 : i32
848+
fir.result %14, %17 : index, i32
849+
}
850+
fir.store %4#1 to %0 : !fir.ref<i32>
851+
return
852+
}

flang/test/Fir/invalid.fir

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,36 @@ func.func @fun(%0 : !fir.ref<i32>) {
345345

346346
// -----
347347

348+
func.func @embox_tdesc(%arg0: !fir.class<!fir.array<10x!fir.type<derived{a:i32,b:i32}>>>) {
349+
%0 = fir.alloca i32
350+
%c1_i32 = arith.constant 1 : i32
351+
%1 = fir.convert %c1_i32 : (i32) -> index
352+
%c10_i32 = arith.constant 10 : i32
353+
%2 = fir.convert %c10_i32 : (i32) -> index
354+
%c1 = arith.constant 1 : index
355+
%3 = fir.convert %1 : (index) -> i32
356+
%4:2 = fir.do_loop %arg2 = %1 to %2 step %c1 iter_args(%arg3 = %3) -> (index, i32) {
357+
fir.store %arg3 to %0 : !fir.ref<i32>
358+
%9 = fir.load %0 : !fir.ref<i32>
359+
%10 = fir.convert %9 : (i32) -> i64
360+
%c1_i64 = arith.constant 1 : i64
361+
%11 = arith.subi %10, %c1_i64 : i64
362+
%12 = fir.coordinate_of %arg0, %11 : (!fir.class<!fir.array<10x!fir.type<derived{a:i32,b:i32}>>>, i64) -> !fir.ref<!fir.type<derived{a:i32,b:i32}>>
363+
%tdesc = fir.box_tdesc %arg0 : (!fir.class<!fir.array<10x!fir.type<derived{a:i32,b:i32}>>>) -> (!fir.tdesc<!fir.type<derived{a:i32,b:i32}>>)
364+
// expected-error@+1 {{'fir.embox' op tdesc must be used with fir.class result type}}
365+
%13 = fir.embox %12 tdesc %tdesc : (!fir.ref<!fir.type<derived{a:i32,b:i32}>>, !fir.tdesc<!fir.type<derived{a:i32,b:i32}>>) -> !fir.box<!fir.type<derived{a:i32,b:i32}>>
366+
%14 = arith.addi %arg2, %c1 : index
367+
%15 = fir.convert %c1 : (index) -> i32
368+
%16 = fir.load %0 : !fir.ref<i32>
369+
%17 = arith.addi %16, %15 : i32
370+
fir.result %14, %17 : index, i32
371+
}
372+
fir.store %4#1 to %0 : !fir.ref<i32>
373+
return
374+
}
375+
376+
// -----
377+
348378
%lo = arith.constant 1 : index
349379
%c1 = arith.constant 1 : index
350380
%up = arith.constant 10 : index

0 commit comments

Comments
 (0)