Commit Graph

219 Commits

Author SHA1 Message Date
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
Jakob Stoklund Olesen
859cca081c Upgrade to rustfmt 0.7.1 2017-01-25 15:17:27 -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
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
Jakob Stoklund Olesen
fb4db38dd6 Fill in boilerplate for Intel and ARM targets.
The intel, arm32, and arm32 targets were only defined in the meta
language previously. Add Rust implementations too.

This is mostly boilerplate, except for the unit tests in the
registers.rs files.
2016-11-23 10:42:07 -08:00
Jakob Stoklund Olesen
353caf23cd Generate register bank descriptions.
Use the information in the ISA's registers.py files to generate a
RegInfo Rust data structure.
2016-11-22 18:15:21 -08:00
Jakob Stoklund Olesen
060735adfe Define register classes for 4 ISAs. 2016-11-11 15:08:12 -08:00
Jakob Stoklund Olesen
e1c0171b2c Define register banks.
Add a RegBank class for describing CPU register banks.

Define register banks for all the ISA stubs. The ARM32 floating point
bank in particular requires attention.
2016-11-11 14:17:10 -08:00
Jakob Stoklund Olesen
f16327e6eb Move some utility functions into the cdsl package.
- is_power_of_two
- next_power_of_two

Make sure we run doctests on these functions.
2016-11-11 13:04:30 -08:00
Jakob Stoklund Olesen
34f7b93482 Add stubs for Intel and ARM architectures.
The Intel ISA handles both 32-bit and 64-bit code.

ARM is split into separate arm32 and arm64 ISAs since the architectures
have little in common in instruction encodings and register files.
2016-11-11 11:32:05 -08:00
Jakob Stoklund Olesen
581294dafe Use uppercase for the global riscv.ISA constant. 2016-11-11 11:17:40 -08:00
Jakob Stoklund Olesen
5e4602efb4 Add expansion patterns for large immediates.
Expand foo_imm into iconst + foo.
2016-11-10 15:55:54 -08:00
Jakob Stoklund Olesen
59eef69a4f Emit type arguments to builder methods that need it.
Use the inferred type variables to construct a type argument for builder
methods. This is for those instructions where the result types cannot be
computed from the result types.
2016-11-10 15:55:54 -08:00
Jakob Stoklund Olesen
36871d3fb1 Add TypeVar.rust_expr().
Generate a Rust expression that computes the value of a derived type
variable.
2016-11-10 15:47:57 -08:00
Jakob Stoklund Olesen
68c9f20b77 Infer type constraints on patterns.
Each instruction used in a pattern has constraints on the types of its
operands. These constraints are expressed as symbolic type variables.

Compute type variables for each variable used in a transformation
pattern. Some are free type variables, and some are derived from the
free type variables.

The type variables associated with variables can be used for computing
the result types of replacement instructions that don't support simple
forward type inference from their inputs.

The type sets computed by this patch are conservatively too large, so
they can't yet be used to type check patterns.
2016-11-10 13:26:07 -08:00
Jakob Stoklund Olesen
38f4b9a7c8 Add a TypeVar.constrain_types() function.
This reduces the set of types a type variable can assume.

This implementation is not complete yet, so it may yield type sets that
are too large.
2016-11-10 11:58:10 -08:00
Jakob Stoklund Olesen
129fd4b06e Add TypeVar.strip_sameas().
Strips out any type variable copies from an expression.
2016-11-10 10:41:49 -08:00
Jakob Stoklund Olesen
d22541dfa2 Add TypeVar.derived() function.
Add TypeVar constants representing the available type functions, and a
TypeVar.derived() static method which creates a derived TypeVar.

Keep the existing non-parametric methods for creating derived type
variables.

Add a method for converting a free type variable to a derived one.
2016-11-10 10:34:27 -08:00