hipe_amd64_ra_sse2_postconditions.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 172 行

ERL
172
字号
%%% -*- erlang-indent-level: 2 -*-%%% $Id$-module(hipe_amd64_ra_sse2_postconditions).-export([check_and_rewrite/2]).-include("../x86/hipe_x86.hrl").-define(HIPE_INSTRUMENT_COMPILER, true).-include("../main/hipe.hrl").-define(count_temp(T), ?cons_counter(counter_mfa_mem_temps, T)).check_and_rewrite(AMD64Defun, Coloring) ->  %%io:format("Converting\n"),  TempMap = hipe_temp_map:cols2tuple(Coloring,hipe_amd64_specific_sse2),  %%io:format("Rewriting\n"),  #defun{code=Code0} = AMD64Defun,  {Code1, DidSpill} = do_insns(Code0, TempMap, [], false),  {AMD64Defun#defun{code=Code1,		  var_range={0, hipe_gensym:get_var(x86)}},    DidSpill}.do_insns([I|Insns], TempMap, Accum, DidSpill0) ->  {NewIs, DidSpill1} = do_insn(I, TempMap),  do_insns(Insns, TempMap, lists:reverse(NewIs, Accum), DidSpill0 or DidSpill1);do_insns([], _TempMap, Accum, DidSpill) ->  {lists:reverse(Accum), DidSpill}.do_insn(I, TempMap) ->	% Insn -> {Insn list, DidSpill}  case I of    #fmove{} ->      do_fmove(I, TempMap);    #fp_unop{} ->      do_fp_unop(I, TempMap);    #fp_binop{} ->      do_fp_binop(I, TempMap);    _ ->      %% All non sse2 ops      {[I], false}  end.%%% Fix an fp_binop.do_fp_binop(I, TempMap) ->  #fp_binop{src=Src,dst=Dst} = I,  case is_mem_opnd(Dst, TempMap) of    true ->      Tmp = clone(Dst),      {[#fmove{src=Dst, dst=Tmp},	I#fp_binop{src=Src,dst=Tmp},	#fmove{src=Tmp,dst=Dst}],       true};    false ->      {[I], false}  end.do_fp_unop(I, TempMap) ->  #fp_unop{arg=Arg} = I,  case is_mem_opnd(Arg, TempMap) of    true ->      Tmp = clone(Arg),      {[#fmove{src=Arg, dst=Tmp},	I#fp_unop{arg=Tmp},	#fmove{src=Tmp,dst=Arg}],       true};    false ->      {[I], false}  end.%%% Fix an fmove op.do_fmove(I, TempMap) ->  #fmove{src=Src,dst=Dst} = I,  case is_mem_opnd(Dst, TempMap) and is_mem_opnd(Src, TempMap) of    true ->      Tmp = clone(Src),      {[#fmove{src=Src, dst=Tmp},I#fmove{src=Tmp,dst=Dst}],       true};    false ->      {[I], false}  end.%%% Check if an operand denotes a memory cell (mem or pseudo).is_mem_opnd(Opnd, TempMap) ->  R =    case Opnd of      #x86_mem{} -> true;      #x86_temp{} -> 	Reg = hipe_x86:temp_reg(Opnd),	case hipe_x86:temp_is_allocatable(Opnd) of	  true -> 	    case size(TempMap) > Reg of 	      true ->		case 		  hipe_temp_map:is_spilled(Reg,					   TempMap) of		  true ->		    ?count_temp(Reg),		    true;		  false -> false		end;	      _ -> false	    end;	  false -> true	end;      _ -> false    end,  %%  io:format("Op ~w mem: ~w\n",[Opnd,R]),  R.%%% Check if an operand is a spilled Temp.%%src_is_spilled(Src, TempMap) ->%%  case hipe_x86:is_temp(Src) of%%    true ->%%      Reg = hipe_x86:temp_reg(Src),%%      case hipe_x86:temp_is_allocatable(Src) of%%	true -> %%	  case size(TempMap) > Reg of %%	    true ->%%	      case hipe_temp_map:is_spilled(Reg, TempMap) of%%		true ->%%		  ?count_temp(Reg),%%		  true;%%		false ->%%		  false%%	      end;%%	    false ->%%	      false%%	  end;%%	false -> true%%      end;%%    false -> false%%  end.%% is_spilled(Temp, TempMap) ->%%   case hipe_x86:temp_is_allocatable(Temp) of%%     true ->%%       Reg = hipe_x86:temp_reg(Temp),%%       case size(TempMap) > Reg of %%  	true ->%%  	  case hipe_temp_map:is_spilled(Reg, TempMap) of%%  	    true ->%%  	      ?count_temp(Reg),%%  	      true;%%  	    false ->%%  	      false%%  	  end;%%  	false ->%%  	  false%%       end;%%     false -> true%%   end.%%% Make Reg a clone of Dst (attach Dst's type to Reg).clone(Dst) ->  Type =    case Dst of      #x86_mem{} -> hipe_x86:mem_type(Dst);      #x86_temp{} -> hipe_x86:temp_type(Dst)    end,  hipe_x86:mk_new_temp(Type).%%% Make a certain reg into a clone of Dst% clone2(Dst, Reg) ->%   Type =%     case Dst of%       #x86_mem{} -> hipe_x86:mem_type(Dst);%       #x86_temp{} -> hipe_x86:temp_type(Dst)%     end,%   hipe_x86:mk_temp(Reg,Type).

⌨️ 快捷键说明

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