Initial implementation.
Based on feedback, I'll add support for FPConstants.
Details
- Reviewers
ab t.p.northover qcolombet dsanders
Diff Detail
Event Timeline
Thanks for working on this! Please add comments and show off one or two examples that highlight the benefits of your extensions.
Cheers
Gerolf
This is helpful in cases where you try to build a generic operation on a constant.
For e.g.,
vreg1(s16) = G_CONSTANT 0
Builder.buildZExt(s32, vreg1) would result in
vreg1(s16) = G_CONSTANT 0
vreg2(s16) = G_ZEXT vreg1
Instead - we can constant fold operations and instead generate
vreg2(s32) = G_CONSTANT i32 0
Similarly we can constant fold binary operations such as Add/sub/or/and/xor/mul.
We also can constant fold intrinsics FABS/FLOG... (constant) -> constant.
Could you run clang-format on this patch? There's a few indentation and style nits in this patch. There's also a few in the neighbouring code which we should deal with separately
Similarly we can constant fold binary operations such as Add/sub/or/and/xor/mul.
I don't see XOR in this patch
! In D35594#814884, @aditya_nandakumar wrote:
This is helpful in cases where you try to build a generic operation on a constant.
For e.g.,
vreg1(s16) = G_CONSTANT 0
Builder.buildZExt(s32, vreg1) would result in
vreg1(s16) = G_CONSTANT 0
vreg2(s16) = G_ZEXT vreg1Instead - we can constant fold operations and instead generate
vreg2(s32) = G_CONSTANT i32 0Similarly we can constant fold binary operations such as Add/sub/or/and/xor/mul.
We also can constant fold intrinsics FABS/FLOG... (constant) -> constant.
I think Gerolf intended the comments and examples to be added to the patch itself.
In my opinion, the main thing this patch is missing is the test case. Is it possible to extend one (preferably a few) of the select-*.mir tests to cover a constant folding case?
include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h | ||
---|---|---|
81–87 | This will need refreshing to account for the updates to one of your other patches. | |
lib/CodeGen/GlobalISel/MachineIRBuilder.cpp | ||
184–185 | XOR seems to be missing |
I can try changing one of IRTranslator's build methods to use this API instead and then I should be able to write a test case.
include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h | ||
---|---|---|
81–87 | This is not needed anymore. The other patch went in. | |
lib/CodeGen/GlobalISel/MachineIRBuilder.cpp | ||
184–185 | Missed that. Thanks. |
Updated diff . Added some test cases by making IRTranslator use buildInstr for binary opcodes.
include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h | ||
---|---|---|
94 | How do you sort the opcodes? The order here is different from other functions (ConstantFoldBinop) in your code? Why not be consistent and eg. order all arithmetic (alphabetical), then all logical (alphabetical) or all alphabetical or ... | |
126 | What about G_TRUNC? | |
lib/CodeGen/GlobalISel/MachineIRBuilder.cpp | ||
200 | BoolValue? Should that be an explicit check for zero instead? | |
398 | For AnyExt ConstandFoldUnaryOp() uses Zext, here you use Sext? | |
408 | Since ConstandFoldUnaryOp supports 4 opcodes, I had expected four calls to it in functions buildSExt, buildZext, buildAnyExt and *buildTrunc*. But the last one seems missing. If the function below (buildSExtorTrunc is covering that than I miss a call to ConstandFoldUnaryOp() there. So either way the code doesn't look quite kosher. |
include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h | ||
---|---|---|
94 | I hadn't thought about sorting. The order is mostly similar to the one in the DAG. I will alphabetically sort it here though. | |
126 | I hadn't initially implemented all of them - as I thought I'd do that based on feedback. I'll certainly add G_TRUNC here. | |
lib/CodeGen/GlobalISel/MachineIRBuilder.cpp | ||
200 | That is how you check for zero in APInt. /// This converts the APInt to a boolean value as a test against zero. bool getBoolValue() const { return !!*this; } | |
398 | Will change to Zext here. Not sure if it matters for any_ext though. | |
408 | I hadn't hooked up G_TRUNC yet. Was planning to do it based on feedback. |
Added more integer operations, along with tests.
Disabled constant folding cast instructions as MIR currently doesn't infer legality of constants of type that it creates.
Disabled constant folding cast instructions as MIR currently doesn't infer legality of constants of type that it creates.
Would it make sense to have a mode in the builder where combines are allow or not, just not type changes?
What I am thinking is every pass before legalization would run in combine mode and every pass after would run in non-combine mode.
Is that one flag that basically enables/disables all optimizations/folding ? Or we have some sort of API where the user opt's in/out into certain transformations..
Is that one flag that basically enables/disables all optimizations/folding ?
Yes, I would go with that for now. But I could see your concerns that we are going to generate crapy code for no good reason, thus you'd like more control.
Or we have some sort of API where the user opt's in/out into certain transformations..
Hi Aditya,
It feels to me that we are attacking the problem of the combine optimizations and I wouldn't want complicated APIs for this. Basically, the way I see it is with a dumb MachineIRBuilder base class that would be specialized with the combines that make sense for a target at a given point for a given optimization level. The challenge here is to define which combines are available and when they are valid to apply (e.g., ok before legalization, etc.) for each target. I can see a table gen path here.
To summarize, I'd like to keep the combiner logic as simple as possible (ideally none at all for O0) because I fear we are already touching something we haven't carefully thought yet.
Cheers,
-Quentin
Hi Aditya,
Is there anything in this patch we still need? I believe you committed similar functionality along with a CSE'ing builder
This will need refreshing to account for the updates to one of your other patches.