[flang-commits] [flang] fd8b2d2 - [flang] lower RANK intrinsic (#93694)
via flang-commits
flang-commits at lists.llvm.org
Thu May 30 02:02:13 PDT 2024
Author: jeanPerier
Date: 2024-05-30T11:02:09+02:00
New Revision: fd8b2d2046508c027ccf0fffb50d665c8355997a
URL: https://github.com/llvm/llvm-project/commit/fd8b2d2046508c027ccf0fffb50d665c8355997a
DIFF: https://github.com/llvm/llvm-project/commit/fd8b2d2046508c027ccf0fffb50d665c8355997a.diff
LOG: [flang] lower RANK intrinsic (#93694)
First commit is reviewed in
https://github.com/llvm/llvm-project/pull/93682.
Lower RANK using fir.box_rank. This patches updates fir.box_rank to
accept box reference, this avoids the need of generating an assumed-rank
fir.load just for the sake of reading ALLOCATABLE/POINTER rank. The
fir.load would generate a "dynamic" memcpy that is hard to optimize
without further knowledge. A read effect is conditionally given to the
operation.
Added:
Modified:
flang/include/flang/Optimizer/Builder/HLFIRTools.h
flang/include/flang/Optimizer/Dialect/FIROps.td
flang/lib/Lower/ConvertExprToHLFIR.cpp
flang/lib/Optimizer/Builder/HLFIRTools.cpp
flang/lib/Optimizer/CodeGen/CodeGen.cpp
flang/lib/Optimizer/Dialect/FIROps.cpp
flang/test/Fir/convert-to-llvm.fir
Removed:
################################################################################
diff --git a/flang/include/flang/Optimizer/Builder/HLFIRTools.h b/flang/include/flang/Optimizer/Builder/HLFIRTools.h
index 43aa1661550ec..6dce89d2ecabb 100644
--- a/flang/include/flang/Optimizer/Builder/HLFIRTools.h
+++ b/flang/include/flang/Optimizer/Builder/HLFIRTools.h
@@ -334,6 +334,9 @@ void genLengthParameters(mlir::Location loc, fir::FirOpBuilder &builder,
mlir::Value genCharLength(mlir::Location loc, fir::FirOpBuilder &builder,
Entity entity);
+mlir::Value genRank(mlir::Location loc, fir::FirOpBuilder &builder,
+ Entity entity, mlir::Type resultType);
+
/// Return the fir base, shape, and type parameters for a variable. Note that
/// type parameters are only added if the entity is not a box and the type
/// parameters is not a constant in the base type. This matches the arguments
diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td
index 584b7e82bf27a..3afc97475db11 100644
--- a/flang/include/flang/Optimizer/Dialect/FIROps.td
+++ b/flang/include/flang/Optimizer/Dialect/FIROps.td
@@ -62,6 +62,12 @@ class fir_SimpleOneResultOp<string mnemonic, list<Trait> traits = []> :
let builders = [fir_OneResultOpBuilder];
}
+// Whether a type is a BaseBoxType or a reference to a BaseBoxType.
+def IsBoxAddressOrValueTypePred
+ : CPred<"::fir::isBoxAddressOrValue($_self)">;
+def fir_BoxAddressOrValueType : Type<IsBoxAddressOrValueTypePred,
+ "fir.box or fir.class type or reference">;
+
//===----------------------------------------------------------------------===//
// Memory SSA operations
//===----------------------------------------------------------------------===//
@@ -1205,7 +1211,8 @@ def fir_BoxProcHostOp : fir_SimpleOp<"boxproc_host", [NoMemoryEffect]> {
let results = (outs fir_ReferenceType);
}
-def fir_BoxRankOp : fir_SimpleOneResultOp<"box_rank", [NoMemoryEffect]> {
+def fir_BoxRankOp : fir_SimpleOneResultOp<"box_rank",
+ [DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
let summary = "return the number of dimensions for the boxed value";
let description = [{
@@ -1222,7 +1229,7 @@ def fir_BoxRankOp : fir_SimpleOneResultOp<"box_rank", [NoMemoryEffect]> {
descriptor may be either an array or a scalar, so the value is nonnegative.
}];
- let arguments = (ins fir_BoxType:$val);
+ let arguments = (ins fir_BoxAddressOrValueType:$box);
let results = (outs AnyIntegerType);
}
diff --git a/flang/lib/Lower/ConvertExprToHLFIR.cpp b/flang/lib/Lower/ConvertExprToHLFIR.cpp
index 3c305955520e2..a4352ee3359e5 100644
--- a/flang/lib/Lower/ConvertExprToHLFIR.cpp
+++ b/flang/lib/Lower/ConvertExprToHLFIR.cpp
@@ -1626,7 +1626,7 @@ class HlfirBuilder {
return castResult(
hlfir::genExtent(loc, builder, entity, desc.dimension()));
case Fortran::evaluate::DescriptorInquiry::Field::Rank:
- TODO(loc, "rank inquiry on assumed rank");
+ return castResult(hlfir::genRank(loc, builder, entity, resultType));
case Fortran::evaluate::DescriptorInquiry::Field::Stride:
// So far the front end does not generate this inquiry.
TODO(loc, "stride inquiry");
diff --git a/flang/lib/Optimizer/Builder/HLFIRTools.cpp b/flang/lib/Optimizer/Builder/HLFIRTools.cpp
index 511585dc76894..e14e635a7f46b 100644
--- a/flang/lib/Optimizer/Builder/HLFIRTools.cpp
+++ b/flang/lib/Optimizer/Builder/HLFIRTools.cpp
@@ -642,6 +642,15 @@ mlir::Value hlfir::genCharLength(mlir::Location loc, fir::FirOpBuilder &builder,
return lenParams[0];
}
+mlir::Value hlfir::genRank(mlir::Location loc, fir::FirOpBuilder &builder,
+ hlfir::Entity entity, mlir::Type resultType) {
+ if (!entity.isAssumedRank())
+ return builder.createIntegerConstant(loc, resultType, entity.getRank());
+ assert(entity.isBoxAddressOrValue() &&
+ "assumed-ranks are box addresses or values");
+ return builder.create<fir::BoxRankOp>(loc, resultType, entity);
+}
+
// Return a "shape" that can be used in fir.embox/fir.rebox with \p exv base.
static mlir::Value asEmboxShape(mlir::Location loc, fir::FirOpBuilder &builder,
const fir::ExtendedValue &exv,
diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index 59aa9216b707f..5d3adc3dfbf47 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -428,7 +428,8 @@ struct BoxRankOpConversion : public fir::FIROpConversion<fir::BoxRankOp> {
mlir::Value a = adaptor.getOperands()[0];
auto loc = boxrank.getLoc();
mlir::Type ty = convertType(boxrank.getType());
- TypePair boxTyPair = getBoxTypePair(boxrank.getVal().getType());
+ TypePair boxTyPair =
+ getBoxTypePair(fir::unwrapRefType(boxrank.getBox().getType()));
mlir::Value rank = getRankFromBox(loc, boxTyPair, a, rewriter);
mlir::Value result = integerCast(loc, rewriter, ty, rank);
rewriter.replaceOp(boxrank, result);
diff --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp
index 998e9535582cb..b541b7cdc7a5b 100644
--- a/flang/lib/Optimizer/Dialect/FIROps.cpp
+++ b/flang/lib/Optimizer/Dialect/FIROps.cpp
@@ -675,6 +675,20 @@ mlir::Type fir::BoxDimsOp::getTupleType() {
return mlir::TupleType::get(getContext(), triple);
}
+//===----------------------------------------------------------------------===//
+// BoxRankOp
+//===----------------------------------------------------------------------===//
+
+void fir::BoxRankOp::getEffects(
+ llvm::SmallVectorImpl<
+ mlir::SideEffects::EffectInstance<mlir::MemoryEffects::Effect>>
+ &effects) {
+ mlir::Value inputBox = getBox();
+ if (fir::isBoxAddress(inputBox.getType()))
+ effects.emplace_back(mlir::MemoryEffects::Read::get(), inputBox,
+ mlir::SideEffects::DefaultResource::get());
+}
+
//===----------------------------------------------------------------------===//
// CallOp
//===----------------------------------------------------------------------===//
diff --git a/flang/test/Fir/convert-to-llvm.fir b/flang/test/Fir/convert-to-llvm.fir
index 81810aa4bfc74..ee116e998c22f 100644
--- a/flang/test/Fir/convert-to-llvm.fir
+++ b/flang/test/Fir/convert-to-llvm.fir
@@ -970,6 +970,18 @@ func.func @extract_rank(%arg0: !fir.box<!fir.array<*:f64>>) -> i32 {
// CHECK: %[[RANK:.*]] = llvm.sext %[[RAW_RANK]] : i8 to i32
// CHECK: llvm.return %[[RANK]] : i32
+func.func @extract_rank2(%arg0: !fir.ref<!fir.box<!fir.array<*:f64>>>) -> i32 {
+ %0 = fir.box_rank %arg0 : (!fir.ref<!fir.box<!fir.array<*:f64>>>) -> i32
+ return %0 : i32
+}
+
+// CHECK-LABEL: llvm.func @extract_rank2(
+// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr) -> i32
+// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ARG0]][0, 3] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>
+// CHECK: %[[RAW_RANK:.*]] = llvm.load %[[GEP]] : !llvm.ptr -> i8
+// CHECK: %[[RANK:.*]] = llvm.sext %[[RAW_RANK]] : i8 to i32
+// CHECK: llvm.return %[[RANK]] : i32
+
// -----
// Test `fir.box_addr` conversion.
More information about the flang-commits
mailing list