Stream: general

Topic: Help on writing a JIT compiler with arithmetic on f32


view this post on Zulip Farooq (Nov 24 2024 at 13:29):

Hello again! It seems that store on r_ptr here has been used wrong. It gives a SEGFAULT. Where am I wrong?

https://codeberg.org/farooqkz/wakegp/src/branch/master/src/compiler.rs#L159
https://codeberg.org/farooqkz/wakegp/src/branch/master/src/compiler.rs#L163

r_ptr comes from the second argument of the function(see this and this). The offset is calculated by the index(r0) multiplied by size of each element in the array(https://codeberg.org/farooqkz/wakegp/src/branch/master/src/compiler.rs#L188).

Thanks in advance!

wakegp - Detecting wake words using Linear Genetic Programming
wakegp - Detecting wake words using Linear Genetic Programming
wakegp - Detecting wake words using Linear Genetic Programming
wakegp - Detecting wake words using Linear Genetic Programming

view this post on Zulip Farooq (Nov 24 2024 at 20:36):

The problem was that I had to map a memory and make it executable. I still have other questions. Should I ask here or open a new topic?

view this post on Zulip bjorn3 (Nov 24 2024 at 22:09):

Asking here is fine. Won't get around to answering any questions today (CET) though.

view this post on Zulip Farooq (Nov 25 2024 at 17:29):

I cannot find brnz in the docs which is used here:
https://github.com/Rodrigodd/bf-compiler/blob/master/cranelift-jit/src/main.rs#L219

Interpreted, optimized, JITed and compiled implementations of the Brainfuck lang. - Rodrigodd/bf-compiler

view this post on Zulip Farooq (Nov 25 2024 at 17:31):

I basically doing an fcmp, if it's true, there will be a jump, either backward or forward within the function(jump offsets are guarrented to be always inside my function). If it's false, there won't be any jump.

view this post on Zulip Farooq (Nov 25 2024 at 17:32):

Furthermore, for forward jumps, how can I jump to an address which I've yet to write the instructions for? I mean if I don't have instructions yet, how do I get the jump address?

Edit: nvm this. There is an example in the bf compiler repository.

view this post on Zulip Farooq (Nov 25 2024 at 17:36):

hmm it seems that repo is using an ancient version of cranelift :)

view this post on Zulip Farooq (Nov 25 2024 at 17:39):

There is br_if and br_table. The first accepts arguments for both the true and else/false cases which does not match in my use case. The latter seems more like it, but I'm unsure if I can do backward jumps with it.

view this post on Zulip bjorn3 (Nov 26 2024 at 09:46):

Clif ir uses basic blocks rather than extended basic blocks, so every branch instruction is always jumps to another block and must be the last instruction in the block. In the backend a jump to the block immediately following the current block will be optimized away though.

view this post on Zulip bjorn3 (Nov 26 2024 at 09:47):

brz/brnz no longer exist and have been replaced by br_if when we moved from extended basic blocks to basic blocks.

view this post on Zulip Farooq (Nov 27 2024 at 17:08):

Can you please post an example on how to use do a simple if else statement like in C with cranelift?

view this post on Zulip Chris Fallin (Nov 27 2024 at 17:10):

Here's an example of the use of brif in Wasmtime's translation to CLIF: https://github.com/bytecodealliance/wasmtime/blob/66910067642ce2ddf5509845306508f89a24fc9e/crates/cranelift/src/func_environ.rs#L913

A fast and secure runtime for WebAssembly. Contribute to bytecodealliance/wasmtime development by creating an account on GitHub.

view this post on Zulip Chris Fallin (Nov 27 2024 at 17:10):

note the "continuation block" -- that's a common idiom, if you have what is logically a "one-way branch" (if condition, go somewhere else)

view this post on Zulip Chris Fallin (Nov 27 2024 at 17:10):

and note you can create blocks so you have their labels for targets before you fill them in

view this post on Zulip Farooq (Nov 27 2024 at 17:11):

Thanks!

view this post on Zulip Farooq (Jan 26 2025 at 19:15):

Hello. I've got time to get back to this. A question. If I just want to continue execution in the else, I should put the rest of the program and the continue block. right?

view this post on Zulip Farooq (Jan 26 2025 at 20:40):

More on details, I've got a function. It executes sequentially and then returns one of memory cells at the end. I want to return a constant(-1.0f32) early if a condition is met. Let me know if there is a better approach.

view this post on Zulip Farooq (Jan 30 2025 at 10:57):

Bump

view this post on Zulip Chris Fallin (Jan 31 2025 at 19:12):

Sorry, it's hard to help you debug your implementation without actually diving into it (and in general I don't have time to dive into others' projects and help them debug). The abstraction that Cranelift provides is hopefully clear: blocks, and jumps between them. How you map your control flow to that is up to you

view this post on Zulip Farooq (Feb 01 2025 at 14:27):

Thanks. But I still don't know how to use brif. If I want to continue execution, should I create a new block for the rest of instructions and make it else block?
I mean there is a then block which is my code I want to execute. But if the condition is not met, there is else block. What the else block would be? the continuation of the instructions? And then should I create new blocks whenever there is a condition as continuation block?

view this post on Zulip bjorn3 (Feb 01 2025 at 15:08):

If you have something like if (cond) { foo... } else { bar... } rest... in source code you can lower this to clif ir like

block0:
    brif cond, block1, block2

block1:
    foo...
    jump block3

block2:
    bar...
    jump block3

block3:
    rest...

view this post on Zulip Farooq (Feb 01 2025 at 15:16):

I have if (cond) { foo } rest...

view this post on Zulip Farooq (Feb 01 2025 at 15:16):

so I was right it seems. Everytime a condition comes, I should create a new block for the rest

view this post on Zulip Farooq (Feb 01 2025 at 19:46):

In this example, what is usage of null block? https://github.com/bytecodealliance/wasmtime/blob/66910067642ce2ddf5509845306508f89a24fc9e/crates/cranelift/src/func_environ.rs#L902

A lightweight WebAssembly runtime that is fast, secure, and standards-compliant - bytecodealliance/wasmtime

view this post on Zulip Chris Fallin (Feb 01 2025 at 20:37):

But if the condition is not met, there is else block. What the else block would be? the continuation of the instructions? And then should I create new blocks whenever there is a condition as continuation block?

Yes, exactly; to get a deeper understanding of this, it might be good to read about basic blocks and control-flow graphs. These are the fundamental compiler concepts at play here.

Specifically, the semantics of brif are if (condition) goto then_block; else goto else_block;. That's fully general and you can translate whatever control-flow you need into that, but as you note, you may need to create an arbitrary number of blocks.

In this example, what is usage of null block? https://github.com/bytecodealliance/wasmtime/blob/66910067642ce2ddf5509845306508f89a24fc9e/crates/cranelift/src/func_environ.rs#L902

Here we are getting into the specifics of Wasmtime's internal representations, but in that code, null_block is the else-target of a brif a few lines below, and is branched to if value is false. Specifically here it is testing if an entry in a table is null or not (so all-zeroes is "false" to brif and branches to null_block).

In computer science, a control-flow graph (CFG) is a representation, using graph notation, of all paths that might be traversed through a program during its execution. The control-flow graph was conceived by Frances E. Allen,[1] who noted that Reese T. Prosser used boolean connectivity matrices for flow analysis before.[2]

view this post on Zulip Farooq (Feb 02 2025 at 07:20):

Thanks


Last updated: Feb 28 2025 at 03:10 UTC