Skip to content

Commit 49ee563

Browse files
committed
[flang] Add fir.box_typecode operation
`fir.box_typecode` operation allows to retrieve the type code from a boxed value. This will be used in the `fir.select_type` conversion to if-then-else ladder for type guard statement with intrinsic type spec instead of using a runtime call. Reviewed By: jeanPerier Differential Revision: https://reviews.llvm.org/D137829
1 parent f677c5e commit 49ee563

File tree

4 files changed

+73
-18
lines changed

4 files changed

+73
-18
lines changed

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,23 @@ def fir_BoxEleSizeOp : fir_SimpleOneResultOp<"box_elesize", [NoMemoryEffect]> {
10531053
let results = (outs AnyIntegerLike);
10541054
}
10551055

1056+
def fir_BoxTypeCodeOp : fir_SimpleOneResultOp<"box_typecode", [NoMemoryEffect]>
1057+
{
1058+
let summary = "return the type code the boxed value";
1059+
1060+
let description = [{
1061+
Returns the descriptor type code of an entity of `box` type.
1062+
1063+
```mlir
1064+
%1 = fir.box_type %0 : (!fir.box<T>) -> i32
1065+
```
1066+
}];
1067+
1068+
let arguments = (ins BoxOrClassType:$box);
1069+
1070+
let results = (outs AnyIntegerLike);
1071+
}
1072+
10561073
def fir_BoxIsAllocOp : fir_SimpleOp<"box_isalloc", [NoMemoryEffect]> {
10571074
let summary = "is the boxed value an ALLOCATABLE?";
10581075

flang/lib/Optimizer/CodeGen/CodeGen.cpp

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,23 @@ struct BoxTypeDescOpConversion : public FIROpConversion<fir::BoxTypeDescOp> {
650650
}
651651
};
652652

653+
/// Lower `fir.box_typecode` to a sequence of operations to extract the type
654+
/// code in the boxed value.
655+
struct BoxTypeCodeOpConversion : public FIROpConversion<fir::BoxTypeCodeOp> {
656+
using FIROpConversion::FIROpConversion;
657+
658+
mlir::LogicalResult
659+
matchAndRewrite(fir::BoxTypeCodeOp op, OpAdaptor adaptor,
660+
mlir::ConversionPatternRewriter &rewriter) const override {
661+
mlir::Value box = adaptor.getOperands()[0];
662+
auto loc = box.getLoc();
663+
auto ty = convertType(op.getType());
664+
auto typeCode = getValueFromBox(loc, box, ty, rewriter, kTypePosInBox);
665+
rewriter.replaceOp(op, typeCode);
666+
return mlir::success();
667+
}
668+
};
669+
653670
/// Lower `fir.string_lit` to LLVM IR dialect operation.
654671
struct StringLitOpConversion : public FIROpConversion<fir::StringLitOp> {
655672
using FIROpConversion::FIROpConversion;
@@ -3584,24 +3601,24 @@ class FIRToLLVMLowering
35843601
AllocaOpConversion, AllocMemOpConversion, BoxAddrOpConversion,
35853602
BoxCharLenOpConversion, BoxDimsOpConversion, BoxEleSizeOpConversion,
35863603
BoxIsAllocOpConversion, BoxIsArrayOpConversion, BoxIsPtrOpConversion,
3587-
BoxProcHostOpConversion, BoxRankOpConversion, BoxTypeDescOpConversion,
3588-
CallOpConversion, CmpcOpConversion, ConstcOpConversion,
3589-
ConvertOpConversion, CoordinateOpConversion, DispatchOpConversion,
3590-
DispatchTableOpConversion, DTEntryOpConversion, DivcOpConversion,
3591-
EmboxOpConversion, EmboxCharOpConversion, EmboxProcOpConversion,
3592-
ExtractValueOpConversion, FieldIndexOpConversion, FirEndOpConversion,
3593-
FreeMemOpConversion, GenTypeDescOpConversion, GlobalLenOpConversion,
3594-
GlobalOpConversion, HasValueOpConversion, InsertOnRangeOpConversion,
3595-
InsertValueOpConversion, IsPresentOpConversion,
3596-
LenParamIndexOpConversion, LoadOpConversion, MulcOpConversion,
3597-
NegcOpConversion, NoReassocOpConversion, SelectCaseOpConversion,
3598-
SelectOpConversion, SelectRankOpConversion, SelectTypeOpConversion,
3599-
ShapeOpConversion, ShapeShiftOpConversion, ShiftOpConversion,
3600-
SliceOpConversion, StoreOpConversion, StringLitOpConversion,
3601-
SubcOpConversion, UnboxCharOpConversion, UnboxProcOpConversion,
3602-
UndefOpConversion, UnreachableOpConversion, XArrayCoorOpConversion,
3603-
XEmboxOpConversion, XReboxOpConversion, ZeroOpConversion>(
3604-
typeConverter, options, bindingTables);
3604+
BoxProcHostOpConversion, BoxRankOpConversion, BoxTypeCodeOpConversion,
3605+
BoxTypeDescOpConversion, CallOpConversion, CmpcOpConversion,
3606+
ConstcOpConversion, ConvertOpConversion, CoordinateOpConversion,
3607+
DispatchOpConversion, DispatchTableOpConversion, DTEntryOpConversion,
3608+
DivcOpConversion, EmboxOpConversion, EmboxCharOpConversion,
3609+
EmboxProcOpConversion, ExtractValueOpConversion, FieldIndexOpConversion,
3610+
FirEndOpConversion, FreeMemOpConversion, GenTypeDescOpConversion,
3611+
GlobalLenOpConversion, GlobalOpConversion, HasValueOpConversion,
3612+
InsertOnRangeOpConversion, InsertValueOpConversion,
3613+
IsPresentOpConversion, LenParamIndexOpConversion, LoadOpConversion,
3614+
MulcOpConversion, NegcOpConversion, NoReassocOpConversion,
3615+
SelectCaseOpConversion, SelectOpConversion, SelectRankOpConversion,
3616+
SelectTypeOpConversion, ShapeOpConversion, ShapeShiftOpConversion,
3617+
ShiftOpConversion, SliceOpConversion, StoreOpConversion,
3618+
StringLitOpConversion, SubcOpConversion, UnboxCharOpConversion,
3619+
UnboxProcOpConversion, UndefOpConversion, UnreachableOpConversion,
3620+
XArrayCoorOpConversion, XEmboxOpConversion, XReboxOpConversion,
3621+
ZeroOpConversion>(typeConverter, options, bindingTables);
36053622
mlir::populateFuncToLLVMConversionPatterns(typeConverter, pattern);
36063623
mlir::populateOpenMPToLLVMConversionPatterns(typeConverter, pattern);
36073624
mlir::arith::populateArithToLLVMConversionPatterns(typeConverter, pattern);

flang/test/Fir/box-typecode.fir

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: tco %s | FileCheck %s
2+
3+
func.func @test_box_typecode(%a: !fir.class<none>) -> i32 {
4+
%0 = fir.box_typecode %a : (!fir.class<none>) -> i32
5+
return %0 : i32
6+
}
7+
8+
// CHECK-LABEL: @test_box_typecode(
9+
// CHECK-SAME: ptr %[[BOX:.*]])
10+
// CHECK: %[[GEP:.*]] = getelementptr { ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}} }, ptr %[[BOX]], i32 0, i32 4
11+
// CHECK: %[[TYPE_CODE:.*]] = load i32, ptr %[[GEP]]
12+
// CHECK: ret i32 %[[TYPE_CODE]]

flang/test/Fir/fir-ops.fir

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -882,3 +882,12 @@ func.func @test_fortran_var_attrs() {
882882
// CHECK: fir.alloca f32 {fortran_attrs = #fir.var_attrs<volatile>}
883883
// CHECK: fir.alloca !fir.box<!fir.ptr<!fir.array<?xf32>>> {fortran_attrs = #fir.var_attrs<contiguous, pointer, volatile>}
884884
}
885+
886+
func.func @test_box_typecode(%a: !fir.class<none>) {
887+
%0 = fir.box_typecode %a : (!fir.class<none>) -> i32
888+
return
889+
}
890+
891+
// CHECK-LABEL: func.func @test_box_typecode(
892+
// CHECK-SAME: %[[A:.*]]: !fir.class<none>)
893+
// CHECK: %{{.*}} = fir.box_typecode %[[A]] : (!fir.class<none>) -> i32

0 commit comments

Comments
 (0)