Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[flang] split character procedure arguments in target-rewrite pass
When passing a character procedure as a dummy procedure, the result length must be passed along the function address. This is to cover the cases where the dummy procedure is declared with assumed length inside the scope that will call it (it will need the length to allocate the result on the caller side). To be compatible with other Fortran compiler, this length must be appended after all other argument just like character objects (fir.boxchar). A fir.boxchar cannot be used to implement this feature because it is meant to take an object address, not a function address. Instead, argument like `tuple<function type, integer type> {fir.char_proc}` will be recognized as being character dummy procedure in FIR. That way lowering does not have to do the argument split. This patch adds tools in Character.h to create this type and tuple values as well as to recognize them and extract its tuple members. It also updates the target rewrite pass to split these arguments like fir.boxchar. This part is part of fir-dev upstreaming. It was reviwed previously in: flang-compiler#1393 Differential Revision: https://reviews.llvm.org/D118108
- Loading branch information
1 parent
f482e86
commit 416e503
Showing
6 changed files
with
234 additions
and
2 deletions.
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
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,69 @@ | ||
// Test rewrite of character procedure pointer tuple argument to two different | ||
// arguments: one for the function address, and one for the length. The length | ||
// argument is added after other characters. | ||
// RUN: fir-opt --target-rewrite="target=x86_64-unknown-linux-gnu" %s | FileCheck %s | ||
|
||
// CHECK: func private @takes_char_proc(() -> () {fir.char_proc}, i64) | ||
func private @takes_char_proc(tuple<() -> (), i64> {fir.char_proc}) | ||
|
||
func private @takes_char(!fir.boxchar<1>) | ||
func private @char_proc(!fir.ref<!fir.char<1,7>>, index) -> !fir.boxchar<1> | ||
|
||
func @_QPcst_len() { | ||
%0 = fir.address_of(@char_proc) : (!fir.ref<!fir.char<1,7>>, index) -> !fir.boxchar<1> | ||
%c7_i64 = arith.constant 7 : i64 | ||
%1 = fir.convert %0 : ((!fir.ref<!fir.char<1,7>>, index) -> !fir.boxchar<1>) -> (() -> ()) | ||
%2 = fir.undefined tuple<() -> (), i64> | ||
%3 = fir.insert_value %2, %1, [0 : index] : (tuple<() -> (), i64>, () -> ()) -> tuple<() -> (), i64> | ||
%4 = fir.insert_value %3, %c7_i64, [1 : index] : (tuple<() -> (), i64>, i64) -> tuple<() -> (), i64> | ||
|
||
// CHECK: %[[PROC_ADDR:.*]] = fir.extract_value %{{.*}}, [0 : index] : (tuple<() -> (), i64>) -> (() -> ()) | ||
// CHECK: %[[LEN:.*]] = fir.extract_value %{{.*}}, [1 : index] : (tuple<() -> (), i64>) -> i64 | ||
// CHECK: fir.call @takes_char_proc(%[[PROC_ADDR]], %[[LEN]]) : (() -> (), i64) -> () | ||
fir.call @takes_char_proc(%4) : (tuple<() -> (), i64>) -> () | ||
return | ||
} | ||
|
||
// CHECK: func @test_dummy_proc_that_takes_dummy_char_proc( | ||
// CHECK-SAME: %[[ARG0:.*]]: () -> ()) { | ||
func @test_dummy_proc_that_takes_dummy_char_proc(%arg0: () -> ()) { | ||
%0 = fir.address_of(@char_proc) : (!fir.ref<!fir.char<1,7>>, index) -> !fir.boxchar<1> | ||
%c7_i64 = arith.constant 7 : i64 | ||
%1 = fir.convert %0 : ((!fir.ref<!fir.char<1,7>>, index) -> !fir.boxchar<1>) -> (() -> ()) | ||
%2 = fir.undefined tuple<() -> (), i64> | ||
%3 = fir.insert_value %2, %1, [0 : index] : (tuple<() -> (), i64>, () -> ()) -> tuple<() -> (), i64> | ||
%4 = fir.insert_value %3, %c7_i64, [1 : index] : (tuple<() -> (), i64>, i64) -> tuple<() -> (), i64> | ||
%5 = fir.convert %arg0 : (() -> ()) -> ((tuple<() -> (), i64>) -> ()) | ||
|
||
// CHECK: %[[ARG_CAST:.*]] = fir.convert %[[ARG0]] : (() -> ()) -> ((() -> (), i64) -> ()) | ||
// CHECK: %[[PROC_ADDR:.*]] = fir.extract_value %4, [0 : index] : (tuple<() -> (), i64>) -> (() -> ()) | ||
// CHECK: %[[PROC_LEN:.*]] = fir.extract_value %4, [1 : index] : (tuple<() -> (), i64>) -> i64 | ||
// CHECK: fir.call %[[ARG_CAST]](%[[PROC_ADDR]], %[[PROC_LEN]]) : (() -> (), i64) -> () | ||
fir.call %5(%4) : (tuple<() -> (), i64>) -> () | ||
return | ||
} | ||
|
||
// CHECK: func @takes_dummy_char_proc_impl( | ||
// CHECK-SAME: %[[PROC_ADDR:.*]]: () -> () {fir.char_proc}, | ||
// CHECK-SAME: %[[C_ADDR:.*]]: !fir.ref<!fir.char<1,?>>, | ||
// CHECK-SAME: %[[PROC_LEN:.*]]: i64, | ||
// CHECK-SAME: %[[C_LEN:.*]]: i64) { | ||
func @takes_dummy_char_proc_impl(%arg0: tuple<() -> (), i64> {fir.char_proc}, %arg1: !fir.boxchar<1>) { | ||
// CHECK: %[[UNDEF:.*]] = fir.undefined tuple<() -> (), i64> | ||
// CHECK: %[[TUPLE0:.*]] = fir.insert_value %[[UNDEF]], %[[PROC_ADDR]], [0 : index] : (tuple<() -> (), i64>, () -> ()) -> tuple<() -> (), i64> | ||
// CHECK: %[[TUPLE1:.*]] = fir.insert_value %[[TUPLE0]], %[[PROC_LEN]], [1 : index] : (tuple<() -> (), i64>, i64) -> tuple<() -> (), i64> | ||
%0 = fir.alloca !fir.char<1,7> {bindc_name = ".result"} | ||
%1:2 = fir.unboxchar %arg1 : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index) | ||
%c5 = arith.constant 5 : index | ||
%2 = fir.emboxchar %1#0, %c5 : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1> | ||
%3 = fir.extract_value %arg0, [0 : index] : (tuple<() -> (), i64>) -> (() -> ()) | ||
%c7_i64 = arith.constant 7 : i64 | ||
%4 = fir.convert %c7_i64 : (i64) -> index | ||
%6 = fir.convert %3 : (() -> ()) -> ((!fir.ref<!fir.char<1,7>>, index, !fir.boxchar<1>) -> !fir.boxchar<1>) | ||
%7 = fir.call %6(%0, %4, %2) : (!fir.ref<!fir.char<1,7>>, index, !fir.boxchar<1>) -> !fir.boxchar<1> | ||
%8 = fir.convert %0 : (!fir.ref<!fir.char<1,7>>) -> !fir.ref<!fir.char<1,?>> | ||
%9 = fir.emboxchar %8, %4 : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1> | ||
fir.call @takes_char(%9) : (!fir.boxchar<1>) -> () | ||
return | ||
} | ||
|