Skip to content

Commit

Permalink
separate core AbstractAnalyzer functionalities from JETAnalyzer a…
Browse files Browse the repository at this point in the history
…nalysis (#244)

* separate core `AbstractAnalyzer` functionalities from `JETAnalyzer` analysis

Remaining TODOs:
1. [x] explain directory structure
2. [x] add performance analyzer (deprecate JETTest.jl)
3. [ x re-organize test
4. [ ] re-organize documentation

Maybe I address 2. ~ 4. in another PR.

* explain code structure

* add performance analyzer

* organize tests
  • Loading branch information
aviatesk authored Sep 2, 2021
1 parent 8b7de0c commit 85aa6be
Show file tree
Hide file tree
Showing 34 changed files with 4,376 additions and 3,686 deletions.
2 changes: 1 addition & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ function generate_api_doc(examples_pages)
isfile(PLUGIN_API_FILENAME) && rm(PLUGIN_API_FILENAME)
open(PLUGIN_API_FILENAME, write=true) do io
contents = codeblock("Pages = $(repr([out]))", "@contents")
interface_docs = codeblock(join(JET.JETInterfaces.DOCUMENTED_NAMES, '\n'))
interface_docs = codeblock(join(JET.JETInterface.DOCUMENTED_NAMES, '\n'))
examples_contents = codeblock("Pages = $(repr(examples_pages))", "@contents")

s = md"""
Expand Down
4 changes: 2 additions & 2 deletions docs/src/internals.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Internals of JET.jl

## [Abstract Interpretation Based Analysis](@id abstractinterpret-analysis)
## [Abstract Interpretation](@id abstractinterpret)

In order to perform type level program analysis, JET.jl uses
[`Core.Compiler.AbstractInterpreter` interface](https://github.com/JuliaLang/julia/blob/master/base/compiler/types.jl),
Expand Down Expand Up @@ -35,7 +35,7 @@ JET.inlining_policy
```


## [Top-level Analysis](@id top-level-analysis)
## [Top-level Analysis](@id toplevel)

```@docs
JET.virtual_process
Expand Down
12 changes: 6 additions & 6 deletions examples/dispatch_analysis.jl
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
# - `Core.Compiler.finish(frame::CC.InferenceState, analyzer::DispatchAnalyzer)` to check if optimization will happen or not (the case 1.)
# - `Core.Compiler.finish!(analyzer::DispatchAnalyzer, caller::CC.InferenceResult)` to inspect an optimized IR (the case 2.)

using JET.JETInterfaces
using JET.JETInterface
const CC = Core.Compiler
import JET:
JET,
Expand Down Expand Up @@ -79,9 +79,9 @@ function module_filter(m)
end

## AbstractAnalyzer API requirements
JETInterfaces.AnalyzerState(analyzer::DispatchAnalyzer) = analyzer.state
JETInterfaces.AbstractAnalyzer(analyzer::DispatchAnalyzer, state::AnalyzerState) = DispatchAnalyzer(state, analyzer.opts, analyzer.frame_filter)
JETInterfaces.ReportPass(analyzer::DispatchAnalyzer) = DispatchAnalysisPass()
JETInterface.AnalyzerState(analyzer::DispatchAnalyzer) = analyzer.state
JETInterface.AbstractAnalyzer(analyzer::DispatchAnalyzer, state::AnalyzerState) = DispatchAnalyzer(state, analyzer.opts, analyzer.frame_filter)
JETInterface.ReportPass(analyzer::DispatchAnalyzer) = DispatchAnalysisPass()

## we want to run different analysis with a different filter, so include its hash into the cache key
function JET.get_cache_key(analyzer::DispatchAnalyzer)
Expand Down Expand Up @@ -120,7 +120,7 @@ function CC.finish(frame::CC.InferenceState, analyzer::DispatchAnalyzer)
end

@reportdef struct OptimizationFailureReport <: InferenceErrorReport end
JETInterfaces.get_msg(::Type{OptimizationFailureReport}, args...) =
JETInterface.get_msg(::Type{OptimizationFailureReport}, args...) =
return "failed to optimize" #: signature of this MethodInstance

function (::DispatchAnalysisPass)(::Type{OptimizationFailureReport}, analyzer::DispatchAnalyzer, result::CC.InferenceResult)
Expand Down Expand Up @@ -151,7 +151,7 @@ function CC.finish!(analyzer::DispatchAnalyzer, frame::CC.InferenceState)
end

@reportdef struct RuntimeDispatchReport <: InferenceErrorReport end
JETInterfaces.get_msg(::Type{RuntimeDispatchReport}, analyzer, s) =
JETInterface.get_msg(::Type{RuntimeDispatchReport}, analyzer, s) =
return "runtime dispatch detected" #: call signature

function (::DispatchAnalysisPass)(::Type{RuntimeDispatchReport}, analyzer::DispatchAnalyzer, caller::CC.InferenceResult, opt::CC.OptimizationState)
Expand Down
12 changes: 6 additions & 6 deletions examples/find_unstable_api.jl
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
# language and those written by ourselves, and in the latter case we're certainly uses
# "unstable API" under the definition above.

using JET.JETInterfaces # to load APIs of the pluggable analysis framework
using JET.JETInterface # to load APIs of the pluggable analysis framework
const CC = Core.Compiler # to inject a customized report pass

# First off, we define `UnstableAPIAnalyzer`, which is a new [`AbstractAnalyzer`](@ref) and will
Expand All @@ -47,12 +47,12 @@ function UnstableAPIAnalyzer(;
jetconfigs...)
return UnstableAPIAnalyzer(AnalyzerState(; jetconfigs...), is_target_module)
end
JETInterfaces.AnalyzerState(analyzer::UnstableAPIAnalyzer) = analyzer.state
JETInterfaces.AbstractAnalyzer(analyzer::UnstableAPIAnalyzer, state::AnalyzerState) =
JETInterface.AnalyzerState(analyzer::UnstableAPIAnalyzer) = analyzer.state
JETInterface.AbstractAnalyzer(analyzer::UnstableAPIAnalyzer, state::AnalyzerState) =
UnstableAPIAnalyzer(state, analyzer.is_target_module)
JETInterfaces.ReportPass(analyzer::UnstableAPIAnalyzer) = UnstableAPIAnalysisPass()
JETInterface.ReportPass(analyzer::UnstableAPIAnalyzer) = UnstableAPIAnalysisPass()

# Next, we overload some of `Core.Compiler`'s [abstract interpretation](@ref abstractinterpret-analysis) methods,
# Next, we overload some of `Core.Compiler`'s [abstract interpretation](@ref abstractinterpret) methods,
# and inject a customized analysis pass (here we gonna name it `UnstableAPIAnalysisPass`).
# In this analysis, we are interested in whether a binding that appears in a target code is
# an "unstable API" or not, and we can simply check if each abstract element appeared during
Expand Down Expand Up @@ -115,7 +115,7 @@ end
@reportdef struct UnstableAPI <: InferenceErrorReport
g::GlobalRef
end
function JETInterfaces.get_msg(::Type{UnstableAPI}, analyzer::UnstableAPIAnalyzer, sv, g::GlobalRef)
function JETInterface.get_msg(::Type{UnstableAPI}, analyzer::UnstableAPIAnalyzer, sv, g::GlobalRef)
(; mod, name) = Base.resolve(g) # resolve to original name
return "$mod.$name is unstable !"
end
Expand Down
Loading

0 comments on commit 85aa6be

Please sign in to comment.