Commit Graph

961 Commits

Author SHA1 Message Date
Mikko Perttunen
5a1d9561a7 Coalesce live range intervals in adjacent EBBs
LiveRanges represent the live-in range of a value as a sorted
list of intervals. Each interval starts at an EBB and continues
to an instruction. Before this commit, the LiveRange would store
an interval for each EBB. This commit changes the representation
such that intervals continuing from one EBB to another are coalesced
into one.

Fixes #37.
2017-02-14 08:06:38 -08:00
Jakob Stoklund Olesen
f6391c57e8 Compute register affinities during liveness analysis.
Each live range has an affinity hint containing the preferred register
class (or stack slot). Compute the affinity by merging the constraints
of the def and all uses.
2017-02-03 15:06:05 -08:00
Jakob Stoklund Olesen
f8e4d4e839 Speling. 2017-02-03 12:49:40 -08:00
Jakob Stoklund Olesen
933dfc70c1 Fix a dead code warning from the new Rust compiler.
On ISAs with no instruction predicates, just emit an unimplemented!()
stub for the check_instp() function. It is unlikely that a finished ISA
will not have any instruction predicates.
2017-02-03 11:28:59 -08:00
Jakob Stoklund Olesen
dab96d8ea2 Add entity lists.
Like a vector, but with a tiny footprint, and allocated from a pool so
all memory can be released very quickly.
2017-01-31 15:04:26 -08:00
Jakob Stoklund Olesen
16f4b4c7d5 Implement value affinities for register allocation.
An SSA value is usually biased towards a specific register class or a
stack slot, depending on the constraints of the instructions using it.

Represent this bias as an Affinity enum, and implement a merging
algorithm for updating an affinity to satisfy a new constraint.

Affinities will be computed as part of the liveness analysis. This is
not implemented yet.
2017-01-27 10:22:50 -08:00
Andrea Canciani
fd3cd153ed Fix some typos in the documentation
These were found by the spellchecker.
2017-01-27 09:51:22 -08:00
Jakob Stoklund Olesen
c767f277fa Stop testing on nightly rust
The nightly compiler isn't able to compile rustfmt in 10 minutes. This causes Travis CI to terminate the build.

We keep testing on beta and stable.
2017-01-25 16:35:28 -08:00
Jakob Stoklund Olesen
38bb98cf39 Make sure we can find rustfmt. 2017-01-25 15:57:43 -08:00
Jakob Stoklund Olesen
38aff37c1e Install rustfmt when running under Travis CI.
The built rustfmt should be cached.
2017-01-25 15:42:16 -08:00
Jakob Stoklund Olesen
eecbcf9844 Add pip files to the cache. 2017-01-25 15:35:58 -08:00
Jakob Stoklund Olesen
859cca081c Upgrade to rustfmt 0.7.1 2017-01-25 15:17:27 -08:00
Jakob Stoklund Olesen
70957cc7ce Doesn't work with 12.02 LTS's Python 3.2.
Try switching to Trusty to get a newer Python 3.
2017-01-25 14:59:48 -08:00
Jakob Stoklund Olesen
361d71a0ab The python3-pip package does not exist on Ubuntu 12.04 LTS.
Try to go via python3-setuptools instead.
2017-01-25 14:51:48 -08:00
Jakob Stoklund Olesen
10c2f397a8 Pull in a python3 Ubuntu package for Travis CI.
Then use pip3 to install dependencies.
2017-01-25 14:45:41 -08:00
Jakob Stoklund Olesen
91a7922474 Use Python 3.6 in Travis builds 2017-01-25 14:32:52 -08:00
Jakob Stoklund Olesen
4c5bca6b0d Install Python packages without Travis root user. 2017-01-25 14:26:28 -08:00
Jakob Stoklund Olesen
3bbe3f71cb Install mypy and flake8 in Travis environment. 2017-01-25 14:20:22 -08:00
Jakob Stoklund Olesen
4a0d8aaa3d Run Python checks from test-all.sh
The Python style enforcements are easy to miss otherwise.
2017-01-25 14:12:36 -08:00
Jakob Stoklund Olesen
130c4acf51 Compute register class intersections.
Ensure that the set of register classes is closed under intersection.

Provide a RegClass::intersect() method which finds the register class
representing the intersection of two classes.

Generate a bit-mask of subclasses for each register class to be used by
the intersect() method.

Ensure that register classes are sorted topologically. This is also used
by the intersect() method.
2017-01-25 13:57:43 -08:00
Jakob Stoklund Olesen
2390e3e3f0 Add operand register constraints.
Every encoding recipe must specify register constraints on input and
output values.

Generate recipe constraint tables along with the other encoding tables.
2017-01-25 13:35:18 -08:00
Jakob Stoklund Olesen
3b83496edb Add an AllocatableSet for registers.
This set of available register units also manages register aliasing in
an efficient way.

Detect if the units in a register straddles mask words. The algorithm
for allocating multi-unit registers expect the whole register to be
inside a single mask word. We could handle this if necessary, but so far
no ISAs need it.
2017-01-23 12:43:32 -08:00
Jakob Stoklund Olesen
1d21422032 Generate register class descriptors.
Add a mechanism for defining sub-classes of register classes.
2017-01-20 14:23:06 -08:00
Jakob Stoklund Olesen
58c36f71e9 Fix flake8 style issue. 2017-01-20 10:33:45 -08:00
Jakob Stoklund Olesen
5eba3db4e0 Remove EntityRef::wrap().
This has been superceded by PackedOption.
2017-01-20 09:35:57 -08:00
Jakob Stoklund Olesen
2e19fa8e07 Remove NO_INST and the Default+Ord impls for Inst.
Clean up comments.

Add an assertion to check that PackedOption is working as designed.
2017-01-19 19:44:16 -08:00
Jakob Stoklund Olesen
02bf84431b Use PackedOption<Inst> in the dominator tree.
Also rework the algorithm to be more robust against unreachable blocks.

- Add an is_reachable(ebb) method.
- Change idom(ebb) to just return an instruction.
- Make idom() return None for the entry block as well as unreachable
  blocks.
2017-01-19 19:44:16 -08:00
Jakob Stoklund Olesen
0d77b19708 Use PackedOption<Value> instead of NO_VALUE.
- Remove NO_VALUE and ExpandedValue::None.
- Remove the Default implelmentation for Value.
- InstructionData::second_result() returns an Option<Value>.
- InstructionData::second_result() returns a reference to the packed
  option.
2017-01-19 15:55:18 -08:00
Jakob Stoklund Olesen
1389a51c7a Avoid using NO_INST in the parser.
This was only used for the comment rewrite mechanism, and we can just
predict the next allocated instruction number instead. See the other
uses of next_key() for gather_comments().
2017-01-19 14:49:55 -08:00
Jakob Stoklund Olesen
bdc0f53c91 Use PackedOption<Inst> in the Layout implementation.
This also revealed that the last_inst() method should return an Option.
2017-01-19 14:26:47 -08:00
Jakob Stoklund Olesen
b8200d7be9 Use PackedOption<Ebb> in the Layout implementation.
The doubly linked lists are terminated with None.

Remove NO_EBB and the Default impl for Ebb.
2017-01-19 14:05:32 -08:00
Jakob Stoklund Olesen
2f6a33f16d Use PackedOption<Ebb> to represent jump tables.
Avoid NO_EBB.
2017-01-19 13:41:56 -08:00
Jakob Stoklund Olesen
7b8239d076 Remove Default implementations from many entity references.
These types can be wrapped in a PackedOption now, so we don't need the
NO_* constants and default values.
2017-01-19 13:15:50 -08:00
Jakob Stoklund Olesen
8a30bae909 Move duplicated entity code into a macro.
Implement ReservedValue for all the entities.
2017-01-19 13:11:50 -08:00
Jakob Stoklund Olesen
b42faea980 Implement PackedOption to address #19.
The PackedOption<T> struct uses the same amount of memory as T, but can
represent None via a reserved value.
2017-01-19 13:10:32 -08:00
Jakob Stoklund Olesen
32193d21a2 Update regalloc document to reflect implementation. 2017-01-19 11:04:11 -08:00
Jakob Stoklund Olesen
aec53ec3a9 Add a liveness analysis.
This code is best tested with larger functions with more EBBs.
Perhaps a new file-test category is in order?
2017-01-13 11:59:00 -08:00
Jakob Stoklund Olesen
05e06cb876 Implement DoubleEndedIterator for the ebb_insts() iterator.
Make it possible to iterate backwards over the instructions in an EBB.
2017-01-10 15:33:03 -08:00
Jakob Stoklund Olesen
b5715d5c48 Allow live ranges to be values in a SparseMap.
This requires the value number to be stored in the live range itself.
2017-01-10 14:21:56 -08:00
Jakob Stoklund Olesen
748fbd993e Add iteration support to SparseMap.
This is simply the slice iterator for the dense vector.

- map.values() returns an iterator with references to the values.
- for i in &map iterates over references to the values.
2017-01-10 13:54:46 -08:00
Jakob Stoklund Olesen
d9b63bf227 Implement a SparseMap data structure.
This implements the classic Briggs/Torczon sparse set construct.

Adapt it to our existing EntityRef infrastructure so we can use types
keys instead of just integers like the original paper does.

Also provide a SparseSet<T> type alias which implements a sparse set of
entity refeences. This is actually closer to what the original paper
describes.
2017-01-10 11:38:26 -08:00
Jakob Stoklund Olesen
b6c2d4588f Add a LiveRange data structure.
We will track live ranges separately for each SSA value, rather than per
virtual register like LLVM does.

This is the basis for a register allocator, so place it in a new
regalloc module.
2017-01-06 17:16:25 -08:00
Jakob Stoklund Olesen
ae28ef90ef Encourage better optimization of ProgramOrder::cmp.
The ProgramOrder::cmp() comparison is often used where one or both
arguments are statically known to be an Inst or Ebb. Give the compiler a
better chance to discover this via inlining and other optimizations.

- Make cmp() generic with Into<ExpandedProgramPoint> bounds.
- Implement the natural From<T> traits for ExpandedProgramPoint.
- Make Layout::pp_seq() generic with the same bound.

Now, with inlining and constant folding, passing an Inst argument to
PO::cmp() will result in a call to a monomorphized Layout::seq::<Inst>()
which can avoid the dynamic match to select a table for looking up the
sequence number.

The result is that comparing two program points of statically known type
results in two direct table lookups and a sequence number comparison.

This all uses ExpandedProgramPoint because it is more likely to be
transparent to the constant folder than the bit-packed ProgramPoint
type.
2017-01-05 14:03:09 -08:00
Jakob Stoklund Olesen
7b04f5bb31 Implement ProgramOrder for Layout.
Assign sequence numbers to both instructions and EBB headers such that
their relative position can be determined in constant time simply by
comparing sequence numbers.

Implement the sequence numbers with a scheme similar to the line numbers
used in BASIC programs. Start out with 10, 20, 30, ... and pick numbers
in the gaps as long as possible. Renumber locally when needed.
2016-12-30 12:22:48 -08:00
Jakob Stoklund Olesen
a61a6e888e Upgrade to rustfmt 0.6.3 2016-12-21 10:06:49 -08:00
Jakob Stoklund Olesen
29276679b1 Add program points.
Program points are used to represent a linear position in a function.
Thus will be used for the live ranges of values.
2016-12-20 15:50:29 -08:00
Jakob Stoklund Olesen
e1c5abaff5 Add a ValueLoc type and the locations table.
This table holds the result of register allocation.
2016-12-08 13:57:28 -10:00
Jakob Stoklund Olesen
a08a470a18 Fix Python formatting to keep flake8 happy.
Python coding style is verified by the lib/cretonne/meta/check.sh script
which is not run as part of test-all.sh.

cc @dinfuehr
2016-12-08 13:30:40 -10:00
Dominik Inführ
de0ea36942 remove old is_terminating function
for InstructionData. Use generated `is_terminator()` for `Opcode`
instead. `is_terminator`, `can_trap` and `is_branch` functions are now
public.

fix syntax error
2016-12-07 10:16:01 -10:00
Dominik Inführ
8285f2a672 added Opcode flags methods
generate `is_branch`, `is_terminator`, `can_trap` methods for `enum
Opcode`.
2016-12-02 15:50:28 -08:00