Skip to content

Commit

Permalink
update README
Browse files Browse the repository at this point in the history
  • Loading branch information
aviatesk committed Nov 16, 2021
1 parent 8ceae69 commit 61a9fba
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 36 deletions.
32 changes: 13 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@

`EscapeAnalysis` is a simple module that collects escape information from Julia's optimization IR (i.e. `IRCode`).

This analysis works on a lattice called `EscapeLattice`, which holds the following properties:
- `x.Analyzed::Bool`: not formally part of the lattice, indicates this statement has not been analyzed at all
- `x.ReturnEscape::BitSet`: keeps SSA numbers of return statements where it can be returned to the caller
* `isempty(x.ReturnEscape)` means it never escapes to the caller
* otherwise it indicates it will escape to the caller via return (possibly as a field),
where `0 ∈ x.ReturnEscape` has the special meaning that it's visible to the caller
simply because it's passed as call argument
- `x.ThrownEscape::Bool`: indicates it may escape to somewhere through an exception (possibly as a field)
- `x.GlobalEscape::Bool`: indicates it may escape to a global space an exception (possibly as a field)
This analysis works on a lattice called `x::EscapeLattice`, which holds the following properties:
- `x.Analyzed::Bool`: not formally part of the lattice, indicates `x` has not been analyzed at all
- `x.ReturnEscape::Bool`: indicates `x` may escape to the caller via return (possibly as a field),
where `x.ReturnEscape && 0 ∈ x.EscapeSites` has the special meaning that it's visible to
the caller simply because it's passed as call argument
- `x.ThrownEscape::Bool`: indicates `x` may escape to somewhere through an exception (possibly as a field)
- `x.GlobalEscape::Bool`: indicates `x` may escape to a global space an exception (possibly as a field)
- `x.EscapeSites::BitSet`: records program counters (SSA numbers) where `x` can escape
- `x.ArgEscape::Int` (not implemented yet): indicates it will escape to the caller through `setfield!` on argument(s)
* `-1` : no escape
* `0` : unknown or multiple
Expand All @@ -37,15 +36,10 @@ The analysis works on the lattice of [`EscapeLattice`](@ref) and transitions lat
from the bottom to the top in a _backward_ way, i.e. data flows from usage cites to definitions,
until every lattice gets converged to a fixed point by maintaining a (conceptual) working set
that contains program counters corresponding to remaining SSA statements to be analyzed.
Note that the analysis only manages a single global state, with some flow-sensitivity
encoded as property of `EscapeLattice`.
The analysis only manages a single global state that tracks `EscapeLattice` of each argument
and SSA statement, but also note that some flow-sensitivity is encoded as program counters
recorded in the `EscapeSites` property of each each lattice element.

[^MM02]: A Graph-Free approach to Data-Flow Analysis.
[^MM02]: _A Graph-Free approach to Data-Flow Analysis_.
Markas Mohnen, 2002, April.
<https://api.semanticscholar.org/CorpusID:28519618>

TODO:
- [ ] implement more builtin function handlings, and make escape information more accurate
- [ ] make analysis take into account alias information
- [ ] implement `finalizer` elision optimization ([#17](https://github.com/aviatesk/EscapeAnalysis.jl/issues/17))
- [ ] circumvent too conservative escapes through potential `throw` calls by copying stack-to-heap on exception ([#15](https://github.com/aviatesk/EscapeAnalysis.jl/issues/15))
<https://api.semanticscholar.org/CorpusID:28519618>.
34 changes: 17 additions & 17 deletions src/EscapeAnalysis.jl
Original file line number Diff line number Diff line change
Expand Up @@ -145,14 +145,13 @@ end
x::EscapeLattice
A lattice for escape information, which holds the following properties:
- `x.Analyzed::Bool`: not formally part of the lattice, indicates this statement has not been analyzed at all
- `x.ReturnEscape::BitSet`: keeps SSA numbers of return statements where it can be returned to the caller
* `isempty(x.ReturnEscape)` means it never escapes to the caller
* otherwise it indicates it will escape to the caller via return (possibly as a field),
where `0 ∈ x.ReturnEscape` has the special meaning that it's visible to the caller
simply because it's passed as call argument
- `x.ThrownEscape::Bool`: indicates it may escape to somewhere through an exception (possibly as a field)
- `x.GlobalEscape::Bool`: indicates it may escape to a global space an exception (possibly as a field)
- `x.Analyzed::Bool`: not formally part of the lattice, indicates `x` has not been analyzed at all
- `x.ReturnEscape::Bool`: indicates `x` may escape to the caller via return (possibly as a field),
where `x.ReturnEscape && 0 ∈ x.EscapeSites` has the special meaning that it's visible to
the caller simply because it's passed as call argument
- `x.ThrownEscape::Bool`: indicates `x` may escape to somewhere through an exception (possibly as a field)
- `x.GlobalEscape::Bool`: indicates `x` may escape to a global space an exception (possibly as a field)
- `x.EscapeSites::BitSet`: records program counters (SSA numbers) where `x` can escape
- `x.ArgEscape::Int` (not implemented yet): indicates it will escape to the caller through `setfield!` on argument(s)
* `-1` : no escape
* `0` : unknown or multiple
Expand Down Expand Up @@ -194,12 +193,12 @@ ThrownEscape(pc::Int) = EscapeLattice(true, false, true, false, BitSet(pc))
GlobalEscape(pc::Int) = EscapeLattice(true, false, false, true, BitSet(pc))
ArgumentReturnEscape() = EscapeLattice(true, true, false, false, ARGUMENT_ESCAPE_SITES)
let
all_return = BitSet(0:100_000)
global AllEscape() = EscapeLattice(true, true, true, true, all_return)
all_escape_sites = BitSet(0:100_000)
global AllEscape() = EscapeLattice(true, true, true, true, all_escape_sites)
# used for `show`
global AllReturnEscape() = EscapeLattice(true, true, false, false, all_return)
global AllThrownEscape() = EscapeLattice(true, false, true, false, all_return)
global AllGlobalEscape() = EscapeLattice(true, false, false, true, all_return)
global AllReturnEscape() = EscapeLattice(true, true, false, false, all_escape_sites)
global AllThrownEscape() = EscapeLattice(true, false, true, false, all_escape_sites)
global AllGlobalEscape() = EscapeLattice(true, false, false, true, all_escape_sites)
end

# Convenience names for some ⊑ queries
Expand Down Expand Up @@ -317,12 +316,13 @@ The analysis works on the lattice of [`EscapeLattice`](@ref) and transitions lat
from the bottom to the top in a _backward_ way, i.e. data flows from usage cites to definitions,
until every lattice gets converged to a fixed point by maintaining a (conceptual) working set
that contains program counters corresponding to remaining SSA statements to be analyzed.
Note that the analysis only manages a single global state, with some flow-sensitivity
encoded as property of `EscapeLattice`.
The analysis only manages a single global state that tracks `EscapeLattice` of each argument
and SSA statement, but also note that some flow-sensitivity is encoded as program counters
recorded in the `EscapeSites` property of each each lattice element.
[^MM02]: A Graph-Free approach to Data-Flow Analysis.
[^MM02]: _A Graph-Free approach to Data-Flow Analysis_.
Markas Mohnen, 2002, April.
<https://api.semanticscholar.org/CorpusID:28519618>
<https://api.semanticscholar.org/CorpusID:28519618>.
"""
function find_escapes(ir::IRCode, nargs::Int)
(; stmts, sptypes, argtypes) = ir
Expand Down

0 comments on commit 61a9fba

Please sign in to comment.