%% -*- mode: erlang; erlang-indent-level: 2 -*-
%%
%% %CopyrightBegin%
%%
%% Copyright Ericsson AB 2001-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%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Filename : hipe.hrl (automatically generated by hipe.hrl.src)
%% Purpose : Defines some useful macros for debugging and error
%% reporting.
%%
%% History : * 2000-11-03 Erik Johansson ([email protected]): Created.
%% ====================================================================
%%
%% Defines:
%% msg/2 - Works like io:format but prepends
%% ?MSGTAG to the message.
%% If LOGGING is defined then error_logger is used,
%% or rather its substitute in code_server.
%% untagged_msg/2 - Like msg/2 but without the tag.
%% WARNING_MSG/2 - Prints a tagged warning.
%% error_msg/2 - Logs a tagged error.
%% debug_msg/2 - Prints a tagged msg if DEBUG is defined.
%% IF_DEBUG(A,B) - Executes A if DEBUG is defined B otherwise.
%% IF_DEBUG(Lvl,A,B) - Executes A if DEBUG is defined to a value >= Lvl
%% otherwise B is executed.
%% EXIT - Exits with added module and line info.
%% ASSERT - Exits if the expresion does not evaluate to true.
%% VERBOSE_ASSSERT - A message is printed even when an asertion is true.
%% TIME_STMNT(Stmnt, String, FreeVar)
%% - Times the statemnet Stmnt if TIMING is on.
%% The execution time is bound to FreeVar.
%% String is printed after the execution
%% followed by the execution time in seconds and
%% a newline.
%%
%% Flags:
%% DEBUG - Turns on debugging. (Can be defined to a integer
%% value to determine the level of debugging)
%% HIPE_LOGGING - Turn on logging of messages with erl_logger.
%% DO_ASSERT - Turn on assertions.
%% TIMING - Turn on timing.
%% HIPE_INSTRUMENT_COMPILER - Turn on instrumentation of the compiler.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-define(VERSION_STRING(),"%VSN%").
-define(MSGTAG, "<HiPE (v " ++ ?VERSION_STRING() ++ ")> ").
%%
%% Define the message macros with or without logging,
%% depending on the value of the HIPE_LOGGING flag.
%%
-ifdef(HIPE_LOGGING).
-define(msg(Msg, Args),
code_server:info_msg(?MSGTAG ++ Msg, Args)).
-define(untagged_msg(Msg, Args),
code_server:info_msg(Msg, Args)).
-define(untagged_error_msg(Msg, Args),
code_server:error_msg(Msg, Args)).
-else.
-define(msg(Msg, Args),
io:format(?MSGTAG ++ Msg, Args)).
-define(untagged_msg(Msg, Args),
io:format(Msg, Args)).
-define(untagged_error_msg(Msg, Args),
io:format(Msg, Args)).
-endif.
%%
%% Define error and warning messages.
%%
-define(error_msg(Msg, Args),
?untagged_error_msg(?MSGTAG ++
"Error: [~s:~w]: " ++ Msg,
[?MODULE,?LINE|Args])).
-define(WARNING_MSG(Msg, Args),
?msg("Warning: [~s:~w]: " ++ Msg, [?MODULE,?LINE|Args])).
%%
%% Define the macros that are dependent on the debug flag.
%%
-ifdef(DEBUG).
-define(debug_msg(Msg,Data), ?msg(Msg,Data)).
-define(debug_untagged_msg(Msg,Data), ?untagged_msg(Msg,Data)).
-define(IF_DEBUG(DebugAction,NoDebugAction), DebugAction).
-define(IF_DEBUG_LEVEL(Level,DebugAction,NoDebugAction),
if (Level =< ?DEBUG) -> DebugAction; true -> NoDebugAction end).
-else.
-define(debug_msg(Msg,Data), no_debug).
-define(debug_untagged_msg(Msg,Data), no_debug).
-define(IF_DEBUG(DebugAction,NoDebugAction), NoDebugAction).
-define(IF_DEBUG_LEVEL(Level,DebugAction,NoDebugAction), NoDebugAction).
-endif.
%%
%% Define the exit macro
%%
-define(EXIT(Reason),
?msg("EXITED with reason ~w @~w:~w\n", [Reason,?MODULE,?LINE]),
erlang:error({?MODULE,?LINE,Reason})).
%%
%% Assertions.
%%
-ifdef(DO_ASSERT).
-define(VERBOSE_ASSERT(X),
case X of
true ->
io:format("Assertion ok ~w ~w\n",[?MODULE,?LINE]),
true;
__ASSVAL_R ->
io:format("Assertion failed ~w ~w: ~p\n",
[?MODULE,?LINE, __ASSVAL_R]),
?EXIT(assertion_failed)
end).
-define(ASSERT(X),
case X of
true -> true;
_ -> ?EXIT(assertion_failed)
end).
-else.
-define(ASSERT(X),true).
-define(VERBOSE_ASSERT(X),true).
-endif.
%% Use this to display info, save stuff and so on.
%% Vars cannot be exported from __Action
-define(when_option(__Opt,__Opts,__Action),
case proplists:get_bool(__Opt,__Opts) of
true -> __Action;
false -> ok
end).
%% Timing macros
-ifdef(TIMING).
-define(TIME_STMNT(STMNT,Msg,Timer),
Timer = hipe_timing:start_timer(),
STMNT,
?untagged_msg(Msg ++ "~.2f s\n",[hipe_timing:stop_timer(Timer)/1000])).
-else.
-define(TIME_STMNT(STMNT,Msg,Timer), STMNT).
-endif.
-define(start_timer(Text), hipe_timing:start(Text, ?MODULE)).
-define(stop_timer(Text), hipe_timing:stop(Text, ?MODULE)).
-define(start_hipe_timer(Timer), hipe_timing:start_hipe_timer(Timer)).
-define(stop_hipe_timer(Timer), hipe_timing:stop_hipe_timer(Timer)).
-define(get_hipe_timer_val(Timer), get(Timer)).
-define(set_hipe_timer_val(Timer, Val), put(Timer, Val)).
-define(option_time(Stmnt, Text, Options),
begin
?when_option(time, Options, ?start_timer(Text)),
fun(R) ->
?when_option(time, Options, ?stop_timer(Text)),
R
end(Stmnt)
end).
-define(option_start_time(Text, Options),
?when_option(time, Options, ?start_timer(Text))).
-define(option_stop_time(Text, Options),
?when_option(time, Options, ?stop_timer(Text))).
-define(opt_start_timer(Text),
hipe_timing:start_optional_timer(Text, ?MODULE)).
-define(opt_stop_timer(Text),
hipe_timing:stop_optional_timer(Text, ?MODULE)).
%%
%% Turn on instrumentation of the compiler.
%%
-ifdef(HIPE_INSTRUMENT_COMPILER).
-define(count_pre_ra_instructions(Options, NoInstrs),
?when_option(count_instrs, Options,
put(pre_ra_instrs,
get(pre_ra_instrs) + NoInstrs))).
-define(count_post_ra_instructions(Options, NoInstrs),
?when_option(count_instrs, Options,
put(post_ra_instrs,
get(post_ra_instrs) + NoInstrs))).
-define(start_time_regalloc(Options),
?when_option(timeregalloc, Options,
put(regalloctime1, erlang:statistics(runtime)))).
-define(stop_time_regalloc(Options),
?when_option(timeregalloc, Options,
put(regalloctime,
get(regalloctime) +
(element(1,erlang:statistics(runtime))
-element(1,get(regalloctime1)))))).
-define(start_time_caller_saves(Options),
?when_option(timeregalloc, Options,
put(callersavetime1,erlang:statistics(runtime)))).
-define(stop_time_caller_saves(Options),
?when_option(timeregalloc, Options,
put(callersavetime,
get(callersavetime) +
(element(1,erlang:statistics(runtime))
-element(1,get(callersavetime1)))))).
-define(count_pre_ra_temps(Options, NoTemps),
?when_option(count_temps, Options,
put(pre_ra_temps,
get(pre_ra_temps) + NoTemps))).
-define(count_post_ra_temps(Options, NoTemps),
?when_option(count_temps, Options,
put(post_ra_temps,
get(post_ra_temps) + NoTemps))).
-define(inc_counter(Counter, Val),
case get(Counter) of
undefined -> true;
_ -> put(Counter, Val + get(Counter))
end).
-define(cons_counter(Counter, Val),
case get(Counter) of
undefined -> true;
_ -> put(Counter, [Val|get(Counter)])
end).
-define(update_counter(Counter, Val, Op),
case get(Counter) of
undefined -> true;
_ -> put(Counter, get(Counter) Op Val)
end).
-define(start_ra_instrumentation(Options, NoInstrs, NoTemps),
begin
?count_pre_ra_instructions(Options, NoInstrs),
?count_pre_ra_temps(Options, NoTemps),
case get(counter_mem_temps) of
undefined -> true;
_ -> put(counter_mfa_mem_temps,[])
end,
?start_time_regalloc(Options)
end).
-define(stop_ra_instrumentation(Options, NoInstrs, NoTemps),
begin
?stop_time_regalloc(Options),
?count_post_ra_instructions(Options, NoInstrs),
?cons_counter(counter_mem_temps, get(counter_mfa_mem_temps)),
?cons_counter(ra_all_iterations_counter, get(ra_iteration_counter)),
put(ra_iteration_counter, 0),
?count_post_ra_temps(Options, NoTemps)
end).
-define(add_spills(Options, NoSpills),
?when_option(count_spills, Options,
put(spilledtemps, get(spilledtemps) + NoSpills))).
-define(optional_start_timer(Timer, Options),
case lists:member(Timer, proplists:get_value(timers, Options++[{timers,[]}])) of
true -> ?start_hipe_timer(Timer);
false -> true
end).
-define(optional_stop_timer(Timer, Options),
case lists:member(Timer, proplists:get_value(timers, Options++[{timers,[]}])) of
true -> ?stop_hipe_timer(Timer);
false -> true
end).
-else. %% HIPE_INSTRUMENT_COMPILER
-define(count_pre_ra_instructions(Options, NoInstrs), no_instrumentation).
-define(count_post_ra_instructions(Options, NoInstrs),no_instrumentation).
-define(start_time_regalloc(Options), no_instrumentation).
-define(stop_time_regalloc(Options), no_instrumentation).
-define(start_time_caller_saves(Options), no_instrumentation).
-define(stop_time_caller_saves(Options), no_instrumentation).
-define(count_pre_ra_temps(Options, NoTemps), no_instrumentation).
-define(count_post_ra_temps(Options, NoTemps), no_instrumentation).
-define(start_ra_instrumentation(Options, NoInstrs, NoTemps),no_instrumentation).
-define(stop_ra_instrumentation(Options, NoInstrs, NoTemps),no_instrumentation).
-define(add_spills(Options, NoSpills), no_instrumentation).
-define(optional_start_timer(Options, Timer), no_instrumentation).
-define(optional_stop_timer(Options, Timer), no_instrumentation).
-define(inc_counter(Counter, Val), no_instrumentation).
-define(update_counter(Counter, Val, Op), no_instrumentation).
-define(cons_counter(Counter, Val), no_instrumentation).
-endif. %% HIPE_INSTRUMENT_COMPILER
%%----------------------------------------------------------------------------
%% Records defined in the hipe module used in other parts of the compiler
%%----------------------------------------------------------------------------
-type mpid() :: 'none' | pid().
-record(comp_servers, {pp_server :: mpid(), range :: mpid(), type :: mpid()}).
%%----------------------------------------------------------------------------
%% Basic types of the 'hipe' application used in other parts of the system
%%----------------------------------------------------------------------------
-type comp_option() :: atom() | {atom(), atom()}.
-type comp_options() :: [comp_option()].
-type hipe_architecture() ::
'amd64' | 'arm' | 'powerpc' | 'ppc64' | 'ultrasparc' | 'x86'.
-type hipe_map() :: [{non_neg_integer(),
'unknown' | {'reg' | 'fp_reg' | 'spill',
non_neg_integer()}}].
-type hipe_temp_map() :: tuple().
-type hipe_spill_map() :: [{non_neg_integer(), {'spill', non_neg_integer()}}].