@@ -676,6 +676,34 @@ mlir::Value hlfir::genLBound(mlir::Location loc, fir::FirOpBuilder &builder,
676676 return dimInfo.getLowerBound ();
677677}
678678
679+ static bool
680+ getExprLengthParameters (mlir::Value expr,
681+ llvm::SmallVectorImpl<mlir::Value> &result) {
682+ if (auto concat = expr.getDefiningOp <hlfir::ConcatOp>()) {
683+ result.push_back (concat.getLength ());
684+ return true ;
685+ }
686+ if (auto setLen = expr.getDefiningOp <hlfir::SetLengthOp>()) {
687+ result.push_back (setLen.getLength ());
688+ return true ;
689+ }
690+ if (auto elemental = expr.getDefiningOp <hlfir::ElementalOp>()) {
691+ result.append (elemental.getTypeparams ().begin (),
692+ elemental.getTypeparams ().end ());
693+ return true ;
694+ }
695+ if (auto evalInMem = expr.getDefiningOp <hlfir::EvaluateInMemoryOp>()) {
696+ result.append (evalInMem.getTypeparams ().begin (),
697+ evalInMem.getTypeparams ().end ());
698+ return true ;
699+ }
700+ if (auto apply = expr.getDefiningOp <hlfir::ApplyOp>()) {
701+ result.append (apply.getTypeparams ().begin (), apply.getTypeparams ().end ());
702+ return true ;
703+ }
704+ return false ;
705+ }
706+
679707void hlfir::genLengthParameters (mlir::Location loc, fir::FirOpBuilder &builder,
680708 Entity entity,
681709 llvm::SmallVectorImpl<mlir::Value> &result) {
@@ -688,29 +716,14 @@ void hlfir::genLengthParameters(mlir::Location loc, fir::FirOpBuilder &builder,
688716 // Going through fir::ExtendedValue would create a temp,
689717 // which is not desired for an inquiry.
690718 // TODO: make this an interface when adding further character producing ops.
691- if (auto concat = expr.getDefiningOp <hlfir::ConcatOp>()) {
692- result.push_back (concat.getLength ());
693- return ;
694- } else if (auto concat = expr.getDefiningOp <hlfir::SetLengthOp>()) {
695- result.push_back (concat.getLength ());
696- return ;
697- } else if (auto asExpr = expr.getDefiningOp <hlfir::AsExprOp>()) {
719+
720+ if (auto asExpr = expr.getDefiningOp <hlfir::AsExprOp>()) {
698721 hlfir::genLengthParameters (loc, builder, hlfir::Entity{asExpr.getVar ()},
699722 result);
700723 return ;
701- } else if (auto elemental = expr.getDefiningOp <hlfir::ElementalOp>()) {
702- result.append (elemental.getTypeparams ().begin (),
703- elemental.getTypeparams ().end ());
704- return ;
705- } else if (auto evalInMem =
706- expr.getDefiningOp <hlfir::EvaluateInMemoryOp>()) {
707- result.append (evalInMem.getTypeparams ().begin (),
708- evalInMem.getTypeparams ().end ());
709- return ;
710- } else if (auto apply = expr.getDefiningOp <hlfir::ApplyOp>()) {
711- result.append (apply.getTypeparams ().begin (), apply.getTypeparams ().end ());
712- return ;
713724 }
725+ if (getExprLengthParameters (expr, result))
726+ return ;
714727 if (entity.isCharacter ()) {
715728 result.push_back (hlfir::GetLengthOp::create (builder, loc, expr));
716729 return ;
@@ -733,6 +746,36 @@ mlir::Value hlfir::genCharLength(mlir::Location loc, fir::FirOpBuilder &builder,
733746 return lenParams[0 ];
734747}
735748
749+ std::optional<std::int64_t > hlfir::getCharLengthIfConst (hlfir::Entity entity) {
750+ if (!entity.isCharacter ()) {
751+ return std::nullopt ;
752+ }
753+ if (mlir::isa<hlfir::ExprType>(entity.getType ())) {
754+ mlir::Value expr = entity;
755+ if (auto reassoc = expr.getDefiningOp <hlfir::NoReassocOp>())
756+ expr = reassoc.getVal ();
757+
758+ if (auto asExpr = expr.getDefiningOp <hlfir::AsExprOp>())
759+ return getCharLengthIfConst (hlfir::Entity{asExpr.getVar ()});
760+
761+ llvm::SmallVector<mlir::Value> param;
762+ if (getExprLengthParameters (expr, param)) {
763+ assert (param.size () == 1 && " characters must have one length parameters" );
764+ return fir::getIntIfConstant (param.pop_back_val ());
765+ }
766+ return std::nullopt ;
767+ }
768+
769+ // entity is a var
770+ if (mlir::Value len = tryGettingNonDeferredCharLen (entity))
771+ return fir::getIntIfConstant (len);
772+ auto charType =
773+ mlir::cast<fir::CharacterType>(entity.getFortranElementType ());
774+ if (charType.hasConstantLen ())
775+ return charType.getLen ();
776+ return std::nullopt ;
777+ }
778+
736779mlir::Value hlfir::genRank (mlir::Location loc, fir::FirOpBuilder &builder,
737780 hlfir::Entity entity, mlir::Type resultType) {
738781 if (!entity.isAssumedRank ())
0 commit comments