diff --git a/flang/include/flang/Lower/PFTBuilder.h b/flang/include/flang/Lower/PFTBuilder.h --- a/flang/include/flang/Lower/PFTBuilder.h +++ b/flang/include/flang/Lower/PFTBuilder.h @@ -638,6 +638,15 @@ return *symbol; } + /// Return a pointer to the main program symbol for named programs + /// Return the null pointer for anonymous programs + const semantics::Symbol *getMainProgramSymbol() const { + if (!isMainProgram()) { + llvm::report_fatal_error("call only on main program."); + } + return entryPointList[activeEntry].first; + } + /// Return a pointer to the current entry point Evaluation. /// This is null for a primary entry point. Evaluation *getEntryEval() const { diff --git a/flang/lib/Lower/CallInterface.cpp b/flang/lib/Lower/CallInterface.cpp --- a/flang/lib/Lower/CallInterface.cpp +++ b/flang/lib/Lower/CallInterface.cpp @@ -428,7 +428,7 @@ const Fortran::semantics::Symbol * Fortran::lower::CalleeInterface::getProcedureSymbol() const { if (funit.isMainProgram()) - return nullptr; + return funit.getMainProgramSymbol(); return &funit.getSubprogramSymbol(); } @@ -529,8 +529,15 @@ mlir::Location loc = side().getCalleeLocation(); mlir::FunctionType ty = genFunctionType(); func = fir::FirOpBuilder::createFunction(loc, module, name, ty); - if (const Fortran::semantics::Symbol *sym = side().getProcedureSymbol()) - addSymbolAttribute(func, *sym, converter.getMLIRContext()); + if (const Fortran::semantics::Symbol *sym = side().getProcedureSymbol()) { + if (side().isMainProgram()) { + func->setAttr(fir::getSymbolAttrName(), + mlir::StringAttr::get(&converter.getMLIRContext(), + sym->name().ToString())); + } else { + addSymbolAttribute(func, *sym, converter.getMLIRContext()); + } + } for (const auto &placeHolder : llvm::enumerate(inputs)) if (!placeHolder.value().attributes.empty()) func.setArgAttrs(placeHolder.index(), placeHolder.value().attributes); diff --git a/flang/test/Lower/OpenMP/atomic-read.f90 b/flang/test/Lower/OpenMP/atomic-read.f90 --- a/flang/test/Lower/OpenMP/atomic-read.f90 +++ b/flang/test/Lower/OpenMP/atomic-read.f90 @@ -2,7 +2,7 @@ ! This test checks the lowering of atomic read -!CHECK: func @_QQmain() { +!CHECK: func @_QQmain() attributes {fir.bindc_name = "ompatomic"} { !CHECK: %[[VAR_A:.*]] = fir.alloca !fir.char<1> {bindc_name = "a", uniq_name = "_QFEa"} !CHECK: %[[VAR_B:.*]] = fir.alloca !fir.char<1> {bindc_name = "b", uniq_name = "_QFEb"} !CHECK: %[[VAR_C:.*]] = fir.alloca !fir.logical<4> {bindc_name = "c", uniq_name = "_QFEc"} diff --git a/flang/test/Lower/OpenMP/atomic-update.f90 b/flang/test/Lower/OpenMP/atomic-update.f90 --- a/flang/test/Lower/OpenMP/atomic-update.f90 +++ b/flang/test/Lower/OpenMP/atomic-update.f90 @@ -10,7 +10,7 @@ a=>c b=>d -!CHECK: func.func @_QQmain() { +!CHECK: func.func @_QQmain() attributes {fir.bindc_name = "ompatomicupdate"} { !CHECK: %[[A:.*]] = fir.alloca !fir.box> {bindc_name = "a", uniq_name = "_QFEa"} !CHECK: %[[A_ADDR:.*]] = fir.alloca !fir.ptr {uniq_name = "_QFEa.addr"} !CHECK: %{{.*}} = fir.zero_bits !fir.ptr diff --git a/flang/test/Lower/OpenMP/atomic-write.f90 b/flang/test/Lower/OpenMP/atomic-write.f90 --- a/flang/test/Lower/OpenMP/atomic-write.f90 +++ b/flang/test/Lower/OpenMP/atomic-write.f90 @@ -2,7 +2,7 @@ ! This test checks the lowering of atomic write -!CHECK: func @_QQmain() { +!CHECK: func @_QQmain() attributes {fir.bindc_name = "ompatomicwrite"} { !CHECK: %[[VAR_X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFEx"} !CHECK: %[[VAR_Y:.*]] = fir.alloca i32 {bindc_name = "y", uniq_name = "_QFEy"} !CHECK: %[[VAR_Z:.*]] = fir.alloca i32 {bindc_name = "z", uniq_name = "_QFEz"} diff --git a/flang/test/Lower/OpenMP/default-clause.f90 b/flang/test/Lower/OpenMP/default-clause.f90 --- a/flang/test/Lower/OpenMP/default-clause.f90 +++ b/flang/test/Lower/OpenMP/default-clause.f90 @@ -5,7 +5,7 @@ ! RUN: bbc -fopenmp -emit-fir %s -o - | FileCheck %s -!CHECK: func @_QQmain() { +!CHECK: func @_QQmain() attributes {fir.bindc_name = "default_clause_lowering"} { !CHECK: %[[W:.*]] = fir.alloca i32 {bindc_name = "w", uniq_name = "_QFEw"} !CHECK: %[[X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFEx"} !CHECK: %[[Y:.*]] = fir.alloca i32 {bindc_name = "y", uniq_name = "_QFEy"} diff --git a/flang/test/Lower/OpenMP/omp-wsloop-chunks.f90 b/flang/test/Lower/OpenMP/omp-wsloop-chunks.f90 --- a/flang/test/Lower/OpenMP/omp-wsloop-chunks.f90 +++ b/flang/test/Lower/OpenMP/omp-wsloop-chunks.f90 @@ -7,7 +7,7 @@ integer :: i integer :: chunk -! CHECK-LABEL: func.func @_QQmain() { +! CHECK-LABEL: func.func @_QQmain() attributes {fir.bindc_name = "wsloop"} { ! CHECK: %[[VAL_0:.*]] = fir.alloca i32 {bindc_name = "chunk", uniq_name = "_QFEchunk"} !$OMP DO SCHEDULE(static, 4) diff --git a/flang/test/Lower/OpenMP/sections.f90 b/flang/test/Lower/OpenMP/sections.f90 --- a/flang/test/Lower/OpenMP/sections.f90 +++ b/flang/test/Lower/OpenMP/sections.f90 @@ -2,7 +2,7 @@ ! RUN: %flang_fc1 -emit-fir -fopenmp %s -o - | FileCheck %s -!CHECK: func @_QQmain() { +!CHECK: func @_QQmain() attributes {fir.bindc_name = "sample"} { !CHECK: %[[COUNT:.*]] = fir.address_of(@_QFEcount) : !fir.ref !CHECK: %[[ETA:.*]] = fir.alloca f32 {bindc_name = "eta", uniq_name = "_QFEeta"} !CHECK: %[[CONST_1:.*]] = arith.constant 1 : i32 diff --git a/flang/test/Lower/array-character.f90 b/flang/test/Lower/array-character.f90 --- a/flang/test/Lower/array-character.f90 +++ b/flang/test/Lower/array-character.f90 @@ -53,7 +53,7 @@ ! CHECK: } end subroutine -! CHECK-LABEL: func @_QQmain() { +! CHECK-LABEL: func @_QQmain() attributes {fir.bindc_name = "p"} { program p ! CHECK-DAG: %[[VAL_0:.*]] = arith.constant 4 : index ! CHECK-DAG: %[[VAL_1:.*]] = arith.constant 3 : index diff --git a/flang/test/Lower/array-expression-slice-1.f90 b/flang/test/Lower/array-expression-slice-1.f90 --- a/flang/test/Lower/array-expression-slice-1.f90 +++ b/flang/test/Lower/array-expression-slice-1.f90 @@ -1,6 +1,6 @@ ! RUN: bbc -o - --outline-intrinsics %s | FileCheck %s -! CHECK-LABEL: func @_QQmain() { +! CHECK-LABEL: func @_QQmain() attributes {fir.bindc_name = "p"} { ! CHECK-DAG: %[[VAL_0:.*]] = arith.constant 10 : index ! CHECK-DAG: %[[VAL_4:.*]] = arith.constant 2 : index ! CHECK-DAG: %[[VAL_5:.*]] = arith.constant 1 : index diff --git a/flang/test/Lower/basic-program.f90 b/flang/test/Lower/basic-program.f90 --- a/flang/test/Lower/basic-program.f90 +++ b/flang/test/Lower/basic-program.f90 @@ -8,6 +8,6 @@ ! CHECK: 1 EndProgramStmt: end program ! CHECK: End Program basic -! FIR-LABEL: func @_QQmain() { +! FIR-LABEL: func @_QQmain() attributes {fir.bindc_name = "basic"} { ! FIR: return ! FIR: } diff --git a/flang/test/Lower/big-integer-parameter.f90 b/flang/test/Lower/big-integer-parameter.f90 --- a/flang/test/Lower/big-integer-parameter.f90 +++ b/flang/test/Lower/big-integer-parameter.f90 @@ -13,7 +13,7 @@ print*,y end -! CHECK-LABEL: func.func @_QQmain() { +! CHECK-LABEL: func.func @_QQmain() attributes {fir.bindc_name = "i128"} { ! CHECK-COUNT-2: %{{.*}} = fir.call @_FortranAioOutputInteger128(%{{.*}}, %{{.*}}) {{.*}}: (!fir.ref, i128) -> i1 diff --git a/flang/test/Lower/derived-type-finalization.f90 b/flang/test/Lower/derived-type-finalization.f90 --- a/flang/test/Lower/derived-type-finalization.f90 +++ b/flang/test/Lower/derived-type-finalization.f90 @@ -212,7 +212,7 @@ print *, 'end of program' end program -! CHECK-LABEL: func.func @_QQmain() { +! CHECK-LABEL: func.func @_QQmain() attributes {fir.bindc_name = "p"} { ! CHECK: %[[T:.*]] = fir.alloca !fir.type<_QMderived_type_finalizationTt1{a:i32}> {bindc_name = "t", uniq_name = "_QFEt"} ! CHECK: cf.cond_br %{{.*}}, ^bb1, ^bb2 ! CHECK: ^bb1: diff --git a/flang/test/Lower/nested-where.f90 b/flang/test/Lower/nested-where.f90 --- a/flang/test/Lower/nested-where.f90 +++ b/flang/test/Lower/nested-where.f90 @@ -1,6 +1,6 @@ ! RUN: bbc -emit-fir %s -o - | FileCheck %s -! CHECK-LABEL: func @_QQmain() { +! CHECK-LABEL: func @_QQmain() attributes {fir.bindc_name = "nested_where"} { program nested_where ! CHECK: %[[VAL_0:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"} diff --git a/flang/test/Lower/polymorphic.f90 b/flang/test/Lower/polymorphic.f90 --- a/flang/test/Lower/polymorphic.f90 +++ b/flang/test/Lower/polymorphic.f90 @@ -945,7 +945,7 @@ l = i < o%inner end program -! CHECK-LABEL: func.func @_QQmain() { +! CHECK-LABEL: func.func @_QQmain() attributes {fir.bindc_name = "test"} { ! CHECK: %[[ADDR_O:.*]] = fir.address_of(@_QFEo) : !fir.ref}>>>> ! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[ADDR_O]] : (!fir.ref}>>>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 diff --git a/flang/test/Lower/program-units-fir-mangling.f90 b/flang/test/Lower/program-units-fir-mangling.f90 --- a/flang/test/Lower/program-units-fir-mangling.f90 +++ b/flang/test/Lower/program-units-fir-mangling.f90 @@ -126,7 +126,7 @@ ! CHECK: } end subroutine -! CHECK-LABEL: func @_QQmain() { +! CHECK-LABEL: func @_QQmain() attributes {fir.bindc_name = "test"} { program test ! CHECK: } contains diff --git a/flang/test/Lower/return-statement.f90 b/flang/test/Lower/return-statement.f90 --- a/flang/test/Lower/return-statement.f90 +++ b/flang/test/Lower/return-statement.f90 @@ -4,7 +4,7 @@ return end program -! CHECK-LABEL: func @_QQmain() { +! CHECK-LABEL: func @_QQmain() attributes {fir.bindc_name = "basic"} { ! CHECK: return ! CHECK: }