1%% -*- erlang-indent-level: 2 -*-
2%%
3%% Licensed under the Apache License, Version 2.0 (the "License");
4%% you may not use this file except in compliance with the License.
5%% You may obtain a copy of the License at
6%%
7%%     http://www.apache.org/licenses/LICENSE-2.0
8%%
9%% Unless required by applicable law or agreed to in writing, software
10%% distributed under the License is distributed on an "AS IS" BASIS,
11%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12%% See the License for the specific language governing permissions and
13%% limitations under the License.
14%%
15%%%--------------------------------------------------------------------
16%%% File    : hipe_icode_type.erl
17%%% Author  : Tobias Lindahl <Tobias.Lindahl@it.uu.se>
18%%% Description : Propagate type information.
19%%%
20%%% Created : 25 Feb 2003 by Tobias Lindahl <Tobias.Lindahl@it.uu.se>
21%%%--------------------------------------------------------------------
22
23-module(hipe_icode_type).
24
25-export([cfg/4, unannotate_cfg/1, specialize/1]).
26
27%%=====================================================================
28%% Icode Coordinator Callbacks
29%%=====================================================================
30
31-export([replace_nones/1,
32	 update__info/2, new__info/1, return__info/1,
33	 return_none/0, return_none_args/2, return_any_args/2]).
34
35%%=====================================================================
36
37-include("../main/hipe.hrl").
38-include("hipe_icode.hrl").
39-include("hipe_icode_primops.hrl").
40-include("hipe_icode_type.hrl").
41-include("../flow/cfg.hrl").
42
43-type args_fun()  :: fun((mfa(), cfg()) -> [erl_types:erl_type()]).
44-type call_fun()  :: fun((mfa(), [_]) -> erl_types:erl_type()).
45-type final_fun() :: fun((mfa(), [_]) -> 'ok').
46-type data()	  :: {mfa(), args_fun(), call_fun(), final_fun()}.
47
48%-define(DO_HIPE_ICODE_TYPE_TEST, false).
49
50-ifdef(DO_HIPE_ICODE_TYPE_TEST).
51-export([test/0]).
52-endif.
53
54-define(MFA_debug, fun(_, _, _) -> ok end).
55
56%-define(debug, fun(X, Y) -> io:format("~s ~p~n", [X, Y]) end).
57-define(debug, fun(_, _) -> ok end).
58
59%-define(flow_debug, fun(X, Y) -> io:format("flow: ~s ~p~n", [X, Y]) end).
60-define(flow_debug, fun(_, _) -> ok end).
61
62%-define(widening_debug, fun(X, Y) -> io:format("wid: ~s ~p~n", [X, Y]) end).
63-define(widening_debug, fun(_, _) -> ok end).
64
65%-define(call_debug, fun(X, Y) -> io:format("call: ~s ~p~n", [X, Y]) end).
66-define(call_debug, fun(_, _) -> ok end).
67
68%-define(ineq_debug, fun(X, Y) -> io:format("ineq: ~s ~p~n", [X, Y]) end).
69-define(ineq_debug, fun(_, _) -> ok end).
70
71%-define(server_debug, fun(X, Y) -> io:format("~p server: ~s ~p~n", [self(), X, Y]) end).
72-define(server_debug, fun(_, _) -> ok end).
73
74-import(erl_types, [number_min/1, number_max/1,
75		    t_any/0, t_atom/1, t_atom/0, t_atom_vals/1,
76		    t_binary/0, t_bitstr/0, t_bitstr_base/1, t_bitstr_unit/1,
77		    t_boolean/0, t_cons/0,
78		    t_float/0, t_from_term/1, t_from_range/2,
79		    t_fun/0, t_fun/1, t_fun/2, t_fun_args/1, t_fun_arity/1,
80		    t_inf/2, t_inf_lists/2, t_integer/0,
81		    t_integer/1, t_is_atom/1, t_is_any/1,
82		    t_is_binary/1, t_is_bitstr/1, t_is_bitwidth/1,
83		    t_is_boolean/1, t_is_fixnum/1, t_is_cons/1, t_is_map/1,
84		    t_is_maybe_improper_list/1, t_is_equal/2, t_is_float/1,
85		    t_is_fun/1, t_is_integer/1, t_is_non_neg_integer/1,
86		    t_is_number/1, t_is_matchstate/1,
87		    t_is_none/1, t_is_port/1, t_is_pid/1,
88		    t_is_reference/1, t_is_subtype/2, t_is_tuple/1,
89		    t_limit/2, t_matchstate_present/1, t_matchstate/0,
90		    t_matchstate_slots/1, t_maybe_improper_list/0, t_map/0,
91		    t_nil/0, t_none/0, t_number/0, t_number/1, t_number_vals/1,
92		    t_pid/0, t_port/0, t_reference/0, t_subtract/2, t_sup/2,
93		    t_to_tlist/1, t_tuple/0, t_tuple/1, t_tuple_sizes/1]).
94
95-record(state, {info_map  = gb_trees:empty() :: gb_trees:tree(),
96		cfg                          :: cfg(),
97		liveness                     :: hipe_icode_ssa:liveness(),
98		arg_types                    :: [erl_types:erl_type()],
99		ret_type  = [t_none()]       :: [erl_types:erl_type()],
100		lookupfun                    :: call_fun(),
101		resultaction                 :: final_fun()}).
102-type state() :: #state{}.
103
104%%-----------------------------------------------------------------------
105%% The main exported function
106%%-----------------------------------------------------------------------
107
108-spec cfg(cfg(), mfa(), comp_options(), #comp_servers{}) -> cfg().
109
110cfg(Cfg, MFA, Options, Servers) ->
111  case proplists:get_bool(concurrent_comp, Options) of
112    true ->
113      concurrent_cfg(Cfg, MFA, Servers#comp_servers.type);
114    false ->
115      ordinary_cfg(Cfg, MFA)
116  end.
117
118concurrent_cfg(Cfg, MFA, CompServer) ->
119  CompServer ! {ready, {MFA, self()}},
120  {ArgsFun, CallFun, FinalFun} = do_analysis(Cfg, MFA),
121  Ans = do_rewrite(Cfg, MFA, ArgsFun, CallFun, FinalFun),
122  CompServer ! {done_rewrite, MFA},
123  Ans.
124
125do_analysis(Cfg, MFA) ->
126  receive
127    {analyse, {ArgsFun,CallFun,FinalFun}} ->
128      analyse(Cfg, {MFA,ArgsFun,CallFun,FinalFun}),
129      do_analysis(Cfg, MFA);
130    {done, {_NewArgsFun,_NewCallFun,_NewFinalFun} = Done} ->
131      Done
132  end.
133
134do_rewrite(Cfg, MFA, ArgsFun, CallFun, FinalFun) ->
135  common_rewrite(Cfg, {MFA,ArgsFun,CallFun,FinalFun}).
136
137ordinary_cfg(Cfg, MFA) ->
138  Data = make_data(Cfg,MFA),
139  common_rewrite(Cfg, Data).
140
141common_rewrite(Cfg, Data) ->
142  State = safe_analyse(Cfg, Data),
143  NewState = simplify_controlflow(State),
144  NewCfg = state__cfg(annotate_cfg(NewState)),
145  hipe_icode_cfg:remove_unreachable_code(specialize(NewCfg)).
146
147make_data(Cfg, {_M,_F,A}=MFA) ->
148  NoArgs =
149    case hipe_icode_cfg:is_closure(Cfg) of
150      true -> hipe_icode_cfg:closure_arity(Cfg);
151      false -> A
152    end,
153  Args = lists:duplicate(NoArgs, t_any()),
154  ArgsFun = fun(_,_) -> Args end,
155  CallFun = fun(_,_) -> t_any() end,
156  FinalFun = fun(_,_) -> ok end,
157  {MFA,ArgsFun,CallFun,FinalFun}.
158
159%%debug_make_data(Cfg, {_M,_F,A}=MFA) ->
160%%  NoArgs =
161%%    case hipe_icode_cfg:is_closure(Cfg) of
162%%      true -> hipe_icode_cfg:closure_arity(Cfg);
163%%      false -> A
164%%    end,
165%%  Args = lists:duplicate(NoArgs, t_any()),
166%%  ArgsFun = fun(MFA,_Cfg) -> io:format("Start:~p~n",[MFA]),Args end,
167%%  CallFun = fun(MFA,Types) -> io:format("Call With:~p~nTo:~p~n",[Types,MFA]), t_any() end,
168%%  FinalFun = fun(MFA,Type) -> io:format("ResType:~p~nFor:~p~n",[Type,MFA]),ok end,
169%%  {MFA,ArgsFun,CallFun,FinalFun}.
170
171
172%%-------------------------------------------------------------------
173%% Global type analysis on the whole function. Demands that the code
174%% is in SSA form. When we encounter a phi node, the types of the
175%% arguments are joined. At the end of a block the information out is
176%% joined with the current information in for all _valid_ successors,
177%% that is, of all successors that actually can be reached. If the
178%% join produces new information in for the successor, this
179%% information is added to the worklist.
180%%-------------------------------------------------------------------
181
182-spec analyse(cfg(), data()) -> 'ok'.
183
184analyse(Cfg, Data) ->
185  try
186    #state{} = safe_analyse(Cfg, Data),
187    ok
188  catch throw:no_input -> ok % No need to do anything since we have no input
189  end.
190
191-spec safe_analyse(cfg(), data()) -> state().
192
193safe_analyse(Cfg, {MFA,_,_,_}=Data) ->
194  State = new_state(Cfg, Data),
195  NewState = analyse_blocks(State,MFA),
196  (state__resultaction(NewState))(MFA,state__ret_type(NewState)),
197  NewState.
198
199analyse_blocks(State, MFA) ->
200  Work = init_work(State),
201  analyse_blocks(Work, State, MFA).
202
203analyse_blocks(Work, State, MFA) ->
204  case get_work(Work) of
205    fixpoint ->
206      State;
207    {Label, NewWork} ->
208      Info = state__info_in(State, Label),
209      {NewState, NewLabels}  =
210	try analyse_block(Label, Info, State)
211	catch throw:none_type ->
212	    %% io:format("received none type at label: ~p~n", [Label]),
213	    {State,[]}
214	end,
215      NewWork2 = add_work(NewWork, NewLabels),
216      analyse_blocks(NewWork2, NewState, MFA)
217  end.
218
219analyse_block(Label, InfoIn, State) ->
220  BB = state__bb(State, Label),
221  Code = hipe_bb:butlast(BB),
222  Last = hipe_bb:last(BB),
223  InfoOut = analyse_insns(Code, InfoIn, state__lookupfun(State)),
224  NewState = state__info_out_update(State, Label, InfoOut),
225  case Last of
226    #icode_if{} ->
227      UpdateInfo = do_if(Last, InfoOut),
228      do_updates(NewState, UpdateInfo);
229    #icode_type{} ->
230      UpdateInfo = do_type(Last, InfoOut),
231      do_updates(NewState, UpdateInfo);
232    #icode_switch_tuple_arity{} ->
233      UpdateInfo = do_switch_tuple_arity(Last, InfoOut),
234      do_updates(NewState, UpdateInfo);
235    #icode_switch_val{} ->
236      UpdateInfo = do_switch_val(Last, InfoOut),
237      do_updates(NewState, UpdateInfo);
238    #icode_enter{} ->
239      NewState1 = do_enter(Last, InfoOut, NewState, state__lookupfun(NewState)),
240      do_updates(NewState1,[]);
241    #icode_call{} ->
242      {NewState1,UpdateInfo} = do_last_call(Last, InfoOut, NewState, Label),
243      do_updates(NewState1, UpdateInfo);
244    #icode_return{} ->
245      NewState1 = do_return(Last, InfoOut, NewState),
246      do_updates(NewState1,[]);
247    _ ->
248      UpdateInfo = [{X, InfoOut} || X <- state__succ(NewState, Label)],
249      do_updates(NewState, UpdateInfo)
250  end.
251
252analyse_insns([I|Insns], Info, LookupFun) ->
253  NewInfo = analyse_insn(I, Info, LookupFun),
254  analyse_insns(Insns, NewInfo, LookupFun);
255analyse_insns([], Info, _) ->
256  Info.
257
258analyse_insn(I, Info, LookupFun) ->
259  case I of
260    #icode_move{} ->
261      do_move(I, Info);
262    #icode_call{} ->
263      NewInfo = do_call(I, Info, LookupFun),
264      %% io:format("Analysing Call: ~w~n~w~n", [I, NewInfo]),
265      update_call_arguments(I, NewInfo);
266    #icode_phi{} ->
267      Type = t_limit(join_list(hipe_icode:args(I), Info), ?TYPE_DEPTH),
268      enter_defines(I, Type, Info);
269    #icode_begin_handler{} ->
270      enter_defines(I, t_any(), Info);
271    _ ->
272      %% Just an assert
273      case defines(I) of
274	[] -> Info;
275	_ -> exit({"Instruction with destination not analysed", I})
276      end
277  end.
278
279do_move(I, Info) ->
280  %% Can't use uses/1 since we must keep constants.
281  [Src] = hipe_icode:args(I),
282  enter_defines(I, lookup(Src, Info), Info).
283
284do_basic_call(I, Info, LookupFun) ->
285    case hipe_icode:call_type(I) of
286      primop ->
287	Fun = hipe_icode:call_fun(I),
288	ArgTypes = lookup_list(hipe_icode:args(I), Info),
289	primop_type(Fun, ArgTypes);
290      remote ->
291	{M, F, A} = hipe_icode:call_fun(I),
292	ArgTypes = lookup_list(hipe_icode:args(I), Info),
293	None = t_none(),
294	case erl_bif_types:type(M, F, A, ArgTypes) of
295	  None ->
296	    NewArgTypes = add_funs_to_arg_types(ArgTypes),
297	    erl_bif_types:type(M, F, A, NewArgTypes);
298	  Other ->
299	    Other
300	end;
301      local ->
302	MFA = hipe_icode:call_fun(I),
303	ArgTypes = lookup_list(hipe_icode:args(I), Info),
304	%% io:format("Call:~p~nTypes: ~p~n",[I,ArgTypes]),
305	LookupFun(MFA,ArgTypes)
306    end.
307
308do_call(I, Info, LookupFun) ->
309  RetType = do_basic_call(I, Info, LookupFun),
310  IsNone = t_is_none(RetType),
311  %% io:format("RetType ~p~nIsNone ~p~n~p~n",[RetType,IsNone,I]),
312  if IsNone -> throw(none_type);
313     true -> enter_defines(I, RetType, Info)
314  end.
315
316do_safe_call(I, Info, LookupFun) ->
317  RetType = do_basic_call(I, Info, LookupFun),
318  enter_defines(I, RetType, Info).
319
320do_last_call(Last, InfoOut, State, Label) ->
321  try
322    NewInfoOut = do_call(Last, InfoOut, state__lookupfun(State)),
323    NewState = state__info_out_update(State, Label, NewInfoOut),
324    ContInfo = update_call_arguments(Last, NewInfoOut),
325    Cont = hipe_icode:call_continuation(Last),
326    Fail = hipe_icode:call_fail_label(Last),
327    ?call_debug("Continfo, NewInfoOut", {ContInfo, NewInfoOut}),
328    UpdateInfo =
329    case Fail of
330      [] ->
331	[{Cont, ContInfo}];
332      _ ->
333	case call_always_fails(Last, InfoOut) of
334	  true ->
335	    [{Fail, NewInfoOut}];
336	  false ->
337	    Fun = hipe_icode:call_fun(Last),
338	    case hipe_icode_primops:fails(Fun) of
339	      true ->
340		[{Cont, ContInfo}, {Fail, NewInfoOut}];
341	      false ->
342		[{Cont, ContInfo}]
343	    end
344	end
345    end,
346    {NewState,UpdateInfo}
347  catch throw:none_type ->
348      State2 = state__info_out_update(State, Label, InfoOut),
349      case hipe_icode:call_fail_label(Last) of
350	[] -> throw(none_type);
351	FailLbl ->
352	  {State2,[{FailLbl, InfoOut}]}
353      end
354  end.
355
356call_always_fails(#icode_call{} = I, Info) ->
357  case hipe_icode:call_fun(I) of
358    %% These can actually be calls too.
359    {erlang, halt, 0} -> false;
360    {erlang, halt, 1} -> false;
361    {erlang, halt, 2} -> false;
362    {erlang, exit, 1} -> false;
363    {erlang, error, 1} -> false;
364    {erlang, error, 2} -> false;
365    {erlang, throw, 1} -> false;
366    {erlang, hibernate, 3} -> false;
367    Fun ->
368      case hipe_icode:call_type(I) of
369	primop ->
370	  Args = safe_lookup_list(hipe_icode:call_args(I), Info),
371	  ReturnType = primop_type(Fun, Args),
372	  t_is_none(ReturnType);
373	_ -> false
374      end
375  end.
376
377do_enter(I, Info, State, LookupFun) ->
378  %% io:format("Enter:~p~n",[I]),
379  ArgTypes = lookup_list(hipe_icode:args(I), Info),
380  RetTypes =
381    case hipe_icode:enter_type(I) of
382      local ->
383	MFA = hipe_icode:enter_fun(I),
384	LookupFun(MFA,ArgTypes);
385      remote ->
386	{M, F, A} = hipe_icode:enter_fun(I),
387	None = t_none(),
388	case erl_bif_types:type(M, F, A, ArgTypes) of
389	  None ->
390	    NewArgTypes = add_funs_to_arg_types(ArgTypes),
391	    erl_bif_types:type(M, F, A, NewArgTypes);
392	  Other ->
393	    Other
394	end;
395      primop ->
396	Fun = hipe_icode:enter_fun(I),
397	primop_type(Fun, ArgTypes)
398    end,
399  state__ret_type_update(State, RetTypes).
400
401do_return(I, Info, State) ->
402  RetTypes = lookup_list(hipe_icode:args(I), Info),
403  state__ret_type_update(State, RetTypes).
404
405do_if(I, Info) ->
406  %% XXX: Could probably do better than this.
407  TrueLab = hipe_icode:if_true_label(I),
408  FalseLab = hipe_icode:if_false_label(I),
409  case hipe_icode:if_args(I) of
410    [Arg1, Arg2] = Args ->
411      [Type1, Type2] = lookup_list(Args, Info),
412      case t_is_none(Type1) orelse t_is_none(Type2) of
413	true ->
414	  [{TrueLab, Info}, {FalseLab, Info}];
415	false ->
416	  Inf = t_inf(Type1, Type2),
417	  case hipe_icode:if_op(I) of
418	    '=:='->
419	      case t_is_none(Inf) of
420		true ->
421		  [{FalseLab, Info}];
422		false ->
423		  [{TrueLab, enter(Arg1, Inf, enter(Arg2, Inf, Info))},
424		   {FalseLab, Info}]
425	      end;
426	    '=/=' ->
427	      case t_is_none(Inf) of
428		true ->
429		  [{TrueLab, Info}];
430		false ->
431		  [{FalseLab, enter(Arg1, Inf, enter(Arg2, Inf, Info))},
432		   {TrueLab, Info}]
433	      end;
434	    '==' ->
435	      [{TrueLab, Info}, {FalseLab, Info}];
436	    '/=' ->
437	      [{TrueLab, Info}, {FalseLab, Info}];
438	    Op ->
439	      integer_range_inequality_propagation(Op, Arg1, Arg2,
440						   TrueLab, FalseLab, Info)
441	      %%_ ->
442	      %%  [{TrueLab, Info}, {FalseLab, Info}]
443	  end
444      end;
445    _ ->
446      %% Only care for binary if:s
447      [{TrueLab, Info}, {FalseLab, Info}]
448  end.
449
450integer_range_inequality_propagation(Op, A1, A2, TrueLab, FalseLab, Info) ->
451  Arg1 = lookup(A1, Info),
452  Arg2 = lookup(A2, Info),
453  ?ineq_debug("args", [Arg1,Arg2]),
454  IntArg1 = t_inf(Arg1, t_integer()),
455  IntArg2 = t_inf(Arg2, t_integer()),
456  NonIntArg1 = t_subtract(Arg1, t_integer()),
457  NonIntArg2 = t_subtract(Arg2, t_integer()),
458  ?ineq_debug("nonintargs", [NonIntArg1,NonIntArg2]),
459  case t_is_none(IntArg1) orelse t_is_none(IntArg2) of
460    true ->
461      ?ineq_debug("one is none", [IntArg1,IntArg2]),
462      [{TrueLab, Info}, {FalseLab, Info}];
463    false ->
464      {TrueArg1, TrueArg2, FalseArg1, FalseArg2} =
465	case Op of
466	  '>=' ->
467	    {FA1, FA2, TA1, TA2} = int_range_lt_propagator(IntArg1, IntArg2),
468	    {TA1, TA2, FA1, FA2};
469	  '>' ->
470	    {TA2, TA1, FA2, FA1} = int_range_lt_propagator(IntArg2, IntArg1),
471	    {TA1, TA2, FA1, FA2};
472	  '<' ->
473	    int_range_lt_propagator(IntArg1, IntArg2);
474	  '=<' ->
475	    {FA2, FA1, TA2, TA1} = int_range_lt_propagator(IntArg2, IntArg1),
476	    {TA1, TA2, FA1, FA2}
477	end,
478      ?ineq_debug("int res", [TrueArg1, TrueArg2, FalseArg1, FalseArg2]),
479      False = {FalseLab, enter(A1, t_sup(FalseArg1, NonIntArg1),
480			       enter(A2, t_sup(FalseArg2, NonIntArg2), Info))},
481      True = {TrueLab, enter(A1, t_sup(TrueArg1, NonIntArg1),
482			     enter(A2, t_sup(TrueArg2, NonIntArg2), Info))},
483      [True, False]
484  end.
485
486int_range_lt_propagator(IntArg1, IntArg2) ->
487  Min1 = number_min(IntArg1),
488  Max1 = number_max(IntArg1),
489  Min2 = number_min(IntArg2),
490  Max2 = number_max(IntArg2),
491  %% is this the same as erl_types:t_subtract?? no ... ??
492  TrueMax1 = erl_types:min(Max1, erl_bif_types:infinity_add(Max2, -1)),
493  TrueMin2 = erl_types:max(erl_bif_types:infinity_add(Min1, 1), Min2),
494  FalseMin1 = erl_types:max(Min1, Min2),
495  FalseMax2 = erl_types:min(Max1, Max2),
496  {t_from_range(Min1, TrueMax1),
497   t_from_range(TrueMin2, Max2),
498   t_from_range(FalseMin1, Max1),
499   t_from_range(Min2, FalseMax2)}.
500
501do_type(I, Info) ->
502  case hipe_icode:args(I) of
503    [Var] -> do_type(I, Info, Var);
504    [Var1,Var2] -> do_type2(I, Info, Var1, Var2)
505  end.
506
507do_type2(I, Info, FunVar, ArityVar) -> % function2(Fun,Arity)
508  %% Just for sanity.
509  function2 = hipe_icode:type_test(I),
510  FunType = lookup(FunVar, Info),
511  ArityType = lookup(ArityVar, Info),
512  TrueLab = hipe_icode:type_true_label(I),
513  FalseLab = hipe_icode:type_false_label(I),
514  SuccType1 = t_inf(t_fun(), FunType),
515  case combine_test(test_type(function, FunType),
516		    test_type(integer, ArityType)) of
517    true ->
518      case t_number_vals(ArityType) of
519	[Arity] ->
520	  case t_fun_arity(SuccType1) of
521	    unknown ->
522	      SuccType = t_inf(t_fun(Arity,t_any()),FunType),
523	      [{TrueLab, enter(FunVar, SuccType, Info)},
524	       {FalseLab, Info}];
525	    Arity when is_integer(Arity) ->
526	      FalseType = t_subtract(FunType, t_fun(Arity, t_any())),
527	      [{TrueLab,  enter(FunVar, SuccType1, Info)},
528	       {FalseLab, enter(FunVar, FalseType, Info)}]
529	  end;
530	_ ->
531	  case t_fun_arity(SuccType1) of
532	    unknown ->
533	      [{TrueLab, enter(FunVar,SuccType1,Info)},
534	       {FalseLab, Info}];
535	    Arity when is_integer(Arity) ->
536	      T = t_from_term(Arity),
537	      NewInfo = enter(ArityVar, T, Info),
538	      [{TrueLab, enter(FunVar, SuccType1, NewInfo)},
539	       {FalseLab, enter(ArityVar, t_subtract(T, ArityType), Info)}]
540	  end
541      end;
542    false ->
543      [{FalseLab, Info}];
544    maybe ->
545      GenTrueArity = t_inf(t_integer(), ArityType),
546      GenTrueFun = t_inf(t_fun(), FunType),
547      case {t_number_vals(GenTrueArity), t_fun_arity(GenTrueFun)} of
548	{unknown, unknown} ->
549	  TrueInfo = enter_list([FunVar, ArityVar],
550				[GenTrueFun, GenTrueArity], Info),
551	  [{TrueLab, TrueInfo}, {FalseLab, Info}];
552	{unknown, Arity} when is_integer(Arity) ->
553	  TrueInfo = enter_list([FunVar, ArityVar],
554				[GenTrueFun, t_integer(Arity)], Info),
555	  [{TrueLab, TrueInfo}, {FalseLab, Info}];
556	{[Val], unknown} when is_integer(Val) ->
557	  TrueInfo = enter_list([FunVar, ArityVar],
558				[t_inf(GenTrueFun, t_fun(Val, t_any())),
559				 GenTrueArity], Info),
560	  [{TrueLab, TrueInfo}, {FalseLab, Info}];
561	{Vals, unknown} when is_list(Vals) ->
562	  %% The function type gets widened when we have more than one arity.
563	  TrueInfo = enter_list([FunVar, ArityVar],
564				[GenTrueFun, GenTrueArity], Info),
565	  [{TrueLab, TrueInfo}, {FalseLab, Info}];
566	{Vals, Arity} when is_list(Vals), is_integer(Arity) ->
567	  case lists:member(Arity, Vals) of
568	    false ->
569	      [{FalseLab, Info}];
570	    true ->
571	      TrueInfo = enter_list([FunVar, ArityVar],
572				    [GenTrueFun, t_integer(Arity)], Info),
573	      [{TrueLab, TrueInfo}, {FalseLab, Info}]
574	  end
575      end
576  end.
577
578combine_test(true, true) -> true;
579combine_test(false, _)   -> false;
580combine_test(_, false)   -> false;
581combine_test(_, _)       -> maybe.
582
583do_type(I, Info, Var) ->
584  TrueLab = hipe_icode:type_true_label(I),
585  FalseLab = hipe_icode:type_false_label(I),
586  None = t_none(),
587  case lookup(Var, Info) of
588    None ->
589      [{TrueLab, Info}, {FalseLab, Info}];
590    VarInfo ->
591      case hipe_icode:type_test(I) of
592	cons ->
593	  test_cons_or_nil(t_cons(), Var, VarInfo, TrueLab, FalseLab, Info);
594	nil ->
595	  test_cons_or_nil(t_nil(), Var, VarInfo, TrueLab, FalseLab, Info);
596	{atom, A} = Test ->
597	  test_number_or_atom(fun(X) -> t_atom(X) end,
598			      A, Var, VarInfo, Test, TrueLab, FalseLab, Info);
599	{integer, N} = Test ->
600	  test_number_or_atom(fun(X) -> t_number(X) end,
601			      N, Var, VarInfo, Test, TrueLab, FalseLab, Info);
602	{record, Atom, Size} ->
603	  test_record(Atom, Size, Var, VarInfo, TrueLab, FalseLab, Info);
604	Other ->
605	  case t_is_any(VarInfo) of
606	    true ->
607	      TrueType = t_inf(true_branch_info(Other), VarInfo),
608	      TrueInfo = enter(Var, TrueType, Info),
609	      [{TrueLab, TrueInfo}, {FalseLab, Info}];
610	    false ->
611	      case test_type(Other, VarInfo) of
612		true ->
613		  [{TrueLab, Info}];
614		false ->
615		  [{FalseLab, Info}];
616		maybe ->
617		  TrueType = t_inf(true_branch_info(Other), VarInfo),
618		  TrueInfo = enter(Var, TrueType, Info),
619		  FalseType = t_subtract(VarInfo, TrueType),
620		  FalseInfo = enter(Var, FalseType, Info),
621		  [{TrueLab, TrueInfo}, {FalseLab, FalseInfo}]
622	      end
623	  end
624      end
625  end.
626
627do_switch_tuple_arity(I, Info) ->
628  Var = hipe_icode:switch_tuple_arity_term(I),
629  VarType = lookup(Var, Info),
630  Cases = hipe_icode:switch_tuple_arity_cases(I),
631  FailLabel = hipe_icode:switch_tuple_arity_fail_label(I),
632  case legal_switch_tuple_arity_cases(Cases, VarType) of
633    [] ->
634      [{FailLabel, Info}];
635    LegalCases ->
636      {Fail, UpdateInfo} =
637	switch_tuple_arity_update_info(LegalCases, Var, VarType,
638				       FailLabel, VarType, Info, []),
639      case switch_tuple_arity_can_fail(LegalCases, VarType) of
640	true -> [Fail|UpdateInfo];
641	false -> UpdateInfo
642      end
643  end.
644
645legal_switch_tuple_arity_cases(Cases, Type) ->
646  case t_is_tuple(Type) of
647    false ->
648      Inf = t_inf(t_tuple(), Type),
649      case t_is_tuple(Inf) of
650	true -> legal_switch_tuple_arity_cases_1(Cases, Inf);
651	false -> []
652      end;
653    true ->
654      legal_switch_tuple_arity_cases_1(Cases, Type)
655  end.
656
657legal_switch_tuple_arity_cases_1(Cases, Type) ->
658  case t_tuple_sizes(Type) of
659    unknown ->
660      Cases;
661    TupleSizes ->
662      [Case || {Size, _Label} = Case <- Cases,
663	       lists:member(hipe_icode:const_value(Size), TupleSizes)]
664  end.
665
666switch_tuple_arity_can_fail(LegalCases, ArgType) ->
667  case t_is_tuple(ArgType) of
668    false -> true;
669    true ->
670      case t_tuple_sizes(ArgType) of
671	unknown -> true;
672	Sizes1 ->
673	  Sizes2 = [hipe_icode:const_value(X) || {X, _} <- LegalCases],
674	  Set1 = sets:from_list(Sizes1),
675	  Set2 = sets:from_list(Sizes2),
676	  not sets:is_subset(Set1, Set2)
677      end
678  end.
679
680switch_tuple_arity_update_info([{Arity, Label}|Left], Var, TupleType,
681			       FailLabel, FailType, Info, Acc) ->
682  Inf = t_inf(TupleType, t_tuple(hipe_icode:const_value(Arity))),
683  NewInfo = enter(Var, Inf, Info),
684  NewFailType = t_subtract(FailType, Inf),
685  switch_tuple_arity_update_info(Left, Var, TupleType, FailLabel, NewFailType,
686				 Info, [{Label, NewInfo}|Acc]);
687switch_tuple_arity_update_info([], Var, _TupleType,
688			       FailLabel, FailType, Info, Acc) ->
689  {{FailLabel, enter(Var, FailType, Info)}, Acc}.
690
691do_switch_val(I, Info) ->
692  Var = hipe_icode:switch_val_term(I),
693  VarType = lookup(Var, Info),
694  Cases = hipe_icode:switch_val_cases(I),
695  FailLabel = hipe_icode:switch_val_fail_label(I),
696  case legal_switch_val_cases(Cases, VarType) of
697    [] ->
698      [{FailLabel, Info}];
699    LegalCases ->
700      switch_val_update_info(LegalCases, Var, VarType,
701			     FailLabel, VarType, Info, [])
702  end.
703
704legal_switch_val_cases(Cases, Type) ->
705  legal_switch_val_cases(Cases, Type, []).
706
707legal_switch_val_cases([{Val, _Label} = VL|Left], Type, Acc) ->
708  ConstType = t_from_term(hipe_icode:const_value(Val)),
709  case t_is_subtype(ConstType, Type) of
710    true ->
711      legal_switch_val_cases(Left, Type, [VL|Acc]);
712    false ->
713      legal_switch_val_cases(Left, Type, Acc)
714  end;
715legal_switch_val_cases([], _Type, Acc) ->
716  lists:reverse(Acc).
717
718switch_val_update_info([{Const, Label}|Left], Arg, ArgType,
719		       FailLabel, FailType, Info, Acc) ->
720  TrueType = t_from_term(hipe_icode:const_value(Const)),
721  NewInfo = enter(Arg, TrueType, Info),
722  NewFailType = t_subtract(FailType, TrueType),
723  switch_val_update_info(Left, Arg, ArgType, FailLabel, NewFailType,
724			 Info, [{Label, NewInfo}|Acc]);
725switch_val_update_info([], Arg, _ArgType, FailLabel, FailType,Info, Acc) ->
726  [{FailLabel, enter(Arg, FailType, Info)}|Acc].
727
728test_cons_or_nil(Type, Var, VarInfo, TrueLab, FalseLab, Info) ->
729  case t_is_any(VarInfo) of
730    true ->
731      [{TrueLab, enter(Var, Type, Info)},
732       {FalseLab, Info}];
733    false ->
734      TrueType = t_inf(VarInfo, Type),
735      FalseType = t_subtract(VarInfo, TrueType),
736      case t_is_none(FalseType) of
737	true ->
738	  [{TrueLab, Info}];
739	false ->
740	  case t_is_none(TrueType) of
741	    true ->
742	      [{FalseLab, Info}];
743	    false ->
744	      [{TrueLab, enter(Var, TrueType, Info)},
745	       {FalseLab, enter(Var, FalseType, Info)}]
746	  end
747      end
748  end.
749
750test_number_or_atom(Fun, X, Var, VarInfo, TypeTest,
751		    TrueLab, FalseLab, Info) ->
752  case t_is_any(VarInfo) of
753    true ->
754      [{TrueLab, enter(Var, Fun(X), Info)},
755       {FalseLab, Info}];
756    false ->
757      case test_type(TypeTest, VarInfo) of
758	false ->
759	  [{FalseLab, Info}];
760	true ->
761	  [{TrueLab, Info}];
762	maybe ->
763	  FalseType = t_subtract(VarInfo, Fun(X)),
764	  [{TrueLab, enter(Var, Fun(X), Info)},
765	   {FalseLab, enter(Var, FalseType, Info)}]
766      end
767  end.
768
769test_record(Atom, Size, Var, VarInfo, TrueLab, FalseLab, Info) ->
770  AnyList = lists:duplicate(Size - 1, t_any()),
771  RecordType = t_tuple([t_atom(Atom)|AnyList]),
772  Inf = t_inf(RecordType, VarInfo),
773  case t_is_none(Inf) of
774    true ->
775      [{FalseLab, Info}];
776    false ->
777      Sub = t_subtract(VarInfo, Inf),
778      case t_is_none(Sub) of
779	true ->
780	  [{TrueLab, enter(Var, Inf, Info)}];
781	false ->
782	  [{TrueLab, enter(Var, Inf, Info)},
783	   {FalseLab, enter(Var, Sub, Info)}]
784      end
785  end.
786
787test_type(Test, Type) ->
788  %% io:format("Test is: ~w\n", [Test]),
789  %% io:format("Type is: ~s\n", [format_type(Type)]),
790  Ans =
791    case t_is_any(Type) of
792      true -> maybe;
793      false ->
794	TrueTest = true_branch_info(Test),
795	Inf = t_inf(TrueTest, Type),
796	%% io:format("TrueTest is: ~s\n", [format_type(TrueTest)]),
797	%% io:format("Inf is: ~s\n", [format_type(Inf)]),
798	case t_is_equal(Type, Inf) of
799	  true ->
800	    not t_is_none(Type);
801	  false ->
802	    case t_is_equal(TrueTest, Inf) of
803	      true ->
804		case test_type0(Test, Type) of
805		  false ->
806		    maybe;
807		  true ->
808		    true;
809		  maybe ->
810		    maybe
811		end;
812	      false ->
813		case test_type0(Test, Inf) of
814		  true ->
815		    maybe;
816		  false ->
817		    false;
818		  maybe ->
819		    maybe
820		end
821	    end
822	end
823    end,
824  %% io:format("Result is: ~s\n\n", [Ans]),
825  Ans.
826
827test_type0(integer, T) ->
828  t_is_integer(T);
829test_type0({integer, N}, T) ->
830  case t_is_integer(T) of
831    true ->
832      case t_number_vals(T) of
833	unknown -> maybe;
834	[N] -> true;
835	List when is_list(List) ->
836	  case lists:member(N, List) of
837	    true -> maybe;
838	    false -> false
839	  end
840      end;
841    false -> false
842  end;
843test_type0(float, T) ->
844  t_is_float(T);
845test_type0(number, T) ->
846  t_is_number(T);
847test_type0(atom, T) ->
848  t_is_atom(T);
849test_type0({atom, A}, T) ->
850  case t_is_atom(T) of
851    true ->
852      case t_atom_vals(T) of
853	unknown -> maybe;
854	[A] -> true;
855	List when is_list(List) ->
856	  case lists:member(A, List) of
857	    true -> maybe;
858	    false -> false
859	  end
860      end;
861    false -> false
862  end;
863test_type0(tuple, T) ->
864  t_is_tuple(T);
865test_type0({tuple, N}, T) ->
866  case t_is_tuple(T) of
867    true ->
868      case t_tuple_sizes(T) of
869	unknown -> maybe;
870	[X] when is_integer(X) -> X =:= N;
871	List when is_list(List) ->
872	  case lists:member(N, List) of
873	    true -> maybe;
874	    false -> false
875	  end
876      end;
877    false -> false
878  end;
879test_type0(pid, T) ->
880  t_is_pid(T);
881test_type0(port, T) ->
882  t_is_port(T);
883test_type0(binary, T) ->
884  t_is_binary(T);
885test_type0(bitstr, T) ->
886  t_is_bitstr(T);
887test_type0(reference, T) ->
888  t_is_reference(T);
889test_type0(function, T) ->
890  t_is_fun(T);
891test_type0(boolean, T) ->
892  t_is_boolean(T);
893test_type0(list, T) ->
894  t_is_maybe_improper_list(T);
895%% test_type0(cons, T) ->
896%%   t_is_cons(T);
897%% test_type0(nil, T) ->
898%%   t_is_nil(T).
899test_type0(map, T) ->
900  t_is_map(T).
901
902true_branch_info(integer) ->
903  t_integer();
904true_branch_info({integer, N}) ->
905  t_integer(N);
906true_branch_info(float) ->
907  t_float();
908true_branch_info(number) ->
909  t_number();
910true_branch_info(atom) ->
911  t_atom();
912true_branch_info({atom, A}) ->
913  t_atom(A);
914true_branch_info(list) ->
915  t_maybe_improper_list();
916true_branch_info(tuple) ->
917  t_tuple();
918true_branch_info({tuple, N}) ->
919  t_tuple(N);
920true_branch_info(pid) ->
921  t_pid();
922true_branch_info(port) ->
923  t_port();
924true_branch_info(binary) ->
925  t_binary();
926true_branch_info(bitstr) ->
927  t_bitstr();
928true_branch_info(reference) ->
929  t_reference();
930true_branch_info(function) ->
931  t_fun();
932%% true_branch_info(cons) ->
933%%   t_cons();
934%% true_branch_info(nil) ->
935%%   t_nil();
936true_branch_info(boolean) ->
937  t_boolean();
938true_branch_info(map) ->
939  t_map();
940true_branch_info(T) ->
941  exit({?MODULE, unknown_typetest, T}).
942
943
944%% _________________________________________________________________
945%%
946%% Remove the redundant type tests. If a test is removed, the trace
947%% that isn't taken is explicitly removed from the CFG to simplify
948%% the handling of Phi nodes. If a Phi node is left and at least one
949%% branch into it has disappeared, the SSA propagation pass cannot
950%% handle it.
951%%
952%% If the CFG has changed at the end of this pass, the analysis is
953%% done again since we might be able to find more information because
954%% of the simplification of the CFG.
955%%
956
957simplify_controlflow(State) ->
958  Cfg = state__cfg(State),
959  simplify_controlflow(hipe_icode_cfg:reverse_postorder(Cfg), State).
960
961simplify_controlflow([Label|Left], State) ->
962  Info = state__info_out(State, Label),
963  NewState =
964    case state__bb(State, Label) of
965      not_found -> State;
966      BB ->
967	I = hipe_bb:last(BB),
968	case I of
969	  #icode_if{} ->
970	    rewrite_if(State,I,BB,Info,Label);
971	  #icode_type{} ->
972	    rewrite_type(State,I,BB,Info,Label);
973	  #icode_switch_tuple_arity{} ->
974	    rewrite_switch_tuple_arity(State,I,BB,Info,Label);
975	  #icode_switch_val{} ->
976	    rewrite_switch_val(State,I,BB,Info,Label);
977	  #icode_call{} ->
978	    rewrite_call(State,I,BB,Info,Label);
979	  _ ->
980	    State
981	end
982    end,
983  simplify_controlflow(Left, NewState);
984simplify_controlflow([], State) ->
985  State.
986
987rewrite_if(State, I, BB, Info, Label) ->
988  case do_if(I, Info) of
989    [{Lab, _}] ->
990      mk_goto(State, BB, Label, Lab);
991    [_,_] ->
992      State
993  end.
994
995rewrite_type(State, I, BB, Info, Label) ->
996  FalseLab = hipe_icode:type_false_label(I),
997  case hipe_icode:type_true_label(I) of
998    FalseLab ->
999      %% true label = false label, this can occur!
1000      mk_goto(State, BB, Label, FalseLab);
1001    TrueLab ->
1002      case do_type(I, Info) of
1003	[{TrueLab, _}] ->
1004	  mk_goto(State, BB, Label, TrueLab);
1005	[{FalseLab, _}] ->
1006	  mk_goto(State, BB, Label, FalseLab);
1007	[_,_] -> %% Maybe
1008	  State
1009      end
1010  end.
1011
1012rewrite_switch_tuple_arity(State, I, BB, Info, Label) ->
1013  Cases = hipe_icode:switch_tuple_arity_cases(I),
1014  Var = hipe_icode:switch_tuple_arity_term(I),
1015  Type = safe_lookup(Var, Info),
1016  case legal_switch_tuple_arity_cases(Cases, Type) of
1017    [] ->
1018      Fail = hipe_icode:switch_tuple_arity_fail_label(I),
1019      mk_goto(State, BB, Label, Fail);
1020    Cases ->
1021      %% Nothing changed.
1022      case switch_tuple_arity_can_fail(Cases, Type) of
1023	true -> State;
1024	false ->
1025	  NewCases = butlast(Cases),
1026	  {_Arity, NewFail} = lists:last(Cases),
1027	  TmpI =
1028	    hipe_icode:switch_tuple_arity_fail_label_update(I, NewFail),
1029	  NewI =
1030	    hipe_icode:switch_tuple_arity_cases_update(TmpI, NewCases),
1031	  NewBB = hipe_bb:code_update(BB, hipe_bb:butlast(BB) ++ [NewI]),
1032	  state__bb_add(State, Label, NewBB)
1033      end;
1034    LegalCases ->
1035      NewI =
1036	case switch_tuple_arity_can_fail(LegalCases, Type) of
1037	  true ->
1038	    hipe_icode:switch_tuple_arity_cases_update(I, LegalCases);
1039	  false ->
1040	    NewCases = butlast(LegalCases),
1041	    {_Arity, NewFail} = lists:last(LegalCases),
1042	    TmpI =
1043	      hipe_icode:switch_tuple_arity_cases_update(I, NewCases),
1044	    hipe_icode:switch_tuple_arity_fail_label_update(TmpI, NewFail)
1045	end,
1046      NewBB = hipe_bb:code_update(BB, hipe_bb:butlast(BB) ++ [NewI]),
1047      state__bb_add(State, Label, NewBB)
1048  end.
1049
1050rewrite_switch_val(State, I, BB, Info, Label) ->
1051  Cases = hipe_icode:switch_val_cases(I),
1052  Var = hipe_icode:switch_val_term(I),
1053  VarType = safe_lookup(Var, Info),
1054  case legal_switch_val_cases(Cases, VarType) of
1055    [] ->
1056      Fail = hipe_icode:switch_val_fail_label(I),
1057      mk_goto(State, BB, Label, Fail);
1058    Cases ->
1059      State;
1060    %% TODO: Find out whether switch_val can fail
1061    %% just as switch_tuple_arity
1062    LegalCases ->
1063      NewI = hipe_icode:switch_val_cases_update(I, LegalCases),
1064      NewBB = hipe_bb:code_update(BB, hipe_bb:butlast(BB) ++ [NewI]),
1065      state__bb_add(State, Label, NewBB)
1066  end.
1067
1068rewrite_call(State,I,BB,Info,Label) ->
1069  case call_always_fails(I, Info) of
1070    false ->
1071      Fun = hipe_icode:call_fun(I),
1072      case hipe_icode_primops:fails(Fun) of
1073	false ->
1074	  case hipe_icode:call_fail_label(I) of
1075	    [] -> State;
1076	    _ -> unset_fail(State, BB, Label, I)
1077	  end;
1078	true -> State
1079      end;
1080    true ->
1081      case hipe_icode:call_in_guard(I) of
1082	false -> State;
1083	true ->
1084	  FailLabel = hipe_icode:call_fail_label(I),
1085	  mk_goto(State, BB, Label, FailLabel)
1086      end
1087  end.
1088
1089mk_goto(State, BB, Label, Succ) ->
1090  NewI = hipe_icode:mk_goto(Succ),
1091  NewBB = hipe_bb:code_update(BB, hipe_bb:butlast(BB) ++ [NewI]),
1092  state__bb_add(State, Label, NewBB).
1093
1094unset_fail(State, BB, Label, I) ->
1095  %%io:format("Setting a guard that cannot fail\n", []),
1096  NewI = hipe_icode:call_set_fail_label(I, []),
1097  NewBB = hipe_bb:code_update(BB, hipe_bb:butlast(BB) ++ [NewI]),
1098  state__bb_add(State, Label, NewBB).
1099
1100%% _________________________________________________________________
1101%%
1102%% Make transformations (specialisations) based on the type knowledge.
1103%%
1104%% Annotate the variables with the local information. Since we have
1105%% the code in SSA form and the type information can only depend on
1106%% assignments or branches (type tests), we can use the information
1107%% out of the block to annotate all variables in it.
1108%%
1109
1110-spec specialize(cfg()) -> cfg().
1111
1112specialize(Cfg) ->
1113  Labels = hipe_icode_cfg:reverse_postorder(Cfg),
1114  transform_bbs(Labels, Cfg).
1115
1116transform_bbs([Label|Left], Cfg) ->
1117  BB = hipe_icode_cfg:bb(Cfg, Label),
1118  Code = hipe_bb:code(BB),
1119  NewCode = make_transformations(Code),
1120  NewBB = hipe_bb:code_update(BB, NewCode),
1121  NewCfg = hipe_icode_cfg:bb_add(Cfg, Label, NewBB),
1122  transform_bbs(Left, NewCfg);
1123transform_bbs([], Cfg) ->
1124  Cfg.
1125
1126make_transformations(Is) ->
1127  lists:flatten([transform_insn(I) || I <- Is]).
1128
1129transform_insn(I) ->
1130  case I of
1131    #icode_call{} ->
1132      handle_call_and_enter(I);
1133    #icode_enter{} ->
1134      handle_call_and_enter(I);
1135    #icode_if{} ->
1136      CurrentIfOp = hipe_icode:if_op(I),
1137      UsesFixnums = all_fixnums([get_type(A) || A <- hipe_icode:args(I)]),
1138      AnyImmediate = any_immediate([get_type(A) || A <- hipe_icode:args(I)]),
1139      ExactComp = is_exact_comp(CurrentIfOp),
1140      if UsesFixnums ->
1141	  hipe_icode:if_op_update(I, fixnum_ifop(CurrentIfOp));
1142	 AnyImmediate andalso ExactComp ->
1143	  hipe_icode:if_op_update(I, fixnum_ifop(CurrentIfOp));
1144	 true ->
1145	  I
1146      end;
1147    _ ->
1148      I
1149  end.
1150
1151handle_call_and_enter(I) ->
1152  case call_or_enter_fun(I) of
1153    #element{} ->
1154      transform_insn(update_call_or_enter(I, {erlang, element, 2}));
1155    {erlang, element, 2} ->
1156      NewI1 = transform_element2(I),
1157      case is_record(I, icode_call) andalso hipe_icode:call_in_guard(I) of
1158	true ->
1159	  case hipe_icode:call_fun(NewI1) of
1160	    #unsafe_element{} -> NewI1;
1161	    _ -> I
1162	  end;
1163	false ->
1164	  NewI1
1165      end;
1166    {erlang, hd, 1} -> transform_hd_or_tl(I, unsafe_hd);
1167    {erlang, tl, 1} -> transform_hd_or_tl(I, unsafe_tl);
1168    {hipe_bs_primop, BsOP} ->
1169      NewBsOp =
1170	bit_opts(BsOP, get_type_list(hipe_icode:args(I))),
1171      update_call_or_enter(I, {hipe_bs_primop, NewBsOp});
1172    conv_to_float ->
1173      [Src] = hipe_icode:args(I),
1174      case t_is_float(get_type(Src)) of
1175	true ->
1176	  update_call_or_enter(I, unsafe_untag_float);
1177	false ->
1178	  I
1179      end;
1180    FunName ->
1181      case is_arith_function(FunName) of
1182	true ->
1183	  case strength_reduce(I, FunName) of
1184	    NewIs when is_list(NewIs) ->
1185	      [pos_transform_arith(NewI) || NewI <- NewIs];
1186	    NewI ->
1187	      pos_transform_arith(NewI)
1188	  end;
1189	false ->
1190	  I
1191      end
1192  end.
1193
1194pos_transform_arith(I) ->
1195  case hipe_icode:is_enter(I) orelse hipe_icode:is_call(I) of
1196    true ->
1197      FunName = call_or_enter_fun(I),
1198      transform_arith(I, FunName);
1199    false ->
1200      I
1201  end.
1202
1203is_arith_function(Name) ->
1204  case Name of
1205    'band' -> true;
1206    'bor'  -> true;
1207    'bxor' -> true;
1208    'bnot' -> true;
1209    'bsl'  -> true;
1210    'bsr'  -> true;
1211    '+'    -> true;
1212    '-'    -> true;
1213    '*'    -> true;
1214    'div'  -> true;
1215    'rem'  -> true;
1216    _      -> false
1217  end.
1218
1219%%---------------------------------------------------------------------
1220%% Perform a limited form of strength reduction for multiplication and
1221%% division of an integer with constants which are multiples of 2.
1222%%---------------------------------------------------------------------
1223
1224strength_reduce(I, Op) ->
1225  case Op of
1226    '*' ->
1227      [Arg1, Arg2] = mult_args_const_second(I),
1228      ArgT1 = get_type(Arg1),
1229      case t_is_integer(ArgT1) of
1230	true ->
1231          case hipe_icode:is_const(Arg2) of
1232            true ->
1233              case hipe_icode:const_value(Arg2) of
1234		  0 -> case call_dstlist(I) of
1235			 [] -> remove_useless_arithmetic_instruction(I);
1236			 [Dst] -> create_strength_reduce_move(I, Dst, Arg2)
1237		       end;
1238		  1 -> case call_dstlist(I) of
1239			 [] -> remove_useless_arithmetic_instruction(I);
1240			 [Dst] -> create_strength_reduce_move(I, Dst, Arg1)
1241		       end;
1242		  2 -> strength_reduce_imult(I, Arg1, 1);
1243		  4 -> strength_reduce_imult(I, Arg1, 2);
1244		  8 -> strength_reduce_imult(I, Arg1, 3);
1245		 16 -> strength_reduce_imult(I, Arg1, 4);
1246		 32 -> strength_reduce_imult(I, Arg1, 5);
1247		 64 -> strength_reduce_imult(I, Arg1, 6);
1248                128 -> strength_reduce_imult(I, Arg1, 7);
1249                256 -> strength_reduce_imult(I, Arg1, 8);
1250                ___ -> I
1251	      end;
1252            false -> I
1253          end;
1254        false -> I
1255      end;
1256    'div' ->
1257      [Arg1, Arg2] = hipe_icode:args(I),
1258      ArgT1 = get_type(Arg1),
1259      case t_is_non_neg_integer(ArgT1) of
1260        true -> %% the optimization is NOT valid for negative integers
1261          case hipe_icode:is_const(Arg2) of
1262            true ->
1263              case hipe_icode:const_value(Arg2) of
1264		  0 -> io:fwrite("Integer division by 0 detected!\n"), I;
1265		  1 -> case call_dstlist(I) of
1266			 [] -> remove_useless_arithmetic_instruction(I);
1267			 [Dst] -> create_strength_reduce_move(I, Dst, Arg1)
1268		       end;
1269		  2 -> strength_reduce_div(I, Arg1, 1);
1270		  4 -> strength_reduce_div(I, Arg1, 2);
1271		  8 -> strength_reduce_div(I, Arg1, 3);
1272		 16 -> strength_reduce_div(I, Arg1, 4);
1273		 32 -> strength_reduce_div(I, Arg1, 5);
1274		 64 -> strength_reduce_div(I, Arg1, 6);
1275                128 -> strength_reduce_div(I, Arg1, 7);
1276                256 -> strength_reduce_div(I, Arg1, 8);
1277                ___ -> I
1278	      end;
1279            false -> I
1280          end;
1281        false -> I
1282      end;
1283    'rem' ->
1284      [Arg1, Arg2] = hipe_icode:args(I),
1285      ArgT1 = get_type(Arg1),
1286      case t_is_non_neg_integer(ArgT1) of
1287	true -> %% the optimization is NOT valid for negative integers
1288	  case hipe_icode:is_const(Arg2) of
1289	    true ->
1290	      case hipe_icode:const_value(Arg2) of
1291		  0 -> io:fwrite("Remainder with 0 detected!\n"), I;
1292		  1 -> case call_dstlist(I) of
1293			 [] -> remove_useless_arithmetic_instruction(I);
1294			 [Dst] -> create_strength_reduce_move(
1295				    I, Dst, hipe_icode:mk_const(0))
1296		       end;
1297		  2 -> strength_reduce_rem(I, Arg1,   1);
1298		  4 -> strength_reduce_rem(I, Arg1,   3);
1299		  8 -> strength_reduce_rem(I, Arg1,   7);
1300		 16 -> strength_reduce_rem(I, Arg1,  15);
1301		 32 -> strength_reduce_rem(I, Arg1,  31);
1302		 64 -> strength_reduce_rem(I, Arg1,  63);
1303		128 -> strength_reduce_rem(I, Arg1, 127);
1304		256 -> strength_reduce_rem(I, Arg1, 255);
1305                ___ -> I
1306	      end;
1307            false -> I
1308          end;
1309        false -> I
1310      end;
1311    _ -> I
1312  end.
1313
1314remove_useless_arithmetic_instruction(_) ->
1315  [].
1316
1317create_strength_reduce_move(I, Dst, Val) ->
1318  case hipe_icode:call_continuation(I) of
1319    [] ->
1320      hipe_icode:mk_move(Dst, Val);
1321    Lbl ->
1322      [hipe_icode:mk_move(Dst, Val),
1323       hipe_icode:mk_goto(Lbl)]
1324  end.
1325
1326%% Puts the args of a multiplication in a form where the constant
1327%% (if present) is always the second argument.
1328mult_args_const_second(I) ->
1329  [Arg1, Arg2] = Args = hipe_icode:args(I),
1330  case hipe_icode:is_const(Arg1) of
1331    true  -> [Arg2, Arg1];
1332    false -> Args
1333  end.
1334
1335%% In all three functions below:
1336%%   - Arg1 is a variable of integer type
1337%%   - N is a small positive integer that will be used in a bit shift operation
1338strength_reduce_imult(I, Arg1, N) ->
1339  case t_number_vals(get_type(Arg1)) of
1340    [X] when is_integer(X) ->
1341      %% io:format("Multiplication with constant arguments:\n  ~w\n", [I]),
1342      case call_dstlist(I) of
1343	[] -> remove_useless_arithmetic_instruction(I);
1344	[D] -> create_strength_reduce_move(I, D, hipe_icode:mk_const(X bsl N))
1345      end;
1346    _ ->
1347      update_call_or_enter(I, 'bsl', [Arg1, hipe_icode:mk_const(N)])
1348  end.
1349
1350strength_reduce_div(I, Arg1, N) ->
1351  case t_number_vals(get_type(Arg1)) of
1352    [X] when is_integer(X) ->
1353      %% io:format("Division with constant arguments:\n  ~w\n", [I]),
1354      case call_dstlist(I) of
1355	[] -> remove_useless_arithmetic_instruction(I);
1356	[D] -> create_strength_reduce_move(I, D, hipe_icode:mk_const(X bsr N))
1357      end;
1358    _ ->
1359      update_call_or_enter(I, 'bsr', [Arg1, hipe_icode:mk_const(N)])
1360  end.
1361
1362strength_reduce_rem(I, Arg1, N) ->
1363  case t_number_vals(get_type(Arg1)) of
1364    [X] when is_integer(X) ->
1365      %% io:format("Remainder with constant arguments:\n  ~w\n", [I]),
1366      case call_dstlist(I) of
1367	[] -> remove_useless_arithmetic_instruction(I);
1368	[D] -> create_strength_reduce_move(I, D, hipe_icode:mk_const(X band N))
1369      end;
1370    _ ->
1371      update_call_or_enter(I, 'band', [Arg1, hipe_icode:mk_const(N)])
1372  end.
1373
1374%%---------------------------------------------------------------------
1375
1376call_or_enter_fun(I) ->
1377  case hipe_icode:is_call(I) of
1378    true -> hipe_icode:call_fun(I);
1379    false -> hipe_icode:enter_fun(I)
1380  end.
1381
1382update_call_or_enter(I, NewFun) ->
1383  case hipe_icode:is_call(I) of
1384    true ->
1385      case hipe_icode_primops:fails(NewFun) of
1386	false ->
1387	  NewI = hipe_icode:call_fun_update(I, NewFun),
1388	  hipe_icode:call_set_fail_label(NewI, []);
1389	true ->
1390	  hipe_icode:call_fun_update(I, NewFun)
1391      end;
1392    false -> hipe_icode:enter_fun_update(I, NewFun)
1393  end.
1394
1395update_call_or_enter(I, NewFun, NewArgs) ->
1396  case hipe_icode:is_call(I) of
1397    true ->
1398      I1 = hipe_icode:call_args_update(I, NewArgs),
1399      hipe_icode:call_fun_update(I1, NewFun);
1400    false ->
1401      I1 = hipe_icode:enter_args_update(I, NewArgs),
1402      hipe_icode:enter_fun_update(I1, NewFun)
1403  end.
1404
1405transform_element2(I) ->
1406  [Index, Tuple] = hipe_icode:args(I),
1407  IndexType = get_type(Index),
1408  TupleType = get_type(Tuple),
1409  ?debug("Tuple", TupleType),
1410  NewIndex =
1411    case test_type(integer, IndexType) of
1412      true ->
1413	case {number_min(IndexType), number_max(IndexType)} of
1414	  {Lb0, Ub0} when is_integer(Lb0), is_integer(Ub0) ->
1415	    {number, Lb0, Ub0};
1416	  {_, _} -> unknown
1417	end;
1418      _ -> unknown
1419    end,
1420  MinSize =
1421    case test_type(tuple, TupleType) of
1422      true ->
1423	?debug("is tuple", TupleType),
1424	case t_tuple_sizes(TupleType) of
1425	  unknown -> unknown;
1426	  Sizes -> {tuple, lists:min(Sizes)}
1427	end;
1428      _ -> unknown
1429    end,
1430  case {NewIndex, MinSize} of
1431    {{number, Lb, Ub}, {tuple, A}} when is_integer(A) ->
1432      case 0 < Lb andalso Ub =< A of
1433	true ->
1434	  case {Lb, Ub} of
1435	    {Idx, Idx} ->
1436	      [_, Tuple] = hipe_icode:args(I),
1437	      update_call_or_enter(I, #unsafe_element{index = Idx}, [Tuple]);
1438	    {_, _} ->
1439	      NewFun = {element, [MinSize, valid]},
1440	      update_call_or_enter(I, NewFun)
1441	  end;
1442	false ->
1443	  case lists:all(fun(X) -> hipe_tagscheme:is_fixnum(X) end, [Lb, Ub]) of
1444	    true ->
1445	      NewFun = {element, [MinSize, fixnums]},
1446	      update_call_or_enter(I, NewFun);
1447	    false ->
1448	      NewFun = {element, [MinSize, unknown]},
1449	      update_call_or_enter(I, NewFun)
1450	  end
1451      end;
1452    _ when (NewIndex =:= unknown) orelse (MinSize =:= unknown) ->
1453      case t_is_fixnum(IndexType) of
1454	true ->
1455	  NewFun = {element, [MinSize, fixnums]},
1456	  update_call_or_enter(I, NewFun);
1457	false ->
1458	  NewFun = {element, [MinSize, NewIndex]},
1459	  update_call_or_enter(I, NewFun)
1460      end
1461  end.
1462
1463transform_hd_or_tl(I, Primop) ->
1464  [Arg] = hipe_icode:args(I),
1465  case t_is_cons(get_type(Arg)) of
1466    true -> update_call_or_enter(I, Primop);
1467    false -> I
1468  end.
1469
1470transform_arith(I, Op) ->
1471  ArgTypes = get_type_list(hipe_icode:args(I)),
1472  %% io:format("Op = ~w, Args = ~w\n", [Op, ArgTypes]),
1473  DstTypes =
1474    case hipe_icode:is_call(I) of
1475      true -> get_type_list(call_dstlist(I));
1476      false -> [erl_bif_types:type(erlang, Op, length(ArgTypes), ArgTypes)]
1477    end,
1478  case valid_unsafe_args(ArgTypes, Op) of
1479    true ->
1480      case all_is_fixnum(DstTypes) of
1481	true ->
1482	  update_call_or_enter(I, arithop_to_extra_unsafe(Op));
1483	false ->
1484	  update_call_or_enter(I, arithop_to_unsafe(Op))
1485      end;
1486    false ->
1487      I
1488  end.
1489
1490all_is_fixnum(Types) ->
1491  lists:all(fun erl_types:t_is_fixnum/1, Types).
1492
1493valid_unsafe_args(Args, Op) ->
1494  if Op =:= 'bnot' ->
1495      [Arg] = Args,
1496      t_is_fixnum(Arg);
1497     true ->
1498      [LeftArg, RightArg] = Args,
1499      case Op of
1500	'bsl' -> t_is_fixnum(LeftArg) and t_is_bitwidth(RightArg);
1501	'bsr' -> t_is_fixnum(LeftArg) and t_is_bitwidth(RightArg);
1502	_     -> t_is_fixnum(LeftArg) and t_is_fixnum(RightArg)
1503      end
1504  end.
1505
1506arithop_to_extra_unsafe(Op) ->
1507  case Op of
1508    '+'    -> extra_unsafe_add;
1509    '-'    -> extra_unsafe_sub;
1510    '*'    -> '*';	%% XXX: Revise?
1511    'div'  -> 'div';	%% XXX: Revise?
1512    'rem'  -> 'rem';    %% XXX: Revise?
1513    'band' -> unsafe_band;
1514    'bor'  -> unsafe_bor;
1515    'bxor' -> unsafe_bxor;
1516    'bnot' -> unsafe_bnot;
1517    'bsl'  -> unsafe_bsl;
1518    'bsr'  -> unsafe_bsr
1519  end.
1520
1521arithop_to_unsafe(Op) ->
1522  case Op of
1523    '+' -> unsafe_add;
1524    '-' -> unsafe_sub;
1525    _   -> Op
1526  end.
1527
1528fixnum_ifop(Op) ->
1529  case Op of
1530    '=:=' -> 'fixnum_eq';
1531    '=/=' -> 'fixnum_neq';
1532    '==' -> 'fixnum_eq';
1533    '/=' -> 'fixnum_neq';
1534    '>'   -> 'fixnum_gt';
1535    '<'   -> 'fixnum_lt';
1536    '>='  -> 'fixnum_ge';
1537    '=<'  -> 'fixnum_le';
1538    Op    -> Op
1539  end.
1540
1541bit_opts({Name, Size, Flags} = I, [MSType]) when Name =:= bs_get_integer;
1542						 Name =:= bs_get_float;
1543						 Name =:= bs_get_binary ->
1544  Bits = t_matchstate_present(MSType),
1545  case t_is_bitstr(Bits) of
1546    true ->
1547      Base = t_bitstr_base(Bits),
1548      if Base >= Size ->
1549	  {Name, Size, Flags bor 16};
1550	 true -> I
1551      end;
1552    false -> I
1553  end;
1554bit_opts({bs_get_binary_all, Size, Flags} = I, [MSType]) ->
1555  Bits = t_matchstate_present(MSType),
1556  case t_is_bitstr(Bits) of
1557    true ->
1558      Base = t_bitstr_base(Bits),
1559      Unit = t_bitstr_unit(Bits),
1560      if (Base rem Size) =:= 0 andalso (Unit rem Size) =:= 0 ->
1561	  {bs_get_binary_all, Size, Flags bor 16};
1562	 true -> I
1563      end;
1564    false -> I
1565  end;
1566bit_opts({bs_test_unit, Size} = I, [MSType]) ->
1567  Bits = t_matchstate_present(MSType),
1568  case t_is_bitstr(Bits) of
1569    true ->
1570      Base = t_bitstr_base(Bits),
1571      Unit = t_bitstr_unit(Bits),
1572      if (Base rem Size) =:= 0 andalso (Unit rem Size) =:= 0 ->
1573	  {bs_test_unit, 1};
1574	 true -> I
1575      end;
1576    false -> I
1577  end;
1578bit_opts({bs_put_integer, Size, Flags, ConstInfo} = I, [Src|_]) ->
1579  case t_is_fixnum(Src) of
1580    true ->
1581      {unsafe_bs_put_integer, Size, Flags, ConstInfo};
1582    false -> I
1583  end;
1584bit_opts({bs_start_match, Max} = I, [Src]) ->
1585  case t_is_bitstr(Src) of
1586    true -> {{bs_start_match, bitstr}, Max};
1587    false ->
1588      MSorNone = t_inf(t_matchstate(), Src),
1589      case t_is_matchstate(MSorNone) of
1590	true ->
1591	  Slots = t_matchstate_slots(MSorNone),
1592	  case t_is_any(Slots) orelse (length(t_to_tlist(Slots)) =< Max) of
1593	    true -> I;
1594	    false -> {{bs_start_match, ok_matchstate}, Max}
1595	  end;
1596	false -> I
1597      end
1598  end;
1599bit_opts(I, _) -> I.
1600
1601is_exact_comp(Op) ->
1602  case Op of
1603    '=:=' -> true;
1604    '=/=' -> true;
1605    _Op   -> false
1606  end.
1607
1608all_fixnums([Type|Types]) ->
1609  t_is_fixnum(Type) andalso all_fixnums(Types);
1610all_fixnums([]) ->
1611  true.
1612
1613any_immediate([Type|Types]) ->
1614  t_is_fixnum(Type) orelse t_is_atom(Type) orelse any_immediate(Types);
1615any_immediate([]) -> false.
1616
1617get_standard_primop(unsafe_bsl) -> 'bsl';
1618get_standard_primop(unsafe_bsr) -> 'bsr';
1619get_standard_primop(unsafe_add) -> '+';
1620get_standard_primop(extra_unsafe_add) -> '+';
1621get_standard_primop(unsafe_bnot) -> 'bnot';
1622get_standard_primop(unsafe_bxor) -> 'bxor';
1623get_standard_primop(unsafe_band) -> 'band';
1624get_standard_primop(unsafe_bor) -> 'bor';
1625get_standard_primop(unsafe_sub) -> '-';
1626get_standard_primop(extra_unsafe_sub) -> '-';
1627get_standard_primop(Op) -> Op.
1628
1629primop_type(Op, Args) ->
1630  case Op of
1631    #mkfun{mfa = MFA} ->
1632      t_inf(t_fun(), find_signature_mfa(MFA));
1633    _ ->
1634      None = t_none(),
1635      Primop = get_standard_primop(Op),
1636      RetType = hipe_icode_primops:type(Primop, Args),
1637      case RetType of
1638	None ->
1639	  hipe_icode_primops:type(Primop, add_funs_to_arg_types(Args));
1640	Other ->
1641	  Other
1642      end
1643  end.
1644
1645%%------------------------------------------------------------------
1646%% Various help functions.
1647%%------------------------------------------------------------------
1648
1649add_arg_types(Args, Types) ->
1650  add_arg_types(Args, Types, gb_trees:empty()).
1651
1652add_arg_types([Arg|Args], [Type|Types], Acc) ->
1653  Type1 =
1654    case t_is_none(Type) of
1655      true -> t_any();
1656      false -> Type
1657    end,
1658  add_arg_types(Args,Types, enter(Arg, Type1, Acc));
1659add_arg_types(_, [], Acc) ->
1660  Acc.
1661
1662get_type_list(ArgList) ->
1663  [get_type(Arg) || Arg <- ArgList].
1664
1665get_type(Arg) ->
1666  case hipe_icode:is_annotated_variable(Arg) of
1667    true ->
1668      None = t_none(),
1669      case hipe_icode:variable_annotation(Arg) of
1670	{type_anno, None, _} -> t_any();
1671	{type_anno, Type, _} -> Type
1672      end;
1673    false ->
1674      case hipe_icode:is_const(Arg) of
1675	true -> const_type(Arg);
1676	false -> t_any()
1677      end
1678  end.
1679
1680%% Lookup treats anything that is neither in the map or a constant as
1681%% t_none(). Use this during type propagation!
1682
1683lookup(Var, Tree) ->
1684  case gb_trees:lookup(Var, Tree) of
1685    none ->
1686      case hipe_icode:is_const(Var) of
1687	true -> const_type(Var);
1688	false -> t_none()
1689      end;
1690    {value, Type} ->
1691       Type
1692  end.
1693
1694lookup_list(List, Info) ->
1695  lookup_list0(List, Info, []).
1696
1697lookup_list0([H|T], Info, Acc) ->
1698  lookup_list0(T, Info, [lookup(H, Info)|Acc]);
1699lookup_list0([], _, Acc) ->
1700  lists:reverse(Acc).
1701
1702%% safe_lookup treats anything that is neither in the map nor a
1703%% constant as t_any(). Use this during transformations.
1704
1705safe_lookup(Var, Tree) ->
1706  case gb_trees:lookup(Var, Tree) of
1707    none ->
1708      case hipe_icode:is_const(Var) of
1709	true -> const_type(Var);
1710	false ->
1711	  %% io:format("Expression has undefined type\n",[]),
1712	  t_any()
1713      end;
1714    {value, Type} ->
1715      Type
1716  end.
1717
1718safe_lookup_list(List, Info) ->
1719  safe_lookup_list0(List, Info, []).
1720
1721safe_lookup_list0([H|T], Info, Acc) ->
1722  safe_lookup_list0(T, Info, [safe_lookup(H, Info)|Acc]);
1723safe_lookup_list0([], _, Acc) ->
1724  lists:reverse(Acc).
1725
1726enter_list([Var|VarLeft], [Type|TypeLeft], Info) ->
1727  NewInfo = enter(Var, Type, Info),
1728  enter_list(VarLeft, TypeLeft, NewInfo);
1729enter_list([], [], Info) ->
1730  Info.
1731
1732enter([Key], Value, Tree) ->
1733  enter(Key, Value, Tree);
1734enter(Key, Value, Tree) ->
1735  case is_var_or_reg(Key) of
1736    true ->
1737      case t_is_none(Value) of
1738	true ->
1739	  gb_trees:delete_any(Key, Tree);
1740	false ->
1741	  gb_trees:enter(Key, Value, Tree)
1742      end;
1743    false ->
1744      Tree
1745  end.
1746
1747join_list(List, Info) ->
1748  join_list(List, Info, t_none()).
1749
1750join_list([H|T], Info, Acc) ->
1751  Type = t_sup(lookup(H, Info), Acc),
1752  join_list(T, Info, Type);
1753join_list([], _, Acc) ->
1754  Acc.
1755
1756join_info_in([], _OldInfo, _NewInfo) ->
1757  %% No variables are live in. The information must be at a fixpoint.
1758  fixpoint;
1759join_info_in(Vars, OldInfo, NewInfo) ->
1760  NewInfo2 = join_info_in(Vars, Vars, OldInfo, NewInfo, gb_trees:empty()),
1761  case info_is_equal(NewInfo2, OldInfo) of
1762    true -> fixpoint;
1763    false -> NewInfo2
1764  end.
1765
1766%% NOTE: Variables can be bound to other variables. Joining these is
1767%% only possible if the binding is the same from both traces and this
1768%% variable is still live.
1769
1770join_info_in([Var|Left], LiveIn, Info1, Info2, Acc) ->
1771  Type1 = gb_trees:lookup(Var, Info1),
1772  Type2 = gb_trees:lookup(Var, Info2),
1773  case {Type1, Type2} of
1774    {none, none} ->
1775      join_info_in(Left, LiveIn, Info1, Info2, Acc);
1776    {none, {value, Val}} ->
1777      NewTree = gb_trees:insert(Var, Val, Acc),
1778      join_info_in(Left, LiveIn, Info1, Info2, NewTree);
1779    {{value, Val}, none} ->
1780      NewTree = gb_trees:insert(Var, Val, Acc),
1781      join_info_in(Left, LiveIn, Info1, Info2, NewTree);
1782    {{value, Val1}, {value, Val2}} ->
1783       NewTree = gb_trees:insert(Var, t_sup(Val1, Val2), Acc),
1784      join_info_in(Left, LiveIn, Info1, Info2, NewTree)
1785  end;
1786join_info_in([], _LiveIn, _Info1, _Info2, Acc) ->
1787  Acc.
1788
1789info_is_equal(Info1, Info2) ->
1790  compare(gb_trees:to_list(Info1), gb_trees:to_list(Info2)).
1791
1792compare([{Var, Type1}|Left1], [{Var, Type2}|Left2]) ->
1793  t_is_equal(Type1, Type2) andalso compare(Left1, Left2);
1794compare([], []) ->
1795  true;
1796compare(_, _) ->
1797  false.
1798
1799const_type(Const) ->
1800  t_from_term(hipe_icode:const_value(Const)).
1801
1802do_updates(State, List) ->
1803  do_updates(State, List, []).
1804
1805do_updates(State, [{Label, Info}|Tail], Worklist) ->
1806  case state__info_in_update(State, Label, Info) of
1807    fixpoint ->
1808      %% io:format("Info in for ~w is: fixpoint\n", [Label]),
1809      do_updates(State, Tail, Worklist);
1810    NewState ->
1811      %% io:format("Info in for ~w is:\n", [Label]),
1812      %% [io:format("~w: ~p\n", [X, format_type(Y)])
1813      %%  || {X, Y} <- gb_trees:to_list(state__info_in(NewState, Label))],
1814      do_updates(NewState, Tail, [Label|Worklist])
1815  end;
1816do_updates(State, [], Worklist) ->
1817  {State, Worklist}.
1818
1819enter_defines(I, Type, Info) ->
1820  case defines(I) of
1821    [] -> Info;
1822    [Def] ->
1823      enter(Def, Type, Info);
1824    Defs ->
1825      Pairs = case t_is_any(Type) of
1826		true ->
1827		  [{Def, t_any()} || Def <- Defs];
1828		false ->
1829		  case t_is_none(Type) of
1830		    true ->
1831		      [{Def, t_none()} || Def <- Defs];
1832		    false ->
1833		      lists:zip(Defs, t_to_tlist(Type))
1834		  end
1835	      end,
1836      lists:foldl(fun({X, T}, Inf) -> enter(X, T, Inf) end, Info, Pairs)
1837  end.
1838
1839defines(I) ->
1840  keep_vars_and_regs(hipe_icode:defines(I)).
1841
1842call_dstlist(I) ->
1843  hipe_icode:call_dstlist(I).
1844
1845uses(I) ->
1846  keep_vars_and_regs(hipe_icode:uses(I)).
1847
1848keep_vars_and_regs(Vars) ->
1849  [V || V <- Vars, is_var_or_reg(V)].
1850
1851butlast([_]) ->
1852  [];
1853butlast([H|T]) ->
1854  [H|butlast(T)].
1855
1856-spec any_is_none([erl_types:erl_type()]) -> boolean().
1857
1858any_is_none(Types) ->
1859  lists:any(fun (T) -> t_is_none(T) end, Types).
1860
1861is_var_or_reg(X) ->
1862  hipe_icode:is_var(X) orelse hipe_icode:is_reg(X).
1863
1864%% _________________________________________________________________
1865%%
1866%% Handling the state
1867%%
1868
1869new_state(Cfg, {MFA, GetCallFun, GetResFun, FinalAction}) ->
1870  Start = hipe_icode_cfg:start_label(Cfg),
1871  Params = hipe_icode_cfg:params(Cfg),
1872  ParamTypes = GetCallFun(MFA, Cfg),
1873  case any_is_none(ParamTypes) of
1874    true ->
1875      FinalAction(MFA, [t_none()]),
1876      throw(no_input);
1877    false ->
1878      Info = add_arg_types(Params, ParamTypes),
1879      InfoMap = gb_trees:insert({Start, in}, Info, gb_trees:empty()),
1880      Liveness = hipe_icode_ssa:ssa_liveness__analyze(Cfg),
1881      #state{info_map = InfoMap, cfg = Cfg, liveness = Liveness,
1882	     arg_types = ParamTypes, lookupfun = GetResFun,
1883	     resultaction = FinalAction}
1884  end.
1885
1886state__cfg(#state{cfg = Cfg}) ->
1887  Cfg.
1888
1889state__succ(#state{cfg = Cfg}, Label) ->
1890  hipe_icode_cfg:succ(Cfg, Label).
1891
1892state__bb(#state{cfg = Cfg}, Label) ->
1893  hipe_icode_cfg:bb(Cfg, Label).
1894
1895state__bb_add(S = #state{cfg = Cfg}, Label, BB) ->
1896  NewCfg = hipe_icode_cfg:bb_add(Cfg, Label, BB),
1897  S#state{cfg=NewCfg}.
1898
1899state__params_update(S = #state{cfg = Cfg}, NewParams) ->
1900  NewCfg = hipe_icode_cfg:params_update(Cfg, NewParams),
1901  S#state{cfg = NewCfg}.
1902
1903state__ret_type(#state{ret_type = RT}) -> RT.
1904
1905state__lookupfun(#state{lookupfun = LF}) -> LF.
1906
1907state__resultaction(#state{resultaction = RA}) -> RA.
1908
1909state__info_in(S, Label) ->
1910  state__info(S, {Label, in}).
1911
1912state__info_out(S, Label) ->
1913  state__info(S, {Label, out}).
1914
1915state__info(#state{info_map = IM}, Label) ->
1916  case gb_trees:lookup(Label, IM) of
1917    {value, Info} -> Info;
1918    none -> gb_trees:empty()
1919  end.
1920
1921state__ret_type_update(#state{ret_type = RT} = State, NewType) when
1922  is_list(NewType) ->
1923  TotType = lists:zipwith(fun erl_types:t_sup/2, RT, NewType),
1924  State#state{ret_type = TotType};
1925state__ret_type_update(#state{ret_type = RT} = State, NewType) ->
1926  state__ret_type_update(State, [NewType || _ <- RT]).
1927
1928state__info_in_update(S=#state{info_map=IM, liveness=Liveness}, Label, Info) ->
1929  LiveIn = hipe_icode_ssa:ssa_liveness__livein(Liveness, Label),
1930  LabelIn = {Label, in},
1931  case gb_trees:lookup(LabelIn, IM) of
1932    none ->
1933      OldInfo = gb_trees:empty(),
1934      case join_info_in(LiveIn, OldInfo, Info) of
1935	fixpoint ->
1936	  %% If the BB has not been handled we ignore the fixpoint.
1937	  S#state{info_map = gb_trees:enter(LabelIn, OldInfo, IM)};
1938	NewInfo ->
1939	  S#state{info_map = gb_trees:enter(LabelIn, NewInfo, IM)}
1940      end;
1941    {value, OldInfo} ->
1942      case join_info_in(LiveIn, OldInfo, Info) of
1943	fixpoint ->
1944	  fixpoint;
1945	NewInfo ->
1946	  S#state{info_map = gb_trees:enter(LabelIn, NewInfo, IM)}
1947      end
1948  end.
1949
1950state__info_out_update(#state{info_map = IM} = State, Label, Info) ->
1951  State#state{info_map = gb_trees:enter({Label, out}, Info, IM)}.
1952
1953%% _________________________________________________________________
1954%%
1955%% The worklist.
1956%%
1957
1958init_work(State) ->
1959  %% Labels = hipe_icode_cfg:reverse_postorder(state__cfg(State)),
1960  Labels = [hipe_icode_cfg:start_label(state__cfg(State))],
1961  {Labels, [], gb_sets:from_list(Labels)}.
1962
1963get_work({[Label|Left], List, Set}) ->
1964  NewWork = {Left, List, gb_sets:delete(Label, Set)},
1965  {Label, NewWork};
1966get_work({[], [], _Set}) ->
1967  fixpoint;
1968get_work({[], List, Set}) ->
1969  get_work({lists:reverse(List), [], Set}).
1970
1971add_work(Work = {List1, List2, Set}, [Label|Left]) ->
1972  case gb_sets:is_member(Label, Set) of
1973    true ->
1974      add_work(Work, Left);
1975    false ->
1976      %% io:format("Adding work: ~w\n", [Label]),
1977      add_work({List1, [Label|List2], gb_sets:insert(Label, Set)}, Left)
1978  end;
1979add_work(Work, []) ->
1980  Work.
1981
1982%% _________________________________________________________________
1983%%
1984%% Annotator
1985%%
1986
1987annotate_cfg(State) ->
1988  Cfg = state__cfg(State),
1989  NewState = annotate_params(hipe_icode_cfg:params(Cfg), State,
1990			     hipe_icode_cfg:start_label(Cfg)),
1991  Labels = hipe_icode_cfg:reverse_postorder(Cfg),
1992  annotate_bbs(Labels, NewState).
1993
1994annotate_params(Params, State, Start) ->
1995  Info = state__info_in(State, Start),
1996  AnnoFun = fun hipe_icode:annotate_variable/2,
1997  NewParams =
1998    lists:zipwith(AnnoFun, Params, [make_annotation(P,Info) || P <- Params]),
1999  state__params_update(State,NewParams).
2000
2001annotate_bbs([Label|Left], State) ->
2002  BB = state__bb(State, Label),
2003  Code = hipe_bb:code(BB),
2004  Info = state__info_in(State, Label),
2005  NewCode = annotate_instr_list(Code, Info, state__lookupfun(State), []),
2006  NewBB = hipe_bb:code_update(BB, NewCode),
2007  NewState = state__bb_add(State, Label, NewBB),
2008  annotate_bbs(Left, NewState);
2009annotate_bbs([], State) ->
2010  State.
2011
2012annotate_instr_list([I], Info, LookupFun, Acc) ->
2013  NewInfo =
2014    case I of
2015      #icode_call{} ->
2016	do_safe_call(I, Info, LookupFun);
2017      _ ->
2018	analyse_insn(I, Info, LookupFun)
2019    end,
2020  NewI = annotate_instr(I, NewInfo, Info),
2021  lists:reverse([NewI|Acc]);
2022annotate_instr_list([I|Left], Info, LookupFun, Acc) ->
2023  NewInfo =
2024    case I of
2025      #icode_call{} ->
2026	do_safe_call(I, Info, LookupFun);
2027      _ ->
2028	analyse_insn(I, Info, LookupFun)
2029    end,
2030  NewI = annotate_instr(I, NewInfo, Info),
2031  annotate_instr_list(Left, NewInfo, LookupFun, [NewI|Acc]).
2032
2033annotate_instr(I, DefInfo, UseInfo) ->
2034  Def = defines(I),
2035  Use = uses(I),
2036  Fun = fun hipe_icode:annotate_variable/2,
2037  DefSubst = [{X, Fun(X, make_annotation(X, DefInfo))} || X <- Def],
2038  UseSubst = [{X, Fun(X, make_annotation(X, UseInfo))} || X <- Use],
2039  case DefSubst ++ UseSubst of
2040    [] ->
2041      I;
2042    Subst ->
2043      hipe_icode:subst(Subst, I)
2044  end.
2045
2046make_annotation(X, Info) ->
2047  {type_anno, safe_lookup(X, Info), fun erl_types:t_to_string/1}.
2048
2049-spec unannotate_cfg(cfg()) -> cfg().
2050
2051unannotate_cfg(Cfg) ->
2052  NewCfg = unannotate_params(Cfg),
2053  Labels = hipe_icode_cfg:labels(NewCfg),
2054  unannotate_bbs(Labels, NewCfg).
2055
2056unannotate_params(Cfg) ->
2057  Params = hipe_icode_cfg:params(Cfg),
2058  NewParams = [hipe_icode:unannotate_variable(X)
2059	       || X <- Params, hipe_icode:is_variable(X)],
2060  hipe_icode_cfg:params_update(Cfg, NewParams).
2061
2062unannotate_bbs([Label|Left], Cfg) ->
2063  BB = hipe_icode_cfg:bb(Cfg, Label),
2064  Code = hipe_bb:code(BB),
2065  NewCode = unannotate_instr_list(Code, []),
2066  NewBB = hipe_bb:code_update(BB, NewCode),
2067  NewCfg = hipe_icode_cfg:bb_add(Cfg, Label, NewBB),
2068  unannotate_bbs(Left, NewCfg);
2069unannotate_bbs([], Cfg) ->
2070  Cfg.
2071
2072unannotate_instr_list([I|Left], Acc) ->
2073  NewI = unannotate_instr(I),
2074  unannotate_instr_list(Left, [NewI|Acc]);
2075unannotate_instr_list([], Acc) ->
2076  lists:reverse(Acc).
2077
2078unannotate_instr(I) ->
2079  DefUses = hipe_icode:defines(I) ++ hipe_icode:uses(I),
2080  Subst = [{X, hipe_icode:unannotate_variable(X)} || X <- DefUses,
2081						     hipe_icode:is_variable(X)],
2082  if Subst =:= [] -> I;
2083     true -> hipe_icode:subst(Subst, I)
2084  end.
2085
2086%% _________________________________________________________________
2087%%
2088%% Find the types of the arguments to a call
2089%%
2090
2091update_call_arguments(I, Info) ->
2092  Args = hipe_icode:call_args(I),
2093  ArgTypes = lookup_list(Args, Info),
2094  Signature = find_signature(hipe_icode:call_fun(I), length(Args)),
2095  case t_fun_args(Signature) of
2096    unknown ->
2097      Info;
2098    PltArgTypes ->
2099      NewArgTypes = t_inf_lists(ArgTypes, PltArgTypes),
2100      enter_list(Args, NewArgTypes, Info)
2101  end.
2102
2103%% _________________________________________________________________
2104%%
2105%% PLT info
2106%%
2107
2108find_signature(MFA = {_, _, _}, _) -> find_signature_mfa(MFA);
2109find_signature(Primop, Arity) -> find_signature_primop(Primop, Arity).
2110
2111find_signature_mfa(MFA) ->
2112  case get_mfa_arg_types(MFA) of
2113    any ->
2114      t_fun(get_mfa_type(MFA));
2115    BifArgs ->
2116      t_fun(BifArgs, get_mfa_type(MFA))
2117  end.
2118
2119find_signature_primop(Primop, Arity) ->
2120  case get_primop_arg_types(Primop) of
2121    any ->
2122      t_fun(Arity, get_primop_type(Primop));
2123    ArgTypes ->
2124      t_fun(ArgTypes, get_primop_type(Primop))
2125  end.
2126
2127get_primop_arg_types(Primop) ->
2128  case hipe_icode_primops:arg_types(Primop) of
2129    unknown -> any;
2130    ArgTypes -> add_tuple_to_args(ArgTypes)
2131  end.
2132
2133get_mfa_arg_types({M, F, A}) ->
2134  case erl_bif_types:arg_types(M, F, A) of
2135    unknown ->
2136      any;
2137    BifArgs ->
2138      add_tuple_to_args(BifArgs)
2139  end.
2140
2141get_mfa_type({M, F, A}) ->
2142  erl_bif_types:type(M, F, A).
2143
2144get_primop_type(Primop) ->
2145  hipe_icode_primops:type(get_standard_primop(Primop)).
2146
2147add_tuple_to_args(Types) ->
2148  [add_tuple_to_type(T) || T <- Types].
2149
2150add_tuple_to_type(T) ->
2151  None = t_none(),
2152  case t_inf(t_fun(), T) of
2153    None -> T;
2154    _Other -> t_sup(T, t_tuple([t_atom(),t_atom()]))
2155  end.
2156
2157add_funs_to_arg_types(Types) ->
2158  [add_fun_to_arg_type(T) || T <- Types].
2159
2160add_fun_to_arg_type(T) ->
2161  None = t_none(),
2162  case t_inf(t_tuple([t_atom(),t_atom()]), T) of
2163    None -> T;
2164    _Other -> t_sup(T, t_fun())
2165  end.
2166
2167%%=====================================================================
2168%% Icode Coordinator Callbacks
2169%%=====================================================================
2170
2171-spec replace_nones([erl_types:erl_type()] | erl_types:erl_type()) ->
2172        [erl_types:erl_type()].
2173
2174replace_nones(Types) when is_list(Types) ->
2175  [replace_none(T) || T <- Types];
2176replace_nones(Type) ->
2177  [replace_none(Type)].
2178
2179-spec replace_none(erl_types:erl_type()) -> erl_types:erl_type().
2180
2181replace_none(Type) ->
2182  case erl_types:t_is_none(Type) of
2183    true ->
2184      erl_types:t_any();
2185    false ->
2186      Type
2187  end.
2188
2189-spec update__info([erl_types:erl_type()], [erl_types:erl_type()]) ->
2190        {boolean(), [erl_types:erl_type()]}.
2191
2192update__info(NewTypes, OldTypes) ->
2193  SupFun =
2194    fun(T1, T2) -> erl_types:t_limit(erl_types:t_sup(T1,T2), ?TYPE_DEPTH) end,
2195  EqFun = fun erl_types:t_is_equal/2,
2196  ResTypes = lists:zipwith(SupFun, NewTypes, OldTypes),
2197  Change = lists:zipwith(EqFun, ResTypes, OldTypes),
2198  {lists:all(fun(X) -> X end, Change), ResTypes}.
2199
2200-spec new__info([erl_types:erl_type()]) -> [erl_types:erl_type()].
2201
2202new__info(NewTypes) ->
2203  [erl_types:t_limit(T, ?TYPE_DEPTH) || T <- NewTypes].
2204
2205-spec return__info(erl_types:erl_type()) -> erl_types:erl_type().
2206
2207return__info(Types) ->
2208  Types.
2209
2210-spec return_none() -> [erl_types:erl_type(),...].
2211
2212return_none() ->
2213  [erl_types:t_none()].
2214
2215-spec return_none_args(cfg(), mfa()) -> [erl_types:erl_type()].
2216
2217return_none_args(Cfg, {_M,_F,A}) ->
2218  NoArgs =
2219    case hipe_icode_cfg:is_closure(Cfg) of
2220      true -> hipe_icode_cfg:closure_arity(Cfg) - 1;
2221      false -> A
2222    end,
2223  lists:duplicate(NoArgs, erl_types:t_none()).
2224
2225-spec return_any_args(cfg(), mfa()) -> [erl_types:erl_type()].
2226
2227return_any_args(Cfg, {_M,_F,A}) ->
2228  NoArgs =
2229    case hipe_icode_cfg:is_closure(Cfg) of
2230      true -> hipe_icode_cfg:closure_arity(Cfg);
2231      false -> A
2232    end,
2233  lists:duplicate(NoArgs, erl_types:t_any()).
2234
2235%%=====================================================================
2236%% Testing function below
2237%%=====================================================================
2238
2239-ifdef(DO_HIPE_ICODE_TYPE_TEST).
2240
2241test() ->
2242  Range1 = t_from_range(1, pos_inf),
2243  Range2 = t_from_range(0, 5),
2244  Var1 = hipe_icode:mk_var(1),
2245  Var2 = hipe_icode:mk_var(2),
2246
2247  Info = enter(Var1, Range1, enter(Var2, Range2, gb_trees:empty())),
2248  io:format("A1 ~p~n", [Info]),
2249  A = integer_range_inequality_propagation('<', Var1, Var2, 1, 2, Info),
2250  B = integer_range_inequality_propagation('>=', Var1, Var2, 1, 2, Info),
2251  C = integer_range_inequality_propagation('=<', Var1, Var2, 1, 2, Info),
2252  D = integer_range_inequality_propagation('>', Var1, Var2, 1, 2, Info),
2253
2254  io:format("< ~p~n", [A]),
2255  io:format(">= ~p~n", [B]),
2256  io:format("<= ~p~n", [C]),
2257  io:format("> ~p~n", [D]).
2258
2259-endif.
2260