[flang-commits] [flang] [flang] Consider bind(c) when lowering calls to intrinsic module procedures (PR #70386)

Razvan Lupusoru via flang-commits flang-commits at lists.llvm.org
Thu Oct 26 21:44:39 PDT 2023


https://github.com/razvanlupusoru updated https://github.com/llvm/llvm-project/pull/70386

>From 6b9e225da0f4e4b944f354c214ee09fc29467215 Mon Sep 17 00:00:00 2001
From: Razvan Lupusoru <rlupusoru at nvidia.com>
Date: Thu, 26 Oct 2023 15:17:20 -0700
Subject: [PATCH 1/4] [flang] Consider bind(c) when lowering calls to intrinsic
 module procedures

When attempting to lower an intrinsic module procedure call, take into
account bind(c). Such procedures cannot be lowered as intrinsics
since their implementation is external to the module.

With this solution, the hardcoded "omp_lib" string can be removed when
checking if intrinsic module procedure since all procedure interfaces in
that module use bind(c).
---
 flang/lib/Lower/ConvertCall.cpp | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/flang/lib/Lower/ConvertCall.cpp b/flang/lib/Lower/ConvertCall.cpp
index bc9426827c3ba1d..82e1ece4efeafe7 100644
--- a/flang/lib/Lower/ConvertCall.cpp
+++ b/flang/lib/Lower/ConvertCall.cpp
@@ -2122,7 +2122,12 @@ genProcedureRef(CallContext &callContext) {
   mlir::Location loc = callContext.loc;
   if (auto *intrinsic = callContext.procRef.proc().GetSpecificIntrinsic())
     return genIntrinsicRef(intrinsic, callContext);
-  if (Fortran::lower::isIntrinsicModuleProcRef(callContext.procRef))
+  // If it is an intrinsic module procedure reference - then treat as
+  // intrinsic unless it is bind(c) (since implementation is external from
+  // module).
+  if (Fortran::lower::isIntrinsicModuleProcRef(callContext.procRef) &&
+      !Fortran::semantics::IsBindCProcedure(
+          *callContext.procRef.proc().GetSymbol()))
     return genIntrinsicRef(nullptr, callContext);
 
   if (callContext.isStatementFunctionCall())
@@ -2227,8 +2232,7 @@ bool Fortran::lower::isIntrinsicModuleProcRef(
     return false;
   const Fortran::semantics::Symbol *module =
       symbol->GetUltimate().owner().GetSymbol();
-  return module && module->attrs().test(Fortran::semantics::Attr::INTRINSIC) &&
-         module->name().ToString().find("omp_lib") == std::string::npos;
+  return module && module->attrs().test(Fortran::semantics::Attr::INTRINSIC);
 }
 
 std::optional<hlfir::EntityWithAttributes> Fortran::lower::convertCallToHLFIR(

>From dcf0b973be174c44904d57ddb9764a0986cce3a4 Mon Sep 17 00:00:00 2001
From: Razvan Lupusoru <rlupusoru at nvidia.com>
Date: Thu, 26 Oct 2023 16:38:50 -0700
Subject: [PATCH 2/4] Add lowering test calling omp_lib

---
 .../test/Lower/OpenMP/omp-lib-num-threads.f90 | 21 +++++++++++++++++++
 1 file changed, 21 insertions(+)
 create mode 100644 flang/test/Lower/OpenMP/omp-lib-num-threads.f90

diff --git a/flang/test/Lower/OpenMP/omp-lib-num-threads.f90 b/flang/test/Lower/OpenMP/omp-lib-num-threads.f90
new file mode 100644
index 000000000000000..01c3e93d97bfcc0
--- /dev/null
+++ b/flang/test/Lower/OpenMP/omp-lib-num-threads.f90
@@ -0,0 +1,21 @@
+! RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - 2>&1 | FileCheck %s
+! RUN: bbc -fopenmp -emit-hlfir -o - %s 2>&1 | FileCheck %s
+!
+! Test that the calls to omp_lib's omp_get_num_threads and omp_set_num_threads
+! get lowered even though their implementation is not in the omp_lib module
+! (and this matters because this is an intrinsic module - and calls to
+! intrinsics are specially resolved).
+
+program main
+  use omp_lib
+  integer(omp_integer_kind) :: num_threads
+  integer(omp_integer_kind), parameter :: requested_num_threads = 4
+  call omp_set_num_threads(requested_num_threads)
+  num_threads = omp_get_num_threads()
+  print *, num_threads
+end program
+
+!CHECK-NOT: not yet implemented: intrinsic: omp_set_num_threads
+!CHECK-NOT: not yet implemented: intrinsic: omp_get_num_threads
+!CHECK: fir.call @omp_set_num_threads
+!CHECK: fir.call @omp_get_num_threads

>From 0a4e956c545bf44c5f27ae2ee4568cf90fcf5651 Mon Sep 17 00:00:00 2001
From: Razvan Lupusoru <rlupusoru at nvidia.com>
Date: Thu, 26 Oct 2023 17:15:50 -0700
Subject: [PATCH 3/4] Add bind(c) to all procedures missing it from flang's
 omp_lib module

---
 flang/module/omp_lib.h | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/flang/module/omp_lib.h b/flang/module/omp_lib.h
index d8a9aeb152df5fc..8579059ca4a9cfc 100644
--- a/flang/module/omp_lib.h
+++ b/flang/module/omp_lib.h
@@ -264,23 +264,23 @@
       integer(kind=omp_integer_kind), intent(out) :: place_nums(*)
     end subroutine omp_get_partition_place_nums
 
-    subroutine omp_set_affinity_format(format)
+    subroutine omp_set_affinity_format(format) bind(c)
       import
       character(len=*), intent(in) :: format
     end subroutine omp_set_affinity_format
 
-    function omp_get_affinity_format(buffer)
+    function omp_get_affinity_format(buffer) bind(c)
       import
       character(len=*), intent(out) :: buffer
       integer(kind=omp_integer_kind) :: omp_get_affinity_format
     end function omp_get_affinity_format
 
-    subroutine omp_display_affinity(format)
+    subroutine omp_display_affinity(format) bind(c)
       import
       character(len=*), intent(in) :: format
     end subroutine omp_display_affinity
 
-    function omp_capture_affinity(buffer, format)
+    function omp_capture_affinity(buffer, format) bind(c)
       import
       character(len=*), intent(out) :: buffer
       character(len=*), intent(in) :: format
@@ -339,7 +339,7 @@
       integer(kind=omp_integer_kind) :: omp_pause_resource
     end function omp_pause_resource
 
-    function omp_pause_resource_all(kind)
+    function omp_pause_resource_all(kind) bind(c)
       import
       integer(kind=omp_pause_resource_kind), value :: kind
       integer(kind=omp_integer_kind) :: omp_pause_resource_all
@@ -428,7 +428,7 @@
 ! Device Memory Routines
 
 ! Memory Management Routines
-    function omp_init_allocator(memspace, ntraits, traits)
+    function omp_init_allocator(memspace, ntraits, traits) bind(c)
       import
       integer(kind=omp_memspace_handle_kind), value :: memspace
       integer, value :: ntraits
@@ -446,7 +446,7 @@
       integer(kind=omp_allocator_handle_kind), value :: allocator
     end subroutine omp_set_default_allocator
 
-    function omp_get_default_allocator()
+    function omp_get_default_allocator() bind(c)
       import
       integer(kind=omp_allocator_handle_kind) :: omp_get_default_allocator
     end function omp_get_default_allocator

>From 9d7756320c636ce6107176f6ed06e5ee3cbf752a Mon Sep 17 00:00:00 2001
From: Razvan Lupusoru <rlupusoru at nvidia.com>
Date: Thu, 26 Oct 2023 21:44:16 -0700
Subject: [PATCH 4/4] Update omp_alloctrait type to be bind(c) to avoid errors

---
 flang/module/omp_lib.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/flang/module/omp_lib.h b/flang/module/omp_lib.h
index 8579059ca4a9cfc..efc9ceb16968bbf 100644
--- a/flang/module/omp_lib.h
+++ b/flang/module/omp_lib.h
@@ -90,7 +90,7 @@
     omp_atv_blocked = 17, &
     omp_atv_interleaved = 18
 
-  type :: omp_alloctrait
+  type, bind(c) :: omp_alloctrait
     integer(kind=omp_alloctrait_key_kind) :: key, value
   end type omp_alloctrait
 



More information about the flang-commits mailing list