forked from OSchip/llvm-project
[flang] Lower system_clock intrinsic
This patch adds lowering ofr the `system_clock` intrinsic. The call is lowered to runtime function call. This patch is part of the upstreaming effort from fir-dev branch. Reviewed By: jeanPerier Differential Revision: https://reviews.llvm.org/D121776 Co-authored-by: V Donaldson <vdonaldson@nvidia.com> Co-authored-by: Jean Perier <jperier@nvidia.com>
This commit is contained in:
parent
7fb2d9f9b5
commit
264d966232
|
@ -81,6 +81,11 @@ void genRandomNumber(fir::FirOpBuilder &, mlir::Location, mlir::Value harvest);
|
|||
void genRandomSeed(fir::FirOpBuilder &, mlir::Location, int argIndex,
|
||||
mlir::Value argBox);
|
||||
|
||||
/// generate system_clock runtime call/s
|
||||
/// all intrinsic arguments are optional and may appear here as mlir::Value{}
|
||||
void genSystemClock(fir::FirOpBuilder &, mlir::Location, mlir::Value count,
|
||||
mlir::Value rate, mlir::Value max);
|
||||
|
||||
} // namespace lower
|
||||
} // namespace Fortran
|
||||
|
||||
|
|
|
@ -462,6 +462,7 @@ struct IntrinsicLibrary {
|
|||
void genRandomSeed(llvm::ArrayRef<fir::ExtendedValue>);
|
||||
fir::ExtendedValue genSize(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
|
||||
fir::ExtendedValue genSum(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
|
||||
void genSystemClock(llvm::ArrayRef<fir::ExtendedValue>);
|
||||
fir::ExtendedValue genUbound(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
|
||||
|
||||
/// Define the different FIR generators that can be mapped to intrinsic to
|
||||
|
@ -652,6 +653,10 @@ static constexpr IntrinsicHandler handlers[]{
|
|||
{"dim", asValue},
|
||||
{"mask", asBox, handleDynamicOptional}}},
|
||||
/*isElemental=*/false},
|
||||
{"system_clock",
|
||||
&I::genSystemClock,
|
||||
{{{"count", asAddr}, {"count_rate", asAddr}, {"count_max", asAddr}}},
|
||||
/*isElemental=*/false},
|
||||
{"ubound",
|
||||
&I::genUbound,
|
||||
{{{"array", asBox}, {"dim", asValue}, {"kind", asValue}}},
|
||||
|
@ -1875,6 +1880,13 @@ IntrinsicLibrary::genSum(mlir::Type resultType,
|
|||
builder, loc, stmtCtx, "unexpected result for Sum", args);
|
||||
}
|
||||
|
||||
// SYSTEM_CLOCK
|
||||
void IntrinsicLibrary::genSystemClock(llvm::ArrayRef<fir::ExtendedValue> args) {
|
||||
assert(args.size() == 3);
|
||||
Fortran::lower::genSystemClock(builder, loc, fir::getBase(args[0]),
|
||||
fir::getBase(args[1]), fir::getBase(args[2]));
|
||||
}
|
||||
|
||||
// SIZE
|
||||
fir::ExtendedValue
|
||||
IntrinsicLibrary::genSize(mlir::Type resultType,
|
||||
|
|
|
@ -233,3 +233,31 @@ void Fortran::lower::genRandomSeed(fir::FirOpBuilder &builder,
|
|||
builder, loc, funcTy, argBox, sourceFile, sourceLine);
|
||||
builder.create<fir::CallOp>(loc, func, args);
|
||||
}
|
||||
|
||||
/// generate system_clock runtime call/s
|
||||
/// all intrinsic arguments are optional and may appear here as mlir::Value{}
|
||||
void Fortran::lower::genSystemClock(fir::FirOpBuilder &builder,
|
||||
mlir::Location loc, mlir::Value count,
|
||||
mlir::Value rate, mlir::Value max) {
|
||||
auto makeCall = [&](mlir::FuncOp func, mlir::Value arg) {
|
||||
mlir::Type kindTy = func.getType().getInput(0);
|
||||
int integerKind = 8;
|
||||
if (auto intType =
|
||||
fir::unwrapRefType(arg.getType()).dyn_cast<mlir::IntegerType>())
|
||||
integerKind = intType.getWidth() / 8;
|
||||
mlir::Value kind = builder.createIntegerConstant(loc, kindTy, integerKind);
|
||||
mlir::Value res =
|
||||
builder.create<fir::CallOp>(loc, func, mlir::ValueRange{kind})
|
||||
.getResult(0);
|
||||
mlir::Value castRes =
|
||||
builder.createConvert(loc, fir::dyn_cast_ptrEleTy(arg.getType()), res);
|
||||
builder.create<fir::StoreOp>(loc, castRes, arg);
|
||||
};
|
||||
using fir::runtime::getRuntimeFunc;
|
||||
if (count)
|
||||
makeCall(getRuntimeFunc<mkRTKey(SystemClockCount)>(loc, builder), count);
|
||||
if (rate)
|
||||
makeCall(getRuntimeFunc<mkRTKey(SystemClockCountRate)>(loc, builder), rate);
|
||||
if (max)
|
||||
makeCall(getRuntimeFunc<mkRTKey(SystemClockCountMax)>(loc, builder), max);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
! RUN: bbc -emit-fir %s -o - | FileCheck %s
|
||||
|
||||
! CHECK-LABEL: system_clock_test
|
||||
subroutine system_clock_test()
|
||||
integer(4) :: c
|
||||
integer(8) :: m
|
||||
real :: r
|
||||
! CHECK-DAG: %[[c:.*]] = fir.alloca i32 {bindc_name = "c"
|
||||
! CHECK-DAG: %[[m:.*]] = fir.alloca i64 {bindc_name = "m"
|
||||
! CHECK-DAG: %[[r:.*]] = fir.alloca f32 {bindc_name = "r"
|
||||
! CHECK: %[[c4:.*]] = arith.constant 4 : i32
|
||||
! CHECK: %[[Count:.*]] = fir.call @_FortranASystemClockCount(%[[c4]]) : (i32) -> i64
|
||||
! CHECK: %[[Count1:.*]] = fir.convert %[[Count]] : (i64) -> i32
|
||||
! CHECK: fir.store %[[Count1]] to %[[c]] : !fir.ref<i32>
|
||||
! CHECK: %[[c8:.*]] = arith.constant 8 : i32
|
||||
! CHECK: %[[Rate:.*]] = fir.call @_FortranASystemClockCountRate(%[[c8]]) : (i32) -> i64
|
||||
! CHECK: %[[Rate1:.*]] = fir.convert %[[Rate]] : (i64) -> f32
|
||||
! CHECK: fir.store %[[Rate1]] to %[[r]] : !fir.ref<f32>
|
||||
! CHECK: %[[c8_2:.*]] = arith.constant 8 : i32
|
||||
! CHECK: %[[Max:.*]] = fir.call @_FortranASystemClockCountMax(%[[c8_2]]) : (i32) -> i64
|
||||
! CHECK: fir.store %[[Max]] to %[[m]] : !fir.ref<i64>
|
||||
call system_clock(c, r, m)
|
||||
! print*, c, r, m
|
||||
! CHECK-NOT: fir.call
|
||||
! CHECK: %[[c8_3:.*]] = arith.constant 8 : i32
|
||||
! CHECK: %[[Rate:.*]] = fir.call @_FortranASystemClockCountRate(%[[c8_3]]) : (i32) -> i64
|
||||
! CHECK: fir.store %[[Rate]] to %[[m]] : !fir.ref<i64>
|
||||
call system_clock(count_rate=m)
|
||||
! CHECK-NOT: fir.call
|
||||
! print*, m
|
||||
end subroutine
|
Loading…
Reference in New Issue