Stream: cranelift

Topic: How to get the immediate number in IR instruction


view this post on Zulip ping ping (Aug 21 2024 at 10:31):

I'm working with Cranelift IR for the first time, and I want to make some modifications to the existing IR. I referred to cranelift-fuzzgen and wrote the following code to traverse each IR instruction in a function. This code can retrieve the opcode of the instruction as well as its args and results. However, I found that args and results seem to pertain to variables. For an instruction like v2 = iconst.i32 32, the args is empty, so how can I retrieve the immediate value 32 in this instruction? Additionally, are there any codes or tutorials related to modifying Cranelift IR that I can refer to?

fn traverse_instrs(func: &mut Function) {

    let mut pos = FuncCursor::new(func);
    while let Some(_block) = pos.next_block() {
        while let Some(inst) = pos.next_inst() {
            let instr_data = pos.func.dfg.insts[inst];

            let opcode = instr_data.opcode();
            let instr_args = pos.func.dfg.inst_args(inst);
            let instr_results = pos.func.dfg.inst_results(inst);
        }
    };
}

view this post on Zulip Afonso Bordado (Aug 21 2024 at 10:37):

In general all of the special information for a given opcode is going to be in the InstructionData struct. We have some functions there to simplify feching values from some instructions, but we don't have anything for fetching the constant value from a const.

So you might have to destructure it. iconst is of type InstructionData::UnaryImm so you can probably do something along these lines.

let imm = match instr_data {
    InstructionData::UnaryImm { imm, ..} => imm,
    _ => panic!("unrecognized instr"),
};

view this post on Zulip Afonso Bordado (Aug 21 2024 at 10:38):

Additionally, are there any codes or tutorials related to modifying Cranelift IR that I can refer to?

Unfortunately I don't think so

view this post on Zulip Afonso Bordado (Aug 21 2024 at 10:40):

For doing more complicated changes in the IR you might want to use FuncCursor that lets you replace whole instructions at certain points

view this post on Zulip ping ping (Aug 22 2024 at 07:53):

Afonso Bordado said:

For doing more complicated changes in the IR you might want to use FuncCursor that lets you replace whole instructions at certain points

Thank you very much for your answer :+1:

view this post on Zulip ping ping (Sep 05 2024 at 03:19):

@Afonso Bordado
Hi, I encountered a strange control flow behavior with the following piece of code. The control flow generated seems unusual and not as expected.

let mut func = Function::new();
        let block0 = func.dfg.make_block();
        let cond = func.dfg.append_block_param(block0, types::I32);
        let block1 = func.dfg.make_block();
        let block2 = func.dfg.make_block();

        let br_block1_block0_block2;

        {
            let mut cur = FuncCursor::new(&mut func);
            cur.insert_block(block0);
            cur.insert_block(block1);
            br_block1_block0_block2 = cur.ins().brif(cond, block0, &[], block2, &[]);
            cur.insert_block(block2);
        }

        let block3 = func.dfg.make_block();
        func.layout.remove_block(block2);
        {
            let mut cur = FuncCursor::new(&mut func);
            let mut cur = cur.at_last_inst(block1);
            // let removed_instr = cur.remove_inst();
            cur.ins().brif(cond, block0, &[], block3, &[]);
            cur.insert_block(block3);
        }

The control flow graph generated by this code is as follows:
image.png

In the code, I didn’t add any instructions to block3, but the generated control flow graph shows that block3 contains the br_if instruction, and these instructions were originally in block1. Only when I uncomment the lines in the code can the correct control flow graph be generated.

view this post on Zulip Afonso Bordado (Sep 05 2024 at 04:30):

I'm not entirely sure why that br_if gets placed there, but when inserting the first br_if the cursor is not explicitly placed anywhere, so I'm not sure what the behaviour is there


Last updated: Dec 23 2024 at 12:05 UTC