Skip to content

Commit 51277d1

Browse files
committed
Compiler: avoid nesting loops if unnecessary
1 parent d66a793 commit 51277d1

File tree

3 files changed

+60
-57
lines changed

3 files changed

+60
-57
lines changed

compiler/lib/structure.ml

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -189,15 +189,18 @@ let mark_loops g =
189189
in_loop
190190

191191
let rec measure blocks g pc limit =
192-
let b = Addr.Map.find pc blocks in
193-
let limit = limit - List.length b.body in
194-
if limit < 0
195-
then limit
192+
if is_loop_header g pc
193+
then -1
196194
else
197-
Addr.Set.fold
198-
(fun pc limit -> if limit < 0 then limit else measure blocks g pc limit)
199-
(get_edges g.succs pc)
200-
limit
195+
let b = Addr.Map.find pc blocks in
196+
let limit = limit - List.length b.body in
197+
if limit < 0
198+
then limit
199+
else
200+
Addr.Set.fold
201+
(fun pc limit -> if limit < 0 then limit else measure blocks g pc limit)
202+
(get_edges g.succs pc)
203+
limit
201204

202205
let is_small blocks g pc = measure blocks g pc 20 >= 0
203206

@@ -225,20 +228,16 @@ let shrink_loops blocks ({ succs; preds; reverse_post_order; _ } as g) =
225228
in
226229
let loops' = get_edges in_loop pc' in
227230
let left_loops = Addr.Set.diff (Addr.Set.diff loops loops') ignored in
228-
(* If we leave a loop, we add an edge from a predecessor of
231+
(* If we leave a loop, we add an edge from predecessors of
229232
the loop header to the current block, so that it is
230233
considered outside of the loop. *)
231234
if not (Addr.Set.is_empty left_loops || is_small blocks g pc')
232235
then
233236
Addr.Set.iter
234237
(fun pc0 ->
235-
match
236-
Addr.Set.find_first
237-
(fun pc -> is_forward g pc pc0)
238-
(get_edges g.preds pc0)
239-
with
240-
| pc -> add_edge pc pc'
241-
| exception Not_found -> ())
238+
Addr.Set.iter
239+
(fun pc -> if is_forward g pc pc0 then add_edge pc pc')
240+
(get_edges g.preds pc0))
242241
left_loops;
243242
traverse ignored pc')
244243
succs

compiler/tests-compiler/loops.ml

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -167,21 +167,20 @@ let for_for_while () =
167167
var k = 1;
168168
for(;;){
169169
var j = 1;
170-
a:
171-
for(;;)
170+
for(;;){
172171
for(;;){
173-
if(10 <= caml_div(k, j)){
174-
var _b_ = j + 1 | 0;
175-
if(10 !== j){var j = _b_; break;}
176-
var _a_ = k + 1 | 0;
177-
if(10 === k) return 0;
178-
var k = _a_;
179-
break a;
180-
}
172+
if(10 <= caml_div(k, j)) break;
181173
try{caml_div(k, j);}
182174
catch(_c_){throw caml_maybe_attach_backtrace(Stdlib[8], 1);}
183175
id[1]++;
184176
}
177+
var _b_ = j + 1 | 0;
178+
if(10 === j) break;
179+
var j = _b_;
180+
}
181+
var _a_ = k + 1 | 0;
182+
if(10 === k) return 0;
183+
var k = _a_;
185184
}
186185
}
187186
//end |}]
@@ -569,29 +568,31 @@ let () = print_endline (trim " ")
569568
len = caml_ml_bytes_length(s$0),
570569
i = [0, 0];
571570
for(;;){
572-
if(i[1] < len && is_space(caml_bytes_unsafe_get(s$0, i[1]))){i[1]++; continue;}
573-
var j = [0, len - 1 | 0];
574-
for(;;){
575-
if(i[1] > j[1]) break;
576-
if(! is_space(caml_bytes_unsafe_get(s$0, j[1]))) break;
577-
j[1] += - 1;
578-
}
579-
a:
580-
{
581-
if(i[1] <= j[1]){
582-
var len$0 = (j[1] - i[1] | 0) + 1 | 0, ofs = i[1];
583-
if
584-
(0 <= ofs && 0 <= len$0 && (caml_ml_bytes_length(s$0) - len$0 | 0) >= ofs){
585-
var r = caml_create_bytes(len$0);
586-
caml_blit_bytes(s$0, ofs, r, 0, len$0);
587-
var b = r;
588-
break a;
589-
}
590-
throw caml_maybe_attach_backtrace([0, Invalid_argument, s], 1);
571+
if(i[1] >= len) break;
572+
if(! is_space(caml_bytes_unsafe_get(s$0, i[1]))) break;
573+
i[1]++;
574+
}
575+
var j = [0, len - 1 | 0];
576+
for(;;){
577+
if(i[1] > j[1]) break;
578+
if(! is_space(caml_bytes_unsafe_get(s$0, j[1]))) break;
579+
j[1] += - 1;
580+
}
581+
a:
582+
{
583+
if(i[1] <= j[1]){
584+
var len$0 = (j[1] - i[1] | 0) + 1 | 0, ofs = i[1];
585+
if
586+
(0 <= ofs && 0 <= len$0 && (caml_ml_bytes_length(s$0) - len$0 | 0) >= ofs){
587+
var r = caml_create_bytes(len$0);
588+
caml_blit_bytes(s$0, ofs, r, 0, len$0);
589+
var b = r;
590+
break a;
591591
}
592-
var b = empty;
592+
throw caml_maybe_attach_backtrace([0, Invalid_argument, s], 1);
593593
}
594-
return caml_string_of_bytes(copy(b));
594+
var b = empty;
595595
}
596+
return caml_string_of_bytes(copy(b));
596597
}
597598
//end |}]

compiler/tests-full/stdlib.cma.expected.js

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5239,15 +5239,17 @@
52395239
len = caml_ml_bytes_length(s),
52405240
/*<<bytes.ml:157:10>>*/ i = [0, 0];
52415241
for(;;){
5242-
/*<<bytes.ml:158:20>>*/ if
5243-
(i[1] < len && is_space(caml_bytes_unsafe_get(s, i[1]))){i[1]++; continue;}
5244-
/*<<bytes.ml:161:10>>*/ /*<<bytes.ml:161:10>>*/ var
5245-
j = [0, len - 1 | 0];
5246-
for(;;){
5247-
/*<<bytes.ml:162:20>>*/ if
5248-
(i[1] <= j[1] && is_space(caml_bytes_unsafe_get(s, j[1]))){j[1] += -1; continue;}
5249-
return i[1] <= j[1] ? sub(s, i[1], (j[1] - i[1] | 0) + 1 | 0) : empty;
5250-
}
5242+
if(i[1] >= len) break;
5243+
/*<<bytes.ml:158:20>>*/ if(! is_space(caml_bytes_unsafe_get(s, i[1])))
5244+
break;
5245+
i[1]++;
5246+
}
5247+
/*<<bytes.ml:161:10>>*/ /*<<bytes.ml:161:10>>*/ var
5248+
j = [0, len - 1 | 0];
5249+
for(;;){
5250+
/*<<bytes.ml:162:20>>*/ if
5251+
(i[1] <= j[1] && is_space(caml_bytes_unsafe_get(s, j[1]))){j[1] += -1; continue;}
5252+
return i[1] <= j[1] ? sub(s, i[1], (j[1] - i[1] | 0) + 1 | 0) : empty;
52515253
}
52525254
/*<<bytes.ml:168:9>>*/ }
52535255
function unsafe_escape(s){
@@ -31156,9 +31158,10 @@
3115631158
/*<<camlinternalMod.ml:75:7>>*/ cl[1 + j] = n$0[1 + j];
3115731159
/*<<camlinternalMod.ml:75:7>>*/ /*<<camlinternalMod.ml:75:7>>*/ var
3115831160
_c_ = j + 1 | 0;
31159-
if(3 === j) break a;
31161+
if(3 === j) break;
3116031162
var j = _c_;
3116131163
}
31164+
break a;
3116231165
}
3116331166
/*<<camlinternalMod.ml:72:5>>*/ throw /*<<camlinternalMod.ml:72:5>>*/ caml_maybe_attach_backtrace
3116431167
([0, Assert_failure, _a_], 1);

0 commit comments

Comments
 (0)