Skip to content

Commit 264d966

Browse files
clementvalvdonaldsonjeanPerier
committed
[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 <[email protected]> Co-authored-by: Jean Perier <[email protected]>
1 parent 7fb2d9f commit 264d966

File tree

4 files changed

+76
-0
lines changed

4 files changed

+76
-0
lines changed

flang/include/flang/Lower/Runtime.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ void genRandomNumber(fir::FirOpBuilder &, mlir::Location, mlir::Value harvest);
8181
void genRandomSeed(fir::FirOpBuilder &, mlir::Location, int argIndex,
8282
mlir::Value argBox);
8383

84+
/// generate system_clock runtime call/s
85+
/// all intrinsic arguments are optional and may appear here as mlir::Value{}
86+
void genSystemClock(fir::FirOpBuilder &, mlir::Location, mlir::Value count,
87+
mlir::Value rate, mlir::Value max);
88+
8489
} // namespace lower
8590
} // namespace Fortran
8691

flang/lib/Lower/IntrinsicCall.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,7 @@ struct IntrinsicLibrary {
462462
void genRandomSeed(llvm::ArrayRef<fir::ExtendedValue>);
463463
fir::ExtendedValue genSize(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
464464
fir::ExtendedValue genSum(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
465+
void genSystemClock(llvm::ArrayRef<fir::ExtendedValue>);
465466
fir::ExtendedValue genUbound(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
466467

467468
/// Define the different FIR generators that can be mapped to intrinsic to
@@ -652,6 +653,10 @@ static constexpr IntrinsicHandler handlers[]{
652653
{"dim", asValue},
653654
{"mask", asBox, handleDynamicOptional}}},
654655
/*isElemental=*/false},
656+
{"system_clock",
657+
&I::genSystemClock,
658+
{{{"count", asAddr}, {"count_rate", asAddr}, {"count_max", asAddr}}},
659+
/*isElemental=*/false},
655660
{"ubound",
656661
&I::genUbound,
657662
{{{"array", asBox}, {"dim", asValue}, {"kind", asValue}}},
@@ -1875,6 +1880,13 @@ IntrinsicLibrary::genSum(mlir::Type resultType,
18751880
builder, loc, stmtCtx, "unexpected result for Sum", args);
18761881
}
18771882

1883+
// SYSTEM_CLOCK
1884+
void IntrinsicLibrary::genSystemClock(llvm::ArrayRef<fir::ExtendedValue> args) {
1885+
assert(args.size() == 3);
1886+
Fortran::lower::genSystemClock(builder, loc, fir::getBase(args[0]),
1887+
fir::getBase(args[1]), fir::getBase(args[2]));
1888+
}
1889+
18781890
// SIZE
18791891
fir::ExtendedValue
18801892
IntrinsicLibrary::genSize(mlir::Type resultType,

flang/lib/Lower/Runtime.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,3 +233,31 @@ void Fortran::lower::genRandomSeed(fir::FirOpBuilder &builder,
233233
builder, loc, funcTy, argBox, sourceFile, sourceLine);
234234
builder.create<fir::CallOp>(loc, func, args);
235235
}
236+
237+
/// generate system_clock runtime call/s
238+
/// all intrinsic arguments are optional and may appear here as mlir::Value{}
239+
void Fortran::lower::genSystemClock(fir::FirOpBuilder &builder,
240+
mlir::Location loc, mlir::Value count,
241+
mlir::Value rate, mlir::Value max) {
242+
auto makeCall = [&](mlir::FuncOp func, mlir::Value arg) {
243+
mlir::Type kindTy = func.getType().getInput(0);
244+
int integerKind = 8;
245+
if (auto intType =
246+
fir::unwrapRefType(arg.getType()).dyn_cast<mlir::IntegerType>())
247+
integerKind = intType.getWidth() / 8;
248+
mlir::Value kind = builder.createIntegerConstant(loc, kindTy, integerKind);
249+
mlir::Value res =
250+
builder.create<fir::CallOp>(loc, func, mlir::ValueRange{kind})
251+
.getResult(0);
252+
mlir::Value castRes =
253+
builder.createConvert(loc, fir::dyn_cast_ptrEleTy(arg.getType()), res);
254+
builder.create<fir::StoreOp>(loc, castRes, arg);
255+
};
256+
using fir::runtime::getRuntimeFunc;
257+
if (count)
258+
makeCall(getRuntimeFunc<mkRTKey(SystemClockCount)>(loc, builder), count);
259+
if (rate)
260+
makeCall(getRuntimeFunc<mkRTKey(SystemClockCountRate)>(loc, builder), rate);
261+
if (max)
262+
makeCall(getRuntimeFunc<mkRTKey(SystemClockCountMax)>(loc, builder), max);
263+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
! RUN: bbc -emit-fir %s -o - | FileCheck %s
2+
3+
! CHECK-LABEL: system_clock_test
4+
subroutine system_clock_test()
5+
integer(4) :: c
6+
integer(8) :: m
7+
real :: r
8+
! CHECK-DAG: %[[c:.*]] = fir.alloca i32 {bindc_name = "c"
9+
! CHECK-DAG: %[[m:.*]] = fir.alloca i64 {bindc_name = "m"
10+
! CHECK-DAG: %[[r:.*]] = fir.alloca f32 {bindc_name = "r"
11+
! CHECK: %[[c4:.*]] = arith.constant 4 : i32
12+
! CHECK: %[[Count:.*]] = fir.call @_FortranASystemClockCount(%[[c4]]) : (i32) -> i64
13+
! CHECK: %[[Count1:.*]] = fir.convert %[[Count]] : (i64) -> i32
14+
! CHECK: fir.store %[[Count1]] to %[[c]] : !fir.ref<i32>
15+
! CHECK: %[[c8:.*]] = arith.constant 8 : i32
16+
! CHECK: %[[Rate:.*]] = fir.call @_FortranASystemClockCountRate(%[[c8]]) : (i32) -> i64
17+
! CHECK: %[[Rate1:.*]] = fir.convert %[[Rate]] : (i64) -> f32
18+
! CHECK: fir.store %[[Rate1]] to %[[r]] : !fir.ref<f32>
19+
! CHECK: %[[c8_2:.*]] = arith.constant 8 : i32
20+
! CHECK: %[[Max:.*]] = fir.call @_FortranASystemClockCountMax(%[[c8_2]]) : (i32) -> i64
21+
! CHECK: fir.store %[[Max]] to %[[m]] : !fir.ref<i64>
22+
call system_clock(c, r, m)
23+
! print*, c, r, m
24+
! CHECK-NOT: fir.call
25+
! CHECK: %[[c8_3:.*]] = arith.constant 8 : i32
26+
! CHECK: %[[Rate:.*]] = fir.call @_FortranASystemClockCountRate(%[[c8_3]]) : (i32) -> i64
27+
! CHECK: fir.store %[[Rate]] to %[[m]] : !fir.ref<i64>
28+
call system_clock(count_rate=m)
29+
! CHECK-NOT: fir.call
30+
! print*, m
31+
end subroutine

0 commit comments

Comments
 (0)