Skip to content

Commit ed657c6

Browse files
committed
[flang][HLFIR] add skip_rebox option to hlfir.declare
1 parent a798a10 commit ed657c6

File tree

5 files changed

+37
-5
lines changed

5 files changed

+37
-5
lines changed

flang/include/flang/Optimizer/HLFIR/HLFIROps.td

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ def hlfir_DeclareOp
7373
local lower bound values. It is intended to be used when generating FIR
7474
from HLFIR in order to avoid descriptor creation for simple entities.
7575

76+
The attribute skip_rebox can be set to indicate that the second and first
77+
result are known to be the same descriptors (the input descriptor is known
78+
to already have the correct attributes and lower bounds).
79+
7680
Example:
7781

7882
CHARACTER(n) :: c(10:n, 20:n)
@@ -98,14 +102,16 @@ def hlfir_DeclareOp
98102
DefaultValuedAttr<UI64Attr, "0">:$storage_offset,
99103
Builtin_StringAttr:$uniq_name,
100104
OptionalAttr<fir_FortranVariableFlagsAttr>:$fortran_attrs,
101-
OptionalAttr<cuf_DataAttributeAttr>:$data_attr);
105+
OptionalAttr<cuf_DataAttributeAttr>:$data_attr,
106+
OptionalAttr<UnitAttr>:$skip_rebox);
102107

103108
let results = (outs AnyFortranVariable, AnyRefOrBoxLike);
104109

105110
let assemblyFormat = [{
106111
$memref (`(` $shape^ `)`)? (`typeparams` $typeparams^)?
107112
(`dummy_scope` $dummy_scope^)?
108113
(`storage` `(` $storage^ `[` $storage_offset `]` `)`)?
114+
(`skip_rebox` $skip_rebox^)?
109115
attr-dict `:` functional-type(operands, results)
110116
}];
111117

flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ void hlfir::DeclareOp::build(mlir::OpBuilder &builder,
281281
getDeclareOutputTypes(inputType, hasExplicitLbs);
282282
build(builder, result, {hlfirVariableType, firVarType}, memref, shape,
283283
typeparams, dummy_scope, storage, storage_offset, nameAttr,
284-
fortran_attrs, data_attr);
284+
fortran_attrs, data_attr, /*skip_rebox=*/mlir::UnitAttr{});
285285
}
286286

287287
llvm::LogicalResult hlfir::DeclareOp::verify() {
@@ -294,6 +294,9 @@ llvm::LogicalResult hlfir::DeclareOp::verify() {
294294
return emitOpError("first result type is inconsistent with variable "
295295
"properties: expected ")
296296
<< hlfirVariableType;
297+
if (getSkipRebox() && !llvm::isa<fir::BaseBoxType>(getMemref().getType()))
298+
return emitOpError(
299+
"skip_rebox attribute must only be set when the input is a box");
297300
// The rest of the argument verification is done by the
298301
// FortranVariableInterface verifier.
299302
auto fortranVar =

flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "flang/Optimizer/HLFIR/HLFIROps.h"
2424
#include "flang/Optimizer/HLFIR/Passes.h"
2525
#include "mlir/Transforms/DialectConversion.h"
26+
#include "llvm/ADT/SmallSet.h"
2627

2728
namespace hlfir {
2829
#define GEN_PASS_DEF_CONVERTHLFIRTOFIR
@@ -312,10 +313,12 @@ class DeclareOpConversion : public mlir::OpRewritePattern<hlfir::DeclareOp> {
312313
// Propagate other attributes from hlfir.declare to fir.declare.
313314
// OpenACC's acc.declare is one example. Right now, the propagation
314315
// is verbatim.
315-
mlir::NamedAttrList elidedAttrs =
316-
mlir::NamedAttrList{firDeclareOp->getAttrs()};
316+
llvm::SmallSet<llvm::StringRef, 8> elidedAttrs;
317+
for (const mlir::NamedAttribute &firAttr : firDeclareOp->getAttrs())
318+
elidedAttrs.insert(firAttr.getName());
319+
elidedAttrs.insert(declareOp.getSkipReboxAttrName());
317320
for (const mlir::NamedAttribute &attr : declareOp->getAttrs())
318-
if (!elidedAttrs.get(attr.getName()))
321+
if (!elidedAttrs.contains(attr.getName()))
319322
firDeclareOp->setAttr(attr.getName(), attr.getValue());
320323

321324
auto firBase = firDeclareOp.getResult();
@@ -328,6 +331,8 @@ class DeclareOpConversion : public mlir::OpRewritePattern<hlfir::DeclareOp> {
328331
auto genHlfirBox = [&]() -> mlir::Value {
329332
if (auto baseBoxType =
330333
mlir::dyn_cast<fir::BaseBoxType>(firBase.getType())) {
334+
if (declareOp.getSkipRebox())
335+
return firBase;
331336
// Rebox so that lower bounds and attributes are correct.
332337
if (baseBoxType.isAssumedRank())
333338
return fir::ReboxAssumedRankOp::create(

flang/test/HLFIR/declare-codegen.fir

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,15 @@ func.func @array_declare_box_2(%arg0: !fir.box<!fir.array<?x?xf32>>) {
124124
// CHECK: %[[VAL_1:.*]] = fir.declare %[[VAL_0]] {uniq_name = "x"} : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<!fir.array<?x?xf32>>
125125
// CHECK: %[[VAL_2:.*]] = fir.rebox %[[VAL_1]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<!fir.array<?x?xf32>>
126126

127+
func.func @array_declare_box_3(%arg0: !fir.box<!fir.array<?x?xf32>>) -> !fir.box<!fir.array<?x?xf32>> {
128+
%0:2 = hlfir.declare %arg0 skip_rebox {uniq_name = "x"} : (!fir.box<!fir.array<?x?xf32>>) -> (!fir.box<!fir.array<?x?xf32>>, !fir.box<!fir.array<?x?xf32>>)
129+
return %0#0 : !fir.box<!fir.array<?x?xf32>>
130+
}
131+
// CHECK-LABEL: func.func @array_declare_box_3(
132+
// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?x?xf32>>) -> !fir.box<!fir.array<?x?xf32>> {
133+
// CHECK: %[[VAL_1:.*]] = fir.declare %[[VAL_0]] {uniq_name = "x"} : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<!fir.array<?x?xf32>>
134+
// CHECK: return %[[VAL_1]]
135+
127136
func.func @array_declare_char_box(%arg0: !fir.box<!fir.array<?x?x!fir.char<1,?>>>) {
128137
%0:2 = hlfir.declare %arg0 {uniq_name = "x"} : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, !fir.box<!fir.array<?x?x!fir.char<1,?>>>)
129138
return

flang/test/HLFIR/invalid.fir

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,15 @@ func.func @bad_array_declare(%arg0: !fir.ref<!fir.array<?x?xf32>>) {
3636
return
3737
}
3838

39+
// -----
40+
func.func @bad_declare_skip_rebox(%arg0: !fir.ref<f32>) {
41+
// expected-error@+1 {{'hlfir.declare' op skip_rebox attribute must only be set when the input is a box}}
42+
%0:2 = hlfir.declare %arg0 skip_rebox {uniq_name = "x"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
43+
return
44+
}
45+
46+
// -----
47+
3948
// -----
4049
func.func @bad_assign_scalar_character(%arg0: !fir.boxchar<1>, %arg1: !fir.char<1,?>) {
4150
// expected-error@+1 {{'hlfir.assign' op operand #0 must be any Fortran value or variable type, but got '!fir.char<1,?>'}}

0 commit comments

Comments
 (0)