-
Notifications
You must be signed in to change notification settings - Fork 10
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
Type inference prototype based on static analysis #92
Open
0x7CFE
wants to merge
105
commits into
develop
Choose a base branch
from
feature/17/type_inference
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Also branch optimization technique is proposed, however it is currently lead to a malformed graph Issue: #32
This allows us to classify graph edges during graph walk.
Previous version of optimizer merged taus incorrectly. Method which produced error was Interval>>do: Producer1 \ { Aggregator <- Consumer } x 3 / Producer2 \ { Aggregator <- Consumer } x 3 Producer3 / Correct solution should be Producer1 \ / Consumer1 Aggregator - Consumer2 / \ Consumer3 Producer2 \ / Consumer4 Aggregator - Consumer5 Producer3 / \ Consumer6 but due to incorrect handling of pending nodes lists algorithm yielded the following result: Producer1 \ Producer2 - Aggregator <- Consumer x 6 Producer3 / So there was a single aggregator node that was referred by all six consumers.
AssignX instructions leave their argument on the stack. That was causing problems during processing of argument requests.
Issue: #17
It allows to compare any two types, store them in STL container such as std::set, use them as a key in std::map and use composition operators during type inference procedure. Operator | is a disjunction-like operator used to get sum of several possible types within a type. For example: 2 | 2 -> 2 2 | 3 -> (2, 3) 2 | * -> (2, *) (Object) | (SmallInt) -> ((Object), (SmallInt)) This operator may be used to aggregate possible types within a linear sequence where several type outcomes are possible: x <- y isNil ifTrue: [ nil ] ifFalse: [ 42 ]. In this case x will have composite type (nil, 42). On the other hand, when dealing with loops we need some kind of a reduction operator that will act as a conjunction: 2 & 2 -> 2 2 & 3 -> (SmallInt) 2 & (SmallInt) -> (SmallInt) <any type> & * -> * (SmallInt) & (Object) -> * This operator is used during induction run of the type analyzer to prove that variable does not leave it's local type domain, i.e it's type is not reduced to a *. Issue: #17
Meta info is very useful during type analysis. It helps to make decisions based on graph structure. In future, more flags will be added. Issue: #17
This code need to be refactored properly. In case if both operands are literal, then result may be defined as literal too. Otherwise primitive should "fail" by allowing control flow to pass further. For literal calculation it is best to use existing code for software VM. Issue: #17
kpp
added a commit
that referenced
this pull request
Aug 13, 2016
Issue: #92
kpp
force-pushed
the
feature/17/type_inference
branch
from
August 13, 2016 04:22
3a54498
to
9cfb35d
Compare
kpp
added a commit
that referenced
this pull request
Aug 13, 2016
kpp
force-pushed
the
feature/17/type_inference
branch
from
August 13, 2016 04:49
9cfb35d
to
6c130b3
Compare
kpp
added a commit
that referenced
this pull request
Aug 13, 2016
kpp
force-pushed
the
feature/17/type_inference
branch
from
August 13, 2016 08:49
6c130b3
to
c8e71b9
Compare
kpp
added a commit
that referenced
this pull request
Aug 13, 2016
kpp
force-pushed
the
feature/17/type_inference
branch
from
August 13, 2016 09:31
c8e71b9
to
1c03337
Compare
kpp
added a commit
that referenced
this pull request
Aug 13, 2016
kpp
force-pushed
the
feature/17/type_inference
branch
from
August 13, 2016 10:11
1c03337
to
8dd1ffa
Compare
kpp
added a commit
that referenced
this pull request
Aug 13, 2016
kpp
force-pushed
the
feature/17/type_inference
branch
from
August 13, 2016 10:36
8dd1ffa
to
9c654c5
Compare
kpp
added a commit
that referenced
this pull request
Aug 13, 2016
kpp
added a commit
that referenced
this pull request
Aug 13, 2016
kpp
force-pushed
the
feature/17/type_inference
branch
from
August 13, 2016 10:48
9c654c5
to
a187a4b
Compare
kpp
added a commit
that referenced
this pull request
Aug 13, 2016
kpp
force-pushed
the
feature/17/type_inference
branch
from
August 13, 2016 10:56
a187a4b
to
cc8290a
Compare
kpp
added a commit
that referenced
this pull request
Aug 13, 2016
kpp
force-pushed
the
feature/17/type_inference
branch
from
August 13, 2016 11:39
cc8290a
to
5dd2d12
Compare
kpp
added a commit
that referenced
this pull request
Aug 13, 2016
kpp
force-pushed
the
feature/17/type_inference
branch
from
August 13, 2016 14:21
5dd2d12
to
06d0901
Compare
kpp
added a commit
that referenced
this pull request
Aug 13, 2016
kpp
force-pushed
the
feature/17/type_inference
branch
from
August 13, 2016 16:09
06d0901
to
5d23406
Compare
kpp
added a commit
that referenced
this pull request
Aug 13, 2016
kpp
force-pushed
the
feature/17/type_inference
branch
from
August 13, 2016 17:07
5d23406
to
34c1048
Compare
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR is my first rather independent (or naïve?) attempt to realize how type inference may be used to aid JIT VM. Underlying concept is not based on any well-known theory like Hindley-Milner type system or Martin Löf's Intuitionistic type theory. It's the result of a pure meditation on Smalltalk bytecodes.
Surprisingly enough, Smalltalk being fully dynamic in it's nature is still very regular in terms of it's memory access and control flow. This really helps when we try to perform static analysis.
Current implementation concentrates on the method temporaries and gives up completely when it faces object fields. However, I believe that in local context it is still possible to infer the object's fields to fully unlock further analysis and optimizations, like stack allocation, GC root elimination, and of course TBAA.
Current implementation is powerful enough to infer self assigning temporaries within a loop and even in complex closure contexts.
For example, the following method is inferred completely:
Here analyzer proves that
sum
variable will haveSmallInt
type in it's scope which spans across the follwing methods:Undefined>>testInference
,Number>>to:do:
,Block>>value:
and finally, the blockUndefined>>testInference@8
. Integer overflow is currently undefined.This allows IR generator to encode operations on
sum
directly asi32
without any worries about GC or dynamic dispatch.Current inference scheme highly uses method monomorphisation and specialization, which helps to perform calculations at compile time.
For example, this code is reduced to a single literal value (the result) at compile time:
Type inference works even in case of recurring contexts and correctly solves chicken or egg problem. Consider the listing of the
Collection>>sort:
This is suboptimal implementation of the Quicksort algorithm used here only for testing purposes. It performs two recursive calls to
Collection>>sort:
when sortingleft
andright
sublists. The main difficulty here is to infer the return value of theCollection>>sort:
. For example, analysis of theleft
refers to the outer context which at that point is not inferred completely, hence no return type available.However, current implementation correctly solves the problem using a fact, that every recursion has it's base which should be evaluated prior to the next recursive call. By propagating the base return type from the outer context to the inner one we succeed in the whole process. See the log for an example of such inference. You may also see the resulting call graph as rendered svg or graphviz source.
Static analysis along with runtime statistics and polymorphic method cacheing provides enough information for effective dispatch of the Smalltalk code.
See also: #56, #58.
The implementation is not complete yet, there are a lot of things to do:
Collection>>sort: