Skip to content
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

GlobalStructInference: Un-nest struct.news in globals when that is helpful #6688

Merged
merged 25 commits into from
Jun 20, 2024

Conversation

kripken
Copy link
Member

@kripken kripken commented Jun 20, 2024

If we have

(global $g (struct.new $S
  (i32.const 1)
  (struct.new $T ..)
  (ref.func $f)
))

then before this PR if we wanted to read the middle field we'd stop, as it is non-constant.
However, we can un-nest it, making it constant:

(global $g.unnested (struct.new $T ..))
(global $g (struct.new $S
  (i32.const 1)
  (global.get $g.unnested)
  (ref.func $f)
))

Now the field is a global.get of an immutable global, which is constant. Using this
technique we can handle anything in a struct field, constant or not. The cost of adding
a global is likely offset by the benefit of being able to refer to it directly, as that opens
up more opportunities later.

Concretely, this replaces the constant values we look for in GSI with a variant over
constants or expressions (we do still want to group constants, as multiple globals
with the same constant field can be treated as a whole). And we note cases where we
need to un-nest, and handle those at the end.

@kripken kripken requested a review from tlively June 20, 2024 17:52

std::unique_ptr<Pass> create() override {
return std::make_unique<FunctionOptimizer>(parent);
const PossibleConstantValues& getConstant() const {
Copy link
Member

Choose a reason for hiding this comment

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

If you have this return a pointer, then you can avoid the need for a separate isConstant and you can use it conveniently in if (assignment) expressions.

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm, yeah, that might be a little less code here. But I'm not sure if it would be more clear (as working with pointers is less nice). Also, this is parallel to other existing APIs:

bool isConstant() const {
return !std::get_if<None>(&value) && !std::get_if<Many>(&value);
}
bool isConstantLiteral() const { return std::get_if<Literal>(&value); }
bool isConstantGlobal() const { return std::get_if<Name>(&value); }
bool isNull() const {
return isConstantLiteral() && getConstantLiteral().isNull();
}
// Returns the single constant value.
Literal getConstantLiteral() const {
assert(isConstant());
return std::get<Literal>(value);
}

Copy link
Member

Choose a reason for hiding this comment

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

I see we have divergent styles here. All of the variant-using code I've written uses the pointer approach :)

src/passes/GlobalStructInference.cpp Show resolved Hide resolved
// See if it matches anything we've seen before.
bool grouped = false;
if (value.isConstant()) {
for (auto& oldValue : values) {
Copy link
Member

Choose a reason for hiding this comment

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

Would it be worth mapping constants to Values to avoid this linear lookup?

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't think so, since we have a limit on 2 values (so that we can do a single comparison to pick between them).

Copy link
Member

Choose a reason for hiding this comment

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

Ah, right, that makes sense, too.

@kripken kripken merged commit c3089b3 into WebAssembly:main Jun 20, 2024
14 checks passed
@kripken kripken deleted the gsi.unnest branch June 20, 2024 22:24
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.

None yet

2 participants