Hey @bjorn3 -- I've been studying cranelift recently and as you know implemented a backend with it for my toy compiler. I'm wondering if there are any issues that I could help with in your cranelift codegen now. What would be a good starter for me?
https://github.com/bjorn3/rustc_codegen_cranelift/issues/920 is an easy to fix issue.
Fixing https://github.com/bjorn3/rustc_codegen_cranelift/blob/7031c96fb3dc829586676d55e4d451f2c8de88bd/src/abi/mod.rs#L443 should also be relatively easy. You can use tcx.codegen_fn_attrs
to determine if the called function is cold and then insert the current block into fx.cold_blocks
if the called function is cold. You will probably also need to pass the current block to the codegen_terminator_call
function.
@osa1 If you have any questions, let me now.
Perfect, thanks @bjorn3 . The FIXME you linked looks easy to fix, I'll be working on it. I'm guessing there isn't an issue for it since you linked the source instead of issue?
:+1: There is indeed no issue for it.
@bjorn3 I'm getting the "cold" attribute of the callee, how do I update the current cranelift block with that information now?
I searched in documentation for "cold", but I don't see anything relevant.
@osa1 fx.cold_blocks
is a HashSet
containing all cold blocks. You will need to add a new argument to codegen_terminator_call
to pass the current block first.
The concept of "cold" is not part of Cranelift. Instead cg_clif keeps track of it itself and has an optimization pass to move all cold blocks to the end of the function.
OK done ,it builds. Is there a way to test this now?
There is no testing infrastructure other than to make sure things compile and run fine. You can verify it manually by compiling something like
fn main() {
let a = true;
if !a {
a();
} else {
loop {}
}
}
#[cold]
fn a() {}
if cg_clif was built in debug mode, the target/out/clif
dir will contain .clif
files for every function. There should be a .unopt.clif
file and a .opt.clif
file containing main
. The .opt.clif
file should contain the call to a
after the loop, while .unopt.clif
should contain it before the loop.
I opened https://github.com/bjorn3/rustc_codegen_cranelift/issues/1020 for making it possible to show the clif ir when cg_clif is compiled in release mode.
Hey @bjorn3 . I'm testing my code before submitting a PR. How do I make sure cg_clif was built in debug mode? It's currently not generating and .clif files as far as I can see (find . -name "*.clif"
)
Just removed --release
argument from ./test.sh
, I'll try again now
Even in debug mode I don't get any .clif output:
$ CHANNEL="debug" ../rustc_codegen_cranelift/cargo.sh run
rustc_codegen_cranelift is build for rustc 1.45.0-nightly (46e85b432 2020-05-24) but the default rustc version is rustc 1.45.0-nightly (a74d1862d 2020-05-14).
Using rustc 1.45.0-nightly (46e85b432 2020-05-24).
Compiling cranelift_test v0.1.0 (/home/omer/rust/cranelift_test)
[cranelift_test : codegen mono items] start
[cranelift_test : codegen mono items] end time: 7.835233ms
Finished dev [unoptimized + debuginfo] target(s) in 0.20s
Running `target/x86_64-unknown-linux-gnu/debug/cranelift_test`
^C
$ find . -name "*.clif"
$
The PR is here: https://github.com/bjorn3/rustc_codegen_cranelift/pull/1021
Ohhh.. the outputs are generated in the rustc_codegen_cranelift directory, not in the current project's directory :-O
Nice, my patch seems to work!
@bjorn3 what does this line mean in clif output: v25 -> v24
I'd expect this to mean "move v25 to v24", but I think it's actually "move v24 to v25"? "v25" is never used in this output (only appears in this line) so I'm not sure.
@bjorn3 another PR arrived: https://github.com/bjorn3/rustc_codegen_cranelift/pull/1022 again, I'm unsure about how to format these files as rustfmt isn't working
Another: https://github.com/bjorn3/rustc_codegen_cranelift/pull/1023
osa1 said:
bjorn3 what does this line mean in clif output:
v25 -> v24
I'd expect this to mean "move v25 to v24", but I think it's actually "move v24 to v25"? "v25" is never used in this output (only appears in this line) so I'm not sure.
This means that v25
is an alias for v24
. Every time Cranelift sees v25
it will pretend that it was actually v24
. These are created by cranelift-frontend
to avoid having to walk over the full clif ir to replace all occurrences of v25
with v24
.
Thanks! When is an alias introduced exactly?
Found a relevant comment:
// Here all the predecessors use a single value to represent our variable
// so we don't need to have it as a block argument.
// We need to replace all the occurrences of val with pred_val but since
// we can't afford a re-writing pass right now we just declare an alias.
// Resolve aliases eagerly so that we can check for cyclic aliasing,
// which can occur in unreachable code.
OK now that all is merged I'll be working on https://github.com/bjorn3/rustc_codegen_cranelift/issues/920
osa1 said:
bjorn3 what does this line mean in clif output:
v25 -> v24
I'd expect this to mean "move v25 to v24", but I think it's actually "move v24 to v25"? "v25" is never used in this output (only appears in this line) so I'm not sure.
This is an alias. EDIT: Didn't see this was already answered, zulip noob
Hey @bjorn3 -- currently looking at #920. What is the issue here exactly? Does the out-of-space error happens in generated code, or in the compiler during compilation? (or when linking?)
@osa1 If you run out of disk space during the compilation, cg_clif will panic when trying to write files. Instead it should just use sess.fatal
to report the error and abort compilation. This can happen during most of the unwraps
in https://github.com/bjorn3/rustc_codegen_cranelift/blob/master/src/archive.rs. It can also happen at https://github.com/bjorn3/rustc_codegen_cranelift/blob/1e70c51f60abc544d9a325c77474190f1719e560/src/driver/aot.rs#L52 and https://github.com/bjorn3/rustc_codegen_cranelift/blob/1e70c51f60abc544d9a325c77474190f1719e560/src/driver/aot.rs#L232. This issue can happen for all IO errors, but on my system that is mostly running out of disk space.
Last updated: Nov 22 2024 at 17:03 UTC