walrus icon indicating copy to clipboard operation
walrus copied to clipboard

How to replace one instruction with a block

Open chenyan2002 opened this issue 4 years ago • 0 comments

Summary

We can use visit_instr_mut to easily replace one instruction with another instruction. But how to replace the instruction with a block? It seems there is no direct way of creating InstrSeqBuilder, and I need to use FunctionBuilder and dangling_instr_seq. The following code compiles, but got a runtime error. Any help?

thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `30`,
 right: `387`', /.../walrus-0.19.0/src/module/functions/local_function/mod.rs:109:14

[Update] I can create a new function, and replace the instruction to call the new function. Is this an expected pattern, or there is a better way?

Additional Details

    struct Replacer<'a> {
        types: &'a mut ModuleTypes,
        func_id: FunctionId,
    }
    impl<'a> ir::VisitorMut for Replacer<'a> {
        fn visit_instr_mut(&mut self, instr: &mut ir::Instr, _instr_loc: &mut ir::InstrLocId) {
            if let ir::Instr::Call(ir::Call { func }) = instr {
                if *func == self.func_id {
                    let mut builder = FunctionBuilder::new(self.types, &[], &[]);
                    let mut seq = builder.dangling_instr_seq(None);
                    seq.drop().i32_const(...).call(...);
                    *instr = ir::Block { seq: seq.id() }.into();
                }
            }
        }
    }

chenyan2002 avatar Aug 03 '21 00:08 chenyan2002