jhuber6 updated this revision to Diff 554434.
jhuber6 added a comment.

Address nits and add static check for size of `clock_t` type.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D159118/new/

https://reviews.llvm.org/D159118

Files:
  clang/lib/Headers/llvm_libc_wrappers/time.h
  libc/config/gpu/api.td
  libc/config/gpu/entrypoints.txt
  libc/config/gpu/headers.txt
  libc/docs/gpu/support.rst
  libc/include/llvm-libc-macros/gpu/CMakeLists.txt
  libc/include/llvm-libc-macros/gpu/time-macros.h
  libc/include/llvm-libc-macros/time-macros.h
  libc/src/time/gpu/CMakeLists.txt
  libc/src/time/gpu/clock.cpp

Index: libc/src/time/gpu/clock.cpp
===================================================================
--- /dev/null
+++ libc/src/time/gpu/clock.cpp
@@ -0,0 +1,64 @@
+//===-- GPU implementation of the clock function --------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/time/clock.h"
+#include "src/__support/GPU/utils.h"
+
+namespace __llvm_libc {
+
+#if defined(LIBC_TARGET_ARCH_IS_GPU)
+// AMDGPU does not have a single set frequency. Different architectures and
+// cards can have vary values. Here we default to a few known values, but for
+// complete support the frequency needs to be read from the kernel driver.
+#if defined(__gfx1010__) || defined(__gfx1011__) || defined(__gfx1012__) ||    \
+    defined(__gfx1013__) || defined(__gfx1030__) || defined(__gfx1031__) ||    \
+    defined(__gfx1032__) || defined(__gfx1033__) || defined(__gfx1034__) ||    \
+    defined(__gfx1035__) || defined(__gfx1036__) || defined(__gfx1100__) ||    \
+    defined(__gfx1101__) || defined(__gfx1102__) || defined(__gfx1103__) ||    \
+    defined(__gfx1150__) || defined(__gfx1151__)
+// These architectures use a 100 MHz fixed frequency clock.
+constexpr uint64_t clock_freq = 100000000;
+#elif defined(__gfx900__) || defined(__gfx902__) || defined(__gfx904__) ||     \
+    defined(__gfx906__) || defined(__gfx908__) || defined(__gfx909__) ||       \
+    defined(__gfx90a__) || defined(__gfx90c__) || defined(__gfx940__)
+// These architectures use a 25 MHz fixed frequency clock expect for Vega 10
+// which is actually 27 Mhz. We default to 25 MHz in all cases anyway.
+constexpr uint64_t clock_freq = 25000000;
+#else
+// The frequency for these architecture is unknown. We simply default to zero.
+constexpr uint64_t clock_freq = 0;
+#endif
+
+// We provide an externally visible symbol such that the runtime can set this to
+// the correct value. If it is not set we try to default to the known values.
+extern "C" [[gnu::visibility("protected")]] uint64_t
+    [[clang::address_space(4)]] __llvm_libc_clock_freq = clock_freq;
+#define GPU_CLOCKS_PER_SEC static_cast<clock_t>(__llvm_libc_clock_freq)
+
+#elif defined(LIBC_TARGET_ARCH_IS_NVPTX)
+// NPVTX uses a single 1 GHz fixed frequency clock for all target architectures.
+#define GPU_CLOCKS_PER_SEC static_cast<clock_t>(1000000000UL)
+#else
+#error "Unsupported target"
+#endif
+
+LLVM_LIBC_FUNCTION(clock_t, clock, ()) {
+  if (!GPU_CLOCKS_PER_SEC)
+    return clock_t(0);
+
+  uint64_t ticks = gpu::fixed_frequency_clock();
+
+  // We need to convert between the GPU's fixed frequency and whatever `time.h`
+  // declares it to be. This is done so that dividing the result of this
+  // function by 'CLOCKS_PER_SEC' yields the elapsed time.
+  if (GPU_CLOCKS_PER_SEC > CLOCKS_PER_SEC)
+    return clock_t(ticks / (GPU_CLOCKS_PER_SEC / CLOCKS_PER_SEC));
+  return clock_t(ticks * (CLOCKS_PER_SEC / GPU_CLOCKS_PER_SEC));
+}
+
+} // namespace __llvm_libc
Index: libc/src/time/gpu/CMakeLists.txt
===================================================================
--- /dev/null
+++ libc/src/time/gpu/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_entrypoint_object(
+  clock
+  SRCS
+    clock.cpp
+  HDRS
+    ../clock.h
+  DEPENDS
+    libc.include.time
+    libc.src.__support.GPU.utils
+)
Index: libc/include/llvm-libc-macros/time-macros.h
===================================================================
--- libc/include/llvm-libc-macros/time-macros.h
+++ libc/include/llvm-libc-macros/time-macros.h
@@ -3,6 +3,8 @@
 
 #ifdef __linux__
 #include "linux/time-macros.h"
+#elif defined(__AMDGPU__) || defined(__NVPTX__)
+#include "gpu/time-macros.h"
 #endif
 
 #endif // __LLVM_LIBC_MACROS_TIME_MACROS_H
Index: libc/include/llvm-libc-macros/gpu/time-macros.h
===================================================================
--- /dev/null
+++ libc/include/llvm-libc-macros/gpu/time-macros.h
@@ -0,0 +1,14 @@
+//===-- Definition of macros from time.h ---------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __LLVM_LIBC_MACROS_GPU_TIME_MACROS_H
+#define __LLVM_LIBC_MACROS_GPU_TIME_MACROS_H
+
+#define CLOCKS_PER_SEC 1000000
+
+#endif // __LLVM_LIBC_MACROS_GPU_TIME_MACROS_H
Index: libc/include/llvm-libc-macros/gpu/CMakeLists.txt
===================================================================
--- /dev/null
+++ libc/include/llvm-libc-macros/gpu/CMakeLists.txt
@@ -0,0 +1,5 @@
+add_header(
+  time_macros
+  HDR
+    time-macros.h
+)
Index: libc/docs/gpu/support.rst
===================================================================
--- libc/docs/gpu/support.rst
+++ libc/docs/gpu/support.rst
@@ -128,3 +128,12 @@
 fopen          |check|    |check|
 fread          |check|    |check|
 =============  =========  ============
+
+stdio.h
+--------
+
+=============  =========  ============
+Function Name  Available  RPC Required
+=============  =========  ============
+clock          |check|
+=============  =========  ============
Index: libc/config/gpu/headers.txt
===================================================================
--- libc/config/gpu/headers.txt
+++ libc/config/gpu/headers.txt
@@ -4,6 +4,7 @@
     libc.include.inttypes
     libc.include.math
     libc.include.fenv
+    libc.include.time
     libc.include.errno
     libc.include.stdlib
     libc.include.stdio
Index: libc/config/gpu/entrypoints.txt
===================================================================
--- libc/config/gpu/entrypoints.txt
+++ libc/config/gpu/entrypoints.txt
@@ -96,6 +96,9 @@
     libc.src.inttypes.strtoimax
     libc.src.inttypes.strtoumax
 
+    # time.h entrypoints
+    libc.src.time.clock
+
     # gpu/rpc.h entrypoints
     libc.src.gpu.rpc_reset
     libc.src.gpu.rpc_host_call
Index: libc/config/gpu/api.td
===================================================================
--- libc/config/gpu/api.td
+++ libc/config/gpu/api.td
@@ -34,3 +34,9 @@
 def IntTypesAPI : PublicAPI<"inttypes.h"> {
   let Types = ["imaxdiv_t"];
 }
+
+def TimeAPI : PublicAPI<"time.h"> {
+  let Types = [
+    "clock_t",
+  ];
+}
Index: clang/lib/Headers/llvm_libc_wrappers/time.h
===================================================================
--- /dev/null
+++ clang/lib/Headers/llvm_libc_wrappers/time.h
@@ -0,0 +1,34 @@
+//===-- Wrapper for C standard time.h declarations on the GPU -------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __CLANG_LLVM_LIBC_WRAPPERS_TIME_H__
+#define __CLANG_LLVM_LIBC_WRAPPERS_TIME_H__
+
+#if !defined(_OPENMP) && !defined(__HIP__) && !defined(__CUDA__)
+#error "This file is for GPU offloading compilation only"
+#endif
+
+#include_next <time.h>
+
+#if __has_include(<llvm-libc-decls/time.h>)
+
+#if defined(__HIP__) || defined(__CUDA__)
+#define __LIBC_ATTRS __attribute__((device))
+#endif
+
+#pragma omp begin declare target
+
+_Static_assert(sizeof(clock_t) == sizeof(long), "ABI mismatch!");
+
+#include <llvm-libc-decls/ctype.h>
+
+#pragma omp end declare target
+
+#endif
+
+#endif // __CLANG_LLVM_LIBC_WRAPPERS_TIME_H__
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to