-
Notifications
You must be signed in to change notification settings - Fork 456
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make br_if return its operands #330
Conversation
I don't think this is a useful change, it seems to run counter to consuming values to get them off the stack, and counter to the expression pattern. It is equivalent to For the text presentation it requires the following change or some more complex live range checking.
It is also very brittle as
If there are stats showing that these values are mostly live out then that might be something? I really doubt it but surprise me. If the arguments are going to be duplicated rather than consumed then at least make them general Otherwise please stick to the expression pattern and just pop them and leave it to the producer to duplicate them only when necessary. |
@rossberg-chromium: I can't seem to remember the details behind this, what's the context? |
It's simpler in terms of the stack-machine semantics. This way, The test changes here lgtm. |
@sunfishcode: I get that. Not arguing :) What I am asking is, the last time I remember this discussion, it didn't end with a decision to go this way, WebAssembly/design#539 In fact it seemed like things were going in another direction as shown there. What changed? |
@kripken What changed since those issues was switching to stack machine semantics which makes it more natural to not pop the If there's a significant size motivation (additional |
I see, sounds like the points brought up in WebAssembly/design#703? WebAssembly/design#709 can probably be closed. |
I believe I have made a great case for not doing this, and that there is a very poor case for making this change. We can have a stack machine but that does not in itself justify constraints on the stack machine operators that frustrate a structured presentation language (even frustrate nice stack machine code). The That multiple VMs happened to not pop these values seems besides the point. It is not a big matter, or inefficient, for them to pop these values is it? I think the lack of commitment and demonstration of a structured presentation language, and how this PR change affects it, is causing disproportionate weight to be given to rather minor matters. I challenge the proponents to consider how this is consistent with an expression based presentation language? As noted above, if the stats show that in most case the values are live out then that might be a good reason for making an exception for this operator, but do we have those results? Even if so, please change the PR so that these operators can pick arbitrary values from the stack rather than only using an immediate linear sequence of stack values which is very fragile. Another example. With the current design, if these values are used out of order or multiple times then they would have been saved to local variables and reloaded just for this operator and thus need dropping after it if not popped - in the general case these values need to be popped. |
@JSStats It's fairly straightforward to represent this change in a structured text format. Ignoring the issues that arise with arity>1 (which are not specific to
might be rendered something like this:
(adjust as desired according to your syntactic preferences). Essentially, the |
@sunfishcode Examples are good, thanks. Two things make your example look a simple matter: as you note it deals with only one value, but multiple values need to be considered in the design; the values have already been saved to locals hiding the cost of spilling them to the locals and hiding the difference that the value is still live at the end of the sequence. Part of my argument against this PR as it is, is how fragile the pattern that it matches is and that this makes it poor stack machine code and a poor fit to an expression based presentation. Let me work through some examples to illustrate some of these points: The value might be used out of stack order, in which case the result of
Lets consider an example starting from a point at which values have not already been spilled to local variables, and that is a perfect match to the pattern. Note that all the values are consumed, there are no values live at the end of the sequence except the result of the last call.
Now lets change the order of the arguments to
Let's say
If popping all the arguments to
Thus I suggest just leaving it popping the values from the stack. It may well be possible to work around this proposed change to I understand that a stack machine |
When arity>1, one catch-all approach for structured text formats is to use "let"-like syntax to assign names to values. This is a general solution which is not specific to
As was mentioned above, if having extra drops after |
@sunfishcode Yes, I agree that the 'let'-like syntax is one good approach. I assume this is the same as a value on the values stack referenced via
If you must do this then I would much rather see general support for picking the arguments so that the code is not so brittle. I would be delighted if the But lets say we use this 'let' pattern for
This patten works well using the 'expression' pattern, where values are popped. It's the same pattern that would be used for
There might be some code sequences in which the arguments to The expression pattern, of popping arguments, seems to have the wasm encoding optimized for the high frequency expression pattern where values can be consumed in stack order. This degrades gracefully for local variables, just requiring a Thus my suggestion to not change I don't see many other operators that do keep values live. There are block ends that pass multiple values, but they seem very different as they keep some values and discard the rest, and block ends can use the same general pattern as in the example above, and do not need to be followed by |
@JSStats Your first example appears to be emulating a It is indeed not always easy to generate stack-machine code that pushes operands in the desired order, and It's true that most instructions pop their operands. The value operands of branch instructions are special though, as their value operands aren't normal operands. They're not participating in any computation that the branch is doing; they're just values that the branch is forwarding on the stack to the destination -- to be popped by some other instruction. |
@sunfishcode After looking at the text decoder challenges I now think this PR could be handled, but it will demand that text decoders are two-pass, they will need to pre-compute the number of uses on a first pass so that they know if the arguments to Another way to look at this is that producers could just leave the values on the stack after There are lots of 'connectivity' operators that only copy through references, perhaps shuffling them etc, and it is even possible to define functions that do this, yet that does not make them 'special' enough to keep their arguments live after the operation - so I don't think the 'special' argument helps this PR. Here are some examples of what the text decoder will need to do and some of the lossage:
After second pass:
If the producer has not bothered to
|
@JSStats The text format strategy I sketched out above doesn't require two passes. If Concerning "connectivity" operands, whether or not a |
@sunfishcode Actually it does need two passes. Even the expression pattern requires stacking pending operations until the results are consumed, and in the limit it might need to delay emitting the first operator until the end of a block. In your example above the text decoder will at least need to delay emitting the You make lots of valid point regards 'connectivity', but how do they support this PR? There needs to be a rationale that connects the facts to the decision, and I don't see that? We already have Your case for this PR does seem to depend on |
@JSStats It really doesn't require two passes. We indeed don't have a lot of data on Using In reverse, the adding a |
That redundancy would only occur when the arguments were all in the correct order and only when they were live after the When some or all of the values are not used after the I worry that it's just resistance to exploring the benefits of Re the text decoder, I think your efforts on the text format are great, just wish you would ponder where it will be heading with multiple values and
This is how I would like it presented, and this is what I expect is most familiar:
If the values are passed through then it could also be the following. But this is creating a new definition, it does not seem so familiar. This text code pattern would generally be used when the definition had been modified, not when it was just copied through. Would you consider it good code style to be creating multiple copies of scoped constants?
Another option using
All the above deal with a single value. Try multiple values and we end up with the following general pattern which is pointlessly verbose.
Anyway it seems to be possible to decode away these copies, by considering the live range, so this is not really a show stopper for this PR, perhaps this text decoder discussion should be moved elsewhere. |
Merged into binary-0xc. |
No description provided.