[flang-commits] [flang] [flang] Lower BIND(C) module variables (PR #78279)

via flang-commits flang-commits at lists.llvm.org
Tue Jan 16 05:55:35 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

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

Author: None (jeanPerier)

<details>
<summary>Changes</summary>

Lower initialized BIND(C) module variable as regular module variable, except that the fir.global symbol name is the binding label.

For uninitialized variables, add the common linkage so that C code may define the variables. The standard does not provide a way to indicate that a variable is defined in C, but there are use cases.

Beware that if the module file compiled object is added to a shared library, the variable will become a regular global definition and may override the C variable depending on the linking order.

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


2 Files Affected:

- (modified) flang/lib/Lower/ConvertVariable.cpp (+10-7) 
- (added) flang/test/Lower/HLFIR/bindc-module-var.f90 (+29) 


``````````diff
diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index ad44de71ee828a..dd024a0a1ec792 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -595,14 +595,17 @@ static fir::GlobalOp defineGlobal(Fortran::lower::AbstractConverter &converter,
   // Creates zero initializer for globals without initializers, this is a common
   // and expected behavior (although not required by the standard)
   if (!globalIsInitialized(global)) {
-    // TODO: For BIND(C) variables, an initial value may be given in another
-    // compilation unit (on the C side), and setting an zero init here creates
-    // linkage conflicts. See if there is a way to get it zero initialized if
-    // not initialized elsewhere. MLIR also used to drop globals without
-    // initializers that are not used in the file, but this may not be true
-    // anymore.
+    // Fortran does not provide means to specify that a BIND(C) module
+    // uninitialized variables will be defined in C.
+    // Add the common linkage to those to allow some level of support
+    // for this use case. Note that this use case will not work if the Fortran
+    // module code is placed in a shared library since, at least for the ELF
+    // format, common symbols are assigned a section in shared libraries.
+    // The best is still to declare C defined variables in a Fortran module file
+    // with no other definitions, and to never link the resulting module object
+    // file.
     if (sym.attrs().test(Fortran::semantics::Attr::BIND_C))
-      TODO(loc, "BIND(C) module variable linkage");
+      global.setLinkName(builder.createCommonLinkage());
     Fortran::lower::createGlobalInitialization(
         builder, global, [&](fir::FirOpBuilder &builder) {
           mlir::Value initValue = builder.create<fir::ZeroOp>(loc, symTy);
diff --git a/flang/test/Lower/HLFIR/bindc-module-var.f90 b/flang/test/Lower/HLFIR/bindc-module-var.f90
new file mode 100644
index 00000000000000..20848078b3eba3
--- /dev/null
+++ b/flang/test/Lower/HLFIR/bindc-module-var.f90
@@ -0,0 +1,29 @@
+! Test BIND(C) module variable lowering
+! RUN: bbc -emit-hlfir -o - %s | FileCheck %s
+
+module some_c_module
+  integer, bind(c, name="i_var") :: i = 1
+  integer, bind(c, name="i_var_no_init") :: i_no_init
+  integer, bind(c) :: j_var = 2
+  integer, bind(c) :: j_var_no_init
+end module
+
+! CHECK-LABEL:   fir.global @i_var : i32 {
+! CHECK:           %[[VAL_0:.*]] = arith.constant 1 : i32
+! CHECK:           fir.has_value %[[VAL_0]] : i32
+! CHECK:         }
+
+! CHECK-LABEL:   fir.global common @i_var_no_init : i32 {
+! CHECK:           %[[VAL_0:.*]] = fir.zero_bits i32
+! CHECK:           fir.has_value %[[VAL_0]] : i32
+! CHECK:         }
+
+! CHECK-LABEL:   fir.global @j_var : i32 {
+! CHECK:           %[[VAL_0:.*]] = arith.constant 2 : i32
+! CHECK:           fir.has_value %[[VAL_0]] : i32
+! CHECK:         }
+
+! CHECK-LABEL:   fir.global common @j_var_no_init : i32 {
+! CHECK:           %[[VAL_0:.*]] = fir.zero_bits i32
+! CHECK:           fir.has_value %[[VAL_0]] : i32
+! CHECK:         }

``````````

</details>


https://github.com/llvm/llvm-project/pull/78279


More information about the flang-commits mailing list