Skip to content

Commit

Permalink
remove redundant list of local var names from AST, add list of static…
Browse files Browse the repository at this point in the history
… params

part of JuliaLang#10403

ast.args[2][1] has been removed since all of its information was also
in the varinfo lists ast.args[2][2]. the varinfo lists are now at
ast.args[2][1]. args[2][2] is captured var info, args[2][3] is gensym info,
and now args[2][4] is a list of static parameter names.

GlobalRef is now built in so it can be used more extensively.
  • Loading branch information
JeffBezanson committed Jun 9, 2015
1 parent 43d5a9f commit a9915ff
Show file tree
Hide file tree
Showing 12 changed files with 132 additions and 128 deletions.
11 changes: 6 additions & 5 deletions base/boot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@
# name::Symbol
#end

#immutable GlobalRef
# mod::Module
# name::Symbol
#end

# type Task
# parent::Task
# last::Task
Expand Down Expand Up @@ -235,11 +240,6 @@ type SymbolNode
SymbolNode(name::Symbol, t::ANY) = new(name, t)
end

immutable GlobalRef
mod::Module
name::Symbol
end

immutable ASCIIString <: DirectIndexString
data::Array{UInt8,1}
end
Expand Down Expand Up @@ -285,6 +285,7 @@ _new(:TopNode, :Symbol)
_new(:NewvarNode, :Symbol)
_new(:QuoteNode, :ANY)
_new(:GenSym, :Int)
eval(:(Core.call(::Type{GlobalRef}, m::Module, s::Symbol) = $(Expr(:new, :GlobalRef, :m, :s))))

Module(name::Symbol=:anonymous, std_imports::Bool=true) = ccall(:jl_f_new_module, Any, (Any, Bool), name, std_imports)::Module

Expand Down
75 changes: 43 additions & 32 deletions base/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1423,8 +1423,8 @@ function typeinf_uncached(linfo::LambdaStaticData, atypes::ANY, sparams::SimpleV
args = f_argnames(ast)
la = length(args)
assert(is(ast.head,:lambda))
locals = (ast.args[2][1])::Array{Any,1}
vars = append_any(args, locals)
vinflist = ast.args[2][1]::Array{Any,1}
vars = map(vi->vi[1], vinflist)
body = (ast.args[3].args)::Array{Any,1}
n = length(body)

Expand Down Expand Up @@ -1491,14 +1491,13 @@ function typeinf_uncached(linfo::LambdaStaticData, atypes::ANY, sparams::SimpleV

# types of closed vars
cenv = ObjectIdDict()
for vi in (ast.args[2][3])::Array{Any,1}
for vi in (ast.args[2][2])::Array{Any,1}
vi::Array{Any,1}
vname = vi[1]
vtype = vi[2]
cenv[vname] = vtype
s[1][vname] = VarState(vtype,false)
end
vinflist = ast.args[2][2]::Array{Any,1}
for vi in vinflist
vi::Array{Any,1}
if (vi[3]&4)!=0
Expand Down Expand Up @@ -1839,29 +1838,29 @@ function type_annotate(ast::Expr, states::Array{Any,1}, sv::ANY, rettype::ANY, a
ast.args[3].typ = rettype

# add declarations for variables that are always the same type
for vi in ast.args[2][2]::Array{Any,1}
for vi in ast.args[2][1]::Array{Any,1}
if (vi[3]&4)==0
vi[2] = get(decls, vi[1], vi[2])
end
if haskey(undefs, vi[1])
vi[3] |= 32
end
end
for vi in ast.args[2][3]::Array{Any,1}
for vi in ast.args[2][2]::Array{Any,1}
if (vi[3]&4)==0
vi[2] = get(decls, vi[1], vi[2])
end
if haskey(undefs, vi[1])
vi[3] |= 32
end
end
ast.args[2][4] = sv.gensym_types
ast.args[2][3] = sv.gensym_types

for (li::LambdaStaticData) in closures
if !li.inferred
a = li.ast
# pass on declarations of captured vars
for vi in a.args[2][3]::Array{Any,1}
for vi in a.args[2][2]::Array{Any,1}
if (vi[3]&4)==0
vi[2] = get(decls, vi[1], vi[2])
end
Expand Down Expand Up @@ -2184,6 +2183,20 @@ function effect_free(e::ANY, sv, allow_volatile::Bool)
return false
end

function ast_localvars(ast)
args = ObjectIdDict()
for argname in (ast.args[1]::Array{Any,1})
args[argname] = true
end
locals = Any[]
for vi in (ast.args[2][1]::Array{Any,1})
if !haskey(args, vi[1])
push!(locals, vi[1])
end
end
locals
end

# inline functions whose bodies "inline_worthy"
# where the function body doesn't contain any argument more than once.
# functions with closure environments or varargs are also excluded.
Expand Down Expand Up @@ -2311,7 +2324,7 @@ function inlineable(f::ANY, e::Expr, atype::ANY, sv::StaticVarInfo, enclosing_as
needcopy = false
end
ast = ast::Expr
vinflist = ast.args[2][2]::Array{Any,1}
vinflist = ast.args[2][1]::Array{Any,1}
for vi in vinflist
if (vi[3]&1)!=0
# captures variables (TODO)
Expand Down Expand Up @@ -2360,9 +2373,9 @@ function inlineable(f::ANY, e::Expr, atype::ANY, sv::StaticVarInfo, enclosing_as
end

spnames = Any[ sp[i].name for i=1:2:length(sp) ]
enc_vinflist = enclosing_ast.args[2][2]::Array{Any,1}
enc_locllist = enclosing_ast.args[2][1]::Array{Any,1}
locllist = ast.args[2][1]::Array{Any,1}
enc_vinflist = enclosing_ast.args[2][1]::Array{Any,1}
enc_locllist = ast_localvars(enclosing_ast)
locllist = ast_localvars(ast)

# check for vararg function
args = f_argnames(ast)
Expand Down Expand Up @@ -2438,7 +2451,7 @@ function inlineable(f::ANY, e::Expr, atype::ANY, sv::StaticVarInfo, enclosing_as
# 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][3]
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))
Expand Down Expand Up @@ -2600,17 +2613,17 @@ function inlineable(f::ANY, e::Expr, atype::ANY, sv::StaticVarInfo, enclosing_as
end

# re-number the GenSyms and copy their type-info to the new ast
gensym_types = ast.args[2][4]
gensym_types = ast.args[2][3]
if gensym_types != 0
if (isa(gensym_types,Integer))
gensym_types = Any[Any for i = 1:ast.args[2][4]]
gensym_types = Any[Any for i = 1:ast.args[2][3]]
end
if !isempty(gensym_types)
incr = length(sv.gensym_types)
if incr != 0
body = gensym_increment(body, incr)
end
append!(sv.gensym_types, ast.args[2][4])
append!(sv.gensym_types, ast.args[2][3])
end
end

Expand Down Expand Up @@ -2927,9 +2940,7 @@ end

function add_variable(ast, name, typ, is_sa)
vinf = Any[name, typ, 2+16*is_sa]
locllist = ast.args[2][1]::Array{Any,1}
vinflist = ast.args[2][2]::Array{Any,1}
push!(locllist, name)
vinflist = ast.args[2][1]::Array{Any,1}
push!(vinflist, vinf)
end

Expand All @@ -2946,7 +2957,7 @@ function contains_is1(vinflist::Array{Any,1}, x::Symbol)
return false
end
function unique_name(ast)
locllist = ast.args[2][2]::Array{Any,1}
locllist = ast.args[2][1]::Array{Any,1}
for g in some_names
if !contains_is1(locllist, g)
return g
Expand All @@ -2959,8 +2970,8 @@ function unique_name(ast)
g
end
function unique_name(ast1, ast2)
locllist1 = ast1.args[2][2]::Array{Any,1}
locllist2 = ast2.args[2][2]::Array{Any,1}
locllist1 = ast1.args[2][1]::Array{Any,1}
locllist2 = ast2.args[2][1]::Array{Any,1}
for g in some_names
if !contains_is1(locllist1, g) &&
!contains_is1(locllist2, g)
Expand All @@ -2977,7 +2988,7 @@ end

function unique_names(ast, n)
ns = []
locllist = ast.args[2][2]::Array{Any,1}
locllist = ast.args[2][1]::Array{Any,1}
for g in some_names
if !contains_is1(locllist, g)
push!(ns, g)
Expand Down Expand Up @@ -3013,7 +3024,7 @@ function is_known_call_p(e::Expr, pred::Function, sv)
end

function is_var_assigned(ast, v)
for vi in ast.args[2][2]
for vi in ast.args[2][1]
if symequal(vi[1], v) && (vi[3]&2)!=0
return true
end
Expand All @@ -3023,8 +3034,7 @@ end

function delete_var!(ast, v)
if !isa(v, GenSym)
filter!(vi->!symequal(vi[1],v), ast.args[2][2])
filter!(x->!symequal(x,v), ast.args[2][1])
filter!(vi->!symequal(vi[1],v), ast.args[2][1])
end
filter!(x->!(isa(x,Expr) && (x.head === :(=) || x.head === :const) &&
symequal(x.args[1],v)),
Expand All @@ -3036,8 +3046,8 @@ end
# and not assigned.
# "sa" is the result of find_sa_vars
function remove_redundant_temp_vars(ast, sa)
varinfo = ast.args[2][2]
gensym_types = ast.args[2][4]
varinfo = ast.args[2][1]
gensym_types = ast.args[2][3]
for (v,init) in sa
if ((isa(init,Symbol) || isa(init,SymbolNode)) &&
any(vi->symequal(vi[1],init), varinfo) &&
Expand Down Expand Up @@ -3087,7 +3097,8 @@ function find_sa_vars(ast)
body = ast.args[3].args
av = ObjectIdDict()
av2 = ObjectIdDict()
vnames = ast.args[2][1]
vinfos = ast.args[2][1]::Array{Any,1}
args = ast.args[1]
for i = 1:length(body)
e = body[i]
if isa(e,Expr) && is(e.head,:(=))
Expand All @@ -3098,7 +3109,7 @@ function find_sa_vars(ast)
av2[(lhs::SymbolNode).name] = true
else
lhs = lhs::Symbol
if contains_is(vnames, lhs) # exclude globals
if contains_is1(vinfos,lhs) && !contains_is(args,lhs) # exclude globals & args
if !haskey(av, lhs)
av[lhs] = e.args[2]
else
Expand All @@ -3109,7 +3120,7 @@ function find_sa_vars(ast)
end
end
filter!((var,_)->!haskey(av2,var), av)
for vi in ast.args[2][2]
for vi in vinfos
if (vi[3]&1)!=0
# remove captured vars
delete!(av, vi[1])
Expand Down Expand Up @@ -3255,7 +3266,7 @@ function replace_getfield!(ast, e::ANY, tupname, vals, sv, i0)
val = val::SymbolNode
if a.typ <: val.typ && !typeseq(a.typ,val.typ)
val.typ = a.typ
for vi in ast.args[2][2]::Array{Any,1}
for vi in ast.args[2][1]::Array{Any,1}
if vi[1] === val.name
vi[2] = a.typ
break
Expand Down
2 changes: 1 addition & 1 deletion base/interactiveutil.jl
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ function code_warntype(io::IO, f, t::ANY)
show_expr_type_emphasize::Bool = may_show_expr_type_emphasize::Bool = true
for ast in ct
println(io, "Variables:")
vars = ast.args[2][2]
vars = ast.args[2][1]
for v in vars
print(io, " ", v[1])
show_expr_type(io, v[2])
Expand Down
41 changes: 20 additions & 21 deletions src/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -301,15 +301,15 @@ static jl_value_t *scm_to_julia_(value_t e, int eo)

value_t ee = car_(e);
jl_array_t *vinf = jl_alloc_cell_1d(4);
jl_cellset(vinf, 0, full_list(car_(ee),eo));
jl_cellset(vinf, 0, full_list_of_lists(car_(ee),eo));
ee = cdr_(ee);
jl_cellset(vinf, 1, full_list_of_lists(car_(ee),eo));
ee = cdr_(ee);
jl_cellset(vinf, 2, full_list_of_lists(car_(ee),eo));
jl_cellset(vinf, 2, isfixnum(car_(ee)) ?
jl_box_long(numval(car_(ee))) :
full_list(car_(ee),eo));
ee = cdr_(ee);
jl_cellset(vinf, 3, isfixnum(car_(ee)) ?
jl_box_long(numval(car_(ee))) :
full_list(car_(ee),eo));
jl_cellset(vinf, 3, full_list(car_(ee),eo));
assert(!iscons(cdr_(ee)));
jl_cellset(ex->args, 1, vinf);
e = cdr_(e);
Expand All @@ -319,8 +319,7 @@ 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);
return (jl_value_t*)jl_new_lambda_info((jl_value_t*)ex, jl_emptysvec);
}

e = cdr_(e);
Expand Down Expand Up @@ -620,8 +619,8 @@ jl_lambda_info_t *jl_wrap_expr(jl_value_t *expr)
vi = (jl_value_t*)jl_alloc_cell_1d(4);
jl_cellset(vi, 0, mt);
jl_cellset(vi, 1, mt);
jl_cellset(vi, 2, mt);
jl_cellset(vi, 3, jl_box_long(jl_max_jlgensym_in(expr)+1));
jl_cellset(vi, 2, jl_box_long(jl_max_jlgensym_in(expr)+1));
jl_cellset(vi, 3, mt);
jl_cellset(le->args, 1, vi);
if (!jl_is_expr(expr) || ((jl_expr_t*)expr)->head != body_sym) {
bo = jl_exprn(body_sym, 1);
Expand Down Expand Up @@ -659,8 +658,8 @@ jl_sym_t *jl_lam_argname(jl_lambda_info_t *li, int i)
return (jl_sym_t*)jl_cellref(jl_lam_args(ast),i);
}

// get array of local var symbols
jl_array_t *jl_lam_locals(jl_expr_t *l)
// get array of var info records (for args and locals)
jl_array_t *jl_lam_vinfo(jl_expr_t *l)
{
assert(jl_is_expr(l));
jl_value_t *le = jl_exprarg(l, 1);
Expand All @@ -670,8 +669,8 @@ jl_array_t *jl_lam_locals(jl_expr_t *l)
return (jl_array_t*)ll;
}

// get array of var info records
jl_array_t *jl_lam_vinfo(jl_expr_t *l)
// get array of var info records for captured vars
jl_array_t *jl_lam_capt(jl_expr_t *l)
{
assert(jl_is_expr(l));
jl_value_t *le = jl_exprarg(l, 1);
Expand All @@ -681,25 +680,25 @@ jl_array_t *jl_lam_vinfo(jl_expr_t *l)
return (jl_array_t*)ll;
}

// get array of var info records for captured vars
jl_array_t *jl_lam_capt(jl_expr_t *l)
// get array of types for GenSym vars, or its length (if not type-inferred)
jl_value_t *jl_lam_gensyms(jl_expr_t *l)
{
assert(jl_is_expr(l));
jl_value_t *le = jl_exprarg(l, 1);
assert(jl_is_array(le));
jl_value_t *ll = jl_cellref(le, 2);
assert(jl_is_array(ll));
return (jl_array_t*)ll;
assert(jl_array_len(le) == 4);
return jl_cellref(le, 2);
}

// get array of types for GenSym vars, or it's length (if not type-inferred)
jl_value_t *jl_lam_gensyms(jl_expr_t *l)
// get array of static parameter symbols
jl_array_t *jl_lam_staticparams(jl_expr_t *l)
{
assert(jl_is_expr(l));
jl_value_t *le = jl_exprarg(l, 1);
assert(jl_is_array(le));
assert(jl_array_len(le) == 4);
return jl_cellref(le, 3);
assert(jl_is_array(jl_cellref(le, 3)));
return (jl_array_t*)jl_cellref(le, 3);
}

int jl_lam_vars_captured(jl_expr_t *ast)
Expand Down
1 change: 1 addition & 0 deletions src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -1238,6 +1238,7 @@ void jl_init_primitives(void)
add_builtin("QuoteNode", (jl_value_t*)jl_quotenode_type);
add_builtin("TopNode", (jl_value_t*)jl_topnode_type);
add_builtin("NewvarNode", (jl_value_t*)jl_newvarnode_type);
add_builtin("GlobalRef", (jl_value_t*)jl_globalref_type);

#ifdef _P64
add_builtin("Int", (jl_value_t*)jl_int64_type);
Expand Down
Loading

0 comments on commit a9915ff

Please sign in to comment.