diff options
author | Björn Gustavsson <[email protected]> | 2010-03-12 09:42:40 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2010-06-02 11:51:25 +0200 |
commit | 470c91d43eae54f63661645acbce4b92d73287cc (patch) | |
tree | c3138d787cdc668f3cfc9d94b25f7c564118b29d /lib/compiler/src | |
parent | 7ac0808979534a94617c3391503c961d1ef72755 (diff) | |
download | otp-470c91d43eae54f63661645acbce4b92d73287cc.tar.gz otp-470c91d43eae54f63661645acbce4b92d73287cc.tar.bz2 otp-470c91d43eae54f63661645acbce4b92d73287cc.zip |
Evaluate is_record/3 at compile-time using type information
Diffstat (limited to 'lib/compiler/src')
-rw-r--r-- | lib/compiler/src/sys_core_fold.erl | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl index 3e572d4b27..96015fbe58 100644 --- a/lib/compiler/src/sys_core_fold.erl +++ b/lib/compiler/src/sys_core_fold.erl @@ -1038,6 +1038,8 @@ fold_non_lit_args(Call, lists, append, [Arg1,Arg2], _) -> eval_append(Call, Arg1, Arg2); fold_non_lit_args(Call, erlang, setelement, [Arg1,Arg2,Arg3], _) -> eval_setelement(Call, Arg1, Arg2, Arg3); +fold_non_lit_args(Call, erlang, is_record, [Arg1,Arg2,Arg3], Sub) -> + eval_is_record(Call, Arg1, Arg2, Arg3, Sub); fold_non_lit_args(Call, erlang, N, Args, Sub) -> NumArgs = length(Args), case erl_internal:comp_op(N, NumArgs) of @@ -1218,6 +1220,20 @@ eval_element(Call, Pos, Tuple, _Types) -> Call end. +%% eval_is_record(Call, Var, Tag, Size, Types) -> Val. +%% Evaluates is_record/3 using type information. +%% +eval_is_record(Call, #c_var{name=V}, #c_literal{val=NeededTag}=Lit, + #c_literal{val=Size}, Types) -> + case orddict:find(V, Types#sub.t) of + {ok,#c_tuple{es=[#c_literal{val=Tag}|_]=Es}} -> + Lit#c_literal{val=Tag =:= NeededTag andalso + length(Es) =:= Size}; + _ -> + Call + end; +eval_is_record(Call, _, _, _, _) -> Call. + %% is_not_integer(Core) -> true | false. %% Returns true if Core is definitely not an integer. |