Rename the ArgumentType type to AbiParam since it describes the ABI
characteristics of a parameter or return value, not just the value type.
In Signature, rename members argument_types and return_types to "params"
and "returns". Again, they are not just types.
Fix a couple lingering references to "EBB arguments".
Add EBB parameter and EBB argument to the langref glossary to clarify
the distinction between formal EBB parameter values and arguments passed
to branches.
- Replace "ebb_arg" with "ebb_param" in function names that deal with
EBB parameters.
- Rename the ValueDef variants to Result and Param.
- A bunch of other small langref fixes.
No functional changes intended.
Also move the CursorPosition type into the cursor module.
Move layout::cursor into the tests module as LayoutCursor and remove its
ability to insert instructions via the dfg.ins() method. This cursor
type is only used in the layout unit tests now.
The FuncCursor and EncCursor types are the commonly used cursors now.
Add integer and floating comparison instructions that return CPU flags:
ifcmp, ifcmp_imm, and ffcmp.
Add conditional branch instructions that check CPU flags: brif, brff
Add instructions that check a condition in the CPU flags and return a
b1: trueif, trueff.
These two value types represent the state of CPU flags after an integer
comparison and a floating point comparison respectively.
Instructions using these types TBD.
The value types are now classified into three groups:
1. Lane types are scalar types that can also be used to form vectors.
2. Vector types 2-256 copies of a lane type.
3. Special types. This is where the CPU flag types will go.
The special types can't be used to form vectors.
Change the numbering scheme for value types to make room for the special
types and add `is_lane()` and `is_special()` classification methods.
The VOID type still has number 0, but it can no longer appear as a
vector lane. It classifies as special now.
The word "scalar" is a bit vague and tends to mean "non-vector". Since
we are about to add new CPU flag value types that can't appear as vector
lanes, make the distinction clear: LaneType represents value types that
can appear as a vector lane.
Also replace the Type::is_scalar() method with an is_vector() method.
This is primarily for the benefit of 32-bit x86 code which can't spill
1-byte types from arbitrary registers. This makes it possible to use
32-bit writes to spill types like b1 and i8.
These small types are expected to be very rare since WebAssembly doesn't
have then, and we tend to push integer arithmetic to at least i32. The
effect of frame sizes should be minimal.
The register allocator doesn't even try to compile unreachable EBBs, so
any values defined in such blocks won't be assigned registers.
Since the dominator tree already has determined which EBBs are
reachable, we should just eliminate any unreachable blocks instead o
trying to do something with the dead code.
Not that this is not a "dead code elimination" pass which would also
remove individual instructions whose results are not used.
- Create a new kind of stack slot: emergency_slot.
- Add a get_emergency_slot() method which finds a suitable emergency
slot given a list of slots already in use.
- Use emergency spill slots when schedule_moves needs them.
This method was important back when result values couldn't be moved
between instructions. Now that results can be moved, value aliases do
everything we need.
Copy instructions are still used to break interferences in the register
allocator's coalescing phase, but there isn't really any reason to use a
copy instruction over a value alias anywhere else.
After and during register allocation, copy instructions are significant,
so we never want to "see through" them like the resolve_copies()
function did.
This is related to #166, but probably doesn't fix the underlying
problem.
These are parallels to the existing regmove instruction, but the divert
the value to and from a stack slot.
Like regmove diversions, this is a temporary diversion that must be
local to the EBB.
An f64 can represent multiple values in the range INT_MIN-1 < x <=
INT_MIN which all truncate to INT_MIN, so comparing the input value
against INT_MIN is not good enough.
Instead, detect overflow on x <= INT_MIN-1 when INT_MIN-1 is an exact
floating point value.
A cursor now also remembers a current source location which will be
assigned to all new instructions created with the cursor.
The old layout::Cursor can't support source locations because it doesn't
have a reference to the full ir::Function.
These formats are not used any longer after the heap_load and heap_store
instructions were replaced by heap_addr.
Also drop the Uoffset32 immediate operand type which isn't used either.
Use the simplest expansion which materializes the bits of the floating
point constant as an integer and then bit-casts to the floating point
type. In the future, we may want to use constant pools instead. Either
way, we need custom legalization.
Also add a legalize_monomorphic() function to the Python targetISA class
which permits the configuration of a default legalization action for
monomorphic instructions, just like legalize_type() does for polymorphic
instructions.
Fixes#56.
We now have complete support for value location annotations in the
textual IL format. Values defined by instructions as well as EBB
arguments are covered.
- ArgumentType::special() creates a new special-purpose argument without
assigning it to a register location.
- Signature::special_arg_index() funds a unique special-purpose
argument.
- Function::special_arg() finds a special-purpose argument by value.
Also add a new "sigid" argument purpose which will be used for runtime
signature checks in WebAssembly indirect calls.
The flag guarantees that the generated function does not have any
internal return instructions. If the function returns at all, the return
must be the last instruction.
For now just implement a verifier check for this property. When we get
CFG simplifiers and block layout optimizations, they will need to heed
the flag.
With FuncEnvironment using FuncCursors in place of full
FunctionBuilders, it's useful to move several of these convenience
functions from FunctionBuilder to Function.
This makes it possible to clear out a Function data structure so it can
be reused for compiling multiple functions.
Also add clear() methods to various sub-structures.
Add two new arguments:
- table_index is the WebAssembly table referenced in the indirect call.
- sig_index is the WebAssembly signature index. We still have the SigRef
that was created by make_indirect_sig(), but the WebAssembly signature
index may be needed for detecting type mismatches at runtime.
Change the insertion location to a plain FuncCursor rather than a
FunctionBuilder<Local>. The fact that cretonne-wasm uses FunctionBuilder
should be an implementation detail, and the callbacks don't need to
access WebAssembly locals, so they don't need the extended interface.
Add a FunctionBuilder::cursor() method which creates a FuncCursor for
inserting instructions in the current EBB.
Also add a FuncEnvironment::translate_call() method which allows the
environment to override direct calls the same way as indirect calls.