-
Notifications
You must be signed in to change notification settings - Fork 1
Text format #16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Text format #16
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -37,7 +37,7 @@ The following contains a list of hints to be included in the first version of th | |||||||||||||||||
The section `metadata.code.compilation_order` contains the order in which functions should be compiled in order to minimize wait times until the compilation is completed. This is especially relevant during instantiation and startup but might also be relevant later. | ||||||||||||||||||
* *byte offset* |U32| with value 0 (function level only) | ||||||||||||||||||
* *hint length* |U32| in bytes | ||||||||||||||||||
* *compilation order* |U32| starting at 0 (functions with the same order value will be compiled in an arbitrary order but before functions with a higher order value) | ||||||||||||||||||
* *compilation priority* |U32| starting at 0 (functions with the same order value will be compiled in an arbitrary order but before functions with a higher order value) | ||||||||||||||||||
* *hotness* |U32| defining how often this function is called | ||||||||||||||||||
|
||||||||||||||||||
If a length of larger than required to store 2 values is present, only the first two values of the following hint data is evalued while the rest is ignored. This leaves space for future extensions, e.g. grouping functions. Similarly, the *hotness* can be dropped if a length corresponds to only 1 value is given. | ||||||||||||||||||
|
@@ -49,6 +49,22 @@ It is expected and even desired that not all functions are annotated to keep thi | |||||||||||||||||
*Note: This should be moved to `metadata.function.compilation_order` without the byte offset if such a namespace will be supported by custom annotations.* | ||||||||||||||||||
|
||||||||||||||||||
|
||||||||||||||||||
#### Text format | ||||||||||||||||||
|
||||||||||||||||||
Instead of a binary string representation, these hints can also be provided using a more human readable notation in text format: | ||||||||||||||||||
``` | ||||||||||||||||||
@metadata.code.compilation_order( | ||||||||||||||||||
(priority 1) | ||||||||||||||||||
(hotness 100) | ||||||||||||||||||
) | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like the current branch hints have this form: (@metadata.code.branch_hint "\01")
(..instruction attached to..) Perhaps we can follow that? That is,
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, of course. I misremembered the syntax. |
||||||||||||||||||
``` | ||||||||||||||||||
The above example is equivalent to | ||||||||||||||||||
``` | ||||||||||||||||||
@metadata.code.compilation_order("\01\64") | ||||||||||||||||||
``` | ||||||||||||||||||
and tools can produce one or the other. | ||||||||||||||||||
|
||||||||||||||||||
|
||||||||||||||||||
### Instruction frequencies | ||||||||||||||||||
|
||||||||||||||||||
Instruction frequencies might be useful to guide optimizations like inlining, loop unrolling, block deferrals, etc. Within a function, these frequencies inform which blocks lie on the hot path and deserve more expensive optimizations, as well as which are on the cold path and might even allow very expensive steps to even execute the code within (e.g. outlining or de-optimization). An engine can take those decisisions based on the instruction frequency observed, but cannot assume that any part of the code is unreachable based on the instruction frequency. | ||||||||||||||||||
|
@@ -88,6 +104,23 @@ Special values of 0 and 127 indicate that a function should never or always be i | |||||||||||||||||
| 127| |*always optimize* | | ||||||||||||||||||
|
||||||||||||||||||
|
||||||||||||||||||
#### Text format | ||||||||||||||||||
|
||||||||||||||||||
The alternative text format representation for such a section would look as follows | ||||||||||||||||||
``` | ||||||||||||||||||
@metadata.code.instr_freq( | ||||||||||||||||||
(freq 123.45) | ||||||||||||||||||
) | ||||||||||||||||||
``` | ||||||||||||||||||
The given frequency $\frac{n}{N}$ is then converted into the equivalent binary representation | ||||||||||||||||||
``` | ||||||||||||||||||
@metadata.code.instr_freq("\26") | ||||||||||||||||||
``` | ||||||||||||||||||
according to the formula above. | ||||||||||||||||||
|
||||||||||||||||||
Alternatively to `freq` followed by a numeric value, one can provide `never_opt` and `always_opt` with binary representations of `"\00"` and `"\7f"` respectively. | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just to bikeshed a bit, what do you think about |
||||||||||||||||||
|
||||||||||||||||||
|
||||||||||||||||||
### Call targets | ||||||||||||||||||
|
||||||||||||||||||
When dealing with `call_indirect` or `call_ref`, often inefficient code is generated, because the call target is unknown. With code that e.g. uses virtual function calls, there are often very few commonly called targets which a compiler could optimize for. It still needs to have the ability to handle other call targets, but that can then happen at a much lower performance in favor of optimizing for the more commonly called target. | ||||||||||||||||||
|
@@ -104,3 +137,19 @@ The `metadata.code.call_targets` section contains instruction level annotations | |||||||||||||||||
The accumulated call frequency must add up to 100 or less. If it is less than 100, then other call targets that are not listed are responsible for the missing calls. Together with the inline hints on call frequency, this can information can be used to inline function calls as well. The effective call frequency for each call target is then the inlining call frequency multiplied by the fractional call frequency encoded in this section. | ||||||||||||||||||
|
||||||||||||||||||
Similarly to the compilation order section, not all call sites need to be annotated and not all call targets be listed. However, if other call targets are known but not emitted, then the frequency must be below 100 to inform the engine of the missing information. | ||||||||||||||||||
|
||||||||||||||||||
|
||||||||||||||||||
#### Text format | ||||||||||||||||||
|
||||||||||||||||||
The text representation allows for multiple targets | ||||||||||||||||||
``` | ||||||||||||||||||
@metadata.code.call_targets( | ||||||||||||||||||
(target $func1 0.73) | ||||||||||||||||||
(target $func2 0.21) | ||||||||||||||||||
) | ||||||||||||||||||
``` | ||||||||||||||||||
which would be converted into binary format as | ||||||||||||||||||
``` | ||||||||||||||||||
@metadata.code.call_targets("\01\49\02\15) | ||||||||||||||||||
``` | ||||||||||||||||||
under the assumption that `$func1` and `$func2` have function indices 1 and 2 respectively. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the hint itself be renamed to
metadata.code.compilation_priority
?