mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-26 13:26:22 +00:00
[flang] Allow conversion from hlfir.expr to fir::ExtendedValue
For now at least, the plan is to keep hlfir.expr usage limited as sub-expression operand, assignment rhs, and a few other contexts ( e.g. Associate statements). The rest of lowering (statements lowering in the bridge) will still expect to get and manipulate characters and arrays in memory. That means that hlfir.expr must be converted to variable in converter.genExprAddr/converter.genExprBox. This is done using an hlfir.associate, and generating the related hlfir.end_associate in the statement context. hlfir::getFirBase of is updated to avoid bringing in the HLFIR fir.boxchar/fir.box into FIR when the entity was created with hlfir::AssociateOp. Differential Revision: https://reviews.llvm.org/D139328
This commit is contained in:
parent
bda1f0b96c
commit
788960d628
@ -508,12 +508,16 @@ public:
|
||||
hlfir::EntityWithAttributes 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");
|
||||
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;
|
||||
}
|
||||
return Fortran::lower::createSomeExtendedAddress(loc, *this, expr,
|
||||
localSymbols, context);
|
||||
@ -564,14 +568,10 @@ public:
|
||||
hlfir::EntityWithAttributes 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");
|
||||
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);
|
||||
}
|
||||
return Fortran::lower::createBoxValue(loc, *this, expr, localSymbols,
|
||||
stmtCtx);
|
||||
|
@ -76,16 +76,28 @@ hlfir::translateToExtendedValue(mlir::Location loc, fir::FirOpBuilder &builder,
|
||||
if (entity.isVariable())
|
||||
TODO(loc, "HLFIR variable to fir::ExtendedValue without a "
|
||||
"FortranVariableOpInterface");
|
||||
if (entity.getType().isa<hlfir::ExprType>())
|
||||
TODO(loc, "hlfir.expr to fir::ExtendedValue"); // use hlfir.associate
|
||||
if (entity.getType().isa<hlfir::ExprType>()) {
|
||||
hlfir::AssociateOp associate = hlfir::genAssociateExpr(
|
||||
loc, builder, entity, entity.getType(), "adapt.valuebyref");
|
||||
auto *bldr = &builder;
|
||||
hlfir::CleanupFunction cleanup = [bldr, loc, associate]() -> void {
|
||||
bldr->create<hlfir::EndAssociateOp>(loc, associate);
|
||||
};
|
||||
hlfir::Entity temp{associate.getBase()};
|
||||
return {translateToExtendedValue(loc, builder, temp).first, cleanup};
|
||||
}
|
||||
return {{static_cast<mlir::Value>(entity)}, {}};
|
||||
}
|
||||
|
||||
mlir::Value hlfir::Entity::getFirBase() const {
|
||||
if (fir::FortranVariableOpInterface variable = getIfVariableInterface())
|
||||
if (fir::FortranVariableOpInterface variable = getIfVariableInterface()) {
|
||||
if (auto declareOp =
|
||||
mlir::dyn_cast<hlfir::DeclareOp>(variable.getOperation()))
|
||||
return declareOp.getOriginalBase();
|
||||
if (auto associateOp =
|
||||
mlir::dyn_cast<hlfir::AssociateOp>(variable.getOperation()))
|
||||
return associateOp.getFirBase();
|
||||
}
|
||||
return getBase();
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ end subroutine
|
||||
! CHECK-LABEL: func.func @_QPcall_int_arg_expr() {
|
||||
! CHECK: %[[VAL_0:.*]] = arith.constant 42 : i32
|
||||
! CHECK: %[[VAL_1:.*]]:3 = hlfir.associate %[[VAL_0]] {uniq_name = "adapt.valuebyref"} : (i32) -> (!fir.ref<i32>, !fir.ref<i32>, i1)
|
||||
! CHECK: fir.call @_QPtake_i4(%[[VAL_1]]#0) fastmath<contract> : (!fir.ref<i32>) -> ()
|
||||
! CHECK: fir.call @_QPtake_i4(%[[VAL_1]]#1) fastmath<contract> : (!fir.ref<i32>) -> ()
|
||||
! CHECK: hlfir.end_associate %[[VAL_1]]#1, %[[VAL_1]]#2 : !fir.ref<i32>, i1
|
||||
|
||||
subroutine call_real_arg_expr()
|
||||
@ -36,7 +36,7 @@ end subroutine
|
||||
! CHECK-LABEL: func.func @_QPcall_real_arg_expr() {
|
||||
! CHECK: %[[VAL_0:.*]] = arith.constant 4.200000e-01 : f32
|
||||
! CHECK: %[[VAL_1:.*]]:3 = hlfir.associate %[[VAL_0]] {uniq_name = "adapt.valuebyref"} : (f32) -> (!fir.ref<f32>, !fir.ref<f32>, i1)
|
||||
! CHECK: fir.call @_QPtake_r4(%[[VAL_1]]#0) fastmath<contract> : (!fir.ref<f32>) -> ()
|
||||
! CHECK: fir.call @_QPtake_r4(%[[VAL_1]]#1) fastmath<contract> : (!fir.ref<f32>) -> ()
|
||||
! CHECK: hlfir.end_associate %[[VAL_1]]#1, %[[VAL_1]]#2 : !fir.ref<f32>, i1
|
||||
|
||||
subroutine call_real_arg_var(x)
|
||||
@ -64,7 +64,7 @@ end subroutine
|
||||
! CHECK: %[[VAL_0:.*]] = arith.constant true
|
||||
! CHECK: %[[VAL_1:.*]] = fir.convert %[[VAL_0]] : (i1) -> !fir.logical<4>
|
||||
! CHECK: %[[VAL_2:.*]]:3 = hlfir.associate %[[VAL_1]] {uniq_name = "adapt.valuebyref"} : (!fir.logical<4>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>, i1)
|
||||
! CHECK: fir.call @_QPtake_l4(%[[VAL_2]]#0) fastmath<contract> : (!fir.ref<!fir.logical<4>>) -> ()
|
||||
! CHECK: fir.call @_QPtake_l4(%[[VAL_2]]#1) fastmath<contract> : (!fir.ref<!fir.logical<4>>) -> ()
|
||||
! CHECK: hlfir.end_associate %[[VAL_2]]#1, %[[VAL_2]]#2 : !fir.ref<!fir.logical<4>>, i1
|
||||
|
||||
subroutine call_logical_arg_expr_2()
|
||||
@ -74,7 +74,7 @@ end subroutine
|
||||
! CHECK: %[[VAL_0:.*]] = arith.constant true
|
||||
! CHECK: %[[VAL_1:.*]] = fir.convert %[[VAL_0]] : (i1) -> !fir.logical<8>
|
||||
! CHECK: %[[VAL_2:.*]]:3 = hlfir.associate %[[VAL_1]] {uniq_name = "adapt.valuebyref"} : (!fir.logical<8>) -> (!fir.ref<!fir.logical<8>>, !fir.ref<!fir.logical<8>>, i1)
|
||||
! CHECK: fir.call @_QPtake_l8(%[[VAL_2]]#0) fastmath<contract> : (!fir.ref<!fir.logical<8>>) -> ()
|
||||
! CHECK: fir.call @_QPtake_l8(%[[VAL_2]]#1) fastmath<contract> : (!fir.ref<!fir.logical<8>>) -> ()
|
||||
! CHECK: hlfir.end_associate %[[VAL_2]]#1, %[[VAL_2]]#2 : !fir.ref<!fir.logical<8>>, i1
|
||||
|
||||
subroutine call_char_arg_var(x)
|
||||
|
@ -10,3 +10,16 @@ subroutine foo(x)
|
||||
! CHECK: %[[x_cast:.*]] = fir.convert %[[x]]#1 : (!fir.ref<i32>) -> !fir.ref<i64>
|
||||
! CHECK: fir.call @_FortranAioInputInteger(%{{.*}}, %[[x_cast]], %{{.*}}) {{.*}}: (!fir.ref<i8>, !fir.ref<i64>, i32) -> i1
|
||||
end subroutine
|
||||
|
||||
subroutine expr_to_var(c)
|
||||
character(*) :: c
|
||||
print *, c//c
|
||||
end subroutine
|
||||
|
||||
! CHECK-LABEL: func.func @_QPexpr_to_var(
|
||||
! CHECK: %[[VAL_9:.*]] = hlfir.concat %{{.*}}, %{{.*}} len %[[VAL_8:.*]] : (!fir.boxchar<1>, !fir.boxchar<1>, index) -> !hlfir.expr<!fir.char<1,?>>
|
||||
! CHECK: %[[VAL_10:.*]]:3 = hlfir.associate %[[VAL_9]] typeparams %[[VAL_8]] {uniq_name = "adapt.valuebyref"} : (!hlfir.expr<!fir.char<1,?>>, index) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>, i1)
|
||||
! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_10]]#1 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
|
||||
! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_8]] : (index) -> i64
|
||||
! CHECK: %[[VAL_13:.*]] = fir.call @_FortranAioOutputAscii(%{{.*}}, %[[VAL_11]], %[[VAL_12]]) {{.*}} : (!fir.ref<i8>, !fir.ref<i8>, i64) -> i1
|
||||
! CHECK: hlfir.end_associate %[[VAL_10]]#1, %[[VAL_10]]#2 : !fir.ref<!fir.char<1,?>>, i1
|
||||
|
Loading…
x
Reference in New Issue
Block a user