aboutsummaryrefslogtreecommitdiff
path: root/flang/lib/Optimizer/Builder/HLFIRTools.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'flang/lib/Optimizer/Builder/HLFIRTools.cpp')
-rw-r--r--flang/lib/Optimizer/Builder/HLFIRTools.cpp81
1 files changed, 62 insertions, 19 deletions
diff --git a/flang/lib/Optimizer/Builder/HLFIRTools.cpp b/flang/lib/Optimizer/Builder/HLFIRTools.cpp
index f93eaf7..dbfcae1 100644
--- a/flang/lib/Optimizer/Builder/HLFIRTools.cpp
+++ b/flang/lib/Optimizer/Builder/HLFIRTools.cpp
@@ -676,6 +676,34 @@ mlir::Value hlfir::genLBound(mlir::Location loc, fir::FirOpBuilder &builder,
return dimInfo.getLowerBound();
}
+static bool
+getExprLengthParameters(mlir::Value expr,
+ llvm::SmallVectorImpl<mlir::Value> &result) {
+ if (auto concat = expr.getDefiningOp<hlfir::ConcatOp>()) {
+ result.push_back(concat.getLength());
+ return true;
+ }
+ if (auto setLen = expr.getDefiningOp<hlfir::SetLengthOp>()) {
+ result.push_back(setLen.getLength());
+ return true;
+ }
+ if (auto elemental = expr.getDefiningOp<hlfir::ElementalOp>()) {
+ result.append(elemental.getTypeparams().begin(),
+ elemental.getTypeparams().end());
+ return true;
+ }
+ if (auto evalInMem = expr.getDefiningOp<hlfir::EvaluateInMemoryOp>()) {
+ result.append(evalInMem.getTypeparams().begin(),
+ evalInMem.getTypeparams().end());
+ return true;
+ }
+ if (auto apply = expr.getDefiningOp<hlfir::ApplyOp>()) {
+ result.append(apply.getTypeparams().begin(), apply.getTypeparams().end());
+ return true;
+ }
+ return false;
+}
+
void hlfir::genLengthParameters(mlir::Location loc, fir::FirOpBuilder &builder,
Entity entity,
llvm::SmallVectorImpl<mlir::Value> &result) {
@@ -688,29 +716,14 @@ void hlfir::genLengthParameters(mlir::Location loc, fir::FirOpBuilder &builder,
// Going through fir::ExtendedValue would create a temp,
// which is not desired for an inquiry.
// TODO: make this an interface when adding further character producing ops.
- if (auto concat = expr.getDefiningOp<hlfir::ConcatOp>()) {
- result.push_back(concat.getLength());
- return;
- } else if (auto concat = expr.getDefiningOp<hlfir::SetLengthOp>()) {
- result.push_back(concat.getLength());
- return;
- } else if (auto asExpr = expr.getDefiningOp<hlfir::AsExprOp>()) {
+
+ if (auto asExpr = expr.getDefiningOp<hlfir::AsExprOp>()) {
hlfir::genLengthParameters(loc, builder, hlfir::Entity{asExpr.getVar()},
result);
return;
- } else if (auto elemental = expr.getDefiningOp<hlfir::ElementalOp>()) {
- result.append(elemental.getTypeparams().begin(),
- elemental.getTypeparams().end());
- return;
- } else if (auto evalInMem =
- expr.getDefiningOp<hlfir::EvaluateInMemoryOp>()) {
- result.append(evalInMem.getTypeparams().begin(),
- evalInMem.getTypeparams().end());
- return;
- } else if (auto apply = expr.getDefiningOp<hlfir::ApplyOp>()) {
- result.append(apply.getTypeparams().begin(), apply.getTypeparams().end());
- return;
}
+ if (getExprLengthParameters(expr, result))
+ return;
if (entity.isCharacter()) {
result.push_back(hlfir::GetLengthOp::create(builder, loc, expr));
return;
@@ -733,6 +746,36 @@ mlir::Value hlfir::genCharLength(mlir::Location loc, fir::FirOpBuilder &builder,
return lenParams[0];
}
+std::optional<std::int64_t> hlfir::getCharLengthIfConst(hlfir::Entity entity) {
+ if (!entity.isCharacter()) {
+ return std::nullopt;
+ }
+ if (mlir::isa<hlfir::ExprType>(entity.getType())) {
+ mlir::Value expr = entity;
+ if (auto reassoc = expr.getDefiningOp<hlfir::NoReassocOp>())
+ expr = reassoc.getVal();
+
+ if (auto asExpr = expr.getDefiningOp<hlfir::AsExprOp>())
+ return getCharLengthIfConst(hlfir::Entity{asExpr.getVar()});
+
+ llvm::SmallVector<mlir::Value> param;
+ if (getExprLengthParameters(expr, param)) {
+ assert(param.size() == 1 && "characters must have one length parameters");
+ return fir::getIntIfConstant(param.pop_back_val());
+ }
+ return std::nullopt;
+ }
+
+ // entity is a var
+ if (mlir::Value len = tryGettingNonDeferredCharLen(entity))
+ return fir::getIntIfConstant(len);
+ auto charType =
+ mlir::cast<fir::CharacterType>(entity.getFortranElementType());
+ if (charType.hasConstantLen())
+ return charType.getLen();
+ return std::nullopt;
+}
+
mlir::Value hlfir::genRank(mlir::Location loc, fir::FirOpBuilder &builder,
hlfir::Entity entity, mlir::Type resultType) {
if (!entity.isAssumedRank())