[Flang][OpenMP] Use internal linkage for OpenMP code-gen'ed helper functions (#117911)

When compiling WORKSHARE construct in different compilation units, a
linker error happened, when two equal WORKSHARE constructs with a copy
operation have been compiled:

```
/usr/bin/ld: module2.o: in function `_workshare_copy_f64':
FIRModule:(.text+0x0): multiple definition of `_workshare_copy_f64'; module1.o:FIRModule:(.text+0x0): first defined here
```

Reason is that the generate copy function has the wrong linkage:

```
0000000000000000 T _workshare_copy_f64
```

while it should be

```
0000000000000000 t _workshare_copy_f64
```
This commit is contained in:
Michael Klemm
2024-11-28 17:28:56 +01:00
committed by GitHub
parent b207a17ea0
commit 261a4026e8
6 changed files with 27 additions and 21 deletions

View File

@@ -744,6 +744,7 @@ createCopyFunc(mlir::Location loc, lower::AbstractConverter &converter,
mlir::func::FuncOp funcOp =
modBuilder.create<mlir::func::FuncOp>(loc, copyFuncName, funcType);
funcOp.setVisibility(mlir::SymbolTable::Visibility::Private);
fir::factory::setInternalLinkage(funcOp);
builder.createBlock(&funcOp.getRegion(), funcOp.getRegion().end(), argsTy,
{loc, loc});
builder.setInsertionPointToStart(&funcOp.getRegion().back());

View File

@@ -153,6 +153,7 @@ static mlir::func::FuncOp createCopyFunc(mlir::Location loc, mlir::Type varType,
if (auto decl = module.lookupSymbol<mlir::func::FuncOp>(copyFuncName))
return decl;
// create function
mlir::OpBuilder::InsertionGuard guard(builder);
mlir::OpBuilder modBuilder(module.getBodyRegion());
@@ -161,6 +162,7 @@ static mlir::func::FuncOp createCopyFunc(mlir::Location loc, mlir::Type varType,
mlir::func::FuncOp funcOp =
modBuilder.create<mlir::func::FuncOp>(loc, copyFuncName, funcType);
funcOp.setVisibility(mlir::SymbolTable::Visibility::Private);
fir::factory::setInternalLinkage(funcOp);
builder.createBlock(&funcOp.getRegion(), funcOp.getRegion().end(), argsTy,
{loc, loc});
builder.setInsertionPointToStart(&funcOp.getRegion().back());

View File

@@ -8,24 +8,24 @@
!RUN: %flang_fc1 -emit-llvm -fopenmp %s -o - | FileCheck %s
!CHECK-DAG: define void @_copy_box_Uxi32(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
!CHECK-DAG: define void @_copy_10xi32(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
!CHECK-DAG: define void @_copy_i64(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
!CHECK-DAG: define void @_copy_box_Uxi64(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
!CHECK-DAG: define void @_copy_f32(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
!CHECK-DAG: define void @_copy_2x3xf32(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
!CHECK-DAG: define void @_copy_z32(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
!CHECK-DAG: define void @_copy_10xz32(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
!CHECK-DAG: define void @_copy_l32(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
!CHECK-DAG: define void @_copy_5xl32(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
!CHECK-DAG: define void @_copy_c8x8(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
!CHECK-DAG: define void @_copy_10xc8x8(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
!CHECK-DAG: define void @_copy_c16x5(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
!CHECK-DAG: define void @_copy_rec__QFtest_typesTdt(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
!CHECK-DAG: define void @_copy_box_heap_Uxi32(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
!CHECK-DAG: define void @_copy_box_ptr_Uxc8x9(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
!CHECK-DAG: define internal void @_copy_box_Uxi32(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
!CHECK-DAG: define internal void @_copy_10xi32(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
!CHECK-DAG: define internal void @_copy_i64(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
!CHECK-DAG: define internal void @_copy_box_Uxi64(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
!CHECK-DAG: define internal void @_copy_f32(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
!CHECK-DAG: define internal void @_copy_2x3xf32(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
!CHECK-DAG: define internal void @_copy_z32(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
!CHECK-DAG: define internal void @_copy_10xz32(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
!CHECK-DAG: define internal void @_copy_l32(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
!CHECK-DAG: define internal void @_copy_5xl32(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
!CHECK-DAG: define internal void @_copy_c8x8(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
!CHECK-DAG: define internal void @_copy_10xc8x8(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
!CHECK-DAG: define internal void @_copy_c16x5(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
!CHECK-DAG: define internal void @_copy_rec__QFtest_typesTdt(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
!CHECK-DAG: define internal void @_copy_box_heap_Uxi32(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
!CHECK-DAG: define internal void @_copy_box_ptr_Uxc8x9(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
!CHECK-LABEL: define void @_copy_i32(
!CHECK-LABEL: define internal void @_copy_i32(
!CHECK-SAME: ptr nocapture %[[DST:.*]], ptr nocapture %[[SRC:.*]]){{.*}} {
!CHECK-NEXT: %[[SRC_VAL:.*]] = load i32, ptr %[[SRC]]
!CHECK-NEXT: store i32 %[[SRC_VAL]], ptr %[[DST]]

View File

@@ -31,7 +31,7 @@
!CHECK-DAG: func private @_copy_box_ptr_Uxc8x9(%{{.*}}: !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,9>>>>>, %{{.*}}: !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,9>>>>>)
!CHECK-LABEL: func private @_copy_i32(
!CHECK-SAME: %[[ARG0:.*]]: !fir.ref<i32>, %[[ARG1:.*]]: !fir.ref<i32>) {
!CHECK-SAME: %[[ARG0:.*]]: !fir.ref<i32>, %[[ARG1:.*]]: !fir.ref<i32>) attributes {llvm.linkage = #llvm.linkage<internal>} {
!CHECK-NEXT: %[[DST:.*]]:2 = hlfir.declare %[[ARG0]] {uniq_name = "_copy_i32_dst"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
!CHECK-NEXT: %[[SRC:.*]]:2 = hlfir.declare %[[ARG1]] {uniq_name = "_copy_i32_src"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
!CHECK-NEXT: %[[SRC_VAL:.*]] = fir.load %[[SRC]]#0 : !fir.ref<i32>

View File

@@ -3,7 +3,8 @@
!CHECK-LABEL: func private @_copy_box_ptr_i32(
!CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.ptr<i32>>>,
!CHECK-SAME: %[[ARG1:.*]]: !fir.ref<!fir.box<!fir.ptr<i32>>>) {
!CHECK-SAME: %[[ARG1:.*]]: !fir.ref<!fir.box<!fir.ptr<i32>>>)
!CHECK-SAME: attributes {llvm.linkage = #llvm.linkage<internal>} {
!CHECK-NEXT: %[[DST:.*]]:2 = hlfir.declare %[[ARG0]] {fortran_attrs = #fir.var_attrs<pointer>,
!CHECK-SAME: uniq_name = "_copy_box_ptr_i32_dst"} : (!fir.ref<!fir.box<!fir.ptr<i32>>>) ->
!CHECK-SAME: (!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.ptr<i32>>>)
@@ -17,7 +18,8 @@
!CHECK-LABEL: func private @_copy_box_heap_Uxi32(
!CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>,
!CHECK-SAME: %[[ARG1:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) {
!CHECK-SAME: %[[ARG1:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)
!CHECK-SAME: attributes {llvm.linkage = #llvm.linkage<internal>} {
!CHECK-NEXT: %[[DST:.*]]:2 = hlfir.declare %[[ARG0]] {fortran_attrs = #fir.var_attrs<allocatable>,
!CHECK-SAME: uniq_name = "_copy_box_heap_Uxi32_dst"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) ->
!CHECK-SAME: (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)

View File

@@ -22,7 +22,8 @@ func.func @wsfunc() {
// CHECK-LABEL: func.func private @_workshare_copy_i32(
// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<i32>,
// CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<i32>) {
// CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<i32>)
// CHECK-SAME: attributes {llvm.linkage = #llvm.linkage<internal>} {
// CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_1]] : !fir.ref<i32>
// CHECK: fir.store %[[VAL_2]] to %[[VAL_0]] : !fir.ref<i32>
// CHECK: return