mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-28 16:11:29 +00:00
[Flang] Lower the repeat intrinsic
The repeat intrinsic creates ncopies of a string. The lowering is to a runtime call to a function in the flang library. The runtime allocates the buffer to store the result string. This buffer is freed by code added in the lowering. This is part of the upstreaming effort from the fir-dev branch in [1]. [1] https://github.com/flang-compiler/f18-llvm-project Reviewed By: clementval Differential Revision: https://reviews.llvm.org/D121880 Co-authored-by: Valentin Clement <clementval@gmail.com> Co-authored-by: Jean Perier <jperier@nvidia.com>
This commit is contained in:
parent
2b55850df8
commit
291913db53
@ -499,6 +499,7 @@ struct IntrinsicLibrary {
|
||||
void genRandomInit(llvm::ArrayRef<fir::ExtendedValue>);
|
||||
void genRandomNumber(llvm::ArrayRef<fir::ExtendedValue>);
|
||||
void genRandomSeed(llvm::ArrayRef<fir::ExtendedValue>);
|
||||
fir::ExtendedValue genRepeat(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
|
||||
fir::ExtendedValue genReshape(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
|
||||
mlir::Value genScale(mlir::Type, llvm::ArrayRef<mlir::Value>);
|
||||
fir::ExtendedValue genScan(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
|
||||
@ -787,6 +788,10 @@ static constexpr IntrinsicHandler handlers[]{
|
||||
&I::genRandomSeed,
|
||||
{{{"size", asBox}, {"put", asBox}, {"get", asBox}}},
|
||||
/*isElemental=*/false},
|
||||
{"repeat",
|
||||
&I::genRepeat,
|
||||
{{{"string", asAddr}, {"ncopies", asValue}}},
|
||||
/*isElemental=*/false},
|
||||
{"reshape",
|
||||
&I::genReshape,
|
||||
{{{"source", asBox},
|
||||
@ -2840,6 +2845,25 @@ void IntrinsicLibrary::genRandomSeed(llvm::ArrayRef<fir::ExtendedValue> args) {
|
||||
Fortran::lower::genRandomSeed(builder, loc, -1, mlir::Value{});
|
||||
}
|
||||
|
||||
// REPEAT
|
||||
fir::ExtendedValue
|
||||
IntrinsicLibrary::genRepeat(mlir::Type resultType,
|
||||
llvm::ArrayRef<fir::ExtendedValue> args) {
|
||||
assert(args.size() == 2);
|
||||
mlir::Value string = builder.createBox(loc, args[0]);
|
||||
mlir::Value ncopies = fir::getBase(args[1]);
|
||||
// Create mutable fir.box to be passed to the runtime for the result.
|
||||
fir::MutableBoxValue resultMutableBox =
|
||||
fir::factory::createTempMutableBox(builder, loc, resultType);
|
||||
mlir::Value resultIrBox =
|
||||
fir::factory::getMutableIRBox(builder, loc, resultMutableBox);
|
||||
// Call runtime. The runtime is allocating the result.
|
||||
fir::runtime::genRepeat(builder, loc, resultIrBox, string, ncopies);
|
||||
// Read result from mutable fir.box and add it to the list of temps to be
|
||||
// finalized by the StatementContext.
|
||||
return readAndAddCleanUp(resultMutableBox, resultType, "REPEAT");
|
||||
}
|
||||
|
||||
// RESHAPE
|
||||
fir::ExtendedValue
|
||||
IntrinsicLibrary::genReshape(mlir::Type resultType,
|
||||
|
24
flang/test/Lower/Intrinsics/repeat.f90
Normal file
24
flang/test/Lower/Intrinsics/repeat.f90
Normal file
@ -0,0 +1,24 @@
|
||||
! RUN: bbc -emit-fir %s -o - | FileCheck %s
|
||||
! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s
|
||||
|
||||
! CHECK-LABEL: func @_QPrepeat_test(
|
||||
! CHECK-SAME: %[[arg0:.*]]: !fir.boxchar<1>{{.*}}, %[[arg1:.*]]: !fir.ref<i32>{{.*}}) {
|
||||
subroutine repeat_test(c, n)
|
||||
character(*) :: c
|
||||
integer :: n
|
||||
! CHECK: %[[tmpBox:.*]] = fir.alloca !fir.box<!fir.heap<!fir.char<1,?>>>
|
||||
! CHECK-DAG: %[[c:.*]]:2 = fir.unboxchar %[[arg0]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
|
||||
! CHECK-DAG: %[[ni32:.*]] = fir.load %[[arg1]] : !fir.ref<i32>
|
||||
! CHECK-DAG: %[[n:.*]] = fir.convert %[[ni32]] : (i32) -> i64
|
||||
! CHECK-DAG: %[[cBox:.*]] = fir.embox %[[c]]#0 typeparams %[[c]]#1 : (!fir.ref<!fir.char<1,?>>, index) -> !fir.box<!fir.char<1,?>>
|
||||
! CHECK-DAG: %[[cBoxNone:.*]] = fir.convert %[[cBox]] : (!fir.box<!fir.char<1,?>>) -> !fir.box<none>
|
||||
! CHECK-DAG: %[[resBox:.*]] = fir.convert %[[tmpBox]] : (!fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>) -> !fir.ref<!fir.box<none>>
|
||||
! CHECK: fir.call @{{.*}}Repeat(%[[resBox]], %[[cBoxNone]], %[[n]], {{.*}}, {{.*}}) : (!fir.ref<!fir.box<none>>, !fir.box<none>, i64, !fir.ref<i8>, i32) -> none
|
||||
! CHECK-DAG: %[[tmpAddr:.*]] = fir.box_addr
|
||||
! CHECK-DAG: fir.box_elesize
|
||||
! CHECK: fir.call @{{.*}}bar_repeat_test
|
||||
call bar_repeat_test(repeat(c,n))
|
||||
! CHECK: fir.freemem %[[tmpAddr]] : <!fir.char<1,?>>
|
||||
return
|
||||
end subroutine
|
||||
|
Loading…
Reference in New Issue
Block a user