Commit Graph

29 Commits

Author SHA1 Message Date
Dan Gohman
e46ddfaa34 [WebAssembly] Put __stack_pointer in the offset field of loads and stores.
Instead of this:

i32.const       $push10=, __stack_pointer
i32.load        $push11=, 0($pop10)

Emit this:

i32.const       $push10=, 0
i32.load        $push11=, __stack_pointer($pop10)

It's not currently clear which is better, though there's a chance the second
form may be better at overall compression. We can revisit this when we have
more data; for now it makes sense to make PEI consistent with isel.

Differential Revision: http://reviews.llvm.org/D20411

llvm-svn: 270635
2016-05-24 23:47:41 +00:00
Dan Gohman
920c7d7490 [WebAssembly] Optimize away return instructions using fallthroughs.
This saves a small amount of code size, and is a first small step toward
passing values on the stack across block boundaries.

Differential Review: http://reviews.llvm.org/D20450

llvm-svn: 270294
2016-05-21 00:21:56 +00:00
Dan Gohman
65295f5464 [WebAssembly] Make several CHECK lines less fragile using regexes and CHECK-DAG.
llvm-svn: 270011
2016-05-19 01:52:56 +00:00
Dan Gohman
889b2555f5 [WebAssembly] Rename $discard to $drop in the assembly output.
llvm-svn: 269862
2016-05-17 23:19:03 +00:00
Dan Gohman
df1ae0caf4 [WebAssembly] Model the stack evaluation order more precisely.
We currently don't represent get_local and set_local explicitly; they
are just implied by virtual register use and def. This avoids a lot of
clutter, but it does complicate stackifying: get_locals read their
operands at their position in the stack evaluation order, rather than
at their parent instruction. This patch adds code to walk the stack to
determine the precise ordering, when needed.

llvm-svn: 269854
2016-05-17 22:24:18 +00:00
Dan Gohman
f9dd86b5c9 [WebAssembly] Mark COPY_LOCAL and TEE_LOCAL instructions has having no side effects.
llvm-svn: 269683
2016-05-16 19:16:32 +00:00
Dan Gohman
ba5248ef2c [WebAssembly] Preliminary fast-isel support.
llvm-svn: 269083
2016-05-10 17:39:48 +00:00
Dan Gohman
13d15dbc40 [WebAssembly] Move register stackification and coloring to a late phase.
Move the register stackification and coloring passes to run very late, after
PEI, tail duplication, and most other passes. This means that all code emitted
and expanded by those passes is now exposed to these passes. This also
eliminates the need for prologue/epilogue code to be manually stackified,
which significantly simplifies the code.

This does require running LiveIntervals a second time. It's useful to think
of these late passes not as late optimization passes, but as a domain-specific
compression algorithm based on knowledge of liveness information. It's used to
compress the code after all conventional optimizations are complete, which is
why it uses LiveIntervals at a phase when actual optimization passes don't
typically need it.

Differential Revision: http://reviews.llvm.org/D20075

llvm-svn: 269012
2016-05-10 04:24:02 +00:00
Derek Schuff
cd46ca19fb [WebAssembly] Stackify code emitted by eliminateFrameIndex and SP writeback
Summary:
MRI::eliminateFrameIndex can emit several instructions to do address
calculations; these can usually be stackified. Because instructions with
FI operands can have subsequent operands which may be expression trees,
find the top of the leftmost tree and insert the code before it, to keep
the LIFO property.

Also use stackified registers when writing back the SP value to memory
in the epilog; it's unnecessary because SP will not be used after the
epilog, and it results in better code.

Differential Revision: http://reviews.llvm.org/D18234

llvm-svn: 263725
2016-03-17 17:00:29 +00:00
Derek Schuff
c81038d2b7 Revert "[WebAssembly] Stackify code emitted by eliminateFrameIndex"
This reverts r261685 due to wasm test breakage.

llvm-svn: 261702
2016-02-23 22:13:21 +00:00
Derek Schuff
74080913f6 [WebAssembly] Stackify code emitted by eliminateFrameIndex
llvm-svn: 261685
2016-02-23 21:25:17 +00:00
Derek Schuff
7fa1e4425f [WebAssembly] Implement red zone for user stack
Implements a mostly-conventional redzone for the userspace
stack. Because we have unsigned load/store offsets we continue to use a
local SP subtracted from the incoming SP but do not write it back to
memory.

Differential Revision: http://reviews.llvm.org/D17525

llvm-svn: 261662
2016-02-23 18:13:07 +00:00
Derek Schuff
5fd7c2542e [WebAssembly] Fix writeback of stack pointer with dynamic alloca
Previously the stack pointer was only written back to memory in the
prolog. But this is wrong for dynamic allocas, for which
target-independent codegen handles SP updates after the prolog (and
possibly even in another BB). Instead update the SP global in
ADJCALLSTACKDOWN which is generated after the SP update sequence.
This will have further refinements when we add red zone support.

llvm-svn: 261579
2016-02-22 21:57:17 +00:00
Dan Gohman
c3f23ceef3 [WebAssembly] Support physical registers in the rewrite-to-discard optimization.
llvm-svn: 261465
2016-02-21 03:27:22 +00:00
Dan Gohman
3f10ef519d [WebAssembly] Handle CopyToReg nodes with flag results in LowerCopyToReg.
llvm-svn: 261457
2016-02-20 23:09:44 +00:00
Derek Schuff
ee2bcbc1d2 [WebAssembly] Write stack pointer back to memory when FP is used
The stack pointer is bumped when there is a frame pointer or when there
are static-size objects, but was only getting written back when there
were static-size objects.

llvm-svn: 261453
2016-02-20 22:18:47 +00:00
Derek Schuff
5cc4608440 [WebAssembly] Stackify function prologs and epilogs
The instructions are the same, but fewer locals are used.

Differential Revision: http://reviews.llvm.org/D17428

llvm-svn: 261452
2016-02-20 21:46:50 +00:00
Dan Gohman
7699d5ed4b [WebAssembly] Implement __builtin_frame_address.
Differential Revision: http://reviews.llvm.org/D17307

llvm-svn: 261032
2016-02-16 23:48:04 +00:00
Derek Schuff
abc1815dc3 [WebAssembly] Insert COPY_LOCAL between CopyToReg and FrameIndex DAG nodes
CopyToReg nodes don't support FrameIndex operands. Other targets select
the FI to some LEA-like instruction, but since we don't have that, we
need to insert some kind of instruction that can take an FI operand and
produces a value usable by CopyToReg (i.e. in a vreg). So insert a dummy
copy_local between Op and its FI operand. This results in a redundant
copy which we should optimize away later (maybe in the post-FI-lowering
peephole pass).

Differential Revision: http://reviews.llvm.org/D17213

llvm-svn: 260987
2016-02-16 18:18:36 +00:00
Derek Schuff
2f77371cea [WebAssembly] Fix uses of FrameIndex as store values
Previously the code assumed all uses of FI on loads and stores were as
addresses. This checks whether the use is the address or a value and
handles the latter case as it does for non-memory instructions.

llvm-svn: 259306
2016-01-30 21:43:08 +00:00
Derek Schuff
385a651d43 [WebAssembly] Support frame pointer
Add support for frame pointer use in prolog/epilog.
Supports dynamic allocas but not yet over-aligned locals.
Target-independend CG generates SP updates, but we still need to write
back the SP value to memory when necessary.

llvm-svn: 259220
2016-01-29 18:37:49 +00:00
Derek Schuff
821f0edf1c [WebAssembly] Omit no-op adds for non-mem uses of FrameIndex
Differential Revision: http://reviews.llvm.org/D16554

llvm-svn: 258872
2016-01-26 22:47:43 +00:00
Dan Gohman
e694253126 [WebAssembly] Implement unaligned loads and stores.
Differential Revision: http://reviews.llvm.org/D16534

llvm-svn: 258779
2016-01-26 03:39:31 +00:00
Dan Gohman
e0f4353910 [WebAssembly] Don't stackify stores across instructions with side effects.
llvm-svn: 258285
2016-01-20 04:21:16 +00:00
Derek Schuff
03c784208d [WebAssembly] Support combining GEP and FrameIndex offsets in memory operand offset field
Previously we only supported putting the FI into memory operand offset
fields if there was nothing there already. Now combine them.

Differential Revision: http://reviews.llvm.org/D15941

llvm-svn: 257084
2016-01-07 18:55:52 +00:00
Dan Gohman
8422d6f477 [WebAssembly] Add -m:e to the target triple.
This enables ELF-style name mangling, which primarily means using ".L" for
private symbols.

llvm-svn: 257020
2016-01-07 03:19:23 +00:00
Derek Schuff
b1cc2b699b [WebAssembly] Implement eliminateCallFramePseudo
Summary:
Implement eliminateCallFramePsuedo to handle ADJCALLSTACKUP/DOWN
pseudo-instructions. Add a test calling a vararg function which causes non-0
adjustments. This revealed an issue with RegisterCoalescer wherein it
eliminates a COPY from SP32 to a vreg but failes to update the live ranges
of EXPR_STACK, causing a machineinstr verifier failure (so this test
is commented out).

Also add a dynamic alloca test, which causes a callseq_end dag node with
a 0 (instead of undef) second argument to be generated. We currently fail to
select that, so adjust the ADJCALLSTACKUP tablegen code to handle it.

Differential Revision: http://reviews.llvm.org/D15587

llvm-svn: 255844
2015-12-16 23:21:30 +00:00
Derek Schuff
2d33f198e0 [WebAssembly] Print an extra local decl when the user stack pointer is used
Differential Revision: http://reviews.llvm.org/D15546

llvm-svn: 255815
2015-12-16 20:43:06 +00:00
Derek Schuff
75ae87426d [WebAssembly] Implement prolog/epilog insertion and FrameIndex elimination
Summary:
Use the SP32 physical register as the base for FrameIndex
lowering. Update it and the __stack_pointer global var in the prolog and
epilog. Extend the mapping of virtual registers to wasm locals to
include the physical registers.

Rather than modify the target-independent PrologEpilogInserter (which
asserts that there are no virtual registers left) include a
slightly-modified copy for Wasm that does not have this assertion and
only clears the virtual registers if scavenging was needed (which of
course it isn't for wasm).

Differential Revision: http://reviews.llvm.org/D15344

llvm-svn: 255392
2015-12-11 23:49:46 +00:00