Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
ronlieb authored Mar 3, 2025
2 parents 665b4f6 + 3ea28c9 commit 49d15cc
Show file tree
Hide file tree
Showing 74 changed files with 975 additions and 1,245 deletions.
86 changes: 86 additions & 0 deletions flang/include/flang/Optimizer/Dialect/FIROps.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,95 @@ struct DebuggingResource
mlir::StringRef getName() final { return "DebuggingResource"; }
};

class CoordinateIndicesAdaptor;
using IntOrValue = llvm::PointerUnion<mlir::IntegerAttr, mlir::Value>;

} // namespace fir

#define GET_OP_CLASSES
#include "flang/Optimizer/Dialect/FIROps.h.inc"

namespace fir {
class CoordinateIndicesAdaptor {
public:
using value_type = IntOrValue;

CoordinateIndicesAdaptor(mlir::DenseI32ArrayAttr fieldIndices,
mlir::ValueRange values)
: fieldIndices(fieldIndices), values(values) {}

value_type operator[](size_t index) const {
assert(index < size() && "index out of bounds");
return *std::next(begin(), index);
}

size_t size() const {
return fieldIndices ? fieldIndices.size() : values.size();
}

bool empty() const {
return values.empty() && (!fieldIndices || fieldIndices.empty());
}

class iterator
: public llvm::iterator_facade_base<iterator, std::forward_iterator_tag,
value_type, std::ptrdiff_t,
value_type *, value_type> {
public:
iterator(const CoordinateIndicesAdaptor *base,
std::optional<llvm::ArrayRef<int32_t>::iterator> fieldIter,
llvm::detail::IterOfRange<const mlir::ValueRange> valuesIter)
: base(base), fieldIter(fieldIter), valuesIter(valuesIter) {}

value_type operator*() const {
if (fieldIter && **fieldIter != fir::CoordinateOp::kDynamicIndex) {
return mlir::IntegerAttr::get(base->fieldIndices.getElementType(),
**fieldIter);
}
return *valuesIter;
}

iterator &operator++() {
if (fieldIter) {
if (**fieldIter == fir::CoordinateOp::kDynamicIndex)
valuesIter++;
(*fieldIter)++;
} else {
valuesIter++;
}
return *this;
}

bool operator==(const iterator &rhs) const {
return base == rhs.base && fieldIter == rhs.fieldIter &&
valuesIter == rhs.valuesIter;
}

private:
const CoordinateIndicesAdaptor *base;
std::optional<llvm::ArrayRef<int32_t>::const_iterator> fieldIter;
llvm::detail::IterOfRange<const mlir::ValueRange> valuesIter;
};

iterator begin() const {
std::optional<llvm::ArrayRef<int32_t>::const_iterator> fieldIter;
if (fieldIndices)
fieldIter = fieldIndices.asArrayRef().begin();
return iterator(this, fieldIter, values.begin());
}

iterator end() const {
std::optional<llvm::ArrayRef<int32_t>::const_iterator> fieldIter;
if (fieldIndices)
fieldIter = fieldIndices.asArrayRef().end();
return iterator(this, fieldIter, values.end());
}

private:
mlir::DenseI32ArrayAttr fieldIndices;
mlir::ValueRange values;
};

} // namespace fir

#endif // FORTRAN_OPTIMIZER_DIALECT_FIROPS_H
19 changes: 15 additions & 4 deletions flang/include/flang/Optimizer/Dialect/FIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -1748,10 +1748,16 @@ def fir_CoordinateOp : fir_Op<"coordinate_of", [NoMemoryEffect]> {
Unlike LLVM's GEP instruction, one cannot stride over the outermost
reference; therefore, the leading 0 index must be omitted.

This operation can be used to index derived type fields, in which case
the operand is the name of the index field.

```
%i = ... : index
%h = ... : !fir.heap<!fir.array<100 x f32>>
%p = fir.coordinate_of %h, %i : (!fir.heap<!fir.array<100 x f32>>, index) -> !fir.ref<f32>

%d = ... : !fir.ref<!fir.type<t{field1:i32, field2:f32}>>
%f = fir.coordinate_of %d, field2 : (!fir.ref<!fir.type<t{field1:i32, field2:f32}>>) -> !fir.ref<f32>
```

In the example, `%p` will be a pointer to the `%i`-th f32 value in the
Expand All @@ -1761,7 +1767,8 @@ def fir_CoordinateOp : fir_Op<"coordinate_of", [NoMemoryEffect]> {
let arguments = (ins
AnyRefOrBox:$ref,
Variadic<AnyCoordinateType>:$coor,
TypeAttr:$baseType
TypeAttr:$baseType,
OptionalAttr<DenseI32ArrayAttr>:$field_indices
);

let results = (outs RefOrLLVMPtr);
Expand All @@ -1771,10 +1778,14 @@ def fir_CoordinateOp : fir_Op<"coordinate_of", [NoMemoryEffect]> {

let builders = [
OpBuilder<(ins "mlir::Type":$resultType,
"mlir::Value":$ref, "mlir::ValueRange":$coor),
[{ return build($_builder, $_state, resultType, ref, coor,
mlir::TypeAttr::get(ref.getType())); }]>,
"mlir::Value":$ref, "mlir::ValueRange":$coor)>,
OpBuilder<(ins "mlir::Type":$resultType,
"mlir::Value":$ref, "llvm::ArrayRef<fir::IntOrValue>":$coor)>
];
let extraClassDeclaration = [{
constexpr static int32_t kDynamicIndex = std::numeric_limits<int32_t>::min();
CoordinateIndicesAdaptor getIndices();
}];
}

def fir_ExtractValueOp : fir_OneResultOp<"extract_value", [NoMemoryEffect]> {
Expand Down
10 changes: 4 additions & 6 deletions flang/lib/Lower/OpenMP/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -359,14 +359,12 @@ mlir::Value createParentSymAndGenIntermediateMaps(
// type.
if (fir::RecordType recordType = mlir::dyn_cast<fir::RecordType>(
fir::unwrapPassByRefType(curValue.getType()))) {
mlir::Value idxConst = firOpBuilder.createIntegerConstant(
clauseLocation, firOpBuilder.getIndexType(),
indices[currentIndicesIdx]);
mlir::Type memberTy =
recordType.getTypeList().at(indices[currentIndicesIdx]).second;
fir::IntOrValue idxConst = mlir::IntegerAttr::get(
firOpBuilder.getI32Type(), indices[currentIndicesIdx]);
mlir::Type memberTy = recordType.getType(indices[currentIndicesIdx]);
curValue = firOpBuilder.create<fir::CoordinateOp>(
clauseLocation, firOpBuilder.getRefType(memberTy), curValue,
idxConst);
llvm::SmallVector<fir::IntOrValue, 1>{idxConst});

// Skip mapping and the subsequent load if we're the final member or not
// a type with a descriptor such as a pointer/allocatable. If we're a
Expand Down
5 changes: 3 additions & 2 deletions flang/lib/Optimizer/CodeGen/BoxedProcedure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -348,8 +348,9 @@ class BoxedProcedurePass
rewriter.setInsertionPoint(coor);
auto toTy = typeConverter.convertType(ty);
auto toBaseTy = typeConverter.convertType(baseTy);
rewriter.replaceOpWithNewOp<CoordinateOp>(coor, toTy, coor.getRef(),
coor.getCoor(), toBaseTy);
rewriter.replaceOpWithNewOp<CoordinateOp>(
coor, toTy, coor.getRef(), coor.getCoor(), toBaseTy,
coor.getFieldIndicesAttr());
opIsValid = false;
}
} else if (auto index = mlir::dyn_cast<FieldIndexOp>(op)) {
Expand Down
Loading

0 comments on commit 49d15cc

Please sign in to comment.