This is an archive of the discontinued LLVM Phabricator instance.

[WebAssembly] Implement -print-gc-sections to test global GC
ClosedPublic

Authored by ncw on Mar 9 2018, 9:17 AM.

Details

Summary

We don't have any tests for GC of globals yet. I've therefore implemented -print-gc-sections for globals, and extended the tests to exercise it. I've also made it follow the --no-gc-sections flag, so the tests are consistent.

It does require the addition of a YAML file, since user-defined globals aren't accessible from LLC at the moment. It's better to have the test in there than not!

Diff Detail

Repository
rL LLVM

Event Timeline

ncw created this revision.Mar 9 2018, 9:17 AM
ncw updated this revision to Diff 137779.Mar 9 2018, 9:56 AM

Improve test a bit

ruiu added inline comments.Mar 9 2018, 10:56 AM
wasm/Writer.cpp
790–791 ↗(On Diff #137779)

I believe you added Config->GcSections because if GC is off, all globals are alive by default and therefore we don't need to set that bit at all. Is this correct? If so, please add a comment.

807 ↗(On Diff #137779)

It seems a bit too late to do this kind of stuff, since this is a writer. Is there any way to detect liveness of globals earlier than it is now, move code to MarkLive, and also move this code to MarkLive?

sbc100 added inline comments.Mar 9 2018, 4:33 PM
wasm/InputGlobal.h
55 ↗(On Diff #137779)

Non of this is needed if you don't include globals in the output of --print-gc-section.

wasm/MarkLive.cpp
110 ↗(On Diff #137779)

Can you make this a separate change?

wasm/Writer.cpp
790–791 ↗(On Diff #137779)

I don't really consider what we are going here as GC of sections. Its more like we are building the sythentic type and global section, and we always do it precisely based on what is needed. There is no option to disable this, as there is no need to a more conservative approach AFAICT.

Perhaps it we rename Global->Live to Global->Used it will make the distinction more clear?

So I don't agree with this part of the change.

ncw added inline comments.Mar 10 2018, 8:01 AM
wasm/Writer.cpp
790–791 ↗(On Diff #137779)

Globals are an externally-visible piece of linked output. The browser can tell whether globals were GC'ed or not, so it's very different to say building the TYPE section. That's purely a filesize compression, using the TypeIsUsed map. It's not GC as such, since the contents of the TYPE section are not visible as part of the module's "interface" (no way of telling if extra types were included or not).

But for globals, they really are usable/callable objects just like functions are. Hence --no-gc-sections ought to prevent them being stripped. They are part of the objects that the user passed to the linker, and requested to be included in the final output!

(To be honest, I slightly struggle to see whether --no-gc-sections has any good use-cases, in fact. Are there situations where you'd want it - maybe to include some functions in the indirect table, that are never called from the Wasm code but should be callable externally via an indirect call?)

790–791 ↗(On Diff #137779)

I believe you added Config->GcSections because if GC is off, all globals are alive by default and therefore we don't need to set that bit at all. Is this correct? If so, please add a comment.

I added it here, so that globals behave the same as functions. This exact same check is made in MarkLive, so adding it here is simply removing a existing difference, rather than introducing something "weird". We currently don't have any tests at all for GC of globals, so when I added them to tests/wasm/gc-sections.ll the test started to look very odd. In a test file that exercises --gc-sections and --no-gc-sections for functions and data symbols, it would strange to assert that the same options don't have any effect on globals!

807 ↗(On Diff #137779)

Yes, it can certainly be done in MarkLive, and I feel it really ought to be done in MarkLive. Sam was resistant to that though, so this change preserves the status quo.

In D44313 (which builds on this patch) I've moved all the GC into MarkLive, where I feel it belongs.

ncw updated this revision to Diff 138209.Mar 13 2018, 9:29 AM
ncw marked an inline comment as done.

Updated: removed chunk from MarkLive, fixed conflicts on rebase.

Not sure how to resolve the discussion on this one... Rui suggested moving it to MarkLive to sit alongside the function GC, which I've done in D44313 rather than open that can of worms here. But Sam isn't too keen on that, and prefers doing global GC in a separate later pass, although the code for handling function/global GC looks essentially the same.

Really all this commit is trying to do is just add a simple test for global GC, and implement --print-gc-sections with the same behaviour as function GC, just so that the test output matches.

I had hoped to be able to merge this one without stirring up disagreement :( I'm sorry.

ncw added inline comments.Mar 13 2018, 10:18 AM
wasm/InputGlobal.h
55 ↗(On Diff #137779)

True... but it's not a lot of code, and why would we support and test --print-gc-section for functions but not globals? I added it because otherwise the existing tests would look lopsided. It seems odd if the test has an assertion that does: "check that a function and a global were GC'd and the logging indicates that the function but not the global was GC'd".

wasm/MarkLive.cpp
110 ↗(On Diff #137779)

Done, sorry, it's pulled out now.

sbc100 added inline comments.Mar 13 2018, 12:43 PM
wasm/InputGlobal.h
55 ↗(On Diff #137779)

There a couple of reasons I don't think this is needed/wanted. Firstly, I don't consider wasm globals to be sections. Secondly that building of types and globals section I chose not be contolled by the --gc-sections flag. Rather its always generated precisely, based on the inputs. In the future maybe we could revisit this, and maybe we want to completely remove --gc-section/--print-gc-sections from the wasm port, since we probably always want to enable them. However I think this incremental change muddies the water.

Perhaps once we have more use for wasm globals we can revisit? At least then we won't need to include the yaml test input.

ncw added inline comments.Mar 14 2018, 11:57 AM
wasm/InputGlobal.h
55 ↗(On Diff #137779)

Hmm. It's linked to whether you're happy to move the GC of globals into MarkLive (as Rui suggested, and which would tidy up Writer).

I can do it - and keep globals as they are.. it's just going to mean that yet another block of MarkLive is going to get copy-and-pasted into Writer in D44313 (import GC). By the time we have chunk/global GC and import GC and print-gc-sections duplicated between MarkLive and Writer it's just getting progressively uglier keep two implementations going.

I realise you don't see it as a section... I just want to check you're happy with the implications. Because in order to keep the existing behaviour of doing global GC regardless of whether gc-sections is on, that implies not moving global GC to MarkLive in D44313 (which you hadn't objected to in that review).

sbc100 added inline comments.Mar 14 2018, 12:15 PM
wasm/InputGlobal.h
55 ↗(On Diff #137779)

I don't think I'd want to move this handling to markLive, at least no unless we completely remove the --no-gc-sections option and have markLive always called. Given that we are already processing relocations twice, once in markLive and once here, then I think it makes sense to only handle functions and data segments in markLive. I don't see any real urgency to unify these two.

Is see this code not so much as "mark live", more as "find and build the import table". Just like we use this same loop to build the indirect function table.

ncw added inline comments.Mar 16 2018, 9:00 AM
wasm/InputGlobal.h
55 ↗(On Diff #137779)

In my defence - the sole purpose of the code in question is to set the Live bit on InputGlobal. (And markLive is there to set the Live bit on InputGlobal).

The urgency/immediate reason was simply that the Live/Used bit on a symbol is the same for globals as for functions. If we continue to handle InputGlobal::Live in Writer, we'd be in the awkward situation of doing GC for global imports in a different place to the InputGlobals.

What I'll do is rebase these GC patches onto master, and see how it looks just with each change in isolation rather than as a sequence of cumulative changes.

Thanks for your patience!

ncw planned changes to this revision.Mar 27 2018, 11:04 AM
ncw updated this revision to Diff 143344.Apr 20 2018, 10:29 AM
ncw edited the summary of this revision. (Show Details)

Updated: rebased.

Now there's nothing contentious, I think this one is safe to land too? It's been a loong time (weeks) since there was any movement on these LLD bugs. If you want me to come back and make further changes however, I'm happy to do that.

This revision was not accepted when it landed; it landed in state Needs Review.Apr 20 2018, 10:31 AM
This revision was automatically updated to reflect the committed changes.