This patch fixes LLD to allow element sections for tables whose number
is nonzero. We also add a test for linking multiple tables, showing
that nonzero table numbers for the indirect function table,
user-declared imported tables, and local user table definitions work.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
OK let's do this! This one finally makes multi-table linking work as it should, and includes what i think is a reasonably thorough test.
This one is ready for review. +tlively for a second eye on how the expected behavior should work (see lld/test/wasm/multi-table.s).
lld/wasm/SyntheticSections.cpp | ||
---|---|---|
458 | This flag is never set so this is dead code isn't it? I'm guessing that when we add actual multi table here we will still want to separate the linker-synthetic indirectFunctionTable from other tables that are composed of actual input segments, so I'm not sure it makes since to make this code too generic here. | |
llvm/include/llvm/ObjectYAML/WasmYAML.h | ||
68 ↗ | (On Diff #323966) | It would be nice to see all of the non-linker parts of this change tested by llvm/test/MC/WebAssembly/tables.s. However, I IIRC, the reason that might be hard today is that we don't support declaring elements in the assembly syntax. Perhaps we should take should figure out how that will work so we can land the core part here without depending on the linker to test them? |
llvm/lib/MC/WasmObjectWriter.cpp | ||
923 ↗ | (On Diff #323966) | Might as well use if (TableNumber) again here for consistency with above. |
936 ↗ | (On Diff #323966) | This is dead code no? Since that flag cannot be set? In fact all these changes to writeElemSection look unused (and therefore untested), perhaps we can split this out and make it part of a future PR? |
llvm/lib/MC/WasmObjectWriter.cpp | ||
---|---|---|
936 ↗ | (On Diff #323966) | So the tableNumber changes above are definitely used and tested. Definitely possible to have non-zero table numbers for the indirect function table. I could remove this HAS_ELEM_KIND bit here but let me push back gently -- we would like to test that this output is spec-conforming and also that it "makes" sense" from a LLVM point of view (e.g. can round trip through tables.s). But the former is more important than the latter. By structuring this function to look more like the [binary spec]((https://webassembly.github.io/reference-types/core/binary/modules.html#binary-elemsec)) -- e.g. checking the HAS_TABLE_NUMBER flag instead of checking TableNumber -- I have greater confidence reading the code that it does what the spec says. |
llvm/lib/MC/WasmObjectWriter.cpp | ||
---|---|---|
936 ↗ | (On Diff #323966) | Sure, I don't really care if you check TableNumber of HAS_TABLE_NUMBER above. But these six lines seems compltely pointless and in fact that are dead code right? This function doesn't write arbitrary tables it *only* writes the special __indirect_function_table (at least today). Can that ever have an ElemKind? |
lld/wasm/SyntheticSections.cpp | ||
---|---|---|
433 | This assertion fails for the bsymbolic test; see https://bugs.llvm.org/show_bug.cgi?id=49397. |
lld/wasm/SyntheticSections.cpp | ||
---|---|---|
458 | I still think this block should be completely removed. This method exists only for writing the indirectFunctionTable which by definition does not have this flag and does need this code block. If we ever change the type of indirectFunctionTable we can change this function. When we add a method for writing a generic element section it most likely won't be a SyntheticSections like this one is but one that is made up of InputChunk.. that method will want to be more generic but I don't see why this one should be. | |
llvm/lib/MC/WasmObjectWriter.cpp | ||
908 ↗ | (On Diff #327437) | How about moving the assert below the early return and changing it to just assert(IndirectFunctionTable) |
917 ↗ | (On Diff #327437) | This cast looks redundant maybe? |
1839 ↗ | (On Diff #327437) | llvm policy it to avoid using auto on the left unless the type is completely obvious (e.g. already stated on the same line): https://llvm.org/docs/CodingStandards.html#use-auto-type-deduction-to-make-code-more-readable |
1840 ↗ | (On Diff #327437) | I wonder if |
lld/wasm/SyntheticSections.cpp | ||
---|---|---|
458 | Aaah yes I had removed it locally; I think I must have fat-fingered the "arc diff". Tx for sharp eye. |
lld/wasm/SyntheticSections.cpp | ||
---|---|---|
458 | As noted below, this isn't dead code at all. You have to write the elem kind if the table number is nonzero. LMK your thoughts here. | |
llvm/lib/MC/WasmObjectWriter.cpp | ||
936 ↗ | (On Diff #323966) | Paging this back in -- this code was not dead. See the definition for WASM_ELEM_SEGMENT_HAS_ELEM_KIND. I have restored it here. WDYT? |
llvm/include/llvm/ObjectYAML/WasmYAML.h | ||
---|---|---|
68 ↗ | (On Diff #323966) | I'd still think it would be good to see at least one llvm-side test (not just the lld integration test) test for this code. |
llvm/lib/MC/WasmObjectWriter.cpp | ||
936 ↗ | (On Diff #323966) |
Oh I see.. WASM_ELEM_SEGMENT_HAS_ELEM_KIND is defined as ~SOME_OTHER_FLAG.. that seem odd at best. Perhaps better write to little helper function elemSegmentNeedsElemKind() rather than trying to make that part of the enum? Otherwise folks will think that WASM_ELEM_SEGMENT_HAS_ELEM_KIND is just another flag they can | together. Either that or maybe add MASK to its name and take it out of the enum with the others. It looks like WASM_ELEM_SEGMENT_HAS_ELEM_KIND is basically PASSIVE | HAS_TABLE_NUMBER ... maybe its more clear to just write that out here? |
This assertion fails for the bsymbolic test; see https://bugs.llvm.org/show_bug.cgi?id=49397.