Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[flang][hlfir] Add hlfir.parent_comp for leaf parent component refere…
…nces In Fortran, it is possible to refer to the "parent part" of a derived type as if it were a component: ```Fortran type t1 integer :: i end type type t2 integer :: j end type type(t2) :: a print *, a%t1%i ! "inner" parent component reference print *, a%t1 ! "leaf" parent component reference end ``` Inner parent component references can be dropped on the floor in lowering: "a%t1%i" is equivalent to "a%i". Leaf parent component references, however, must be taken care of. For scalars, "a%t1" is a simple addressc ast to "t1", for arrays, however, this creates an array section that must be represented with a descriptor (fir.box). hlfir.designate could have been extended to deal with this, but I think it would make hlfir.designate too complex and hard to manipulate. This patch adds an hlfir.parent_comp op that represents and implements leaf parent component references. Differential Revision: https://reviews.llvm.org/D144946
- Loading branch information
1 parent
91ee72d
commit 131c917
Showing
6 changed files
with
284 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// Test hlfir.parent_comp code generation to FIR | ||
// RUN: fir-opt %s -convert-hlfir-to-fir | FileCheck %s | ||
|
||
func.func @test_scalar(%arg0: !fir.ref<!fir.type<t2{i:i32,j:i32}>>) { | ||
%1 = hlfir.parent_comp %arg0 : (!fir.ref<!fir.type<t2{i:i32,j:i32}>>) -> !fir.ref<!fir.type<t1{i:i32}>> | ||
return | ||
} | ||
// CHECK-LABEL: func.func @test_scalar( | ||
// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.type<t2{i:i32,j:i32}>>) { | ||
// CHECK: fir.convert %[[VAL_0]] : (!fir.ref<!fir.type<t2{i:i32,j:i32}>>) -> !fir.ref<!fir.type<t1{i:i32}>> | ||
|
||
func.func @test_scalar_polymorphic(%arg0: !fir.class<!fir.type<t2{i:i32,j:i32}>>) { | ||
%1 = hlfir.parent_comp %arg0 : (!fir.class<!fir.type<t2{i:i32,j:i32}>>) -> !fir.ref<!fir.type<t1{i:i32}>> | ||
return | ||
} | ||
// CHECK-LABEL: func.func @test_scalar_polymorphic( | ||
// CHECK-SAME: %[[VAL_0:.*]]: !fir.class<!fir.type<t2{i:i32,j:i32}>>) { | ||
// CHECK: %[[VAL_1:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class<!fir.type<t2{i:i32,j:i32}>>) -> !fir.ref<!fir.type<t2{i:i32,j:i32}>> | ||
// CHECK: fir.convert %[[VAL_1]] : (!fir.ref<!fir.type<t2{i:i32,j:i32}>>) -> !fir.ref<!fir.type<t1{i:i32}>> | ||
|
||
func.func @test_array(%arg0: !fir.ref<!fir.array<10x!fir.type<t2{i:i32,j:i32}>>>) { | ||
%c10 = arith.constant 10 : index | ||
%1 = fir.shape %c10 : (index) -> !fir.shape<1> | ||
%2 = hlfir.parent_comp %arg0 shape %1 : (!fir.ref<!fir.array<10x!fir.type<t2{i:i32,j:i32}>>>, !fir.shape<1>) -> !fir.box<!fir.array<10x!fir.type<t1{i:i32}>>> | ||
return | ||
} | ||
// CHECK-LABEL: func.func @test_array( | ||
// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<10x!fir.type<t2{i:i32,j:i32}>>>) { | ||
// CHECK: %[[VAL_1:.*]] = arith.constant 10 : index | ||
// CHECK: %[[VAL_2:.*]] = fir.shape %[[VAL_1]] : (index) -> !fir.shape<1> | ||
// CHECK: %[[VAL_3:.*]] = fir.embox %[[VAL_0]](%[[VAL_2]]) : (!fir.ref<!fir.array<10x!fir.type<t2{i:i32,j:i32}>>>, !fir.shape<1>) -> !fir.box<!fir.array<10x!fir.type<t2{i:i32,j:i32}>>> | ||
// CHECK: fir.rebox %[[VAL_3]] : (!fir.box<!fir.array<10x!fir.type<t2{i:i32,j:i32}>>>) -> !fir.box<!fir.array<10x!fir.type<t1{i:i32}>>> | ||
|
||
func.func @test_array_polymorphic(%arg0: !fir.class<!fir.array<10x!fir.type<t2{i:i32,j:i32}>>>) { | ||
%c10 = arith.constant 10 : index | ||
%1 = fir.shape %c10 : (index) -> !fir.shape<1> | ||
%2 = hlfir.parent_comp %arg0 shape %1 : (!fir.class<!fir.array<10x!fir.type<t2{i:i32,j:i32}>>>, !fir.shape<1>) -> !fir.box<!fir.array<10x!fir.type<t1{i:i32}>>> | ||
return | ||
} | ||
// CHECK-LABEL: func.func @test_array_polymorphic( | ||
// CHECK-SAME: %[[VAL_0:.*]]: !fir.class<!fir.array<10x!fir.type<t2{i:i32,j:i32}>>>) { | ||
// CHECK: %[[VAL_1:.*]] = arith.constant 10 : index | ||
// CHECK: %[[VAL_2:.*]] = fir.shape %[[VAL_1]] : (index) -> !fir.shape<1> | ||
// CHECK: fir.rebox %[[VAL_0]] : (!fir.class<!fir.array<10x!fir.type<t2{i:i32,j:i32}>>>) -> !fir.box<!fir.array<10x!fir.type<t1{i:i32}>>> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// Test hlfir.parent_comp operation parse, verify (no errors), and unparse. | ||
// RUN: fir-opt %s | fir-opt | FileCheck %s | ||
|
||
func.func @test_scalar(%arg0: !fir.ref<!fir.type<t2{i:i32,j:i32}>>) { | ||
%1 = hlfir.parent_comp %arg0 : (!fir.ref<!fir.type<t2{i:i32,j:i32}>>) -> !fir.ref<!fir.type<t1{i:i32}>> | ||
return | ||
} | ||
// CHECK-LABEL: func.func @test_scalar( | ||
// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.type<t2{i:i32,j:i32}>>) { | ||
// CHECK: hlfir.parent_comp %[[VAL_0]] : (!fir.ref<!fir.type<t2{i:i32,j:i32}>>) -> !fir.ref<!fir.type<t1{i:i32}>> | ||
|
||
func.func @test_scalar_polymorphic(%arg0: !fir.class<!fir.type<t2{i:i32,j:i32}>>) { | ||
%1 = hlfir.parent_comp %arg0 : (!fir.class<!fir.type<t2{i:i32,j:i32}>>) -> !fir.ref<!fir.type<t1{i:i32}>> | ||
return | ||
} | ||
// CHECK-LABEL: func.func @test_scalar_polymorphic( | ||
// CHECK-SAME: %[[VAL_0:.*]]: !fir.class<!fir.type<t2{i:i32,j:i32}>>) { | ||
// CHECK: hlfir.parent_comp %[[VAL_0]] : (!fir.class<!fir.type<t2{i:i32,j:i32}>>) -> !fir.ref<!fir.type<t1{i:i32}>> | ||
|
||
func.func @test_array(%arg0: !fir.ref<!fir.array<10x!fir.type<t2{i:i32,j:i32}>>>) { | ||
%c10 = arith.constant 10 : index | ||
%1 = fir.shape %c10 : (index) -> !fir.shape<1> | ||
%2 = hlfir.parent_comp %arg0 shape %1 : (!fir.ref<!fir.array<10x!fir.type<t2{i:i32,j:i32}>>>, !fir.shape<1>) -> !fir.box<!fir.array<10x!fir.type<t1{i:i32}>>> | ||
return | ||
} | ||
// CHECK-LABEL: func.func @test_array( | ||
// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<10x!fir.type<t2{i:i32,j:i32}>>>) { | ||
// CHECK: %[[VAL_1:.*]] = arith.constant 10 : index | ||
// CHECK: %[[VAL_2:.*]] = fir.shape %[[VAL_1]] : (index) -> !fir.shape<1> | ||
// CHECK: hlfir.parent_comp %[[VAL_0]] shape %[[VAL_2]] : (!fir.ref<!fir.array<10x!fir.type<t2{i:i32,j:i32}>>>, !fir.shape<1>) -> !fir.box<!fir.array<10x!fir.type<t1{i:i32}>>> | ||
|
||
func.func @test_array_polymorphic(%arg0: !fir.class<!fir.array<10x!fir.type<t2{i:i32,j:i32}>>>) { | ||
%c10 = arith.constant 10 : index | ||
%1 = fir.shape %c10 : (index) -> !fir.shape<1> | ||
%2 = hlfir.parent_comp %arg0 shape %1 : (!fir.class<!fir.array<10x!fir.type<t2{i:i32,j:i32}>>>, !fir.shape<1>) -> !fir.box<!fir.array<10x!fir.type<t1{i:i32}>>> | ||
return | ||
} | ||
// CHECK-LABEL: func.func @test_array_polymorphic( | ||
// CHECK-SAME: %[[VAL_0:.*]]: !fir.class<!fir.array<10x!fir.type<t2{i:i32,j:i32}>>>) { | ||
// CHECK: %[[VAL_1:.*]] = arith.constant 10 : index | ||
// CHECK: %[[VAL_2:.*]] = fir.shape %[[VAL_1]] : (index) -> !fir.shape<1> | ||
// CHECK: hlfir.parent_comp %[[VAL_0]] shape %[[VAL_2]] : (!fir.class<!fir.array<10x!fir.type<t2{i:i32,j:i32}>>>, !fir.shape<1>) -> !fir.box<!fir.array<10x!fir.type<t1{i:i32}>>> |