Skip to content

Select Case constructs with character selector expressions #685

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 1 commit into from
Mar 18, 2021
Merged

Select Case constructs with character selector expressions #685

merged 1 commit into from
Mar 18, 2021

Conversation

vdonaldson
Copy link
Collaborator

Add the capability to lower select case constructs of any type to
either FIR SelectCaseOp's or a sequence of comparisons and branches.
Actually generate SelectCaseOp's for integer type constructs, but use
comparisons and branches for logical types (the code is better) and
for character types (it isn't possible yet to handle character
SelectCaseOp's downstream).

Add the capability to lower select case constructs of any type to
either FIR SelectCaseOp's or a sequence of comparisons and branches.
Actually generate SelectCaseOp's for integer type constructs, but use
comparisons and branches for logical types (the code is better) and
for character types (it isn't possible yet to handle character
SelectCaseOp's downstream).
Copy link
Collaborator

@jeanPerier jeanPerier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code looks good to me.
I am more in favor of having this logic as a FIR to FIR pass operating from a select-case op, which would both move some complexity outside of lowering and allow some more flexibility for future optimizations. Have you tried a bit this option ?

Copy link

@schweitzpgi schweitzpgi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm approving this so you can commit it.

The plan is for the Burnside bridge to lower to fir.select_case unconditionally. A rewrite pass will lower these high-level control ops to some primitive implementation(s) (perhaps a choice from a menu of possibilities) before everything is converted to LLVM-IR dialect. But I can do that after this code is merged.

Thanks for pulling this together, Val. It's great to have CHARACTER support.

@@ -395,6 +396,14 @@ class FirConverter : public Fortran::lower::AbstractConverter {
return cat == Fortran::common::TypeCategory::Derived;
}

/// Insert a new block before \p block. Leave the insertion point unchanged.
mlir::Block *insertBlock(mlir::Block *block) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use mlir's splitBlock function?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mlir functions splitBlock and (one overload of) createBlock are complementary. createBlock inserts a new block before a given block, and splitBlock inserts the new block after the given block. Since "the given block" may actually be the first of multiple blocks, createBlock makes much more sense here. Of course, where blocks are inserted doesn't affect actual code relationships between blocks. But it is much easier to read and debug IR when blocks are placed in more natural locations.

if (isCharacterCategory(exprType->category())) {
TODO(loc, "Select Case selector of type Character");
bool isCharSelector = isCharacterCategory(expr->GetType()->category());
bool isLogicalSelector = isLogicalCategory(expr->GetType()->category());

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we have moved to using the FIR type for these tests. @jeanPerier ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general yes, when there is a mlir::Type available working with it is the preferred way. But Here I think it would make the code more complex given this is needed before producing any mlir values, and working with mlir::Type would not be 100% straightforward given logicals are mlir::IntegerType. So what Val has here looks clean to me.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, that was the motivation for doing it this way.

@vdonaldson
Copy link
Collaborator Author

I am more in favor of having this logic as a FIR to FIR pass operating from a select-case op, which would both move some complexity outside of lowering and allow some more flexibility for future optimizations. Have you tried a bit this option ?

Although the current lack of support for generating runtime support calls in bbc is a significant motivation for doing this conversion in bbc now, as the code illustrates, the conversion is fairly simple, so it may be reasonable to have a 3-tier lowering/translation process even in the long run. Lowering early enables earlier optimization of lowered code. I can envision doing some of the lowering in bbc (as here) to take advantage of fir::IfOp, for example. Any fir::SelectCaseOp that reaches the beginning of bbc can then be considered for lowering at that point. And if some optimizations in bbc are best done directly on a fir::SelectCaseOp, then those cases can be retained, and any surviving fir::SelectCaseOp can finally be converted at the end of bbc. That allows a lot of flexibility for generating the best code.

@vdonaldson vdonaldson merged commit 0d7372a into flang-compiler:fir-dev Mar 18, 2021
@schweitzpgi
Copy link

I'm seeing some warnings here:

/local/home/eschweitz/f18-llvm-project/flang/lib/Lower/Bridge.cpp:1274:16: warning: variable 'pred' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized]
      else if (attr.isa<fir::UpperBoundAttr>())
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/local/home/eschweitz/f18-llvm-project/flang/lib/Lower/Bridge.cpp:1276:41: note: uninitialized use occurs here
      auto cond = genCond(*caseValue++, pred);
                                        ^~~~
/local/home/eschweitz/f18-llvm-project/flang/lib/Lower/Bridge.cpp:1274:12: note: remove the 'if' if its condition is always true
      else if (attr.isa<fir::UpperBoundAttr>())
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/local/home/eschweitz/f18-llvm-project/flang/lib/Lower/Bridge.cpp:1269:7: note: variable 'pred' is declared here
      mlir::CmpIPredicate pred;
      ^

@vdonaldson vdonaldson deleted the vkd1 branch March 19, 2021 00:54
jeanPerier pushed a commit that referenced this pull request May 25, 2021
Add the capability to lower select case constructs of any type to
either FIR SelectCaseOp's or a sequence of comparisons and branches.
Actually generate SelectCaseOp's for integer type constructs, but use
comparisons and branches for logical types (the code is better) and
for character types (it isn't possible yet to handle character
SelectCaseOp's downstream).
mleair pushed a commit that referenced this pull request Oct 18, 2021
Add the capability to lower select case constructs of any type to
either FIR SelectCaseOp's or a sequence of comparisons and branches.
Actually generate SelectCaseOp's for integer type constructs, but use
comparisons and branches for logical types (the code is better) and
for character types (it isn't possible yet to handle character
SelectCaseOp's downstream).
jeanPerier pushed a commit that referenced this pull request Oct 22, 2021
Add the capability to lower select case constructs of any type to
either FIR SelectCaseOp's or a sequence of comparisons and branches.
Actually generate SelectCaseOp's for integer type constructs, but use
comparisons and branches for logical types (the code is better) and
for character types (it isn't possible yet to handle character
SelectCaseOp's downstream).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants