Skip to content

Commit

Permalink
resolve all globals to GlobalRef very early
Browse files Browse the repository at this point in the history
part of #10403
  • Loading branch information
JeffBezanson committed Jun 30, 2015
1 parent 7b4a0e8 commit 8578b15
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 97 deletions.
93 changes: 0 additions & 93 deletions base/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1908,77 +1908,6 @@ function _sym_repl(s::Union{Symbol,GenSym}, from1, from2, to1, to2, deflt)
return deflt
end

# return an expr to evaluate "from.sym" in module "to"
function resolve_relative(sym, locals, args, from, to, orig)
if sym in locals || sym in args
return GlobalRef(from, sym)
end
if is(from,to)
return orig
end
const_from = (isconst(from,sym) && isdefined(from,sym))
const_to = (isconst(to,sym) && isdefined(to,sym))
if const_from
if const_to && is(eval(from,sym), eval(to,sym))
return orig
end
m = _topmod()
if is(from, m) || is(from, Core)
return TopNode(sym)
end
end
return GlobalRef(from, sym)
end

# annotate symbols with their original module for inlining
function resolve_globals(e::ANY, locals, args, from, to, env1, env2)
if isa(e,Symbol)
s = e::Symbol
if contains_is(env1, s) || contains_is(env2, s)
return s
end
return resolve_relative(s, locals, args, from, to, s)
end
if isa(e,SymbolNode)
s = e::SymbolNode
name = s.name
if contains_is(env1, name) || contains_is(env2, name)
return s
end
return resolve_relative(name, locals, args, from, to, s)
end
if !isa(e,Expr)
return e
end
e = e::Expr
if e.head === :(=)
# remove_redundant_temp_vars can only handle Symbols
# on the LHS of assignments, so we make sure not to put
# something else there
e2 = resolve_globals(e.args[1]::Union{Symbol,GenSym}, locals, args, from, to, env1, env2)
if isa(e2, GlobalRef)
# abort when trying to inline a function which assigns to a global
# variable in a different module, since `Mod.X=V` isn't allowed
throw(e2)
# e2 = e2::GetfieldNode
# e = Expr(:call, top_setfield, e2.value, qn(e2.name),
# resolve_globals(e.args[2], locals, args, from, to, env1, env2))
# e.typ = e2.typ
else
e.args[1] = e2::Union{Symbol,GenSym}
e.args[2] = resolve_globals(e.args[2], locals, args, from, to, env1, env2)
end
elseif !is(e.head,:line)
for i=1:length(e.args)
subex = e.args[i]
if !(isa(subex,Number) || isa(subex,AbstractString))
e.args[i] = resolve_globals(subex, locals, args, from, to, env1, env2)
end
end
end
e
end

# count occurrences up to n+1
function occurs_more(e::ANY, pred, n)
if isa(e,Expr)
Expand Down Expand Up @@ -2307,7 +2236,6 @@ function inlineable(f::ANY, e::Expr, atype::ANY, sv::StaticVarInfo, enclosing_as

body = Expr(:block)
body.args = without_linenums(ast.args[3].args)::Array{Any,1}
need_mod_annotate = true
cost::Int = 1000
if incompletematch
cost *= 4
Expand Down Expand Up @@ -2338,7 +2266,6 @@ function inlineable(f::ANY, e::Expr, atype::ANY, sv::StaticVarInfo, enclosing_as
end
body.args = Any[Expr(:return, newcall)]
ast = Expr(:lambda, newnames, Any[[], locals, [], 0], body)
need_mod_annotate = false
needcopy = false
else
return NF
Expand Down Expand Up @@ -2421,26 +2348,6 @@ function inlineable(f::ANY, e::Expr, atype::ANY, sv::StaticVarInfo, enclosing_as
end
end

# annotate variables in the body expression with their module
if need_mod_annotate
mfrom = linfo.module; mto = (inference_stack::CallStack).mod
enc_capt = enclosing_ast.args[2][2]
if !isempty(enc_capt)
# add captured var names to list of locals
enc_vars = vcat(enc_locllist, map(vi->vi[1], enc_capt))
else
enc_vars = enc_locllist
end
try
body = resolve_globals(body, enc_vars, enclosing_ast.args[1], mfrom, mto, args, spnames)
catch ex
if isa(ex,GlobalRef)
return NF
end
rethrow(ex)
end
end

# see if each argument occurs only once in the body expression
stmts = []
stmts_free = true # true = all entries of stmts are effect_free
Expand Down
5 changes: 3 additions & 2 deletions base/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ isidentifier(s::Symbol) = isidentifier(string(s))

isoperator(s::Symbol) = ccall(:jl_is_operator, Cint, (Cstring,), s) != 0
operator_precedence(s::Symbol) = Int(ccall(:jl_operator_precedence, Cint, (Cstring,), s))
operator_precedence(s::GlobalRef) = operator_precedence(s.name)
operator_precedence(x::Any) = 0 # fallback for generic expression nodes
const prec_power = operator_precedence(:(^))

Expand Down Expand Up @@ -502,8 +503,8 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int)
end

# scalar multiplication (i.e. "100x")
if (func == :(*) && length(func_args)==2 &&
isa(func_args[1], Real) && isa(func_args[2], Symbol))
if ((func == :(*) || (isa(func,GlobalRef) && func.name == :(*))) &&
length(func_args)==2 && isa(func_args[1], Real) && isa(func_args[2], Symbol))
if func_prec <= prec
show_enclosed_list(io, '(', func_args, "", ')', indent, func_prec)
else
Expand Down
71 changes: 70 additions & 1 deletion src/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,8 @@ static jl_value_t *full_list_of_lists(value_t e, int expronly)
return (jl_value_t*)ar;
}

static jl_value_t *resolve_globals(jl_value_t *expr, jl_lambda_info_t *lam);

static jl_value_t *scm_to_julia(value_t e, int expronly)
{
int en = jl_gc_enable(0);
Expand Down Expand Up @@ -314,7 +316,9 @@ static jl_value_t *scm_to_julia_(value_t e, int eo)
jl_cellset(ex->args, i, scm_to_julia_(car_(e), eo));
e = cdr_(e);
}
return (jl_value_t*)jl_new_lambda_info((jl_value_t*)ex, jl_emptysvec);
jl_lambda_info_t *nli = jl_new_lambda_info((jl_value_t*)ex, jl_emptysvec);
resolve_globals(nli->ast, nli);
return (jl_value_t*)nli;
}

e = cdr_(e);
Expand Down Expand Up @@ -960,6 +964,71 @@ jl_value_t *skip_meta(jl_array_t *body)
return body1;
}

static int in_vinfo_array(jl_array_t *a, jl_value_t *v)
{
size_t i, l=jl_array_len(a);
for(i=0; i<l; i++) {
if (jl_cellref(jl_cellref(a,i),0) == v)
return 1;
}
return 0;
}

static int in_sym_array(jl_array_t *a, jl_value_t *v)
{
size_t i, l=jl_array_len(a);
for(i=0; i<l; i++) {
if (jl_cellref(a,i) == v)
return 1;
}
return 0;
}

static jl_value_t *resolve_globals(jl_value_t *expr, jl_lambda_info_t *lam)
{
if (jl_is_symbol(expr)) {
if (lam->module == NULL)
return expr;
int is_local = in_vinfo_array(jl_lam_vinfo((jl_expr_t*)lam->ast), expr) ||
in_vinfo_array(jl_lam_capt((jl_expr_t*)lam->ast), expr) ||
in_sym_array(jl_lam_staticparams((jl_expr_t*)lam->ast), expr);
if (!is_local) {
//return jl_module_global_ref(lam->module, (jl_sym_t*)expr);
return jl_new_struct(jl_globalref_type, lam->module, (jl_sym_t*)expr);
}
}
else if (jl_is_lambda_info(expr)) {
jl_lambda_info_t *l = (jl_lambda_info_t*)expr;
(void)resolve_globals(l->ast, l);
}
else if (jl_is_expr(expr)) {
jl_expr_t *e = (jl_expr_t*)expr;
if (e->head == lambda_sym) {
(void)resolve_globals(jl_exprarg(e,2), lam);
}
/*
else if (e->head == assign_sym) {
jl_exprargset(e, 0, dont_copy_ast(jl_exprarg(e,0), sp, 0));
jl_exprargset(e, 1, dont_copy_ast(jl_exprarg(e,1), sp, 1));
}
*/
else if (jl_is_toplevel_only_expr(expr) || e->head == const_sym || e->head == copyast_sym ||
e->head == global_sym || e->head == quote_sym || e->head == inert_sym ||
e->head == line_sym || e->head == meta_sym) {
}
else {
size_t i = 0;
if (e->head == method_sym || e->head == abstracttype_sym || e->head == compositetype_sym ||
e->head == bitstype_sym || e->head == macro_sym || e->head == module_sym)
i++;
for(; i < jl_array_len(e->args); i++) {
jl_exprargset(e, i, resolve_globals(jl_exprarg(e,i), lam));
}
}
}
return expr;
}

#ifdef __cplusplus
}
#endif
17 changes: 16 additions & 1 deletion src/gf.c
Original file line number Diff line number Diff line change
Expand Up @@ -895,7 +895,7 @@ DLLEXPORT jl_function_t *jl_instantiate_staged(jl_methlist_t *m, jl_tupletype_t
oldast = (jl_expr_t*)jl_uncompress_ast(m->func->linfo, m->func->linfo->ast);
assert(oldast->head == lambda_sym);
ex = jl_exprn(arrow_sym, 2);
jl_array_t *oldargnames = (jl_array_t*)jl_cellref(oldast->args,0);
jl_array_t *oldargnames = jl_lam_args(oldast);
jl_expr_t *argnames = jl_exprn(tuple_sym, jl_array_len(oldargnames));
jl_cellset(ex->args, 0, argnames);
for (size_t i = 0; i < jl_array_len(oldargnames); ++i) {
Expand All @@ -921,6 +921,21 @@ DLLEXPORT jl_function_t *jl_instantiate_staged(jl_methlist_t *m, jl_tupletype_t
jl_cellset(linenode->args, 0, jl_box_long(m->func->linfo->line));
jl_cellset(linenode->args, 1, m->func->linfo->file);
jl_cellset(body->args, 1, jl_apply(func, jl_svec_data(tt->parameters), jl_nparams(tt)));
if (m->tvars != jl_emptysvec) {
// mark this function as having the same static parameters as the generator
size_t nsp = jl_is_typevar(m->tvars) ? 1 : jl_svec_len(m->tvars);
oldast = jl_exprn(jl_symbol("with-static-parameters"), nsp+1);
jl_exprarg(oldast,0) = (jl_value_t*)ex;
// (with-static-parameters func_expr sp_1 sp_2 ...)
if (jl_is_typevar(m->tvars)) {
jl_exprarg(oldast,1) = (jl_value_t*)((jl_tvar_t*)m->tvars)->name;
}
else {
for(size_t i=0; i < nsp; i++)
jl_exprarg(oldast,i+1) = (jl_value_t*)((jl_tvar_t*)jl_svecref(m->tvars,i))->name;
}
ex = oldast;
}
func = (jl_function_t*)jl_toplevel_eval_in(m->func->linfo->module, (jl_value_t*)ex);
func->linfo->name = m->func->linfo->name;
JL_GC_POP();
Expand Down
4 changes: 4 additions & 0 deletions src/julia-syntax.scm
Original file line number Diff line number Diff line change
Expand Up @@ -3038,6 +3038,10 @@ So far only the second case can actually occur.
`(call (lambda ,vs ,(caddr (cadr e)) ,(cadddr (cadr e)))
,@vs)
env captvars sp))))
((with-static-parameters)
;; (with-static-parameters func_expr sp_1 sp_2 ...)
(analyze-vars (cadr e) env captvars
(delete-duplicates (append sp (cddr e)))))
((method)
(let ((vi (var-info-for (method-expr-name e) env)))
(if vi
Expand Down

0 comments on commit 8578b15

Please sign in to comment.