[flang-commits] [flang] 4e78f88 - [flang] Lower addresses inside global initializers in HLFIR
Jean Perier via flang-commits
flang-commits at lists.llvm.org
Tue Jan 10 00:33:18 PST 2023
Author: Jean Perier
Date: 2023-01-10T09:32:55+01:00
New Revision: 4e78f88561af26c74b4b7fa2a017cd836a9f9bf4
URL: https://github.com/llvm/llvm-project/commit/4e78f88561af26c74b4b7fa2a017cd836a9f9bf4
DIFF: https://github.com/llvm/llvm-project/commit/4e78f88561af26c74b4b7fa2a017cd836a9f9bf4.diff
LOG: [flang] Lower addresses inside global initializers in HLFIR
Move the code to lower an expression to address or a box in HLFIR from
Bridge.cpp to ConvertExpr.cpp so that it can be used inside
ConvertVariable.cpp (that needs to use a different symbol map that the
one held in the bridge).
Lower NULL to hlfir.null.
This allows lowering derived type constant structure constructors with
pointer components into fir.global.
Differential Revision: https://reviews.llvm.org/D141276
Added:
Modified:
flang/include/flang/Lower/ConvertExprToHLFIR.h
flang/include/flang/Lower/StatementContext.h
flang/lib/Lower/Bridge.cpp
flang/lib/Lower/ConvertExprToHLFIR.cpp
flang/lib/Lower/ConvertVariable.cpp
flang/test/Lower/HLFIR/constant-derived.f90
Removed:
################################################################################
diff --git a/flang/include/flang/Lower/ConvertExprToHLFIR.h b/flang/include/flang/Lower/ConvertExprToHLFIR.h
index abcab29f1457c..fb701660efa5f 100644
--- a/flang/include/flang/Lower/ConvertExprToHLFIR.h
+++ b/flang/include/flang/Lower/ConvertExprToHLFIR.h
@@ -17,6 +17,7 @@
#ifndef FORTRAN_LOWER_CONVERTEXPRTOHLFIR_H
#define FORTRAN_LOWER_CONVERTEXPRTOHLFIR_H
+#include "flang/Lower/StatementContext.h"
#include "flang/Lower/Support/Utils.h"
#include "flang/Optimizer/Builder/FIRBuilder.h"
#include "flang/Optimizer/Builder/HLFIRTools.h"
@@ -29,13 +30,36 @@ class Location;
namespace Fortran::lower {
class AbstractConverter;
-class StatementContext;
class SymMap;
hlfir::EntityWithAttributes
convertExprToHLFIR(mlir::Location loc, Fortran::lower::AbstractConverter &,
const Fortran::lower::SomeExpr &, Fortran::lower::SymMap &,
Fortran::lower::StatementContext &);
+
+inline fir::ExtendedValue
+translateToExtendedValue(mlir::Location loc, fir::FirOpBuilder &builder,
+ hlfir::EntityWithAttributes entity,
+ Fortran::lower::StatementContext &context) {
+ auto [exv, exvCleanup] =
+ hlfir::translateToExtendedValue(loc, builder, entity);
+ if (exvCleanup)
+ context.attachCleanup(*exvCleanup);
+ return exv;
+}
+
+fir::BoxValue convertExprToBox(mlir::Location loc,
+ Fortran::lower::AbstractConverter &,
+ const Fortran::lower::SomeExpr &,
+ Fortran::lower::SymMap &,
+ Fortran::lower::StatementContext &);
+
+// Probably not what you think.
+fir::ExtendedValue convertExprToAddress(mlir::Location loc,
+ Fortran::lower::AbstractConverter &,
+ const Fortran::lower::SomeExpr &,
+ Fortran::lower::SymMap &,
+ Fortran::lower::StatementContext &);
} // namespace Fortran::lower
#endif // FORTRAN_LOWER_CONVERTEXPRTOHLFIR_H
diff --git a/flang/include/flang/Lower/StatementContext.h b/flang/include/flang/Lower/StatementContext.h
index ed8bdc2df165f..9ee304af13073 100644
--- a/flang/include/flang/Lower/StatementContext.h
+++ b/flang/include/flang/Lower/StatementContext.h
@@ -13,6 +13,7 @@
#ifndef FORTRAN_LOWER_STATEMENTCONTEXT_H
#define FORTRAN_LOWER_STATEMENTCONTEXT_H
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include <functional>
#include <optional>
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 9f10ec59a988a..5bddf958d9b2d 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -472,37 +472,14 @@ class FirConverter : public Fortran::lower::AbstractConverter {
return iter->second;
}
- fir::ExtendedValue
- translateToExtendedValue(mlir::Location loc,
- hlfir::EntityWithAttributes entity,
- Fortran::lower::StatementContext &context) {
- auto [exv, exvCleanup] =
- hlfir::translateToExtendedValue(loc, getFirOpBuilder(), entity);
- if (exvCleanup)
- context.attachCleanup(*exvCleanup);
- return exv;
- }
-
fir::ExtendedValue
genExprAddr(const Fortran::lower::SomeExpr &expr,
Fortran::lower::StatementContext &context,
mlir::Location *locPtr = nullptr) override final {
mlir::Location loc = locPtr ? *locPtr : toLocation();
- if (bridge.getLoweringOptions().getLowerToHighLevelFIR()) {
- hlfir::EntityWithAttributes loweredExpr =
- Fortran::lower::convertExprToHLFIR(loc, *this, expr, localSymbols,
- context);
- if (expr.Rank() > 0 &&
- !Fortran::evaluate::IsSimplyContiguous(expr, getFoldingContext()))
- TODO(loc, "genExprAddr of non contiguous variables in HLFIR");
- fir::ExtendedValue exv =
- translateToExtendedValue(loc, loweredExpr, context);
- if (fir::isa_trivial(fir::getBase(exv).getType()))
- TODO(loc, "place trivial in memory");
- if (const auto *mutableBox = exv.getBoxOf<fir::MutableBoxValue>())
- exv = fir::factory::genMutableBoxRead(*builder, loc, *mutableBox);
- return exv;
- }
+ if (bridge.getLoweringOptions().getLowerToHighLevelFIR())
+ return Fortran::lower::convertExprToAddress(loc, *this, expr,
+ localSymbols, context);
return Fortran::lower::createSomeExtendedAddress(loc, *this, expr,
localSymbols, context);
}
@@ -516,8 +493,8 @@ class FirConverter : public Fortran::lower::AbstractConverter {
hlfir::EntityWithAttributes loweredExpr =
Fortran::lower::convertExprToHLFIR(loc, *this, expr, localSymbols,
context);
- fir::ExtendedValue exv =
- translateToExtendedValue(loc, loweredExpr, context);
+ fir::ExtendedValue exv = Fortran::lower::translateToExtendedValue(
+ loc, getFirOpBuilder(), loweredExpr, context);
// Load scalar references to integer, logical, real, or complex value
// to an mlir value, dereference allocatable and pointers, and get rid
// of fir.box that are no needed or create a copy into contiguous memory.
@@ -548,15 +525,9 @@ class FirConverter : public Fortran::lower::AbstractConverter {
fir::ExtendedValue
genExprBox(mlir::Location loc, const Fortran::lower::SomeExpr &expr,
Fortran::lower::StatementContext &stmtCtx) override final {
- if (bridge.getLoweringOptions().getLowerToHighLevelFIR()) {
- hlfir::EntityWithAttributes loweredExpr =
- Fortran::lower::convertExprToHLFIR(loc, *this, expr, localSymbols,
- stmtCtx);
- auto exv = translateToExtendedValue(loc, loweredExpr, stmtCtx);
- if (fir::isa_trivial(fir::getBase(exv).getType()))
- TODO(loc, "place trivial in memory");
- return fir::factory::createBoxValue(getFirOpBuilder(), loc, exv);
- }
+ if (bridge.getLoweringOptions().getLowerToHighLevelFIR())
+ return Fortran::lower::convertExprToBox(loc, *this, expr, localSymbols,
+ stmtCtx);
return Fortran::lower::createBoxValue(loc, *this, expr, localSymbols,
stmtCtx);
}
diff --git a/flang/lib/Lower/ConvertExprToHLFIR.cpp b/flang/lib/Lower/ConvertExprToHLFIR.cpp
index 4b1a54268d028..034ee2a992d73 100644
--- a/flang/lib/Lower/ConvertExprToHLFIR.cpp
+++ b/flang/lib/Lower/ConvertExprToHLFIR.cpp
@@ -21,6 +21,7 @@
#include "flang/Lower/StatementContext.h"
#include "flang/Lower/SymbolMap.h"
#include "flang/Optimizer/Builder/Complex.h"
+#include "flang/Optimizer/Builder/MutableBox.h"
#include "flang/Optimizer/Builder/Runtime/Character.h"
#include "flang/Optimizer/Builder/Todo.h"
#include "flang/Optimizer/HLFIR/HLFIROps.h"
@@ -797,9 +798,12 @@ class HlfirBuilder {
gen(const Fortran::evaluate::BOZLiteralConstant &expr) {
fir::emitFatalError(loc, "BOZ literal must be replaced by semantics");
}
+
hlfir::EntityWithAttributes gen(const Fortran::evaluate::NullPointer &expr) {
- TODO(getLoc(), "lowering NullPointer to HLFIR");
+ auto nullop = getBuilder().create<hlfir::NullOp>(getLoc());
+ return mlir::cast<fir::FortranVariableOpInterface>(nullop.getOperation());
}
+
hlfir::EntityWithAttributes
gen(const Fortran::evaluate::ProcedureDesignator &expr) {
TODO(getLoc(), "lowering ProcDes to HLFIR");
@@ -1024,3 +1028,35 @@ hlfir::EntityWithAttributes Fortran::lower::convertExprToHLFIR(
Fortran::lower::StatementContext &stmtCtx) {
return HlfirBuilder(loc, converter, symMap, stmtCtx).gen(expr);
}
+
+fir::BoxValue Fortran::lower::convertExprToBox(
+ mlir::Location loc, Fortran::lower::AbstractConverter &converter,
+ const Fortran::lower::SomeExpr &expr, Fortran::lower::SymMap &symMap,
+ Fortran::lower::StatementContext &stmtCtx) {
+ hlfir::EntityWithAttributes loweredExpr =
+ HlfirBuilder(loc, converter, symMap, stmtCtx).gen(expr);
+ auto exv = Fortran::lower::translateToExtendedValue(
+ loc, converter.getFirOpBuilder(), loweredExpr, stmtCtx);
+ if (fir::isa_trivial(fir::getBase(exv).getType()))
+ TODO(loc, "place trivial in memory");
+ return fir::factory::createBoxValue(converter.getFirOpBuilder(), loc, exv);
+}
+
+fir::ExtendedValue Fortran::lower::convertExprToAddress(
+ mlir::Location loc, Fortran::lower::AbstractConverter &converter,
+ const Fortran::lower::SomeExpr &expr, Fortran::lower::SymMap &symMap,
+ Fortran::lower::StatementContext &stmtCtx) {
+ hlfir::EntityWithAttributes loweredExpr =
+ HlfirBuilder(loc, converter, symMap, stmtCtx).gen(expr);
+ if (expr.Rank() > 0 && !Fortran::evaluate::IsSimplyContiguous(
+ expr, converter.getFoldingContext()))
+ TODO(loc, "genExprAddr of non contiguous variables in HLFIR");
+ fir::ExtendedValue exv = Fortran::lower::translateToExtendedValue(
+ loc, converter.getFirOpBuilder(), loweredExpr, stmtCtx);
+ if (fir::isa_trivial(fir::getBase(exv).getType()))
+ TODO(loc, "place trivial in memory");
+ if (const auto *mutableBox = exv.getBoxOf<fir::MutableBoxValue>())
+ exv = fir::factory::genMutableBoxRead(converter.getFirOpBuilder(), loc,
+ *mutableBox);
+ return exv;
+}
diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index 084221f3840d6..8cb6dea1363aa 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -163,8 +163,6 @@ hasDerivedTypeWithLengthParameters(const Fortran::semantics::Symbol &sym) {
fir::ExtendedValue Fortran::lower::genExtAddrInInitializer(
Fortran::lower::AbstractConverter &converter, mlir::Location loc,
const Fortran::lower::SomeExpr &addr) {
- if (converter.getLoweringOptions().getLowerToHighLevelFIR())
- TODO(loc, "generate initializer address in HLFIR");
Fortran::lower::SymMap globalOpSymMap;
Fortran::lower::AggregateStoreMap storeMap;
Fortran::lower::StatementContext stmtCtx;
@@ -179,6 +177,10 @@ fir::ExtendedValue Fortran::lower::genExtAddrInInitializer(
Fortran::lower::instantiateVariable(converter, var, globalOpSymMap,
storeMap);
}
+
+ if (converter.getLoweringOptions().getLowerToHighLevelFIR())
+ return Fortran::lower::convertExprToAddress(loc, converter, addr,
+ globalOpSymMap, stmtCtx);
return Fortran::lower::createInitializerAddress(loc, converter, addr,
globalOpSymMap, stmtCtx);
}
@@ -188,8 +190,6 @@ mlir::Value Fortran::lower::genInitialDataTarget(
Fortran::lower::AbstractConverter &converter, mlir::Location loc,
mlir::Type boxType, const Fortran::lower::SomeExpr &initialTarget,
bool couldBeInEquivalence) {
- if (converter.getLoweringOptions().getLowerToHighLevelFIR())
- TODO(loc, "initial data target in HLFIR");
Fortran::lower::SymMap globalOpSymMap;
Fortran::lower::AggregateStoreMap storeMap;
Fortran::lower::StatementContext stmtCtx;
@@ -248,16 +248,23 @@ mlir::Value Fortran::lower::genInitialDataTarget(
mlir::Value targetBox;
mlir::Value targetShift;
- if (initialTarget.Rank() > 0) {
- auto target = Fortran::lower::createSomeArrayBox(converter, initialTarget,
- globalOpSymMap, stmtCtx);
+ if (converter.getLoweringOptions().getLowerToHighLevelFIR()) {
+ auto target = Fortran::lower::convertExprToBox(
+ loc, converter, initialTarget, globalOpSymMap, stmtCtx);
targetBox = fir::getBase(target);
targetShift = builder.createShape(loc, target);
} else {
- fir::ExtendedValue addr = Fortran::lower::createInitializerAddress(
- loc, converter, initialTarget, globalOpSymMap, stmtCtx);
- targetBox = builder.createBox(loc, addr);
- // Nothing to do for targetShift, the target is a scalar.
+ if (initialTarget.Rank() > 0) {
+ auto target = Fortran::lower::createSomeArrayBox(converter, initialTarget,
+ globalOpSymMap, stmtCtx);
+ targetBox = fir::getBase(target);
+ targetShift = builder.createShape(loc, target);
+ } else {
+ fir::ExtendedValue addr = Fortran::lower::createInitializerAddress(
+ loc, converter, initialTarget, globalOpSymMap, stmtCtx);
+ targetBox = builder.createBox(loc, addr);
+ // Nothing to do for targetShift, the target is a scalar.
+ }
}
// The targetBox is a fir.box<T>, not a fir.box<fir.ptr<T>> as it should for
// pointers (this matters to get the POINTER attribute correctly inside the
diff --git a/flang/test/Lower/HLFIR/constant-derived.f90 b/flang/test/Lower/HLFIR/constant-derived.f90
index 4da714ebfcbeb..62d5079b57206 100644
--- a/flang/test/Lower/HLFIR/constant-derived.f90
+++ b/flang/test/Lower/HLFIR/constant-derived.f90
@@ -1,5 +1,4 @@
! Test lowering of Constant<SomeDerived>.
-! TODO: remove "-I nowhere" once derived type descriptor can be lowered.
! RUN: bbc -hlfir -emit-fir -o - -I nowhere %s 2>&1 | FileCheck %s
subroutine test_constant_scalar()
@@ -14,6 +13,17 @@ subroutine test_constant_scalar()
! CHECK: fir.address_of(@[[CST:_QQro._QFtest_constant_scalarTmyderived..*]])
end subroutine
+subroutine test_constant_scalar_ptr_component()
+ type myderived
+ real, pointer :: x
+ real, pointer :: y(:)
+ end type
+ real, target, save :: targ(100)
+ call test(myderived(NULL(), targ(1:50:5)))
+! CHECK-LABEL: func.func @_QPtest_constant_scalar_ptr_component() {
+! CHECK: fir.address_of(@[[CST_TARGET:_QQro._QFtest_constant_scalar_ptr_componentTmyderived..*]])
+end subroutine
+
! CHECK: fir.global internal @[[CST]] constant : !fir.type<[[DERIVED:_QFtest_constant_scalarTmyderived{i:i32,j:i32,x:!fir.array<2xf32>,c:!fir.char<1,10>}]]> {
! CHECK: %[[VAL_0:.*]] = fir.undefined !fir.type<[[DERIVED]]>
! CHECK: %[[VAL_1:.*]] = fir.field_index i, !fir.type<[[DERIVED]]>
@@ -36,3 +46,26 @@ subroutine test_constant_scalar()
! CHECK: %[[VAL_18:.*]] = fir.insert_value %[[VAL_14]], %[[VAL_16]], ["c", !fir.type<[[DERIVED]]>] : (!fir.type<[[DERIVED]]>, !fir.char<1,10>) -> !fir.type<[[DERIVED]]>
! CHECK: fir.has_value %[[VAL_18]] : !fir.type<[[DERIVED]]>
! CHECK: }
+
+! CHECK: fir.global internal @[[CST_TARGET]] constant :
+! CHECK-SAME: !fir.type<[[DERIVED_2:_QFtest_constant_scalar_ptr_componentTmyderived{x:!fir.box<!fir.ptr<f32>>,y:!fir.box<!fir.ptr<!fir.array<\?xf32>>>}]]> {
+! CHECK: %[[VAL_0:.*]] = fir.undefined !fir.type<[[DERIVED_2]]>
+! CHECK: %[[VAL_1:.*]] = fir.field_index x, !fir.type<[[DERIVED_2]]>
+! CHECK: %[[VAL_2:.*]] = fir.zero_bits !fir.ptr<f32>
+! CHECK: %[[VAL_3:.*]] = fir.embox %[[VAL_2]] : (!fir.ptr<f32>) -> !fir.box<!fir.ptr<f32>>
+! CHECK: %[[VAL_4:.*]] = fir.insert_value %[[VAL_0]], %[[VAL_3]], ["x", !fir.type<[[DERIVED_2]]>] : (!fir.type<[[DERIVED_2]]>, !fir.box<!fir.ptr<f32>>) -> !fir.type<[[DERIVED_2]]>
+! CHECK: %[[VAL_5:.*]] = fir.field_index y, !fir.type<[[DERIVED_2]]>
+! CHECK: %[[VAL_6:.*]] = fir.address_of(@_QFtest_constant_scalar_ptr_componentEtarg) : !fir.ref<!fir.array<100xf32>>
+! CHECK: %[[VAL_7:.*]] = arith.constant 100 : index
+! CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_7]] : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_6]](%[[VAL_8]])
+! CHECK: %[[VAL_11:.*]] = arith.constant 1 : index
+! CHECK: %[[VAL_13:.*]] = arith.constant 50 : index
+! CHECK: %[[VAL_15:.*]] = arith.constant 5 : index
+! CHECK: %[[VAL_16:.*]] = arith.constant 10 : index
+! CHECK: %[[VAL_17:.*]] = fir.shape %[[VAL_16]] : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_18:.*]] = hlfir.designate %[[VAL_9]]#0 (%[[VAL_11]]:%[[VAL_13]]:%[[VAL_15]]) shape %[[VAL_17]] : (!fir.ref<!fir.array<100xf32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<10xf32>>
+! CHECK: %[[VAL_19:.*]] = fir.rebox %[[VAL_18]] : (!fir.box<!fir.array<10xf32>>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
+! CHECK: %[[VAL_20:.*]] = fir.insert_value %[[VAL_4]], %[[VAL_19]], ["y", !fir.type<[[DERIVED_2]]>] : (!fir.type<[[DERIVED_2]]>, !fir.box<!fir.ptr<!fir.array<?xf32>>>) -> !fir.type<[[DERIVED_2]]>
+! CHECK: fir.has_value %[[VAL_20]] : !fir.type<[[DERIVED_2]]>
+! CHECK: }
More information about the flang-commits
mailing list