~rdoering/ubuntu/karmic/erlang/fix-535090

« back to all changes in this revision

Viewing changes to lib/hipe/icode/hipe_icode_range.erl

  • Committer: Bazaar Package Importer
  • Author(s): Sergei Golovan
  • Date: 2009-02-15 16:42:52 UTC
  • mfrom: (3.1.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090215164252-q5x4rcf8a5pbesb1
Tags: 1:12.b.5-dfsg-2
Upload to unstable after lenny is released.

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
-include("../flow/hipe_bb.hrl").
36
36
-include("hipe_icode_type.hrl").
37
37
 
38
 
-type(range_rep() :: {'neg_inf' | integer(), 'pos_inf' | integer()} | 'empty').
39
 
-type(fun_name() :: atom() | tuple()).
40
 
-type(inf_integer() :: 'neg_inf' | 'pos_inf' | integer()).
 
38
-type range_rep() :: {'neg_inf' | integer(), 'pos_inf' | integer()} | 'empty'.
 
39
-type fun_name() :: atom() | tuple().
 
40
-type inf_integer() :: 'neg_inf' | 'pos_inf' | integer().
41
41
 
42
42
-record(range, {range :: range_rep(),
43
43
                other :: bool()}).
44
44
 
45
 
-record(ann,   {range :: #range{}, 
46
 
                type  :: erl_type(), 
 
45
-record(ann,   {range :: #range{},
 
46
                type  :: erl_type(),
47
47
                count :: integer()}).
48
48
 
49
 
-type(range_anno() :: {range_anno, #ann{}, fun((#ann{}) -> string())}). 
50
 
-type(args_fun() :: fun((mfa(),cfg()) -> [#range{}])). 
51
 
-type(call_fun() :: fun((mfa(),[#range{}]) -> #range{})).                     
52
 
-type(final_fun() :: fun((mfa(),[#range{}]) -> ok)).     
53
 
-type(data() :: {mfa(), args_fun(), call_fun(), final_fun()}).
54
 
-type(label() :: integer()).
55
 
-type(info() :: gb_tree()).
56
 
-type(work_list() :: {[label()],[label()],set()}).
57
 
-type(variable() :: #icode_variable{}).
58
 
-type(annotated_variable() :: #icode_variable{}).
59
 
-type(argument() :: #icode_const{} | variable()).
60
 
-type(three_range_fun()   :: fun((#range{},#range{},#range{}) -> #range{})).
61
 
-type(instr_split_info()  :: {icode_instr(),[{label(),info()}]}).
62
 
-type(last_instr_return() :: {instr_split_info(), #range{}}).  
 
49
-type range_anno() :: {range_anno, #ann{}, fun((#ann{}) -> string())}.
 
50
-type args_fun() :: fun((mfa(),cfg()) -> [#range{}]).
 
51
-type call_fun() :: fun((mfa(),[#range{}]) -> #range{}).                      
 
52
-type final_fun() :: fun((mfa(),[#range{}]) -> ok).
 
53
-type data() :: {mfa(), args_fun(), call_fun(), final_fun()}.
 
54
-type label() :: integer().
 
55
-type info() :: gb_tree().
 
56
-type work_list() :: {[label()],[label()],set()}.
 
57
-type variable() :: #icode_variable{}.
 
58
-type annotated_variable() :: #icode_variable{}.
 
59
-type argument() :: #icode_const{} | variable().
 
60
-type three_range_fun()   :: fun((#range{},#range{},#range{}) -> #range{}).
 
61
-type instr_split_info()  :: {icode_instr(),[{label(),info()}]}.
 
62
-type last_instr_return() :: {instr_split_info(), #range{}}.
63
63
 
64
64
-record(state, {info_map           :: gb_tree(), 
65
65
                counter=dict:new() :: dict(), 
77
77
 
78
78
%%---------------------------------------------------------------------
79
79
 
80
 
-spec(cfg/4 :: (cfg(), mfa(), comp_options(), #comp_servers{}) -> cfg()).
 
80
-spec cfg(cfg(), mfa(), comp_options(), #comp_servers{}) -> cfg().
81
81
 
82
82
cfg(Cfg, MFA, Options, Servers) ->
83
83
  case proplists:get_bool(concurrent_comp, Options) of
87
87
      ordinary_cfg(Cfg, MFA)
88
88
  end.
89
89
 
90
 
-spec(concurrent_cfg/3 :: (cfg(), mfa(), pid()) -> cfg()).
 
90
-spec concurrent_cfg(cfg(), mfa(), pid()) -> cfg().
91
91
 
92
92
concurrent_cfg(Cfg, MFA, CompServer) ->
93
93
  CompServer ! {ready, {MFA,self()}},
96
96
  CompServer ! {done_rewrite, MFA},
97
97
  Ans.
98
98
 
99
 
-spec(do_analysis/2 :: 
100
 
      (cfg(), mfa()) -> {args_fun(), call_fun(), final_fun()}).
 
99
-spec do_analysis(cfg(), mfa()) -> {args_fun(), call_fun(), final_fun()}.
101
100
 
102
101
do_analysis(Cfg, MFA) ->
103
102
  receive
108
107
      {NewArgsFun, NewCallFun, NewFinalFun}
109
108
  end.
110
109
 
111
 
-spec(do_rewrite/5 :: 
112
 
      (cfg(), mfa(), args_fun(), call_fun(), final_fun()) -> cfg()).
 
110
-spec do_rewrite(cfg(), mfa(), args_fun(), call_fun(), final_fun()) -> cfg().
113
111
 
114
112
do_rewrite(Cfg, MFA, ArgsFun, CallFun, FinalFun) ->
115
113
  common_rewrite(Cfg, {MFA, ArgsFun, CallFun, FinalFun}).
116
114
 
117
 
-spec(ordinary_cfg/2 :: (cfg(), mfa()) -> cfg()).
 
115
-spec ordinary_cfg(cfg(), mfa()) -> cfg().
118
116
 
119
117
ordinary_cfg(Cfg, MFA) ->
120
118
  Data = make_data(Cfg,MFA),
121
119
  common_rewrite(Cfg, Data).
122
120
  
123
 
-spec(common_rewrite/2 :: (cfg(), data()) -> cfg()).
 
121
-spec common_rewrite(cfg(), data()) -> cfg().
124
122
 
125
123
common_rewrite(Cfg, Data) ->
126
124
  State = safe_analyse(Cfg, Data),
130
128
  Cfg3 = convert_cfg_to_types(Cfg2),
131
129
  hipe_icode_type:specialize(Cfg3).
132
130
 
133
 
-spec(make_data/2 :: (cfg(), mfa()) -> data()).
 
131
-spec make_data(cfg(), mfa()) -> data().
134
132
 
135
133
make_data(Cfg, {_M,_F,A}=MFA) ->
136
134
  NoArgs = 
144
142
  FinalFun = fun(_,_) -> ok end,
145
143
  {MFA, ArgsFun, CallFun, FinalFun}.
146
144
 
147
 
-spec(analyse/2 :: (cfg(), data()) -> 'ok').
 
145
-spec analyse(cfg(), data()) -> 'ok'.
148
146
 
149
147
analyse(Cfg, Data) ->
150
148
  try 
153
151
  catch throw:no_input -> ok
154
152
  end.
155
153
 
156
 
-spec(safe_analyse/2 :: (cfg(), data()) -> #state{}).
 
154
-spec safe_analyse(cfg(), data()) -> #state{}.
157
155
 
158
156
safe_analyse(CFG, Data={MFA,_,_,_}) ->
159
157
  State = state__init(CFG, Data),
162
160
  (state__result_action(NewState))(MFA, [state__ret_type(NewState)]),
163
161
  NewState.
164
162
 
165
 
-spec(rewrite_blocks/1 :: (#state{}) -> #state{}).
 
163
-spec rewrite_blocks(#state{}) -> #state{}.
166
164
 
167
165
rewrite_blocks(State) ->
168
166
  CFG = state__cfg(State),
169
167
  Start = hipe_icode_cfg:start_label(CFG),
170
168
  rewrite_blocks([Start], State, [Start]).
171
169
 
172
 
-spec(rewrite_blocks/3 :: ([label()], #state{}, [label()]) -> #state{}).
 
170
-spec rewrite_blocks([label()], #state{}, [label()]) -> #state{}.
173
171
 
174
172
rewrite_blocks([Next|Rest], State, Visited) ->
175
173
  Info = state__info_in(State, Next),
182
180
rewrite_blocks([], State, _) ->
183
181
  State.
184
182
 
185
 
-spec(analyse_blocks/2 :: (#state{}, work_list()) -> #state{}).
 
183
-spec analyse_blocks(#state{}, work_list()) -> #state{}.
186
184
 
187
185
analyse_blocks(State, Work) ->
188
186
  case get_work(Work) of
199
197
      analyse_blocks(NewState, NewWork2)
200
198
  end.
201
199
 
202
 
-spec(analyse_block/4 :: 
203
 
      (label(), info(), #state{}, bool()) -> {#state{}, [label()]}).
 
200
-spec analyse_block(label(), info(), #state{}, bool()) -> {#state{}, [label()]}.
204
201
 
205
202
analyse_block(Label, Info, State, Rewrite) ->
206
203
  BB = state__bb(State, Label),
211
208
  State2 = state__ret_type_update(State1, RetType),
212
209
  state__update_info(State2, InfoList, Rewrite).
213
210
 
214
 
-spec(analyse_BB/5 ::
215
 
      ([icode_instr()], info(), [icode_instr()], bool(), call_fun()) -> 
216
 
         {[icode_instr()], [info()], #range{}}).
 
211
-spec analyse_BB([icode_instr()], info(), [icode_instr()], bool(), call_fun()) ->
 
212
         {[icode_instr()], [info()], #range{}}.
217
213
 
218
214
analyse_BB([Last], Info, Code, Rewrite, LookupFun) ->
219
215
  %% io:format("I: ~w~n",[Last]),
223
219
  {NewInfo,NewI} = analyse_insn(Insn, Info, LookupFun), 
224
220
  analyse_BB(InsnList, NewInfo, [NewI|Code], Rewrite, LookupFun).
225
221
 
226
 
-spec(analyse_insn/3 ::
227
 
      (icode_instr(), info(), call_fun()) -> {info(), icode_instr()}).
 
222
-spec analyse_insn(icode_instr(), info(), call_fun()) -> {info(), icode_instr()}.
228
223
 
229
224
analyse_insn(I, Info, LookupFun) ->
230
225
  %% io:format("~w Info: ~p~n",[I,Info]),
239
234
    end,
240
235
  {enter_vals(FinalI, Info), FinalI}.
241
236
 
242
 
-spec(handle_args/2 :: (icode_instr(), info()) -> icode_instr()).
 
237
-spec handle_args(icode_instr(), info()) -> icode_instr().
243
238
 
244
239
handle_args(I, Info) ->
245
240
  WidenFun = fun update_three/3,
246
241
  handle_args(I, Info, WidenFun).
247
242
 
248
 
-spec(handle_args/3 ::
249
 
      (icode_instr(), info(), three_range_fun()) -> icode_instr()).
 
243
-spec handle_args(icode_instr(), info(), three_range_fun()) -> icode_instr().
250
244
 
251
245
handle_args(I, Info, WidenFun) ->
252
246
  Uses = hipe_icode:uses(I),
256
250
  NewUses = lists:zipwith(JoinFun, Uses, PresentRanges),
257
251
  hipe_icode:subst_uses(lists:zip(Uses, NewUses),I).
258
252
 
259
 
-spec(join_info/3 :: (#ann{}, #range{}, three_range_fun()) -> #ann{}).
 
253
-spec join_info(#ann{}, #range{}, three_range_fun()) -> #ann{}.
260
254
 
261
255
join_info(Ann = #ann{range=R1,type=Type,count=?WIDEN}, R2, Fun)  ->
262
256
  Ann#ann{range = Fun(R1, R2, range_from_simple_type(Type))};
266
260
    NewR -> Ann#ann{range=NewR, count=C+1}
267
261
  end.
268
262
 
269
 
-spec(join_three/3 :: (#range{}, #range{}, #range{}) -> #range{}).
 
263
-spec join_three(#range{}, #range{}, #range{}) -> #range{}.
270
264
 
271
265
join_three(R1, R2, R3) ->
272
266
  inf(sup(R1, R2), R3).
273
267
 
274
 
-spec(update_info/2 :: (variable(), #range{}) -> annotated_variable()).
 
268
-spec update_info(variable(), #range{}) -> annotated_variable().
275
269
 
276
270
update_info(Var, Range) ->
277
271
  update_info(Var, Range, fun update_three/3).
278
272
 
279
 
-spec(update_info/3 ::
280
 
      (variable(), #range{}, three_range_fun()) -> annotated_variable()).
 
273
-spec update_info(variable(), #range{}, three_range_fun()) -> annotated_variable().
281
274
 
282
275
update_info(Arg, R, Fun) ->
283
276
  case hipe_icode:is_annotated_variable(Arg) of
288
281
      Arg
289
282
  end.
290
283
 
291
 
-spec(update_info1/3 :: (any(), #range{}, three_range_fun()) -> range_anno()).
 
284
-spec update_info1(any(), #range{}, three_range_fun()) -> range_anno().
292
285
 
293
286
update_info1({range_anno, Ann, _}, R2, Fun) ->
294
287
  make_range_anno(update_ann(Ann,R2,Fun));
303
296
    NewR -> Ann#ann{range=NewR, count=C+1}
304
297
  end.
305
298
 
306
 
-spec(type_to_ann/1 :: (any()) -> #ann{}).
 
299
-spec type_to_ann(any()) -> #ann{}.
307
300
 
308
301
type_to_ann(Type) ->
309
302
  #ann{range = range_from_simple_type(Type), type = t_limit(Type,1), count=1}.
310
303
 
311
 
-spec(make_range_anno/1 :: (#ann{}) -> range_anno()).
 
304
-spec make_range_anno(#ann{}) -> range_anno().
312
305
 
313
306
make_range_anno(Ann) ->
314
307
  {range_anno, Ann, fun pp_ann/1}. 
315
308
 
316
 
-spec(update_three/3 :: (#range{}, #range{}, #range{}) -> #range{}).
 
309
-spec update_three(#range{}, #range{}, #range{}) -> #range{}.
317
310
 
318
311
update_three(_R1, R2, R3) ->
319
312
  inf(R2, R3).
320
313
 
321
 
-spec(safe_widen/3 :: (#range{},#range{},#range{}) -> #range{}).
 
314
-spec safe_widen(#range{}, #range{}, #range{}) -> #range{}.
322
315
 
323
316
safe_widen(#range{range=Old}, #range{range=New}, T = #range{range=Wide}) ->
324
317
  ResRange =
350
343
    end,
351
344
  T#range{range=ResRange}.
352
345
 
353
 
-spec(widen/3 :: (#range{}, #range{}, #range{}) -> #range{}).
 
346
-spec widen(#range{}, #range{}, #range{}) -> #range{}.
354
347
 
355
348
widen(#range{range=Old}, #range{range=New}, T = #range{range=Wide}) ->
356
349
  ResRange =
382
375
    end,
383
376
  T#range{range=ResRange}.
384
377
 
385
 
-spec(analyse_call/2 :: (#icode_call{}, call_fun()) -> #icode_call{}).
 
378
-spec analyse_call(#icode_call{}, call_fun()) -> #icode_call{}.
386
379
 
387
380
analyse_call(Call, LookupFun) ->
388
381
  case hipe_icode:call_dstlist(Call) of
397
390
      hipe_icode:subst_defines(lists:zip(Dsts, NewDefs), Call)
398
391
  end.
399
392
 
400
 
-spec(analyse_move/1 :: (#icode_move{}) -> #icode_move{}).
 
393
-spec analyse_move(#icode_move{}) -> #icode_move{}.
401
394
 
402
395
analyse_move(Move) ->
403
396
  Src = hipe_icode:move_src(Move),
406
399
  NewDst = update_info(Dst, Range),  
407
400
  hipe_icode:subst_defines([{Dst,NewDst}], Move).
408
401
 
409
 
-spec(analyse_begin_handler/1 ::
410
 
      (#icode_begin_handler{}) -> #icode_begin_handler{}).
 
402
-spec analyse_begin_handler(#icode_begin_handler{}) -> #icode_begin_handler{}.
411
403
 
412
404
analyse_begin_handler(Handler) ->
413
405
  SubstList =
415
407
      Dst <- hipe_icode:begin_handler_dstlist(Handler)],
416
408
  hipe_icode:subst_defines(SubstList, Handler).
417
409
 
418
 
-spec(analyse_phi/1 :: (#icode_phi{}) -> #icode_phi{}).
 
410
-spec analyse_phi(#icode_phi{}) -> #icode_phi{}.
419
411
    
420
412
analyse_phi(Phi) ->
421
413
  {_, Args} = lists:unzip(hipe_icode:phi_arglist(Phi)),
426
418
  NewDst = update_info(Dst, DstRange, fun widen/3),  
427
419
  hipe_icode:subst_defines([{Dst, NewDst}], Phi).
428
420
 
429
 
-spec(analyse_last_insn/4 ::
430
 
      (icode_instr(), info(), bool(), call_fun()) -> last_instr_return()).
 
421
-spec analyse_last_insn(icode_instr(), info(), bool(), call_fun()) ->
 
422
          last_instr_return().
431
423
 
432
424
analyse_last_insn(I, Info, Rewrite, LookupFun) ->
433
425
  %% io:format("~w Info: ~p~n",[I,Info]),
448
440
    #icode_begin_try{} -> {analyse_begin_try(NewI, Info), none_type()}
449
441
  end.
450
442
 
451
 
-spec(analyse_return/2 :: (icode_instr(),info()) -> last_instr_return()).
 
443
-spec analyse_return(icode_instr(),info()) -> last_instr_return().
452
444
 
453
445
analyse_return(Insn, _Info) ->
454
446
  [RetRange] = get_range_from_args(hipe_icode:return_vars(Insn)),
455
447
  {{Insn,[]}, RetRange}.
456
448
 
457
 
-spec(analyse_enter/3 ::
458
 
      (icode_instr(), info(), call_fun()) -> last_instr_return()).
 
449
-spec analyse_enter(icode_instr(), info(), call_fun()) -> last_instr_return().
459
450
  
460
451
analyse_enter(Insn, _Info, LookupFun) ->
461
452
  Args = hipe_icode:args(Insn),
464
455
  [RetRange] = analyse_call_or_enter_fun(Fun, Args, CallType, LookupFun),
465
456
  {{Insn,[]}, RetRange}.
466
457
 
467
 
-spec(analyse_switch_val/3 ::
468
 
      (#icode_switch_val{},info(),bool()) -> instr_split_info()).
 
458
-spec analyse_switch_val(#icode_switch_val{},info(),bool()) -> instr_split_info().
469
459
 
470
460
analyse_switch_val(Switch, Info, Rewrite) -> 
471
461
  Var = hipe_icode:switch_val_term(Switch),
486
476
      end
487
477
  end.
488
478
 
489
 
-spec(update_infos/3 :: 
490
 
      (argument(), info(), [{#range{},label()}]) -> [{label(),info()}]).
 
479
-spec update_infos(argument(), info(), [{#range{},label()}]) -> [{label(),info()}].
491
480
 
492
481
update_infos(Arg, Info, [{Range, Label}|Rest]) ->
493
482
  [{Label,enter_define({Arg,Range},Info)} | update_infos(Arg,Info,Rest)];
494
483
update_infos(_, _, []) -> [].
495
484
 
496
 
-spec(get_range_label_list/3 :: 
497
 
      ([{argument(),label()}], #range{},[{#range{},label()}]) -> 
498
 
         {#range{},[{#range{},label()}]}).
 
485
-spec get_range_label_list([{argument(),label()}], #range{}, [{#range{},label()}]) ->
 
486
         {#range{},[{#range{},label()}]}.
499
487
 
500
488
get_range_label_list([{Val,Label}|Cases], SRange, Acc) ->
501
489
  VRange = get_range_from_arg(Val),
510
498
  {PointTypes, _} = lists:unzip(Acc),
511
499
  {remove_point_types(SRange, PointTypes), Acc}.
512
500
 
513
 
-spec(update_switch/3 :: 
514
 
      (#icode_switch_val{}, [{#range{},label()}], bool()) ->
515
 
         #icode_switch_val{}).
 
501
-spec update_switch(#icode_switch_val{}, [{#range{},label()}], bool()) ->
 
502
         #icode_switch_val{}.
516
503
 
517
504
update_switch(Switch, LabelRangeList, KeepFail) ->
518
505
  S2 =
526
513
     true -> S2
527
514
  end.
528
515
 
529
 
-spec(label_range_list_to_cases/2 :: 
530
 
      ([{#range{},label()}], [{#icode_const{},label()}]) ->
531
 
         'no_update' | [{#icode_const{},label()}]).
 
516
-spec label_range_list_to_cases([{#range{},label()}], [{#icode_const{},label()}]) ->
 
517
         'no_update' | [{#icode_const{},label()}].
532
518
 
533
519
label_range_list_to_cases([{#range{range={C,C},other=false},Label}|Rest],
534
520
                          Acc) when is_integer(C) -> 
538
524
label_range_list_to_cases([], Acc) ->
539
525
  lists:reverse(Acc).
540
526
 
541
 
-spec(analyse_switch_tuple_arity/2 ::
542
 
      (#icode_switch_tuple_arity{},info()) ->
543
 
         {#icode_switch_tuple_arity{},[{label(),info()}]}).
 
527
-spec analyse_switch_tuple_arity(#icode_switch_tuple_arity{}, info()) ->
 
528
         {#icode_switch_tuple_arity{},[{label(),info()}]}.
544
529
  
545
530
analyse_switch_tuple_arity(Switch, Info) -> 
546
531
  Var = hipe_icode:switch_tuple_arity_term(Switch),
551
536
  Labels = [Fail|Case_labels],
552
537
  {Switch, [{Label,NewInfo} || Label <- Labels]}.
553
538
 
554
 
-spec(analyse_goto/2 ::
555
 
      (#icode_goto{},info()) -> {#icode_goto{}, [{label(),info()},...]}).
 
539
-spec analyse_goto(#icode_goto{},info()) -> {#icode_goto{}, [{label(),info()},...]}.
556
540
 
557
541
analyse_goto(Insn, Info) ->
558
542
  GotoLabel = hipe_icode:goto_label(Insn),
559
543
  {Insn, [{GotoLabel,Info}]}.
560
544
 
561
 
-spec(analyse_fail/2 ::
562
 
      (#icode_fail{}, info()) -> {#icode_fail{}, [{label(),info()}]}).
 
545
-spec analyse_fail(#icode_fail{}, info()) -> {#icode_fail{}, [{label(),info()}]}.
563
546
 
564
547
analyse_fail(Fail, Info) ->
565
548
  case hipe_icode:fail_label(Fail) of
567
550
    Label -> {Fail, [{Label,Info}]}
568
551
  end.
569
552
 
570
 
-spec(analyse_begin_try/2 ::
571
 
      (#icode_begin_try{}, info()) ->
572
 
         {#icode_begin_try{}, [{label(),info()},...]}).
 
553
-spec analyse_begin_try(#icode_begin_try{}, info()) ->
 
554
         {#icode_begin_try{}, [{label(),info()},...]}.
573
555
 
574
556
analyse_begin_try(Insn, Info) ->
575
557
  Label = hipe_icode:begin_try_label(Insn),
576
558
  Successor = hipe_icode:begin_try_successor(Insn),
577
559
  {Insn, [{Label,Info},{Successor,Info}]}.
578
560
 
579
 
-spec(analyse_last_call/3 :: 
580
 
      (#icode_call{}, info(), call_fun()) ->
581
 
         {#icode_call{}, [{label(),info()},...]}).
 
561
-spec analyse_last_call(#icode_call{}, info(), call_fun()) ->
 
562
         {#icode_call{}, [{label(),info()},...]}.
582
563
 
583
564
analyse_last_call(Call, Info, LookupFun) ->
584
565
  %% hipe_icode_pp:pp_block([Insn]),
592
573
      {NewI, [{Continuation,NewInfo}, {Fail,Info}]}
593
574
  end.
594
575
 
595
 
-spec(analyse_if/3 ::
596
 
      (#icode_if{}, info(), bool()) ->
597
 
         {#icode_goto{} | #icode_if{}, [{label(),info()}]}).
 
576
-spec analyse_if(#icode_if{}, info(), bool()) ->
 
577
         {#icode_goto{} | #icode_if{}, [{label(),info()}]}.
598
578
 
599
579
analyse_if(If, Info, Rewrite) ->
600
580
  case hipe_icode:if_args(If) of
606
586
      {If, [{TrueLabel,Info},{FalseLabel,Info}]}
607
587
  end.
608
588
 
609
 
-spec(analyse_sane_if/5 :: 
610
 
      (#icode_if{},info(),[argument(),...],[#range{},...],bool()) -> 
611
 
         {#icode_goto{} | #icode_if{},[{label(),info()}]}).
 
589
-spec analyse_sane_if(#icode_if{}, info(), [argument(),...],
 
590
                      [#range{},...], bool()) ->
 
591
         {#icode_goto{} | #icode_if{}, [{label(), info()}]}.
612
592
 
613
593
analyse_sane_if(If, Info, [Arg1, Arg2], [Range1, Range2], Rewrite) ->
614
594
  case normalize_name(hipe_icode:if_op(If)) of
675
655
    end,
676
656
  {NewIF, UpdateInfo}.
677
657
 
678
 
-spec(normalize_name/1 :: (atom()) -> atom()).
 
658
-spec normalize_name(atom()) -> atom().
679
659
 
680
660
normalize_name(Name) ->
681
661
  case Name of
688
668
    Name -> Name
689
669
  end.
690
670
 
691
 
-spec(range_equality_propagation/2 :: 
692
 
      (#range{}, #range{}) -> {#range{}, #range{}, #range{}, #range{}}).
 
671
-spec range_equality_propagation(#range{}, #range{}) ->
 
672
          {#range{}, #range{}, #range{}, #range{}}.
693
673
 
694
674
range_equality_propagation(Range_1, Range_2) ->  
695
675
  True_range = inf(Range_1, Range_2),
712
692
  end,
713
693
  {True_range, True_range, False_range_1, False_range_2}.
714
694
 
715
 
-spec(range_inequality_propagation/2 :: 
716
 
      (#range{}, #range{}) -> {#range{}, #range{}, #range{}, #range{}}).
 
695
-spec range_inequality_propagation(#range{}, #range{}) ->
 
696
          {#range{}, #range{}, #range{}, #range{}}.
717
697
 
718
698
%% Range1 < Range2
719
699
range_inequality_propagation(Range1, Range2) ->
769
749
   range_init(R1_false_range, R1_other),
770
750
   range_init(R2_false_range, R2_other)}.
771
751
 
772
 
-spec(analyse_type/3 ::
773
 
      (#icode_type{}, info(), bool()) ->
774
 
         {#icode_goto{} | #icode_type{}, [{label(),info()}]}).
 
752
-spec analyse_type(#icode_type{}, info(), bool()) ->
 
753
         {#icode_goto{} | #icode_type{}, [{label(),info()}]}.
775
754
 
776
755
analyse_type(Type, Info, Rewrite) ->
777
756
  TypeTest = hipe_icode:type_test(Type),
819
798
    end,
820
799
  {NewType,True ++ False}.
821
800
 
822
 
-spec(compare_with_integer/2 :: (integer(),#range{}) -> {#range{},#range{}}).
 
801
-spec compare_with_integer(integer(), #range{}) -> {#range{}, #range{}}.
823
802
 
824
803
compare_with_integer(N, OldVarRange) ->
825
804
  TestRange = range_init({N, N}, false),
846
825
 
847
826
%%== Ranges ==================================================================
848
827
 
849
 
-spec(pp_ann/1 :: (#ann{} | erl_type()) -> [string()]).
 
828
-spec pp_ann(#ann{} | erl_type()) -> [string()].
850
829
 
851
830
pp_ann(#ann{range=#range{range=R, other=false}}) ->
852
831
  pp_range(R);
857
836
pp_ann(Type) ->
858
837
  t_to_string(Type).
859
838
 
860
 
-spec(pp_range/1 :: (range_rep()) -> string()).
 
839
-spec pp_range(range_rep()) -> string().
861
840
 
862
841
pp_range(empty) ->
863
842
  "none";
864
843
pp_range({Min, Max}) ->
865
844
  val_to_string(Min) ++ ".." ++ val_to_string(Max).
866
845
 
867
 
-spec(val_to_string/1 :: ('pos_inf' | 'neg_inf' | integer()) -> string()).
 
846
-spec val_to_string('pos_inf' | 'neg_inf' | integer()) -> string().
868
847
 
869
848
val_to_string(pos_inf) -> "inf";
870
849
val_to_string(neg_inf) -> "-inf";
871
850
val_to_string(X) when is_integer(X) -> integer_to_list(X).
872
851
 
873
 
-spec(range_from_type/1 :: (_) -> [#range{}]).
 
852
-spec range_from_type(_) -> [#range{}].
874
853
 
875
854
range_from_type(Type) ->
876
855
  case t_components(Type) of
880
859
      [range_from_simple_type(Type)]
881
860
  end.
882
861
  
883
 
-spec(range_from_simple_type/1 :: (_) -> #range{}).
 
862
-spec range_from_simple_type(_) -> #range{}.
884
863
 
885
864
range_from_simple_type(Type) ->
886
865
  None = t_none(),
895
874
      #range{range=Range, other=true}
896
875
  end.
897
876
 
898
 
-spec(range_init/2 :: (range_rep(), bool()) -> #range{}).
 
877
-spec range_init(range_rep(), bool()) -> #range{}.
899
878
 
900
879
range_init({Min,Max}, Other) ->
901
880
  case inf_geq(Max,Min) of
907
886
range_init(empty, Other) ->
908
887
  #range{range=empty, other=Other}.
909
888
 
910
 
-spec(range/1 :: (#range{}) -> range_rep()).
 
889
-spec range(#range{}) -> range_rep().
911
890
 
912
891
range(#range{range=R}) -> R.
913
892
 
914
 
-spec(other/1 :: (#range{}) -> bool()).
 
893
-spec other(#range{}) -> bool().
915
894
 
916
895
other(#range{other=O}) -> O.
917
896
 
918
 
-spec(set_other/2 :: (#range{}, bool()) -> #range{}).
 
897
-spec set_other(#range{}, bool()) -> #range{}.
919
898
 
920
899
set_other(R, O) -> R#range{other=O}.
921
900
 
922
 
-spec(range__min/1 :: (#range{}) -> 'empty' | 'neg_inf' | integer()).
 
901
-spec range__min(#range{}) -> 'empty' | 'neg_inf' | integer().
923
902
 
924
903
range__min(#range{range=empty}) -> empty;
925
904
range__min(#range{range={Min,_}}) -> Min.
926
905
 
927
 
-spec(range__max/1 :: (#range{}) -> 'empty' | 'pos_inf' | integer()).
 
906
-spec range__max(#range{}) -> 'empty' | 'pos_inf' | integer().
928
907
 
929
908
range__max(#range{range=empty}) -> empty;
930
909
range__max(#range{range={_,Max}}) -> Max.
931
910
 
932
 
-spec(range__is_none/1 :: (#range{}) -> bool()).
 
911
-spec range__is_none(#range{}) -> bool().
933
912
 
934
913
range__is_none(#range{range=empty, other=false}) -> true;
935
914
range__is_none(#range{}) -> false.
936
915
 
937
 
-spec(range__is_empty/1 :: (#range{}) -> bool()).
 
916
-spec range__is_empty(#range{}) -> bool().
938
917
 
939
918
range__is_empty(#range{range=empty}) -> true;
940
919
range__is_empty(#range{range={_,_}}) -> false.
941
920
 
942
 
-spec(remove_point_types/2 :: (#range{}, [#range{}]) -> #range{}).
 
921
-spec remove_point_types(#range{}, [#range{}]) -> #range{}.
943
922
 
944
923
remove_point_types(Range, Ranges) ->
945
924
  Sorted = lists:sort(Ranges),
947
926
  Range1 = lists:foldl(FoldFun, Range, Sorted),
948
927
  lists:foldl(FoldFun, Range1, lists:reverse(Sorted)).
949
928
 
950
 
-spec(range__remove_constant/2 :: (#range{},#range{}) -> #range{}).
 
929
-spec range__remove_constant(#range{}, #range{}) -> #range{}.
951
930
 
952
931
range__remove_constant(R = #range{range={C,C}}, #range{range={C,C}}) ->
953
932
  R#range{range=empty};
960
939
range__remove_constant(R = #range{}, _) ->
961
940
  R.
962
941
 
963
 
-spec(any_type/0 :: () -> #range{}).
 
942
-spec any_type() -> #range{}.
964
943
 
965
944
any_type() ->
966
945
  #range{range=any_r(), other=true}.
967
946
 
968
 
-spec(any_range/0 :: () -> #range{}).
 
947
-spec any_range() -> #range{}.
969
948
 
970
949
any_range() ->
971
950
  #range{range=any_r(), other=false}.
972
951
 
973
 
-spec(none_range/0 :: () -> #range{}).
 
952
-spec none_range() -> #range{}.
974
953
 
975
954
none_range() ->
976
955
  #range{range=empty, other=true}.
977
956
 
978
 
-spec(none_type/0 :: () -> #range{}).
 
957
-spec none_type() -> #range{}.
979
958
 
980
959
none_type() ->
981
960
  #range{range=empty, other=false}.
982
961
 
983
 
-spec(any_r/0 :: () -> {'neg_inf','pos_inf'}).
 
962
-spec any_r() -> {'neg_inf','pos_inf'}.
984
963
 
985
964
any_r() -> {neg_inf,pos_inf}.
986
965
 
987
 
-spec(get_range_from_args/1 :: ([argument()]) -> [#range{}]).
 
966
-spec get_range_from_args([argument()]) -> [#range{}].
988
967
  
989
968
get_range_from_args(Args) ->
990
969
  [get_range_from_arg(Arg) || Arg <- Args].
991
970
 
992
 
-spec(get_range_from_arg/1 :: (argument()) -> #range{}).
 
971
-spec get_range_from_arg(argument()) -> #range{}.
993
972
 
994
973
get_range_from_arg(Arg) ->
995
974
  case hipe_icode:is_const(Arg) of
1020
999
%% inf([R1,R2|Rest]) ->
1021
1000
%%   inf([inf(R1,R2)|Rest]).
1022
1001
 
1023
 
-spec(inf/2 :: (#range{}, #range{}) -> #range{}).
 
1002
-spec inf(#range{}, #range{}) -> #range{}.
1024
1003
 
1025
1004
inf(#range{range=R1, other=O1}, #range{range=R2, other=O2}) -> 
1026
1005
  #range{range=range_inf(R1,R2), other=other_inf(O1,O2)}.
1027
1006
 
1028
 
-spec(range_inf/2 :: (range_rep(), range_rep()) -> range_rep()).
 
1007
-spec range_inf(range_rep(), range_rep()) -> range_rep().
1029
1008
 
1030
1009
range_inf(empty, _) -> empty;
1031
1010
range_inf(_, empty) -> empty;
1039
1018
      empty
1040
1019
  end.
1041
1020
 
1042
 
-spec(other_inf/2 :: (bool(), bool()) -> bool()).
 
1021
-spec other_inf(bool(), bool()) -> bool().
1043
1022
 
1044
1023
other_inf(O1, O2) -> O1 and O2.
1045
1024
 
1046
 
-spec(sup/1 :: ([#range{},...]) -> #range{}).
 
1025
-spec sup([#range{},...]) -> #range{}.
1047
1026
 
1048
1027
sup([R]) ->
1049
1028
  R;
1050
1029
sup([R1,R2|Rest]) ->
1051
1030
  sup([sup(R1, R2)|Rest]).
1052
1031
 
1053
 
-spec(sup/2 :: (#range{}, #range{}) -> #range{}).
 
1032
-spec sup(#range{}, #range{}) -> #range{}.
1054
1033
 
1055
1034
sup(#range{range=R1,other=O1}, #range{range=R2,other=O2}) -> 
1056
1035
  #range{range=range_sup(R1,R2), other=other_sup(O1,O2)}.
1057
1036
 
1058
 
-spec(range_sup/2 :: (range_rep(), range_rep()) -> range_rep()).
 
1037
-spec range_sup(range_rep(), range_rep()) -> range_rep().
1059
1038
         
1060
1039
range_sup(empty, R) -> R;
1061
1040
range_sup(R, empty) -> R;
1064
1043
  NewMax = inf_max([Max1,Max2]),
1065
1044
  {NewMin,NewMax}.
1066
1045
 
1067
 
-spec(other_sup/2 :: (bool(), bool()) -> bool()).
 
1046
-spec other_sup(bool(), bool()) -> bool().
1068
1047
 
1069
1048
other_sup(O1, O2) -> O1 or O2.
1070
1049
 
1071
1050
%%== Call Support =============================================================
1072
1051
 
1073
 
-spec(analyse_call_or_enter_fun/4 :: 
1074
 
      (fun_name(), [argument()], icode_call_type(), call_fun()) -> [#range{}]).
 
1052
-spec analyse_call_or_enter_fun(fun_name(), [argument()],
 
1053
                                icode_call_type(), call_fun()) -> [#range{}].
1075
1054
 
1076
1055
analyse_call_or_enter_fun(Fun, Args, CallType, LookupFun) ->
1077
1056
  %%io:format("Fun: ~p~n Args: ~p~n CT: ~p~n LF: ~p~n", [Fun, Args, CallType, LookupFun]),
1118
1097
      range_from_type(Type)
1119
1098
  end.
1120
1099
 
1121
 
-type(bin_operation() :: fun((#range{},#range{}) -> #range{})).
1122
 
-type(unary_operation() :: fun((#range{}) -> #range{})).
 
1100
-type bin_operation() :: fun((#range{},#range{}) -> #range{}).
 
1101
-type unary_operation() :: fun((#range{}) -> #range{}).
1123
1102
 
1124
 
-spec(basic_type/1 :: 
1125
 
      (fun_name()) -> 'not_int' | 'not_analysed' | {bin, bin_operation()} |
1126
 
                        {unary, unary_operation()} | {fcall, mfa()} |
1127
 
                        {hipe_bs_primop, _}).
 
1103
-spec basic_type(fun_name()) -> 'not_int' | 'not_analysed'
 
1104
                             | {bin, bin_operation()}
 
1105
                             | {unary, unary_operation()}
 
1106
                             | {fcall, mfa()} | {hipe_bs_primop, _}.
1128
1107
 
1129
1108
%% Arithmetic operations
1130
1109
basic_type('+') -> {bin, fun(R1, R2) -> range_add(R1, R2) end};
1199
1178
basic_type(#unsafe_element{}) -> not_analysed;
1200
1179
basic_type(#unsafe_update_element{}) -> not_analysed.
1201
1180
 
1202
 
-spec(analyse_bs_get_integer/3 ::
1203
 
      (integer(), integer(), bool()) -> range_rep()).
 
1181
-spec analyse_bs_get_integer(integer(), integer(), bool()) -> range_rep().
1204
1182
 
1205
1183
analyse_bs_get_integer(Size, Flags, true) ->
1206
1184
  Signed = Flags band 4,
1222
1200
 
1223
1201
%% Arithmetic
1224
1202
 
1225
 
-spec(range_add/2 :: (#range{}, #range{}) -> #range{}).
 
1203
-spec range_add(#range{}, #range{}) -> #range{}.
1226
1204
 
1227
1205
range_add(Range1, Range2) ->
1228
1206
  NewMin = inf_add(range__min(Range1), range__min(Range2)),
1230
1208
  Other = other(Range1) orelse other(Range2),
1231
1209
  range_init({NewMin, NewMax}, Other).
1232
1210
 
1233
 
-spec(range_sub/2 :: (#range{}, #range{}) -> #range{}).
 
1211
-spec range_sub(#range{}, #range{}) -> #range{}.
1234
1212
 
1235
1213
range_sub(Range1, Range2) ->
1236
1214
  Min_sub = inf_min([inf_inv(range__max(Range2)), 
1242
1220
  Other = other(Range1) orelse other(Range2),
1243
1221
  range_init({NewMin, NewMax}, Other).
1244
1222
 
1245
 
-spec(range_mult/2 :: (#range{}, #range{}) -> #range{}).
 
1223
-spec range_mult(#range{}, #range{}) -> #range{}.
1246
1224
 
1247
1225
range_mult(#range{range=empty, other=true}, _Range2) ->
1248
1226
  range_init(empty, true);
1282
1260
  Other = other(Range1) orelse other(Range2),
1283
1261
  range_init(Range, Other).
1284
1262
 
1285
 
-spec(extreme_divisors/1 :: (#range{}) -> range_rep()).
 
1263
-spec extreme_divisors(#range{}) -> range_rep().
1286
1264
 
1287
1265
extreme_divisors(#range{range={0,0}}) -> {0,0};
1288
1266
extreme_divisors(#range{range={0,Max}}) -> {1,Max};
1297
1275
      end
1298
1276
  end.
1299
1277
 
1300
 
-spec(range_div/2 :: (#range{}, #range{}) -> #range{}).
 
1278
-spec range_div(#range{}, #range{}) -> #range{}.
1301
1279
 
1302
1280
%% this is div, not /.
1303
1281
range_div(_, #range{range={0,0}}) ->
1314
1292
                  inf_div(Max1, Min2), inf_div(Max1, Max2)],
1315
1293
  range_init({inf_min(Min_max_list), inf_max(Min_max_list)}, false).
1316
1294
 
1317
 
-spec(range_rem/2 :: (#range{}, #range{}) -> #range{}).
 
1295
-spec range_rem(#range{}, #range{}) -> #range{}.
1318
1296
 
1319
1297
range_rem(Range1, Range2) ->
1320
1298
  %% Range1 desides the sign of the answer.
1340
1318
 
1341
1319
%%--- Bit operations ----------------------------
1342
1320
 
1343
 
-spec(range_bsr/2 :: (#range{}, #range{}) -> #range{}).
 
1321
-spec range_bsr(#range{}, #range{}) -> #range{}.
1344
1322
 
1345
1323
range_bsr(Range1, Range2=#range{range={Min, Max}}) -> 
1346
1324
  New_Range2 = range_init({inf_inv(Max), inf_inv(Min)}, other(Range2)), 
1348
1326
  %% io:format("bsr res:~w~nInput:= ~w~n", [Ans, {Range1,Range2}]),
1349
1327
  Ans.
1350
1328
 
1351
 
-spec(range_bsl/2 :: (#range{}, #range{}) -> #range{}).
 
1329
-spec range_bsl(#range{}, #range{}) -> #range{}.
1352
1330
 
1353
1331
range_bsl(Range1, Range2) ->
1354
1332
  Min1 = range__min(Range1),
1367
1345
    end,
1368
1346
  range_init({Min, Max}, false).
1369
1347
 
1370
 
-spec(range_bnot/1 :: (#range{}) -> #range{}).
 
1348
-spec range_bnot(#range{}) -> #range{}.
1371
1349
 
1372
1350
range_bnot(Range) ->
1373
1351
  Minus_one = range_init({-1,-1}, false),
1374
1352
  range_add(range_mult(Range, Minus_one), Minus_one).
1375
1353
 
1376
 
-spec(width/1 :: (range_rep() | integer()) -> 'pos_inf' | non_neg_integer()).
 
1354
-spec width(range_rep() | integer()) -> 'pos_inf' | non_neg_integer().
1377
1355
 
1378
1356
width({Min, Max}) -> inf_max([width(Min), width(Max)]);
1379
1357
width(pos_inf) -> pos_inf;
1381
1359
width(X) when is_integer(X), X >= 0 -> poswidth(X, 0);
1382
1360
width(X) when is_integer(X), X < 0 -> negwidth(X, 0).
1383
1361
 
1384
 
-spec(poswidth/2 :: (integer(), non_neg_integer()) -> non_neg_integer()).
 
1362
-spec poswidth(integer(), non_neg_integer()) -> non_neg_integer().
1385
1363
 
1386
1364
poswidth(X, N) ->
1387
1365
  case X < (1 bsl N) of
1389
1367
    false -> poswidth(X, N+1)
1390
1368
  end.
1391
1369
 
1392
 
-spec(negwidth/2 :: (integer(), non_neg_integer()) -> non_neg_integer()).
 
1370
-spec negwidth(integer(), non_neg_integer()) -> non_neg_integer().
1393
1371
 
1394
1372
negwidth(X, N) ->
1395
1373
  case X > (-1 bsl N) of
1397
1375
    false -> negwidth(X, N+1)
1398
1376
  end.
1399
1377
 
1400
 
-spec(range_band/2 :: (#range{}, #range{}) -> #range{}).
 
1378
-spec range_band(#range{}, #range{}) -> #range{}.
1401
1379
 
1402
1380
range_band(R1, R2) ->
1403
1381
  {Min1, Max1} = range(R1),
1431
1409
    end,
1432
1410
  range_init(Range, false).  
1433
1411
 
1434
 
-spec(range_bor/2 :: (#range{}, #range{}) -> #range{}).
 
1412
-spec range_bor(#range{}, #range{}) -> #range{}.
1435
1413
 
1436
1414
range_bor(R1, R2) ->
1437
1415
  {Min1, Max1} = range(R1),
1465
1443
    end,
1466
1444
  range_init(Range, false).  
1467
1445
 
1468
 
-spec(classify_range/1 ::
1469
 
      (#range{}) -> 'minus_minus' | 'minus_plus' | 'plus_plus').
 
1446
-spec classify_range(#range{}) -> 'minus_minus' | 'minus_plus' | 'plus_plus'.
1470
1447
 
1471
1448
classify_range(Range) ->
1472
1449
  case range(Range) of
1479
1456
      classify_int_range(Number1, Number2)
1480
1457
  end.
1481
1458
 
1482
 
-spec(classify_int_range/2 :: 
1483
 
      (integer(), integer()) -> 'minus_minus' | 'minus_plus' | 'plus_plus').
 
1459
-spec classify_int_range(integer(), integer()) ->
 
1460
          'minus_minus' | 'minus_plus' | 'plus_plus'.
1484
1461
 
1485
1462
classify_int_range(Number1, _Number2) when Number1 >= 0 ->
1486
1463
  plus_plus;
1489
1466
classify_int_range(_Number1, _Number2) ->
1490
1467
  minus_plus.
1491
1468
      
1492
 
-spec(range_bxor/2 :: (#range{}, #range{}) -> #range{}).
 
1469
-spec range_bxor(#range{}, #range{}) -> #range{}.
1493
1470
 
1494
1471
range_bxor(R1, R2) ->
1495
1472
  {Min1, Max1} = range(R1),
1536
1513
%% Inf operations
1537
1514
%%---------------------------------------------------------------------------
1538
1515
 
1539
 
-spec(inf_max/1 :: ([inf_integer(),...]) -> inf_integer()).
 
1516
-spec inf_max([inf_integer(),...]) -> inf_integer().
1540
1517
 
1541
1518
inf_max([H|T]) ->
1542
1519
  lists:foldl(fun (Elem, Max) ->
1546
1523
                  end
1547
1524
              end, H, T).
1548
1525
 
1549
 
-spec(inf_min/1 :: ([inf_integer(),...]) -> inf_integer()).
 
1526
-spec inf_min([inf_integer(),...]) -> inf_integer().
1550
1527
 
1551
1528
inf_min([H|T]) ->
1552
1529
  lists:foldl(fun (Elem, Min) ->
1556
1533
                  end
1557
1534
              end, H, T).
1558
1535
 
1559
 
-spec(inf_abs/1 :: (inf_integer()) -> 'pos_inf' | integer()).
 
1536
-spec inf_abs(inf_integer()) -> 'pos_inf' | integer().
1560
1537
 
1561
1538
inf_abs(pos_inf) -> pos_inf;
1562
1539
inf_abs(neg_inf) -> pos_inf;
1563
1540
inf_abs(Number) when is_integer(Number), (Number < 0) -> - Number;
1564
1541
inf_abs(Number) when is_integer(Number) -> Number.
1565
1542
 
1566
 
-spec(inf_add/2 :: (inf_integer(), inf_integer()) -> inf_integer()).
 
1543
-spec inf_add(inf_integer(), inf_integer()) -> inf_integer().
1567
1544
 
1568
1545
inf_add(pos_inf, _Number) -> pos_inf;
1569
1546
inf_add(neg_inf, _Number) -> neg_inf;
1572
1549
inf_add(Number1, Number2) when is_integer(Number1), is_integer(Number2) ->
1573
1550
  Number1 + Number2.
1574
1551
 
1575
 
-spec(inf_inv/1 :: (inf_integer()) -> inf_integer()).
 
1552
-spec inf_inv(inf_integer()) -> inf_integer().
1576
1553
 
1577
1554
inf_inv(pos_inf) -> neg_inf;
1578
1555
inf_inv(neg_inf) -> pos_inf;
1579
1556
inf_inv(Number) -> -Number.
1580
1557
 
1581
 
-spec(inf_geq/2 :: (inf_integer(), inf_integer()) -> bool()).
 
1558
-spec inf_geq(inf_integer(), inf_integer()) -> bool().
1582
1559
 
1583
1560
inf_geq(pos_inf, _) -> true;
1584
1561
inf_geq(_, pos_inf) -> false;
1586
1563
inf_geq(neg_inf, _) -> false;
1587
1564
inf_geq(A, B) -> A >= B.
1588
1565
 
1589
 
-spec(inf_greater_zero/1 :: (inf_integer()) -> bool()).
 
1566
-spec inf_greater_zero(inf_integer()) -> bool().
1590
1567
 
1591
1568
inf_greater_zero(pos_inf) -> true;
1592
1569
inf_greater_zero(neg_inf) -> false;
1593
1570
inf_greater_zero(Number) when is_integer(Number), Number >= 0 -> true;
1594
1571
inf_greater_zero(Number) when is_integer(Number), Number < 0 -> false.
1595
1572
 
1596
 
-spec(inf_div/2 :: (inf_integer(), inf_integer()) -> inf_integer()).
 
1573
-spec inf_div(inf_integer(), inf_integer()) -> inf_integer().
1597
1574
 
1598
1575
inf_div(Number, 0) ->
1599
1576
  Greater = inf_greater_zero(Number),
1622
1599
  end;
1623
1600
inf_div(Number1, Number2) -> Number1 div Number2.
1624
1601
 
1625
 
-spec(inf_mult/2 :: (inf_integer(), inf_integer()) -> inf_integer()).
 
1602
-spec inf_mult(inf_integer(), inf_integer()) -> inf_integer().
1626
1603
 
1627
1604
inf_mult(neg_inf, Number) -> 
1628
1605
  Greater = inf_greater_zero(Number), 
1638
1615
inf_mult(Number, neg_inf) -> inf_mult(neg_inf, Number);
1639
1616
inf_mult(Number1, Number2) -> Number1 * Number2.
1640
1617
 
1641
 
-spec(inf_bsl/2 :: (inf_integer(), _) -> inf_integer()).
 
1618
-spec inf_bsl(inf_integer(), _) -> inf_integer().
1642
1619
 
1643
1620
inf_bsl(pos_inf, _) -> pos_inf;
1644
1621
inf_bsl(neg_inf, _) -> neg_inf;
1657
1634
 
1658
1635
%% State
1659
1636
 
1660
 
-spec(state__init/2 :: (cfg(), data()) -> #state{}).
 
1637
-spec state__init(cfg(), data()) -> #state{}.
1661
1638
 
1662
1639
state__init(Cfg, {MFA, ArgsFun, CallFun, FinalFun}) ->
1663
1640
  Start = hipe_icode_cfg:start_label(Cfg),  
1680
1657
             lookup_fun=CallFun, result_action=FinalFun}
1681
1658
  end.
1682
1659
 
1683
 
-spec(state__cfg/1 :: (#state{}) -> cfg()).
 
1660
-spec state__cfg(#state{}) -> cfg().
1684
1661
 
1685
1662
state__cfg(#state{cfg=Cfg}) ->
1686
1663
  Cfg.
1687
1664
 
1688
 
-spec(state__bb/2 :: (#state{}, label()) -> bb()).
 
1665
-spec state__bb(#state{}, label()) -> bb().
1689
1666
 
1690
1667
state__bb(#state{cfg=Cfg}, Label) ->
1691
1668
  BB = hipe_icode_cfg:bb(Cfg, Label),
1692
1669
  true = hipe_bb:is_bb(BB), % Just an assert
1693
1670
  BB.
1694
1671
  
1695
 
-spec(state__bb_add/3 :: (#state{}, label(), bb()) -> #state{}).
 
1672
-spec state__bb_add(#state{}, label(), bb()) -> #state{}.
1696
1673
 
1697
1674
state__bb_add(S=#state{cfg=Cfg}, Label, BB) ->
1698
1675
  NewCfg = hipe_icode_cfg:bb_add(Cfg, Label, BB),
1903
1880
%% Icode Coordinator Callbacks
1904
1881
%%=====================================================================
1905
1882
 
1906
 
-spec(replace_nones/1 :: ([#range{}]) -> [#range{}]).
 
1883
-spec replace_nones([#range{}]) -> [#range{}].
1907
1884
replace_nones(Args) ->
1908
1885
  [replace_none(Arg) || Arg <- Args].
1909
1886
 
1913
1890
    false -> Arg
1914
1891
  end.
1915
1892
 
1916
 
-spec(update__info/2 :: ([#range{}], [#range{}]) -> {bool(), [#ann{}]}).
 
1893
-spec update__info([#range{}], [#range{}]) -> {bool(), [#ann{}]}.
1917
1894
update__info(NewRanges, OldRanges) ->
1918
1895
  SupFun = fun (Ann, Range) -> 
1919
1896
               join_info(Ann, Range, fun safe_widen/3)
1923
1900
  Change = lists:zipwith(EqFun, ResRanges, OldRanges),
1924
1901
  {lists:all(fun (X) -> X end, Change), ResRanges}.
1925
1902
 
1926
 
-spec(new__info/1 :: ([#range{}]) -> [#ann{}]).
 
1903
-spec new__info/1 :: ([#range{}]) -> [#ann{}].
1927
1904
new__info(NewRanges) ->
1928
1905
  [#ann{range=Range,count=1,type=t_any()} || Range <- NewRanges].
1929
1906
 
1930
 
-spec(return__info/1 :: ([#ann{}]) -> [#range{}]).
 
1907
-spec return__info/1 :: ([#ann{}]) -> [#range{}].
1931
1908
return__info(Ranges) ->
1932
1909
  [Range || #ann{range=Range} <- Ranges].
1933
1910
 
1934
 
-spec(return_none/0 :: () -> [#range{}]).
 
1911
-spec return_none/0 :: () -> [#range{}].
1935
1912
return_none() ->
1936
1913
  [none_type()].
1937
1914
 
1938
 
-spec(return_none_args/2 :: (#cfg{}, mfa()) -> [#range{}]).
 
1915
-spec return_none_args/2 :: (#cfg{}, mfa()) -> [#range{}].
1939
1916
return_none_args(Cfg, {_M,_F,A}) ->
1940
1917
  NoArgs =
1941
1918
    case hipe_icode_cfg:is_closure(Cfg) of
1944
1921
    end,
1945
1922
  lists:duplicate(NoArgs, none_type()).
1946
1923
 
1947
 
-spec(return_any_args/2 :: (#cfg{}, mfa()) -> [#range{}]).
 
1924
-spec return_any_args/2 :: (#cfg{}, mfa()) -> [#range{}].
1948
1925
return_any_args(Cfg, {_M,_F,A}) ->
1949
1926
  NoArgs = 
1950
1927
    case hipe_icode_cfg:is_closure(Cfg) of