Skip to content

Commit 0345444

Browse files
Refactor the hlfir declare utility for clarity
1 parent aeed3ec commit 0345444

File tree

3 files changed

+37
-32
lines changed

3 files changed

+37
-32
lines changed

flang/lib/Optimizer/Dialect/FIROps.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1542,8 +1542,7 @@ bool fir::ConvertOp::canBeConverted(mlir::Type inType, mlir::Type outType) {
15421542
// 1. passing an entity to an external function and there's nothing we can do
15431543
// about volatility after that happens, or
15441544
// 2. for code generation, at which point we represent volatility with
1545-
// attributes
1546-
// on the LLVM instructions and intrinsics.
1545+
// attributes on the LLVM instructions and intrinsics.
15471546
//
15481547
// For all other cases, volatility ought to match exactly.
15491548
static mlir::LogicalResult verifyVolatility(mlir::Type inType,

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

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -207,34 +207,37 @@ static bool hasExplicitLowerBounds(mlir::Value shape) {
207207
mlir::isa<fir::ShapeShiftType, fir::ShiftType>(shape.getType());
208208
}
209209

210-
static std::pair<mlir::Type, mlir::Value> updateDeclaredInputTypeWithVolatility(
211-
mlir::Type inputType, mlir::Value memref, mlir::OpBuilder &builder,
212-
fir::FortranVariableFlagsAttr fortran_attrs) {
213-
if (fortran_attrs &&
214-
bitEnumContainsAny(fortran_attrs.getFlags(),
215-
fir::FortranVariableFlagsEnum::fortran_volatile)) {
216-
// A volatile pointer's pointee is volatile.
217-
const bool isPointer = bitEnumContainsAny(
218-
fortran_attrs.getFlags(), fir::FortranVariableFlagsEnum::pointer);
219-
// An allocatable's inner type's volatility matches that of the reference.
220-
const bool isAllocatable = bitEnumContainsAny(
221-
fortran_attrs.getFlags(), fir::FortranVariableFlagsEnum::allocatable);
222-
auto updateType = [&](auto t) {
223-
using FIRT = decltype(t);
224-
auto elementType = t.getEleTy();
225-
const bool elementTypeIsBox = mlir::isa<fir::BoxType>(elementType);
226-
const bool elementTypeIsVolatile = isPointer || isAllocatable ||
227-
elementTypeIsBox ||
228-
fir::isa_volatile_type(elementType);
229-
auto newEleTy =
230-
fir::updateTypeWithVolatility(elementType, elementTypeIsVolatile);
231-
inputType = FIRT::get(newEleTy, true);
232-
};
233-
llvm::TypeSwitch<mlir::Type>(inputType)
234-
.Case<fir::ReferenceType, fir::BoxType, fir::ClassType>(updateType);
235-
memref =
236-
builder.create<fir::VolatileCastOp>(memref.getLoc(), inputType, memref);
210+
static std::pair<mlir::Type, mlir::Value>
211+
updateDeclaredInputTypeWithVolatility(mlir::Type inputType, mlir::Value memref,
212+
mlir::OpBuilder &builder,
213+
fir::FortranVariableFlagsEnum flags) {
214+
if (!bitEnumContainsAny(flags,
215+
fir::FortranVariableFlagsEnum::fortran_volatile)) {
216+
return std::make_pair(inputType, memref);
237217
}
218+
219+
// A volatile pointer's pointee is volatile.
220+
const bool isPointer =
221+
bitEnumContainsAny(flags, fir::FortranVariableFlagsEnum::pointer);
222+
// An allocatable's inner type's volatility matches that of the reference.
223+
const bool isAllocatable =
224+
bitEnumContainsAny(flags, fir::FortranVariableFlagsEnum::allocatable);
225+
226+
auto updateType = [&](auto t) {
227+
using FIRT = decltype(t);
228+
auto elementType = t.getEleTy();
229+
const bool elementTypeIsBox = mlir::isa<fir::BaseBoxType>(elementType);
230+
const bool elementTypeIsVolatile = isPointer || isAllocatable ||
231+
elementTypeIsBox ||
232+
fir::isa_volatile_type(elementType);
233+
auto newEleTy =
234+
fir::updateTypeWithVolatility(elementType, elementTypeIsVolatile);
235+
inputType = FIRT::get(newEleTy, true);
236+
};
237+
llvm::TypeSwitch<mlir::Type>(inputType)
238+
.Case<fir::ReferenceType, fir::BoxType, fir::ClassType>(updateType);
239+
memref =
240+
builder.create<fir::VolatileCastOp>(memref.getLoc(), inputType, memref);
238241
return std::make_pair(inputType, memref);
239242
}
240243

@@ -248,8 +251,11 @@ void hlfir::DeclareOp::build(mlir::OpBuilder &builder,
248251
auto nameAttr = builder.getStringAttr(uniq_name);
249252
mlir::Type inputType = memref.getType();
250253
bool hasExplicitLbs = hasExplicitLowerBounds(shape);
251-
std::tie(inputType, memref) = updateDeclaredInputTypeWithVolatility(
252-
inputType, memref, builder, fortran_attrs);
254+
if (fortran_attrs) {
255+
const auto flags = fortran_attrs.getFlags();
256+
std::tie(inputType, memref) = updateDeclaredInputTypeWithVolatility(
257+
inputType, memref, builder, flags);
258+
}
253259
mlir::Type hlfirVariableType =
254260
getHLFIRVariableType(inputType, hasExplicitLbs);
255261
build(builder, result, {hlfirVariableType, inputType}, memref, shape,

flang/test/Fir/invalid.fir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1260,7 +1260,7 @@ func.func @dc_invalid_reduction(%arg0: index, %arg1: index) {
12601260

12611261
// Should fail when volatility changes from a fir.convert
12621262
func.func @bad_convert_volatile(%arg0: !fir.ref<i32>) -> !fir.ref<i32, volatile> {
1263-
// expected-error@+1 {{op this conversion does not preserve volatilit}}
1263+
// expected-error@+1 {{op this conversion does not preserve volatility}}
12641264
%0 = fir.convert %arg0 : (!fir.ref<i32>) -> !fir.ref<i32, volatile>
12651265
return %0 : !fir.ref<i32, volatile>
12661266
}

0 commit comments

Comments
 (0)