clangir
clangir copied to clipboard
Use the canonicalizer pass for the new operations in CIR (with workaround sharing)
Soon or later we'll need the canonicalizer
pass to be run with no problems from our side or implement and use something similar.
The pass itself is described here.
As it was suggested by @orbiri , new operations in CIR should be always tested to make sure the canonicalizer
won't remove them.
Workaround
The point is that we still have some problems with this pass, since it too aggressive and may remove the useful code. In the same time it has some parameters that can be set in order to disable certain optimizations.
And here is something I want to share, e.g. how to disable region simplification. For the next trivial code:
void foo() {
goto exit;
exit:
return;
}
CIR looks like the following:
cir.func @foo() {
cir.goto "exit"
^bb1: // no predecessors
cir.label "exit"
cir.return
}
This code being run with cir-opt example.cir -canonicalize
causes the verification error, which states 'cir.func' op goto/label mismatch
and points to the function body as just:
cir.func @foo() {
cir.goto "exit"
}
This is due to the canonicalizer
pass that removed the unreachable (from its point of view) code - block bb1
.
While the better solution is expected (and I believe one will find it), the workaround here is to set region-simplify
parameter of the pass in question to false
. The only I found it the next one:
cir-opt example.cir --pass-pipeline='builtin.module(canonicalize{region-simplify=false})'
.
In this case no errors happen and everything is just fine.
Note, one can add another passes in this pipeline, e.g. cir-to-llvm
:
cir-opt example.cir --pass-pipeline='builtin.module(cir-to-llvm,canonicalize{region-simplify=false})'
.