浏览代码

[hl] Fix do-while loop in genhl+hlopt (#11461)

* [hl] Fix do-while loop in genhl+hlopt

* remove can_do
Yuxiao Mao 1 年之前
父节点
当前提交
adef8b3ec3
共有 3 个文件被更改,包括 11 次插入12 次删除
  1. 1 4
      src/generators/genhl.ml
  2. 8 5
      src/generators/hlopt.ml
  3. 2 3
      src/optimization/analyzerTexpr.ml

+ 1 - 4
src/generators/genhl.ml

@@ -2698,13 +2698,10 @@ and eval_expr ctx e =
 		ctx.m.mbreaks <- [];
 		ctx.m.mbreaks <- [];
 		ctx.m.mcontinues <- [];
 		ctx.m.mcontinues <- [];
 		ctx.m.mloop_trys <- ctx.m.mtrys;
 		ctx.m.mloop_trys <- ctx.m.mtrys;
-		let start = jump ctx (fun p -> OJAlways p) in
 		let continue_pos = current_pos ctx in
 		let continue_pos = current_pos ctx in
 		let ret = jump_back ctx in
 		let ret = jump_back ctx in
-		let j = jump_expr ctx cond false in
-		start();
 		ignore(eval_expr ctx eloop);
 		ignore(eval_expr ctx eloop);
-		set_curpos ctx (max_pos e);
+		let j = jump_expr ctx cond false in
 		ret();
 		ret();
 		j();
 		j();
 		List.iter (fun f -> f (current_pos ctx)) ctx.m.mbreaks;
 		List.iter (fun f -> f (current_pos ctx)) ctx.m.mbreaks;

+ 8 - 5
src/generators/hlopt.ml

@@ -947,8 +947,8 @@ let _optimize (f:fundecl) =
 				(* loop : first pass does not recurse, second pass uses cache *)
 				(* loop : first pass does not recurse, second pass uses cache *)
 				if b2.bloop && b2.bstart < b.bstart then (match b2.bneed_all with None -> acc | Some s -> ISet.union acc s) else
 				if b2.bloop && b2.bstart < b.bstart then (match b2.bneed_all with None -> acc | Some s -> ISet.union acc s) else
 				ISet.union acc (live b2)
 				ISet.union acc (live b2)
-			) ISet.empty b.bnext in
-			let need_sub = ISet.filter (fun r ->
+			) ISet.empty in
+			let need_sub bl = ISet.filter (fun r ->
 				try
 				try
 					let w = PMap.find r b.bwrite in
 					let w = PMap.find r b.bwrite in
 					set_live r (w + 1) b.bend;
 					set_live r (w + 1) b.bend;
@@ -956,8 +956,8 @@ let _optimize (f:fundecl) =
 				with Not_found ->
 				with Not_found ->
 					set_live r b.bstart b.bend;
 					set_live r b.bstart b.bend;
 					true
 					true
-			) need_sub in
-			let need = ISet.union b.bneed need_sub in
+			) (need_sub bl) in
+			let need = ISet.union b.bneed (need_sub b.bnext) in
 			b.bneed_all <- Some need;
 			b.bneed_all <- Some need;
 			if b.bloop then begin
 			if b.bloop then begin
 				(*
 				(*
@@ -974,8 +974,11 @@ let _optimize (f:fundecl) =
 				in
 				in
 				List.iter (fun b2 -> if b2.bstart > b.bstart then clear b2) b.bprev;
 				List.iter (fun b2 -> if b2.bstart > b.bstart then clear b2) b.bprev;
 				List.iter (fun b -> ignore(live b)) b.bnext;
 				List.iter (fun b -> ignore(live b)) b.bnext;
+				(* do-while loop : recompute self after recompute all next *)
+				let need = ISet.union b.bneed (need_sub b.bnext) in
+				b.bneed_all <- Some need;
 			end;
 			end;
-			need
+			Option.get b.bneed_all
 	in
 	in
 	ignore(live root);
 	ignore(live root);
 
 

+ 2 - 3
src/optimization/analyzerTexpr.ml

@@ -1069,12 +1069,11 @@ module Cleanup = struct
 							| TLocal v when IntMap.mem v.v_id !locals -> true
 							| TLocal v when IntMap.mem v.v_id !locals -> true
 							| _ -> check_expr references_local e
 							| _ -> check_expr references_local e
 						in
 						in
-						let can_do = match com.platform with Hl -> false | _ -> true in
 						let rec loop2 el = match el with
 						let rec loop2 el = match el with
-							| [{eexpr = TBreak}] when is_true_expr e1 && can_do && not has_continue ->
+							| [{eexpr = TBreak}] when is_true_expr e1 && not has_continue ->
 								do_while := Some (Texpr.Builder.make_bool com.basic true e1.epos);
 								do_while := Some (Texpr.Builder.make_bool com.basic true e1.epos);
 								[]
 								[]
-							| [{eexpr = TIf(econd,{eexpr = TBlock[{eexpr = TBreak}]},None)}] when is_true_expr e1 && not (references_local econd) && can_do && not has_continue ->
+							| [{eexpr = TIf(econd,{eexpr = TBlock[{eexpr = TBreak}]},None)}] when is_true_expr e1 && not (references_local econd) && not has_continue ->
 								do_while := Some econd;
 								do_while := Some econd;
 								[]
 								[]
 							| {eexpr = TBreak | TContinue | TReturn _ | TThrow _} as e :: el ->
 							| {eexpr = TBreak | TContinue | TReturn _ | TThrow _} as e :: el ->