[flang] Add kernel to lower expressions to HLFIR
This patch adds the kernel to lower evaluate::Expr to HLFIR to a
hlfir::FortranEntity (a single mlir::Value that can be interpreted as
a Fortran variable or the value of a Fortram expression).
It implements lowering of simple name designators ("x") and starts
adding a translation layer in AbstractConverter::genExprBox and
AbstractConverter::genExprAddr so that the new expression lowering
can be used without any changes for now in the current statement and
construct lowering.
Differential Revision: https://reviews.llvm.org/D136453
This commit is contained in:
parent
b7c922607c
commit
c14ef2d762
42
flang/include/flang/Lower/ConvertExprToHLFIR.h
Normal file
42
flang/include/flang/Lower/ConvertExprToHLFIR.h
Normal file
@ -0,0 +1,42 @@
|
||||
//===-- Lower/ConvertExprToHLFIR.h -- lowering of expressions ----*- C++-*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// Implements the conversion from Fortran::evaluate::Expr trees to HLFIR.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef FORTRAN_LOWER_CONVERTEXPRTOHLFIR_H
|
||||
#define FORTRAN_LOWER_CONVERTEXPRTOHLFIR_H
|
||||
|
||||
#include "flang/Lower/Support/Utils.h"
|
||||
#include "flang/Optimizer/Builder/FIRBuilder.h"
|
||||
#include "flang/Optimizer/Builder/HLFIRTools.h"
|
||||
#include "flang/Optimizer/Dialect/FIRDialect.h"
|
||||
|
||||
namespace mlir {
|
||||
class Location;
|
||||
} // namespace mlir
|
||||
|
||||
namespace Fortran::lower {
|
||||
|
||||
class AbstractConverter;
|
||||
class StatementContext;
|
||||
class SymMap;
|
||||
|
||||
hlfir::FortranEntity convertExprToHLFIR(mlir::Location loc,
|
||||
Fortran::lower::AbstractConverter &,
|
||||
const Fortran::lower::SomeExpr &,
|
||||
Fortran::lower::SymMap &,
|
||||
Fortran::lower::StatementContext &);
|
||||
} // namespace Fortran::lower
|
||||
|
||||
#endif // FORTRAN_LOWER_CONVERTEXPRTOHLFIR_H
|
||||
@ -348,6 +348,9 @@ public:
|
||||
symbolMapStack.back().try_emplace(sym, definingOp);
|
||||
}
|
||||
|
||||
llvm::Optional<fir::FortranVariableOpInterface>
|
||||
lookupVariableDefinition(semantics::SymbolRef sym);
|
||||
|
||||
private:
|
||||
/// Add `symbol` to the current map and bind a `box`.
|
||||
void makeSym(semantics::SymbolRef symRef, const SymbolBox &box,
|
||||
|
||||
@ -561,6 +561,10 @@ mlir::Value genMaxWithZero(fir::FirOpBuilder &builder, mlir::Location loc,
|
||||
mlir::Value genCPtrOrCFunptrAddr(fir::FirOpBuilder &builder, mlir::Location loc,
|
||||
mlir::Value cPtr, mlir::Type ty);
|
||||
|
||||
/// Create a fir.box from a fir::ExtendedValue and wrap it in a fir::BoxValue
|
||||
/// to keep all the lower bound and explicit parameter information.
|
||||
fir::BoxValue createBoxValue(fir::FirOpBuilder &builder, mlir::Location loc,
|
||||
const fir::ExtendedValue &exv);
|
||||
} // namespace fir::factory
|
||||
|
||||
#endif // FORTRAN_OPTIMIZER_BUILDER_FIRBUILDER_H
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
#include "flang/Lower/CallInterface.h"
|
||||
#include "flang/Lower/Coarray.h"
|
||||
#include "flang/Lower/ConvertExpr.h"
|
||||
#include "flang/Lower/ConvertExprToHLFIR.h"
|
||||
#include "flang/Lower/ConvertType.h"
|
||||
#include "flang/Lower/ConvertVariable.h"
|
||||
#include "flang/Lower/HostAssociations.h"
|
||||
@ -416,16 +417,35 @@ public:
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
fir::ExtendedValue
|
||||
translateToExtendedValue(mlir::Location loc, hlfir::FortranEntity 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())
|
||||
TODO(loc, "lower expr to HLFIR address");
|
||||
if (bridge.getLoweringOptions().getLowerToHighLevelFIR()) {
|
||||
hlfir::FortranEntity loweredExpr = Fortran::lower::convertExprToHLFIR(
|
||||
loc, *this, expr, localSymbols, context);
|
||||
if (fir::FortranVariableOpInterface variable =
|
||||
loweredExpr.getIfVariable())
|
||||
if (!variable.isBox())
|
||||
return translateToExtendedValue(loc, loweredExpr, context);
|
||||
TODO(loc, "lower expr that is not a scalar or explicit shape array "
|
||||
"variable to HLFIR address");
|
||||
}
|
||||
return Fortran::lower::createSomeExtendedAddress(loc, *this, expr,
|
||||
localSymbols, context);
|
||||
}
|
||||
|
||||
fir::ExtendedValue
|
||||
genExprValue(const Fortran::lower::SomeExpr &expr,
|
||||
Fortran::lower::StatementContext &context,
|
||||
@ -440,8 +460,18 @@ public:
|
||||
fir::ExtendedValue
|
||||
genExprBox(mlir::Location loc, const Fortran::lower::SomeExpr &expr,
|
||||
Fortran::lower::StatementContext &stmtCtx) override final {
|
||||
if (bridge.getLoweringOptions().getLowerToHighLevelFIR())
|
||||
TODO(loc, "lower expr to HLFIR box");
|
||||
if (bridge.getLoweringOptions().getLowerToHighLevelFIR()) {
|
||||
hlfir::FortranEntity loweredExpr = Fortran::lower::convertExprToHLFIR(
|
||||
loc, *this, expr, localSymbols, stmtCtx);
|
||||
if (fir::FortranVariableOpInterface variable =
|
||||
loweredExpr.getIfVariable())
|
||||
if (variable.isBoxValue() || !variable.isBoxAddress()) {
|
||||
auto exv = translateToExtendedValue(loc, loweredExpr, stmtCtx);
|
||||
return fir::factory::createBoxValue(getFirOpBuilder(), loc, exv);
|
||||
}
|
||||
TODO(loc,
|
||||
"lower expression value or pointer and allocatable to HLFIR box");
|
||||
}
|
||||
return Fortran::lower::createBoxValue(loc, *this, expr, localSymbols,
|
||||
stmtCtx);
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ add_flang_library(FortranLower
|
||||
CallInterface.cpp
|
||||
Coarray.cpp
|
||||
ConvertExpr.cpp
|
||||
ConvertExprToHLFIR.cpp
|
||||
ConvertType.cpp
|
||||
ConvertVariable.cpp
|
||||
ComponentPath.cpp
|
||||
@ -28,6 +29,7 @@ add_flang_library(FortranLower
|
||||
FIRBuilder
|
||||
FIRSupport
|
||||
FIRTransforms
|
||||
HLFIRDialect
|
||||
${dialect_libs}
|
||||
|
||||
LINK_LIBS
|
||||
@ -35,6 +37,7 @@ add_flang_library(FortranLower
|
||||
FIRBuilder
|
||||
FIRSupport
|
||||
FIRTransforms
|
||||
HLFIRDialect
|
||||
${dialect_libs}
|
||||
FortranCommon
|
||||
FortranParser
|
||||
|
||||
195
flang/lib/Lower/ConvertExprToHLFIR.cpp
Normal file
195
flang/lib/Lower/ConvertExprToHLFIR.cpp
Normal file
@ -0,0 +1,195 @@
|
||||
//===-- ConvertExprToHLFIR.cpp --------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "flang/Lower/ConvertExprToHLFIR.h"
|
||||
#include "flang/Lower/AbstractConverter.h"
|
||||
#include "flang/Lower/StatementContext.h"
|
||||
#include "flang/Lower/SymbolMap.h"
|
||||
#include "flang/Optimizer/Builder/Todo.h"
|
||||
|
||||
namespace {
|
||||
|
||||
/// Lower Designators to HLFIR.
|
||||
class HlfirDesignatorBuilder {
|
||||
public:
|
||||
HlfirDesignatorBuilder(mlir::Location loc,
|
||||
Fortran::lower::AbstractConverter &converter,
|
||||
Fortran::lower::SymMap &symMap,
|
||||
Fortran::lower::StatementContext &stmtCtx)
|
||||
: converter{converter}, symMap{symMap}, stmtCtx{stmtCtx}, loc{loc} {}
|
||||
|
||||
// Character designators variant contains substrings
|
||||
using CharacterDesignators =
|
||||
decltype(Fortran::evaluate::Designator<Fortran::evaluate::Type<
|
||||
Fortran::evaluate::TypeCategory::Character, 1>>::u);
|
||||
hlfir::FortranEntity gen(const CharacterDesignators &designatorVariant) {
|
||||
return std::visit([&](const auto &x) { return gen(x); }, designatorVariant);
|
||||
}
|
||||
// Character designators variant contains complex parts
|
||||
using RealDesignators =
|
||||
decltype(Fortran::evaluate::Designator<Fortran::evaluate::Type<
|
||||
Fortran::evaluate::TypeCategory::Real, 4>>::u);
|
||||
hlfir::FortranEntity gen(const RealDesignators &designatorVariant) {
|
||||
return std::visit([&](const auto &x) { return gen(x); }, designatorVariant);
|
||||
}
|
||||
// All other designators are similar
|
||||
using OtherDesignators =
|
||||
decltype(Fortran::evaluate::Designator<Fortran::evaluate::Type<
|
||||
Fortran::evaluate::TypeCategory::Integer, 4>>::u);
|
||||
hlfir::FortranEntity gen(const OtherDesignators &designatorVariant) {
|
||||
return std::visit([&](const auto &x) { return gen(x); }, designatorVariant);
|
||||
}
|
||||
|
||||
private:
|
||||
hlfir::FortranEntity gen(const Fortran::evaluate::SymbolRef &symbolRef) {
|
||||
if (llvm::Optional<fir::FortranVariableOpInterface> varDef =
|
||||
getSymMap().lookupVariableDefinition(symbolRef))
|
||||
return *varDef;
|
||||
TODO(getLoc(), "lowering symbol to HLFIR");
|
||||
}
|
||||
hlfir::FortranEntity gen(const Fortran::evaluate::Component &component) {
|
||||
TODO(getLoc(), "lowering component to HLFIR");
|
||||
}
|
||||
hlfir::FortranEntity gen(const Fortran::evaluate::ArrayRef &arrayRef) {
|
||||
TODO(getLoc(), "lowering ArrayRef to HLFIR");
|
||||
}
|
||||
hlfir::FortranEntity gen(const Fortran::evaluate::CoarrayRef &coarrayRef) {
|
||||
TODO(getLoc(), "lowering CoarrayRef to HLFIR");
|
||||
}
|
||||
hlfir::FortranEntity gen(const Fortran::evaluate::ComplexPart &complexPart) {
|
||||
TODO(getLoc(), "lowering complex part to HLFIR");
|
||||
}
|
||||
hlfir::FortranEntity gen(const Fortran::evaluate::Substring &substring) {
|
||||
TODO(getLoc(), "lowering substrings to HLFIR");
|
||||
}
|
||||
|
||||
mlir::Location getLoc() const { return loc; }
|
||||
Fortran::lower::AbstractConverter &getConverter() { return converter; }
|
||||
fir::FirOpBuilder &getBuilder() { return converter.getFirOpBuilder(); }
|
||||
Fortran::lower::SymMap &getSymMap() { return symMap; }
|
||||
Fortran::lower::StatementContext &getStmtCtx() { return stmtCtx; }
|
||||
|
||||
Fortran::lower::AbstractConverter &converter;
|
||||
Fortran::lower::SymMap &symMap;
|
||||
Fortran::lower::StatementContext &stmtCtx;
|
||||
mlir::Location loc;
|
||||
};
|
||||
|
||||
/// Lower Expr to HLFIR.
|
||||
class HlfirBuilder {
|
||||
public:
|
||||
HlfirBuilder(mlir::Location loc, Fortran::lower::AbstractConverter &converter,
|
||||
Fortran::lower::SymMap &symMap,
|
||||
Fortran::lower::StatementContext &stmtCtx)
|
||||
: converter{converter}, symMap{symMap}, stmtCtx{stmtCtx}, loc{loc} {}
|
||||
|
||||
template <typename T>
|
||||
hlfir::FortranEntity gen(const Fortran::evaluate::Expr<T> &expr) {
|
||||
return std::visit([&](const auto &x) { return gen(x); }, expr.u);
|
||||
}
|
||||
|
||||
private:
|
||||
hlfir::FortranEntity gen(const Fortran::evaluate::BOZLiteralConstant &expr) {
|
||||
fir::emitFatalError(loc, "BOZ literal must be replaced by semantics");
|
||||
}
|
||||
hlfir::FortranEntity gen(const Fortran::evaluate::NullPointer &expr) {
|
||||
TODO(getLoc(), "lowering NullPointer to HLFIR");
|
||||
}
|
||||
hlfir::FortranEntity gen(const Fortran::evaluate::ProcedureDesignator &expr) {
|
||||
TODO(getLoc(), "lowering ProcDes to HLFIR");
|
||||
}
|
||||
hlfir::FortranEntity gen(const Fortran::evaluate::ProcedureRef &expr) {
|
||||
TODO(getLoc(), "lowering ProcRef to HLFIR");
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
hlfir::FortranEntity gen(const Fortran::evaluate::Designator<T> &designator) {
|
||||
return HlfirDesignatorBuilder(getLoc(), getConverter(), getSymMap(),
|
||||
getStmtCtx())
|
||||
.gen(designator.u);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
hlfir::FortranEntity gen(const Fortran::evaluate::FunctionRef<T> &expr) {
|
||||
TODO(getLoc(), "lowering funcRef to HLFIR");
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
hlfir::FortranEntity gen(const Fortran::evaluate::Constant<T> &expr) {
|
||||
TODO(getLoc(), "lowering constant to HLFIR");
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
hlfir::FortranEntity gen(const Fortran::evaluate::ArrayConstructor<T> &expr) {
|
||||
TODO(getLoc(), "lowering ArrayCtor to HLFIR");
|
||||
}
|
||||
|
||||
template <Fortran::common::TypeCategory TC1, int KIND,
|
||||
Fortran::common::TypeCategory TC2>
|
||||
hlfir::FortranEntity
|
||||
gen(const Fortran::evaluate::Convert<Fortran::evaluate::Type<TC1, KIND>, TC2>
|
||||
&convert) {
|
||||
TODO(getLoc(), "lowering convert to HLFIR");
|
||||
}
|
||||
|
||||
template <typename D, typename R, typename O>
|
||||
hlfir::FortranEntity gen(const Fortran::evaluate::Operation<D, R, O> &op) {
|
||||
TODO(getLoc(), "lowering unary op to HLFIR");
|
||||
}
|
||||
|
||||
template <typename D, typename R, typename LO, typename RO>
|
||||
hlfir::FortranEntity
|
||||
gen(const Fortran::evaluate::Operation<D, R, LO, RO> &op) {
|
||||
TODO(getLoc(), "lowering binary op to HLFIR");
|
||||
}
|
||||
|
||||
hlfir::FortranEntity
|
||||
gen(const Fortran::evaluate::Relational<Fortran::evaluate::SomeType> &op) {
|
||||
return std::visit([&](const auto &x) { return gen(x); }, op.u);
|
||||
}
|
||||
|
||||
hlfir::FortranEntity gen(const Fortran::evaluate::TypeParamInquiry &) {
|
||||
TODO(getLoc(), "lowering type parameter inquiry to HLFIR");
|
||||
}
|
||||
|
||||
hlfir::FortranEntity gen(const Fortran::evaluate::DescriptorInquiry &desc) {
|
||||
TODO(getLoc(), "lowering descriptor inquiry to HLFIR");
|
||||
}
|
||||
|
||||
hlfir::FortranEntity gen(const Fortran::evaluate::ImpliedDoIndex &var) {
|
||||
TODO(getLoc(), "lowering implied do index to HLFIR");
|
||||
}
|
||||
|
||||
hlfir::FortranEntity gen(const Fortran::evaluate::StructureConstructor &var) {
|
||||
TODO(getLoc(), "lowering structure constructor to HLFIR");
|
||||
}
|
||||
|
||||
mlir::Location getLoc() const { return loc; }
|
||||
Fortran::lower::AbstractConverter &getConverter() { return converter; }
|
||||
fir::FirOpBuilder &getBuilder() { return converter.getFirOpBuilder(); }
|
||||
Fortran::lower::SymMap &getSymMap() { return symMap; }
|
||||
Fortran::lower::StatementContext &getStmtCtx() { return stmtCtx; }
|
||||
|
||||
Fortran::lower::AbstractConverter &converter;
|
||||
Fortran::lower::SymMap &symMap;
|
||||
Fortran::lower::StatementContext &stmtCtx;
|
||||
mlir::Location loc;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
hlfir::FortranEntity Fortran::lower::convertExprToHLFIR(
|
||||
mlir::Location loc, Fortran::lower::AbstractConverter &converter,
|
||||
const Fortran::lower::SomeExpr &expr, Fortran::lower::SymMap &symMap,
|
||||
Fortran::lower::StatementContext &stmtCtx) {
|
||||
return HlfirBuilder(loc, converter, symMap, stmtCtx).gen(expr);
|
||||
}
|
||||
@ -1359,7 +1359,7 @@ static void genDeclareSymbol(Fortran::lower::AbstractConverter &converter,
|
||||
auto newBase = builder.create<fir::DeclareOp>(
|
||||
loc, base.getType(), base, shapeOrShift, lenParams, name, attributes);
|
||||
base = newBase;
|
||||
symMap.addVariableDefinition(sym, newBase);
|
||||
symMap.addVariableDefinition(sym, newBase, force);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -90,6 +90,22 @@ Fortran::lower::SymMap::lookupImpliedDo(Fortran::lower::SymMap::AcDoVar var) {
|
||||
return {};
|
||||
}
|
||||
|
||||
llvm::Optional<fir::FortranVariableOpInterface>
|
||||
Fortran::lower::SymMap::lookupVariableDefinition(semantics::SymbolRef sym) {
|
||||
for (auto jmap = symbolMapStack.rbegin(), jend = symbolMapStack.rend();
|
||||
jmap != jend; ++jmap) {
|
||||
auto iter = jmap->find(&*sym);
|
||||
if (iter != jmap->end()) {
|
||||
if (const auto *varDef =
|
||||
std::get_if<fir::FortranVariableOpInterface>(&iter->second))
|
||||
return *varDef;
|
||||
else
|
||||
return llvm::None;
|
||||
}
|
||||
}
|
||||
return llvm::None;
|
||||
}
|
||||
|
||||
llvm::raw_ostream &
|
||||
Fortran::lower::operator<<(llvm::raw_ostream &os,
|
||||
const Fortran::lower::SymbolBox &symBox) {
|
||||
|
||||
@ -1323,3 +1323,30 @@ mlir::Value fir::factory::genCPtrOrCFunptrAddr(fir::FirOpBuilder &builder,
|
||||
return builder.create<fir::CoordinateOp>(loc, builder.getRefType(fieldTy),
|
||||
cPtr, field);
|
||||
}
|
||||
|
||||
fir::BoxValue fir::factory::createBoxValue(fir::FirOpBuilder &builder,
|
||||
mlir::Location loc,
|
||||
const fir::ExtendedValue &exv) {
|
||||
if (auto *boxValue = exv.getBoxOf<fir::BoxValue>())
|
||||
return *boxValue;
|
||||
mlir::Value box = builder.createBox(loc, exv);
|
||||
llvm::SmallVector<mlir::Value> lbounds;
|
||||
llvm::SmallVector<mlir::Value> explicitTypeParams;
|
||||
exv.match(
|
||||
[&](const fir::ArrayBoxValue &box) {
|
||||
lbounds.append(box.getLBounds().begin(), box.getLBounds().end());
|
||||
},
|
||||
[&](const fir::CharArrayBoxValue &box) {
|
||||
lbounds.append(box.getLBounds().begin(), box.getLBounds().end());
|
||||
explicitTypeParams.emplace_back(box.getLen());
|
||||
},
|
||||
[&](const fir::CharBoxValue &box) {
|
||||
explicitTypeParams.emplace_back(box.getLen());
|
||||
},
|
||||
[&](const fir::MutableBoxValue &x) {
|
||||
explicitTypeParams.append(x.nonDeferredLenParams().begin(),
|
||||
x.nonDeferredLenParams().end());
|
||||
},
|
||||
[](const auto &) {});
|
||||
return fir::BoxValue(box, lbounds, explicitTypeParams);
|
||||
}
|
||||
|
||||
@ -1,8 +1,12 @@
|
||||
! Test lowering of of expressions as address
|
||||
! RUN: %not_todo_cmd bbc -emit-fir -hlfir -o - %s 2>&1 | FileCheck %s
|
||||
! RUN: bbc -emit-fir -hlfir -o - %s 2>&1 | FileCheck %s
|
||||
|
||||
! CHECK-LABEL: func.func @_QPfoo(
|
||||
! CHECK-SAME: %[[arg0:.*]]: !fir.ref<i32>
|
||||
subroutine foo(x)
|
||||
integer :: x
|
||||
! CHECK: not yet implemented: lower expr to HLFIR address
|
||||
read (*,*) x
|
||||
! CHECK: %[[x:.]] = fir.declare %[[arg0]] {uniq_name = "_QFfooEx"} : (!fir.ref<i32>) -> !fir.ref<i32>
|
||||
! CHECK: %[[x_cast:.*]] = fir.convert %[[x]] : (!fir.ref<i32>) -> !fir.ref<i64>
|
||||
! CHECK: fir.call @_FortranAioInputInteger(%{{.*}}, %[[x_cast]], %{{.*}}) : (!fir.ref<i8>, !fir.ref<i64>, i32) -> i1
|
||||
end subroutine
|
||||
|
||||
@ -1,8 +1,14 @@
|
||||
! Test lowering of of expressions as fir.box
|
||||
! RUN: %not_todo_cmd bbc -emit-fir -hlfir -o - %s 2>&1 | FileCheck %s
|
||||
! RUN: bbc -hlfir -o - %s 2>&1 | FileCheck %s
|
||||
|
||||
! CHECK-LABEL: func.func @_QPfoo(
|
||||
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<10xi32>>
|
||||
subroutine foo(x)
|
||||
integer :: x(:)
|
||||
! CHECK: not yet implemented: generate fir.declare for box
|
||||
integer :: x(21:30)
|
||||
print *, x
|
||||
! CHECK-DAG: %[[VAL_3:.*]] = arith.constant 21 : index
|
||||
! CHECK-DAG: %[[VAL_4:.*]] = arith.constant 10 : index
|
||||
! CHECK: %[[VAL_5:.*]] = fir.shape_shift %[[VAL_4]], %[[VAL_3]] : (index, index) -> !fir.shapeshift<1>
|
||||
! CHECK: %[[VAL_6:.*]] = fir.declare %[[VAL_0]](%[[VAL_5]]) {uniq_name = "_QFfooEx"} : (!fir.ref<!fir.array<10xi32>>, !fir.shapeshift<1>) -> !fir.ref<!fir.array<10xi32>>
|
||||
! CHECK: fir.embox %[[VAL_6]](%[[VAL_5]]) : (!fir.ref<!fir.array<10xi32>>, !fir.shapeshift<1>) -> !fir.box<!fir.array<10xi32>>
|
||||
end subroutine
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user