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%% File : hipe_icode_call_elim.erl 16%% Authors : Daniel S. McCain <dsmccain@acm.org>, 17%% Magnus Lång <margnus1@telia.com> 18%% Created : 14 Apr 2014 by Magnus Lång <margnus1@telia.com> 19%% Purpose : Eliminate calls to BIFs that are side-effect free only when 20%% executed on some argument types. 21%%---------------------------------------------------------------------- 22-module(hipe_icode_call_elim). 23-export([cfg/1]). 24 25-include("hipe_icode.hrl"). 26-include("../flow/cfg.hrl"). 27 28-spec cfg(cfg()) -> cfg(). 29 30cfg(IcodeSSA) -> 31 lists:foldl(fun (Lbl, CFG1) -> 32 BB1 = hipe_icode_cfg:bb(CFG1, Lbl), 33 Code1 = hipe_bb:code(BB1), 34 Code2 = lists:map(fun elim_insn/1, Code1), 35 BB2 = hipe_bb:code_update(BB1, Code2), 36 hipe_icode_cfg:bb_add(CFG1, Lbl, BB2) 37 end, IcodeSSA, hipe_icode_cfg:labels(IcodeSSA)). 38 39-spec elim_insn(icode_instr()) -> icode_instr(). 40elim_insn(Insn=#icode_call{'fun'={_,_,_}=MFA, args=Args, type=remote, 41 dstlist=[Dst=#icode_variable{ 42 annotation={type_anno, RetType, _}}], 43 continuation=[], fail_label=[]}) -> 44 Opaques = 'universe', 45 case erl_types:t_is_singleton(RetType, Opaques) of 46 true -> 47 ArgTypes = [case Arg of 48 #icode_variable{annotation={type_anno, Type, _}} -> Type; 49 #icode_const{} -> 50 erl_types:t_from_term(hipe_icode:const_value(Arg)) 51 end || Arg <- Args], 52 case can_be_eliminated(MFA, ArgTypes) of 53 true -> 54 Const = hipe_icode:mk_const( 55 erl_types:t_singleton_to_term(RetType, Opaques)), 56 #icode_move{dst=Dst, src=Const}; 57 false -> Insn 58 end; 59 false -> Insn 60 end; 61elim_insn(Insn) -> Insn. 62 63 64%% A function can be eliminated for some argument types if it has no side 65%% effects when run on arguments of those types. 66 67-spec can_be_eliminated(mfa(), [erl_types:erl_type()]) -> boolean(). 68 69can_be_eliminated({maps, is_key, 2}, [_K, M]) -> 70 erl_types:t_is_map(M); 71can_be_eliminated(_, _) -> 72 false. 73