Skip to content

Commit

Permalink
add CfUsed, CfMaybeUsed, CUsed
Browse files Browse the repository at this point in the history
Can't get rid of Meta.Used entirely yet because enums and abstracts don't have flags
  • Loading branch information
Simn committed Jan 11, 2024
1 parent a2bbb11 commit 020ad1b
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 49 deletions.
6 changes: 0 additions & 6 deletions src-json/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -714,12 +714,6 @@
"metadata": ":macro",
"doc": "(deprecated)"
},
{
"name": "MaybeUsed",
"metadata": ":maybeUsed",
"doc": "Internally used by DCE to mark fields that might be kept.",
"internal": true
},
{
"name": "MergeBlock",
"metadata": ":mergeBlock",
Expand Down
2 changes: 1 addition & 1 deletion src/codegen/genxml.ml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ let rec follow_param t =
t

let gen_meta meta =
let meta = List.filter (fun (m,_,_) -> match m with Meta.Used | Meta.MaybeUsed | Meta.RealPath | Meta.Pure -> false | _ -> true) meta in
let meta = List.filter (fun (m,_,_) -> match m with Meta.Used | Meta.RealPath | Meta.Pure -> false | _ -> true) meta in
match meta with
| [] -> []
| _ ->
Expand Down
10 changes: 8 additions & 2 deletions src/context/common.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1033,9 +1033,15 @@ let rec has_feature com f =
(match List.find (fun t -> t_path t = path && not (Meta.has Meta.RealPath (t_infos t).mt_meta)) com.types with
| t when field = "*" ->
not (has_dce com) ||
(match t with TAbstractDecl a -> Meta.has Meta.ValueUsed a.a_meta | _ -> Meta.has Meta.Used (t_infos t).mt_meta)
begin match t with
| TClassDecl c ->
has_class_flag c CUsed;
| TAbstractDecl a ->
Meta.has Meta.ValueUsed a.a_meta
| _ -> Meta.has Meta.Used (t_infos t).mt_meta
end;
| TClassDecl c when (has_class_flag c CExtern) && (com.platform <> Js || cl <> "Array" && cl <> "Math") ->
not (has_dce com) || Meta.has Meta.Used (try PMap.find field c.cl_statics with Not_found -> PMap.find field c.cl_fields).cf_meta
not (has_dce com) || has_class_field_flag (try PMap.find field c.cl_statics with Not_found -> PMap.find field c.cl_fields) CfUsed
| TClassDecl c ->
PMap.exists field c.cl_statics || PMap.exists field c.cl_fields
| _ ->
Expand Down
5 changes: 4 additions & 1 deletion src/core/tType.ml
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,7 @@ type flag_tclass =
| CInterface
| CAbstract
| CFunctionalInterface
| CUsed (* Marker for DCE *)

type flag_tclass_field =
| CfPublic
Expand All @@ -478,10 +479,12 @@ type flag_tclass_field =
| CfGeneric
| CfDefault (* Interface field with default implementation (only valid on Java) *)
| CfPostProcessed (* Marker to indicate the field has been post-processed *)
| CfUsed (* Marker for DCE *)
| CfMaybeUsed (* Marker for DCE *)

(* Order has to match declaration for printing*)
let flag_tclass_field_names = [
"CfPublic";"CfStatic";"CfExtern";"CfFinal";"CfModifiesThis";"CfOverride";"CfAbstract";"CfOverload";"CfImpl";"CfEnum";"CfGeneric";"CfDefault";"CfPostProcessed"
"CfPublic";"CfStatic";"CfExtern";"CfFinal";"CfModifiesThis";"CfOverride";"CfAbstract";"CfOverload";"CfImpl";"CfEnum";"CfGeneric";"CfDefault";"CfPostProcessed";"CfUsed";"CfMaybeUsed"
]

type flag_tvar =
Expand Down
10 changes: 4 additions & 6 deletions src/core/tUnification.ml
Original file line number Diff line number Diff line change
Expand Up @@ -788,15 +788,14 @@ let rec unify (uctx : unification_context) a b =
then error [Missing_overload (f1, f2o.cf_type)]
) f2.cf_overloads;
(* we mark the field as :?used because it might be used through the structure *)
if not (Meta.has Meta.MaybeUsed f1.cf_meta) then begin
f1.cf_meta <- (Meta.MaybeUsed,[],f1.cf_pos) :: f1.cf_meta;
if not (has_class_field_flag f1 CfMaybeUsed) then begin
add_class_field_flag f1 CfMaybeUsed;
match f2.cf_kind with
| Var vk ->
let check name =
try
let _,_,cf = raw_class_field make_type c tl name in
if not (Meta.has Meta.MaybeUsed cf.cf_meta) then
cf.cf_meta <- (Meta.MaybeUsed,[],f1.cf_pos) :: cf.cf_meta
add_class_field_flag cf CfMaybeUsed
with Not_found ->
()
in
Expand Down Expand Up @@ -951,8 +950,7 @@ and unify_anons uctx a b a1 a2 =
)
| ClassStatics c1,_ ->
unify_fields c1.cl_statics (fun f1 ->
if not (Meta.has Meta.MaybeUsed f1.cf_meta) then
f1.cf_meta <- (Meta.MaybeUsed,[],f1.cf_pos) :: f1.cf_meta
add_class_field_flag f1 CfMaybeUsed
) (fun _ -> false)
| _ ->
unify_fields a1.a_fields (fun _ -> ()) (fun _ -> false)
Expand Down
2 changes: 1 addition & 1 deletion src/generators/genhxold.ml
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ let generate_type com t =
let print_meta ml =
List.iter (fun (m,pl,_) ->
match m with
| Meta.DefParam | Meta.CoreApi | Meta.Used | Meta.MaybeUsed | Meta.FlatEnum | Meta.Value | Meta.DirectlyUsed | Meta.Enum -> ()
| Meta.DefParam | Meta.CoreApi | Meta.Used | Meta.FlatEnum | Meta.Value | Meta.DirectlyUsed | Meta.Enum -> ()
| _ ->
match pl with
| [] -> p "@%s " (Meta.to_string m)
Expand Down
36 changes: 18 additions & 18 deletions src/optimization/dce.ml
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ let mk_keep_meta pos =
*)
let rec keep_field dce cf c kind =
let is_static = kind = CfrStatic in
Meta.has_one_of (Meta.Used :: keep_metas) cf.cf_meta
Meta.has_one_of keep_metas cf.cf_meta
|| has_class_field_flag cf CfUsed
|| cf.cf_name = "__init__"
|| has_class_field_flag cf CfExtern
|| (not is_static && overrides_extern_field cf c)
Expand Down Expand Up @@ -166,8 +167,8 @@ and check_and_add_feature dce s =
(* mark a field as kept *)
and mark_field dce c cf kind =
let add c' cf =
if not (Meta.has Meta.Used cf.cf_meta) then begin
cf.cf_meta <- (mk_used_meta cf.cf_pos) :: cf.cf_meta;
if not (has_class_field_flag cf CfUsed) then begin
add_class_field_flag cf CfUsed;
dce.added_fields <- (c',cf,kind) :: dce.added_fields;
dce.marked_fields <- cf :: dce.marked_fields;
check_feature dce (Printf.sprintf "%s.%s" (s_type_path c.cl_path) cf.cf_name);
Expand Down Expand Up @@ -202,10 +203,10 @@ let rec update_marked_class_fields dce c =
let pop = push_class dce c in
(* mark all :?used fields as surely :used now *)
List.iter (fun cf ->
if Meta.has Meta.MaybeUsed cf.cf_meta then mark_field dce c cf CfrStatic
if has_class_field_flag cf CfMaybeUsed then mark_field dce c cf CfrStatic
) c.cl_ordered_statics;
List.iter (fun cf ->
if Meta.has Meta.MaybeUsed cf.cf_meta then mark_field dce c cf CfrMember
if has_class_field_flag cf CfMaybeUsed then mark_field dce c cf CfrMember
) c.cl_ordered_fields;
(* we always have to keep super classes and implemented interfaces *)
(match c.cl_init with None -> () | Some init -> dce.follow_expr dce init);
Expand All @@ -214,8 +215,8 @@ let rec update_marked_class_fields dce c =
pop()

(* mark a class as kept. If the class has fields marked as @:?keep, make sure to keep them *)
and mark_class dce c = if not (Meta.has Meta.Used c.cl_meta) then begin
c.cl_meta <- (mk_used_meta c.cl_pos) :: c.cl_meta;
and mark_class dce c = if not (has_class_flag c CUsed) then begin
add_class_flag c CUsed;
check_feature dce (Printf.sprintf "%s.*" (s_type_path c.cl_path));
update_marked_class_fields dce c;
end
Expand All @@ -238,8 +239,8 @@ and mark_t dce p t =
dce.t_stack <- t :: dce.t_stack;
begin match follow t with
| TInst({cl_kind = KTypeParameter ttp} as c,pl) ->
if not (Meta.has Meta.Used c.cl_meta) then begin
c.cl_meta <- (mk_used_meta c.cl_pos) :: c.cl_meta;
if not (has_class_flag c CUsed) then begin
add_class_flag c CUsed;
List.iter (mark_t dce p) (get_constraints ttp);
end;
List.iter (mark_t dce p) pl
Expand Down Expand Up @@ -288,10 +289,10 @@ let mark_dependent_fields dce csup n kind =
let cf = PMap.find n (if stat then c.cl_statics else c.cl_fields) in
(* if it's clear that the class is kept, the field has to be kept as well. This is also true for
extern interfaces because we cannot remove fields from them *)
if Meta.has Meta.Used c.cl_meta || ((has_class_flag csup CInterface) && (has_class_flag csup CExtern)) then mark_field dce c cf kind
if has_class_flag c CUsed || ((has_class_flag csup CInterface) && (has_class_flag csup CExtern)) then mark_field dce c cf kind
(* otherwise it might be kept if the class is kept later, so mark it as :?used *)
else if not (Meta.has Meta.MaybeUsed cf.cf_meta) then begin
cf.cf_meta <- (Meta.MaybeUsed,[],cf.cf_pos) :: cf.cf_meta;
else if not (has_class_field_flag cf CfMaybeUsed) then begin
add_class_field_flag cf CfMaybeUsed;
dce.marked_maybe_fields <- cf :: dce.marked_maybe_fields;
end
with Not_found ->
Expand Down Expand Up @@ -685,7 +686,7 @@ and expr dce e =
let fix_accessors com =
List.iter (fun mt -> match mt with
(* filter empty abstract implementation classes (issue #1885). *)
| TClassDecl({cl_kind = KAbstractImpl _} as c) when c.cl_ordered_statics = [] && c.cl_ordered_fields = [] && not (Meta.has Meta.Used c.cl_meta) ->
| TClassDecl({cl_kind = KAbstractImpl _} as c) when c.cl_ordered_statics = [] && c.cl_ordered_fields = [] && not (has_class_flag c CUsed) ->
add_class_flag c CExtern;
| TClassDecl({cl_kind = KAbstractImpl a} as c) when a.a_enum ->
let is_runtime_field cf =
Expand Down Expand Up @@ -719,10 +720,9 @@ let fix_accessors com =
let collect_entry_points dce com =
let delayed = ref [] in
List.iter (fun t ->
let mt = t_infos t in
mt.mt_meta <- Meta.remove Meta.Used mt.mt_meta;
match t with
| TClassDecl c ->
remove_class_flag c CUsed;
let keep_class = keep_whole_class dce c && (not (has_class_flag c CExtern) || (has_class_flag c CInterface)) in
let is_struct = dce.com.platform = Hl && Meta.has Meta.Struct c.cl_meta in
let loop kind cf =
Expand Down Expand Up @@ -762,6 +762,7 @@ let collect_entry_points dce com =
()
end;
| TEnumDecl en when keep_whole_enum dce en ->
en.e_meta <- Meta.remove Meta.Used en.e_meta;
delayed := (fun () ->
let pop = push_class dce {null_class with cl_module = en.e_module} in
mark_enum dce en;
Expand Down Expand Up @@ -862,7 +863,7 @@ let sweep dce com =
let inef cf = is_physical_field cf in
let has_non_extern_fields = List.exists inef c.cl_ordered_fields || List.exists inef c.cl_ordered_statics in
(* we keep a class if it was used or has a used field *)
if Meta.has Meta.Used c.cl_meta || has_non_extern_fields then loop (mt :: acc) l else begin
if has_class_flag c CUsed || has_non_extern_fields then loop (mt :: acc) l else begin
(match c.cl_init with
| Some f when Meta.has Meta.KeepInit c.cl_meta ->
(* it means that we only need the __init__ block *)
Expand Down Expand Up @@ -944,5 +945,4 @@ let run com main mode =
) com.types;

(* cleanup added fields metadata - compatibility with compilation server *)
List.iter (fun cf -> cf.cf_meta <- Meta.remove Meta.Used cf.cf_meta) dce.marked_fields;
List.iter (fun cf -> cf.cf_meta <- Meta.remove Meta.MaybeUsed cf.cf_meta) dce.marked_maybe_fields
List.iter (fun cf -> remove_class_field_flag cf CfUsed) dce.marked_fields
28 changes: 14 additions & 14 deletions tests/unit/src/unit/issues/Issue8502.hx
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
package unit.issues;

class Issue8502 extends Test {
#if cpp
public function test() {
#if cpp
public function test() {
var t:scripthost.Issue8502 = Type.createInstance(Type.resolveClass('unit.issues.Issue8502_2'), []);
eq(t.doTest1(25), 'cppia 25');
eq(t.doTest2(25), 'cppia 25');
eq(t.doTest3(25), 'cppia 25');
eq(t.doTest4(25), 'cppia 25');
eq(t.doTest5(25), 'cppia 25');
eq(t.doTest3u(25), 'cppia 25');
eq(t.doTest4u(25), 'cppia 25');
eq(t.doTest5u(25), 'cppia 25');
}
#end
eq(t.doTest1(25), 'cppia 25');
eq(t.doTest2(25), 'cppia 25');
eq(t.doTest3(25), 'cppia 25');
eq(t.doTest4(25), 'cppia 25');
eq(t.doTest5(25), 'cppia 25');
eq(t.doTest3u(25), 'cppia 25');
eq(t.doTest4u(25), 'cppia 25');
eq(t.doTest5u(25), 'cppia 25');
}
#end
}

#if cpp
@:keep

This comment has been minimized.

Copy link
@Simn

Simn Jan 11, 2024

Author Member

I don't know why this class wasn't DCEd before, it's not referenced anywhere. But I also don't know why this changed now.

class Issue8502_2 extends scripthost.Issue8502 {
override public function doTest1(f:cpp.Float32):String {
return 'cppia ' + super.doTest1(f);
Expand Down Expand Up @@ -50,5 +51,4 @@ class Issue8502_2 extends scripthost.Issue8502 {
return 'cppia ' + super.doTest5u(f);
}
}

#end
#end

0 comments on commit 020ad1b

Please sign in to comment.