aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorMagnus Lång <margnus1@telia.com>2016-06-20 18:26:39 +0200
committerMagnus Lång <margnus1@telia.com>2016-09-02 15:59:17 +0200
commit38c10d20f7b0a83f4d94a92d30ca649b86b0a7cb (patch)
treee9bc6081a91c43bc504a93217e9776c5f1d006d5 /lib
parent86eeae878efbbcfb12245cdab992bb39987f09bf (diff)
downloadotp-38c10d20f7b0a83f4d94a92d30ca649b86b0a7cb.tar.gz
otp-38c10d20f7b0a83f4d94a92d30ca649b86b0a7cb.tar.bz2
otp-38c10d20f7b0a83f4d94a92d30ca649b86b0a7cb.zip
hipe_x86: 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_x86_subst, was introduced to the x86 backend. Due to differences in the 'jtab' field of a #jmp_switch{} between x86 and amd64, it regrettably needed to be duplicated to hipe_amd64_subst.
Diffstat (limited to 'lib')
-rw-r--r--lib/hipe/amd64/Makefile1
-rw-r--r--lib/hipe/amd64/hipe_amd64_subst.erl21
-rw-r--r--lib/hipe/main/hipe.app.src2
-rw-r--r--lib/hipe/regalloc/hipe_amd64_specific_sse2.erl26
-rw-r--r--lib/hipe/regalloc/hipe_x86_specific.erl28
-rw-r--r--lib/hipe/x86/Makefile1
-rw-r--r--lib/hipe/x86/hipe_x86_subst.erl94
7 files changed, 173 insertions, 0 deletions
diff --git a/lib/hipe/amd64/Makefile b/lib/hipe/amd64/Makefile
index ea3559b7e6..617f6749ac 100644
--- a/lib/hipe/amd64/Makefile
+++ b/lib/hipe/amd64/Makefile
@@ -59,6 +59,7 @@ MODULES=hipe_amd64_assemble \
hipe_amd64_ra_sse2_postconditions \
hipe_amd64_registers \
hipe_amd64_spill_restore \
+ hipe_amd64_subst \
hipe_amd64_x87 \
hipe_amd64_sse2 \
hipe_rtl_to_amd64
diff --git a/lib/hipe/amd64/hipe_amd64_subst.erl b/lib/hipe/amd64/hipe_amd64_subst.erl
new file mode 100644
index 0000000000..7d0f06684b
--- /dev/null
+++ b/lib/hipe/amd64/hipe_amd64_subst.erl
@@ -0,0 +1,21 @@
+%%
+%% %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%
+%%
+
+-include("../x86/hipe_x86_subst.erl").
diff --git a/lib/hipe/main/hipe.app.src b/lib/hipe/main/hipe.app.src
index e4796368c3..39b249de15 100644
--- a/lib/hipe/main/hipe.app.src
+++ b/lib/hipe/main/hipe.app.src
@@ -55,6 +55,7 @@
hipe_amd64_specific_x87,
hipe_amd64_spill_restore,
hipe_amd64_sse2,
+ hipe_amd64_subst,
hipe_amd64_x87,
hipe_arm,
hipe_arm_assemble,
@@ -222,6 +223,7 @@
hipe_x86_specific,
hipe_x86_specific_x87,
hipe_x86_spill_restore,
+ hipe_x86_subst,
hipe_x86_x87]},
{registered,[]},
{applications, [kernel,stdlib]},
diff --git a/lib/hipe/regalloc/hipe_amd64_specific_sse2.erl b/lib/hipe/regalloc/hipe_amd64_specific_sse2.erl
index 35d19ef1df..dec7c1734d 100644
--- a/lib/hipe/regalloc/hipe_amd64_specific_sse2.erl
+++ b/lib/hipe/regalloc/hipe_amd64_specific_sse2.erl
@@ -57,6 +57,12 @@
-export([check_and_rewrite/2,
check_and_rewrite/3]).
+%% callbacks for hipe_regalloc_prepass
+-export([new_reg_nr/0,
+ update_reg_nr/2,
+ update_bb/3,
+ subst_temps/2]).
+
%%----------------------------------------------------------------------------
-include("../flow/cfg.hrl").
@@ -150,6 +156,9 @@ number_of_temporaries(_CFG) ->
bb(CFG, L) ->
hipe_x86_cfg:bb(CFG, L).
+update_bb(CFG,L,BB) ->
+ hipe_x86_cfg:bb_add(CFG,L,BB).
+
%% AMD64 stuff
def_use(Instruction) ->
@@ -186,6 +195,23 @@ is_move(Instruction) ->
reg_nr(Reg) ->
hipe_x86:temp_reg(Reg).
+new_reg_nr() ->
+ hipe_gensym:get_next_var(x86).
+
+update_reg_nr(Nr, _Temp) ->
+ hipe_x86:mk_temp(Nr, 'double').
+
+subst_temps(SubstFun, Instr) ->
+ hipe_amd64_subst:insn_temps(
+ fun(Op) ->
+ case hipe_x86:temp_is_allocatable(Op)
+ andalso hipe_x86:temp_type(Op) =:= 'double'
+ of
+ true -> SubstFun(Op);
+ false -> Op
+ end
+ end, Instr).
+
-spec new_spill_index(non_neg_integer()) -> pos_integer().
new_spill_index(SpillIndex) when is_integer(SpillIndex) ->
SpillIndex + 1.
diff --git a/lib/hipe/regalloc/hipe_x86_specific.erl b/lib/hipe/regalloc/hipe_x86_specific.erl
index d5acdc0bd5..627aaa19b4 100644
--- a/lib/hipe/regalloc/hipe_x86_specific.erl
+++ b/lib/hipe/regalloc/hipe_x86_specific.erl
@@ -25,12 +25,14 @@
-define(HIPE_X86_REGISTERS, hipe_amd64_registers).
-define(HIPE_X86_LIVENESS, hipe_amd64_liveness).
-define(HIPE_X86_DEFUSE, hipe_amd64_defuse).
+-define(HIPE_X86_SUBST, hipe_amd64_subst).
-else.
-define(HIPE_X86_SPECIFIC, hipe_x86_specific).
-define(HIPE_X86_RA_POSTCONDITIONS, hipe_x86_ra_postconditions).
-define(HIPE_X86_REGISTERS, hipe_x86_registers).
-define(HIPE_X86_LIVENESS, hipe_x86_liveness).
-define(HIPE_X86_DEFUSE, hipe_x86_defuse).
+-define(HIPE_X86_SUBST, hipe_x86_subst).
-endif.
-module(?HIPE_X86_SPECIFIC).
@@ -68,6 +70,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_X86_RA_POSTCONDITIONS:check_and_rewrite(CFG, Coloring, 'normal').
@@ -152,6 +160,9 @@ number_of_temporaries(_CFG) ->
bb(CFG,L) ->
hipe_x86_cfg:bb(CFG,L).
+update_bb(CFG,L,BB) ->
+ hipe_x86_cfg:bb_add(CFG,L,BB).
+
%% X86 stuff
def_use(Instruction) ->
@@ -199,5 +210,22 @@ is_move(Instruction) ->
reg_nr(Reg) ->
hipe_x86:temp_reg(Reg).
+new_reg_nr() ->
+ hipe_gensym:get_next_var(x86).
+
+update_reg_nr(Nr, Temp) ->
+ hipe_x86:mk_temp(Nr, hipe_x86:temp_type(Temp)).
+
+subst_temps(SubstFun, Instr) ->
+ ?HIPE_X86_SUBST:insn_temps(
+ fun(Op) ->
+ case hipe_x86:temp_is_allocatable(Op)
+ andalso hipe_x86:temp_type(Op) =/= 'double'
+ of
+ true -> SubstFun(Op);
+ false -> Op
+ end
+ end, Instr).
+
new_spill_index(SpillIndex) when is_integer(SpillIndex) ->
SpillIndex+1.
diff --git a/lib/hipe/x86/Makefile b/lib/hipe/x86/Makefile
index 9b21270426..84edeaebe7 100644
--- a/lib/hipe/x86/Makefile
+++ b/lib/hipe/x86/Makefile
@@ -62,6 +62,7 @@ MODULES=hipe_rtl_to_x86 \
hipe_x86_ra_postconditions \
hipe_x86_registers \
hipe_x86_spill_restore \
+ hipe_x86_subst \
hipe_x86_x87
HRL_FILES=hipe_x86.hrl
diff --git a/lib/hipe/x86/hipe_x86_subst.erl b/lib/hipe/x86/hipe_x86_subst.erl
new file mode 100644
index 0000000000..5e642d1d06
--- /dev/null
+++ b/lib/hipe/x86/hipe_x86_subst.erl
@@ -0,0 +1,94 @@
+%% -*- 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%
+%%
+
+-ifdef(HIPE_AMD64).
+-define(HIPE_X86_SUBST, hipe_amd64_subst).
+-else.
+-define(HIPE_X86_SUBST, hipe_x86_subst).
+-endif.
+
+-module(?HIPE_X86_SUBST).
+-export([insn_temps/2]).
+-include("../x86/hipe_x86.hrl").
+
+%% These should be moved to hipe_x86 and exported
+-type temp() :: #x86_temp{}.
+-type oper() :: temp() | #x86_imm{} | #x86_mem{}.
+-type mfarec() :: #x86_mfa{}.
+-type prim() :: #x86_prim{}.
+-type funv() :: mfarec() | prim() | temp().
+-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(SubstTemp, I) ->
+ O = fun(O) -> oper_temps(SubstTemp, O) end,
+ case I of
+ #alu {src=S, dst=D} -> I#alu {src=O(S), dst=O(D)};
+ #cmovcc {src=S, dst=D} -> I#cmovcc {src=O(S), dst=O(D)};
+ #cmp {src=S, dst=D} -> I#cmp {src=O(S), dst=O(D)};
+ #fmove {src=S, dst=D} -> I#fmove {src=O(S), dst=O(D)};
+ #fp_binop{src=S, dst=D} -> I#fp_binop{src=O(S), dst=O(D)};
+ #imul {src=S, temp=T} -> I#imul {src=O(S), temp=O(T)};
+ #lea {mem=M, temp=T} -> I#lea {mem=O(M), temp=O(T)};
+ #move {src=S, dst=D} -> I#move {src=O(S), dst=O(D)};
+ #movsx {src=S, dst=D} -> I#movsx {src=O(S), dst=O(D)};
+ #movzx {src=S, dst=D} -> I#movzx {src=O(S), dst=O(D)};
+ #shift {src=S, dst=D} -> I#shift {src=O(S), dst=O(D)};
+ #test {src=S, dst=D} -> I#test {src=O(S), dst=O(D)};
+ #fp_unop{arg=A} -> I#fp_unop{arg=O(A)};
+ #move64 {dst=D} -> I#move64 {dst=O(D)};
+ #push {src=S} -> I#push {src=O(S)};
+ #pop {dst=D} -> I#pop {dst=O(D)};
+ #jmp_switch{temp=T, jtab=J} ->
+ I#jmp_switch{temp=O(T), jtab=jtab_temps(SubstTemp, J)};
+ #pseudo_call{'fun'=F} ->
+ I#pseudo_call{'fun'=funv_temps(SubstTemp, F)};
+ #pseudo_tailcall{'fun'=F, stkargs=Stk} ->
+ I#pseudo_tailcall{'fun'=funv_temps(SubstTemp, F),
+ stkargs=lists:map(O, Stk)};
+ #comment{} -> I;
+ #jmp_label{} -> I;
+ #pseudo_tailcall_prepare{} -> I;
+ #pseudo_jcc{} -> I;
+ #ret{} -> I
+ end.
+
+-spec oper_temps(subst_fun(), oper()) -> oper().
+oper_temps(_SubstTemp, I=#x86_imm{}) -> I;
+oper_temps(SubstTemp, T=#x86_temp{}) -> SubstTemp(T);
+oper_temps(SubstTemp, M=#x86_mem{base=Base,off=Off}) ->
+ M#x86_mem{base=oper_temps(SubstTemp, Base),
+ off =oper_temps(SubstTemp, Off)}.
+
+-spec funv_temps(subst_fun(), funv()) -> funv().
+funv_temps(_SubstTemp, MFA=#x86_mfa{}) -> MFA;
+funv_temps(_SubstTemp, P=#x86_prim{}) -> P;
+funv_temps(SubstTemp, T=#x86_temp{}) -> SubstTemp(T).
+
+%% TODO: Undo this ifdeffery at the source (make jtab an #x86_imm{} on x86)
+-ifdef(HIPE_AMD64).
+jtab_temps(SubstTemp, T=#x86_temp{}) -> SubstTemp(T).
+-else.
+jtab_temps(_SubstTemp, DataLbl) when is_integer(DataLbl) -> DataLbl.
+-endif.