[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