Skip to content

Commit ecec131

Browse files
authored
[flang] Remove double pointer indirection for _QQEnvironmentDefaults (#90615)
A double pointer was being passed to the call to FortranStart rather than just a pointer to the EnvironmentDefaults.list. This now passes `null` directly when there's no EnvironmentDefaults.list and passes the list directly when there is, removing the original global variable which was a pointer to a pointer containing null or the EnvironmentDefaults.list global. Fixes #90537
1 parent 0232b77 commit ecec131

File tree

8 files changed

+37
-50
lines changed

8 files changed

+37
-50
lines changed

flang/include/flang/Optimizer/Builder/Runtime/EnvironmentDefaults.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class GlobalOp;
2727

2828
namespace mlir {
2929
class Location;
30+
class Value;
3031
} // namespace mlir
3132

3233
namespace Fortran::lower {
@@ -38,7 +39,7 @@ namespace fir::runtime {
3839
/// Create the list of environment variable defaults for the runtime to set. The
3940
/// form of the generated list is defined in the runtime header file
4041
/// environment-default-list.h
41-
fir::GlobalOp genEnvironmentDefaults(
42+
mlir::Value genEnvironmentDefaults(
4243
fir::FirOpBuilder &builder, mlir::Location loc,
4344
const std::vector<Fortran::lower::EnvironmentDefault> &envDefaults);
4445

flang/include/flang/Optimizer/Builder/Runtime/Main.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
#ifndef FORTRAN_OPTIMIZER_BUILDER_RUNTIME_MAIN_H
1010
#define FORTRAN_OPTIMIZER_BUILDER_RUNTIME_MAIN_H
1111

12+
#include "flang/Lower/EnvironmentDefault.h"
13+
#include <vector>
14+
1215
namespace mlir {
1316
class Location;
1417
} // namespace mlir
@@ -21,8 +24,7 @@ class GlobalOp;
2124
namespace fir::runtime {
2225

2326
void genMain(fir::FirOpBuilder &builder, mlir::Location loc,
24-
fir::GlobalOp &env);
25-
27+
const std::vector<Fortran::lower::EnvironmentDefault> &defs);
2628
}
2729

2830
#endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_MAIN_H

flang/lib/Lower/Bridge.cpp

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -348,22 +348,11 @@ class FirConverter : public Fortran::lower::AbstractConverter {
348348
createGlobalOutsideOfFunctionLowering(
349349
[&]() { typeInfoConverter.createTypeInfo(*this); });
350350

351-
// Create the list of any environment defaults for the runtime to set. The
352-
// runtime default list is only created if there is a main program to ensure
353-
// it only happens once and to provide consistent results if multiple files
354-
// are compiled separately.
351+
// Generate the `main` entry point if necessary
355352
if (hasMainProgram)
356353
createGlobalOutsideOfFunctionLowering([&]() {
357-
// FIXME: Ideally, this would create a call to a runtime function
358-
// accepting the list of environment defaults. That way, we would not
359-
// need to add an extern pointer to the runtime and said pointer would
360-
// not need to be generated even if no defaults are specified.
361-
// However, generating main or changing when the runtime reads
362-
// environment variables is required to do so.
363-
auto env = fir::runtime::genEnvironmentDefaults(
364-
*builder, toLocation(), bridge.getEnvironmentDefaults());
365-
366-
fir::runtime::genMain(*builder, toLocation(), env);
354+
fir::runtime::genMain(*builder, toLocation(),
355+
bridge.getEnvironmentDefaults());
367356
});
368357

369358
finalizeOpenACCLowering();

flang/lib/Optimizer/Builder/Runtime/EnvironmentDefaults.cpp

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#include "flang/Optimizer/Support/InternalNames.h"
1414
#include "llvm/ADT/ArrayRef.h"
1515

16-
fir::GlobalOp fir::runtime::genEnvironmentDefaults(
16+
mlir::Value fir::runtime::genEnvironmentDefaults(
1717
fir::FirOpBuilder &builder, mlir::Location loc,
1818
const std::vector<Fortran::lower::EnvironmentDefault> &envDefaults) {
1919
std::string envDefaultListPtrName =
@@ -34,13 +34,8 @@ fir::GlobalOp fir::runtime::genEnvironmentDefaults(
3434

3535
// If no defaults were specified, initialize with a null pointer.
3636
if (envDefaults.empty()) {
37-
return builder.createGlobalConstant(
38-
loc, envDefaultListRefTy, envDefaultListPtrName,
39-
[&](fir::FirOpBuilder &builder) {
40-
mlir::Value nullVal =
41-
builder.createNullConstant(loc, envDefaultListRefTy);
42-
builder.create<fir::HasValueOp>(loc, nullVal);
43-
});
37+
mlir::Value nullVal = builder.createNullConstant(loc, envDefaultListRefTy);
38+
return nullVal;
4439
}
4540

4641
// Create the Item list.
@@ -98,11 +93,7 @@ fir::GlobalOp fir::runtime::genEnvironmentDefaults(
9893
envDefaultListBuilder, linkOnce);
9994

10095
// Define the pointer to the list used by the runtime.
101-
return builder.createGlobalConstant(
102-
loc, envDefaultListRefTy, envDefaultListPtrName,
103-
[&](fir::FirOpBuilder &builder) {
104-
mlir::Value addr = builder.create<fir::AddrOfOp>(
105-
loc, envDefaultList.resultType(), envDefaultList.getSymbol());
106-
builder.create<fir::HasValueOp>(loc, addr);
107-
});
96+
mlir::Value addr = builder.create<fir::AddrOfOp>(
97+
loc, envDefaultList.resultType(), envDefaultList.getSymbol());
98+
return addr;
10899
}

flang/lib/Optimizer/Builder/Runtime/Main.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "flang/Optimizer/Builder/Runtime/Main.h"
10+
#include "flang/Lower/EnvironmentDefault.h"
1011
#include "flang/Optimizer/Builder/BoxValue.h"
1112
#include "flang/Optimizer/Builder/FIRBuilder.h"
13+
#include "flang/Optimizer/Builder/Runtime/EnvironmentDefaults.h"
1214
#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
1315
#include "flang/Optimizer/Dialect/FIROps.h"
1416
#include "flang/Optimizer/Dialect/FIRType.h"
@@ -18,8 +20,9 @@
1820
using namespace Fortran::runtime;
1921

2022
/// Create a `int main(...)` that calls the Fortran entry point
21-
void fir::runtime::genMain(fir::FirOpBuilder &builder, mlir::Location loc,
22-
fir::GlobalOp &env) {
23+
void fir::runtime::genMain(
24+
fir::FirOpBuilder &builder, mlir::Location loc,
25+
const std::vector<Fortran::lower::EnvironmentDefault> &defs) {
2326
auto *context = builder.getContext();
2427
auto argcTy = builder.getDefaultIntegerType();
2528
auto ptrTy = mlir::LLVM::LLVMPointerType::get(context);
@@ -48,10 +51,14 @@ void fir::runtime::genMain(fir::FirOpBuilder &builder, mlir::Location loc,
4851
mlir::OpBuilder::InsertionGuard insertGuard(builder);
4952
builder.setInsertionPointToStart(block);
5053

54+
// Create the list of any environment defaults for the runtime to set. The
55+
// runtime default list is only created if there is a main program to ensure
56+
// it only happens once and to provide consistent results if multiple files
57+
// are compiled separately.
58+
auto env = fir::runtime::genEnvironmentDefaults(builder, loc, defs);
59+
5160
llvm::SmallVector<mlir::Value, 4> args(block->getArguments());
52-
auto envAddr =
53-
builder.create<fir::AddrOfOp>(loc, env.getType(), env.getSymbol());
54-
args.push_back(envAddr);
61+
args.push_back(env);
5562

5663
builder.create<fir::CallOp>(loc, startFn, args);
5764
builder.create<fir::CallOp>(loc, qqMainFn);

flang/test/Driver/emit-mlir.f90

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,12 @@
1515
! CHECK-LABEL: func @_QQmain() {
1616
! CHECK-NEXT: return
1717
! CHECK-NEXT: }
18-
! CHECK-NEXT: fir.global @_QQEnvironmentDefaults constant : !fir.ref<tuple<i[[int_size:.*]], !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>> {
19-
! CHECK-NEXT: %[[VAL_0:.*]] = fir.zero_bits !fir.ref<tuple<i[[int_size]], !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>
20-
! CHECK-NEXT: fir.has_value %[[VAL_0]] : !fir.ref<tuple<i[[int_size]], !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>
21-
! CHECK-NEXT: }
2218
! CHECK-NEXT: func.func private @_FortranAProgramStart(i32, !llvm.ptr, !llvm.ptr, !llvm.ptr)
2319
! CHECK-NEXT: func.func private @_FortranAProgramEndStatement()
2420
! CHECK-NEXT: func.func @main(%arg0: i32, %arg1: !llvm.ptr, %arg2: !llvm.ptr) -> i32 {
2521
! CHECK-NEXT: %c0_i32 = arith.constant 0 : i32
26-
! CHECK-NEXT: %0 = fir.address_of(@_QQEnvironmentDefaults) : !fir.ref<tuple<i32, !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>
27-
! CHECK-NEXT: ir.call @_FortranAProgramStart(%arg0, %arg1, %arg2, %0) {{.*}} : (i32, !llvm.ptr, !llvm.ptr, !fir.ref<tuple<i32, !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>)
22+
! CHECK-NEXT: %0 = fir.zero_bits !fir.ref<tuple<i32, !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>
23+
! CHECK-NEXT: fir.call @_FortranAProgramStart(%arg0, %arg1, %arg2, %0) {{.*}} : (i32, !llvm.ptr, !llvm.ptr, !fir.ref<tuple<i32, !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>)
2824
! CHECK-NEXT: fir.call @_QQmain() fastmath<contract> : () -> ()
2925
! CHECK-NEXT: fir.call @_FortranAProgramEndStatement() {{.*}} : () -> ()
3026
! CHECK-NEXT: return %c0_i32 : i32

flang/test/Lower/convert.f90

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ program test
1111
! Try to test that -fconvert=<value> flag results in a environment default list
1212
! with the FORT_CONVERT option correctly specified.
1313

14+
! ALL: %0 = fir.address_of(@_QQEnvironmentDefaults.list) : !fir.ref<tuple<i32, !fir.ref<!fir.array<1xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>
15+
! ALL: fir.call @_FortranAProgramStart(%arg0, %arg1, %arg2, %0)
16+
1417
! ALL: fir.global linkonce @_QQEnvironmentDefaults.items constant : !fir.array<1xtuple<!fir.ref<i8>, !fir.ref<i8>>> {
1518
! ALL: %[[VAL_0:.*]] = fir.undefined !fir.array<1xtuple<!fir.ref<i8>, !fir.ref<i8>>>
1619
! ALL: %[[VAL_1:.*]] = fir.address_of(@[[FC_STR:.*]]) : !fir.ref<!fir.char<1,13>>
@@ -41,6 +44,3 @@ program test
4144
! ALL: %[[VAL_4:.*]] = fir.insert_value %[[VAL_2]], %[[VAL_3]], [1 : index] : (tuple<i[[int_size]], !fir.ref<!fir.array<1xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>, !fir.ref<!fir.array<1xtuple<!fir.ref<i8>, !fir.ref<i8>>>>) -> tuple<i[[int_size]], !fir.ref<!fir.array<1xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>
4245
! ALL: fir.has_value %[[VAL_4]] : tuple<i[[int_size]], !fir.ref<!fir.array<1xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>
4346

44-
! ALL: fir.global @_QQEnvironmentDefaults constant : !fir.ref<tuple<i[[int_size]], !fir.ref<!fir.array<1xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>> {
45-
! ALL: %[[VAL_0:.*]] = fir.address_of(@_QQEnvironmentDefaults.list) : !fir.ref<tuple<i[[int_size]], !fir.ref<!fir.array<1xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>
46-
! ALL: fir.has_value %[[VAL_0]] : !fir.ref<tuple<i[[int_size]], !fir.ref<!fir.array<1xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>

flang/test/Lower/environment-defaults.f90

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ program test
55
continue
66
end
77

8-
! Test that a null pointer is generated for environment defaults if nothing is specified
8+
! Test that a null pointer is passed for environment defaults if nothing is specified
99

10-
! CHECK: fir.global @_QQEnvironmentDefaults constant : !fir.ref<tuple<i[[int_size:.*]], !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>> {
11-
! CHECK: %[[VAL_0:.*]] = fir.zero_bits !fir.ref<tuple<i[[int_size]], !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>
12-
! CHECK: fir.has_value %[[VAL_0]] : !fir.ref<tuple<i[[int_size]], !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>
10+
! CHECK-NOT: @_QQEnvironmentDefaults
11+
12+
! CHECK: %0 = fir.zero_bits !fir.ref<tuple<i32, !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>
13+
! CHECK-NEXT: @_FortranAProgramStart(%arg0, %arg1, %arg2, %0)

0 commit comments

Comments
 (0)