diff options
author | Magnus Lång <[email protected]> | 2016-06-22 19:10:55 +0200 |
---|---|---|
committer | Magnus Lång <[email protected]> | 2016-09-02 15:59:17 +0200 |
commit | 3f678056ab55ae4546c7943b894b70558e3eb26c (patch) | |
tree | f7503c88288709728d1e7f44244a50914135b18f | |
parent | 60b5deae9ca2cb3540c899b19151b7e3391d305d (diff) | |
download | otp-3f678056ab55ae4546c7943b894b70558e3eb26c.tar.gz otp-3f678056ab55ae4546c7943b894b70558e3eb26c.tar.bz2 otp-3f678056ab55ae4546c7943b894b70558e3eb26c.zip |
hipe_sparc: Add code rewrite RA callbacks
These will not only be useful for hipe_regalloc_prepass, but also, after
the introduction of a mk_move/2 (or similar) callback, for the purpose
of range splitting.
Since the substitution needed to case over all the instructions, a new
module, hipe_sparc_subst, was introduced to the sparc backend.
-rw-r--r-- | lib/hipe/main/hipe.app.src | 1 | ||||
-rw-r--r-- | lib/hipe/regalloc/hipe_sparc_specific.erl | 26 | ||||
-rw-r--r-- | lib/hipe/regalloc/hipe_sparc_specific_fp.erl | 26 | ||||
-rw-r--r-- | lib/hipe/sparc/Makefile | 3 | ||||
-rw-r--r-- | lib/hipe/sparc/hipe_sparc_subst.erl | 85 |
5 files changed, 140 insertions, 1 deletions
diff --git a/lib/hipe/main/hipe.app.src b/lib/hipe/main/hipe.app.src index 85b88a9735..d1d98c930d 100644 --- a/lib/hipe/main/hipe.app.src +++ b/lib/hipe/main/hipe.app.src @@ -197,6 +197,7 @@ hipe_sparc_registers, hipe_sparc_specific, hipe_sparc_specific_fp, + hipe_sparc_subst, hipe_spillcost, hipe_spillmin, hipe_spillmin_color, diff --git a/lib/hipe/regalloc/hipe_sparc_specific.erl b/lib/hipe/regalloc/hipe_sparc_specific.erl index 8a792a4fab..1cbfcd4dc7 100644 --- a/lib/hipe/regalloc/hipe_sparc_specific.erl +++ b/lib/hipe/regalloc/hipe_sparc_specific.erl @@ -53,6 +53,12 @@ %% callbacks for hipe_regalloc_loop -export([check_and_rewrite/2]). +%% callbacks for hipe_regalloc_prepass +-export([new_reg_nr/0, + update_reg_nr/2, + update_bb/3, + subst_temps/2]). + check_and_rewrite(CFG, Coloring) -> hipe_sparc_ra_postconditions:check_and_rewrite(CFG, Coloring, 'normal'). @@ -113,6 +119,9 @@ number_of_temporaries(_CFG) -> bb(CFG,L) -> hipe_sparc_cfg:bb(CFG,L). +update_bb(CFG,L,BB) -> + hipe_sparc_cfg:bb_add(CFG,L,BB). + %% SPARC stuff def_use(Instruction) -> @@ -145,6 +154,23 @@ is_move(Instruction) -> reg_nr(Reg) -> hipe_sparc:temp_reg(Reg). +new_reg_nr() -> + hipe_gensym:get_next_var(sparc). + +update_reg_nr(Nr, Temp) -> + hipe_sparc:mk_temp(Nr, hipe_sparc:temp_type(Temp)). + +subst_temps(SubstFun, Instr) -> + hipe_sparc_subst:insn_temps( + fun(Op) -> + case hipe_sparc:temp_is_allocatable(Op) + andalso hipe_sparc:temp_type(Op) =/= 'double' + of + true -> SubstFun(Op); + false -> Op + end + end, Instr). + %%% Linear Scan stuff new_spill_index(SpillIndex) when is_integer(SpillIndex) -> diff --git a/lib/hipe/regalloc/hipe_sparc_specific_fp.erl b/lib/hipe/regalloc/hipe_sparc_specific_fp.erl index 18f4a6b684..040e1346a4 100644 --- a/lib/hipe/regalloc/hipe_sparc_specific_fp.erl +++ b/lib/hipe/regalloc/hipe_sparc_specific_fp.erl @@ -53,6 +53,12 @@ %% callbacks for hipe_regalloc_loop -export([check_and_rewrite/2]). +%% callbacks for hipe_regalloc_prepass +-export([new_reg_nr/0, + update_reg_nr/2, + update_bb/3, + subst_temps/2]). + check_and_rewrite(CFG, Coloring) -> hipe_sparc_ra_postconditions_fp:check_and_rewrite(CFG, Coloring). @@ -106,6 +112,9 @@ number_of_temporaries(_CFG) -> bb(CFG, L) -> hipe_sparc_cfg:bb(CFG, L). +update_bb(CFG,L,BB) -> + hipe_sparc_cfg:bb_add(CFG,L,BB). + %% SPARC stuff def_use(I) -> @@ -126,6 +135,23 @@ is_move(I) -> reg_nr(Reg) -> hipe_sparc:temp_reg(Reg). +new_reg_nr() -> + hipe_gensym:get_next_var(sparc). + +update_reg_nr(Nr, _Temp) -> + hipe_sparc:mk_temp(Nr, 'double'). + +subst_temps(SubstFun, Instr) -> + hipe_sparc_subst:insn_temps( + fun(Op) -> + case hipe_sparc:temp_is_allocatable(Op) + andalso hipe_sparc:temp_type(Op) =:= 'double' + of + true -> SubstFun(Op); + false -> Op + end + end, Instr). + -ifdef(notdef). new_spill_index(SpillIndex)-> SpillIndex+1. 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_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). |