Commit Graph

10588 Commits

Author SHA1 Message Date
Aleksey Kuznetsov
706eef23d3 Binary function names (#91)
* Function names should start with %

* Create FunctionName from string

* Implement displaying of FunctionName as %nnnn with fallback to #xxxx

* Run rustfmt and fix FunctionName::with_string in parser

* Implement FunctionName::new as a generic function

* Binary function names should start with #

* Implement NameRepr for function name

* Fix examples in docs to reflect that function names start with %

* Rebase and fix filecheck tests
2017-06-10 10:30:37 -07:00
Aleksey Kuznetsov
8b484b1c77 Binary function names (#91)
* Function names should start with %

* Create FunctionName from string

* Implement displaying of FunctionName as %nnnn with fallback to #xxxx

* Run rustfmt and fix FunctionName::with_string in parser

* Implement FunctionName::new as a generic function

* Binary function names should start with #

* Implement NameRepr for function name

* Fix examples in docs to reflect that function names start with %

* Rebase and fix filecheck tests
2017-06-10 10:30:37 -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
Denis Merigoux
731278aad8 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
Denis Merigoux
81284dbd93 LICM pass: small changes after code review (#94) 2017-06-08 09:41:57 -07:00
Denis Merigoux
dacc4003a3 LICM pass: small changes after code review (#94) 2017-06-08 09:41:57 -07:00
Jakob Stoklund Olesen
6563270c63 Remove cfg.postorder_ebbs().
This is now unused. Use domtree.cfg_postorder() instead.

Also remove the dead cfg.ebbs().
2017-06-07 13:46:03 -07:00
Jakob Stoklund Olesen
eec980618b Remove cfg.postorder_ebbs().
This is now unused. Use domtree.cfg_postorder() instead.

Also remove the dead cfg.ebbs().
2017-06-07 13:46:03 -07:00
Jakob Stoklund Olesen
f22461b4b3 Stop using cfg.postorder_ebbs().
Switch to the new domtree.cfg_postorder() which returns a reference to a
pre-computed post-order instead of allocating memory and computing a new
post-order.
2017-06-07 13:38:27 -07:00
Jakob Stoklund Olesen
94872cc971 Stop using cfg.postorder_ebbs().
Switch to the new domtree.cfg_postorder() which returns a reference to a
pre-computed post-order instead of allocating memory and computing a new
post-order.
2017-06-07 13:38:27 -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
d94bd8c236 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
dcdfa59aec Implement a conversion from ValueDef into ProgramPoint.
A ValueDef is really no more than a program point plus an
argument/result number.
2017-06-07 11:58:08 -07:00
Jakob Stoklund Olesen
ac1db6e3c9 Implement a conversion from ValueDef into ProgramPoint.
A ValueDef is really no more than a program point plus an
argument/result number.
2017-06-07 11:58:08 -07:00
Jakob Stoklund Olesen
9adfd8709b Add Liveness methods for updating live ranges.
The create_dead() methods can create a live range for a new value, and
extend_local() can extend a live range within an EBB where it is already
live.

This is enough to update liveness for new values as long as they stay
local to their EBB.
2017-06-07 11:57:58 -07:00
Jakob Stoklund Olesen
f545c97cb0 Add Liveness methods for updating live ranges.
The create_dead() methods can create a live range for a new value, and
extend_local() can extend a live range within an EBB where it is already
live.

This is enough to update liveness for new values as long as they stay
local to their EBB.
2017-06-07 11:57:58 -07:00
Denis Merigoux
e47f4a49fb LICM pass (#87)
* LICM pass

* Uses loop analysis to detect loop tree
* For each loop (starting with the inner ones), create a pre-header and move there loop-invariant instructions
* An instruction is loop invariant if it does not use as argument a value defined earlier in the loop
* File tests to check LICM's correctness
* Optimized pre-header creation
If the loop already has a natural pre-header, we use it instead of creating a new one.
The natural pre-header of a loop is the only predecessor of the header it doesn't dominate.
2017-06-07 11:27:22 -07:00
Denis Merigoux
9b06f76057 LICM pass (#87)
* LICM pass

* Uses loop analysis to detect loop tree
* For each loop (starting with the inner ones), create a pre-header and move there loop-invariant instructions
* An instruction is loop invariant if it does not use as argument a value defined earlier in the loop
* File tests to check LICM's correctness
* Optimized pre-header creation
If the loop already has a natural pre-header, we use it instead of creating a new one.
The natural pre-header of a loop is the only predecessor of the header it doesn't dominate.
2017-06-07 11:27:22 -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
Jakob Stoklund Olesen
2d8588d72a 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
Igor
de0f0e5f0a Updated the regex crate to 0.2.2 as per issue #88 (#90)
* Updated the regex crate to 0.2.2 as per issue #88
* Added potential fix for cryptic CI error.
* Fixed incorrect handling of regex name call.

Fixes #88
2017-06-03 12:40:53 -07:00
Igor
90958729fa Updated the regex crate to 0.2.2 as per issue #88 (#90)
* Updated the regex crate to 0.2.2 as per issue #88
* Added potential fix for cryptic CI error.
* Fixed incorrect handling of regex name call.

Fixes #88
2017-06-03 12:40:53 -07:00
Aleksey Kuznetsov
c1d095de18 Run rustfmt on lib/filecheck/tests/basic.rs 2017-06-03 10:00:07 -07:00
Aleksey Kuznetsov
80d92ccbb5 Run rustfmt on lib/filecheck/tests/basic.rs 2017-06-03 10:00:07 -07:00
Aleksey Kuznetsov
026ed7a470 Move lib/filecheck/src/tests directory to lib/filecheck 2017-06-03 10:00:07 -07:00
Aleksey Kuznetsov
920e32ed49 Move lib/filecheck/src/tests directory to lib/filecheck 2017-06-03 10:00:07 -07:00
Jakob Stoklund Olesen
16df1f1cf5 Compute a CFG post-order when building the dominator tree.
The DominatorTree has existing DomNodes per EBB that can be used in lieu
of expensive HastSets for the depth-first traversal of the CFG.

Make the computed and cached post-order available for other passes
through the `cfg_postorder()` method which returns a slice.

The post-order algorithm is essentially the same as the one in
ControlFlowGraph::postorder_ebbs(), except it will never push a
successor node that has already been visited once. This is more
efficient, but it generates a different post-order.

Change the cfg_traversal tests to check this new algorithm.
2017-06-02 16:39:18 -07:00
Jakob Stoklund Olesen
22ad3c0bf8 Compute a CFG post-order when building the dominator tree.
The DominatorTree has existing DomNodes per EBB that can be used in lieu
of expensive HastSets for the depth-first traversal of the CFG.

Make the computed and cached post-order available for other passes
through the `cfg_postorder()` method which returns a slice.

The post-order algorithm is essentially the same as the one in
ControlFlowGraph::postorder_ebbs(), except it will never push a
successor node that has already been visited once. This is more
efficient, but it generates a different post-order.

Change the cfg_traversal tests to check this new algorithm.
2017-06-02 16:39:18 -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
Denis Merigoux
7d6113e479 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
Aleksey Kuznetsov
4f26764e71 Remove unnecessary cloned() in reader::lexer::trailing_digits() 2017-06-02 10:29:13 -07:00
Aleksey Kuznetsov
cb35869803 Remove unnecessary cloned() in reader::lexer::trailing_digits() 2017-06-02 10:29:13 -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
059845880c 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
Dan Gohman
dc809628f4 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
Jakob Stoklund Olesen
1d8efaad83 Add a register pressure tracker.
The spilling and reload passes need to ensure that the set of live
ranges with register affinity can always be assigned registers. The
register pressure tracker can count how many registers are in use for
each top-level register class and give guidance on the type of
registers that need to be spilled when limits are exceeded.

Pressure tracking is extra complicated for the arm32 floating point
register bank because there are multiple top-level register classes (S,
D, Q) competing for the same register units.
2017-05-16 17:02:11 -07:00
Jakob Stoklund Olesen
0c7b2c7b68 Add a register pressure tracker.
The spilling and reload passes need to ensure that the set of live
ranges with register affinity can always be assigned registers. The
register pressure tracker can count how many registers are in use for
each top-level register class and give guidance on the type of
registers that need to be spilled when limits are exceeded.

Pressure tracking is extra complicated for the arm32 floating point
register bank because there are multiple top-level register classes (S,
D, Q) competing for the same register units.
2017-05-16 17:02:11 -07:00
Jakob Stoklund Olesen
d1e37def3f Implement ExactSizeIterator for RegSetIter.
The set of available registers in a register class is known ahead of
time. It can be computed with pop-count.
2017-05-16 10:53:30 -07:00
Jakob Stoklund Olesen
06afd3b77b Implement ExactSizeIterator for RegSetIter.
The set of available registers in a register class is known ahead of
time. It can be computed with pop-count.
2017-05-16 10:53:30 -07:00
Jakob Stoklund Olesen
6787a4ea5c Add a RegClassMask typedef and a MAX_TOPRCS constant.
Avoid spreading u32 as a bitmask of register classes throughout the
code.

Enforce the limit of 32 register classes total. This could easily be
raised if needed.

The MAX_TOPRCS constant is the highest possible number of top-level
register classes in an ISA. The RegClassData.toprc field is always
smaller than this limit.
2017-05-15 16:22:22 -07:00
Jakob Stoklund Olesen
66d2c0a95a Add a RegClassMask typedef and a MAX_TOPRCS constant.
Avoid spreading u32 as a bitmask of register classes throughout the
code.

Enforce the limit of 32 register classes total. This could easily be
raised if needed.

The MAX_TOPRCS constant is the highest possible number of top-level
register classes in an ISA. The RegClassData.toprc field is always
smaller than this limit.
2017-05-15 16:22:22 -07:00
Jakob Stoklund Olesen
71bb7483b7 Compute top-level register classes for each register bank.
A top-level register class is one that has no sub-classes. It is
possible to have multiple top-level register classes in the same
register bank. For example, ARM's FPR bank has both D and Q top-level
register classes.

Number register classes such that all top-level register classes appear
as a contiguous sequence starting from 0. This will be used by the
register allocator when counting used registers per top-level register
class.
2017-05-15 15:19:49 -07:00
Jakob Stoklund Olesen
09ac27a797 Compute top-level register classes for each register bank.
A top-level register class is one that has no sub-classes. It is
possible to have multiple top-level register classes in the same
register bank. For example, ARM's FPR bank has both D and Q top-level
register classes.

Number register classes such that all top-level register classes appear
as a contiguous sequence starting from 0. This will be used by the
register allocator when counting used registers per top-level register
class.
2017-05-15 15:19:49 -07:00
Jakob Stoklund Olesen
621f3a2f50 Add a register bank index to RegClassData.
This makes it possible to find the register bank that contains a
register class.
2017-05-15 15:17:58 -07:00
Jakob Stoklund Olesen
ca6eddaf88 Add a register bank index to RegClassData.
This makes it possible to find the register bank that contains a
register class.
2017-05-15 15:17:58 -07:00
Benjamin Bouvier
29dc723e25 Update rustfmt to 0.8.4; (#81) 2017-05-15 15:10:47 -07:00
Benjamin Bouvier
a2fd9cf0cc Update rustfmt to 0.8.4; (#81) 2017-05-15 15:10:47 -07:00
Jakob Stoklund Olesen
232fb36d8f Generate Intel encoding recipes on demand.
Cretonne's encoding recipes need to have a fixed size so we can compute
accurate branch destination addresses. Intel's instruction encoding has
a lot of variance in the number of bytes needed to encode the opcode
which leads to a number of duplicated encoding recipes that only differ
in the opcode size.

Add an Intel-specific TailEnc Python class which represents an
abstraction over a set of recipes that are identical except for the
opcode encoding. The TailEnc can then generate specific encoding recipes
for each opcode format.

The opcode format is a prefix of the recipe name, so for example, the
'rr' TailEnc will generate the 'Op1rr', 'Op2rr', 'Mp2rr' etc recipes.

The TailEnc class provides a __call__ implementation that simply takes
the sequence of opcode bytes as arguments. It then looks up the right
prefix for the opcode bytes.
2017-05-14 11:53:44 -07:00
Jakob Stoklund Olesen
0694384728 Generate Intel encoding recipes on demand.
Cretonne's encoding recipes need to have a fixed size so we can compute
accurate branch destination addresses. Intel's instruction encoding has
a lot of variance in the number of bytes needed to encode the opcode
which leads to a number of duplicated encoding recipes that only differ
in the opcode size.

Add an Intel-specific TailEnc Python class which represents an
abstraction over a set of recipes that are identical except for the
opcode encoding. The TailEnc can then generate specific encoding recipes
for each opcode format.

The opcode format is a prefix of the recipe name, so for example, the
'rr' TailEnc will generate the 'Op1rr', 'Op2rr', 'Mp2rr' etc recipes.

The TailEnc class provides a __call__ implementation that simply takes
the sequence of opcode bytes as arguments. It then looks up the right
prefix for the opcode bytes.
2017-05-14 11:53:44 -07:00