-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
SSA optimized gensyms #9729
SSA optimized gensyms #9729
Conversation
@@ -132,10 +136,10 @@ | |||
|
|||
(define (sym-dot? e) | |||
(and (length= e 3) (eq? (car e) '|.|) | |||
(symbol? (cadr e)))) | |||
(or (symbol? (cadr e)) (jlgensym? (cadr e))))) |
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.
This should be factored into a function, e.g. symbol-like?
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.
i had a feeling you would say that
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.
symboly?
(travis failures appears to be an unrelated issues with homebrew) it's rare i can make a PR with such a clear across-the-board performance boost: after:
before (master 4ff8145):
|
Here are the percentages (new times / old times), using the data in the comments above:
Whats up with |
What's the deal with the |
good catch, i had missed that one. turns out it was a fix on base that i hadn't incorporated into my test results
hm, how did that sneak back in? I rebased to get rid of it, and added a gitignore entry for it. (it's the same as sys.ji, I just like to make copies of it) |
Wow, is all that improvement just from having fewer symbol objects?? |
it's only a few %, but that would seem to be true |
Quite nice to drop 2.5MB of just symbols from the system image. Yikes. |
to shrink the image a bit further, we might also try to intern strings more often. for example, we end up with a lot of cases of "unrecognized keyword argument "". and every LineNode seems to include a full copy of the filename string. |
CI is green, so I'll go ahead and merge as soon as you are OK with it |
I thought the line nodes used symbols for filenames. |
end | ||
end | ||
|
||
function GenSym(sv::StaticVarInfo, typ) |
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.
I don't think it's good style to have a constructor mutate something. I'd call this something like newvar!(sv, typ)
.
i thought so too, but the text seems to be showing up too many times in |
@@ -1340,6 +1359,7 @@ static jl_arrayvar_t *arrayvar_for(jl_value_t *ex, jl_codectx_t *ctx) | |||
if (aname && ctx->arrayvars->find(aname) != ctx->arrayvars->end()) { | |||
return &(*ctx->arrayvars)[aname]; | |||
} | |||
//TODO: gensym case |
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.
Is this still to be done?
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.
yes, i haven't re-implemented this optimization for GenSym variables
How do you feel about using the GenSym approach for all local variables? (In which case I would name it something like
Of course, we lose the advantage that |
it'll make an expaneded AST much harder to read, although I can see the appeal |
Couldn't that be dealt with by printing the AST in the more human-readable form – i.e. with readable names replaced for gensyms where there is a name to be replaced? |
Yes, it could be dealt with within We know we have to fix the renamed-variables issue eventually anyway, and it seems quite unwieldy to do that by adding a symbol-to-symbol mapping to the AST, as opposed to switching to indexes for everything. |
perhaps, i'm more concerned about dealing with them in contexts where I don't have easy access to the vinfo (like fwiw, this change set also renames inlined variables in such a way that the original names now get included (i figured that was a reasonable tradeoff now to make a few more unique gensym objects here in exchange for many fewer gensym objects elsewhere) |
1) rename id to idx, since lldb doesn't like the name id 2) prevent back-propogation of Intrinsics.box type information 3) use SAvalue location for unboxed values as well as boxed values 4) mark a few more unboxed values (needed by 3) 5) make Type{()} a bitstype (!!!) 6) abstract the isGhost computation into type_is_ghost() 7) don't try to specsig a non-typeinferred function. emit_var may get confused by the presence of unmarked Symbols with known types (from args) 8) TODO: handle isGhost args correctly when their corresponding local variable is not a ghost
…x emission of variables in dead code (having type Union())
this previously could be an issue if specsig was allowed on non-type-inferred functions.
… for (or (symbol?) (jlgensym?))
…syntax.scm handling of (jlgensym) objects, and use of (make-jlgensym) where possible, disable a test that this (temporarily) broke julia-syntax optimistically assumes many variables will be jlgensym-compatible. it is the responsiblity of branch assignment locations (such as if blocks) to handle this case appropriately, and only emit one assignment to the (jlgensym? dest) variable. the type-inference information for GenSym variables now may be just the count of the number of GenSym variable slots present in the function
…ement position, and cleanup of s/gensym/gensy/
note, if we assume that the test suite is a test of compile time, we see an improvement on every test in my measured subset from this PR: after:
before (master adc1c83):
|
Looks like the linalg tests do not benefit and even slow down slightly. I always wish they get faster. |
Look again; the "after" numbers are listed first. Looks like almost all the linalg tests are significantly faster. Only a couple are a hair slower; probably not statistically significant. |
Anyway @vtjnash back to type_goto. Fortunately there are tests for all the relevant issues, and they pass, so hopefully we're in good shape. Your algorithm looks at least as good as mine AFAICT. |
OK. my algorithm avoids computing |
unfortunately, one of the torture tests i was hoping would be greatly improved by this PR (https://gist.github.com/vtjnash/27ff622b2cbed22b51dc) seems to have been not affected much / in the wrong direction: after:
before:
|
The first time seems to be within 10%. Isn't the second one 2x faster with the new code? |
Yes - I misread the timings. Sorry for the noise. |
oh, i was just looking at parse (actually expand) times, not the type-inference pass. yes, it seems it did help that a bit. |
this introduces a new Symbol type as a compiler optimization for places where only a simple unnamed memory location is required. it is for use in places where the jl_varinfo_t is known by construction:
the vinfo for the Symbol should correspond to
18
TODO:
(make-jlgensym)
instead of(gensym)
in julia-syntax generation passes@JeffBezanson