|
@@ -102,7 +102,7 @@ and inline_var = {
|
|
mutable iv_closed : bool (* Inline variables are marked as closed when the scope they were first assigned on ends, any appearance of this variable after it has been closed causes cancellation *)
|
|
mutable iv_closed : bool (* Inline variables are marked as closed when the scope they were first assigned on ends, any appearance of this variable after it has been closed causes cancellation *)
|
|
}
|
|
}
|
|
|
|
|
|
-and inline_object_field =
|
|
|
|
|
|
+and inline_object_field =
|
|
| IOFInlineMethod of inline_object * inline_var * tclass * Type.tparams * tclass_field * tfunc
|
|
| IOFInlineMethod of inline_object * inline_var * tclass * Type.tparams * tclass_field * tfunc
|
|
| IOFInlineVar of inline_var
|
|
| IOFInlineVar of inline_var
|
|
| IOFNone
|
|
| IOFNone
|
|
@@ -203,15 +203,16 @@ let inline_constructors ctx original_e =
|
|
Returns true if there are any potential inline objects in the expression.
|
|
Returns true if there are any potential inline objects in the expression.
|
|
It is used to save work before running mark_ctors and analyze_aliases.
|
|
It is used to save work before running mark_ctors and analyze_aliases.
|
|
*)
|
|
*)
|
|
- let rec check_for_ctors ?(force_inline=false) e =
|
|
|
|
|
|
+ let rec check_for_ctors ?(force_inline=false) e =
|
|
let is_ctor, is_meta_inline = match e.eexpr, force_inline with
|
|
let is_ctor, is_meta_inline = match e.eexpr, force_inline with
|
|
| TMeta((Meta.Inline,_,_),_), _ ->
|
|
| TMeta((Meta.Inline,_,_),_), _ ->
|
|
false, true
|
|
false, true
|
|
| TObjectDecl _, _
|
|
| TObjectDecl _, _
|
|
| TArrayDecl _, _
|
|
| TArrayDecl _, _
|
|
- | TNew({ cl_constructor = Some ({cf_kind = Method MethInline; cf_expr = Some ({eexpr = TFunction _})})},_,_), _
|
|
|
|
| TNew _, true ->
|
|
| TNew _, true ->
|
|
true, false
|
|
true, false
|
|
|
|
+ | TNew({ cl_constructor = Some ({cf_kind = Method MethInline; cf_expr = Some ({eexpr = TFunction _})} as cf)} as c,_,_), _ ->
|
|
|
|
+ Inline.needs_inline ctx c.cl_extern cf, false
|
|
| _ -> false, false
|
|
| _ -> false, false
|
|
in
|
|
in
|
|
is_ctor || Type.check_expr (check_for_ctors ~force_inline:is_meta_inline) e
|
|
is_ctor || Type.check_expr (check_for_ctors ~force_inline:is_meta_inline) e
|
|
@@ -224,15 +225,20 @@ let inline_constructors ctx original_e =
|
|
let rec mark_ctors ?(force_inline=false) e : texpr =
|
|
let rec mark_ctors ?(force_inline=false) e : texpr =
|
|
let is_meta_inline = match e.eexpr with (TMeta((Meta.Inline,_,_),e)) -> true | _ -> false in
|
|
let is_meta_inline = match e.eexpr with (TMeta((Meta.Inline,_,_),e)) -> true | _ -> false in
|
|
let e = Type.map_expr (mark_ctors ~force_inline:is_meta_inline) e in
|
|
let e = Type.map_expr (mark_ctors ~force_inline:is_meta_inline) e in
|
|
|
|
+ let mark() =
|
|
|
|
+ incr curr_io_id;
|
|
|
|
+ let id_expr = (EConst(Int (string_of_int !curr_io_id)), e.epos) in
|
|
|
|
+ let meta = (Meta.InlineObject, [id_expr], e.epos) in
|
|
|
|
+ mk (TMeta(meta, e)) e.etype e.epos
|
|
|
|
+ in
|
|
match e.eexpr, force_inline with
|
|
match e.eexpr, force_inline with
|
|
| TObjectDecl _, _
|
|
| TObjectDecl _, _
|
|
| TArrayDecl _, _
|
|
| TArrayDecl _, _
|
|
- | TNew({ cl_constructor = Some ({cf_kind = Method MethInline; cf_expr = Some ({eexpr = TFunction _})})},_,_), _
|
|
|
|
| TNew _, true ->
|
|
| TNew _, true ->
|
|
- incr curr_io_id;
|
|
|
|
- let id_expr = (EConst(Int (string_of_int !curr_io_id)), e.epos) in
|
|
|
|
- let meta = (Meta.InlineObject, [id_expr], e.epos) in
|
|
|
|
- mk (TMeta(meta, e)) e.etype e.epos
|
|
|
|
|
|
+ mark()
|
|
|
|
+ | TNew({ cl_constructor = Some ({cf_kind = Method MethInline; cf_expr = Some ({eexpr = TFunction _})} as cf)} as c,_,_), _ ->
|
|
|
|
+ if Inline.needs_inline ctx c.cl_extern cf then mark()
|
|
|
|
+ else e
|
|
| _ -> e
|
|
| _ -> e
|
|
in
|
|
in
|
|
|
|
|
|
@@ -242,7 +248,7 @@ let inline_constructors ctx original_e =
|
|
The expression being analyzed should have been processed with mark_ctors before hand.
|
|
The expression being analyzed should have been processed with mark_ctors before hand.
|
|
|
|
|
|
returns: Some(inline variable) if the expression being analyzed returns an inline variable. None otherwise.
|
|
returns: Some(inline variable) if the expression being analyzed returns an inline variable. None otherwise.
|
|
-
|
|
|
|
|
|
+
|
|
seen_ctors: used to avoid infinite constructor inlining loops.
|
|
seen_ctors: used to avoid infinite constructor inlining loops.
|
|
|
|
|
|
captured: Wether the caller is ready to accept an inline variable. If analysis results in an inline
|
|
captured: Wether the caller is ready to accept an inline variable. If analysis results in an inline
|
|
@@ -272,13 +278,17 @@ let inline_constructors ctx original_e =
|
|
let analyze_aliases_in_lvalue e = analyze_aliases seen_ctors captured true e in
|
|
let analyze_aliases_in_lvalue e = analyze_aliases seen_ctors captured true e in
|
|
let analyze_aliases_in_ctor cf captured e = analyze_aliases (cf::seen_ctors) captured false e in
|
|
let analyze_aliases_in_ctor cf captured e = analyze_aliases (cf::seen_ctors) captured false e in
|
|
let analyze_aliases captured e = analyze_aliases seen_ctors captured false e in
|
|
let analyze_aliases captured e = analyze_aliases seen_ctors captured false e in
|
|
- let get_io_inline_method io fname =
|
|
|
|
|
|
+ let get_io_inline_method io fname =
|
|
begin match io.io_kind with
|
|
begin match io.io_kind with
|
|
| IOKCtor(ctor) ->
|
|
| IOKCtor(ctor) ->
|
|
begin try
|
|
begin try
|
|
let f = PMap.find fname ctor.ioc_class.cl_fields in
|
|
let f = PMap.find fname ctor.ioc_class.cl_fields in
|
|
begin match f.cf_params, f.cf_kind, f.cf_expr with
|
|
begin match f.cf_params, f.cf_kind, f.cf_expr with
|
|
- | [], Method MethInline, Some({eexpr = TFunction tf}) -> Some (ctor.ioc_class, ctor.ioc_tparams, f, tf)
|
|
|
|
|
|
+ | [], Method MethInline, Some({eexpr = TFunction tf}) ->
|
|
|
|
+ if Inline.needs_inline ctx ctor.ioc_class.cl_extern f then
|
|
|
|
+ Some (ctor.ioc_class, ctor.ioc_tparams, f, tf)
|
|
|
|
+ else
|
|
|
|
+ None
|
|
| _ -> None
|
|
| _ -> None
|
|
end
|
|
end
|
|
with Not_found -> None
|
|
with Not_found -> None
|
|
@@ -481,7 +491,7 @@ let inline_constructors ctx original_e =
|
|
| TCall(({eexpr=TField(ethis,fa)} as efield),call_args) ->
|
|
| TCall(({eexpr=TField(ethis,fa)} as efield),call_args) ->
|
|
let fname = field_name fa in
|
|
let fname = field_name fa in
|
|
let fiv = handle_field_case efield ethis fname (fun _ -> true) in
|
|
let fiv = handle_field_case efield ethis fname (fun _ -> true) in
|
|
- begin match fiv with
|
|
|
|
|
|
+ begin match fiv with
|
|
| IOFInlineMethod(io,io_var,c,tl,cf,tf) ->
|
|
| IOFInlineMethod(io,io_var,c,tl,cf,tf) ->
|
|
let argvs, pl = analyze_call_args call_args in
|
|
let argvs, pl = analyze_call_args call_args in
|
|
io.io_dependent_vars <- io.io_dependent_vars @ argvs;
|
|
io.io_dependent_vars <- io.io_dependent_vars @ argvs;
|