aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorHans Bolinder <[email protected]>2016-05-30 16:26:43 +0200
committerHans Bolinder <[email protected]>2016-06-09 11:28:00 +0200
commite6595b12b525acb6842ba0f60eef8881fa9c658d (patch)
treea07b2da5896191f05450f84ec861680fb7bd7e12 /lib
parentcc66d101191b072d3a76bcec45fc6c224184cfbd (diff)
downloadotp-e6595b12b525acb6842ba0f60eef8881fa9c658d.tar.gz
otp-e6595b12b525acb6842ba0f60eef8881fa9c658d.tar.bz2
otp-e6595b12b525acb6842ba0f60eef8881fa9c658d.zip
dialyzer: Optimize erl_types:t_form_form()
When the translation from forms to types exceeds some limit, it is faster to try small depths first.
Diffstat (limited to 'lib')
-rw-r--r--lib/hipe/cerl/erl_types.erl34
1 files changed, 21 insertions, 13 deletions
diff --git a/lib/hipe/cerl/erl_types.erl b/lib/hipe/cerl/erl_types.erl
index 8dbf188ab3..7bfb44c06f 100644
--- a/lib/hipe/cerl/erl_types.erl
+++ b/lib/hipe/cerl/erl_types.erl
@@ -4430,8 +4430,7 @@ t_from_form(Form, ExpTypes, Site, RecDict) ->
site(), mod_records(), var_table()) -> erl_type().
t_from_form(Form, ExpTypes, Site, RecDict, VarDict) ->
- {T, _} = t_from_form1(Form, ExpTypes, Site, RecDict, VarDict),
- T.
+ t_from_form1(Form, ExpTypes, Site, RecDict, VarDict).
%% Replace external types with with none().
-spec t_from_form_without_remote(parse_form(), site(), type_table()) ->
@@ -4441,8 +4440,7 @@ t_from_form_without_remote(Form, Site, TypeTable) ->
Module = site_module(Site),
RecDict = dict:from_list([{Module, TypeTable}]),
ExpTypes = replace_by_none,
- {T, _} = t_from_form1(Form, ExpTypes, Site, RecDict, var_table__new()),
- T.
+ t_from_form1(Form, ExpTypes, Site, RecDict, maps:new()).
%% REC_TYPE_LIMIT is used for limiting the depth of recursive types.
%% EXPAND_LIMIT is used for limiting the size of types by
@@ -4457,27 +4455,37 @@ t_from_form_without_remote(Form, Site, TypeTable) ->
-spec t_from_form1(parse_form(), sets:set(mfa()) | 'replace_by_none',
site(), mod_records(), var_table()) ->
- {erl_type(), expand_limit()}.
+ erl_type().
t_from_form1(Form, ET, Site, MR, V) ->
TypeNames = initial_typenames(Site),
- t_from_form1(Form, TypeNames, ET, Site, MR, V, ?EXPAND_DEPTH).
+ D0 = ?EXPAND_DEPTH,
+ {T1, L1} = t_from_form2(Form, TypeNames, ET, Site, MR, V, D0),
+ if
+ L1 =< 0 ->
+ t_from_form_loop(Form, TypeNames, ET, Site, MR, V, 1, ?EXPAND_LIMIT);
+ true -> T1
+ end.
initial_typenames({type, _MTA}=Site) -> [Site];
initial_typenames({spec, _MFA}) -> [];
initial_typenames({record, _MRA}) -> [].
-t_from_form1(Form, TypeNames, ET, Site, MR, V, D) ->
- L = ?EXPAND_LIMIT,
- {T, L1} = t_from_form(Form, TypeNames, ET, Site, MR, V, D, L),
+t_from_form_loop(Form, TypeNames, ET, Site, MR, V, D, L0) ->
+ {T1, L1} = t_from_form2(Form, TypeNames, ET, Site, MR, V, D),
+ Delta = L0 - L1,
if
- L1 =< 0, D > 1 ->
- D1 = D div 2,
- t_from_form1(Form, TypeNames, ET, Site, MR, V, D1);
+ %% Save some time by assuming next depth will exceed the limit.
+ Delta * 8 > L0 -> T1;
true ->
- {T, L1}
+ D1 = D + 1,
+ t_from_form_loop(Form, TypeNames, ET, Site, MR, V, D1, L1)
end.
+t_from_form2(Form, TypeNames, ET, Site, MR, V, D) ->
+ L = ?EXPAND_LIMIT,
+ t_from_form(Form, TypeNames, ET, Site, MR, V, D, L).
+
-spec t_from_form(parse_form(), type_names(),
sets:set(mfa()) | 'replace_by_none',
site(), mod_records(), var_table(),