Commit Graph

75 Commits

Author SHA1 Message Date
Jakob Stoklund Olesen
085e228358 Remove assertions from the hot value_def() function.
The errors caught by these assertions are also detected by the IL
verifier.

Speed up compilation by 13%.
2018-01-22 11:31:21 -08:00
Jakob Stoklund Olesen
d1f236b00a Reimplement coalescer following the Budimlic paper.
The old coalescing algorithm had some algorithmic complexity issues when
dealing with large virtual registers. Reimplement to use a proper
union-find algorithm so we only need one pass through the dominator
forests for virtual registers that are interference free.

Virtual registers that do have interference are split and new registers
built.

This pass is about twice as fast as the old one when dealing with
complex virtual registers.
2018-01-16 12:32:04 -08:00
Jakob Stoklund Olesen
af89006b09 Fix some markdown issues.
Work around some cases where the old markdown parser differs from the
new Pulldown parser for the documentation.
2018-01-08 16:19:16 -08:00
Dan Gohman
3ab4349c1b Use Self instead of repeating the type name. 2017-11-08 10:43:11 -08:00
Dan Gohman
d9743290ea Elide elidable lifetime parameters. 2017-11-06 11:09:56 -08:00
Jakob Stoklund Olesen
b3fb41087e Use the term "Function parameter" instead of "argument".
Rename the ArgumentType type to AbiParam since it describes the ABI
characteristics of a parameter or return value, not just the value type.

In Signature, rename members argument_types and return_types to "params"
and "returns". Again, they are not just types.

Fix a couple lingering references to "EBB arguments".
2017-10-19 17:39:23 -07:00
Jakob Stoklund Olesen
921bcc6c25 Use the term "EBB parameter" everywhere.
Add EBB parameter and EBB argument to the langref glossary to clarify
the distinction between formal EBB parameter values and arguments passed
to branches.

- Replace "ebb_arg" with "ebb_param" in function names that deal with
  EBB parameters.
- Rename the ValueDef variants to Result and Param.
- A bunch of other small langref fixes.

No functional changes intended.
2017-10-19 16:17:09 -07:00
Jakob Stoklund Olesen
57b81a179e Move the CursorBase trait into the cursor module.
Also move the CursorPosition type into the cursor module.

Move layout::cursor into the tests module as LayoutCursor and remove its
ability to insert instructions via the dfg.ins() method. This cursor
type is only used in the layout unit tests now.

The FuncCursor and EncCursor types are the commonly used cursors now.
2017-10-19 12:15:43 -07:00
Jakob Stoklund Olesen
b948de1693 Add a verifier pass for CPU flags.
Only one CPU flags value can be live at a time, and some instructions
clobber the flags.
2017-10-18 15:07:19 -07:00
Jakob Stoklund Olesen
b562fdcd5c Remove the dfg::resolve_copies() method.
This method was important back when result values couldn't be moved
between instructions. Now that results can be moved, value aliases do
everything we need.

Copy instructions are still used to break interferences in the register
allocator's coalescing phase, but there isn't really any reason to use a
copy instruction over a value alias anywhere else.

After and during register allocation, copy instructions are significant,
so we never want to "see through" them like the resolve_copies()
function did.

This is related to #166, but probably doesn't fix the underlying
problem.
2017-10-05 14:46:34 -07:00
Jakob Stoklund Olesen
218959ff65 Convert more tests to FuncCursor. 2017-09-21 13:30:00 -07:00
Jakob Stoklund Olesen
8def91b4ad Remove the unused Nullary instruction format.
This format was only used by the trap instruction which has its own
format now.
2017-09-20 15:59:13 -07:00
Jakob Stoklund Olesen
0c16f13c6b Add a Function::clear() method.
This makes it possible to clear out a Function data structure so it can
be reused for compiling multiple functions.

Also add clear() methods to various sub-structures.
2017-09-08 14:53:55 -07:00
Dan Gohman
2efdc0ed37 Update rustfmt to 0.9.0. 2017-08-31 10:44:59 -07:00
Dan Gohman
bd0590604d Test dfg's next_inst(). 2017-08-31 08:54:50 -07:00
Jakob Stoklund Olesen
7e08b14cf6 Split EntityMap into entity::PrimaryMap and entity::EntityMap.
The new PrimaryMap replaces the primary EntityMap and the PrimaryEntityData
marker trait which was causing some confusion. We now have a clear
division between the two types of maps:

- PrimaryMap is used to assign entity numbers to the primary data for an
  entity.
- EntityMap is a secondary mapping adding additional info.

The split also means that the secondary EntityMap can now behave as if
all keys have a default value. This means that we can get rid of the
annoying ensure() and get_or_default() methods ther were used everywhere
instead of indexing. Just use normal indexing now; non-existent keys
will return the default value.
2017-08-18 16:04:43 -07:00
Jakob Stoklund Olesen
621abb5026 Reorganize the instruction builder traits.
Leave the primary InstBuilderBase trait alone, but add an alternative
InstInserterBase trait that can be implemented instead by builders that
always allocate new instructions with dfg.make_inst().

Any implementation of InstInserterBase can be used as an instruction
builder by wrapping it in an InsertBuilder. The InsertBuilder type adds
additional functionality via the with_results() method which makes it
possible to override the result values on the instruction that is built.

The motivation for this shuffle is that the with_result() functionality
can now be reused by different kinds of instruction builders, as long as
they insert new instructions. So ReplaceBuilder doesn't get
with_results().
2017-08-04 11:56:03 -07:00
Jakob Stoklund Olesen
dba0df787c Move most Cursor methods into a CursorBase trait.
The Cursor navigation methods all just depend on the cursor's position
and layout reference. Make a CursorBase trait that provides access to
this information with methods and implement the navigation methods on
top of that.

This makes it possible to have multiple types implement the cursor
interface.
2017-08-04 09:08:24 -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
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
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
Dan Gohman
0c7316ae28 Lint fixes (#99)
* Replace a single-character string literal with a character literal.

* Use is_some() instead of comparing with Some(_).

* Add code-quotes around type names in comments.

* Use !...is_empty() instead of len() != 0.

* Tidy up redundant returns.

* Remove redundant .clone() calls.

* Remove unnecessary explicit lifetime parameters.

* Tidy up unnecessary '&'s.

* Add parens to make operator precedence explicit.

* Use debug_assert_eq instead of debug_assert with ==.

* Replace a &Vec argument with a &[...].

* Replace `a = a op b` with `a op= b`.

* Avoid unnecessary closures.

* Avoid .iter() and .iter_mut() for iterating over containers.

* Remove unneeded qualification.
2017-06-19 16:24:10 -07:00
Denis Merigoux
2f33848fcd Improved DFG API (#95)
* Improved DFG API with swap_remove_ebb_args and append_inst_arg
* Implemented EntityList::swap_remove
And used it for dfg::swap_remove_ebb_arg
2017-06-09 16:20:38 -07:00
Jakob Stoklund Olesen
0d227fd230 Add a minimalistic reload pass.
The reload pass inserts spill and fill instructions as needed so
instructions that operate on registers will never see a value with stack
affinity.

This is a very basic implementation, and we can't write good test cases
until we have a spilling pass.
2017-06-07 12:05:38 -07:00
Jakob Stoklund Olesen
402cb8e1f6 Add a dfg::replace_result() method.
This is analogous to replace_ebb_arg(). It replaces an instruction
result value with a new value, leaving the old value in a detached
state.
2017-06-07 09:53:27 -07:00
Denis Merigoux
b02ccea8dc Loop analysis of the IL
* Implemented in two passes
* First pass discovers the loops headers (they dominate one of their predecessors)
* Second pass traverses the blocks of each loop
* Discovers the loop tree structure
* Offers a new LoopAnalysis data structure queried from outside the module
2017-06-02 15:30:45 -07:00
Dan Gohman
0e023e97ea Fix more GVN issues (#83)
* Fix GVN skipping the instruction after a deleted instruction.

* Teach GVN to resolve aliases as it proceeds.

* Clean up an obsolete reference to extended_values.
2017-05-25 16:37:31 -07:00
Dan Gohman
c826aefa0a Start a very simple GVN pass (#79)
* Skeleton simple_gvn pass.
* Basic testing infrastructure for simple-gvn.
* Add can_load and can_store flags to instructions.
* Move the replace_values function into the DataFlowGraph.
* Make InstructionData derive from Hash, PartialEq, and Eq.
* Make EntityList's hash and eq functions panic.
* Change Ieee32 and Ieee64 to store u32 and u64, respectively.
2017-05-18 18:18:57 -07:00
Benjamin Bouvier
29dc723e25 Update rustfmt to 0.8.4; (#81) 2017-05-15 15:10:47 -07:00
Jakob Stoklund Olesen
950838c489 Add a regmove instruction.
This will be used to locally change the register locations of values in
order to satisfy instruction constraints.
2017-05-02 11:32:12 -07:00
Jakob Stoklund Olesen
ee5f035e31 Upgrade to Rust 1.17.
- Remove some uses of 'static in const and static globals that are no
  longer needed.
- Use the new struct initialization shorthand.
2017-04-27 12:46:44 -07:00
Jakob Stoklund Olesen
e5115d7793 Remove detach_secondary_results() and other cleanups.
- The detach_secondary_results() is a leftover from the two-plane value
  representation. Use detach_results() instead to remove all instruction
  results.
- Make the append_* DFG methods more direct. Don't depend on calling the
  corresponding attach_* methods. Just create a new value directly,
  using the values.next_key() trick.
2017-04-13 10:37:58 -07:00
Jakob Stoklund Olesen
3197f240ff Add a make_inst_results_reusing() generic method.
This is a generalization of the existing make_inst_results() which lets
you provide some or all of the result values instead of creating all new
ones.
2017-04-13 08:18:52 -07:00
Jakob Stoklund Olesen
84c15e0e66 Add some safety checks for detached values.
These methods are used to reattach detached values:

- change_to_alias
- attach_result
- attach_ebb_arg

Add an assertion to all of them to ensure that the provided value is not
already attached somewhere else. Use a new value_is_attached() method
for the test.

Also include a verifier check for uses of detached values.
2017-04-12 15:19:26 -07:00
Jakob Stoklund Olesen
18b567f88e Flatten the Value reference representation.
All values are now references into the value table, so drop the
distinction between direct and table values. Direct values don't exist
any more.

Also remove the parser support for the 'vxNN' syntax. Only 'vNN' values
can be parsed now.
2017-04-12 14:45:22 -07:00
Jakob Stoklund Olesen
b165d9a313 Remove the first_type() methods from InstructionData.
Also remove the type field from all the variants. The type of the first
result value can be recovered from the value table now.
2017-04-12 14:32:13 -07:00
Jakob Stoklund Olesen
28ff7b7925 Move the ctrl_typevar function into dfg.
Soon, InstructionData won't have sufficient information to compute this.

Give TargetIsa::encode() an explicit ctrl_typevar argument. This
function does not require the instruction to be inserted in the DFG
tables.
2017-04-12 14:32:13 -07:00
Jakob Stoklund Olesen
e653d44f39 Stop linking result values together.
Since results are in a value list, they don't need to form a linked
list any longer.

- Simplify make_inst_results() to create values in the natural order.
- Eliminate the last use of next_secondary_value().
- Delete unused result manipulation methods.
2017-04-12 14:32:13 -07:00
Jakob Stoklund Olesen
8a2398be08 Stop calling Value::new_direct.
We only ever create table values now.

Simplify legalizer::legalize_inst_results. Instead of calling
detach_secondary_results, just detach all the results and don't treat
the first result specially.
2017-04-12 14:32:13 -07:00
Jakob Stoklund Olesen
d133606fe7 Don't assume all first results are direct values.
We're about to change that.
2017-04-12 14:32:13 -07:00
Jakob Stoklund Olesen
f8b473c428 Add detach_results(), attach_result(), and append_result() methods.
These low-level methods for manipulating instruction result value lists
will replace the existing secondary_result methods.
2017-04-12 11:50:59 -07:00
Jakob Stoklund Olesen
0897d43c88 Don't attach a first result in make_inst().
That is now the job of make_inst_results().
2017-04-12 09:45:21 -07:00
Jakob Stoklund Olesen
78a036fa51 Remove the second_result field from instructions.
Now that result values are stored in value lists in the DFG, these
head-of-list pointers are no longer needed.
2017-04-12 09:14:39 -07:00
Jakob Stoklund Olesen
71338bb31f Simplify the back-end of InstBuilder.
We don't want to distinguish between single-result and multiple-result
instructions any longer.

- Merge the simple_instruction() and complex_instruction() builder
  methods into a single build() that can handle all cases.
- All format constructors now take a ctrl_type argument. Previously,
  some would take a result_type argument.
- Instruction constructors no longer attempt to compute a single result
  type. Just pass a ctrl_type and let the backend decide.

Fix one format constructor call in legalizer/split.rs which now takes a
ctrl_type instead of a result type.
2017-04-12 08:56:20 -07:00
Jakob Stoklund Olesen
322a8db839 Change dfg.inst_results to return a slice.
Now we can access instruction results and arguments as well as EBB
arguments as slices.

Delete the Values iterator which was traversing the linked lists of
values. It is no longer needed.
2017-04-11 16:57:15 -07:00
Jakob Stoklund Olesen
3a36435c3b Maintain a ValueList with the results of each instruction.
This is the first step of a larger refactoring to represent instruction
results as value lists instead of using linked lists. The refactoring
will also eliminate the special treatment of first results such that all
result values can be detached and redefined.

This change put us in a temporary state where results are represented
both as linked lists and ValueList vectors.

- Add a dfg.results table.
- Add the first result in make_inst(). This behavior will change.
- Recompute the result list in make_inst_results().
- Make dfg.first_result(inst) crash if the instruction has no results.
2017-04-11 16:21:41 -07:00
Jakob Stoklund Olesen
fe0d986110 Make the dfg.insts table private again.
- Add a dfg.is_inst_valid() method for the verifier.
- Use the inst_args_mut() method when rewriting values in the parser.
- Add a new branch_destination_mut() to use when rewriting EBBs.

This also gets rid of one of the large instruction format switches in
the parser.
2017-04-11 15:03:43 -07:00
Jakob Stoklund Olesen
5209778ae2 Stop maintaining a linked list of EBB arguments.
Now that we have a value list of the arguments, we can get rid of:

- The first_arg and last_arg members in EbbData,
- The next member in the ValueData::Arg variant.
2017-04-11 12:30:37 -07:00
Jakob Stoklund Olesen
ca900d6bf8 Return the whole value list from detach_ebb_args().
Rather than returning the head of a linked list of EBB arguments, just
return the whole value list of all the arguments.

Delete the next_ebb_arg() method which was only used for traversing that
list.
2017-04-11 12:14:33 -07:00
Jakob Stoklund Olesen
dd0a61cc91 Keep EBB arguments in a ValueList.
This is the first step of the value list refactoring which will replace
linked lists of values with value lists.

- Keep a ValueList in the EbbData struct containing all the EBB
  arguments.
- Change dfg.ebb_args() to return a slice instead of an iterator.

This leaves us in a temporary hybrid state where we maintain both a
linked list and a ValueList vector of the EBB arguments.
2017-04-11 11:36:50 -07:00