Commit Graph

886 Commits

Author SHA1 Message Date
Aleksey Kuznetsov
5fa991e325 Apply conditional compilation of isa targets 2017-08-03 06:28:16 -07:00
Aleksey Kuznetsov
c057e005ce Implement conditional compilation configuration in build.rs 2017-08-03 06:28:16 -07:00
Jakob Stoklund Olesen
5edf48b548 Compute the stack frame layout.
Add a StackSlots::layout() method which computes the total stack frame
size and assigns offsets to all spill slots and local variables so they
don't interfere with each other or with incoming or outgoing function
arguments.

Stack slots are given an ad hoc alignment that is the natural alignment
for power-of-two sized spill slots, up to the stack pointer alignment.
It is possible we need explicit stack slot alignment in the future, but
at least for spill slots, this scheme is likely to work for most ISAs.
2017-08-02 13:02:02 -07:00
Dan Gohman
587f37ec6c Don't use documentation-style comments inside a function body. (#131) 2017-08-02 11:19:16 -07:00
Dan Gohman
406d82f62a Avoid floating-point types in Ieee32::new and Ieee64::new. (#130)
* Avoid floating-point types in Ieee32::new and Ieee64::new.

This eliminates the need for unsafe code in code that uses Cretonne, a few
instances of unsafe code in Cretonne itself, and eliminates the only instance
of floating point in Cretonne.

* Rename new to with_bits, and new_from_float to with_float.
2017-08-02 11:05:49 -07:00
Jakob Stoklund Olesen
f03f32ac93 Assign call arguments to stack slots.
When making an outgoing call, some arguments may have to be passed on
the stack. Allocate OutgoingArg stack slots for these arguments and
write them immediately before the outgoing call instruction.

Do the same for incoming function arguments on the stack, but use
IncomingArg stack slots instead. This was previously done in the
spiller, but we move it to the legalizer so it is done at the same time
as outgoing stack arguments.

These stack slot assignments are done in the legalizer before live
range analysis because the outgoing arguments usually are in different
SSSA values with their own short live ranges.
2017-08-01 13:54:47 -07:00
Jakob Stoklund Olesen
ce9e6fe53e Verify the location of outgoing call arguments.
Once a signature has been legalized, the arguments to any call using
that signature must be assigned to the proper stack locations. Outgoing
arguments that are passed on the stack must be assigned to matching
OutgoingArg stack slot locations.

Outgoing arguments that are passed in registers don't need to appear in
the correct registers until after register allocation.
2017-08-01 13:54:47 -07:00
Jakob Stoklund Olesen
7d9edc2d5e Keep track of OutgoingArg stack slots.
Stack slots for outgoing arguments can be reused between function calls.
Add a list of outgoing argument stack slots allocated so far, and
provide a `get_outgoing_arg()` method which will reuse any outgoing
stack slots with matching size and offset.
2017-08-01 13:54:47 -07:00
d1m0
3a4a1d4faf Cleanup for PR #123 (#129)
* Fix bextend semantics; Change smtlib.py to use z3 python bindings for query building instead of raw strings

* Forgot the mypy stubs for z3
2017-07-31 16:02:27 -07:00
Denis Merigoux
07e1f682d0 Added Intel x86-64 encodings for 64bit loads and store instructions (#127)
* Added Intel x86-64 encodings for 64bit loads and store instructions

* Using GPR registers instead of ABCD for istore8 with REX prefix
Fixed testing of 64bit intel encoding

* Emit REX and REX-less encodings for optional REX prefix
Value renumbering in binary64.cton
2017-07-31 14:52:39 -07:00
Jakob Stoklund Olesen
54534e2147 Add Intel legalization for division and multiplication.
These operations need custom legalization in order to use Intel's div
and idiv instructions.
2017-07-28 16:41:59 -07:00
Jakob Stoklund Olesen
99d34cbbd7 Try to depend only on the ir module being in scope.
Generated code should used qualified names assuming that `ir` is in
scope, not everything else.
2017-07-28 16:33:02 -07:00
Jakob Stoklund Olesen
542bad0758 Evaluate instruction predicates during legalization.
The generated legalization code needs to evaluate any instruction
patterns on the input pattern being matched.

Emit predicate checking code inside the InstructionFormat pattern match
where all the instruction's immediate fields are available to the
predicate code.

Also make sure an `args` array is available for any type predicates to
evaluate correctly.
2017-07-28 15:22:53 -07:00
Jakob Stoklund Olesen
b1508d8588 Include bound typevars in the instruction predicate.
We already do this for the encoding tables, but the instruction
predicates computed by Apply.inst_predicate() did not include them.

Make sure we don't duplicate the type check in the Encoding constructor
when passed an Apply AST node.
2017-07-28 14:56:45 -07:00
Jakob Stoklund Olesen
939f188e27 Add an inst.all_typevars() method.
Get all type variables controlling an instruction, whether it is
polymorphic or not.
2017-07-28 14:45:56 -07:00
Jakob Stoklund Olesen
1f02d1f880 Allow for multiple legalization patterns for the same opcode.
Each input pattern can have a predicate in addition to an opcode being
matched. When an opcode has multiple patterns, execute the first pattern
with a true predicate.

The predicates can be type checks or instruction predicates checking
immediate fields.
2017-07-28 13:54:25 -07:00
Jakob Stoklund Olesen
b5076108c1 Support constant integers in AST expressions.
Make it possible to write AST nodes: iconst.i32(imm64(0)).
2017-07-28 13:54:25 -07:00
Dimo
ede02e0f97 Cleanup, typechecking and documentation nits 2017-07-28 10:47:08 -07:00
Dimo
1bbe644080 Add semantics for several more iadd with carry; Add xform_correct() and doc cleanup 2017-07-28 10:47:08 -07:00
Dimo
b5e1e4d454 Add smtlib.py 2017-07-28 10:47:08 -07:00
Dimo
eadb4cd39a Fix broken test_elaborate tests after the moving of is_concrete/cleanup_concrete_rtl 2017-07-28 10:47:08 -07:00
Dimo
42e0476cf4 Add primitive bvult, bvzeroext; Add semantics for bextend, icmp (partial - only for <) iadd_cout 2017-07-28 10:47:08 -07:00
Dimo
51ee47f01e Add Rtl.free_vars() 2017-07-28 10:47:08 -07:00
Dimo
1ddee38895 cleanup_semantics() should remove repeated prim_from_bv(x) 2017-07-28 10:47:08 -07:00
Dimo
11014ec544 Nit: Make elaborate return a new Rtl instead of modifying the existing rtl inplace 2017-07-28 10:47:08 -07:00
Dimo
ef4ca676a4 Move apply() -> Xform.apply(); is_concrete_rtl() -> Rtl.is_concrete(); cleanup_concrete_rtl() -> Rtl.cleanup_concrete_rtl(). Documnetation nits in semantics.elaborate 2017-07-28 10:47:08 -07:00
Dimo
71f1646675 With multiple semantic transforms mentioning Enumerators, it may be possible for there not to be a substitution from the concrete rtl to some of the transforms. This is not an error - just a case where a given semantic transform doesnt apply. (e.g. icmp being described by different transforms with concrete intcc condition codes) 2017-07-28 10:47:08 -07:00
Dimo
5f77369053 Fix up a couple of test changed by unifying control tv first 2017-07-28 10:47:08 -07:00
Dimo
100fbe94dd When doing ti on a polymorphic definition first unify the control variable, then the rest. 2017-07-28 10:47:08 -07:00
Dimo
d5ca31a6fd bextend/breduce need constraints 2017-07-28 10:47:08 -07:00
Jakob Stoklund Olesen
2aca35a9aa Return a function pointer from TargetIsa::encode().
Replace the isa::Legalize enumeration with a function pointer. This
allows an ISA to define its own specific legalization actions instead of
relying on the default two.

Generate a LEGALIZE_ACTIONS table for each ISA which contains
legalization function pointers indexed by the legalization codes that
are already in the encoding tables. Include this table in
isa/*/enc_tables.rs.

Give the `Encodings` iterator a reference to the action table and change
its `legalize()` method to return a function pointer instead of an
ISA-specific code.

The Result<> returned from TargetIsa::encode() no longer implements
Debug, so eliminate uses of unwrap and expect on that type.
2017-07-27 17:08:00 -07:00
Jakob Stoklund Olesen
d1353bba05 Assign legalization codes early.
Make sure legalization codes are assigned by TargetIsa::finish() such
that they can be accessed by multiple gen_* drivers.
2017-07-27 17:08:00 -07:00
Denis Merigoux
b547b78683 Bugfix: encode function wasn't calling legalize function properly 2017-07-27 16:49:09 -07:00
Jakob Stoklund Olesen
051aaed43e Add Intel encodings for more conversion instructions.
The following instructions have simple encodings:

- bitcast.f32.i32
- bitcast.i32.f32
- bitcast.f64.i64
- bitcast.i64.f64
- fpromote.f64.f32
- fdemote.f32.f64

Also add helper functions enc_flt() and enc_i32_i64 to
intel.encodings.py for generating the common set of encodings for an
instruction: I32, I64 w/REX, I64 w/o REX.
2017-07-27 11:08:41 -07:00
Jakob Stoklund Olesen
4cffb7fe53 Add support for type variable wildcards in bound instructions.
Instructions will multiple type variables can now use `any` to indicate
encodings that don't care about the value of a secondary type variable:

    ishl.i32.any instead of ishl.i32.i32

This is only allowed for secondary type variables (which are converted
to instruction predicates). The controlling type variable must still be
fully specified because it is used to key the encoding tables.
2017-07-26 14:55:26 -07:00
Jakob Stoklund Olesen
ef812408f4 Remove the number field from the PredNode union type.
Predicate numbers are available in the maps
isa.settings.predicate_number and isa.instp_number instead.

Like the name field, predicate numbers don't interact well with
unique_pred().
2017-07-26 11:06:43 -07:00
Jakob Stoklund Olesen
98f0a8b8b4 Remove the name field from the PredNode union type.
The name of a predicate was only ever used for named settings that are
computed as a boolean expression of other settings.

- Record the names of these settings in named_predicates instead.
- Remove the name field from all predicates.

Named predicates does not interact well with the interning of predicates
through isa.unique_pred().
2017-07-26 10:14:26 -07:00
Jakob Stoklund Olesen
9ff785fabc Add a predicate_key() method to all predicates.
This enables interning of predicates to avoid duplicates.

Add a predicate registry to TargetIsa for interning predicates per ISA.
2017-07-26 09:58:16 -07:00
Jakob Stoklund Olesen
84aeb3eb56 Generate type check predicates for secondary type variables.
The encoding tables are keyed by the controlling type variable only. We
need to distinguish different encodings for instructions with multiple
type variables.

Add a TypePredicate instruction predicate which can check the type of an
instruction value operand. Combine type checks into the instruction
predicate for instructions with more than one type variable.

Add Intel encodings for fcvt_from_sint.f32.i64 which can now be
distinguished from fcvt_from_sint.f32.i32.
2017-07-26 08:19:44 -07:00
Jakob Stoklund Olesen
637966dc7f Add support for legalization codes in the encoding tables.
The new encoding format allows entries that mean "stop with this
legalization code" which makes it possible to configure legalization
actions per instruction, instead of only per controlling type variable.

This patch adds the Rust side of the legalization codes:

- Add an `Encodings::legalize()` method on the encoding iterator which
  can be called after the iterator has returned `None`. The returned
  code is either the default legalization action for the type, or a
  specific code encountered in the encoding list.

- Change `lookup_enclist` to return a full iterator instead of just an
  offset. The two-phase lookup can bail at multiple points, each time
  with a default legalization code from the level 1 table. This default
  legalization code is stored in the returned iterator.

- Change all the implementations of legal_encodings() in the ISA
  implementations.

This change means that we don't need to return a Result any longer. The
`Encodings` iterator can be empty with an associated legalization code.
2017-07-25 16:45:36 -07:00
Jakob Stoklund Olesen
5a2bb8ba32 Define I64 before I32 for better encoding table compression.
The encoding list compression algorithm is not the sharpest knife in the
drawer. It can reuse subsets of I64 encoding lists for I32 instructions,
but only when the I64 lists are defined first.

With this change and the previous change to the encoding list format, we
get the following table sizes for the Intel ISA:

ENCLISTS: 1478 B ->  662 B
LEVEL2:             1072 B (unchanged)
LEVEL1:     32 B ->   48 B
Total:    2582 B -> 1782 B (-31%)
2017-07-25 15:38:55 -07:00
Jakob Stoklund Olesen
2ccb261e8d Use a more compact encoding list representation.
Encodings has a 16-bit "recipe" field, but even Intel only has 57
recipes currently, so it is unlikely that we will ever need to full
range. Use this to represent encoding lists more compactly.

Change the encoding list to a format that:

- Doesn't need a predicate entry before every encoding entry.
- Doesn't need a terminator after the list for each instruction.
- Supports multiple "stop codes" for configurable guidance of the
  legalizer.

The encoding scheme has these limits:

- 2*NR + NS <= 0x1000
- INSTP + ISAP <= 0x1000

Where:

- NR is the number of recipes in an ISA,
- NS is the number of stop codes (legalization actions).
- INSTP is the number of instruction predicates.
- ISAP is the number of discrete ISA predicates.
2017-07-25 15:38:55 -07:00
Dimo
e41ddf2a0d Change TV ranking to select src vars as a representative during unification; Nit: cleanup dot() emitting code; Nit: fix small bug in verify_semantics() - make an internal copy of src rtl to avoid clobbering of typevars re-used in multiple definitions 2017-07-25 15:38:48 -07:00
Dimo
20d96a1ac4 Handle non-ssa Vars and Enumerator constants in Rtl substitutions 2017-07-24 15:49:34 -07:00
Jakob Stoklund Olesen
776af93ef2 Generate an INST_PREDICATES table for each ISA.
Instead of generating a single `check_instp()` function, create an array
of individual function pointers for checking instruction predicates.

This makes explicit the jump table in the old check_instp() method and
it gives us a way of determining the number of instruction predicates
that exists.
2017-07-24 14:19:17 -07:00
Jakob Stoklund Olesen
f39d75fa58 Generate a RECIPE_PREDICATES table for each ISA.
It turns out that most encoding predicates are expressed as recipe
predicates. This means that the encoding tables can be more compact
since we can check the recipe predicate separately from individual
instruction predicates, and the recipe number is already present in the
table.

- Don't combine recipe and encoding-specific predicates when creating an
  Encoding. Keep them separate.
- Generate a table of recipe predicates with function pointers. Many of
  these are null.
- Check any recipe predicate before accepting a recipe+bits pair.

This has the effect of making almost all instruction predicates
CODE_ALWAYS.
2017-07-24 14:19:17 -07:00
Dimo
b448574a49 Assert all InstructionGroups are closed in TargetIsa.__init__(); Close x86 group 2017-07-24 14:08:44 -07:00
Dimo
7caaf7fea1 Fix CI: Var was only imported when mypy was present. 2017-07-24 14:08:44 -07:00
Dimo
dfb5a524b9 TI failure due to misplaced import 2017-07-24 14:08:44 -07:00
Dimo
74f72a3b43 Documentation nits; Sematnics syntax cleanup 2017-07-24 14:08:44 -07:00