* 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.
- The detach_secondary_results() is a leftover from the two-plane value
representation. Use detach_results() instead to remove all instruction
results.
- Make the append_* DFG methods more direct. Don't depend on calling the
corresponding attach_* methods. Just create a new value directly,
using the values.next_key() trick.
These methods are used to reattach detached values:
- change_to_alias
- attach_result
- attach_ebb_arg
Add an assertion to all of them to ensure that the provided value is not
already attached somewhere else. Use a new value_is_attached() method
for the test.
Also include a verifier check for uses of detached values.
All values are now references into the value table, so drop the
distinction between direct and table values. Direct values don't exist
any more.
Also remove the parser support for the 'vxNN' syntax. Only 'vNN' values
can be parsed now.
Soon, InstructionData won't have sufficient information to compute this.
Give TargetIsa::encode() an explicit ctrl_typevar argument. This
function does not require the instruction to be inserted in the DFG
tables.
Since results are in a value list, they don't need to form a linked
list any longer.
- Simplify make_inst_results() to create values in the natural order.
- Eliminate the last use of next_secondary_value().
- Delete unused result manipulation methods.
We only ever create table values now.
Simplify legalizer::legalize_inst_results. Instead of calling
detach_secondary_results, just detach all the results and don't treat
the first result specially.
We don't want to distinguish between single-result and multiple-result
instructions any longer.
- Merge the simple_instruction() and complex_instruction() builder
methods into a single build() that can handle all cases.
- All format constructors now take a ctrl_type argument. Previously,
some would take a result_type argument.
- Instruction constructors no longer attempt to compute a single result
type. Just pass a ctrl_type and let the backend decide.
Fix one format constructor call in legalizer/split.rs which now takes a
ctrl_type instead of a result type.
Now we can access instruction results and arguments as well as EBB
arguments as slices.
Delete the Values iterator which was traversing the linked lists of
values. It is no longer needed.
This is the first step of a larger refactoring to represent instruction
results as value lists instead of using linked lists. The refactoring
will also eliminate the special treatment of first results such that all
result values can be detached and redefined.
This change put us in a temporary state where results are represented
both as linked lists and ValueList vectors.
- Add a dfg.results table.
- Add the first result in make_inst(). This behavior will change.
- Recompute the result list in make_inst_results().
- Make dfg.first_result(inst) crash if the instruction has no results.
- Add a dfg.is_inst_valid() method for the verifier.
- Use the inst_args_mut() method when rewriting values in the parser.
- Add a new branch_destination_mut() to use when rewriting EBBs.
This also gets rid of one of the large instruction format switches in
the parser.
Now that we have a value list of the arguments, we can get rid of:
- The first_arg and last_arg members in EbbData,
- The next member in the ValueData::Arg variant.
Rather than returning the head of a linked list of EBB arguments, just
return the whole value list of all the arguments.
Delete the next_ebb_arg() method which was only used for traversing that
list.
This is the first step of the value list refactoring which will replace
linked lists of values with value lists.
- Keep a ValueList in the EbbData struct containing all the EBB
arguments.
- Change dfg.ebb_args() to return a slice instead of an iterator.
This leaves us in a temporary hybrid state where we maintain both a
linked list and a ValueList vector of the EBB arguments.
* Verify that a recomputed dominator tree is identical to the existing one.
* The verifier now typechecks instruction results and arguments.
* The verifier now typechecks instruction results and arguments.
* The verifier now typechecks instruction results and arguments.
* Added `inst_{fixed,variable}_args` accessor functions.
* Improved error messages in verifier.
* Type check return statements against the function signature.
These low-level functions allow us to build up a list of instruction
results incrementally. They are equivalent to the existing
attach_ebb_arg and append_ebb_arg.
Instead, just return the first of the detached values, and provide a
next_secondary_result() method for traversing the list.
This is equivalent to how detach_ebb_args() works, and it allows the
data flow graph to be modified while traversing the list of results.
Add a new kind of instruction format that keeps all of its value
arguments in a value list. These value lists are all allocated out of
the dfg.value_lists memory pool.
Instruction formats with the value_list property set store *all* of
their value arguments in a single value list. There is no distinction
between fixed arguments and variable arguments.
Change the Call instruction format to use the value list representation
for its arguments.
This change is only the beginning. The intent is to eliminate the
boxed_storage instruction formats completely. Value lists use less
memory, and when the transition is complete, InstructionData will have a
trivial Drop implementation.
These two methods can be use to rewrite the argument values to an EBB.
In particular, we need to rewrite the arguments to the entry block to be
compatible with a legalized function signature.
Reuse the put_ebb_arg() method in the implementation of
append_ebb_arg().
- 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.
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().
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.
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.
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.
The make_inst_results() method now understands direct and indirect
calls, and can allocate result values matching the return types of the
function call.
These two tables are used to keep track of type signatures of function
calls as well as external function references used in direct function
calls.
Also add an ExtFuncData struct representing an external function that
can be called directly.
Give these crates each a more standard directory layout with sources in
a 'src' sub-sirectory and Cargo.toml in the top lib/foo directory.
Add license and description fields to each.
The build script for the cretonne crate now lives in
'lib/cretonne/build.rs' separating it from the normal library sources
under 'lib/cretonne/src'.