mirror of
https://github.com/catseye/SixtyPical.git
synced 2024-11-22 17:32:01 +00:00
Flesh out and describe the fallthru optimization algorithm.
This commit is contained in:
parent
237a8b5b39
commit
2be4406964
10
README.md
10
README.md
@ -78,16 +78,6 @@ are trashed inside the block.
|
||||
Not because it saves 3 bytes, but because it's a neat trick. Doing it optimally
|
||||
is probably NP-complete. But doing it adequately is probably not that hard.
|
||||
|
||||
> Every routine is falled through to by zero or more routines.
|
||||
> Don't consider the main routine.
|
||||
> For each routine α that is finally-falled through to by a set of routines R(α),
|
||||
> pick a movable routine β from R, move β in front of α, remove the `jmp` at the end of β and
|
||||
> mark β as unmovable.
|
||||
> Note this only works if β finally-falls through. If there are multiple tail
|
||||
> positions, we can't eliminate all the `jmp`s.
|
||||
> Note that if β finally-falls through to α it can't finally-fall through to anything
|
||||
> else, so the sets R(α) should be disjoint for every α. (Right?)
|
||||
|
||||
### And at some point...
|
||||
|
||||
* `low` and `high` address operators - to turn `word` type into `byte`.
|
||||
|
@ -5,6 +5,50 @@ This is a test suite, written in [Falderal][] format, for SixtyPical's
|
||||
ability to detect which routines make tail calls to other routines,
|
||||
and thus can be re-arranged to simply "fall through" to them.
|
||||
|
||||
The theory is as follows.
|
||||
|
||||
SixtyPical supports a `goto`, but it can only appear in tail position.
|
||||
If a routine r1 ends with a unique `goto` to a fixed routine r2 it is said
|
||||
to *potentially fall through* to r2.
|
||||
|
||||
A *unique* `goto` means that there are not multiple different `goto`s in
|
||||
tail position (which can happen if, for example, an `if` is the last thing
|
||||
in a routine, and each branch of that `if` ends with a different `goto`.)
|
||||
|
||||
A *fixed* routine means, a routine which is known at compile time, not a
|
||||
`goto` through a vector.
|
||||
|
||||
Consider the set R of all routines in the program.
|
||||
|
||||
Every routine r1 ∈ R either potentially falls through to a single routine
|
||||
r2 ∈ R (r2 ≠ r1) or it does not potentially fall through to any routine.
|
||||
We can say out(r1) = {r2} or out(r1) = ∅.
|
||||
|
||||
Every routine r ∈ R in this set also has a set of zero or more
|
||||
routines from which it is potentially falled through to by. Call this
|
||||
in(r). It is the case that out(r1) = {r2} → r1 ∈ in(r2).
|
||||
|
||||
We can trace out the connections by following the in- or our- sets of
|
||||
a given routine. Because each routine potentially falls through to only
|
||||
a single routine, the structures we find will be tree-like, not DAG-like.
|
||||
|
||||
But they do permit cycles.
|
||||
|
||||
So, we first break those cycles. We will be left with out() sets which
|
||||
are disjoint trees, i.e. if r1 ∈ in(r2), then r1 ∉ in(r3) for all r3 ≠ r2.
|
||||
|
||||
We then follow an algorithm something like this. Treat R as a mutable
|
||||
set and start with an empty list L. Then,
|
||||
|
||||
- Pick a routine r from R where out(r) = ∅.
|
||||
- Find the longest chain of routines r1,r2,...rn in R where out(r1) = {r2},
|
||||
out(r2} = {r3}, ... out(rn-1) = {rn}, and rn = r.
|
||||
- Remove (r1,r2,...,rn) from R and append them to L in that order.
|
||||
Mark (r1,r2,...rn-1) as "will have their final `goto` removed."
|
||||
- Repeat until R is empty.
|
||||
|
||||
When times comes to generate code, generate it in the order given by L.
|
||||
|
||||
[Falderal]: http://catseye.tc/node/Falderal
|
||||
|
||||
-> Functionality "Dump fallthru map of SixtyPical program" is implemented by
|
||||
|
Loading…
Reference in New Issue
Block a user