This is an archive of the discontinued LLVM Phabricator instance.

[WebAssembly] Split and recombine multivalue calls for ISel
ClosedPublic

Authored by tlively on Dec 13 2019, 3:22 PM.

Details

Summary

Multivalue calls both take and return an arbitrary number of
arguments, but ISel only supports one or the other in a single
instruction. To get around this, calls are modeled as two pseudo
instructions during ISel. These pseudo instructions, CALL_PARAMS and
CALL_RESULTS, are recombined into a single CALL MachineInstr in a
custom emit hook.

RegStackification and the MC layer will additionally need to be made
aware of multivalue calls before the tests will produce correct
output.

Diff Detail

Event Timeline

tlively created this revision.Dec 13 2019, 3:22 PM
Herald added a project: Restricted Project. · View Herald TranscriptDec 13 2019, 3:22 PM
tlively marked an inline comment as done.Dec 13 2019, 4:23 PM
tlively added inline comments.
llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
462

This llvm_unreachable truly is unreachable because it comes after the return. There is a default case at the top of the switch that contains another llvm_unreachable, so this one was both incorrect and redundant.

Nice! Are there no tests because we don't have the assembly printer support yet?

llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
209

Nit: Does this i32 have a meaning? If not, can we use a chain (MVT::Other) instead?

llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
433

Is CallParams guaranteed to be the previous node? What we did in ISelDAGToDAG is to make CallParams an operand of CallResult. While they have data dependences and CallResult will be guaranteed to be selected after CallParams, I'm not sure if there can't be any other instructions in between. Can't we get the operand of CallResults?

444

How do we assign which is defs and which is uses in this new CALL instruction?

llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td
59

CALL->CALL_PARAMS?

63

Sorry for real nit: Can we make comments wrap to 80 cols..? Lines kind of look to short.. I think there should be a shortcut in most editors for doing that.

70

Isn't this also isPseudo = 1?

tlively updated this revision to Diff 234132.Dec 16 2019, 1:29 PM
tlively marked 6 inline comments as done.
  • Address simple comments

Unit tests: pass. 60863 tests passed, 0 failed and 726 were skipped.

clang-format: pass.

Build artifacts: diff.json, CMakeCache.txt, console-log.txt, test-results.xml

tlively added inline comments.Dec 16 2019, 2:25 PM
llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
209

There's no meaning, but I have not been able avoid assertion failures using MTV::Other. I'll investigate further without spending too much time on it.

llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
433

Yeah, good point. I didn't see a simple API for getting defs of operands from MachineInstrs, but making this more robust is probably worth some extra code.

444

MachineOperands store this information on themselves and we follow the convention here of having the defs before the uses so things like getNumDefs should still work. This will be a bigger problem at the MC layer, where the def and use information is erased.

tlively updated this revision to Diff 234163.Dec 16 2019, 2:50 PM
  • Use MVT::Other for link, rebase

Unit tests: pass. 60863 tests passed, 0 failed and 726 were skipped.

clang-format: pass.

Build artifacts: diff.json, CMakeCache.txt, console-log.txt, test-results.xml

tlively marked 2 inline comments as done.Dec 16 2019, 3:14 PM
tlively added inline comments.
llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
209

Ok, I've switched this to use MVT::Other. This just required an update to the previous CL to avoid a nullptr dereference.

llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
433

Now that I switched to using MVT::Other, there isn't even a shared register to look for. I think we have no choice but to blindly hope that these instructions are emitted next to each other :/

aheejin added inline comments.Dec 16 2019, 4:14 PM
llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
433

Oh, if changing to MTV::Other makes things harder, just don't do it ;( Sorry I was just suggesting.
Oh the other hand, can we use the MTV::Glue thing? I haven't used it myself and I'm not super familiar with it, but the definition of that is to glue nodes together, right? If we can actually guarantee they are glued together that's gonna be good.

tlively updated this revision to Diff 238907.Jan 17 2020, 3:26 PM
  • Switch to using MVT::Glue
tlively marked an inline comment as done.Jan 17 2020, 3:28 PM
tlively added inline comments.
llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
433

MVT::Glue works! There must have been something else wrong when I experimented with it before.

Unit tests: fail. 61975 tests passed, 1 failed and 783 were skipped.

failed: LLVM.Bindings/Go/go.test

clang-tidy: unknown.

clang-format: pass.

Build artifacts: diff.json, clang-format.patch, CMakeCache.txt, console-log.txt, test-results.xml

aheejin accepted this revision.EditedJan 21 2020, 9:40 AM

LGTM. Please rebase this onto D71484; this currently contains diff of that CL too.

This revision is now accepted and ready to land.Jan 21 2020, 9:40 AM
This revision was automatically updated to reflect the committed changes.