From c4f52a50338bdde8f87a8c86c552b4d47e8eeb83 Mon Sep 17 00:00:00 2001 From: Yiannis Tsiouris Date: Fri, 11 Apr 2014 14:58:56 +0300 Subject: [PATCH] Simple refactor of hipe_llvm_liveness --- lib/hipe/llvm/hipe_llvm_liveness.erl | 90 ++++++++++++++-------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/lib/hipe/llvm/hipe_llvm_liveness.erl b/lib/hipe/llvm/hipe_llvm_liveness.erl index 4595f0642025..0876789c5c59 100644 --- a/lib/hipe/llvm/hipe_llvm_liveness.erl +++ b/lib/hipe/llvm/hipe_llvm_liveness.erl @@ -7,27 +7,25 @@ analyze(RtlCfg) -> Liveness = hipe_rtl_liveness:analyze(RtlCfg), Roots = find_roots(RtlCfg, Liveness), - %% erlang:display(Roots), NewRtlCfg = mark_dead_roots(RtlCfg, Liveness, Roots), {NewRtlCfg, Roots}. %% @doc Determine which are the GC Roots. Possible roots are all RTL variables %% (rtl_var). However, since function calls are the safe-points, we consider as %% possible GC roots only RTL variables that are live around function calls. -find_roots(Cfg, Liveness) -> - Labels = hipe_rtl_cfg:postorder(Cfg), - Roots = find_roots_bb(Labels, Cfg, Liveness, []), - lists:usort(lists:flatten(Roots)). +find_roots(CFG, Liveness) -> + Labels = hipe_rtl_cfg:postorder(CFG), + find_roots_bb(Labels, CFG, Liveness, []). -find_roots_bb([], _Cfg, _Liveness, RootAcc) -> - RootAcc; -find_roots_bb([L|Ls], Cfg, Liveness, RootAcc) -> - Block = hipe_rtl_cfg:bb(Cfg, L), +find_roots_bb([], _, _, RootAcc) -> + lists:usort(lists:flatten(RootAcc)); +find_roots_bb([L|Ls], CFG, Liveness, RootAcc) -> + Block = hipe_rtl_cfg:bb(CFG, L), BlockCode = hipe_bb:code(Block), LiveIn = ordsets:from_list(strip(hipe_rtl_liveness:livein(Liveness, L))), LiveOut = ordsets:from_list(strip(hipe_rtl_liveness:liveout(Liveness, L))), - Roots = do_find_roots_bb(BlockCode, L, LiveOut, LiveIn, []), - find_roots_bb(Ls, Cfg, Liveness, Roots ++ RootAcc). + Roots = do_find_roots_bb(BlockCode, L, LiveIn, LiveOut, []), + find_roots_bb(Ls, CFG, Liveness, [Roots|RootAcc]). %% For each call inside a BB the GC roots are those RTL variables that are live %% before and after the call. @@ -36,26 +34,26 @@ find_roots_bb([L|Ls], Cfg, Liveness, RootAcc) -> %% Live After Call: These are the RTL variables that belong to the LiveOut %% list or are used after the call inside the BB (they die inside the BB and so %% don't belong to the LiveOut list). -do_find_roots_bb([], _Label, _LiveOut, _LiveBefore, RootAcc) -> +do_find_roots_bb([], _, _, _, RootAcc) -> RootAcc; -do_find_roots_bb([I|Is], L, LiveOut, LiveBefore, RootAcc) -> +do_find_roots_bb([I|Is], L, LiveIn, LiveOut, RootAcc) -> case hipe_rtl:is_call(I) of true -> %% Used inside the BB after the call - UsedAfterCall_ = strip(lists:flatten([hipe_rtl:uses(V) || V <- Is])), - UsedAfterCall = ordsets:from_list(UsedAfterCall_), - LiveAfter = ordsets:union(UsedAfterCall, LiveOut), - %% The Actual Roots - Roots = ordsets:intersection(LiveBefore, LiveAfter), + UsedAfterCall = + ordsets:from_list(strip(lists:flatten([hipe_rtl:uses(V) || V <- Is]))), + LiveAfterCall = ordsets:union(UsedAfterCall, LiveOut), + %% The actual roots + Roots = ordsets:intersection(LiveIn, LiveAfterCall), %% The result of the instruction - Defines = ordsets:from_list(strip(hipe_rtl:defines(I))), - LiveBefore1 = ordsets:union(LiveBefore, Defines), - do_find_roots_bb(Is, L, LiveOut, LiveBefore1, [Roots|RootAcc]); + Defined = ordsets:from_list(strip(hipe_rtl:defines(I))), + LiveIn2 = ordsets:union(LiveIn, Defined), + do_find_roots_bb(Is, L, LiveIn2, LiveOut, [Roots|RootAcc]); false -> %% The result of the instruction - Defines = ordsets:from_list(strip(hipe_rtl:defines(I))), - LiveBefore1 = ordsets:union(LiveBefore, Defines), - do_find_roots_bb(Is, L, LiveOut, LiveBefore1, RootAcc) + Defined = ordsets:from_list(strip(hipe_rtl:defines(I))), + LiveIn2 = ordsets:union(LiveIn, Defined), + do_find_roots_bb(Is, L, LiveIn2, LiveOut, RootAcc) end. %% @doc This function is responsible for marking when GC Roots, which can only @@ -66,41 +64,43 @@ mark_dead_roots(CFG, Liveness, Roots) -> Labels = hipe_rtl_cfg:postorder(CFG), mark_dead_bb(Labels, CFG, Liveness, Roots). -mark_dead_bb([], Cfg, _Liveness, _Roots) -> - Cfg; -mark_dead_bb([L|Ls], Cfg, Liveness, Roots) -> - Block = hipe_rtl_cfg:bb(Cfg, L), +mark_dead_bb([], CFG, _, _) -> + CFG; +mark_dead_bb([L|Ls], CFG, Liveness, Roots) -> + Block = hipe_rtl_cfg:bb(CFG, L), BlockCode = hipe_bb:code(Block), + LiveIn = ordsets:from_list(strip(hipe_rtl_liveness:livein(Liveness, L))), LiveOut = ordsets:from_list(strip(hipe_rtl_liveness:liveout(Liveness, L))), NewBlockCode = do_mark_dead_bb(BlockCode, LiveOut, Roots, []), %% Update the CFG NewBB = hipe_bb:code_update(Block, NewBlockCode), - NewCFG = hipe_rtl_cfg:bb_add(Cfg, L, NewBB), + NewCFG = hipe_rtl_cfg:bb_add(CFG, L, NewBB), mark_dead_bb(Ls, NewCFG, Liveness, Roots). -do_mark_dead_bb([], _LiveOut, _Roots, NewBlockCode) -> +do_mark_dead_bb([], _, _, NewBlockCode) -> lists:reverse(NewBlockCode); -do_mark_dead_bb([I|Is], LiveOut ,Roots, NewBlockCode) -> - Uses = ordsets:from_list(strip(hipe_rtl:uses(I))), +do_mark_dead_bb([I|Is], LiveOut, Roots, NewBlockCode) -> + Used = ordsets:from_list(strip(hipe_rtl:uses(I))), %% GC roots that are used in this instruction - RootsUsed = ordsets:intersection(Roots, Uses), - UsedAfter_ = strip(lists:flatten([hipe_rtl:uses(V) || V <- Is])), - UsedAfter = ordsets:from_list(UsedAfter_), + RootsUsed = ordsets:intersection(Roots, Used), + UsedAfterInstr = + ordsets:from_list(strip(lists:flatten([hipe_rtl:uses(V) || V <- Is]))), %% GC roots that are live after this instruction - LiveAfter = ordsets:union(LiveOut, UsedAfter), + LiveAfterInstr = ordsets:union(LiveOut, UsedAfterInstr), %% GC roots that their last use is in this instruction - DeadRoots = ordsets:subtract(RootsUsed, LiveAfter), + DeadRoots = ordsets:subtract(RootsUsed, LiveAfterInstr), %% Re-create the RTL variable from the corresponding Index - OldVars = [hipe_rtl:mk_var(V1) || V1 <- DeadRoots], - %% Mark the RTL variable as DEAD (last use) - NewVars = [kill_var(V2) || V2 <- OldVars], + OldVars = [hipe_rtl:mk_var(V) || V <- DeadRoots], + %% Mark the RTL variable as 'dead' (last use) + NewVars = [kill_var(V) || V <- OldVars], %% Create a list with the substitution of the old vars with the new %% ones which are marked with the dead keyword - Subtitution = lists:zip(OldVars, NewVars), - NewI = case Subtitution of - [] -> I; - _ -> hipe_rtl:subst_uses_llvm(Subtitution, I) - end, + Substitution = lists:zip(OldVars, NewVars), + NewI = + case Substitution of + [] -> I; + _ -> hipe_rtl:subst_uses_llvm(Substitution, I) + end, do_mark_dead_bb(Is, LiveOut, Roots, [NewI|NewBlockCode]). %% Update the liveness of a var in order to mark that this is the last use.