Stream: cranelift

Topic: Use a Data Address from cranelift_module in Function


view this post on Zulip Chris Clark (Jul 18 2024 at 18:59):

I have this adding of const data section

    pub fn add_const_data(&mut self, name: &str, contents: Vec<u8>) -> () {
        self.data.define(contents.into_boxed_slice());
        let id = self
            .obj_mod
            .declare_data(name, Linkage::Export, false, false)
            .unwrap();
        self.obj_mod.define_data(id, &self.data).unwrap();
    }

My language code looks like the following.

const z = 1
pub const main = fn() usize {
    const m = 7
    const x = 4
    return x + m + z
}

When everything was defined within the function it was easy for me to just reference it like so.

    pub fn handle_sym(&self, op: &SymbolAccess) -> ResultFir<Variable> {
        Ok(Variable::from_u32(
            *self.scope.table.get(&op.ident).unwrap(),
        ))
    }

But there isn't a symbol table for this since it just has an address.

view this post on Zulip bjorn3 (Jul 18 2024 at 19:59):

You can use module.declare_data_in_func passing in both the id returned from declare_data and a mutable reference to the Function you are creating. This method then returns a GlobalValue you can pass to the global_value instruction to get a Value representing the address of the data object.

view this post on Zulip Chris Clark (Jul 18 2024 at 21:03):

mind.blown() Do you have an example?

Do i need to tell it to dereference that Value that is returned?

view this post on Zulip bjorn3 (Jul 19 2024 at 14:40):

If you want to get the value stored in the global variable you did need to load from the address returned by global_value and if you want to change the value you need to use store.

view this post on Zulip Chris Clark (Jul 21 2024 at 19:33):

I think I see what you mean. I need to do some refactoring then. To pass the object_module to my IR builder.

@bjorn3 Since the IR is built to be at the function level, do you recommend an object file with all the data, and then for every function a separate object file? This should also help with caching in between builds if the function doesn't change but some other does.

view this post on Zulip bjorn3 (Jul 21 2024 at 19:36):

Having a separate object file for each function would likely make the linker slower. The way rustc handles this is by splitting all functions between a set of codegen units each corresponding to a single object file. The amount of codegen units is fixed to 16 or 256 depending on if incr comp is enabled or not. 256 when it is enabled to maximize reuse of object files when none of the functions inside it change, and 16 for better optimizations while still enabling each codegen unit to be compiled in parallel when no reuse would happen anyway due to incr comp being disabled. (You can override this using -Ccodegen-units)


Last updated: Oct 23 2024 at 20:03 UTC