Stream: cranelift

Topic: Function declaration confusion


view this post on Zulip osa1 (May 13 2020 at 23:32):

I have functions A and B, and B uses a pointer to A (but does not call it!). How do I need to declare A in B? I generate code for A before B in the same module, which looks like

function u0:34(i64, i64) -> i64 system_v {
    sig0 = (i64) -> i64 system_v
    fn0 = u0:0 sig0

block0(v0: i64, v2: i64):
    v1 = load.i64 v0+8
    v3 = iadd v1, v2
    return v3
}

Now when generating B I use Variable(34) (which is the previous function shown above), but it fails with variable Variable(34) is used but its type has not been declared.

view this post on Zulip bjorn3 (May 14 2020 at 09:13):

@osa1 You need to use module.declare_func_in_func(a_func_id, &mut b_func) to get a FuncRef to A.

view this post on Zulip osa1 (May 14 2020 at 09:50):

I'm confused, why do I need a FuncRef? I'm not calling it, I'm just returning it.

view this post on Zulip bjorn3 (May 14 2020 at 09:53):

In that case you can use the func_addr instruction to get the address of the function from the FuncRef.

view this post on Zulip osa1 (May 14 2020 at 09:59):

What is the iAddr argument for in func_addr?

view this post on Zulip bjorn3 (May 14 2020 at 10:07):

The pointer type. Eg i64 on 64bit systems and i32 on 32bit systems.

view this post on Zulip osa1 (May 14 2020 at 10:08):

So if I understand this correctly, I need to get a FuncId for every function in this compilation unit first, and then maintain a map from my variable type to FuncIds, and check, on every use, whether the used variable is a function

view this post on Zulip osa1 (May 14 2020 at 10:08):

If it is then I need to first import it (declare_func_in_func) and then get address of it using func_addr

view this post on Zulip osa1 (May 14 2020 at 10:08):

In my language I don't do direct calls (maybe later after optimizations)

view this post on Zulip bjorn3 (May 14 2020 at 10:12):

Yes, you need to use declare_func_in_func followed by func_addr to get the address of a function.

view this post on Zulip osa1 (May 14 2020 at 10:13):

Thank you! Really helpful

view this post on Zulip osa1 (May 14 2020 at 10:20):

When building a module with multiple functions do I have to use https://docs.rs/cranelift-codegen/0.63.0/cranelift_codegen/struct.Context.html or can I create a FunctionBuilder for every function?

view this post on Zulip osa1 (May 14 2020 at 10:21):

So instead of FunctionBuilder::new(&mut context.func, ...); can I do let mut func = Function::with_name_signature(...); let mut builder = FunctionBuilder::new(&mut func, &mut fn_builder_ctx); ?

view this post on Zulip osa1 (May 14 2020 at 10:28):

Is the "entry basic block" stuff gone in the latest version? Saw that in an older code

view this post on Zulip bjorn3 (May 14 2020 at 10:34):

You can reuse Context for multiple functions if you call .clear() in between. This is not necessary, but improves performance. You can't reuse FunctionBuilder. Everything that is reusable for cranelift-frontend is stored in FunctionBuilderContext instead.

view this post on Zulip bjorn3 (May 14 2020 at 10:35):

What do you mean with "entry basic block" stuff?

view this post on Zulip osa1 (May 14 2020 at 10:36):

create_ebb and append_ebb_params_for_function_params, they seem to be gone now

view this post on Zulip osa1 (May 14 2020 at 10:36):

How do I create an entry basic block and declare function arguments there in the latest version on crates.io?

view this post on Zulip osa1 (May 14 2020 at 10:50):

If I want the function parameters to be available in all blocks of the function do I need to do `builder.append_block_params_for_function_params(block); for every block?

view this post on Zulip bjorn3 (May 14 2020 at 10:53):

create_ebb has been renamed to create_block.

view this post on Zulip bjorn3 (May 14 2020 at 10:53):

osa1 said:

If I want the function parameters to be available in all blocks of the function do I need to do `builder.append_block_params_for_function_params(block); for every block?

Only do it for the entry block. You can the access the params from all blocks.

view this post on Zulip osa1 (May 14 2020 at 10:54):

I don't understand how to do that. Since entry block creating is not different than others, how do I specify which block is the entry block?

view this post on Zulip bjorn3 (May 14 2020 at 10:54):

Just use builder.block_params(entry_block)[0] to get the first param.

view this post on Zulip bjorn3 (May 14 2020 at 10:54):

The first block inserted is the entry block.

view this post on Zulip osa1 (May 14 2020 at 10:55):

How do I insert a block?

view this post on Zulip bjorn3 (May 14 2020 at 10:55):

aka the first time you call switch_to_block that block will become the entry block.

view this post on Zulip osa1 (May 14 2020 at 10:55):

The first block created?

view this post on Zulip osa1 (May 14 2020 at 10:55):

Ah

view this post on Zulip osa1 (May 14 2020 at 10:57):

I still can't use arguments ...

view this post on Zulip osa1 (May 14 2020 at 10:57):

variable Variable(12) is used but its type has not been declared

view this post on Zulip osa1 (May 14 2020 at 10:58):

Hmm

view this post on Zulip osa1 (May 14 2020 at 10:59):

How do I get Values of the arguments after append_block_params_for_function_params?

view this post on Zulip bjorn3 (May 14 2020 at 10:59):

Where does Variable(12) come from?

view this post on Zulip osa1 (May 14 2020 at 10:59):

Ahh! Found ti!

view this post on Zulip osa1 (May 14 2020 at 10:59):

Thanks @bjorn3

view this post on Zulip osa1 (May 14 2020 at 11:02):

I'll get the values of args using entry_block.block_params(), right?

view this post on Zulip osa1 (May 14 2020 at 11:10):

Do I really ahve to invent Variable numbers myself or is there a method in cranelift for that?

view this post on Zulip osa1 (May 14 2020 at 11:16):

In other words, if I ahve let x = y in my language, do I have to invent a cranelift Variable for that x myself? Any invariants about the u32 for it? (e.g. should variable u32s be consecutive or can I pick 100 for the first var and 123123 for the second?)

view this post on Zulip osa1 (May 14 2020 at 11:36):

What does this mean: assertion failed: func_ctx.is_empty() ?

view this post on Zulip osa1 (May 14 2020 at 11:43):

Figured out the func_ctx.is_empty() stuff. Still a bit confused about variables though

view this post on Zulip osa1 (May 14 2020 at 11:47):

Given a FuncId is there a way to get the signature of the function?

view this post on Zulip osa1 (May 14 2020 at 11:54):

Welp unimplemented type: types::INVALID ...

view this post on Zulip osa1 (May 14 2020 at 12:11):

But the good news is I can generate 2 functions before this error :grinning_face_with_smiling_eyes:

view this post on Zulip bjorn3 (May 14 2020 at 12:19):

osa1 said:

I'll get the values of args using entry_block.block_params(), right?

yes

view this post on Zulip bjorn3 (May 14 2020 at 12:20):

osa1 said:

In other words, if I ahve let x = y in my language, do I have to invent a cranelift Variable for that x myself? Any invariants about the u32 for it? (e.g. should variable u32s be consecutive or can I pick 100 for the first var and 123123 for the second?)

yes, you can use arbitrary numbers, but the memory usage is proportional to the largest number you choose I believe.

view this post on Zulip bjorn3 (May 14 2020 at 12:21):

osa1 said:

Given a FuncId is there a way to get the signature of the function?

I don't think so

view this post on Zulip osa1 (May 14 2020 at 13:39):

OK back at yak shaving -- @bjorn3 do you know what this error means: unimplemented type: types::INVALID

view this post on Zulip osa1 (May 14 2020 at 13:41):

Happens on seal_block()

view this post on Zulip osa1 (May 14 2020 at 13:45):

I think I'm not initializing something that I'm supposed to but I don't know what

view this post on Zulip bjorn3 (May 14 2020 at 14:11):

@osa1 Is there a backtrace?

view this post on Zulip bjorn3 (May 14 2020 at 14:14):

Probably here: https://github.com/bytecodealliance/wasmtime/blob/0592b5a9956a7f8b51abf79830d3b70521c9aa4d/cranelift/frontend/src/ssa.rs#L206

Standalone JIT-style runtime for WebAssembly, using Cranelift - bytecodealliance/wasmtime

view this post on Zulip bjorn3 (May 14 2020 at 14:16):

Did you call builder.declare_var with the type of the variable before you used it?

view this post on Zulip osa1 (May 14 2020 at 14:27):

Hmm I think that's the problem, yes. I have some built-in functions (implemented in C), I think I"m not declaring it currently

view this post on Zulip osa1 (May 14 2020 at 14:27):

Hmm I think that's the problem, yes. I have some built-in functions (implemented in C), I think I"m not declaring it currently


Last updated: Dec 23 2024 at 13:07 UTC