diff options
Diffstat (limited to 'lib/hipe')
-rw-r--r-- | lib/hipe/icode/hipe_icode.erl | 13 | ||||
-rw-r--r-- | lib/hipe/rtl/hipe_rtl.erl | 19 | ||||
-rw-r--r-- | lib/hipe/ssa/hipe_ssa.inc | 22 |
3 files changed, 43 insertions, 11 deletions
diff --git a/lib/hipe/icode/hipe_icode.erl b/lib/hipe/icode/hipe_icode.erl index 78508dff22..dce2fcb392 100644 --- a/lib/hipe/icode/hipe_icode.erl +++ b/lib/hipe/icode/hipe_icode.erl @@ -594,6 +594,7 @@ uses/1, defines/1, is_safe/1, + reduce_unused/1, strip_comments/1, subst/2, subst_uses/2, @@ -1765,6 +1766,18 @@ is_safe(Instr) -> #icode_end_try{} -> false end. +%% @doc Produces a simplified instruction sequence that is equivalent to [Instr] +%% under the assumption that all results of Instr are unused, or 'false' if +%% there is no such sequence (other than [Instr] itself). + +-spec reduce_unused(icode_instr()) -> false | [icode_instr()]. + +reduce_unused(Instr) -> + case is_safe(Instr) of + true -> []; + false -> false + end. + %%----------------------------------------------------------------------- -spec highest_var(icode_instrs()) -> non_neg_integer(). diff --git a/lib/hipe/rtl/hipe_rtl.erl b/lib/hipe/rtl/hipe_rtl.erl index e4e857ec43..d39969a0ed 100644 --- a/lib/hipe/rtl/hipe_rtl.erl +++ b/lib/hipe/rtl/hipe_rtl.erl @@ -334,6 +334,7 @@ defines/1, redirect_jmp/3, is_safe/1, + reduce_unused/1, %% highest_var/1, pp/1, pp/2, @@ -1314,6 +1315,24 @@ is_safe(Instr) -> #switch{} -> false %% Maybe this is safe... end. +%% @spec reduce_unused(rtl_instruction()) +%% -> false | [rtl_instruction()]. +%% +%% @doc Produces a simplified instruction sequence that is equivalent to [Instr] +%% under the assumption that all results of Instr are unused, or 'false' if +%% there is no such sequence (other than [Instr] itself). + +reduce_unused(Instr) -> + case Instr of + #alub{dst=Dst} when Dst =/= [] -> + [Instr#alub{dst=[]}]; + _ -> + case is_safe(Instr) of + true -> []; + false -> false + end + end. + %% %% True if argument is an alu-operator %% diff --git a/lib/hipe/ssa/hipe_ssa.inc b/lib/hipe/ssa/hipe_ssa.inc index 83ab320306..b511bb6f25 100644 --- a/lib/hipe/ssa/hipe_ssa.inc +++ b/lib/hipe/ssa/hipe_ssa.inc @@ -1,4 +1,4 @@ -%% -*- erlang-indent-level: 2 -*- +%% -*- mode: erlang; erlang-indent-level: 2 -*- %% %% %CopyrightBegin% %% @@ -943,9 +943,9 @@ do_code([Instr|Instrs], LiveOut, Changed, Acc) -> false -> do_code(Instrs, LiveIn, Changed, [Instr|Acc]); true -> - case ?CODE:is_safe(Instr) of + case ?CODE:is_call(Instr) of true -> - case ?CODE:is_call(Instr) of + case ?CODE:is_safe(Instr) of true -> case ?CODE:call_continuation(Instr) of [] -> @@ -955,11 +955,6 @@ do_code([Instr|Instrs], LiveOut, Changed, Acc) -> do_code(Instrs, LiveOut, true, [NewInstr|Acc]) end; false -> - do_code(Instrs, LiveOut, true, Acc) - end; - false -> %% not a safe instruction - cannot be removed - case ?CODE:is_call(Instr) of - true -> case ?CODE:call_dstlist(Instr) of [] -> %% result was not used anyway; no change do_code(Instrs, LiveIn, Changed, [Instr|Acc]); @@ -968,9 +963,14 @@ do_code([Instr|Instrs], LiveOut, Changed, Acc) -> do_code(Instrs, LiveIn, true, [NewInstr|Acc]); [_|_] -> %% calls with multiple dests are left untouched do_code(Instrs, LiveIn, Changed, [Instr|Acc]) - end; - false -> - do_code(Instrs, LiveIn, Changed, [Instr|Acc]) + end + end; + false -> + case ?CODE:reduce_unused(Instr) of + false -> % not a safe instruction - cannot be removed + do_code(Instrs, LiveIn, Changed, [Instr|Acc]); + Replacement -> + do_code(lists:reverse(Replacement, Instrs), LiveOut, true, Acc) end end end; |