Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 4 commits into from Oct 27, 2023

Conversation

razvanlupusoru
Copy link
Contributor

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).

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).
@llvmbot llvmbot added flang Flang issues not falling into any other category flang:fir-hlfir labels Oct 26, 2023
@llvmbot
Copy link
Collaborator

llvmbot commented Oct 26, 2023

@llvm/pr-subscribers-flang-openmp

@llvm/pr-subscribers-flang-fir-hlfir

Author: Razvan Lupusoru (razvanlupusoru)

Changes

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).


Full diff: https://github.com/llvm/llvm-project/pull/70386.diff

1 Files Affected:

  • (modified) flang/lib/Lower/ConvertCall.cpp (+7-3)
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(

@clementval
Copy link
Contributor

Do we need a test or is there one already for the omp_lib case?

@razvanlupusoru
Copy link
Contributor Author

Do we need a test or is there one already for the omp_lib case?

Yes - turns out we did need a lowering test for this. I confirmed that this new test fails if I remove the special case for "omp_lib", but passes with my change.

@vdonaldson
Copy link
Contributor

The following functions from omp_lib.h do not have a bind(c) attribute, which might be a problem.

    subroutine omp_set_affinity_format(format)
    function omp_get_affinity_format(buffer)
    subroutine omp_display_affinity(format)
    function omp_capture_affinity(buffer, format)
    function omp_pause_resource_all(kind)
    function omp_init_allocator(memspace, ntraits, traits)
    function omp_get_default_allocator()

@razvanlupusoru
Copy link
Contributor Author

The following functions from omp_lib.h do not have a bind(c) attribute, which might be a problem.

    subroutine omp_set_affinity_format(format)
    function omp_get_affinity_format(buffer)
    subroutine omp_display_affinity(format)
    function omp_capture_affinity(buffer, format)
    function omp_pause_resource_all(kind)
    function omp_init_allocator(memspace, ntraits, traits)
    function omp_get_default_allocator()

Nice catch! Those need the bind(c) attribute also. The implementation for these is not in the module - but in the runtime. llvm/openmp/runtime/src
I will update the module to note this!

@vdonaldson
Copy link
Contributor

For the record, current processing has a negative string compare (to avoid
processing module omp_lib). It would also be possible to implement a positive
string compare (to apply processing to specific modules).

The public llvm-project-mirror/flang/module directory has 13 files that
each contain a single module. The first group of 4 modules have lowering code.
The second group of 8 modules do not appear to have lowering code, either
because they do not declare subprograms, or because subprograms are otherwise
implemented. I'm not sure about the status of (ppc) module mma.

   File                            Module                      Notes
-------------------------------------------------------------------------------
+  __fortran_builtins.f90          __fortran_builtins          lowering code
+  __fortran_ieee_exceptions.f90   __fortran_ieee_exceptions   lowering code
+  ieee_arithmetic.f90             ieee_arithmetic             lowering code
+  __ppc_intrinsics.f90            __ppc_intrinsics            lowering code

-  __cuda_builtins.f90             __CUDA_builtins             no functions
-  __fortran_type_info.f90         __fortran_type_info         no functions
-  ieee_exceptions.f90             ieee_exceptions             wrapper
-  ieee_features.f90               ieee_features               no functions
-  iso_c_binding.f90               iso_c_binding               wrapper
-  iso_fortran_env.f90             iso_fortran_env             no functions
-  omp_lib.f90                     omp_lib                     no lowering code
-  __ppc_types.f90                 __ppc_types                 no functions

?  mma.f90                         mma                         ?

@razvanlupusoru
Copy link
Contributor Author

razvanlupusoru commented Oct 27, 2023

For the record, current processing has a negative string compare (to avoid
processing module omp_lib). It would also be possible to implement a positive
string compare (to apply processing to specific modules).

Thank you for looking into those other modules also. And again for pointing out the issues with omp_lib module! :)

I still think that avoiding either a negative/positive test based on module name is probably best. The bind(c) approach appears to be more general and does solve my concern. And it shouldn't impact any of the other modules since omp_lib was the only one treated specially at the point I resolved this issue.

Copy link
Contributor

@jeanPerier jeanPerier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@kiranchandramohan
Copy link
Contributor

Thanks, the patch looks fine to me.

Users might also use the omp_lib.f90 from the OpenMP runtime. For some reason, these functions are not marked bind(C) there as well.

subroutine omp_set_affinity_format(format)

I have asked a question in the patch that introduced this change. https://reviews.llvm.org/D55148. Maybe you can update there as well.

@razvanlupusoru
Copy link
Contributor Author

Thanks, the patch looks fine to me.

Users might also use the omp_lib.f90 from the OpenMP runtime. For some reason, these functions are not marked bind(C) there as well.

subroutine omp_set_affinity_format(format)

I have asked a question in the patch that introduced this change. https://reviews.llvm.org/D55148. Maybe you can update there as well.

Thanks Kiran for reviewing! I was considering adding you as a reviewer initially - but at first it seemed very little related to omp since I was just removing the hardcoded line to omp_lib. But either way, I appreciate you took the time to look!

Second, I do see that the module there is missing bind(c) also. I have looked at that module and I see several differences - not just this case. For example, in the F18 module, omp_logical_kind = 1 and in that one omp_logical_kind = 4. My point is that there are several differences that likely need consolidated at some point - and I am not the right person to start doing that.

The fact that the module there is missing bind(c) is not an issue as the one in the F18 modules directory since if it is an user module, it won't be considered as intrinsic. But for anything that is intrinsic, we need to specify some implementation - otherwise we cannot distinguish between what remains to be implemented and what is implemented externally.

@kiranchandramohan
Copy link
Contributor

Second, I do see that the module there is missing bind(c) also. I have looked at that module and I see several differences - not just this case. For example, in the F18 module, omp_logical_kind = 1 and in that one omp_logical_kind = 4. My point is that there are several differences that likely need consolidated at some point - and I am not the right person to start doing that.

Yes, at some point we have to copy that in (instead of the local omp_lib.f90), atleast for the upstream version installation since the upstream version will use the llvm openmp library. I agree that we have to consolidate the changes and that need not be part of this patch.

Copy link
Contributor

@kiranchandramohan kiranchandramohan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@razvanlupusoru razvanlupusoru merged commit 3e32b80 into llvm:main Oct 27, 2023
3 checks passed
@DominikAdamski
Copy link
Contributor

@razvanlupusoru I get an error when I try to compile your test to binary:

flang-new -fopenmp flang/test/Lower/OpenMP/omp-lib-num-threads.f90
error: loc("flang/test/Lower/OpenMP/omp-lib-num-threads.f90":13:3): flang/lib/Optimizer/Builder/IntrinsicCall.cpp:1375: not yet implemented: intrinsic: omp_set_num_threads

There is no error message about not implemented intrinsic, if I revert your changes.

@clementval
Copy link
Contributor

There is likely a missing bind© for omp_set_num_threads in your module file.

@kiranchandramohan
Copy link
Contributor

kiranchandramohan commented Nov 2, 2023

I think there is an issue with the non-HLFIR flow. The HLFIR flow is fine.

@razvanlupusoru
Copy link
Contributor Author

@razvanlupusoru I get an error when I try to compile your test to binary:

flang-new -fopenmp flang/test/Lower/OpenMP/omp-lib-num-threads.f90
error: loc("flang/test/Lower/OpenMP/omp-lib-num-threads.f90":13:3): flang/lib/Optimizer/Builder/IntrinsicCall.cpp:1375: not yet implemented: intrinsic: omp_set_num_threads

There is no error message about not implemented intrinsic, if I revert your changes.

Thank you for letting me know! :)
#71101

TIFitis pushed a commit to TIFitis/llvm-project that referenced this pull request Jan 8, 2024
…ule procedures (llvm#70386)"

This reverts commit 529aeaff4d07857027c54e82c0c1ebb6cc6f63ac.

This change causes an error:
flang-new -fopenmp flang/test/Lower/OpenMP/omp-lib-num-threads.f90
error: loc("flang/test/Lower/OpenMP/omp-lib-num-threads.f90":13:3):
    flang/lib/Optimizer/Builder/IntrinsicCall.cpp:1375: not yet implemented: intrinsic: omp_set_num_threads
TIFitis pushed a commit to TIFitis/llvm-project that referenced this pull request Jan 8, 2024
…ines

Revert "[flang] Consider bind(c) when lowering calls to intrinsic module procedures (llvm#70386)"

This revert patch needs to be removed when upstream is fixed.
TIFitis pushed a commit to TIFitis/llvm-project that referenced this pull request Jan 8, 2024
…nsic module procedures (llvm#70386)"" (llvm#246)

This reverts commit 5919156.

Issue solved in upstream commit: llvm#71101
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:fir-hlfir flang:openmp flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants