Update language reference.

Add a glossary and explain the overall shape of a Cretonne function.
This commit is contained in:
Jakob Stoklund Olesen
2016-01-21 14:25:16 -08:00
parent a686c72ad3
commit 75544db19a
3 changed files with 138 additions and 45 deletions

8
cranelift/docs/example.c Normal file
View File

@@ -0,0 +1,8 @@
float
average(const float *array, size_t count)
{
double sum = 0;
for (size_t i = 0; i < count; i++)
sum += array[i];
return sum / count;
}

View File

@@ -0,0 +1,31 @@
function average(i32, i32) -> f32 {
ss1 = local 8, align 4 ; Stack slot for ``sum``.
entry ebb1(v1: i32, v2: i32):
v3 = fconst.f64 0.0
stack_store v3, ss1
brz v2, ebb3 ; Handle count == 0.
v4 = iconst.i32 0
br ebb2(v4)
ebb2(v5: i32):
v6 = imul_imm v5, 4
v7 = iadd v1, v6
v8 = heap_load.f32 v7 ; array[i]
v9 = fext.f64 v8
v10 = stack_load.f64 ss1
v11 = fadd v9, v10
stack_store v11, ss1
v12 = iadd_imm v5, 1
v13 = icmp ult v12, v2
brnz v13, ebb2(v12) ; Loop backedge.
v14 = stack_load.f64 ss1
v15 = cvt_utof.f64 v2
v16 = fdiv v14, v15
v17 = ftrunc.f32 v16
return v17
ebb3:
v100 = fconst.f32 0x7fc00000 ; 0/0 = NaN
return v100
}

View File

@@ -21,62 +21,53 @@ multiple functions, and the programmatic API can create multiple function
handles at the same time, but the functions don't share any data or reference
each other directly.
This is a C function that computes the average of an array of floats:
This is a simple C function that computes the average of an array of floats:
.. code-block:: c
.. literalinclude:: example.c
:language: c
float average(const float *array, size_t count) {
double sum = 0;
for (size_t i = 0; i < count; i++)
sum += array[i];
return sum / count;
}
Here is the same function compiled into Cretonne IL:
Here it is compiled into Cretonne IL::
.. literalinclude:: example.cton
:language: cton
:linenos:
:emphasize-lines: 2
function average(i32, i32) -> f32 {
; Preamble.
ss1 = local 8, align 4
The first line of a function definition provides the function *name* and
the :term:`function signature` which declares the argument and return types.
Then follows the :term:`function preample` which declares a number of entities
that can be referenced inside the function. In the example above, the preample
declares a single local variable, ``ss1``.
entry ebb1(v1: i32, v2: i32):
v3 = fconst.f64 0.0
stack_store v3, ss1
brz v2, ebb3 ; Handle count == 0.
v4 = iconst.i32 0
br ebb2(v4)
After the preample follows the :term:`function body` which consists of
:term:`extended basic block`\s, one of which is marked as the :term:`entry
block`. Every EBB ends with a :term:`terminator instruction`, and execution
can never fall through to the next EBB without an explicit branch.
ebb2(v5: i32):
; Compute address of array element.
v6 = imul_imm v5, 4
v7 = iadd v1, v6
v8 = heap_load.f32 v7 ; array[i]
v9 = fext.f64 v8
; Add to accumulator in ss1.
v10 = stack_load.f64 ss1
v11 = fadd v9, v10
stack_store v11, ss1
; Increment loop counter.
v12 = iadd_imm v5, 1
v13 = icmp ult v12, v2
brnz v13, ebb2(v12) ; Loop backedge.
; Compute average from sum.
v14 = stack_load.f64 ss1
v15 = cvt_utof.f64 v2
v16 = fdiv v14, v15
v17 = ftrunc.f32 v16
return v17
Static single assignment form
-----------------------------
ebb3:
v100 = fconst.f32 0x7f800000 ; Inf
return v100
}
The instructions in the function body use and produce *values* in SSA form. This
means that every value is defined exactly once, and every use of a value must be
dominated by the definition.
Cretonne does not have phi instructions but uses *EBB arguments* instead. An EBB
can be defined with a list of typed arguments. Whenever control is transferred
to the EBB, values for the arguments must be provided. When entering a function,
the incoming function arguments are passed as arguments to the entry EBB.
Type system
Instructions define zero, one, or more result values. All SSA values are either
EBB arguments or instruction results.
In the example above, the loop induction variable ``i`` is represented as three
SSA values: In the entry block, ``v4`` is the initial value. In the loop block
``ebb2``, the EBB argument ``v5`` represents the value of the induction
variable during each iteration. Finally, ``v12`` is computed as the induction
variable value for the next iteration.
Value types
===========
All SSA values have a type which determines the size and shape (for SIMD
vectors) of the value. Many instructions are polymorphic -- they can operate on
different types.
@@ -653,3 +644,66 @@ Conversion operations
.. inst:: a = cvt_utof x
.. inst:: a = cvt_stof x
Glossary
========
.. glossary::
function signature
A function signature describes how to call a function. It consists of:
- The calling convention.
- The number of arguments and return values. (Functions can return
multiple values.)
- Type and flags of each argument.
- Type and flags of each return value.
Not all function atributes are part of the signature. For example, a
function that never returns could be marked as ``noreturn``, but that
is not necessary to know when calling it, so it is just an attribute,
and not part of the signature.
function preample
A list of declarations of entities that are used by the function body.
Some of the entities that can be declared in the preample are:
- Local variables.
- Functions that are called directly.
- Function signatures for indirect function calls.
- Function flags and attributes that are not part of the signature.
basic block
A maximal sequence of instructions that can only be entered from the
top, and that contains no branch or terminator instructions except for
the last instruction.
extended basic block
EBB
A maximal sequence of instructions that can only be entered from the
top, and that contains no :term:`terminator instruction`s except for
the last one. An EBB can contain conditional branches that can fall
through to the following instructions in the block, but only the first
instruction in the EBB can be a branch target.
The last instrution in an EBB must be a :term:`terminator instruction`,
so execion cannot flow through to the next EBB in the function. (But
there may be a branch to the next EBB.)
Note that some textbooks define an EBB as a maximal *subtree* in the
control flow graph where only the root can be a join node. This
definition is not equivalent to Cretonne EBBs.
terminator instruction
A control flow instruction that unconditionally directs the flow of
execution somewhere else. Execution never continues at the instruction
following a terminator instruction.
The basic terminator instructions are :inst:`br`, :inst:`return`, and
:inst:`trap`. Conditional branches and instructions that trap
conditionally are not terminator instructions.
entry block
The :term:`EBB` that is executed first in a function. Currently, a
Cretonne function must have exactly one entry block. The types of the
entry block arguments must match the types of arguments in the function
signature.