Skip to content

Commit

Permalink
hoist static locals when unrolling loops
Browse files Browse the repository at this point in the history
see #11800
  • Loading branch information
Simn committed Oct 25, 2024
1 parent 991e227 commit 5011518
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 9 deletions.
29 changes: 20 additions & 9 deletions src/typing/forLoop.ml
Original file line number Diff line number Diff line change
Expand Up @@ -319,15 +319,28 @@ module IterationKind = struct
| IteratorIntUnroll(offset,length,ascending) ->
check_loop_var_modification [v] e2;
if not ascending then raise_typing_error "Cannot iterate backwards" p;
let el = ExtList.List.init length (fun i ->
let ei = make_int ctx.t (if ascending then i + offset else offset - i) p in
let rec loop e = match e.eexpr with
| TLocal v' when v == v' -> {ei with epos = e.epos}
| _ -> map_expr loop e
let rec unroll acc i =
if i = length then
List.rev acc
else begin
let ei = make_int ctx.t (if ascending then i + offset else offset - i) p in
let static_locals = ref [] in
let rec loop e = match e.eexpr with
| TLocal v' when v == v' ->
{ei with epos = e.epos}
| TVar(v,eo) when has_var_flag v VStatic ->
if acc = [] then
static_locals := e :: !static_locals;
mk (TConst TNull) t_dynamic null_pos
| _ ->
map_expr loop e
in
let e2 = loop e2 in
Texpr.duplicate_tvars e_identity e2
) in
let acc = acc @ !static_locals in
let e2 = Texpr.duplicate_tvars e_identity e2 in
unroll (e2 :: acc) (i + 1)
end in
let el = unroll [] 0 in
mk (TBlock el) t_void p
| IteratorIntConst(a,b,ascending) ->
check_loop_var_modification [v] e2;
Expand Down Expand Up @@ -412,8 +425,6 @@ let is_cheap_enough ctx e2 i =
let rec loop e = match fst e with
| EContinue | EBreak ->
raise Exit
| EVars vl when (List.exists (fun ev -> ev.ev_static) vl) ->
raise Exit
| _ ->
incr num_expr;
Ast.map_expr loop e
Expand Down
25 changes: 25 additions & 0 deletions tests/optimization/src/issues/Issue11800.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package issues;

class Issue11800 {
@:js('
++issues_Issue11800.test_a;
++issues_Issue11800.test_b;
++issues_Issue11800.test_a;
++issues_Issue11800.test_b;
')
static function test() {
static var a = 0;

for (i in 0...3) {
switch i {
case n if (n < 2):
use(++a);
static var b = 0;
use(++b);
case _:
}
}
}

static function use(v:Int) {}
}

0 comments on commit 5011518

Please sign in to comment.