[flang-commits] [flang] 264d966 - [flang] Lower system_clock intrinsic

Valentin Clement via flang-commits flang-commits at lists.llvm.org
Wed Mar 16 01:51:59 PDT 2022


Author: Valentin Clement
Date: 2022-03-16T09:51:51+01:00
New Revision: 264d96623219e4829bf2a2637410ca0762c2f0b9

URL: https://github.com/llvm/llvm-project/commit/264d96623219e4829bf2a2637410ca0762c2f0b9
DIFF: https://github.com/llvm/llvm-project/commit/264d96623219e4829bf2a2637410ca0762c2f0b9.diff

LOG: [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 at nvidia.com>
Co-authored-by: Jean Perier <jperier at nvidia.com>

Added: 
    flang/test/Lower/Intrinsics/system_clock.f90

Modified: 
    flang/include/flang/Lower/Runtime.h
    flang/lib/Lower/IntrinsicCall.cpp
    flang/lib/Lower/Runtime.cpp

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Lower/Runtime.h b/flang/include/flang/Lower/Runtime.h
index fa1bfaa8578c6..3eec7b4d016ff 100644
--- a/flang/include/flang/Lower/Runtime.h
+++ b/flang/include/flang/Lower/Runtime.h
@@ -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
 

diff  --git a/flang/lib/Lower/IntrinsicCall.cpp b/flang/lib/Lower/IntrinsicCall.cpp
index 196ed24d1c257..3a5a6148bc288 100644
--- a/flang/lib/Lower/IntrinsicCall.cpp
+++ b/flang/lib/Lower/IntrinsicCall.cpp
@@ -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 
diff erent 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,

diff  --git a/flang/lib/Lower/Runtime.cpp b/flang/lib/Lower/Runtime.cpp
index a6507e15bbf20..8b97a5125c8ca 100644
--- a/flang/lib/Lower/Runtime.cpp
+++ b/flang/lib/Lower/Runtime.cpp
@@ -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);
+}

diff  --git a/flang/test/Lower/Intrinsics/system_clock.f90 b/flang/test/Lower/Intrinsics/system_clock.f90
new file mode 100644
index 0000000000000..8713acd05e8c3
--- /dev/null
+++ b/flang/test/Lower/Intrinsics/system_clock.f90
@@ -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


        


More information about the flang-commits mailing list