Commit Graph

154 Commits

Author SHA1 Message Date
Jakob Stoklund Olesen
408395db25 Add a legalize_signature method to TargetIsa.
This entry point will be used for controlling ABI conventions when
legalizing.

Provide an empty implementation for RISC-V and let the other ISAs crash
in legalization.

This is just the scaffolding. We still need to:

- Rewrite the entry block arguments to match the legalized signature.
- Rewrite call and return instructions.
- Implement the legalize_signature() function for all ISAs.
- Add shared generic types to help with the legalize_signature()
  functions.
2017-03-03 11:00:26 -08:00
Jakob Stoklund Olesen
cb3e503f07 Use ISA information to display function signatures.
The argument locations contains register unit references that we want to
display with their correct names.
2017-03-03 10:58:45 -08:00
Jakob Stoklund Olesen
00772fb6c4 Add {ValueLoc,ArgumentLoc}::display().
These functions return an object containing the necessary ISA info to
print a ValueLoc or ArgumentLoc correctly.
2017-03-03 10:56:32 -08:00
rep-nop
7459fee71a Converts all try! macros to ? syntax.
Fixes #46
2017-02-26 07:50:55 -08:00
Jakob Stoklund Olesen
c8be39fa9d Add ABI annotations to function signatures.
Specify the location of arguments as well as the size of stack argument
array needed. The ABI annotations are optional, just like the value
locations.

Remove the Eq implementation for Signature which was only used by a
single parser test.
2017-02-24 13:53:46 -08:00
Jakob Stoklund Olesen
15e0822ac3 Add an ArgumentLoc data type.
This will be used to amend function signatures with ABI lowering
information.
2017-02-24 12:09:24 -08:00
Jakob Stoklund Olesen
afd42cf9c2 Convert try! to ? in extfunc.rs 2017-02-24 10:33:08 -08:00
Angus Holder
81a6e343ad Add assertion that the NonZero optimization works on Option<Opcode>. 2017-02-22 10:22:08 -08:00
Angus Holder
75a426a812 Fix test case that I missed before. 2017-02-22 10:22:08 -08:00
Angus Holder
a4e4776087 Removed the Opcode::NotAnOpcode variant, replaced its uses with Option<Opcode>, and used the NonZero optimization to maintain the small 1-byte size of an optional Opcode. 2017-02-22 10:22:08 -08:00
Jakob Stoklund Olesen
a7d24ab1dc Compute the controlling type variable accurately.
Some polymorphic instructions don't return the controlling type
variable, so it has to be computed from the designated operand instead.

- Add a requires_typevar_operand() method to the operand constraints
  which indicates that.
- Add a ctrl_typevar(dfg) method to InstructionData which computes the
  controlling type variable correctly, and returns VOID for monomorphic
  instructions.
- Use ctrl_typevar(dfg) to drive the level-1 encoding table lookups.
2017-02-21 16:26:19 -08:00
Jakob Stoklund Olesen
20ff2f0025 Add a return_reg instruction to the base instruction set.
Register-style return is used by all RISC architectures, so it is
natural to have a shared instruction representation.
2017-02-21 13:05:17 -08:00
Jakob Stoklund Olesen
71ec92281c Add a Layout::next_ebb() method.
This lets us iterate over the blocks in a function without holding a
reference to the layout.
2017-02-14 15:52:44 -08:00
Mikko Perttunen
73202bb3dc 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
4ae7fd2a37 Speling. 2017-02-03 12:49:40 -08:00
Jakob Stoklund Olesen
1221d94272 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
2e6cf219e9 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
f2b9f62f24 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
3fc0f80223 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
52db486500 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
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
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
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
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
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
Jakob Stoklund Olesen
59fd74fb9a Fix off-by-one in resolve_values.
When the extended_values table is empty, the value to resolve is
definitely not an alias, but we still need as least one trip in the loop
to determine that.
2016-11-04 15:28:51 -07:00
Jakob Stoklund Olesen
152aabbfc0 Add arguments() and arguments_mut() methods.
Provide a generic way of accessing the value arguments on an
instruction. This is provided as two slice references. One for the fixed
arguments and one for any VariableArgs.

The arguments() methods return an array of two slices which is a bit
awkward. Also provide an each_arg() method which passes each argument
value to a closure.
2016-11-04 14:16:49 -07:00
Jakob Stoklund Olesen
63fc81541e Add Cursor::set_position.
Make it possible to move a cursor to a new position.

In the current implementation of Layout and Cursor, this is a trivial
operation, but if we switch to a B-tree based function layout, this
involves navigating the tree.
2016-11-04 08:44:01 -07:00
Jakob Stoklund Olesen
3bb6efba6e Add a Value::unwrap_direct() method.
When it is known that a value is the first result of an instruction, it
is safe to unwrap the instruction reference.
2016-11-03 19:13:54 -07:00
Jakob Stoklund Olesen
3da569de06 Require documentation on cretonne public items. 2016-10-26 19:10:06 -07:00
Jakob Stoklund Olesen
bcd5bc559c Begin generating code for the legalizer.
This is a work in progress. The 'legalizer.rs' file generated by
gen_legalizer.py is not used for anything yet.

Add PEP 484 type annotations to a bunch of Python code.
2016-10-26 16:06:57 -07:00
Jakob Stoklund Olesen
b6ff2621f9 File stale path references.
After rearranging the directory layout, some paths in documentation
needed updating.

Fix some typos too.
2016-10-24 13:27:10 -07:00
Jakob Stoklund Olesen
84faddbf65 Introduce value aliases.
A extended value can now be changed to a third form: An alias of another
value. This is like a copy instruction, but implicit in the value table.

Value aliases are used in lieu of use-def chains which would be used to
implement replace-all-uses-with.

Added new DFG methods:

- change_to_alias() changes an existing extended value into an alias.
  Primay values can't be changed, replace their definition with a copy
  instruction instead.
- resolve_aliases() find the original non-alias value.
- resolve_copies() like resolve_aliases(), but also sees through
  copy/spill/fill instructions.
2016-10-21 11:18:12 -07:00
Jakob Stoklund Olesen
61f5eeee2f Properly infer result type for single-result instructions.
Polymorphic single-result instructions don't always return the
controlling type variable as their first result. They may use a derived
type variable, as for example icmp does.
2016-10-21 11:10:26 -07:00
Jakob Stoklund Olesen
20aabcd1c7 Make Type::as_bool() less pedantic for scalars.
All scalar types are mapped to b1 which is usually what you want for a
scalar. Vector types have their lanes mapped to the wider boolean types.

Add an as_bool_pedantic() methos that produces the scalar sized boolean
types as before.

Also add a friendlier Debug implementation for Type.
2016-10-21 10:43:33 -07:00
Jakob Stoklund Olesen
853e995c99 Implement From<i64> for Imm64.
This makes it possible to use literal integers as arguments to
InstBuilder methods.
2016-10-21 10:43:33 -07:00
Jakob Stoklund Olesen
6aa3e4594a Move the 'ins' method to DataFlowGraph.
This given us better symmetry between the replace and insert builder operations:

    dfg.replace(inst).iadd(x, y)
    dfg.ins(cursor).imul(x, y)
2016-10-21 09:46:17 -07:00
Jakob Stoklund Olesen
bb0bb1e91c Add a ReplaceBuilder instruction builder.
The DataFlowGraph::replace(inst) method returns an instruction builder
that will replace an instruction in-place.

This will be used when transforming instructions, replacing an old
instruction with a new (legal) way of computing its primary value. Since
primary result values are essentially instruction pointers, this is the
only way of replacing the definition of a value.

If secondary result values match the old instruction in both number and
types, they can be reused. If not, added a detach_secondary_results()
method for detaching old secondary values.
2016-10-20 13:33:49 -07:00
Jakob Stoklund Olesen
634de93337 Rename Builder to InsertBuilder.
This instruction builder inserts an instruction at the cursor position.
We'll add other kinds of builders shortly.
2016-10-20 11:16:58 -07:00
Jakob Stoklund Olesen
6db94bb980 Switch InstrBuilder to the one-shot builder pattern.
All the InstrBuilder methods now consume the builder, and the non-leaf
methods return the dfg mutable reference they were holding.

This makes it possible to construct instruction builders that are only
safe to use once because they are doing more advanced value rewriting.
2016-10-19 19:33:48 -07:00
Jakob Stoklund Olesen
ab910b3f58 Add a Cursor::ins() method which constructs a Builder.
Rewrite Builder uses in test cases to use this method and construct a
new builder for each instruction. This pattern allows us to change the
InstBuilder trait to a one-shot implementation that can only create a
single instruction.

Don't re-export the Builder struct, it is less important than the
InstBuilder trait, and we may get more implementations.
2016-10-19 19:33:19 -07:00
Jakob Stoklund Olesen
368b12e7cd Use more precise lifetimes for Builder.
Distinguish the lifetime of the Cursor and its referenced function
layout.

Use two separate function lifetimes: 'fc and 'fd. The borrow checker
seems to get confused if we don't.
2016-10-19 19:32:57 -07:00
Jakob Stoklund Olesen
58168bcd07 Generate an InstBuilder trait.
All of the instruction format an opcode methods are emitted as an
InstBuilder trait instead of adding them to the Bulder struct directly.
The methods only make use of the InstBuilderBase methods to create new
instructions.

This makes it possible to reuse the InstBuilder trait for different ways
of inserting instructions.
2016-10-19 18:21:17 -07:00
Jakob Stoklund Olesen
c8f28e5902 Rename lifetimes in layout.rs to 'f
These lifetimes all represent the lifetime of the Function.
2016-10-19 16:23:08 -07:00