-
-
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
fix #6599 #6605
fix #6599 #6605
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1864,7 +1864,12 @@ function effect_free(e::ANY, sv, allow_volatile::Bool) | |
if is_known_call_p(e, is_pure_builtin, sv) | ||
if !allow_volatile && is_known_call_p(e, (f)->contains_is(_pure_builtins_volatile, f), sv) | ||
# arguments must be immutable to ensure e is affect_free | ||
first = true | ||
for a in ea | ||
if first # first "arg" is the function name | ||
first = false | ||
continue | ||
end | ||
if isa(a,Symbol) | ||
return false | ||
end | ||
|
@@ -1890,7 +1895,21 @@ function effect_free(e::ANY, sv, allow_volatile::Bool) | |
end | ||
return true | ||
end | ||
elseif e.head === :new || e.head == :return | ||
elseif e.head == :new | ||
first = !allow_volatile | ||
for a in ea | ||
if first | ||
first = false | ||
isa(a,SymbolNode) || return false | ||
typ = (a::SymbolNode).typ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe this should use |
||
isa(typ,DataType) || return false | ||
!(typ::DataType).mutable || return false | ||
elseif !effect_free(a,sv,allow_volatile) | ||
return false | ||
end | ||
end | ||
return true | ||
elseif e.head == :return | ||
for a in ea | ||
if !effect_free(a,sv,allow_volatile) | ||
return false | ||
|
@@ -2136,16 +2155,19 @@ function inlineable(f, e::Expr, atypes, sv, enclosing_ast) | |
for j = length(body.args):-1:1 | ||
b = body.args[j] | ||
if occ < 1 | ||
occ += occurs_more(b, x->is(x,a), 1) | ||
occ += occurs_more(b, x->is(x,a), 5) | ||
end | ||
if occ > 0 && (!affect_free || !effect_free(b, sv, true)) #TODO: we could short-circuit this test better by memoizing effect_free(b) in the for loop over i | ||
if occ > 0 && affect_free && !effect_free(b, sv, true) #TODO: we could short-circuit this test better by memoizing effect_free(b) in the for loop over i | ||
affect_free = false | ||
end | ||
if occ > 5 | ||
occ = 6 | ||
break | ||
end | ||
end | ||
free = effect_free(aei,sv,true) | ||
affect_unfree = (islocal || (affect_free && !free) || (!affect_free && !effect_free(aei,sv,false))) | ||
if affect_unfree || (occ==0 && is(aeitype,None)) | ||
if ((occ==0 && is(aeitype,None)) || islocal || !inline_worthy(aei, occ) || | ||
(affect_free && !free) || (!affect_free && !effect_free(aei,sv,false))) | ||
if occ != 0 # islocal=true is implied | ||
# introduce variable for this argument | ||
vnew = unique_name(enclosing_ast, ast) | ||
|
@@ -2238,13 +2260,19 @@ function inlineable(f, e::Expr, atypes, sv, enclosing_ast) | |
return (expr, stmts) | ||
end | ||
|
||
function inline_worthy(body::Expr) | ||
inline_worthy(body, occurences::Int) = true | ||
function inline_worthy(body::Expr, occurences::Int=1) # 0 <= occurrences <= 6 | ||
occurences == 0 && return true | ||
# if isa(body.args[1],QuoteNode) && (body.args[1]::QuoteNode).value === :inline | ||
# shift!(body.args) | ||
# return true | ||
# end | ||
if length(body.args) < 6 && occurs_more(body, e->true, 40) < 40 | ||
return true | ||
symlim = div(8,occurences) | ||
if length(body.args) < symlim | ||
symlim *= 12 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. from @stevengj's analysis (e805fd6#commitcomment-6089161) and some of my own, I think we were significantly overestimating the conversion factor. i think we are roughly 1-to-1 for the symbols counted by occurs_more and the number of arguments to the llvm intrinsics the estimate here is that 12 symbols in a line is relatively short. the limit on the number of lines is intended mostly as an optimization to skip counting when it is unlikely to be worth inlining There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok. I'd like this part of the change to be a separate patch, to separate it from the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. changing this back will potentially limit inlining more than before the patch, since now this test also controls inlining of arguments into functions |
||
if occurs_more(body, e->true, symlim) < symlim | ||
return true | ||
end | ||
end | ||
return false | ||
end | ||
|
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 isn't strictly necessary, since the first arg is usually a TopNode. but this should be more correct