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

Fixes regarding explicit names #6466

Merged
merged 5 commits into from
Apr 11, 2024
Merged

Conversation

vouillon
Copy link
Contributor

@vouillon vouillon commented Apr 3, 2024

  • only write explicit function names
  • when merging modules, the name of types, globals and tags in all modules but the first were lost

o << U32LEB(emitted);
writeEscapedName(curr->name.str);
emitted++;
std::vector<std::pair<Index, Function*>> functionsWithNames;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is the very same code as for globals.

@vouillon vouillon force-pushed the explicit-names branch 3 times, most recently from 2738190 to 144a4cb Compare April 3, 2024 15:16
- only write explicit function names
- when merging modules, the name of types, globals and tags in all
  modules but the first were lost
@@ -48,6 +48,7 @@ Function* copyFunction(Function* func,
std::optional<std::vector<Index>> fileIndexMap) {
auto ret = std::make_unique<Function>();
ret->name = newName.is() ? newName : func->name;
ret->hasExplicitName = func->hasExplicitName && !newName.is();
Copy link
Member

Choose a reason for hiding this comment

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

Why not set it to true when newName.is()?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

newName is a generated name. For instance, some names like outlined-A$func-name are generated during inlining. But maybe we can consider it is explicit enough?

Copy link
Member

Choose a reason for hiding this comment

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

Ah, I see what you mean, good point. I guess it depends on the user expectation in this code. I think that we do want to keep such names, as we are copying a function, so we should copy the property of having an explicit name.

@vouillon vouillon changed the title wasm-merge: preserve explicit names Fixes regarding explicit names Apr 4, 2024
@@ -48,6 +48,7 @@ Function* copyFunction(Function* func,
std::optional<std::vector<Index>> fileIndexMap) {
auto ret = std::make_unique<Function>();
ret->name = newName.is() ? newName : func->name;
ret->hasExplicitName = newName.is() || func->hasExplicitName;
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
ret->hasExplicitName = newName.is() || func->hasExplicitName;
ret->hasExplicitName = func->hasExplicitName;

I think it's better to just match the copied function. Their names may differ (if copied into the same module) but the property of having an explicit name seems like it should be the same, at least by default.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, indeed!

@@ -222,7 +231,6 @@ void copyModule(const Module& in, Module& out) {
out.customSections = in.customSections;
out.debugInfoFileNames = in.debugInfoFileNames;
out.features = in.features;
out.typeNames = in.typeNames;
Copy link
Member

Choose a reason for hiding this comment

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

Why did this move? The description of the function it was moved to is that it copies toplevel module items like Functions and Globals, and not metadata.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So, you think I should rather put the code that copy type names in wasm-merge.cc?

Copy link
Member

@kripken kripken Apr 8, 2024

Choose a reason for hiding this comment

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

Sorry, I don't see why my question, which was about the deletion of this line, is answered by something about wasm-merge? What is the context I am missing?

From the standpoint of this file by itself (not thinking about wasm-merge at all), this change seems surprising as I said - it looks like this code moved up to copyModuleItems which I don't understand the motivation for.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

wasm-merge currently does not copy type names from the input modules to the merged module. I added some code for that in copyModuleItems. But then this line became unnecessary.

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, so wasm-merge uses copyModuleItems and not copyModule. The difference between those two decreases with this change, and the meaning of the difference becomes less clear to me. Perhaps we don't need two functions here at all, and there could just be a single function with maybe a set of options as to whether to copy exports, the start method, etc. (the things only in copyModule). Anyhow, for this PR I think the change you made is good, but please add a TODO on copyModule to remind us later, maybe something like TODO: merge this with copyModuleItems, and add options for copying exports and other things that are currently different between them, if we still need those differences.

Copy link
Member

Choose a reason for hiding this comment

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

Why did this change?

Copy link
Contributor Author

@vouillon vouillon Apr 5, 2024

Choose a reason for hiding this comment

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

The function name section is no longer written when there is no name.

@@ -18,15 +18,15 @@

;; PRIMARY: (import "env" "__load_secondary_module" (func $import$__load_secondary_module (param externref)))

;; PRIMARY: (import "placeholder" "0" (func $placeholder_0 (param i32) (result i32)))
;; PRIMARY: (import "placeholder" "0" (func $fimport$1 (param i32) (result i32)))
Copy link
Member

Choose a reason for hiding this comment

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

This looks like a loss of a useful name. Perhaps it's better to keep it?

Copy link
Member

Choose a reason for hiding this comment

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

It's useful in tests, but it's not useful for production. Are tests enough motivation?

Copy link
Member

Choose a reason for hiding this comment

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

I think so. In production no names are shipped anyhow so adding more names in non-production builds has little downside, so long as they are meaningful, which looks like the case here.

@kripken kripken merged commit d662d73 into WebAssembly:main Apr 11, 2024
13 checks passed
@sbc100
Copy link
Member

sbc100 commented Apr 12, 2024

This seems to break some emscripten tests:

======================================================================
FAIL: test_metadce_hello_O0 (test_other.other.test_metadce_hello_O0)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/local/google/home/sbc/dev/wasm/emscripten/test/common.py", line 704, in resulting_test
    return func(self, *args)
           ^^^^^^^^^^^^^^^^^
  File "/usr/local/google/home/sbc/dev/wasm/emscripten/test/test_other.py", line 8522, in test_metadce_hello
    self.run_metadce_test('hello_world.c', *args)
  File "/usr/local/google/home/sbc/dev/wasm/emscripten/test/test_other.py", line 8457, in run_metadce_test
    self.assertFileContents(filename, data)
  File "/usr/local/google/home/sbc/dev/wasm/emscripten/test/common.py", line 1387, in assertFileContents
    self.assertTextDataIdentical(expected_content, contents, message,
  File "/usr/local/google/home/sbc/dev/wasm/emscripten/test/common.py", line 1345, in assertTextDataIdentical
    return self.assertIdentical(text1, text2, msg, fromfile, tofile)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/google/home/sbc/dev/wasm/emscripten/test/common.py", line 1364, in assertIdentical
    self.fail(fail_message)
AssertionError: Unexpected difference:
--- /usr/local/google/home/sbc/dev/wasm/emscripten/test/other/metadce/test_metadce_hello_O0.funcs
+++ /usr/local/google/home/sbc/dev/wasm/emscripten/test/other/metadce/test_metadce_hello_O0.funcs.new
@@ -1,3 +1,5 @@
+$54
+$55
 $__DOUBLE_BITS
 $__ashlti3
 $__emscripten_stdout_close
@@ -26,7 +28,6 @@
 $_emscripten_stack_restore
 $_emscripten_tempret_get
 $_emscripten_tempret_set
-$dynCall_jiji
 $emscripten_stack_get_base
 $emscripten_stack_get_current
 $emscripten_stack_get_end
@@ -41,7 +42,6 @@
 $getint
 $getpid
 $init_pthread_self
-$legalstub$dynCall_jiji
 $main
 $memchr
 $out

For full output run with --verbose.
Run with --rebaseline to automatically update expectations

@sbc100
Copy link
Member

sbc100 commented Apr 12, 2024

Looks like functions that previously had names now just have numbers?

@sbc100
Copy link
Member

sbc100 commented Apr 12, 2024

I guess dymCall-generating pass needs to set hasExplicitName on the functions it creates?

@vouillon
Copy link
Contributor Author

I guess dymCall-generating pass needs to set hasExplicitName on the functions it creates?

Yes, indeed, that would fix the issue. But I'm wondering whether emscripten really needs the internal names. Maybe you can just update the tests? On the other hand, the generated names are meaningful, so it also make sense to fix that in binaryen.

@vouillon vouillon deleted the explicit-names branch April 12, 2024 09:03
@kripken
Copy link
Member

kripken commented Apr 12, 2024

Another fix might be to set hasExplicitName by default in the makeFunction constructor, when it receives a name. When a string name is provided, at least, we can use it. Functions not given any name at all in wat or wasm binaries are the main situations where we don't want hasExplicitName set.

@sbc100 I can look into fixing this but I am out today.

@sbc100
Copy link
Member

sbc100 commented Apr 12, 2024

I guess dymCall-generating pass needs to set hasExplicitName on the functions it creates?

Yes, indeed, that would fix the issue. But I'm wondering whether emscripten really needs the internal names. Maybe you can just update the tests? On the other hand, the generated names are meaningful, so it also make sense to fix that in binaryen.

The generated names are indeed meaningful/useful, at least for debugging.

@sbc100
Copy link
Member

sbc100 commented Apr 12, 2024

Another fix might be to set hasExplicitName by default in the makeFunction constructor, when it receives a name. When a string name is provided, at least, we can use it. Functions not given any name at all in wat or wasm binaries are the main situations where we don't want hasExplicitName set.

That sounds like a good fix.

@sbc100 I can look into fixing this but I am out today.

sbc100 added a commit that referenced this pull request Apr 12, 2024
…icitName. NFC

This is temporary workaround for the current test failures on the
emscripten waterfall.  The real fix I believe will be to make
`hasExplicitName` the default in these kinds of cases.

See: #6466
sbc100 added a commit that referenced this pull request Apr 12, 2024
…icitName. NFC (#6496)

This is temporary workaround for the current test failures on the
emscripten waterfall.  The real fix I believe will be to make
`hasExplicitName` the default in these kinds of cases.

See: #6466
@vouillon
Copy link
Contributor Author

Another fix might be to set hasExplicitName by default in the makeFunction constructor, when it receives a name. When a string name is provided, at least, we can use it. Functions not given any name at all in wat or wasm binaries are the main situations where we don't want hasExplicitName set.

makeFunction is called with a made-up name in several places, though. For instance, in the binary parser (for imports) and in the legacy text parser.

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