bytecodealliance / wasmtime

A fast and secure runtime for WebAssembly
https://wasmtime.dev/
Apache License 2.0
15.14k stars 1.27k forks source link

FunctionBuilder.cursor should not set pristine to false #1125

Open jyn514 opened 5 years ago

jyn514 commented 5 years ago

When FunctionBuilder.cursor() is called, it marks the current EBB as not pristine, even if it has no instructions. API users then have no way of distinguishing between an empty and non-empty block. This is compounded by API users not having any way to get the current block without using cursor.

The call chain for cursor looks like this: cursor -> ensure_inserted_ebb_block -> self.func_ctx.ebbs[ebb].pristine = false;

This is a particular concern for me while generating C case statements, my code looks like this:

    fn case(&mut self, switch: Switch, constexpr: u64, builder: &FunctionBuilder) {
        if builder.is_pristine() {
            let current = builder.cursor().current_ebb().unwrap();
            switch.set_entry(constexpr, current);
        } else {
            let new = builder.create_ebb();
            switch.set_entry(constexpr, new);
            self.switch_to_block(new, builder);
        };
    }

If I call case twice in a row, then I will make two different EBB blocks, even if the first was never filled. As far as I can tell, there's nothing I can do from a user perspective to avoid this. (this is why I was generating empty EBBs in https://github.com/CraneStation/cranelift/issues/1059)

jyn514 commented 5 years ago

(I had another bug in my code that I wasn't jumping to the new block, but the pristine issue is still present, the block is just empty except for an unconditional jump now.)