hipe_icode_range.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,642 行 · 第 1/4 页

ERL
1,642
字号
      {plus_plus,   plus_plus} ->	Width = inf_max([Width1, Width2]),	{0, inf_add(-1,inf_bsl(1, Width))}    end,  range_init(Range, false).  %%---------------------------------------------------------------------------%% Inf operations%%---------------------------------------------------------------------------inf_max([]) -> empty;inf_max([H|T])->  if H =:= empty ->      inf_max(T);     true ->      lists:foldl(fun(Elem, Max) ->			  Geq = inf_geq(Elem, Max),			  if not Geq or (Elem =:= empty) ->				  Max;			     true ->				  Elem			  end		  end,		  H,		  T)  end.inf_min([]) -> empty;inf_min([H|T])->  if H =:= empty ->      inf_min(T);     true ->      lists:foldl(fun(Elem, Min) ->		      Geq = inf_geq(Elem, Min),		      if Geq or (Elem =:= empty) ->			  Min;			 true ->			  Elem		      end		  end,		  H,		  T)  end. inf_abs(pos_inf) -> pos_inf;inf_abs(neg_inf) -> pos_inf;inf_abs(Number) when is_integer(Number), (Number < 0) -> - Number;inf_abs(Number) when is_integer(Number) -> Number.inf_add(pos_inf, _Number) -> pos_inf;inf_add(neg_inf, _Number) -> neg_inf;inf_add(_Number, pos_inf) -> pos_inf;inf_add(_Number, neg_inf) -> neg_inf;inf_add(Number1, Number2) when is_integer(Number1), is_integer(Number2) ->  Number1 + Number2.inf_inv(pos_inf) -> neg_inf;inf_inv(neg_inf) -> pos_inf;inf_inv(Number) -> -Number.inf_geq(pos_inf, _) -> true;inf_geq(_, pos_inf) -> false;inf_geq(_, neg_inf) -> true;inf_geq(neg_inf, _) -> false;inf_geq(A, B) -> A >= B.inf_greater_zero(pos_inf) -> true;inf_greater_zero(neg_inf) -> false;inf_greater_zero(Number) when is_integer(Number), Number >= 0 -> true;inf_greater_zero(Number) when is_integer(Number), Number < 0 -> false.inf_div(Number, 0) ->  Greater = inf_greater_zero(Number),  if Greater -> pos_inf;     true -> neg_inf  end;inf_div(pos_inf, Number) ->  Greater = inf_greater_zero(Number),  if Greater -> pos_inf;     true -> neg_inf  end;inf_div(neg_inf, Number) ->  Greater = inf_greater_zero(Number),  if Greater -> neg_inf;     true -> pos_inf  end;inf_div(Number, pos_inf) ->   Greater = inf_greater_zero(Number),  if Greater -> pos_inf;     true -> neg_inf  end;inf_div(Number, neg_inf) ->  Greater = inf_greater_zero(Number),  if Greater -> neg_inf;     true -> pos_inf  end;inf_div(Number1, Number2) -> Number1 div Number2.inf_mult(neg_inf, Number) ->   Greater = inf_greater_zero(Number),   if Greater -> neg_inf;     true -> pos_inf  end;inf_mult(pos_inf, Number) ->   Greater = inf_greater_zero(Number),  if Greater -> pos_inf;     true -> neg_inf  end;inf_mult(Number, pos_inf) -> inf_mult(pos_inf, Number);inf_mult(Number, neg_inf) -> inf_mult(neg_inf, Number);inf_mult(Number1, Number2) -> Number1 * Number2.inf_bsl(pos_inf, _) -> pos_inf;inf_bsl(neg_inf, _) -> neg_inf;inf_bsl(Number, pos_inf) when is_integer(Number), Number >= 0 -> pos_inf;inf_bsl(_, pos_inf) -> neg_inf;inf_bsl(Number, neg_inf) when is_integer(Number), Number >= 0 -> 0;inf_bsl(_Number, neg_inf) -> -1;inf_bsl(Number1, Number2) when is_integer(Number1), is_integer(Number2) ->  %% We can not shift left with a number which is not a fixnum. We  %% don't have enough memory.  Bits = ?BITS,  if Number2 > (Bits bsl 1) -> inf_bsl(Number1, pos_inf);     Number2 < (-Bits bsl 1) ->	inf_bsl(Number1, neg_inf);     true -> Number1 bsl Number2  end.%% State-record(state, {info_map, counter=dict:new(), 		cfg, liveness, ret_type, 		lookupfun, resultaction}).state__init(Cfg,{MFA,ArgsFun,CallFun,FinalFun}) ->  Start = hipe_icode_cfg:start_label(Cfg),    Params = hipe_icode_cfg:params(Cfg),  Ranges = ArgsFun(MFA,Cfg),  %%io:format("MFA: ~w~nRanges: ~w~n",[MFA,Ranges]),  Liveness = hipe_icode_ssa:ssa_liveness__analyze(	       hipe_icode_type:unannotate_cfg(Cfg)),  case lists:any(fun range__is_none/1, Ranges) of    true ->       FinalFun(MFA,[none_type()]),      throw(no_input);    false ->      NewParams = lists:zipwith(fun update_info/2, Params, Ranges),      NewCfg = hipe_icode_cfg:params_update(Cfg, NewParams),      Info = enter_defines(NewParams,gb_trees:empty()),      InfoMap = gb_trees:insert({Start, in}, Info, gb_trees:empty()),      #state{info_map=InfoMap, cfg=NewCfg, liveness=Liveness,	     ret_type=[none_type()],	     lookupfun=CallFun, resultaction=FinalFun}  end.state__cfg(#state{cfg=Cfg}) ->  Cfg.state__bb(#state{cfg=Cfg}, Label) ->  hipe_icode_cfg:bb(Cfg, Label).  state__bb_add(S=#state{cfg=Cfg}, Label, BB) ->  NewCfg = hipe_icode_cfg:bb_add(Cfg, Label, BB),  S#state{cfg=NewCfg}.state__lookupfun(#state{lookupfun = LF}) -> LF.state__resultaction(#state{resultaction = RA}) -> RA.state__ret_type(#state{ret_type = RT}) -> RT.state__ret_type_update(#state{ret_type=RT} = State, NewType) ->  TotType = lists:zipwith(fun sup/2, RT, NewType),  State#state{ret_type=TotType}.state__info_in(S, Label) ->  state__info(S, {Label, in}).state__info(#state{info_map=IM}, Key) ->  gb_trees:get(Key,IM).state__update_info(State,LabelInfo,Rewrite) ->  update_info(LabelInfo,State,[],Rewrite).update_info([{Label,InfoIn}|Rest],State,LabelAcc,Rewrite) ->  case state__info_in_update(State, Label, InfoIn) of    fixpoint ->      if Rewrite ->	  update_info(Rest,State,[Label|LabelAcc],Rewrite);	 true ->	  update_info(Rest,State,LabelAcc,Rewrite)      end;    NewState ->      update_info(Rest,NewState,[Label|LabelAcc],Rewrite)  end;update_info([], State, LabelAcc,_Rewrite) ->  {State, LabelAcc}.state__info_in_update(S=#state{info_map=IM,liveness=Liveness}, Label, Info) ->  case gb_trees:lookup({Label, in}, IM) of    none ->       Pred = hipe_icode_cfg:pred(state__cfg(S), Label),      RawLiveIn = [hipe_icode_ssa:ssa_liveness__livein(Liveness, Label, X) ||		X <- Pred],      LiveIn = ordsets:from_list(lists:flatten(RawLiveIn)),      NamesLiveIn = [Name || {var,Name} <- LiveIn],      OldInfo = gb_trees:empty(),      case join_info_in(NamesLiveIn, OldInfo, Info) of	fixpoint -> 	  S#state{info_map=gb_trees:insert({Label,in},OldInfo,IM)};	NewInfo ->	  S#state{info_map=gb_trees:enter({Label, in},NewInfo,IM)}      end;    {value, OldInfo} ->      OldVars = gb_trees:keys(OldInfo),      case join_info_in(OldVars, OldInfo, Info) of	fixpoint -> 	  fixpoint;	NewInfo ->	  S#state{info_map=gb_trees:update({Label,in},NewInfo,IM)}      end  end.	  join_info_in(Vars, OldInfo, NewInfo) ->  case join_info_in(Vars, OldInfo, NewInfo, gb_trees:empty(), false) of    {Res, true} -> Res;    {_, false} -> fixpoint  end.  join_info_in([Var|Left], Info1, Info2, Acc, Changed) ->  Type1 = gb_trees:lookup(Var, Info1),  Type2 = gb_trees:lookup(Var, Info2),  case {Type1, Type2} of    {none, none} ->      NewTree = gb_trees:insert(Var, none_type(), Acc),      join_info_in(Left, Info1, Info2, NewTree, true);    {none, {value, Val}} ->      NewTree = gb_trees:insert(Var, Val, Acc),      join_info_in(Left, Info1, Info2, NewTree, true);    {{value, Val}, none} ->      NewTree = gb_trees:insert(Var, Val, Acc),      join_info_in(Left, Info1, Info2, NewTree, Changed);    {{value, Val}, {value, Val}} ->      NewTree = gb_trees:insert(Var, Val, Acc),      join_info_in(Left, Info1, Info2, NewTree, Changed);    {{value, Val1}, {value, Val2}} ->      NewVal = 	case sup(Val1,Val2) of	  Val1 -> 	    NewChanged = Changed,	    Val1;	  Val ->	    NewChanged = true,	    Val	end,      NewTree = gb_trees:insert(Var, NewVal, Acc),      join_info_in(Left, Info1, Info2, NewTree, NewChanged)  end;join_info_in([], _Info1, _Info2, Acc, NewChanged) ->  {Acc, NewChanged}.enter_defines([Def|Rest],Info) ->  enter_defines(Rest,enter_define(Def,Info));enter_defines([], Info) -> Info.enter_define({{var,Name,_},Range}, Info) ->  gb_trees:enter(Name,Range,Info);enter_define({var,Name,#ann{range=Range}}, Info) ->  gb_trees:enter(Name,Range,Info);enter_define(_, Info) -> Info.enter_vals(Ins,Info) ->  NewInfo = enter_defines(hipe_icode:args(Ins),Info),  enter_defines(hipe_icode:defines(Ins),NewInfo).  lookup({var,Name,_},Info) ->  case gb_trees:lookup(Name,Info) of    none ->      none_type();    {value,Val} ->      Val  end;lookup({reg,_},_Info) ->  any_type();lookup({fvar,_},_Info) ->  none_range().%% _________________________________________________________________%%%% The worklist.%%init_work(State) ->  %%Labels = hipe_icode_cfg:reverse_postorder(state__cfg(State)),  Labels = [hipe_icode_cfg:start_label(state__cfg(State))],  {Labels, [], sets:from_list(Labels)}.get_work({[Label|Left], List, Set}) ->  NewWork = {Left, List, sets:del_element(Label, Set)},  {Label, NewWork};get_work({[], [], _Set}) ->  fixpoint;get_work({[], List, Set}) ->  get_work({lists:reverse(List), [], Set}).add_work(Work = {List1, List2, Set},[Label|Left]) ->  case sets:is_element(Label, Set) of    true ->      add_work(Work, Left);    false ->      %%io:format("Adding work: ~w\n", [Label]),      add_work({List1, [Label|List2], sets:add_element(Label, Set)}, Left)  end;add_work(Work, []) ->  Work.convert_cfg_to_types(Cfg) ->  Lbls = hipe_icode_cfg:reverse_postorder(Cfg),  lists:foldl(fun convert_lbl_to_type/2, Cfg, Lbls).convert_lbl_to_type(Lbl,Cfg) ->   BB = hipe_icode_cfg:bb(Cfg, Lbl),  Code = hipe_bb:code(BB),  NewCode = [convert_instr_to_type(I) || I <- Code],  hipe_icode_cfg:bb_add(Cfg,Lbl,hipe_bb:mk_bb(NewCode)).convert_instr_to_type(I) ->  Uses = hipe_icode:uses(I),  UseSubstList = [{Use,{var,Name,convert_ann_to_types(Ann)}} ||		   Use = {var,Name,Ann = #ann{}} <- Uses],  NewI = hipe_icode:subst_uses(UseSubstList,I),  Defs = hipe_icode:defines(NewI),  DefSubstList = [{Def,{var,Name,convert_ann_to_types(Ann)}} ||		   Def = {var,Name,Ann = #ann{}} <- Defs],  hipe_icode:subst_defines(DefSubstList, NewI).convert_ann_to_types(#ann{range=#range{range={Min,Max},other=false}}) ->  t_from_range_unsafe(Min,Max);convert_ann_to_types(#ann{range=#range{range=empty,other=false}}) ->  t_none();convert_ann_to_types(#ann{range=#range{other=true},type=Type}) ->  Type.%%=====================================================================%% Icode Coordinator Callbacks%%=====================================================================replace_nones(Args) ->  [replace_none(Arg) || Arg <- Args].replace_none(Arg) ->  case range__is_none(Arg) of    true -> any_type();    false -> Arg  end.      update__info(NewRanges,OldRanges) ->  SupFun = fun(Ann,Range) -> 	       join_info(Ann, Range, fun safe_widen/3)	   end,  EqFun = fun(X,Y) -> X =:= Y end,  ResRanges = lists:zipwith(SupFun,OldRanges,NewRanges),  Change = lists:zipwith(EqFun,ResRanges,OldRanges),  {lists:all(fun(X) -> X end, Change),ResRanges}.new__info(NewRanges) ->  [#ann{range=Range,count=1,type=t_any()} || Range <- NewRanges].return__info(Ranges) ->  [Range || #ann{range=Range} <- Ranges].return_none() ->    [none_type()].return_none_args(Cfg,{_M,_F,A}) ->  NoArgs =     case hipe_icode_cfg:is_closure(Cfg) of      true -> hipe_icode_cfg:closure_arity(Cfg)+1;      false -> A    end,  lists:duplicate(NoArgs,none_type()).return_any_args(Cfg,{_M,_F,A}) ->  NoArgs =     case hipe_icode_cfg:is_closure(Cfg) of      true -> hipe_icode_cfg:closure_arity(Cfg)+1;      false -> A    end,  lists:duplicate(NoArgs,any_type()).%%=====================================================================next_up_limit(X) when is_integer(X), X < 0 -> 0;next_up_limit(X) when is_integer(X), X < 255 -> 255;next_up_limit(X) when is_integer(X), X < 16#10ffff -> 16#10ffff;next_up_limit(X) when is_integer(X), X < 16#7ffffff -> 16#7ffffff;next_up_limit(X) when is_integer(X), X < 16#7fffffff -> 16#7fffffff;next_up_limit(X) when is_integer(X), X < 16#ffffffff -> 16#ffffffff;next_up_limit(X) when is_integer(X), X < 16#fffffffffff -> 16#fffffffffff;next_up_limit(X) when is_integer(X), X < 16#7fffffffffffffff -> 16#7fffffffffffffff;next_up_limit(_X) -> pos_inf.next_down_limit(X) when is_integer(X), X > 0 -> 0;next_down_limit(X) when is_integer(X), X > -256 -> -256;next_down_limit(X) when is_integer(X), X > -16#10ffff -> -16#10ffff;next_down_limit(X) when is_integer(X), X > -16#8000000 -> -16#8000000;next_down_limit(X) when is_integer(X), X > -16#80000000 -> -16#80000000;next_down_limit(X) when is_integer(X), X > -16#800000000000000 -> -16#800000000000000;next_down_limit(_X) -> neg_inf.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?