Skip to content

Commit

Permalink
use a meta node instead of stagedfunction expression head
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson committed Aug 7, 2017
1 parent 0f4229d commit ea7463a
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 79 deletions.
2 changes: 1 addition & 1 deletion base/docs/Docs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,7 @@ finddoc(λ, def) = false

# Predicates and helpers for `docm` expression selection:

const FUNC_HEADS = [:function, :stagedfunction, :macro, :(=)]
const FUNC_HEADS = [:function, :macro, :(=)]
const BINDING_HEADS = [:typealias, :const, :global, :(=)] # deprecation: remove `typealias` post-0.6
# For the special `:@mac` / `:(Base.@mac)` syntax for documenting a macro after definition.
isquotedmacrocall(x) =
Expand Down
4 changes: 2 additions & 2 deletions base/expr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -333,8 +333,8 @@ function remove_linenums!(ex::Expr)
end

macro generated(f)
if isa(f, Expr) && (f.head === :function || is_short_function_def(f))
f.head = :stagedfunction
if isa(f, Expr) && (f.head === :function || is_short_function_def(f))
pushmeta!(f, :generated)
return Expr(:escape, f)
else
error("invalid syntax; @generated must be used with a function definition")
Expand Down
3 changes: 2 additions & 1 deletion src/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ jl_sym_t *meta_sym; jl_sym_t *compiler_temp_sym;
jl_sym_t *inert_sym; jl_sym_t *vararg_sym;
jl_sym_t *unused_sym; jl_sym_t *static_parameter_sym;
jl_sym_t *polly_sym; jl_sym_t *inline_sym;
jl_sym_t *propagate_inbounds_sym;
jl_sym_t *propagate_inbounds_sym; jl_sym_t *generated_sym;
jl_sym_t *isdefined_sym; jl_sym_t *nospecialize_sym;

static uint8_t flisp_system_image[] = {
Expand Down Expand Up @@ -437,6 +437,7 @@ void jl_init_frontend(void)
propagate_inbounds_sym = jl_symbol("propagate_inbounds");
isdefined_sym = jl_symbol("isdefined");
nospecialize_sym = jl_symbol("nospecialize");
generated_sym = jl_symbol("generated");
}

JL_DLLEXPORT void jl_lisp_prompt(void)
Expand Down
3 changes: 3 additions & 0 deletions src/ast.scm
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,9 @@
(and (if one (length= e 3) (length> e 2))
(eq? (car e) 'meta) (eq? (cadr e) 'nospecialize)))

(define (generated-meta? e)
(and (pair? e) (eq? (car e) 'meta) (any (lambda (x) (eq? x 'generated)) (cdr e))))

;; flatten nested expressions with the given head
;; (op (op a b) c) => (op a b c)
(define (flatten-ex head e)
Expand Down
6 changes: 2 additions & 4 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3776,11 +3776,10 @@ static jl_cgval_t emit_expr(jl_codectx_t &ctx, jl_value_t *expr)
}
Value *a1 = boxed(ctx, emit_expr(ctx, args[1]));
Value *a2 = boxed(ctx, emit_expr(ctx, args[2]));
Value *mdargs[4] = {
Value *mdargs[3] = {
/*argdata*/a1,
/*code*/a2,
/*module*/literal_pointer_val(ctx, (jl_value_t*)ctx.module),
/*isstaged*/literal_pointer_val(ctx, args[3])
/*module*/literal_pointer_val(ctx, (jl_value_t*)ctx.module)
};
ctx.builder.CreateCall(prepare_call(jlmethod_func), makeArrayRef(mdargs));
return ghostValue(jl_void_type);
Expand Down Expand Up @@ -6308,7 +6307,6 @@ static void init_julia_llvm_env(Module *m)
mdargs.push_back(T_prjlvalue);
mdargs.push_back(T_prjlvalue);
mdargs.push_back(T_pjlvalue);
mdargs.push_back(T_pjlvalue);
jlmethod_func =
Function::Create(FunctionType::get(T_void, mdargs, false),
Function::ExternalLinkage,
Expand Down
2 changes: 1 addition & 1 deletion src/interpreter.c
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ static jl_value_t *eval(jl_value_t *e, interpreter_state *s)
JL_GC_PUSH2(&atypes, &meth);
atypes = eval(args[1], s);
meth = eval(args[2], s);
jl_method_def((jl_svec_t*)atypes, (jl_code_info_t*)meth, s->module, args[3]);
jl_method_def((jl_svec_t*)atypes, (jl_code_info_t*)meth, s->module);
JL_GC_POP();
return jl_nothing;
}
Expand Down
83 changes: 40 additions & 43 deletions src/julia-syntax.scm
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@

;; construct the (method ...) expression for one primitive method definition,
;; assuming optional and keyword args are already handled
(define (method-def-expr- name sparams argl body isstaged (rett '(core Any)))
(define (method-def-expr- name sparams argl body (rett '(core Any)))
(if
(any kwarg? argl)
;; has optional positional args
Expand All @@ -315,7 +315,7 @@
(dfl (map caddr kws)))
(receive
(vararg req) (separate vararg? argl)
(optional-positional-defs name sparams req opt dfl body isstaged
(optional-positional-defs name sparams req opt dfl body
(append req opt vararg) rett)))))
;; no optional positional args
(let ((names (map car sparams)))
Expand All @@ -337,7 +337,7 @@
(mdef
(if (null? sparams)
`(method ,name (call (core svec) (call (core svec) ,@(dots->vararg types)) (call (core svec)))
,body ,isstaged)
,body)
`(method ,name
(block
,@(let loop ((n names)
Expand All @@ -358,7 +358,7 @@
(replace-vars ty renames))
types)))
(call (core svec) ,@temps)))
,body ,isstaged))))
,body))))
(if (symbol? name)
`(block (method ,name) ,mdef (unnecessary ,name)) ;; return the function
mdef)))))
Expand All @@ -373,10 +373,8 @@

(define empty-vector-any '(call (core AnyVector) 0))

(define (keywords-method-def-expr name sparams argl body isstaged rett)
(define (keywords-method-def-expr name sparams argl body rett)
(let* ((kargl (cdar argl)) ;; keyword expressions (= k v)
(annotations (map (lambda (a) `(meta nospecialize ,(arg-name (cadr (caddr a)))))
(filter nospecialize-meta? kargl)))
(kargl (map (lambda (a)
(if (nospecialize-meta? a) (caddr a) a))
kargl))
Expand Down Expand Up @@ -413,6 +411,11 @@
keynames))
;; list of function's initial line number and meta nodes (empty if none)
(prologue (extract-method-prologue body))
(annotations (append (if (any generated-meta? prologue)
'((meta generated))
'())
(map (lambda (a) `(meta nospecialize ,(arg-name (cadr (caddr a)))))
(filter nospecialize-meta? kargl))))
;; body statements
(stmts (cdr body))
(positional-sparams
Expand All @@ -437,7 +440,7 @@
,(method-def-expr-
name positional-sparams (append pargl vararg)
`(block
,@prologue
,@(without-generated prologue)
,(let (;; call mangled(vals..., [rest_kw,] pargs..., [vararg]...)
(ret `(return (call ,mangled
,@(if ordered-defaults keynames vals)
Expand All @@ -447,8 +450,7 @@
(list `(... ,(arg-name (car vararg)))))))))
(if ordered-defaults
(scopenest keynames vals ret)
ret)))
#f)
ret))))

;; call with keyword args pre-sorted - original method code goes here
,(method-def-expr-
Expand All @@ -467,7 +469,7 @@
(insert-after-meta `(block
,@stmts)
annotations)
isstaged rett)
rett)

;; call with unsorted keyword args. this sorts and re-dispatches.
,(method-def-expr-
Expand Down Expand Up @@ -549,8 +551,7 @@
,@(if (null? restkw) '() (list rkw))
,@(map arg-name pargl)
,@(if (null? vararg) '()
(list `(... ,(arg-name (car vararg)))))))))
#f)
(list `(... ,(arg-name (car vararg))))))))))
;; return primary function
,(if (not (symbol? name))
'(null) name)))))
Expand All @@ -563,6 +564,12 @@
(cdr body))
'()))

(define (without-generated stmts)
(map (lambda (x) (if (generated-meta? x)
(filter (lambda (e) (not (eq? e 'generated))) x)
x))
stmts))

;; keep only sparams used by `expr` or other sparams
(define (filter-sparams expr sparams)
(let loop ((filtered '())
Expand All @@ -576,8 +583,8 @@
(else
(loop filtered (cdr params))))))

(define (optional-positional-defs name sparams req opt dfl body isstaged overall-argl rett)
(let ((prologue (extract-method-prologue body)))
(define (optional-positional-defs name sparams req opt dfl body overall-argl rett)
(let ((prologue (without-generated (extract-method-prologue body))))
`(block
,@(map (lambda (n)
(let* ((passed (append req (list-head opt n)))
Expand Down Expand Up @@ -606,9 +613,9 @@
`(block
,@prologue
(call ,(arg-name (car req)) ,@(map arg-name (cdr passed)) ,@vals)))))
(method-def-expr- name sp passed body #f)))
(method-def-expr- name sp passed body)))
(iota (length opt)))
,(method-def-expr- name sparams overall-argl body isstaged rett))))
,(method-def-expr- name sparams overall-argl body rett))))

;; strip empty (parameters ...), normalizing `f(x;)` to `f(x)`.
(define (remove-empty-parameters argl)
Expand Down Expand Up @@ -637,14 +644,14 @@
;; definitions without keyword arguments are passed to method-def-expr-,
;; which handles optional positional arguments by adding the needed small
;; boilerplate definitions.
(define (method-def-expr name sparams argl body isstaged rett)
(define (method-def-expr name sparams argl body rett)
(let ((argl (remove-empty-parameters argl)))
(if (has-parameters? argl)
;; has keywords
(begin (check-kw-args (cdar argl))
(keywords-method-def-expr name sparams argl body isstaged rett))
(keywords-method-def-expr name sparams argl body rett))
;; no keywords
(method-def-expr- name sparams argl body isstaged rett))))
(method-def-expr- name sparams argl body rett))))

(define (struct-def-expr name params super fields mut)
(receive
Expand Down Expand Up @@ -773,12 +780,12 @@
,@sig)
new-params)))))

(define (ctor-def keyword name Tname params bounds sig ctor-body body wheres)
(define (ctor-def name Tname params bounds sig ctor-body body wheres)
(let* ((curly? (and (pair? name) (eq? (car name) 'curly)))
(curlyargs (if curly? (cddr name) '()))
(name (if curly? (cadr name) name)))
(cond ((not (eq? name Tname))
`(,keyword ,(with-wheres `(call ,(if curly?
`(function ,(with-wheres `(call ,(if curly?
`(curly ,name ,@curlyargs)
name)
,@sig)
Expand All @@ -787,7 +794,7 @@
;; new{...} inside a non-ctor inner definition.
,(ctor-body body '())))
(wheres
`(,keyword ,(with-wheres `(call ,(if curly?
`(function ,(with-wheres `(call ,(if curly?
`(curly ,name ,@curlyargs)
name)
,@sig)
Expand All @@ -801,7 +808,7 @@
(syntax-deprecation #f
(string "inner constructor " name "(...)" (linenode-string (function-body-lineno body)))
(deparse `(where (call (curly ,name ,@params) ...) ,@params))))
`(,keyword ,sig ,(ctor-body body params)))))))
`(function ,sig ,(ctor-body body params)))))))

(define (function-body-lineno body)
(let ((lnos (filter (lambda (e) (and (pair? e) (eq? (car e) 'line)))
Expand All @@ -828,18 +835,14 @@
(pattern-set
;; definitions without `where`
(pattern-lambda (function (-$ (call name . sig) (|::| (call name . sig) _t)) body)
(ctor-def (car __) name Tname params bounds sig ctor-body body #f))
(pattern-lambda (stagedfunction (-$ (call name . sig) (|::| (call name . sig) _t)) body)
(ctor-def (car __) name Tname params bounds sig ctor-body body #f))
(ctor-def name Tname params bounds sig ctor-body body #f))
(pattern-lambda (= (-$ (call name . sig) (|::| (call name . sig) _t)) body)
(ctor-def 'function name Tname params bounds sig ctor-body body #f))
(ctor-def name Tname params bounds sig ctor-body body #f))
;; definitions with `where`
(pattern-lambda (function (where (-$ (call name . sig) (|::| (call name . sig) _t)) . wheres) body)
(ctor-def (car __) name Tname params bounds sig ctor-body body wheres))
(pattern-lambda (stagedfunction (where (-$ (call name . sig) (|::| (call name . sig) _t)) . wheres) body)
(ctor-def (car __) name Tname params bounds sig ctor-body body wheres))
(ctor-def name Tname params bounds sig ctor-body body wheres))
(pattern-lambda (= (where (-$ (call name . sig) (|::| (call name . sig) _t)) . wheres) body)
(ctor-def 'function name Tname params bounds sig ctor-body body wheres)))
(ctor-def name Tname params bounds sig ctor-body body wheres)))

;; flatten `where`s first
(pattern-replace
Expand Down Expand Up @@ -980,7 +983,7 @@
(loop (if isseq F (cdr F)) (cdr A) stmts
(list* (if isamp `(& ,ca) ca) C) (list* g GC))))))))

(define (expand-function-def e) ;; handle function or stagedfunction
(define (expand-function-def e) ;; handle function definitions
(define (just-arglist? ex)
(and (pair? ex)
(or (memq (car ex) '(tuple block))
Expand Down Expand Up @@ -1038,7 +1041,6 @@
(where where)
(else '())))
(sparams (map analyze-typevar raw-typevars))
(isstaged (eq? (car e) 'stagedfunction))
(adj-decl (lambda (n) (if (and (decl? n) (length= n 2))
`(|::| |#self#| ,(cadr n))
n)))
Expand All @@ -1062,7 +1064,7 @@
(cdr argl)))
,@raw-typevars))))
(expand-forms
(method-def-expr name sparams argl body isstaged rett))))
(method-def-expr name sparams argl body rett))))
(else
(error (string "invalid assignment location \"" (deparse name) "\""))))))

Expand Down Expand Up @@ -1239,7 +1241,6 @@
(cond ((or (atom? e) (quoted? e)) e)
((or (eq? (car e) 'lambda)
(eq? (car e) 'function)
(eq? (car e) 'stagedfunction)
(eq? (car e) '->)) e)
((eq? (car e) 'return)
`(block ,@(if ret `((= ,ret true)) '())
Expand Down Expand Up @@ -1888,7 +1889,6 @@
(define expand-table
(table
'function expand-function-def
'stagedfunction expand-function-def
'-> expand-arrow
'let expand-let
'macro expand-macro-def
Expand Down Expand Up @@ -3165,8 +3165,7 @@ f(x) = yt(x)
,@top-stmts
(block ,@sp-inits
(method ,name ,(cl-convert sig fname lam namemap toplevel interp)
,(julia-expand-macros `(quote ,newlam))
,(last e)))))))
,(julia-expand-macros `(quote ,newlam))))))))
;; local case - lift to a new type at top level
(let* ((exists (get namemap name #f))
(type-name (or exists
Expand Down Expand Up @@ -3239,8 +3238,7 @@ f(x) = yt(x)
(if iskw
(caddr (lam:args lam2))
(car (lam:args lam2)))
#f closure-param-names)
,(last e)))))))
#f closure-param-names)))))))
(mk-closure ;; expression to make the closure
(let* ((var-exprs (map (lambda (v)
(let ((cv (assq v (cadr (lam:vinfo lam)))))
Expand Down Expand Up @@ -3606,8 +3604,7 @@ f(x) = yt(x)
(if (length> e 2)
(begin (emit `(method ,(or (cadr e) 'false)
,(compile (caddr e) break-labels #t #f)
,(linearize (cadddr e))
,(if (car (cddddr e)) 'true 'false)))
,(linearize (cadddr e))))
(if value (compile '(null) break-labels value tail)))
(cond (tail (emit-return e))
(value e)
Expand Down
2 changes: 1 addition & 1 deletion src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -1055,7 +1055,7 @@ JL_DLLEXPORT jl_value_t *jl_generic_function_def(jl_sym_t *name,
jl_module_t *module,
jl_value_t **bp, jl_value_t *bp_owner,
jl_binding_t *bnd);
JL_DLLEXPORT void jl_method_def(jl_svec_t *argdata, jl_code_info_t *f, jl_module_t *module, jl_value_t *isstaged);
JL_DLLEXPORT void jl_method_def(jl_svec_t *argdata, jl_code_info_t *f, jl_module_t *module);
JL_DLLEXPORT jl_code_info_t *jl_code_for_staged(jl_method_instance_t *linfo);
JL_DLLEXPORT jl_code_info_t *jl_copy_code_info(jl_code_info_t *src);
JL_DLLEXPORT size_t jl_get_world_counter(void);
Expand Down
2 changes: 1 addition & 1 deletion src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -995,7 +995,7 @@ extern jl_sym_t *pure_sym; extern jl_sym_t *simdloop_sym;
extern jl_sym_t *meta_sym; extern jl_sym_t *list_sym;
extern jl_sym_t *inert_sym; extern jl_sym_t *static_parameter_sym;
extern jl_sym_t *polly_sym; extern jl_sym_t *inline_sym;
extern jl_sym_t *propagate_inbounds_sym;
extern jl_sym_t *propagate_inbounds_sym; extern jl_sym_t *generated_sym;
extern jl_sym_t *isdefined_sym; extern jl_sym_t *nospecialize_sym;

void jl_register_fptrs(uint64_t sysimage_base, const char *base, const int32_t *offsets,
Expand Down
Loading

0 comments on commit ea7463a

Please sign in to comment.