mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 12:43:36 +01:00
7d3fbb9953
This is just a cleanup of the very high level stuff. I'm sure there is more to update here but I'll leave that to others and/or a followup. Differential Revision: https://reviews.llvm.org/D100888
174 lines
7.2 KiB
Plaintext
174 lines
7.2 KiB
Plaintext
//===-- README.txt - Notes for WebAssembly code gen -----------------------===//
|
|
|
|
The object format emitted by the WebAssembly backed is documented in:
|
|
|
|
* https://github.com/WebAssembly/tool-conventions/blob/master/Linking.md
|
|
|
|
The C ABI is described in:
|
|
|
|
* https://github.com/WebAssembly/tool-conventions/blob/master/BasicCABI.md
|
|
|
|
For more information on WebAssembly itself, see the home page:
|
|
|
|
* https://webassembly.github.io/
|
|
|
|
Emscripten provides a C/C++ compilation environment based on clang which
|
|
includes standard libraries, tools, and packaging for producing WebAssembly
|
|
applications that can run in browsers and other environments.
|
|
|
|
wasi-sdk provides a more minimal C/C++ SDK based on clang, llvm and a libc based
|
|
on musl, for producing WebAssemmbly applictions that use the WASI ABI.
|
|
|
|
Rust provides WebAssembly support integrated into Cargo. There are two
|
|
main options:
|
|
- wasm32-unknown-unknown, which provides a relatively minimal environment
|
|
that has an emphasis on being "native"
|
|
- wasm32-unknown-emscripten, which uses Emscripten internally and
|
|
provides standard C/C++ libraries, filesystem emulation, GL and SDL
|
|
bindings
|
|
For more information, see:
|
|
* https://www.hellorust.com/
|
|
|
|
The following documents contain some information on the semantics and binary
|
|
encoding of WebAssembly itself:
|
|
* https://github.com/WebAssembly/design/blob/master/Semantics.md
|
|
* https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md
|
|
|
|
Some notes on ways that the generated code could be improved follow:
|
|
|
|
//===---------------------------------------------------------------------===//
|
|
|
|
Br, br_if, and br_table instructions can support having a value on the value
|
|
stack across the jump (sometimes). We should (a) model this, and (b) extend
|
|
the stackifier to utilize it.
|
|
|
|
//===---------------------------------------------------------------------===//
|
|
|
|
The min/max instructions aren't exactly a<b?a:b because of NaN and negative zero
|
|
behavior. The ARM target has the same kind of min/max instructions and has
|
|
implemented optimizations for them; we should do similar optimizations for
|
|
WebAssembly.
|
|
|
|
//===---------------------------------------------------------------------===//
|
|
|
|
AArch64 runs SeparateConstOffsetFromGEPPass, followed by EarlyCSE and LICM.
|
|
Would these be useful to run for WebAssembly too? Also, it has an option to
|
|
run SimplifyCFG after running the AtomicExpand pass. Would this be useful for
|
|
us too?
|
|
|
|
//===---------------------------------------------------------------------===//
|
|
|
|
Register stackification uses the VALUE_STACK physical register to impose
|
|
ordering dependencies on instructions with stack operands. This is pessimistic;
|
|
we should consider alternate ways to model stack dependencies.
|
|
|
|
//===---------------------------------------------------------------------===//
|
|
|
|
Lots of things could be done in WebAssemblyTargetTransformInfo.cpp. Similarly,
|
|
there are numerous optimization-related hooks that can be overridden in
|
|
WebAssemblyTargetLowering.
|
|
|
|
//===---------------------------------------------------------------------===//
|
|
|
|
Instead of the OptimizeReturned pass, which should consider preserving the
|
|
"returned" attribute through to MachineInstrs and extending the
|
|
MemIntrinsicResults pass to do this optimization on calls too. That would also
|
|
let the WebAssemblyPeephole pass clean up dead defs for such calls, as it does
|
|
for stores.
|
|
|
|
//===---------------------------------------------------------------------===//
|
|
|
|
Consider implementing optimizeSelect, optimizeCompareInstr, optimizeCondBranch,
|
|
optimizeLoadInstr, and/or getMachineCombinerPatterns.
|
|
|
|
//===---------------------------------------------------------------------===//
|
|
|
|
Find a clean way to fix the problem which leads to the Shrink Wrapping pass
|
|
being run after the WebAssembly PEI pass.
|
|
|
|
//===---------------------------------------------------------------------===//
|
|
|
|
When setting multiple local variables to the same constant, we currently get
|
|
code like this:
|
|
|
|
i32.const $4=, 0
|
|
i32.const $3=, 0
|
|
|
|
It could be done with a smaller encoding like this:
|
|
|
|
i32.const $push5=, 0
|
|
local.tee $push6=, $4=, $pop5
|
|
local.copy $3=, $pop6
|
|
|
|
//===---------------------------------------------------------------------===//
|
|
|
|
WebAssembly registers are implicitly initialized to zero. Explicit zeroing is
|
|
therefore often redundant and could be optimized away.
|
|
|
|
//===---------------------------------------------------------------------===//
|
|
|
|
Small indices may use smaller encodings than large indices.
|
|
WebAssemblyRegColoring and/or WebAssemblyRegRenumbering should sort registers
|
|
according to their usage frequency to maximize the usage of smaller encodings.
|
|
|
|
//===---------------------------------------------------------------------===//
|
|
|
|
Many cases of irreducible control flow could be transformed more optimally
|
|
than via the transform in WebAssemblyFixIrreducibleControlFlow.cpp.
|
|
|
|
It may also be worthwhile to do transforms before register coloring,
|
|
particularly when duplicating code, to allow register coloring to be aware of
|
|
the duplication.
|
|
|
|
//===---------------------------------------------------------------------===//
|
|
|
|
WebAssemblyRegStackify could use AliasAnalysis to reorder loads and stores more
|
|
aggressively.
|
|
|
|
//===---------------------------------------------------------------------===//
|
|
|
|
WebAssemblyRegStackify is currently a greedy algorithm. This means that, for
|
|
example, a binary operator will stackify with its user before its operands.
|
|
However, if moving the binary operator to its user moves it to a place where
|
|
its operands can't be moved to, it would be better to leave it in place, or
|
|
perhaps move it up, so that it can stackify its operands. A binary operator
|
|
has two operands and one result, so in such cases there could be a net win by
|
|
preferring the operands.
|
|
|
|
//===---------------------------------------------------------------------===//
|
|
|
|
Instruction ordering has a significant influence on register stackification and
|
|
coloring. Consider experimenting with the MachineScheduler (enable via
|
|
enableMachineScheduler) and determine if it can be configured to schedule
|
|
instructions advantageously for this purpose.
|
|
|
|
//===---------------------------------------------------------------------===//
|
|
|
|
WebAssemblyRegStackify currently assumes that the stack must be empty after
|
|
an instruction with no return values, however wasm doesn't actually require
|
|
this. WebAssemblyRegStackify could be extended, or possibly rewritten, to take
|
|
full advantage of what WebAssembly permits.
|
|
|
|
//===---------------------------------------------------------------------===//
|
|
|
|
Add support for mergeable sections in the Wasm writer, such as for strings and
|
|
floating-point constants.
|
|
|
|
//===---------------------------------------------------------------------===//
|
|
|
|
The function @dynamic_alloca_redzone in test/CodeGen/WebAssembly/userstack.ll
|
|
ends up with a local.tee in its prolog which has an unused result, requiring
|
|
an extra drop:
|
|
|
|
global.get $push8=, 0
|
|
local.tee $push9=, 1, $pop8
|
|
drop $pop9
|
|
[...]
|
|
|
|
The prologue code initially thinks it needs an FP register, but later it
|
|
turns out to be unneeded, so one could either approach this by being more
|
|
clever about not inserting code for an FP in the first place, or optimizing
|
|
away the copy later.
|
|
|
|
//===---------------------------------------------------------------------===//
|