aboutsummaryrefslogtreecommitdiffstats
path: root/lib/hipe/regalloc/hipe_x86_specific.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/hipe/regalloc/hipe_x86_specific.erl')
-rw-r--r--lib/hipe/regalloc/hipe_x86_specific.erl203
1 files changed, 203 insertions, 0 deletions
diff --git a/lib/hipe/regalloc/hipe_x86_specific.erl b/lib/hipe/regalloc/hipe_x86_specific.erl
new file mode 100644
index 0000000000..0f490ba14d
--- /dev/null
+++ b/lib/hipe/regalloc/hipe_x86_specific.erl
@@ -0,0 +1,203 @@
+%% -*- erlang-indent-level: 2 -*-
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-ifdef(HIPE_AMD64).
+-define(HIPE_X86_SPECIFIC, hipe_amd64_specific).
+-define(HIPE_X86_RA_POSTCONDITIONS, hipe_amd64_ra_postconditions).
+-define(HIPE_X86_REGISTERS, hipe_amd64_registers).
+-define(HIPE_X86_LIVENESS, hipe_amd64_liveness).
+-define(HIPE_X86_DEFUSE, hipe_amd64_defuse).
+-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).
+-endif.
+
+-module(?HIPE_X86_SPECIFIC).
+
+-export([number_of_temporaries/1]).
+
+%% The following exports are used as M:F(...) calls from other modules;
+%% e.g. hipe_x86_ra_ls.
+-export([analyze/1,
+ bb/2,
+ args/1,
+ labels/1,
+ livein/2,
+ liveout/2,
+ uses/1,
+ defines/1,
+ def_use/1,
+ is_arg/1, % used by hipe_ls_regalloc
+ is_move/1,
+ is_fixed/1, % used by hipe_graph_coloring_regalloc
+ is_global/1,
+ is_precoloured/1,
+ reg_nr/1,
+ non_alloc/1,
+ allocatable/0,
+ physical_name/1,
+ all_precoloured/0,
+ new_spill_index/1, % used by hipe_ls_regalloc
+ var_range/1,
+ breadthorder/1,
+ postorder/1,
+ reverse_postorder/1]).
+
+%% callbacks for hipe_regalloc_loop
+-export([defun_to_cfg/1,
+ check_and_rewrite/2]).
+
+defun_to_cfg(Defun) ->
+ hipe_x86_cfg:init(Defun).
+
+check_and_rewrite(Defun, Coloring) ->
+ ?HIPE_X86_RA_POSTCONDITIONS:check_and_rewrite(Defun, Coloring, 'normal').
+
+reverse_postorder(CFG) ->
+ hipe_x86_cfg:reverse_postorder(CFG).
+
+breadthorder(CFG) ->
+ hipe_x86_cfg:breadthorder(CFG).
+
+postorder(CFG) ->
+ hipe_x86_cfg:postorder(CFG).
+
+%% Globally defined registers for linear scan
+is_global(R) ->
+ ?HIPE_X86_REGISTERS:temp1() =:= R orelse
+ ?HIPE_X86_REGISTERS:temp0() =:= R orelse
+ ?HIPE_X86_REGISTERS:is_fixed(R).
+
+is_fixed(R) ->
+ ?HIPE_X86_REGISTERS:is_fixed(R).
+
+is_arg(R) ->
+ ?HIPE_X86_REGISTERS:is_arg(R).
+
+args(CFG) ->
+ ?HIPE_X86_REGISTERS:args(hipe_x86_cfg:arity(CFG)).
+
+non_alloc(CFG) ->
+ non_alloc(?HIPE_X86_REGISTERS:nr_args(), hipe_x86_cfg:params(CFG)).
+
+%% same as hipe_x86_frame:fix_formals/2
+non_alloc(0, Rest) -> Rest;
+non_alloc(N, [_|Rest]) -> non_alloc(N-1, Rest);
+non_alloc(_, []) -> [].
+
+%% Liveness stuff
+
+analyze(CFG) ->
+ ?HIPE_X86_LIVENESS:analyze(CFG).
+
+livein(Liveness,L) ->
+ [X || X <- ?HIPE_X86_LIVENESS:livein(Liveness,L),
+ hipe_x86:temp_is_allocatable(X),
+ hipe_x86:temp_reg(X) =/= ?HIPE_X86_REGISTERS:fcalls(),
+ hipe_x86:temp_reg(X) =/= ?HIPE_X86_REGISTERS:heap_limit(),
+ hipe_x86:temp_type(X) =/= 'double'].
+
+liveout(BB_in_out_liveness,Label) ->
+ [X || X <- ?HIPE_X86_LIVENESS:liveout(BB_in_out_liveness,Label),
+ hipe_x86:temp_is_allocatable(X),
+ hipe_x86:temp_reg(X) =/= ?HIPE_X86_REGISTERS:fcalls(),
+ hipe_x86:temp_reg(X) =/= ?HIPE_X86_REGISTERS:heap_limit(),
+ hipe_x86:temp_type(X) =/= 'double'].
+
+%% Registers stuff
+
+allocatable() ->
+ ?HIPE_X86_REGISTERS:allocatable().
+
+all_precoloured() ->
+ ?HIPE_X86_REGISTERS:all_precoloured().
+
+is_precoloured(Reg) ->
+ ?HIPE_X86_REGISTERS:is_precoloured(Reg).
+
+physical_name(Reg) ->
+ Reg.
+
+%% CFG stuff
+
+labels(CFG) ->
+ hipe_x86_cfg:labels(CFG).
+
+var_range(_CFG) ->
+ hipe_gensym:var_range(x86).
+
+number_of_temporaries(_CFG) ->
+ Highest_temporary = hipe_gensym:get_var(x86),
+ %% Since we can have temps from 0 to Max adjust by +1.
+ Highest_temporary + 1.
+
+bb(CFG,L) ->
+ hipe_x86_cfg:bb(CFG,L).
+
+%% X86 stuff
+
+def_use(Instruction) ->
+ {[X || X <- ?HIPE_X86_DEFUSE:insn_def(Instruction),
+ hipe_x86:temp_is_allocatable(X),
+ hipe_x86:temp_type(X) =/= 'double'],
+ [X || X <- ?HIPE_X86_DEFUSE:insn_use(Instruction),
+ hipe_x86:temp_is_allocatable(X),
+ hipe_x86:temp_type(X) =/= 'double']
+ }.
+
+uses(I) ->
+ [X || X <- ?HIPE_X86_DEFUSE:insn_use(I),
+ hipe_x86:temp_is_allocatable(X),
+ hipe_x86:temp_type(X) =/= 'double'].
+
+defines(I) ->
+ [X || X <- ?HIPE_X86_DEFUSE:insn_def(I),
+ hipe_x86:temp_is_allocatable(X),
+ hipe_x86:temp_type(X) =/= 'double'].
+
+is_move(Instruction) ->
+ case hipe_x86:is_move(Instruction) of
+ true ->
+ Src = hipe_x86:move_src(Instruction),
+ Dst = hipe_x86:move_dst(Instruction),
+ case hipe_x86:is_temp(Src) of
+ true ->
+ case hipe_x86:temp_is_allocatable(Src) of
+ true ->
+ case hipe_x86:is_temp(Dst) of
+ true ->
+ hipe_x86:temp_is_allocatable(Dst);
+ false -> false
+ end;
+ false -> false
+ end;
+ false -> false
+ end;
+ false -> false
+ end.
+
+reg_nr(Reg) ->
+ hipe_x86:temp_reg(Reg).
+
+new_spill_index(SpillIndex) when is_integer(SpillIndex) ->
+ SpillIndex+1.