aboutsummaryrefslogtreecommitdiffstats
path: root/lib/hipe/sparc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/hipe/sparc')
-rw-r--r--lib/hipe/sparc/Makefile3
-rw-r--r--lib/hipe/sparc/hipe_rtl_to_sparc.erl22
-rw-r--r--lib/hipe/sparc/hipe_sparc_cfg.erl1
-rw-r--r--lib/hipe/sparc/hipe_sparc_defuse.erl13
-rw-r--r--lib/hipe/sparc/hipe_sparc_frame.erl65
-rw-r--r--lib/hipe/sparc/hipe_sparc_main.erl8
-rw-r--r--lib/hipe/sparc/hipe_sparc_ra.erl37
-rw-r--r--lib/hipe/sparc/hipe_sparc_ra_finalise.erl11
-rw-r--r--lib/hipe/sparc/hipe_sparc_ra_ls.erl36
-rw-r--r--lib/hipe/sparc/hipe_sparc_ra_naive.erl10
-rw-r--r--lib/hipe/sparc/hipe_sparc_ra_postconditions.erl21
-rw-r--r--lib/hipe/sparc/hipe_sparc_ra_postconditions_fp.erl18
-rw-r--r--lib/hipe/sparc/hipe_sparc_registers.erl2
-rw-r--r--lib/hipe/sparc/hipe_sparc_subst.erl85
14 files changed, 232 insertions, 100 deletions
diff --git a/lib/hipe/sparc/Makefile b/lib/hipe/sparc/Makefile
index 0e36a43d8e..ac1230df7c 100644
--- a/lib/hipe/sparc/Makefile
+++ b/lib/hipe/sparc/Makefile
@@ -63,7 +63,8 @@ MODULES=hipe_rtl_to_sparc \
hipe_sparc_ra_naive \
hipe_sparc_ra_postconditions \
hipe_sparc_ra_postconditions_fp \
- hipe_sparc_registers
+ hipe_sparc_registers \
+ hipe_sparc_subst
HRL_FILES=hipe_sparc.hrl
ERL_FILES=$(MODULES:%=%.erl)
diff --git a/lib/hipe/sparc/hipe_rtl_to_sparc.erl b/lib/hipe/sparc/hipe_rtl_to_sparc.erl
index f9c043eafe..e170fec3d6 100644
--- a/lib/hipe/sparc/hipe_rtl_to_sparc.erl
+++ b/lib/hipe/sparc/hipe_rtl_to_sparc.erl
@@ -625,7 +625,7 @@ conv_return(I, Map, Data) ->
{I2, Map0, Data}.
conv_store(I, Map, Data) ->
- {Base1, Map0} = conv_dst(hipe_rtl:store_base(I), Map), % no immediates allowed
+ {Base1, Map0} = conv_src(hipe_rtl:store_base(I), Map),
{Src, Map1} = conv_src(hipe_rtl:store_src(I), Map0),
{Base2, Map2} = conv_src(hipe_rtl:store_offset(I), Map1),
StOp = conv_stop(hipe_rtl:store_size(I)),
@@ -649,13 +649,27 @@ mk_store(StOp, Src, Base1, Base2) ->
end.
mk_store2(StOp, Src, Base1, Base2) ->
- case hipe_sparc:is_temp(Base2) of
+ case hipe_sparc:is_temp(Base1) of
true ->
- mk_store_rr(StOp, Src, Base1, Base2);
+ case hipe_sparc:is_temp(Base2) of
+ true ->
+ mk_store_rr(StOp, Src, Base1, Base2);
+ _ ->
+ mk_store_ri(StOp, Src, Base1, Base2)
+ end;
_ ->
- mk_store_ri(StOp, Src, Base1, Base2)
+ case hipe_sparc:is_temp(Base2) of
+ true ->
+ mk_store_ri(StOp, Src, Base2, Base1);
+ _ ->
+ mk_store_ii(StOp, Src, Base1, Base2)
+ end
end.
+mk_store_ii(StOp, Src, Base, Disp) ->
+ Tmp = new_untagged_temp(),
+ mk_set(Base, Tmp, mk_store_ri(StOp, Src, Tmp, Disp)).
+
mk_store_ri(StOp, Src, Base, Disp) ->
hipe_sparc:mk_store(StOp, Src, Base, Disp, 'new', []).
diff --git a/lib/hipe/sparc/hipe_sparc_cfg.erl b/lib/hipe/sparc/hipe_sparc_cfg.erl
index 0b2c77f27b..957c8a0d24 100644
--- a/lib/hipe/sparc/hipe_sparc_cfg.erl
+++ b/lib/hipe/sparc/hipe_sparc_cfg.erl
@@ -24,6 +24,7 @@
-export([init/1,
labels/1, start_label/1,
succ/2,
+ map_bbs/2, fold_bbs/3,
bb/2, bb_add/3]).
-export([postorder/1, reverse_postorder/1]).
-export([linearise/1]).
diff --git a/lib/hipe/sparc/hipe_sparc_defuse.erl b/lib/hipe/sparc/hipe_sparc_defuse.erl
index 4f66299f1d..4b5a19a19d 100644
--- a/lib/hipe/sparc/hipe_sparc_defuse.erl
+++ b/lib/hipe/sparc/hipe_sparc_defuse.erl
@@ -23,6 +23,7 @@
-export([insn_def_all/1, insn_use_all/1]).
-export([insn_def_gpr/1, insn_use_gpr/1]).
-export([insn_def_fpr/1, insn_use_fpr/1]).
+-export([insn_defs_all_gpr/1, insn_defs_all_fpr/1]).
-include("hipe_sparc.hrl").
%%%
@@ -51,6 +52,12 @@ insn_def_gpr(I) ->
_ -> []
end.
+insn_defs_all_gpr(I) ->
+ case I of
+ #pseudo_call{} -> true;
+ _ -> false
+ end.
+
call_clobbered_gpr() ->
[hipe_sparc:mk_temp(R, T)
|| {R,T} <- hipe_sparc_registers:call_clobbered() ++ all_fp_pseudos()].
@@ -115,6 +122,12 @@ insn_def_fpr(I) ->
_ -> []
end.
+insn_defs_all_fpr(I) ->
+ case I of
+ #pseudo_call{} -> true;
+ _ -> false
+ end.
+
call_clobbered_fpr() ->
[hipe_sparc:mk_temp(R, 'double') || R <- hipe_sparc_registers:allocatable_fpr()].
diff --git a/lib/hipe/sparc/hipe_sparc_frame.erl b/lib/hipe/sparc/hipe_sparc_frame.erl
index a42c1983f4..37f29e660a 100644
--- a/lib/hipe/sparc/hipe_sparc_frame.erl
+++ b/lib/hipe/sparc/hipe_sparc_frame.erl
@@ -25,16 +25,14 @@
-include("hipe_sparc.hrl").
-include("../rtl/hipe_literals.hrl").
-frame(Defun) ->
- Formals = fix_formals(hipe_sparc:defun_formals(Defun)),
- Temps0 = all_temps(hipe_sparc:defun_code(Defun), Formals),
- MinFrame = defun_minframe(Defun),
+frame(CFG) ->
+ Formals = fix_formals(hipe_sparc_cfg:params(CFG)),
+ Temps0 = all_temps(CFG, Formals),
+ MinFrame = defun_minframe(CFG),
Temps = ensure_minframe(MinFrame, Temps0),
- ClobbersRA = clobbers_ra(hipe_sparc:defun_code(Defun)),
- CFG0 = hipe_sparc_cfg:init(Defun),
- Liveness = hipe_sparc_liveness_all:analyse(CFG0),
- CFG1 = do_body(CFG0, Liveness, Formals, Temps, ClobbersRA),
- hipe_sparc_cfg:linearise(CFG1).
+ ClobbersRA = clobbers_ra(CFG),
+ Liveness = hipe_sparc_liveness_all:analyse(CFG),
+ do_body(CFG, Liveness, Formals, Temps, ClobbersRA).
fix_formals(Formals) ->
fix_formals(hipe_sparc_registers:nr_args(), Formals).
@@ -550,29 +548,41 @@ temp_is_pseudo(Temp) ->
%%% Detect if a Defun's body clobbers RA.
%%%
-clobbers_ra(Insns) ->
- case Insns of
- [#pseudo_call{}|_] -> true;
- %% moves to RA cannot occur yet
- [_|Rest] -> clobbers_ra(Rest);
- [] -> false
+clobbers_ra(CFG) ->
+ any_insn(fun(#pseudo_call{}) -> true;
+ (_) -> false
+ end, CFG).
+
+any_insn(Pred, CFG) ->
+ %% Abuse fold to do an efficient "any"-operation using nonlocal control flow
+ FoundSatisfying = make_ref(),
+ try fold_insns(fun (I, _) ->
+ case Pred(I) of
+ true -> throw(FoundSatisfying);
+ false -> false
+ end
+ end, false, CFG)
+ of _ -> false
+ catch FoundSatisfying -> true
end.
%%%
%%% Build the set of all temps used in a Defun's body.
%%%
-all_temps(Code, Formals) ->
- S0 = find_temps(Code, tset_empty()),
+all_temps(CFG, Formals) ->
+ S0 = fold_insns(fun find_temps/2, tset_empty(), CFG),
S1 = tset_del_list(S0, Formals),
tset_filter(S1, fun(T) -> temp_is_pseudo(T) end).
-find_temps([I|Insns], S0) ->
+find_temps(I, S0) ->
S1 = tset_add_list(S0, hipe_sparc_defuse:insn_def_all(I)),
- S2 = tset_add_list(S1, hipe_sparc_defuse:insn_use_all(I)),
- find_temps(Insns, S2);
-find_temps([], S) ->
- S.
+ tset_add_list(S1, hipe_sparc_defuse:insn_use_all(I)).
+
+fold_insns(Fun, InitAcc, CFG) ->
+ hipe_sparc_cfg:fold_bbs(
+ fun(_, BB, Acc0) -> lists:foldl(Fun, Acc0, hipe_bb:code(BB)) end,
+ InitAcc, CFG).
tset_empty() ->
gb_sets:new().
@@ -601,16 +611,11 @@ tset_to_list(S) ->
%%% in the middle of a tailcall.
%%%
-defun_minframe(Defun) ->
- MaxTailArity = body_mta(hipe_sparc:defun_code(Defun), 0),
- MyArity = length(fix_formals(hipe_sparc:defun_formals(Defun))),
+defun_minframe(CFG) ->
+ MaxTailArity = fold_insns(fun insn_mta/2, 0, CFG),
+ MyArity = length(fix_formals(hipe_sparc_cfg:params(CFG))),
erlang:max(MaxTailArity - MyArity, 0).
-body_mta([I|Code], MTA) ->
- body_mta(Code, insn_mta(I, MTA));
-body_mta([], MTA) ->
- MTA.
-
insn_mta(I, MTA) ->
case I of
#pseudo_tailcall{arity=Arity} ->
diff --git a/lib/hipe/sparc/hipe_sparc_main.erl b/lib/hipe/sparc/hipe_sparc_main.erl
index c16751c7bd..8e9c560bb2 100644
--- a/lib/hipe/sparc/hipe_sparc_main.erl
+++ b/lib/hipe/sparc/hipe_sparc_main.erl
@@ -24,12 +24,14 @@
rtl_to_sparc(MFA, RTL, Options) ->
Defun1 = hipe_rtl_to_sparc:translate(RTL),
+ CFG1 = hipe_sparc_cfg:init(Defun1),
%% io:format("~w: after translate\n", [?MODULE]),
%% hipe_sparc_pp:pp(Defun1),
- Defun2 = hipe_sparc_ra:ra(Defun1, Options),
+ CFG2 = hipe_sparc_ra:ra(CFG1, Options),
%% io:format("~w: after regalloc\n", [?MODULE]),
- %% hipe_sparc_pp:pp(Defun2),
- Defun3 = hipe_sparc_frame:frame(Defun2),
+ %% hipe_sparc_pp:pp(hipe_sparc_cfg:linearise(CFG2)),
+ CFG3 = hipe_sparc_frame:frame(CFG2),
+ Defun3 = hipe_sparc_cfg:linearise(CFG3),
%% io:format("~w: after frame\n", [?MODULE]),
%% hipe_sparc_pp:pp(Defun3),
Defun4 = hipe_sparc_finalise:finalise(Defun3),
diff --git a/lib/hipe/sparc/hipe_sparc_ra.erl b/lib/hipe/sparc/hipe_sparc_ra.erl
index afea8c9b4c..c4b909528d 100644
--- a/lib/hipe/sparc/hipe_sparc_ra.erl
+++ b/lib/hipe/sparc/hipe_sparc_ra.erl
@@ -22,36 +22,39 @@
-module(hipe_sparc_ra).
-export([ra/2]).
-ra(Defun0, Options) ->
- %% hipe_sparc_pp:pp(Defun0),
- {Defun1, Coloring_fp, SpillIndex}
+ra(CFG0, Options) ->
+ %% hipe_sparc_pp:pp(hipe_sparc_cfg:linearise(CFG0)),
+ {CFG1, _FPLiveness1, Coloring_fp, SpillIndex}
= case proplists:get_bool(inline_fp, Options) of
true ->
- hipe_regalloc_loop:ra_fp(Defun0, Options,
+ FPLiveness0 = hipe_sparc_specific_fp:analyze(CFG0, no_context),
+ hipe_regalloc_loop:ra_fp(CFG0, FPLiveness0, Options,
hipe_coalescing_regalloc,
- hipe_sparc_specific_fp);
+ hipe_sparc_specific_fp, no_context);
false ->
- {Defun0,[],0}
+ {CFG0,undefined,[],0}
end,
- %% hipe_sparc_pp:pp(Defun1),
- {Defun2, Coloring}
+ %% hipe_sparc_pp:pp(hipe_sparc_cfg:linearise(CFG1)),
+ GPLiveness1 = hipe_sparc_specific:analyze(CFG1, no_context),
+ {CFG2, _GPLiveness2, Coloring}
= case proplists:get_value(regalloc, Options, coalescing) of
coalescing ->
- ra(Defun1, SpillIndex, Options, hipe_coalescing_regalloc);
+ ra(CFG1, GPLiveness1, SpillIndex, Options, hipe_coalescing_regalloc);
optimistic ->
- ra(Defun1, SpillIndex, Options, hipe_optimistic_regalloc);
+ ra(CFG1, GPLiveness1, SpillIndex, Options, hipe_optimistic_regalloc);
graph_color ->
- ra(Defun1, SpillIndex, Options, hipe_graph_coloring_regalloc);
+ ra(CFG1, GPLiveness1, SpillIndex, Options, hipe_graph_coloring_regalloc);
linear_scan ->
- hipe_sparc_ra_ls:ra(Defun1, SpillIndex, Options);
+ hipe_sparc_ra_ls:ra(CFG1, GPLiveness1, SpillIndex, Options);
naive ->
- hipe_sparc_ra_naive:ra(Defun1, Coloring_fp, Options);
+ hipe_sparc_ra_naive:ra(CFG1, GPLiveness1, Coloring_fp, Options);
_ ->
exit({unknown_regalloc_compiler_option,
proplists:get_value(regalloc,Options)})
end,
- %% hipe_sparc_pp:pp(Defun2),
- hipe_sparc_ra_finalise:finalise(Defun2, Coloring, Coloring_fp).
+ %% hipe_sparc_pp:pp(hipe_sparc_cfg:linearise(CFG2)),
+ hipe_sparc_ra_finalise:finalise(CFG2, Coloring, Coloring_fp).
-ra(Defun, SpillIndex, Options, RegAllocMod) ->
- hipe_regalloc_loop:ra(Defun, SpillIndex, Options, RegAllocMod, hipe_sparc_specific).
+ra(CFG, Liveness, SpillIndex, Options, RegAllocMod) ->
+ hipe_regalloc_loop:ra(CFG, Liveness, SpillIndex, Options, RegAllocMod,
+ hipe_sparc_specific, no_context).
diff --git a/lib/hipe/sparc/hipe_sparc_ra_finalise.erl b/lib/hipe/sparc/hipe_sparc_ra_finalise.erl
index dc1e69c101..5d6056071c 100644
--- a/lib/hipe/sparc/hipe_sparc_ra_finalise.erl
+++ b/lib/hipe/sparc/hipe_sparc_ra_finalise.erl
@@ -23,13 +23,14 @@
-export([finalise/3]).
-include("hipe_sparc.hrl").
-finalise(Defun, TempMap, FPMap0) ->
- Code = hipe_sparc:defun_code(Defun),
- {_, SpillLimit} = hipe_sparc:defun_var_range(Defun),
+finalise(CFG, TempMap, FPMap0) ->
+ {_, SpillLimit} = hipe_gensym:var_range(sparc),
Map = mk_ra_map(TempMap, SpillLimit),
FPMap1 = mk_ra_map_fp(FPMap0, SpillLimit),
- NewCode = ra_code(Code, Map, FPMap1, []),
- Defun#defun{code=NewCode}.
+ hipe_sparc_cfg:map_bbs(fun(_Lbl, BB) -> ra_bb(BB, Map, FPMap1) end, CFG).
+
+ra_bb(BB, Map, FpMap) ->
+ hipe_bb:code_update(BB, ra_code(hipe_bb:code(BB), Map, FpMap, [])).
ra_code([I|Insns], Map, FPMap, Accum) ->
ra_code(Insns, Map, FPMap, [ra_insn(I, Map, FPMap) | Accum]);
diff --git a/lib/hipe/sparc/hipe_sparc_ra_ls.erl b/lib/hipe/sparc/hipe_sparc_ra_ls.erl
index 19e7c92d2f..7019937737 100644
--- a/lib/hipe/sparc/hipe_sparc_ra_ls.erl
+++ b/lib/hipe/sparc/hipe_sparc_ra_ls.erl
@@ -21,37 +21,35 @@
%% Linear Scan register allocator for SPARC
-module(hipe_sparc_ra_ls).
--export([ra/3]).
+-export([ra/4]).
-ra(Defun, SpillIndex, Options) ->
- NewDefun = Defun, %% hipe_${ARCH}_ra_rename:rename(Defun,Options),
- CFG = hipe_sparc_cfg:init(NewDefun),
- SpillLimit = hipe_sparc_specific:number_of_temporaries(CFG),
- alloc(NewDefun, SpillIndex, SpillLimit, Options).
+ra(CFG, Liveness, SpillIndex, Options) ->
+ SpillLimit = hipe_sparc_specific:number_of_temporaries(CFG, no_context),
+ alloc(CFG, Liveness, SpillIndex, SpillLimit, Options).
-alloc(Defun, SpillIndex, SpillLimit, Options) ->
- CFG = hipe_sparc_cfg:init(Defun),
+alloc(CFG, Liveness, SpillIndex, SpillLimit, Options) ->
{Coloring, _NewSpillIndex} =
regalloc(
- CFG,
+ CFG, Liveness,
hipe_sparc_registers:allocatable_gpr()--
[hipe_sparc_registers:temp3(),
hipe_sparc_registers:temp2(),
hipe_sparc_registers:temp1()],
[hipe_sparc_cfg:start_label(CFG)],
SpillIndex, SpillLimit, Options,
- hipe_sparc_specific),
- {NewDefun, _DidSpill} =
+ hipe_sparc_specific, no_context),
+ {NewCFG, _DidSpill} =
hipe_sparc_ra_postconditions:check_and_rewrite(
- Defun, Coloring, 'linearscan'),
- TempMap = hipe_temp_map:cols2tuple(Coloring, hipe_sparc_specific),
+ CFG, Coloring, 'linearscan'),
+ TempMap = hipe_temp_map:cols2tuple(Coloring, hipe_sparc_specific, no_context),
{TempMap2,_NewSpillIndex2} =
- hipe_spillmin:stackalloc(CFG, [], SpillIndex, Options,
- hipe_sparc_specific, TempMap),
+ hipe_spillmin:stackalloc(CFG, Liveness, [], SpillIndex, Options,
+ hipe_sparc_specific, no_context, TempMap),
Coloring2 =
hipe_spillmin:mapmerge(hipe_temp_map:to_substlist(TempMap), TempMap2),
- {NewDefun, Coloring2}.
+ {NewCFG, Liveness, Coloring2}.
-regalloc(CFG, PhysRegs, Entrypoints, SpillIndex, DontSpill, Options, Target) ->
- hipe_ls_regalloc:regalloc(
- CFG, PhysRegs, Entrypoints, SpillIndex, DontSpill, Options, Target).
+regalloc(CFG, Liveness, PhysRegs, Entrypoints, SpillIndex, DontSpill, Options,
+ TgtMod, TgtCtx) ->
+ hipe_ls_regalloc:regalloc(CFG, Liveness, PhysRegs, Entrypoints, SpillIndex,
+ DontSpill, Options, TgtMod, TgtCtx).
diff --git a/lib/hipe/sparc/hipe_sparc_ra_naive.erl b/lib/hipe/sparc/hipe_sparc_ra_naive.erl
index b6c33dec6c..745e44f2f9 100644
--- a/lib/hipe/sparc/hipe_sparc_ra_naive.erl
+++ b/lib/hipe/sparc/hipe_sparc_ra_naive.erl
@@ -20,11 +20,11 @@
%%
-module(hipe_sparc_ra_naive).
--export([ra/3]).
+-export([ra/4]).
-include("hipe_sparc.hrl").
-ra(Defun, _Coloring_fp, _Options) -> % -> {Defun, Coloring}
- {NewDefun,_DidSpill} =
- hipe_sparc_ra_postconditions:check_and_rewrite2(Defun, [], 'naive'),
- {NewDefun, []}.
+ra(CFG, Liveness, _Coloring_fp, _Options) -> % -> {CFG, Liveness, Coloring}
+ {NewCFG,_DidSpill} =
+ hipe_sparc_ra_postconditions:check_and_rewrite2(CFG, [], 'naive'),
+ {NewCFG, Liveness, []}.
diff --git a/lib/hipe/sparc/hipe_sparc_ra_postconditions.erl b/lib/hipe/sparc/hipe_sparc_ra_postconditions.erl
index ab31b3c8d9..e8e231e35c 100644
--- a/lib/hipe/sparc/hipe_sparc_ra_postconditions.erl
+++ b/lib/hipe/sparc/hipe_sparc_ra_postconditions.erl
@@ -25,17 +25,13 @@
-include("hipe_sparc.hrl").
-check_and_rewrite(Defun, Coloring, Allocator) ->
- TempMap = hipe_temp_map:cols2tuple(Coloring, hipe_sparc_specific),
- check_and_rewrite2(Defun, TempMap, Allocator).
+check_and_rewrite(CFG, Coloring, Allocator) ->
+ TempMap = hipe_temp_map:cols2tuple(Coloring, hipe_sparc_specific, no_context),
+ check_and_rewrite2(CFG, TempMap, Allocator).
-check_and_rewrite2(Defun, TempMap, Allocator) ->
+check_and_rewrite2(CFG, TempMap, Allocator) ->
Strategy = strategy(Allocator),
- #defun{code=Code0} = Defun,
- {Code1,DidSpill} = do_insns(Code0, TempMap, Strategy, [], false),
- VarRange = {0, hipe_gensym:get_var(sparc)},
- {Defun#defun{code=Code1, var_range=VarRange},
- DidSpill}.
+ do_bbs(hipe_sparc_cfg:labels(CFG), TempMap, Strategy, CFG, false).
strategy(Allocator) ->
case Allocator of
@@ -44,6 +40,13 @@ strategy(Allocator) ->
'naive' -> 'fixed'
end.
+do_bbs([], _, _, CFG, DidSpill) -> {CFG, DidSpill};
+do_bbs([Lbl|Lbls], TempMap, Strategy, CFG0, DidSpill0) ->
+ Code0 = hipe_bb:code(BB = hipe_sparc_cfg:bb(CFG0, Lbl)),
+ {Code, DidSpill} = do_insns(Code0, TempMap, Strategy, [], DidSpill0),
+ CFG = hipe_sparc_cfg:bb_add(CFG0, Lbl, hipe_bb:code_update(BB, Code)),
+ do_bbs(Lbls, TempMap, Strategy, CFG, DidSpill).
+
do_insns([I|Insns], TempMap, Strategy, Accum, DidSpill0) ->
{NewIs, DidSpill1} = do_insn(I, TempMap, Strategy),
do_insns(Insns, TempMap, Strategy, lists:reverse(NewIs, Accum), DidSpill0 or DidSpill1);
diff --git a/lib/hipe/sparc/hipe_sparc_ra_postconditions_fp.erl b/lib/hipe/sparc/hipe_sparc_ra_postconditions_fp.erl
index d893ac26e9..544b8b05a8 100644
--- a/lib/hipe/sparc/hipe_sparc_ra_postconditions_fp.erl
+++ b/lib/hipe/sparc/hipe_sparc_ra_postconditions_fp.erl
@@ -25,13 +25,17 @@
-include("hipe_sparc.hrl").
-check_and_rewrite(Defun, Coloring) ->
- TempMap = hipe_temp_map:cols2tuple(Coloring, hipe_sparc_specific_fp),
- #defun{code=Code0} = Defun,
- {Code1,DidSpill} = do_insns(Code0, TempMap, [], false),
- VarRange = {0, hipe_gensym:get_var(sparc)},
- {Defun#defun{code=Code1, var_range=VarRange},
- DidSpill}.
+check_and_rewrite(CFG, Coloring) ->
+ TempMap = hipe_temp_map:cols2tuple(Coloring, hipe_sparc_specific_fp,
+ no_context),
+ do_bbs(hipe_sparc_cfg:labels(CFG), TempMap, CFG, false).
+
+do_bbs([], _TempMap, CFG, DidSpill) -> {CFG, DidSpill};
+do_bbs([Lbl|Lbls], TempMap, CFG0, DidSpill0) ->
+ Code0 = hipe_bb:code(BB = hipe_sparc_cfg:bb(CFG0, Lbl)),
+ {Code, DidSpill} = do_insns(Code0, TempMap, [], DidSpill0),
+ CFG = hipe_sparc_cfg:bb_add(CFG0, Lbl, hipe_bb:code_update(BB, Code)),
+ do_bbs(Lbls, TempMap, CFG, DidSpill).
do_insns([I|Insns], TempMap, Accum, DidSpill0) ->
{NewIs, DidSpill1} = do_insn(I, TempMap),
diff --git a/lib/hipe/sparc/hipe_sparc_registers.erl b/lib/hipe/sparc/hipe_sparc_registers.erl
index 6681a10070..20138836dd 100644
--- a/lib/hipe/sparc/hipe_sparc_registers.erl
+++ b/lib/hipe/sparc/hipe_sparc_registers.erl
@@ -249,6 +249,8 @@ is_arg(R) ->
_ -> false
end.
+%% Note: the fact that allocatable_gpr() is a subset of call_clobbered() is
+%% hard-coded in hipe_sparc_defuse:insn_defs_all_gpr/1
call_clobbered() -> % does the RA strip the type or not?
[%% ?G0 is the non-allocatable constant zero
{?G1,tagged},{?G1,untagged},
diff --git a/lib/hipe/sparc/hipe_sparc_subst.erl b/lib/hipe/sparc/hipe_sparc_subst.erl
new file mode 100644
index 0000000000..e5cd244985
--- /dev/null
+++ b/lib/hipe/sparc/hipe_sparc_subst.erl
@@ -0,0 +1,85 @@
+%% -*- erlang-indent-level: 2 -*-
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2016. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(hipe_sparc_subst).
+-export([insn_temps/2]).
+-include("hipe_sparc.hrl").
+
+%% These should be moved to hipe_sparc and exported
+-type temp() :: #sparc_temp{}.
+-type src2() :: temp() | #sparc_simm13{}.
+-type src2b() :: src2() | #sparc_uimm5{}.
+-type funv() :: #sparc_mfa{} | #sparc_prim{} | temp().
+-type arg() :: temp() | integer().
+-type insn() :: tuple(). % for now
+
+-type subst_fun() :: fun((temp()) -> temp()).
+
+%% @doc Maps over the temporaries in an instruction
+-spec insn_temps(subst_fun(), insn()) -> insn().
+insn_temps(T, I) ->
+ S2 = fun(O) -> src2_temps(T, O) end,
+ S2B = fun(O) -> src2b_temps(T, O) end,
+ Arg = fun(O) -> arg_temps(T, O) end,
+ case I of
+ #alu{src1=L,src2=R,dst=D} -> I#alu{src1=T(L),src2=S2B(R),dst=T(D)};
+ #bp{} -> I;
+ #comment{} -> I;
+ #jmp{src1=L,src2=R} -> I#jmp{src1=T(L),src2=S2(R)};
+ #label{} -> I;
+ #pseudo_bp{} -> I;
+ #pseudo_call{funv=F} -> I#pseudo_call{funv=funv_temps(T,F)};
+ #pseudo_call_prepare{} -> I;
+ #pseudo_move{src=S,dst=D} -> I#pseudo_move{src=T(S),dst=T(D)};
+ #pseudo_ret{} -> I;
+ #pseudo_set{dst=D}-> I#pseudo_set{dst=T(D)};
+ #pseudo_tailcall{funv=F,stkargs=Stk} ->
+ I#pseudo_tailcall{funv=funv_temps(T,F),stkargs=lists:map(Arg,Stk)};
+ #pseudo_tailcall_prepare{} -> I;
+ #rdy{dst=D} -> I#rdy{dst=T(D)};
+ #sethi{dst=D} -> I#sethi{dst=T(D)};
+ #store{src=S,base=B,disp=D} -> I#store{src=T(S),base=T(B),disp=S2(D)};
+ #fp_binary{src1=L,src2=R,dst=D} ->
+ I#fp_binary{src1=T(L),src2=T(R),dst=T(D)};
+ #fp_unary{src=S,dst=D} -> I#fp_unary{src=T(S),dst=T(D)};
+ #pseudo_fload{base=B,disp=Di,dst=Ds} ->
+ I#pseudo_fload{base=T(B),disp=S2(Di),dst=T(Ds)};
+ #pseudo_fmove{src=S,dst=D} -> I#pseudo_fmove{src=T(S),dst=T(D)};
+ #pseudo_fstore{src=S,base=B,disp=D} ->
+ I#pseudo_fstore{src=T(S),base=T(B),disp=S2(D)}
+ end.
+
+-spec src2_temps(subst_fun(), src2()) -> src2().
+src2_temps(_SubstTemp, I=#sparc_simm13{}) -> I;
+src2_temps(SubstTemp, T=#sparc_temp{}) -> SubstTemp(T).
+
+-spec src2b_temps(subst_fun(), src2b()) -> src2b().
+src2b_temps(_SubstTemp, I=#sparc_uimm5{}) -> I;
+src2b_temps(SubstTemp, Op) -> src2_temps(SubstTemp, Op).
+
+-spec funv_temps(subst_fun(), funv()) -> funv().
+funv_temps(_SubstTemp, M=#sparc_mfa{}) -> M;
+funv_temps(_SubstTemp, P=#sparc_prim{}) -> P;
+funv_temps(SubstTemp, T=#sparc_temp{}) -> SubstTemp(T).
+
+-spec arg_temps(subst_fun(), arg()) -> arg().
+arg_temps(_SubstTemp, Imm) when is_integer(Imm) -> Imm;
+arg_temps(SubstTemp, T=#sparc_temp{}) -> SubstTemp(T).