Design: block equivalent that can't be jumped to?

Created on 23 Mar 2016  路  13Comments  路  Source: WebAssembly/design

Would it make sense to have block equivalent that did not increment the depth? When transforming the AST, you often need to add blocks but this messes up brs that are beneath it if they are not labeled (which is not impossible to deal with). Furthermore blocks are often used just for structuring but never br to.

Most helpful comment

I've also run into this a number of times with the spec.

The cleanest solution would be to separate concerns entirely: that is, have a unary label operator that increments the depth (and can be applied to any operand), and separately a block that merely implements sequencing, but has no implicit label (nor does any other operator, except loop).

One additional advantage would be that we could decide to type-annotate label in order to aid type checking in a post-order decoder, without paying the cost of a type annotation on every block.

All 13 comments

I definitely could see the benefit in this. Not sure if it's worth burning an opcode now, but I suppose that won't be a problem when/if we have an opcode table of some kind.

I'm not sure I understand: is this purely a tooling concern, before generating the final .wasm file? I'm not convinced that we want such features to show through in the .wasm file.

The binary encoding already has enough information to determine which blocks need labels by checking which are used. I think it has been conceded that tools transforming the AST are expected to use an intermediate representation of the whole functions AST and decode/encode between this so it is not a design goal to support easy transformation of the binary encoding. It might still help reduce the encoding size by reducing the block depths, but perhaps some numbers are needed and it might be insignificant.

I'm not sure I understand: is this purely a tooling concern, before generating the final .wasm file?

yes @jfbastien I think it might be a tooling concern. I want to do the AST injection as suggested here to make nans determinisic (along with other things). Also it should be done in the verification step and in a single pass.

That said; it was an after thought that it might buy more efficiency for jit's because there would be less jump destinations to track

@wanderer Good point about the runtime compiler having 'less jump destinations to track'. Perhaps this would show up in the overhead of tracking the SSA environments and perhaps @titzer could answer that?

Can't speak for V8, but I would be surprised if this is a concern. For us, there is no cost. First thing our JIT does is a transformation to lower level IR, and any label which is not referenced by a branch will be lost. Also, even beyond that, labels maintain a list of branches which target them, so it is very cheap to see if a label is unreferenced and ignore/remove it.

Right, I'm not concerned about cost VM-wise, I'm concerned about adding things in the binary format that aren't needed and don't provide value to the format. It's useful elsewhere and should probably live elsewhere :-)

But in the grand scheme of things, if we're going to add something that doesn't help the binary format then I'd rather have small things like these.

We've added other concessions to the binary format for things that are primarily about making it easier to make context-free decisions/modifications (e.g. explicit arities for function calls). This seems like another reasonable step in that direction. That said, I don't feel strongly about this.

I've also run into this a number of times with the spec.

The cleanest solution would be to separate concerns entirely: that is, have a unary label operator that increments the depth (and can be applied to any operand), and separately a block that merely implements sequencing, but has no implicit label (nor does any other operator, except loop).

One additional advantage would be that we could decide to type-annotate label in order to aid type checking in a post-order decoder, without paying the cost of a type annotation on every block.

@rossberg-chromium interesting, I like the idea of type-annotating label.

In a postorder scheme where if bodies, function bodies, and loops are all already implicitly blocks, it should be fairly rare to need extra blocks just for structuring. And so far, implementations I'm familiar with have a similar outlook as @MikeHolman's; the extra labels are not a significant overhead.

I'm not convinced of the value of type annotations on label: we currently just accumulate the "join" of all branches for each block and that doesn't seem too complex or expensive. Also, a subtle distinction is that previous concessions were for the benefit of _parsing_ (allowing parsing to not depend on any context).

regarding what @sunfishcode said, i think this issue should be delayed PR #628 is resolved. So i'm going to close this for now. Once we have postorder, lets revisit and see if the issue is still relevant.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

void4 picture void4  路  5Comments

chicoxyzzy picture chicoxyzzy  路  5Comments

beriberikix picture beriberikix  路  7Comments

Artur-A picture Artur-A  路  3Comments

badumt55 picture badumt55  路  8Comments