Hi, I'm writing a project that uses Cranelift as a JIT backend for dynamic recompilation. Is there any way to get a GraphViz printout of the basic blocks + instructions from Cranelift for ease of debugging? Or any other debugging outputs I could use, other than just disassembling the JIT output?
Hey, You should be able to get an output in the form of Cranelift IR by calling display on a FunctionBuilder or Function and get a string with the Cranelift IR Module. (Here's a more complete example)
This gets you an output a bit higher level than disassembly. I don't know if we have a GraphViz formatter.
Oops, it looks like you don't get a String directly, but a formattable object, which you can pass into println!
like: println!("{}", func.display(None));
Or into format! :smile:
Great, thank you!
Is there any way to get a GraphViz printout of the basic blocks + instructions from Cranelift for ease of debugging?
Yes, clif-util has the print_cfg
subcommand. You can also use cranelift_codegen::cfg_printer::CFGPrinter
.
Afonso Bordado said:
Hey, You should be able to get an output in the form of Cranelift IR by calling display on a FunctionBuilder or Function and get a string with the Cranelift IR Module. (Here's a more complete example)
This gets you an output a bit higher level than disassembly. I don't know if we have a GraphViz formatter.
Is there a way to do this currently? display
method seems to have been removed since you've commented
The Function
has a display
method in the latest version (though indeed it seems the analogous one on FunctionBuilder
went away as part of some recent cleanups (?)): docs here
Chris Fallin said:
The
Function
has adisplay
method in the latest version (though indeed it seems the analogous one onFunctionBuilder
went away as part of some recent cleanups (?)): docs here
Thanks. How do I acquire a Function
? I'm following along with the JIT demo and all I have access to is a FunctionBuilder
.
Oh, I see, it's func
on FunctionBuilder
Somewhat related to this, I've been trying to figure out how to associate user-generated ExternalName
s to strings or to otherwise make cranelift output use actual names for functions and stuff instead of numbers, is that possible?
Currently this is handled outside of the core Cranelift IR types -- the idea is that the embedding, if it has a concept of symbol names or whatnot, would carry a mapping
there's some overlap between this design choice and the "function-local compilation" choice: keeping a symtab within CLIF would mean duplicating symbols in each function that refers to them, unless we add some module-level context
but, plugging in some custom mapping for symbols to text names during pretty-printing is not a bad idea -- I'm open to something like that at least!
See also https://github.com/bjorn3/rustc_codegen_cranelift/blob/master/src/pretty_clif.rs
Hi, I'm trying to print out some cranelift IR with display
, but I keep getting the below panic, and it happens only if the function i'm printing has a call
in it. Anyone have an idea?
Panic:
thread '<unnamed>' panicked at /home/joefe/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cranelift-codegen-0.91.1/src/ir/extname.rs:191:58:
index out of bounds: the len is 0 but the index is 0
stack backtrace:
0: rust_begin_unwind
at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:597:5
1: core::panicking::panic_fmt
at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:72:14
2: core::panicking::panic_bounds_check
at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:180:5
3: <usize as core::slice::index::SliceIndex<[T]>>::index
at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/slice/index.rs:261:10
4: core::slice::index::<impl core::ops::index::Index<I> for [T]>::index
at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/slice/index.rs:18:9
5: <alloc::vec::Vec<T,A> as core::ops::index::Index<I>>::index
at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/alloc/src/vec/mod.rs:2728:9
6: <cranelift_entity::primary::PrimaryMap<K,V> as core::ops::index::Index<K>>::index
at /home/joefe/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cranelift-entity-0.91.1/src/primary.rs:202:20
7: <cranelift_codegen::ir::extname::DisplayableExternalName as core::fmt::Display>::fmt
at /home/joefe/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cranelift-codegen-0.91.1/src/ir/extname.rs:191:58
8: core::fmt::rt::Argument::fmt
at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/fmt/rt.rs:138:9
9: core::fmt::write
at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/fmt/mod.rs:1114:21
10: <cranelift_codegen::ir::extfunc::DisplayableExtFuncData as core::fmt::Display>::fmt
at /home/joefe/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cranelift-codegen-0.91.1/src/ir/extfunc.rs:363:9
11: core::fmt::rt::Argument::fmt
at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/fmt/rt.rs:138:9
12: core::fmt::write
at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/fmt/mod.rs:1114:21
13: cranelift_codegen::write::FuncWriter::super_entity_definition
at /home/joefe/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cranelift-codegen-0.91.1/src/write.rs:131:9
14: cranelift_codegen::write::FuncWriter::write_entity_definition
at /home/joefe/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cranelift-codegen-0.91.1/src/write.rs:119:9
15: cranelift_codegen::write::FuncWriter::super_preamble
at /home/joefe/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cranelift-codegen-0.91.1/src/write.rs:84:17
16: cranelift_codegen::write::FuncWriter::write_preamble
at /home/joefe/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cranelift-codegen-0.91.1/src/write.rs:38:9
17: cranelift_codegen::write::decorate_function
at /home/joefe/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cranelift-codegen-0.91.1/src/write.rs:191:19
18: cranelift_codegen::write::write_function
at /home/joefe/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cranelift-codegen-0.91.1/src/write.rs:164:5
Wasm throwing the error:
(module
(type (;0;) (func (param i32 i32) (result i32)))
(type (;1;) (func (param i32) (result i32)))
(func (;0;) (type 0) (param i32 i32) (result i32)
(local i32)
local.get 0
local.get 1
i32.add
local.set 2
local.get 2
return)
(func (;1;) (type 1) (param i32) (result i32)
(local i32 i32 i32 i32)
i32.const 2
local.set 1
local.get 0
local.get 1
call 0
local.set 2
i32.const 5
local.set 3
local.get 2
local.get 3
i32.add
local.set 4
local.get 4
return)
(table (;0;) 1 1 funcref)
(memory (;0;) 16)
(global (;0;) (mut i32) (i32.const 1048576))
(global (;1;) i32 (i32.const 1048576))
(global (;2;) i32 (i32.const 1048576))
(export "memory" (memory 0))
(export "add" (func 0))
(export "add_two" (func 1))
(export "__data_end" (global 1))
(export "__heap_base" (global 2)))
Hi @Joseph Kanichai -- can you clarify exactly the method you are using to construct the CLIF?
For example, I don't get a panic from this:
$ wasmtime compile --emit-clif clif input.wat
and fwiw, that yields the following clif files:
clif/wasm_func_0.clif
:
function u0:0(i64 vmctx, i64, i32, i32) -> i32 tail {
gv0 = vmctx
gv1 = load.i64 notrap aligned readonly gv0+8
gv2 = load.i64 notrap aligned gv1
stack_limit = gv2
block0(v0: i64, v1: i64, v2: i32, v3: i32):
@007e v5 = iconst.i32 0
@0084 v6 = iadd v2, v3
@0089 return v6
}
clif/wasm_func_1.clif
:
function u0:1(i64 vmctx, i64, i32) -> i32 tail {
gv0 = vmctx
gv1 = load.i64 notrap aligned readonly gv0+8
gv2 = load.i64 notrap aligned gv1
sig0 = (i64 vmctx, i64, i32, i32) -> i32 tail
fn0 = colocated u0:0 sig0
stack_limit = gv2
block0(v0: i64, v1: i64, v2: i32):
@008d v4 = iconst.i32 0
@008f v5 = iconst.i32 2
@0097 v6 = call fn0(v0, v0, v2, v5) ; v5 = 2
@009b v7 = iconst.i32 5
@00a3 v8 = iadd v6, v7 ; v7 = 5
@00a8 return v8
}
can you clarify exactly the method you are using to construct the CLIF?
to add a little more color here, I ask because it looks like you are indexing into some kind of PrimaryMap
with a key that doesn't exist in that map, which indicates a bug somewhere in that general viscinity
fitzgen (he/him) said:
can you clarify exactly the method you are using to construct the CLIF?
to add a little more color here, I ask because it looks like you are indexing into some kind of
PrimaryMap
with a key that doesn't exist in that map, which indicates a bug somewhere in that general viscinity
I'm calling .display
on cranelift_codegen::ir::function
how did you get the ir::Function
?
and did you modify it yourself at all?
fitzgen (he/him) said:
and did you modify it yourself at all?
I have not performed any modifications, and It's inside a compile function inside wasmer, here.
wasmer is not associated with the bytecode alliance, uses a very outdated version of cranelift, and we don't provide support for it here. if you would like to try out wasmtime, we can help you out with that, but otherwise you're on your own with wasmer issues. good luck!
fitzgen (he/him) Yep looks like wasmer's old cranelift version has issues. Just tried it in wasmtime's repo and it's running fine.
Last updated: Dec 23 2024 at 12:05 UTC