-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[flang] Add hlfir.index op to represent index intrinsic function #157575
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 5 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
4736bb1
[flang] Define hlfir.index op to represent index intrinsic
valerydmit 10339d2
[flang] Lower index intrinsic call into hlfir.index op
valerydmit 264f137
Additional fix for lowering arguments for a transformational intrinsi…
valerydmit 031d800
[flang] Implement naive lowering of hlfir.index into a runtime call
valerydmit 8de0b13
fix formatting
valerydmit 9b2d7af
Adress review comments -part1
valerydmit f397dcb
address review comments - part2 - delete unnecessary code
valerydmit 18b1439
fix pasto in test comment
valerydmit File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -69,6 +69,9 @@ class HlfirTransformationalIntrinsic { | |
| mlir::Value loadBoxAddress( | ||
| const std::optional<Fortran::lower::PreparedActualArgument> &arg); | ||
|
|
||
| mlir::Value loadTrivialScalar( | ||
| const std::optional<Fortran::lower::PreparedActualArgument> &arg); | ||
|
|
||
| void addCleanup(std::optional<hlfir::CleanupFunction> cleanup) { | ||
| if (cleanup) | ||
| cleanupFns.emplace_back(std::move(*cleanup)); | ||
|
|
@@ -204,6 +207,17 @@ class HlfirReshapeLowering : public HlfirTransformationalIntrinsic { | |
| mlir::Type stmtResultType) override; | ||
| }; | ||
|
|
||
| class HlfirIndexLowering : public HlfirTransformationalIntrinsic { | ||
| public: | ||
| using HlfirTransformationalIntrinsic::HlfirTransformationalIntrinsic; | ||
|
|
||
| protected: | ||
| mlir::Value | ||
| lowerImpl(const Fortran::lower::PreparedActualArguments &loweredActuals, | ||
| const fir::IntrinsicArgumentLoweringRules *argLowering, | ||
| mlir::Type stmtResultType) override; | ||
| }; | ||
|
|
||
| } // namespace | ||
|
|
||
| mlir::Value HlfirTransformationalIntrinsic::loadBoxAddress( | ||
|
|
@@ -239,29 +253,10 @@ mlir::Value HlfirTransformationalIntrinsic::loadBoxAddress( | |
| return boxOrAbsent; | ||
| } | ||
|
|
||
| static mlir::Value loadOptionalValue( | ||
| mlir::Location loc, fir::FirOpBuilder &builder, | ||
| const std::optional<Fortran::lower::PreparedActualArgument> &arg, | ||
| hlfir::Entity actual) { | ||
| if (!arg->handleDynamicOptional()) | ||
| return hlfir::loadTrivialScalar(loc, builder, actual); | ||
|
|
||
| mlir::Value isPresent = arg->getIsPresent(); | ||
| mlir::Type eleType = hlfir::getFortranElementType(actual.getType()); | ||
| return builder | ||
| .genIfOp(loc, {eleType}, isPresent, | ||
| /*withElseRegion=*/true) | ||
| .genThen([&]() { | ||
| assert(actual.isScalar() && fir::isa_trivial(eleType) && | ||
| "must be a numerical or logical scalar"); | ||
| hlfir::Entity val = hlfir::loadTrivialScalar(loc, builder, actual); | ||
| fir::ResultOp::create(builder, loc, val); | ||
| }) | ||
| .genElse([&]() { | ||
| mlir::Value zero = fir::factory::createZeroValue(builder, loc, eleType); | ||
| fir::ResultOp::create(builder, loc, zero); | ||
| }) | ||
| .getResults()[0]; | ||
| mlir::Value HlfirTransformationalIntrinsic::loadTrivialScalar( | ||
| const std::optional<Fortran::lower::PreparedActualArgument> &arg) { | ||
| hlfir::Entity actual = arg->getActual(loc, builder); | ||
| return hlfir::loadTrivialScalar(loc, builder, actual); | ||
| } | ||
|
|
||
| llvm::SmallVector<mlir::Value> HlfirTransformationalIntrinsic::getOperandVector( | ||
|
|
@@ -277,29 +272,33 @@ llvm::SmallVector<mlir::Value> HlfirTransformationalIntrinsic::getOperandVector( | |
| operands.emplace_back(); | ||
| continue; | ||
| } | ||
| hlfir::Entity actual = arg->getActual(loc, builder); | ||
| mlir::Value valArg; | ||
|
|
||
| if (!argLowering) { | ||
| valArg = hlfir::loadTrivialScalar(loc, builder, actual); | ||
| } else { | ||
| fir::ArgLoweringRule argRules = | ||
| fir::lowerIntrinsicArgumentAs(*argLowering, i); | ||
| if (argRules.lowerAs == fir::LowerIntrinsicArgAs::Box) | ||
| valArg = loadBoxAddress(arg); | ||
| else if (!argRules.handleDynamicOptional && | ||
| argRules.lowerAs != fir::LowerIntrinsicArgAs::Inquired) | ||
| valArg = hlfir::derefPointersAndAllocatables(loc, builder, actual); | ||
| else if (argRules.handleDynamicOptional && | ||
| argRules.lowerAs == fir::LowerIntrinsicArgAs::Value) | ||
| valArg = loadOptionalValue(loc, builder, arg, actual); | ||
| else if (argRules.handleDynamicOptional) | ||
| valArg = loadTrivialScalar(arg); | ||
| operands.emplace_back(valArg); | ||
| continue; | ||
| } | ||
| fir::ArgLoweringRule argRules = | ||
| fir::lowerIntrinsicArgumentAs(*argLowering, i); | ||
| if (argRules.lowerAs == fir::LowerIntrinsicArgAs::Box) { | ||
| valArg = loadBoxAddress(arg); | ||
| } else if (argRules.handleDynamicOptional) { | ||
| if (argRules.lowerAs == fir::LowerIntrinsicArgAs::Value) { | ||
| if (arg->handleDynamicOptional()) | ||
| valArg = arg->getOptionalValue(loc, builder); | ||
| else | ||
| valArg = loadTrivialScalar(arg); | ||
| } else { | ||
| TODO(loc, "hlfir transformational intrinsic dynamically optional " | ||
| "argument without box lowering"); | ||
| } | ||
| } else { | ||
| hlfir::Entity actual = arg->getActual(loc, builder); | ||
| if (argRules.lowerAs != fir::LowerIntrinsicArgAs::Inquired) | ||
| valArg = hlfir::derefPointersAndAllocatables(loc, builder, actual); | ||
| else | ||
| valArg = actual.getBase(); | ||
| } | ||
|
|
||
| operands.emplace_back(valArg); | ||
| } | ||
| return operands; | ||
|
|
@@ -513,6 +512,35 @@ mlir::Value HlfirReshapeLowering::lowerImpl( | |
| operands[2], operands[3]); | ||
| } | ||
|
|
||
| mlir::Value HlfirIndexLowering::lowerImpl( | ||
| const Fortran::lower::PreparedActualArguments &loweredActuals, | ||
| const fir::IntrinsicArgumentLoweringRules *argLowering, | ||
| mlir::Type stmtResultType) { | ||
| auto operands = getOperandVector(loweredActuals, argLowering); | ||
| assert(operands.size() == 4); | ||
| mlir::Value substr = operands[1]; | ||
| mlir::Value str = operands[0]; | ||
| mlir::Value back = operands[2]; | ||
| mlir::Value kind = operands[3]; | ||
|
|
||
| mlir::Type resultType; | ||
| if (kind) { | ||
| auto kindCst = fir::getIntIfConstant(kind); | ||
| assert(kindCst && | ||
| "kind argument of index must be an integer constant expression"); | ||
| unsigned bits = builder.getKindMap().getIntegerBitsize(*kindCst); | ||
| assert(bits != 0 && "failed to convert kind to integer bitsize"); | ||
| resultType = builder.getIntegerType(bits); | ||
| } else { | ||
| resultType = builder.getDefaultIntegerType(); | ||
| } | ||
|
||
| mlir::Value result = createOp<hlfir::IndexOp>(resultType, substr, str, back); | ||
|
|
||
| if (resultType != stmtResultType) | ||
| return builder.createConvert(loc, stmtResultType, result); | ||
| return result; | ||
| } | ||
|
|
||
| std::optional<hlfir::EntityWithAttributes> Fortran::lower::lowerHlfirIntrinsic( | ||
| fir::FirOpBuilder &builder, mlir::Location loc, const std::string &name, | ||
| const Fortran::lower::PreparedActualArguments &loweredActuals, | ||
|
|
@@ -567,6 +595,10 @@ std::optional<hlfir::EntityWithAttributes> Fortran::lower::lowerHlfirIntrinsic( | |
| if (name == "reshape") | ||
| return HlfirReshapeLowering{builder, loc}.lower(loweredActuals, argLowering, | ||
| stmtResultType); | ||
| if (name == "index") | ||
| return HlfirIndexLowering{builder, loc}.lower(loweredActuals, argLowering, | ||
| stmtResultType); | ||
|
|
||
| if (mlir::isa<fir::CharacterType>(stmtResultType)) { | ||
| if (name == "min") | ||
| return HlfirCharExtremumLowering{builder, loc, | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.