-
Notifications
You must be signed in to change notification settings - Fork 16
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
Conversation
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).
There was a problem hiding this 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 ?
There was a problem hiding this 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) { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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()); |
There was a problem hiding this comment.
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 ?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
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 |
I'm seeing some warnings here:
|
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).
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).