Commit Graph

151 Commits

Author SHA1 Message Date
Jakob Stoklund Olesen
5fc222348d Use PackedOption<Ebb> to represent jump tables.
Avoid NO_EBB.
2017-01-19 13:41:56 -08:00
Jakob Stoklund Olesen
f004f370c5 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
c041a51e2e Move duplicated entity code into a macro.
Implement ReservedValue for all the entities.
2017-01-19 13:11:50 -08:00
Jakob Stoklund Olesen
e8993e79e4 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
8033deda3a 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
8390c829d3 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
29777e26ee 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
a26a8b5f0d 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
56177ce351 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
94a54eaf30 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
27483d9396 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
f1234003a9 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
893a630ca0 Upgrade to rustfmt 0.6.3 2016-12-21 10:06:49 -08:00
Jakob Stoklund Olesen
3568b93b84 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
f9af88c49e 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
3392a2b79a 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
c1ecb29851 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
93aa2b456e 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
19ac05577c 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
1f6dd0dab7 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
4192ba0532 Define register classes for 4 ISAs. 2016-11-11 15:08:12 -08:00
Jakob Stoklund Olesen
b0b6a8f693 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
c20d7d8f13 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
77c672a279 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
856b8c99aa Use uppercase for the global riscv.ISA constant. 2016-11-11 11:17:40 -08:00
Jakob Stoklund Olesen
d76280afba Add expansion patterns for large immediates.
Expand foo_imm into iconst + foo.
2016-11-10 15:55:54 -08:00
Jakob Stoklund Olesen
a7c58b817c 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
5c9a12f101 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
bf1568035f 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
935da5946f 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
6fd5c6195d Add TypeVar.strip_sameas().
Strips out any type variable copies from an expression.
2016-11-10 10:41:49 -08:00
Jakob Stoklund Olesen
98b3bd9e09 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
Jakob Stoklund Olesen
45fd134d3e Assign a type variable to all VALUE operands.
A few operands have a fixed type assigned. Create a singleton type
variable for these exceptions. Most instructions are polymorphic, so
this is a little overhead.

Eliminate the Operand.typ field and replace it with an Operand.typevar
field which is always a TypeVar, but which only exists in VALUE
operands.
2016-11-08 14:58:44 -08:00
Jakob Stoklund Olesen
bd76623266 Move ISA definitions into cdsl.isa.
The cretonne package is now split into two: cdsl and base.
2016-11-08 13:21:05 -08:00
Jakob Stoklund Olesen
09204ca14a Move ast, xform, and legalize modules.
- cdsl.ast defines classes representing abstract syntax trees.
- cdsl.xform defines classes for instruction transformations.
- base.legalize defines legalization patterns.
2016-11-08 12:33:50 -08:00
Jakob Stoklund Olesen
5fa322f797 Split out instruction definitions.
- cdsl.instructions defines the Instruction class.
- base.instructions defines the base instruction set.
2016-11-08 12:33:50 -08:00
Jakob Stoklund Olesen
2a15130518 Split out instruction formats.
- cdsl.formats provides classes for describing instruction formats.
- base.formats provides concrete instruction format definitions.
2016-11-08 11:48:05 -08:00
Jakob Stoklund Olesen
fa7dc6825a Move Operand itself into cdsl.operands. 2016-11-08 11:30:31 -08:00
Jakob Stoklund Olesen
93a1387f2f Get rid of operand_kind()
This method caused lots of import cycles when type checking.

Use isinstance() in the Operand constructor instead to decipher the
OperandSpec union type.
2016-11-08 11:26:26 -08:00
Jakob Stoklund Olesen
5498169ca0 Split out the typevar module.
- cdsl.typevar defines TypeVar and TypeSet classes.
2016-11-08 11:26:25 -08:00
Jakob Stoklund Olesen
6eaa8eb382 Move formats, entities, and immediates to the base package.
- base.formats defines instruction formats.
- base.entities defines kinds of entity references.
- base.immediates defines kinds of imediate operands.
2016-11-08 11:06:37 -08:00
Jakob Stoklund Olesen
bb28dc6686 Split out operand descriptions.
- cdsl.operands has the Operand and OperandKind classes.
2016-11-08 10:58:23 -08:00
Jakob Stoklund Olesen
2fe61e83f6 Split out predicates and settings.
- cdsl.predicates defines classes for describing predicates.
- cdsl.settings defines classes for describing settings.
- base.settings defines shared settings.
2016-11-08 10:37:17 -08:00
Jakob Stoklund Olesen
f8545574b5 Move ValueType into a new cdsl top-level module.
We want to separate the Python classes that make up the DSL used to
define the Cretonne language from the concrete definitions.

- cdsl.types defines the ValueType class hierarchy.
- base.types defines the concrete types.
2016-11-08 10:12:47 -08:00
Jakob Stoklund Olesen
1e1830aaa6 Resolve import cycles. 2016-11-08 09:06:28 -08:00
Jakob Stoklund Olesen
01494b1a47 Add more Python type annotations. 2016-11-08 08:52:21 -08:00
Jakob Stoklund Olesen
1e2f3c0ed4 Check for unsupported value transformations.
Add an assertion for the value placements that we don't support yet.

1. A primary result in the source pattern becomes a secondary result in
   the destination.
2. A secondary result becomes a secondary result, and the destination
   instruction is not exactly matching the source.
2016-11-04 17:39:20 -07:00
Jakob Stoklund Olesen
7bbbe97d2f Resolve value aliases when legalizing instructions.
Since we're deconstructing an instruction anyway, go ahead and resolve
any value aliases on its arguments before we construct the replacement
instructions.
2016-11-04 15:54:58 -07:00
Jakob Stoklund Olesen
6f1a60366f Create value aliases when necessary.
If a secondary value in the source pattern becomes a primary value in
the destination pattern, it is not possible to overwrite the definition
of the source value.

Instead, change the original source value to an alias to the new promary
value.
2016-11-04 15:31:23 -07:00
Jakob Stoklund Olesen
d34ec1bd06 Write out value aliases when writing instructions.
If an instruction uses any values that are aliases of other values,
print out the alias mappings on lines preceding the instruction. This is
necessary to reconstruct the data flow graph.

We don't make any attempt to only write out each alias mapping once.

The parser does not yet support value aliases.
2016-11-04 15:28:51 -07:00