Commit Graph

1125 Commits

Author SHA1 Message Date
Jakob Stoklund Olesen
1f52415b17 Add a WebAssembly filetests directory.
Start adding little 'test compile' test cases which check that the full
compilation pipeline works for each WebAssembly instruction.
2017-07-12 12:22:50 -07:00
Jakob Stoklund Olesen
9e3b6a6eba Add a Context::compile() function which runs all compiler passes.
This is the main entry point to the code generator. It returns the
computed size of the functions code.

Also add a 'test compile' command which runs the whole code generation
pipeline.
2017-07-12 12:22:49 -07:00
Jakob Stoklund Olesen
ae5e440094 Fix Vim syntax highlighting of numbers.
Cretonne allows '_' in number constants.
2017-07-12 12:22:49 -07:00
Jakob Stoklund Olesen
d56d4d171e Tag the regmove instruction with other_side_effects.
This instruction moves a value between registers. This counts as a side
effect that is not tracked by the SSA data flow graph.
2017-07-12 10:43:42 -07:00
Jakob Stoklund Olesen
0917cfe7f4 Attach encodings to regmove instructions generated during coloring.
All emitted regmove instructions must be materialized as real move
instructions.
2017-07-12 10:43:42 -07:00
Jakob Stoklund Olesen
ca99bd1641 Add RISC-V regmove encodings. 2017-07-12 10:43:42 -07:00
Jakob Stoklund Olesen
ad76f80127 Add Intel regmove encodings.
Same as a register copy, but different arguments.
2017-07-12 10:43:42 -07:00
Jakob Stoklund Olesen
69f974ba5d Add an ISA argument to dfg.display_inst().
Include ISA-specific annotations in tracing and error messages.
2017-07-12 10:13:13 -07:00
Jakob Stoklund Olesen
e4da2e1f22 Include ISA-specific information in verifier errors.
When the test driver reports a verifier error, make sure to include the
TargetIsa when printing the failing function.
2017-07-12 10:13:13 -07:00
Jakob Stoklund Olesen
924c4649cc Enforce encodings for instructions with side effects.
We allow ghost instructions to exist if they have no side effects.
Instructions that affect control flow or that have other side effects
must be encoded.

Teach the IL verifier to enforce this. Once any instruction has an
encoding, all instructions with side effects must have an encoding.
2017-07-12 09:41:25 -07:00
Jakob Stoklund Olesen
fc94ce7e8c Add an other_side_effects instruction flag.
This is used to indicate instructions that have some side effect that is
not modelled by the more specific instruction flags.
2017-07-12 09:15:40 -07:00
d1m0
7c438f866c Add fix for #114 (#115)
* Reduce code duplication in TypeConstraint subclasses; Add ConstrainWiderOrEqual to ti and to ireduce,{s,u}extend and f{promote,demote}; Fix bug in emitting constraint edges in TypeEnv.dot(); Modify runtime constraint checks to reject match when they encounter overflow

* Rename Constrain types to something shorter; Move lane_bits/lane_counts in subclasses of ValueType; Add wider_or_eq function in rust and python;
2017-07-12 08:51:55 -07:00
Denis Merigoux
962c945a3c Cretonne IL frontend: ILBuilder (#97)
* API and data structures proposal for the SSA construction module

* Polished API and implemented trivial functions

* API more explicit, Variable now struct parameter

* Sample test written to see how the API could be used

* Implemented local value numbering for SSABuilder

* Implemented SSA within a single Ebb

* Unfinished unoptimized implementation for recursive use and seal

* Working global value numbering
The SSABuilder now create ebb args and modifies jump instructions accordingly

* Updated doc and improved branch argument modifying.
Removed instructions::branch_arguments and instructions::branch_argument_mut

* SSA building: bugfix, asserts and new test case
Missing a key optimization to remove cycles of Phi

* SSA Building: small changes after code review
Created helper function for seal_block (which now contains sanity checks)

* Optimization: removed useless phis (ebb arguments)
Using pessimistic assumption that when using a non-def variable in an unsealed block we create an ebb argument which is removed when sealing if we detect it as useless
Using aliases to avoid rewriting variables

* Changed the semantics of remove_ebb_arg and turned it into a proper API method

* Adapted ssa branch to changes in the DFG API

* Abandonned SparseMaps for EntityMaps, added named structure for headr block data.

* Created skeletton for a Cretonne IL builder frontend

* Frontend IL builder: first draft of implementation with example of instruction methods

* Working basic implementation of the frontend
Missing handling of function arguments and return values

* Interaction with function signature, sample test, more checks

* Test with function verifier, seal and fill sanity check

* Implemented python script to generate ILBuilder methods

* Added support for jump tables and stack slot

* Major API overhaul
* No longer generating rust through Python but implements InstBuilder
* No longer parametrized by user's blocks but use regular `Ebb`
* Reuse of allocated memory via distinction between ILBuilder and FunctionBuilder

* Integrate changes from StackSlot

* Improved error message

* Added support for jump arguments supplied by the user

* Added an ebb_args proxy method needed

* Adapted to Entity_ref splitted into a new module

* Better error messages and fixed tests

* Added method to change jump destination

* We whould be able to add unreachable code

* Added inst_result proxy to frontend

* Import support

* Added optimization for SSA construction:
If multiple predecessors but agree on value don't create EBB argument

* Move unsafe and not write-only funcs apart, improved doc

* Added proxy function for append_ebb_arg

* Support for unreachable code and better layout of the Ebbs

* Fixed a bug yielding an infinite loop in SSA construction

* SSA predecessors lookup code refactoring

* Fixed bug in unreachable definition

* New sanity check and display debug function

* Fixed bug in verifier and added is_pristine ;ethod for frontend

* Extended set of characters printable in function names
To be able to print names of functions in test suite

* Fixes and improvements of SSA construction after code review

* Bugfixes for frontend code simplification

* On-the-fly critical edge splitting in case of br_table with jump arguments

* No more dangling undefined values, now attached as EBB args

* Bugfix: only split corresponding edges on demand, not all br_table edges

* Added signature retrieval method

* Bugfix for critical edge splitting not sealing the ebbs it created

* Proper handling of SSA side effects by the frontend

* Code refactoring: moving frontend and SSA to new crate

* Frontend: small changes and bugfixes after code review
2017-07-11 15:08:57 -07:00
Jakob Stoklund Olesen
a4a8c83aab Start adding Intel 64-bit encodings.
Add a TailRecipe.rex() method which creates an encoding recipe with a
REX prefix.

Define I64 encodings with REX.W for i64 operations and with/without REX
for i32 ops. Only test the with-REX encodings for now. We don't yet have
an instruction shrinking pass that can select the non-REX encodings.
2017-07-11 11:05:27 -07:00
Jakob Stoklund Olesen
fb227cb389 Move Intel recipe_* bodies into intel/recipes.py.
Use a PUT_OP macro in the TailRecipe Python class to replace the code
snippet that emits the prefixes + opcode part of the instruction encoding.

Prepare for the addition of REX prefixes by giving the PUT_OP functions
a third argument representing the REX prefix. For the non-REX encodings,
verify that no REX bits wold be needed.
2017-07-11 11:05:27 -07:00
d1m0
f837dcf4b7 Handle bound instructions in pattern type inference (#113) 2017-07-11 08:39:22 -07:00
d1m0
fc11ae7b72 Emit runtime type checks in legalizer.rs (#112)
* Emit runtime type checks in legalizer.rs
2017-07-10 15:28:32 -07:00
Jakob Stoklund Olesen
528e6ff3f5 Generate instruction unwrapping code for binemit recipes.
Generate code to:

- Unwrap the instruction and generate an error if the instruction format
  doesn't match the recipe.
- Look up the value locations of register and stack arguments.

The recipe_* functions in the ISA binemit modules now take these
unwrapped items as arguments.

Also add an optional `emit` argument to the EncRecipe constructor which
makes it possible to provide inline Rust code snippets for code
emission. This requires a lot less boilerplate than recipe_* functions.
2017-07-07 15:10:17 -07:00
Jakob Stoklund Olesen
27d272ade0 Add a fmt.multi_line() method to srcgen.Formatter.
Write out multiple code lines from a single string after stripping a
common indentation.

Also use this for doc_comment().
2017-07-07 15:10:17 -07:00
Jakob Stoklund Olesen
f0abff3611 Handle tied operands that are not killed by their use.
Any tied register uses are interesting enough to be added to the reguses
list if their value is not killed.

A copy needs to be inserted in that case.
2017-07-05 15:48:06 -07:00
Jakob Stoklund Olesen
64f6a98abe Test a tied operand following a fixed register operand.
The redefined tied value lives in the diverted register.
2017-07-05 15:48:06 -07:00
Jakob Stoklund Olesen
60efc68931 Only print pressure for toprcs containing registers.
Many ISAs don't need 4 top-level register classes, so don't print them.
2017-07-05 15:48:06 -07:00
Jakob Stoklund Olesen
9662f102e5 Intel 32-bit encodings for copy.i32. 2017-07-05 15:48:06 -07:00
d1m0
01abbcbebe Cleanup typos; Remove SAMEAS; More descriptive rank comments; Introduce explicit sorting in free_typevars() (#111)
As per the comment in TypeEnv.normalize_tv about cancellation, whenever we create a TypeVar we must assert that there is no under/overflow. To make sure this always happen move the safety checks to TypeVar.derived() from the other helper methods
2017-07-05 15:47:44 -07:00
Jakob Stoklund Olesen
b7917fe404 Test two consecutive fixed operands.
We need to move the previous value out of the way first.
2017-07-05 12:21:58 -07:00
Jakob Stoklund Olesen
e7db3f2b3a Add a test with a fixed register constraint.
Make sure we use the diverted register location for tied operands.
2017-07-05 12:08:53 -07:00
Jakob Stoklund Olesen
9108716cb7 Implement fmt::Display for AllocatableSet.
Also add a display() method which accepts a RegInfo reference.
2017-07-05 12:08:53 -07:00
d1m0
e35398842d Add better type inference and encapsulate it in its own file (#110)
* Add more rigorous type inference and encapsulate the type inferece code in its own file (ti.py).

Add constraints accumulation during type inference, to represent constraints that cannot be expressed
using bijective derivation functions between typevars.

Add testing for new type inference code.

* Additional annotations to appease mypy
2017-07-05 09:16:44 -07:00
Denis Merigoux
e63c581859 Fixed bug in verifier (#109)
* Fixed bug in verifier
Does not check variable def for unreachable codex

* Check reachability first + file test
2017-07-05 08:44:51 -07:00
Jakob Stoklund Olesen
0d2d1ea8cf Add support for tied operands.
Include a very basic test using an Intel 'sub' instruction. More to
follow.
2017-06-30 13:36:41 -07:00
Jakob Stoklund Olesen
811c1059fc Add Intel call/return encodings. 2017-06-30 12:21:36 -07:00
Jakob Stoklund Olesen
c592d3174f Add Intel iconst.i32 encoding. 2017-06-30 11:41:06 -07:00
Jakob Stoklund Olesen
7bc2e82b16 Implement the basics of the x86-64 ABI.
This is just a rough sketch to get us started. There are bound to be
some issues.

This also legalizes signatures for x86-32, but probably not correctly.
It's basically implementing the x86-64 ABI for 32-bit.
2017-06-30 10:41:26 -07:00
Jakob Stoklund Olesen
983048cdd1 Generate an enum with all the register units in a target.
It is sometimes useful to create constant lists of register units by
name. The generated RU enum can be used for that.
2017-06-30 10:39:51 -07:00
Jakob Stoklund Olesen
aa3bf4467e Hook up the handling of tied register constraints.
Tests are forthcoming, we need to implement Intel ABI lowering first.
2017-06-30 08:41:54 -07:00
Jakob Stoklund Olesen
18dc420352 Repair constraint violations during spilling.
The following constraints may need to be resolved during spilling
because the resolution increases register pressure:

- A tied operand whose value is live through the instruction.
- A fixed register constraint for a value used more than once.
- A register use of a spilled value needs to account for the reload
  register.
2017-06-29 16:51:05 -07:00
Jakob Stoklund Olesen
2b999d9bd6 Add an Index<Value> implementation to Liveness.
Use it to access live ranges that are supposed to be there.
2017-06-29 15:13:04 -07:00
Jakob Stoklund Olesen
138d3c75c6 Spill live-ins and EBB arguments if there are too many. 2017-06-29 14:07:19 -07:00
Jakob Stoklund Olesen
ae661631aa Only color EBB arguments that have register affinity.
It is possible to pass a register value as an argument to an EBB that
expects a "None" affinity. In that case, the destination EBB value
should not be colored.
2017-06-29 13:29:43 -07:00
Jakob Stoklund Olesen
d6f73ac4c8 Split spill_from() into spill_candidate() and spill_reg().
We'll need to pick a spill candidate from a set and allow for the search
to fail to find anything.

This also allows slightly better panic messages when we run out of
registers.
2017-06-29 11:11:46 -07:00
Jakob Stoklund Olesen
588ef0ad2f Propagate affinities for EBB arguments.
A priory, an EBB argument value only gets an affinity if it is used
directly by a non-ghost instruction. A use by a branch passing arguments
to an EBB doesn't count.

When an EBB argument value does have an affinity, the values passed by
all the predecessors must also have affinities. This can cause EBB
argument values to get affinities recursively.

- Add a second pass to the liveness computation for propagating EBB
  argument affinities, possibly recursively.
- Verify EBB argument affinities correctly: A value passed to a branch
  must have an affinity only if the corresponding EBB argument value in
  the destination has an affinity.
2017-06-29 10:30:26 -07:00
Jakob Stoklund Olesen
e7a543ea33 Make sure return values are assigned an affinity.
When an EBB argument value is used only as a return value, it still
needs to be given a register affinity. Otherwise it would appear as a
ghost value with no affinity.

Do the same to call arguments.
2017-06-29 09:24:05 -07:00
Jakob Stoklund Olesen
0574dcdeee Don't coalesce incoming stack arguments.
A function parameter in an incoming_arg stack slot should not be
coalesced into any virtual registers. We don't want to force the whole
virtual register to spill to the incoming_arg slot.
2017-06-28 15:37:38 -07:00
Jakob Stoklund Olesen
b2fda76c5f Assign stack slots to incoming function arguments.
Function arguments that don't fit in registers are passed on the stack.

Create "incoming_arg" stack slots representing the stack arguments, and
assign them to the value arguments during spilling.
2017-06-28 15:03:59 -07:00
Jakob Stoklund Olesen
05cf44a156 Add an offset to StackSlotData.
The offset is relative to the stack pointer in the calling function, so
it excludes the return address pushed by the call instruction itself on
Intel ISAs.

Change the ArgumentLoc::Stack offset to an i32, so it matches the stack
slot offsets.
2017-06-28 14:38:13 -07:00
Jakob Stoklund Olesen
bbdf07a64e Color EBB arguments.
When coloring registers for a branch instruction, also make sure that
the values passed as EBB arguments are in the registers expected by the
EBB.

The first time a branch to an EBB is processed, assign the EBB arguments
to the registers where the branch arguments already reside so no
regmoves are needed.
2017-06-27 16:35:38 -07:00
Jakob Stoklund Olesen
165e80d9bf Process ghost instruction kills during coloring.
Ghost instructions don't generate code, but they can keep registers
alive. The coloring pass needs to process values killed by ghost
instructions so it knows when the registers are freed up.

Also track register pressure changes from ghost kills in the spiller.
2017-06-27 16:35:11 -07:00
Dimo
c073d919f4 Cleanup ValueType.get_names to with_bits form previous PR; Add computation of inverse image of typeset across a derived function - TypeSet.map_inverse; Change TypeVar.constrain_type to perform a more-general computation using inverse images of TypeSets; Tests for map_inverse; 2017-06-26 11:11:28 -07:00
d1m0
7c298078c8 Add image computation of typesets; Remove TypeVar.singleton_type - instead derive singleton type from typeset; (#104) 2017-06-23 11:57:24 -07:00
Jakob Stoklund Olesen
222ea74830 Spill whole virtual registers at a time.
When the spiller decides to spill a value, bring along all of the values
in its virtual register. This ensures that we won't have problems with
computing register pressure around EBB arguments. They will always be
register-to-register or stack-to-stack with related values using the
same stack slot.

This also means that the reloading pass won't have to deal with spilled
EBB arguments.
2017-06-23 10:43:59 -07:00