Skip to content

Refactor i64 lowering to use RAII temp vars#1177

Merged
kripken merged 3 commits intoWebAssembly:masterfrom
tlively:i64-lowering-temp-raii
Sep 24, 2017
Merged

Refactor i64 lowering to use RAII temp vars#1177
kripken merged 3 commits intoWebAssembly:masterfrom
tlively:i64-lowering-temp-raii

Conversation

@tlively
Copy link
Copy Markdown
Member

@tlively tlively commented Sep 10, 2017

No description provided.

}

TempVar& operator=(TempVar&& rhs) {
assert(!rhs.moved);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if:

TempVar a(1, pass);
TempVar b(2, pass);
TempVar c(3, pass);
a = b;
b = c;

?
(having only looked at this struct in this PR)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code doesn't compile because the assignment operator has been deleted. However, if you used std::move to use move assignment, you're totally right that this is completely broken. It leaks 1 and 3 and frees 2. I'll fix this when I have time, probably tomorrow or Friday.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure? This seems to work OK: https://godbolt.org/g/zFjpFw

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would compile fine but it would leak the 1 when a was overwritten with b, since destroying a after that frees the 2 instead of the 1. However, the sample code you linked contains the fixed version that frees the old value before overwriting it in the move assignment operator.

Copy link
Copy Markdown
Member

@binji binji Sep 15, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah sorry, didn't realize I was looking at the fixed code. :-)

TempVar(Index idx, I64ToI32Lowering& pass) :
idx(idx), pass(pass), moved(false) {}

TempVar(TempVar&& other) : idx(other), pass(other.pass), moved(false) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i wonder if it's important to handle moving here? is it for correctness, or to save locals? if just to save locals, we can depend on opts to fix that up later, and this logic could be simpler.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, being move-only is critical for the correctness of these vars. When an expression is lowered its high bits are stored in a new variable and this variable is stored in a lookup table to be retrieved by the expression's parent. The parent can choose to reuse or free the variable, but until the parent expression is processed, the variable must not be used for anything else.

By only allowing variables to be moved and not copied, we can ensure that a variable cannot be improperly reused. Without the move semantics it would be impossible to use RAII for these variables since they would be freed and potentially reused before the parent expression could consume them.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, thanks.

@jgravelle-google
Copy link
Copy Markdown
Contributor

Overall looks good, but Travis is failing because:

wasm2asm: /home/travis/build/WebAssembly/binaryen/src/passes/I64ToI32Lowering.cpp:70:
Index wasm::I64ToI32Lowering::TempVar::operator unsigned int(): Assertion `!moved' failed.

so that should probably be fixed

@tlively
Copy link
Copy Markdown
Member Author

tlively commented Sep 14, 2017

Yeah there's all sorts of wonkiness going on with br_tables right now. I'm working on it!

@tlively
Copy link
Copy Markdown
Member Author

tlively commented Sep 15, 2017

I had to update my strategy for lowering Switch expressions to always use trampoline blocks because the previous strategy relied on being able to store a single variable into multiple locations in a lookup table, which is no longer possible.

@tlively
Copy link
Copy Markdown
Member Author

tlively commented Sep 22, 2017

@kripken @jgravelle-google any more thoughts on this change?

@kripken
Copy link
Copy Markdown
Member

kripken commented Sep 24, 2017

lgtm, thanks!

@kripken kripken merged commit de54837 into WebAssembly:master Sep 24, 2017
@tlively tlively deleted the i64-lowering-temp-raii branch April 24, 2020 23:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants