-
Notifications
You must be signed in to change notification settings - Fork 149
[CIR] Introduce CIR simplification #696
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
Sorry I didn't had the time to look just yet, but should do that soon, can you update post rebase? |
@bcardosolopes updated! |
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.
This PR introduce cir simplification pass. The idea is to have a pass for the redundant operations removal/update.
Right now two pattern implemented, both related to the redundant
bool
operations. First pattern removes redundant casts frombool
toint
and back that for some reasons appear in the code. Second pattern removes sequential unary not operations (!!
) .
Neat!
- I have no idea if it's useful for the community
Definetely great to get rid of these chains of redundant casts.
- There is a test fail - unfortunately current pattern rewriter run DCE underneath the hood and looks like we can't workaround it.
Is this something related to the same issues we see with the canonicalizer? Is it worth adding this case to the bug tracking it?
It's enough just to add an operation to the list - in this case
UnaryOp
- and callapplyOpPatternsAndFold
. I could rewrite a test a little in order to make everything non dead or implement a simple fix point algorithm for the particular task (I would do the former).
Former is a fine solution, I'm a bit worried about the overall approach though (more comments inline), I think we should try as much as possible to fix some of these problems at the MLIR level if necessary, I'm afraid those will keep piling up and might accumlate be too much technical debt in the future (e.g. CIR reinventing the wheel to workaround MLIR issues). Thoughts?
@bcardosolopes
but anyway got a type error. Maybe I'm doing something wrong though and didn't get how I should work wtih folders. Another thought is that from the future optimizations point of view, I would have CIR simplified as much as we can do it, and better to do it explicit with the pass, than implicit with
I would say it's not a bug, it's a feature!! which may hit us only in tests. It's slightly remind us the case with the canonicalizer since it also run the version of To summarize:
|
From the canonicalization docs:
In this case sounds like it wouldn't be a problem for the folder for
Simplifications might work better in face of canonicalized IR, but it's a blurry line sometimes where things should live. In the
MergeCleanups is not about My overall feedback is that I want to see the same optimizations you are trying to implement. But my feedback for this PR is that such simplification is doing too much in one place, pieces should be more independent, behave more like traditional |
@bcardosolopes So. I rewrote everything as folders for the correspondent operations and now it looks more elegant and readable than before.
The first one is clear. The second one may need some extra clarification.
Nope, only the results of unary operations that are not stored somewhere. And it's all because of
So looks like
Well, the patterns I suggest have bool type as a result, so I would say it's safe to drop int promotion here: I explicitly check that the first cast kind is either
Well, may be, but it's so easy to do it right here ... The idea is to use just boolean value when we already got it, without any redundant casts. |
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.
Nice! Just some remaining comments/questions
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 the overall approach is good. Some extra thoughts on how to re-organize the approach a bit.
Ideally we should use one PR for each ::fold
'er, since they are not really dependent, just a quick note for next time around.
|
||
|
||
#define CHECK_PTR(ptr) \ | ||
do { \ |
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.
Do we already have a simplification for do { ... } while (0)
? That'd be a good one for a next PR.
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.
well, we don't have( maybe I will try to implement. From the other point of view, it kind of convenient to have do .. while(0)
since we know where the macroses are) and may use this knowledge for some analysis.
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.
Good point. Right now we don't have a distinction between folders/simplifications meant for cleaning up versus optimization - MergeCleanups (now CIRSimplify) runs before all other passes (even before lifetime checker), which is still harmless because we don't do anything crazy. Looking fwd we might need to separate things that look more like canonicalization from optimization.
For instance, I could see someone arguing the unary folding you added could hurt analysis.
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.
LGTM thanks
This PR introduce cir simplification pass. The idea is to have a pass for the redundant operations removal/update. Right now two pattern implemented, both related to the redundant `bool` operations. First pattern removes redundant casts from `bool` to `int` and back that for some reasons appear in the code. Second pattern removes sequential unary not operations (`!!`) . For example, the code from the test is expanded from the simple check that is common for C code: ``` #define CHECK_PTR(ptr) \ do { \ if (__builtin_expect((!!((ptr) == 0)), 0))\ return -42; \ } while(0) ``` I mark this PR as a draft for the following reasons: 1) I have no idea if it's useful for the community 2) There is a test fail - unfortunately current pattern rewriter run DCE underneath the hood and looks like we can't workaround it. It's enough just to add an operation to the list - in this case `UnaryOp` - and call `applyOpPatternsAndFold`. I could rewrite a test a little in order to make everything non dead or implement a simple fix point algorithm for the particular task (I would do the former).
This PR introduce cir simplification pass. The idea is to have a pass for the redundant operations removal/update. Right now two pattern implemented, both related to the redundant `bool` operations. First pattern removes redundant casts from `bool` to `int` and back that for some reasons appear in the code. Second pattern removes sequential unary not operations (`!!`) . For example, the code from the test is expanded from the simple check that is common for C code: ``` #define CHECK_PTR(ptr) \ do { \ if (__builtin_expect((!!((ptr) == 0)), 0))\ return -42; \ } while(0) ``` I mark this PR as a draft for the following reasons: 1) I have no idea if it's useful for the community 2) There is a test fail - unfortunately current pattern rewriter run DCE underneath the hood and looks like we can't workaround it. It's enough just to add an operation to the list - in this case `UnaryOp` - and call `applyOpPatternsAndFold`. I could rewrite a test a little in order to make everything non dead or implement a simple fix point algorithm for the particular task (I would do the former).
This PR introduce cir simplification pass. The idea is to have a pass for the redundant operations removal/update. Right now two pattern implemented, both related to the redundant `bool` operations. First pattern removes redundant casts from `bool` to `int` and back that for some reasons appear in the code. Second pattern removes sequential unary not operations (`!!`) . For example, the code from the test is expanded from the simple check that is common for C code: ``` #define CHECK_PTR(ptr) \ do { \ if (__builtin_expect((!!((ptr) == 0)), 0))\ return -42; \ } while(0) ``` I mark this PR as a draft for the following reasons: 1) I have no idea if it's useful for the community 2) There is a test fail - unfortunately current pattern rewriter run DCE underneath the hood and looks like we can't workaround it. It's enough just to add an operation to the list - in this case `UnaryOp` - and call `applyOpPatternsAndFold`. I could rewrite a test a little in order to make everything non dead or implement a simple fix point algorithm for the particular task (I would do the former).
This PR introduce cir simplification pass. The idea is to have a pass for the redundant operations removal/update. Right now two pattern implemented, both related to the redundant `bool` operations. First pattern removes redundant casts from `bool` to `int` and back that for some reasons appear in the code. Second pattern removes sequential unary not operations (`!!`) . For example, the code from the test is expanded from the simple check that is common for C code: ``` #define CHECK_PTR(ptr) \ do { \ if (__builtin_expect((!!((ptr) == 0)), 0))\ return -42; \ } while(0) ``` I mark this PR as a draft for the following reasons: 1) I have no idea if it's useful for the community 2) There is a test fail - unfortunately current pattern rewriter run DCE underneath the hood and looks like we can't workaround it. It's enough just to add an operation to the list - in this case `UnaryOp` - and call `applyOpPatternsAndFold`. I could rewrite a test a little in order to make everything non dead or implement a simple fix point algorithm for the particular task (I would do the former).
This PR introduce cir simplification pass. The idea is to have a pass for the redundant operations removal/update. Right now two pattern implemented, both related to the redundant `bool` operations. First pattern removes redundant casts from `bool` to `int` and back that for some reasons appear in the code. Second pattern removes sequential unary not operations (`!!`) . For example, the code from the test is expanded from the simple check that is common for C code: ``` #define CHECK_PTR(ptr) \ do { \ if (__builtin_expect((!!((ptr) == 0)), 0))\ return -42; \ } while(0) ``` I mark this PR as a draft for the following reasons: 1) I have no idea if it's useful for the community 2) There is a test fail - unfortunately current pattern rewriter run DCE underneath the hood and looks like we can't workaround it. It's enough just to add an operation to the list - in this case `UnaryOp` - and call `applyOpPatternsAndFold`. I could rewrite a test a little in order to make everything non dead or implement a simple fix point algorithm for the particular task (I would do the former).
This PR introduce cir simplification pass. The idea is to have a pass for the redundant operations removal/update. Right now two pattern implemented, both related to the redundant `bool` operations. First pattern removes redundant casts from `bool` to `int` and back that for some reasons appear in the code. Second pattern removes sequential unary not operations (`!!`) . For example, the code from the test is expanded from the simple check that is common for C code: ``` #define CHECK_PTR(ptr) \ do { \ if (__builtin_expect((!!((ptr) == 0)), 0))\ return -42; \ } while(0) ``` I mark this PR as a draft for the following reasons: 1) I have no idea if it's useful for the community 2) There is a test fail - unfortunately current pattern rewriter run DCE underneath the hood and looks like we can't workaround it. It's enough just to add an operation to the list - in this case `UnaryOp` - and call `applyOpPatternsAndFold`. I could rewrite a test a little in order to make everything non dead or implement a simple fix point algorithm for the particular task (I would do the former).
This PR introduce cir simplification pass. The idea is to have a pass for the redundant operations removal/update.
Right now two pattern implemented, both related to the redundant
bool
operations.First pattern removes redundant casts from
bool
toint
and back that for some reasons appear in the code.Second pattern removes sequential unary not operations (
!!
) .For example, the code from the test is expanded from the simple check that is common for C code:
I mark this PR as a draft for the following reasons:
It's enough just to add an operation to the list - in this case
UnaryOp
- and callapplyOpPatternsAndFold
. I could rewrite a test a little in order to make everything non dead or implement a simple fix point algorithm for the particular task (I would do the former).