1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2018-2020. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20%% This pass infers types from expressions and attempts to simplify or remove
21%% subsequent instructions based on that information.
22%%
23%% This is divided into two subpasses; the first figures out function type
24%% signatures for the whole module without optimizing anything, and the second
25%% optimizes based on that information, further refining the type signatures as
26%% it goes.
27%%
28
29-module(beam_ssa_type).
30-export([opt_start/2, opt_continue/4, opt_finish/3]).
31
32-include("beam_ssa_opt.hrl").
33-include("beam_types.hrl").
34
35-import(lists, [all/2,any/2,duplicate/2,foldl/3,member/2,
36                keyfind/3,reverse/1,split/2,zip/2]).
37
38%% The maximum number of #b_ret{} terminators a function can have before
39%% collapsing success types into a single entry. Consider the following code:
40%%
41%%    f(0) -> 1;
42%%    f(...) -> ...;
43%%    f(500000) -> 500000.
44%%
45%% Since success types are grouped by return type and each clause returns a
46%% distinct type (singleton #t_integer{}s), we'll add 500000 entries which
47%% makes progress glacial since every call needs to examine them all to
48%% determine the return type.
49%%
50%% The entries are collapsed unconditionally if the number of returns in a
51%% function exceeds this threshold. This is necessary because collapsing as we
52%% go might widen a type; if we're at (?RETURN_LIMIT - 1) entries and suddenly
53%% narrow a type down, it could push us over the edge and collapse all entries,
54%% possibly widening the return type and breaking optimizations that were based
55%% on the earlier (narrower) types.
56-define(RETURN_LIMIT, 30).
57
58%% Constants common to all subpasses.
59-record(metadata,
60        { func_id :: func_id(),
61          limit_return :: boolean(),
62          params :: [beam_ssa:b_var()],
63          used_once :: cerl_sets:set(beam_ssa:b_var()) }).
64
65-type type_db() :: #{ beam_ssa:var_name() := type() }.
66
67%%
68
69-spec opt_start(term(), term()) -> term().
70opt_start(StMap, FuncDb0) when FuncDb0 =/= #{} ->
71    {ArgDb, FuncDb} = signatures(StMap, FuncDb0),
72
73    opt_start_1(maps:keys(StMap), ArgDb, StMap, FuncDb);
74opt_start(StMap, FuncDb) ->
75    %% Module-level analysis is disabled, likely because of a call to
76    %% load_nif/2 or similar. opt_continue/4 will assume that all arguments and
77    %% return types are 'any'.
78    {StMap, FuncDb}.
79
80opt_start_1([Id | Ids], ArgDb, StMap0, FuncDb0) ->
81    case ArgDb of
82        #{ Id := ArgTypes } ->
83            #opt_st{ssa=Linear0,args=Args} = St0 = map_get(Id, StMap0),
84
85            Ts = maps:from_list(zip(Args, ArgTypes)),
86            {Linear, FuncDb} = opt_function(Linear0, Args, Id, Ts, FuncDb0),
87
88            St = St0#opt_st{ssa=Linear},
89            StMap = StMap0#{ Id := St },
90
91            opt_start_1(Ids, ArgDb, StMap, FuncDb);
92        #{} ->
93            %% Unreachable functions must be removed so that opt_continue/4
94            %% won't process them and potentially taint the argument types of
95            %% other functions.
96            StMap = maps:remove(Id, StMap0),
97            FuncDb = maps:remove(Id, FuncDb0),
98
99            opt_start_1(Ids, ArgDb, StMap, FuncDb)
100    end;
101opt_start_1([], _CommittedArgs, StMap, FuncDb) ->
102    {StMap, FuncDb}.
103
104%%
105%% The initial signature analysis is based on the paper "Practical Type
106%% Inference Based on Success Typings" [1] by `Tobias Lindahl` and
107%% `Konstantinos Sagonas`, mainly section 6.1 and onwards.
108%%
109%% The general idea is to start out at the module's entry points and propagate
110%% types to the functions we call. The argument types of all exported functions
111%% start out a 'any', whereas local functions start at 'none'. Every time a
112%% function call widens the argument types, we analyze the callee again and
113%% propagate its return types to the callers, analyzing them again, and
114%% continuing this process until all arguments and return types have been
115%% widened as far as they can be.
116%%
117%% Note that we do not "jump-start the analysis" by first determining success
118%% types as in the paper because we need to know all possible inputs including
119%% those that will not return.
120%%
121%% [1] http://www.it.uu.se/research/group/hipe/papers/succ_types.pdf
122%%
123
124-record(sig_st,
125        { wl = wl_new() :: worklist(),
126          committed = #{} :: #{ func_id() => [type()] },
127          updates = #{} :: #{ func_id() => [type()] }}).
128
129signatures(StMap, FuncDb0) ->
130    State0 = init_sig_st(StMap, FuncDb0),
131    {State, FuncDb} = signatures_1(StMap, FuncDb0, State0),
132    {State#sig_st.committed, FuncDb}.
133
134signatures_1(StMap, FuncDb0, State0) ->
135    case wl_next(State0#sig_st.wl) of
136        {ok, FuncId} ->
137            {State, FuncDb} = sig_function(FuncId, StMap, State0, FuncDb0),
138            signatures_1(StMap, FuncDb, State);
139        empty ->
140            %% No more work to do, assert that we don't have any outstanding
141            %% updates.
142            #sig_st{updates=Same,committed=Same} = State0, %Assertion.
143
144            {State0, FuncDb0}
145    end.
146
147sig_function(Id, StMap, State0, FuncDb0) ->
148    case sig_function_1(Id, StMap, State0, FuncDb0) of
149        {false, false, State, FuncDb} ->
150            %% No added work and the types are identical. Pop ourselves from
151            %% the work list and move on to the next function.
152            Wl = wl_pop(Id, State#sig_st.wl),
153            {State#sig_st{wl=Wl}, FuncDb};
154        {false, true, State, FuncDb} ->
155            %% We've added some work and our return type is unchanged. Keep
156            %% following the work list without popping ourselves; we're very
157            %% likely to need to return here later and can avoid a lot of
158            %% redundant work by keeping our place in line.
159            {State, FuncDb};
160        {true, WlChanged, State, FuncDb} ->
161            %% Our return type has changed so all of our (previously analyzed)
162            %% callers need to be analyzed again.
163            %%
164            %% If our worklist is unchanged we'll pop ourselves since our
165            %% callers will add us back if we need to analyzed again, and
166            %% it's wasteful to stay in the worklist when we don't.
167            Wl0 = case WlChanged of
168                      true -> State#sig_st.wl;
169                      false -> wl_pop(Id, State#sig_st.wl)
170                  end,
171
172            #func_info{in=Cs0} = map_get(Id, FuncDb0),
173            Callers = [C || C <- Cs0, is_map_key(C, State#sig_st.updates)],
174            Wl = wl_defer_list(Callers, Wl0),
175
176            {State#sig_st{wl=Wl}, FuncDb}
177    end.
178
179sig_function_1(Id, StMap, State0, FuncDb) ->
180    #opt_st{ssa=Linear,args=Args} = map_get(Id, StMap),
181
182    {ArgTypes, State1} = sig_commit_args(Id, State0),
183    Ts = maps:from_list(zip(Args, ArgTypes)),
184
185    FakeCall = #b_set{op=call,args=[#b_remote{mod=#b_literal{val=unknown},
186                                              name=#b_literal{val=unknown},
187                                              arity=0}]},
188
189    Ds = maps:from_list([{Var, FakeCall#b_set{dst=Var}} ||
190                            #b_var{}=Var <- Args]),
191
192    Ls = #{ ?EXCEPTION_BLOCK => {incoming, Ts},
193            0 => {incoming, Ts} },
194
195    Meta = init_metadata(Id, Linear, Args),
196
197    Wl0 = State1#sig_st.wl,
198
199    {State, SuccTypes} = sig_bs(Linear, Ds, Ls, FuncDb, #{}, [], Meta, State1),
200
201    WlChanged = wl_changed(Wl0, State#sig_st.wl),
202    #{ Id := #func_info{succ_types=SuccTypes0}=Entry0 } = FuncDb,
203
204    if
205        SuccTypes0 =:= SuccTypes ->
206            {false, WlChanged, State, FuncDb};
207        SuccTypes0 =/= SuccTypes ->
208            Entry = Entry0#func_info{succ_types=SuccTypes},
209            {true, WlChanged, State, FuncDb#{ Id := Entry }}
210    end.
211
212sig_bs([{L, #b_blk{is=Is,last=Last0}} | Bs],
213       Ds0, Ls0, Fdb, Sub0, SuccTypes0, Meta, State0) ->
214    case Ls0 of
215        #{ L := Incoming } ->
216            {incoming, Ts0} = Incoming,         %Assertion.
217
218            {Ts, Ds, Sub, State} =
219                sig_is(Is, Ts0, Ds0, Ls0, Fdb, Sub0, State0),
220
221            Last = simplify_terminator(Last0, Ts, Ds, Sub),
222            SuccTypes = update_success_types(Last, Ts, Ds, Meta, SuccTypes0),
223
224            UsedOnce = Meta#metadata.used_once,
225            {_, Ls1} = update_successors(Last, Ts, Ds, Ls0, UsedOnce),
226
227            %% In the future there may be a point to storing outgoing types on
228            %% a per-edge basis as it would give us more precision in phi
229            %% nodes, but there's nothing to gain from that at the moment so
230            %% we'll store the current Ts to save memory.
231            Ls = Ls1#{ L := {outgoing, Ts} },
232            sig_bs(Bs, Ds, Ls, Fdb, Sub, SuccTypes, Meta, State);
233        #{} ->
234            %% This block is never reached. Ignore it.
235            sig_bs(Bs, Ds0, Ls0, Fdb, Sub0, SuccTypes0, Meta, State0)
236    end;
237sig_bs([], _Ds, _Ls, _Fdb, _Sub, SuccTypes, _Meta, State) ->
238    {State, SuccTypes}.
239
240sig_is([#b_set{op=call,
241               args=[#b_local{}=Callee | _]=Args0,
242               dst=Dst}=I0 | Is],
243       Ts0, Ds0, Ls, Fdb, Sub, State0) ->
244    Args = simplify_args(Args0, Ts0, Sub),
245    I1 = beam_ssa:normalize(I0#b_set{args=Args}),
246
247    [_ | CallArgs] = Args,
248    {I, State} = sig_local_call(I1, Callee, CallArgs, Ts0, Fdb, State0),
249
250    Ts = update_types(I, Ts0, Ds0),
251    Ds = Ds0#{ Dst => I },
252    sig_is(Is, Ts, Ds, Ls, Fdb, Sub, State);
253sig_is([#b_set{op=call,
254               args=[#b_var{} | _]=Args0,
255               dst=Dst}=I0 | Is],
256       Ts0, Ds0, Ls, Fdb, Sub, State) ->
257    Args = simplify_args(Args0, Ts0, Sub),
258    I1 = beam_ssa:normalize(I0#b_set{args=Args}),
259
260    [Fun | _] = Args,
261    I = case normalized_type(Fun, Ts0) of
262            #t_fun{type=Type} -> beam_ssa:add_anno(result_type, Type, I1);
263            _ -> I1
264        end,
265
266    Ts = update_types(I, Ts0, Ds0),
267    Ds = Ds0#{ Dst => I },
268    sig_is(Is, Ts, Ds, Ls, Fdb, Sub, State);
269sig_is([#b_set{op=make_fun,args=Args0,dst=Dst}=I0|Is],
270       Ts0, Ds0, Ls, Fdb, Sub0, State0) ->
271    Args = simplify_args(Args0, Ts0, Sub0),
272    I1 = beam_ssa:normalize(I0#b_set{args=Args}),
273
274    {I, State} = sig_make_fun(I1, Ts0, Fdb, State0),
275
276    Ts = update_types(I, Ts0, Ds0),
277    Ds = Ds0#{ Dst => I },
278    sig_is(Is, Ts, Ds, Ls, Fdb, Sub0, State);
279sig_is([I0 | Is], Ts0, Ds0, Ls, Fdb, Sub0, State) ->
280    case simplify(I0, Ts0, Ds0, Ls, Sub0) of
281        {#b_set{}, Ts, Ds} ->
282            sig_is(Is, Ts, Ds, Ls, Fdb, Sub0, State);
283        Sub when is_map(Sub) ->
284            sig_is(Is, Ts0, Ds0, Ls, Fdb, Sub, State)
285    end;
286sig_is([], Ts, Ds, _Ls, _Fdb, Sub, State) ->
287    {Ts, Ds, Sub, State}.
288
289sig_local_call(I0, Callee, Args, Ts, Fdb, State) ->
290    ArgTypes = argument_types(Args, Ts),
291    I = sig_local_return(I0, Callee, ArgTypes, Fdb),
292    {I, sig_update_args(Callee, ArgTypes, State)}.
293
294%% While it's impossible to tell which arguments a fun will be called with
295%% (someone could steal it through tracing and call it), we do know its free
296%% variables and can update their types as if this were a local call.
297sig_make_fun(#b_set{op=make_fun,
298                    args=[#b_local{}=Callee | FreeVars]}=I0,
299             Ts, Fdb, State) ->
300    ArgCount = Callee#b_local.arity - length(FreeVars),
301
302    FVTypes = [raw_type(FreeVar, Ts) || FreeVar <- FreeVars],
303    ArgTypes = duplicate(ArgCount, any) ++ FVTypes,
304
305    I = sig_local_return(I0, Callee, ArgTypes, Fdb),
306    {I, sig_update_args(Callee, ArgTypes, State)}.
307
308sig_local_return(I, Callee, ArgTypes, Fdb) ->
309    #func_info{succ_types=SuccTypes} = map_get(Callee, Fdb),
310    case return_type(SuccTypes, ArgTypes) of
311        any -> I;
312        Type -> beam_ssa:add_anno(result_type, Type, I)
313    end.
314
315init_sig_st(StMap, FuncDb) ->
316    %% Start out as if all the roots have been called with 'any' for all
317    %% arguments.
318    Roots = init_sig_roots(FuncDb),
319    #sig_st{ committed=#{},
320             updates=init_sig_args(Roots, StMap, #{}),
321             wl=wl_defer_list(Roots, wl_new()) }.
322
323init_sig_roots(FuncDb) ->
324    maps:fold(fun(Id, #func_info{exported=true}, Acc) ->
325                      [Id | Acc];
326                 (_, _, Acc) ->
327                      Acc
328              end, [], FuncDb).
329
330init_sig_args([Root | Roots], StMap, Acc) ->
331    #opt_st{args=Args0} = map_get(Root, StMap),
332    ArgTypes = lists:duplicate(length(Args0), any),
333    init_sig_args(Roots, StMap, Acc#{ Root => ArgTypes });
334init_sig_args([], _StMap, Acc) ->
335    Acc.
336
337sig_commit_args(Id, #sig_st{updates=Us,committed=Committed0}=State0) ->
338    Types = map_get(Id, Us),
339    Committed = Committed0#{ Id => Types },
340    State = State0#sig_st{committed=Committed},
341    {Types, State}.
342
343sig_update_args(Callee, Types, #sig_st{committed=Committed}=State) ->
344    case Committed of
345        #{ Callee := Current } ->
346            case parallel_join(Current, Types) of
347                Current ->
348                    %% We've already processed this function with these
349                    %% arguments, so there's no need to visit it again.
350                    State;
351                Widened ->
352                    sig_update_args_1(Callee, Widened, State)
353            end;
354        #{} ->
355            sig_update_args_1(Callee, Types, State)
356    end.
357
358sig_update_args_1(Callee, Types, #sig_st{updates=Us0,wl=Wl0}=State) ->
359    Us = case Us0 of
360             #{ Callee := Current } ->
361                 Us0#{ Callee => parallel_join(Current, Types) };
362             #{} ->
363                 Us0#{ Callee => Types }
364         end,
365    State#sig_st{updates=Us,wl=wl_add(Callee, Wl0)}.
366
367-spec opt_continue(Linear, Args, Anno, FuncDb) -> {Linear, FuncDb} when
368      Linear :: [{non_neg_integer(), beam_ssa:b_blk()}],
369      Args :: [beam_ssa:b_var()],
370      Anno :: beam_ssa:anno(),
371      FuncDb :: func_info_db().
372opt_continue(Linear0, Args, Anno, FuncDb) when FuncDb =/= #{} ->
373    Id = get_func_id(Anno),
374    case FuncDb of
375        #{ Id := #func_info{exported=false,arg_types=ArgTypes} } ->
376            %% This is a local function and we're guaranteed to have visited
377            %% every call site at least once, so we know that the parameter
378            %% types are at least as narrow as the join of all argument types.
379            Ts = join_arg_types(Args, ArgTypes, #{}),
380            opt_function(Linear0, Args, Id, Ts, FuncDb);
381        #{ Id := #func_info{exported=true} } ->
382            %% We can't infer the parameter types of exported functions, but
383            %% running the pass again could still help other functions.
384            Ts = maps:from_list([{V,any} || #b_var{}=V <- Args]),
385            opt_function(Linear0, Args, Id, Ts, FuncDb)
386    end;
387opt_continue(Linear0, Args, Anno, _FuncDb) ->
388    %% Module-level optimization is disabled, pass an empty function database
389    %% so we only perform local optimizations.
390    Id = get_func_id(Anno),
391    Ts = maps:from_list([{V,any} || #b_var{}=V <- Args]),
392    {Linear, _} = opt_function(Linear0, Args, Id, Ts, #{}),
393    {Linear, #{}}.
394
395join_arg_types([Arg | Args], [TypeMap | TMs], Ts) ->
396    Type = beam_types:join(maps:values(TypeMap)),
397    join_arg_types(Args, TMs, Ts#{ Arg => Type });
398join_arg_types([], [], Ts) ->
399    Ts.
400
401%%
402%% Optimizes a function based on the type information inferred by signatures/2
403%% and earlier runs of opt_function/5.
404%%
405%% This is pretty straightforward as it only walks through each function once,
406%% and because it only makes types narrower it's safe to optimize the functions
407%% in any order or not at all.
408%%
409
410-spec opt_function(Linear, Args, Id, Ts, FuncDb) -> Result when
411      Linear :: [{non_neg_integer(), beam_ssa:b_blk()}],
412      Args :: [beam_ssa:b_var()],
413      Id :: func_id(),
414      Ts :: type_db(),
415      FuncDb :: func_info_db(),
416      Result :: {Linear, FuncDb}.
417opt_function(Linear0, Args, Id, Ts, FuncDb0) ->
418    FakeCall = #b_set{op=call,args=[#b_remote{mod=#b_literal{val=unknown},
419                                              name=#b_literal{val=unknown},
420                                              arity=0}]},
421
422    Ds = maps:from_list([{Var, FakeCall#b_set{dst=Var}} ||
423                            #b_var{}=Var <- Args]),
424
425    Ls = #{ ?EXCEPTION_BLOCK => {incoming, Ts},
426            0 => {incoming, Ts} },
427
428    Meta = init_metadata(Id, Linear0, Args),
429
430    {Linear, FuncDb, SuccTypes} =
431        opt_bs(Linear0, Ds, Ls, FuncDb0, #{}, [], Meta, []),
432
433    case FuncDb of
434        #{ Id := Entry0 } ->
435            Entry = Entry0#func_info{succ_types=SuccTypes},
436            {Linear, FuncDb#{ Id := Entry }};
437        #{} ->
438            %% Module-level optimizations have been turned off.
439            {Linear, FuncDb}
440    end.
441
442get_func_id(Anno) ->
443    #{func_info:={_Mod, Name, Arity}} = Anno,
444    #b_local{name=#b_literal{val=Name}, arity=Arity}.
445
446opt_bs([{L, #b_blk{is=Is0,last=Last0}=Blk0} | Bs],
447       Ds0, Ls0, Fdb0, Sub0, SuccTypes0, Meta, Acc) ->
448    case Ls0 of
449        #{ L := Incoming } ->
450            {incoming, Ts0} = Incoming,         %Assertion.
451
452            {Is, Ts, Ds, Fdb, Sub} =
453            opt_is(Is0, Ts0, Ds0, Ls0, Fdb0, Sub0, Meta, []),
454
455            Last1 = simplify_terminator(Last0, Ts, Ds, Sub),
456            SuccTypes = update_success_types(Last1, Ts, Ds, Meta, SuccTypes0),
457
458            UsedOnce = Meta#metadata.used_once,
459            {Last, Ls1} = update_successors(Last1, Ts, Ds, Ls0, UsedOnce),
460
461            Ls = Ls1#{ L := {outgoing, Ts} },           %Assertion.
462
463            Blk = Blk0#b_blk{is=Is,last=Last},
464            opt_bs(Bs, Ds, Ls, Fdb, Sub, SuccTypes, Meta, [{L,Blk} | Acc]);
465        #{} ->
466            %% This block is never reached. Discard it.
467            opt_bs(Bs, Ds0, Ls0, Fdb0, Sub0, SuccTypes0, Meta, Acc)
468    end;
469opt_bs([], _Ds, _Ls, Fdb, _Sub, SuccTypes, _Meta, Acc) ->
470    {reverse(Acc), Fdb, SuccTypes}.
471
472opt_is([#b_set{op=call,
473               args=[#b_local{}=Callee | _]=Args0,
474               dst=Dst}=I0 | Is],
475       Ts0, Ds0, Ls, Fdb0, Sub, Meta, Acc) ->
476    Args = simplify_args(Args0, Ts0, Sub),
477    I1 = beam_ssa:normalize(I0#b_set{args=Args}),
478
479    [_ | CallArgs] = Args,
480    {I, Fdb} = opt_local_call(I1, Callee, CallArgs, Dst, Ts0, Fdb0, Meta),
481
482    Ts = update_types(I, Ts0, Ds0),
483    Ds = Ds0#{ Dst => I },
484    opt_is(Is, Ts, Ds, Ls, Fdb, Sub, Meta, [I | Acc]);
485opt_is([#b_set{op=call,
486               args=[#b_var{} | _]=Args0,
487               dst=Dst}=I0 | Is],
488       Ts0, Ds0, Ls, Fdb, Sub, Meta, Acc) ->
489    Args = simplify_args(Args0, Ts0, Sub),
490    I1 = beam_ssa:normalize(I0#b_set{args=Args}),
491
492    [Fun | _] = Args,
493    I = case normalized_type(Fun, Ts0) of
494            #t_fun{type=Type} when Type =/= any ->
495                beam_ssa:add_anno(result_type, Type, I1);
496            _ ->
497                I1
498        end,
499
500    Ts = update_types(I, Ts0, Ds0),
501    Ds = Ds0#{ Dst => I },
502    opt_is(Is, Ts, Ds, Ls, Fdb, Sub, Meta, [I | Acc]);
503opt_is([#b_set{op=make_fun,args=Args0,dst=Dst}=I0|Is],
504       Ts0, Ds0, Ls, Fdb0, Sub0, Meta, Acc) ->
505    Args = simplify_args(Args0, Ts0, Sub0),
506    I1 = beam_ssa:normalize(I0#b_set{args=Args}),
507
508    {I, Fdb} = opt_make_fun(I1, Ts0, Fdb0, Meta),
509
510    Ts = update_types(I, Ts0, Ds0),
511    Ds = Ds0#{ Dst => I },
512    opt_is(Is, Ts, Ds, Ls, Fdb, Sub0, Meta, [I|Acc]);
513opt_is([I0 | Is], Ts0, Ds0, Ls, Fdb, Sub0, Meta, Acc) ->
514    case simplify(I0, Ts0, Ds0, Ls, Sub0) of
515        {#b_set{}=I, Ts, Ds} ->
516            opt_is(Is, Ts, Ds, Ls, Fdb, Sub0, Meta, [I | Acc]);
517        Sub when is_map(Sub) ->
518            opt_is(Is, Ts0, Ds0, Ls, Fdb, Sub, Meta, Acc)
519    end;
520opt_is([], Ts, Ds, _Ls, Fdb, Sub, _Meta, Acc) ->
521    {reverse(Acc), Ts, Ds, Fdb, Sub}.
522
523opt_local_call(I0, Callee, Args, Dst, Ts, Fdb, Meta) ->
524    ArgTypes = argument_types(Args, Ts),
525    I = opt_local_return(I0, Callee, ArgTypes, Fdb),
526    case Fdb of
527        #{ Callee := #func_info{exported=false,arg_types=AT0}=Info0 } ->
528            %% Update the argument types of *this exact call*, the types
529            %% will be joined later when the callee is optimized.
530            CallId = {Meta#metadata.func_id, Dst},
531
532            AT = update_arg_types(ArgTypes, AT0, CallId),
533            Info = Info0#func_info{arg_types=AT},
534
535            {I, Fdb#{ Callee := Info }};
536        #{} ->
537            %% We can't narrow the argument types of exported functions as they
538            %% can receive anything as part of an external call. We can still
539            %% rely on their return types however.
540            {I, Fdb}
541    end.
542
543%% See sig_make_fun/4
544opt_make_fun(#b_set{op=make_fun,
545                    dst=Dst,
546                    args=[#b_local{}=Callee | FreeVars]}=I0,
547             Ts, Fdb, Meta) ->
548    ArgCount = Callee#b_local.arity - length(FreeVars),
549    FVTypes = [raw_type(FreeVar, Ts) || FreeVar <- FreeVars],
550    ArgTypes = duplicate(ArgCount, any) ++ FVTypes,
551
552    I = opt_local_return(I0, Callee, ArgTypes, Fdb),
553
554    case Fdb of
555        #{ Callee := #func_info{exported=false,arg_types=AT0}=Info0 } ->
556            CallId = {Meta#metadata.func_id, Dst},
557
558            AT = update_arg_types(ArgTypes, AT0, CallId),
559            Info = Info0#func_info{arg_types=AT},
560
561            {I, Fdb#{ Callee := Info }};
562        #{} ->
563            %% We can't narrow the argument types of exported functions as they
564            %% can receive anything as part of an external call.
565            {I, Fdb}
566    end.
567
568opt_local_return(I, Callee, ArgTypes, Fdb) when Fdb =/= #{} ->
569    #func_info{succ_types=SuccTypes} = map_get(Callee, Fdb),
570    case return_type(SuccTypes, ArgTypes) of
571        any -> I;
572        Type -> beam_ssa:add_anno(result_type, Type, I)
573    end;
574opt_local_return(I, _Callee, _ArgTyps, _Fdb) ->
575    %% Module-level optimization is disabled, assume it returns anything.
576    I.
577
578update_arg_types([ArgType | ArgTypes], [TypeMap0 | TypeMaps], CallId) ->
579    TypeMap = TypeMap0#{ CallId => ArgType },
580    [TypeMap | update_arg_types(ArgTypes, TypeMaps, CallId)];
581update_arg_types([], [], _CallId) ->
582    [].
583
584%%
585
586-spec opt_finish(Args, Anno, FuncDb) -> {Anno, FuncDb} when
587      Args :: [beam_ssa:b_var()],
588      Anno :: beam_ssa:anno(),
589      FuncDb :: func_info_db().
590opt_finish(Args, Anno, FuncDb) ->
591    Id = get_func_id(Anno),
592    case FuncDb of
593        #{ Id := #func_info{exported=false,arg_types=ArgTypes} } ->
594            ParamInfo0 = maps:get(parameter_info, Anno, #{}),
595            ParamInfo = opt_finish_1(Args, ArgTypes, ParamInfo0),
596            {Anno#{ parameter_info => ParamInfo }, FuncDb};
597        #{} ->
598            {Anno, FuncDb}
599    end.
600
601opt_finish_1([Arg | Args], [TypeMap | TypeMaps], Acc0) ->
602    case beam_types:join(maps:values(TypeMap)) of
603        any ->
604            opt_finish_1(Args, TypeMaps, Acc0);
605        JoinedType ->
606            Info = maps:get(Arg, Acc0, []),
607            Acc = Acc0#{ Arg => [{type, JoinedType} | Info] },
608            opt_finish_1(Args, TypeMaps, Acc)
609    end;
610opt_finish_1([], [], Acc) ->
611    Acc.
612
613%%%
614%%% Optimization helpers
615%%%
616
617simplify_terminator(#b_br{bool=Bool}=Br0, Ts, Ds, Sub) ->
618    Br = beam_ssa:normalize(Br0#b_br{bool=simplify_arg(Bool, Ts, Sub)}),
619    simplify_not(Br, Ts, Ds, Sub);
620simplify_terminator(#b_switch{arg=Arg0,fail=Fail,list=List0}=Sw0,
621                    Ts, Ds, Sub) ->
622    Arg = simplify_arg(Arg0, Ts, Sub),
623    %% Ensure that no label in the switch list is the same as the
624    %% failure label.
625    List = [{Val,Lbl} || {Val,Lbl} <- List0, Lbl =/= Fail],
626    case beam_ssa:normalize(Sw0#b_switch{arg=Arg,list=List}) of
627        #b_switch{}=Sw ->
628            case beam_types:is_boolean_type(raw_type(Arg, Ts)) of
629                true -> simplify_switch_bool(Sw, Ts, Ds, Sub);
630                false -> Sw
631            end;
632        #b_br{}=Br ->
633            simplify_terminator(Br, Ts, Ds, Sub)
634    end;
635simplify_terminator(#b_ret{arg=Arg}=Ret, Ts, Ds, Sub) ->
636    %% Reducing the result of a call to a literal (fairly common for 'ok')
637    %% breaks tail call optimization.
638    case Ds of
639        #{ Arg := #b_set{op=call}} -> Ret;
640        #{} -> Ret#b_ret{arg=simplify_arg(Arg, Ts, Sub)}
641    end.
642
643%%
644%% Simplifies an instruction, returning either a new instruction (with updated
645%% type and definition maps), or an updated substitution map if the instruction
646%% was redundant.
647%%
648
649simplify(#b_set{op=phi,dst=Dst,args=Args0}=I0, Ts0, Ds0, Ls, Sub) ->
650    %% Simplify the phi node by removing all predecessor blocks that no
651    %% longer exists or no longer branches to this block.
652    {Type, Args} = simplify_phi_args(Args0, Ls, Sub, none, []),
653    case phi_all_same(Args) of
654        true ->
655            %% Eliminate the phi node if there is just one source
656            %% value or if the values are identical.
657            [{Val, _} | _] = Args,
658            Sub#{ Dst => Val };
659        false ->
660            I = I0#b_set{args=Args},
661
662            Ts = Ts0#{ Dst => Type },
663            Ds = Ds0#{ Dst => I },
664            {I, Ts, Ds}
665    end;
666simplify(#b_set{op={succeeded,Kind},args=[Arg],dst=Dst}=I0,
667         Ts0, Ds0, _Ls, Sub) ->
668    Type = case will_succeed(I0, Ts0, Ds0, Sub) of
669               yes -> beam_types:make_atom(true);
670               no -> beam_types:make_atom(false);
671               maybe -> beam_types:make_boolean()
672           end,
673    case Type of
674        #t_atom{elements=[true]} ->
675            %% The checked operation always succeeds, so it's safe to remove
676            %% this instruction regardless of whether we're in a guard or not.
677            Lit = #b_literal{val=true},
678            Sub#{ Dst => Lit };
679        #t_atom{elements=[false]} when Kind =:= guard ->
680            %% Failing operations are only safe to remove in guards.
681            Lit = #b_literal{val=false},
682            Sub#{ Dst => Lit };
683        _ ->
684            true = is_map_key(Arg, Ds0),        %Assertion.
685
686            %% Note that we never simplify args; this instruction is specific
687            %% to the operation being checked, and simplifying could break that
688            %% connection.
689            I = beam_ssa:normalize(I0),
690            Ts = Ts0#{ Dst => Type },
691            Ds = Ds0#{ Dst => I },
692            {I, Ts, Ds}
693    end;
694simplify(#b_set{op=bs_match,dst=Dst,args=Args0}=I0, Ts0, Ds0, _Ls, Sub) ->
695    Args = simplify_args(Args0, Ts0, Sub),
696    I1 = beam_ssa:normalize(I0#b_set{args=Args}),
697    I2 = case {Args0,Args} of
698             {[_,_,_,#b_var{},_],[Type,Val,Flags,#b_literal{val=all},Unit]} ->
699                 %% The size `all` is used for the size of the final binary
700                 %% segment in a pattern. Using `all` explicitly is not allowed,
701                 %% so we convert it to an obvious invalid size.
702                 I1#b_set{args=[Type,Val,Flags,#b_literal{val=bad_size},Unit]};
703             {_,_} ->
704                 I1
705         end,
706    %% We KNOW that simplify/2 will return a #b_set{} record when called with
707    %% a bs_match instruction.
708    #b_set{} = I3 = simplify(I2, Ts0),
709    I = beam_ssa:normalize(I3),
710    Ts = update_types(I, Ts0, Ds0),
711    Ds = Ds0#{ Dst => I },
712    {I, Ts, Ds};
713simplify(#b_set{dst=Dst,args=Args0}=I0, Ts0, Ds0, _Ls, Sub) ->
714    Args = simplify_args(Args0, Ts0, Sub),
715    I1 = beam_ssa:normalize(I0#b_set{args=Args}),
716    case simplify(I1, Ts0) of
717        #b_set{}=I2 ->
718            I = beam_ssa:normalize(I2),
719            Ts = update_types(I, Ts0, Ds0),
720            Ds = Ds0#{ Dst => I },
721            {I, Ts, Ds};
722        #b_literal{}=Lit ->
723            Sub#{ Dst => Lit };
724        #b_var{}=Var ->
725            Sub#{ Dst => Var }
726    end.
727
728simplify(#b_set{op={bif,'and'},args=Args}=I, Ts) ->
729    case is_safe_bool_op(Args, Ts) of
730        true ->
731            case Args of
732                [_,#b_literal{val=false}=Res] -> Res;
733                [Res,#b_literal{val=true}] -> Res;
734                _ -> eval_bif(I, Ts)
735            end;
736        false ->
737            I
738    end;
739simplify(#b_set{op={bif,'or'},args=Args}=I, Ts) ->
740    case is_safe_bool_op(Args, Ts) of
741        true ->
742            case Args of
743                [Res,#b_literal{val=false}] -> Res;
744                [_,#b_literal{val=true}=Res] -> Res;
745                _ -> eval_bif(I, Ts)
746            end;
747        false ->
748            I
749    end;
750simplify(#b_set{op={bif,element},args=[#b_literal{val=Index},Tuple]}=I0, Ts) ->
751    case normalized_type(Tuple, Ts) of
752        #t_tuple{size=Size} when is_integer(Index),
753                                 1 =< Index,
754                                 Index =< Size ->
755            I = I0#b_set{op=get_tuple_element,
756                         args=[Tuple,#b_literal{val=Index-1}]},
757            simplify(I, Ts);
758        _ ->
759            eval_bif(I0, Ts)
760    end;
761simplify(#b_set{op={bif,hd},args=[List]}=I, Ts) ->
762    case normalized_type(List, Ts) of
763        #t_cons{} ->
764            I#b_set{op=get_hd};
765        _ ->
766            eval_bif(I, Ts)
767    end;
768simplify(#b_set{op={bif,tl},args=[List]}=I, Ts) ->
769    case normalized_type(List, Ts) of
770        #t_cons{} ->
771            I#b_set{op=get_tl};
772        _ ->
773            eval_bif(I, Ts)
774    end;
775simplify(#b_set{op={bif,size},args=[Term]}=I, Ts) ->
776    case normalized_type(Term, Ts) of
777        #t_tuple{} ->
778            simplify(I#b_set{op={bif,tuple_size}}, Ts);
779        #t_bitstring{size_unit=U} when U rem 8 =:= 0 ->
780            %% If the bitstring is a binary (the size in bits is
781            %% evenly divisibly by 8), byte_size/1 gives
782            %% the same result as size/1.
783            simplify(I#b_set{op={bif,byte_size}}, Ts);
784        _ ->
785            eval_bif(I, Ts)
786    end;
787simplify(#b_set{op={bif,tuple_size},args=[Term]}=I, Ts) ->
788    case normalized_type(Term, Ts) of
789        #t_tuple{size=Size,exact=true} ->
790            #b_literal{val=Size};
791        _ ->
792            I
793    end;
794simplify(#b_set{op={bif,is_function},args=[Fun,#b_literal{val=Arity}]}=I, Ts)
795  when is_integer(Arity), Arity >= 0 ->
796    case normalized_type(Fun, Ts) of
797        #t_fun{arity=any} ->
798            I;
799        #t_fun{arity=Arity} ->
800            #b_literal{val=true};
801        any ->
802            I;
803        _ ->
804            #b_literal{val=false}
805    end;
806simplify(#b_set{op={bif,is_map_key},args=[Key,Map]}=I, Ts) ->
807    case normalized_type(Map, Ts) of
808        #t_map{} ->
809            I#b_set{op=has_map_field,args=[Map,Key]};
810        _ ->
811            I
812    end;
813simplify(#b_set{op={bif,Op0},args=Args}=I, Ts) when Op0 =:= '==';
814                                                    Op0 =:= '/=' ->
815    Types = normalized_types(Args, Ts),
816    EqEq0 = case {beam_types:meet(Types),beam_types:join(Types)} of
817                {none,any} -> true;
818                {#t_integer{},#t_integer{}} -> true;
819                {#t_float{},#t_float{}} -> true;
820                {#t_bitstring{},_} -> true;
821                {#t_atom{},_} -> true;
822                {_,_} -> false
823            end,
824    EqEq = EqEq0 orelse any_non_numeric_argument(Args, Ts),
825    case EqEq of
826        true ->
827            Op = case Op0 of
828                     '==' -> '=:=';
829                     '/=' -> '=/='
830                 end,
831            simplify(I#b_set{op={bif,Op}}, Ts);
832        false ->
833            eval_bif(I, Ts)
834    end;
835simplify(#b_set{op={bif,'=:='},args=[Same,Same]}, _Ts) ->
836    #b_literal{val=true};
837simplify(#b_set{op={bif,'=:='},args=[LHS,RHS]}=I, Ts) ->
838    LType = raw_type(LHS, Ts),
839    RType = raw_type(RHS, Ts),
840    case beam_types:meet(LType, RType) of
841        none ->
842            #b_literal{val=false};
843        _ ->
844            case {beam_types:is_boolean_type(LType),
845                  beam_types:normalize(RType)} of
846                {true,#t_atom{elements=[true]}} ->
847                    %% Bool =:= true  ==>  Bool
848                    LHS;
849                {true,#t_atom{elements=[false]}} ->
850                    %% Bool =:= false ==> not Bool
851                    %%
852                    %% This will be further optimized to eliminate the
853                    %% 'not', swapping the success and failure
854                    %% branches in the br instruction. If LHS comes
855                    %% from a type test (such as is_atom/1) or a
856                    %% comparison operator (such as >=) that can be
857                    %% translated to test instruction, this
858                    %% optimization will eliminate one instruction.
859                    simplify(I#b_set{op={bif,'not'},args=[LHS]}, Ts);
860                {_,_} ->
861                    eval_bif(I, Ts)
862            end
863    end;
864simplify(#b_set{op={bif,Op},args=Args}=I, Ts) ->
865    Types = normalized_types(Args, Ts),
866    case is_float_op(Op, Types) of
867        false ->
868            eval_bif(I, Ts);
869        true ->
870            AnnoArgs = [anno_float_arg(A) || A <- Types],
871            eval_bif(beam_ssa:add_anno(float_op, AnnoArgs, I), Ts)
872    end;
873simplify(#b_set{op=bs_extract,args=[Ctx]}=I, Ts) ->
874    case raw_type(Ctx, Ts) of
875        #t_bitstring{} ->
876            %% This is a bs_match that has been rewritten as a bs_get_tail;
877            %% just return the input as-is.
878            Ctx;
879        #t_bs_context{} ->
880            I
881    end;
882simplify(#b_set{op=bs_match,
883                args=[#b_literal{val=binary}, Ctx, _Flags,
884                      #b_literal{val=all},
885                      #b_literal{val=OpUnit}]}=I, Ts) ->
886    %% <<..., Foo/binary>> can be rewritten as <<..., Foo/bits>> if we know the
887    %% unit is correct.
888    #t_bs_context{tail_unit=CtxUnit} = raw_type(Ctx, Ts),
889    if
890        CtxUnit rem OpUnit =:= 0 ->
891            I#b_set{op=bs_get_tail,args=[Ctx]};
892        CtxUnit rem OpUnit =/= 0 ->
893            I
894    end;
895simplify(#b_set{op=bs_start_match,args=[#b_literal{val=new}, Src]}=I, Ts) ->
896    case raw_type(Src, Ts) of
897        #t_bs_context{} ->
898            I#b_set{op=bs_start_match,args=[#b_literal{val=resume}, Src]};
899        _ ->
900            I
901    end;
902simplify(#b_set{op=get_tuple_element,args=[Tuple,#b_literal{val=N}]}=I, Ts) ->
903    #t_tuple{size=Size,elements=Es} = normalized_type(Tuple, Ts),
904    true = Size > N,                            %Assertion.
905    ElemType = beam_types:get_tuple_element(N + 1, Es),
906    case beam_types:get_singleton_value(ElemType) of
907        {ok, Val} -> #b_literal{val=Val};
908        error -> I
909    end;
910simplify(#b_set{op=is_nonempty_list,args=[Src]}=I, Ts) ->
911    case normalized_type(Src, Ts) of
912        any ->
913            I;
914        #t_list{} ->
915            I;
916        #t_cons{} ->
917            #b_literal{val=true};
918        _ ->
919            #b_literal{val=false}
920    end;
921simplify(#b_set{op=is_tagged_tuple,
922                args=[Src,#b_literal{val=Size},#b_literal{}=Tag]}=I, Ts) ->
923    simplify_is_record(I, normalized_type(Src, Ts), Size, Tag, Ts);
924simplify(#b_set{op=put_list,args=[#b_literal{val=H},
925                                  #b_literal{val=T}]}, _Ts) ->
926    #b_literal{val=[H|T]};
927simplify(#b_set{op=put_tuple,args=Args}=I, _Ts) ->
928    case make_literal_list(Args) of
929        none -> I;
930        List -> #b_literal{val=list_to_tuple(List)}
931    end;
932simplify(#b_set{op=wait_timeout,args=[#b_literal{val=0}]}, _Ts) ->
933    #b_literal{val=true};
934simplify(#b_set{op=call,args=[#b_remote{}=Rem|Args]}=I, _Ts) ->
935    case Rem of
936        #b_remote{mod=#b_literal{val=Mod},
937                  name=#b_literal{val=Name}} ->
938            case erl_bifs:is_pure(Mod, Name, length(Args)) of
939                true ->
940                    simplify_remote_call(Mod, Name, Args, I);
941                false ->
942                    I
943            end;
944        #b_remote{} ->
945            I
946    end;
947simplify(#b_set{op=call,args=[#b_literal{val=Fun}|Args]}=I, _Ts)
948  when is_function(Fun, length(Args)) ->
949    FI = erlang:fun_info(Fun),
950    {module,M} = keyfind(module, 1, FI),
951    {name,F} = keyfind(name, 1, FI),
952    {arity,A} = keyfind(arity, 1, FI),
953    Rem = #b_remote{mod=#b_literal{val=M},
954                    name=#b_literal{val=F},
955                    arity=A},
956    I#b_set{args=[Rem|Args]};
957simplify(I, _Ts) -> I.
958
959will_succeed(#b_set{args=[Src]}, Ts, Ds, Sub) ->
960    case {Ds, Ts} of
961        {#{}, #{ Src := none }} ->
962            %% Checked operation never returns.
963            no;
964        {#{ Src := I }, #{}} ->
965            will_succeed_1(I, Src, Ts, Sub);
966        {#{}, #{}} ->
967            %% The checked instruction has been removed and substituted, so we
968            %% can assume it always succeeds.
969            true = is_map_key(Src, Sub),        %Assertion.
970            yes
971    end.
972
973will_succeed_1(#b_set{op=bs_get_tail}, _Src, _Ts, _Sub) ->
974    yes;
975will_succeed_1(#b_set{op=bs_start_match,args=[_, Arg]}, _Src, Ts, _Sub) ->
976    ArgType = raw_type(Arg, Ts),
977    case beam_types:is_bs_matchable_type(ArgType) of
978        true ->
979            %% In the future we may be able to remove this instruction
980            %% altogether when we have a #t_bs_context{}, but for now we need
981            %% to keep it for compatibility with older releases of OTP.
982            yes;
983        false ->
984            %% Is it at all possible to match?
985            case beam_types:meet(ArgType, #t_bs_matchable{}) of
986                none -> no;
987                _ -> maybe
988            end
989    end;
990
991will_succeed_1(#b_set{op={bif,Bif},args=BifArgs}, _Src, Ts, _Sub) ->
992    ArgTypes = normalized_types(BifArgs, Ts),
993    beam_call_types:will_succeed(erlang, Bif, ArgTypes);
994will_succeed_1(#b_set{op=call,
995                      args=[#b_remote{mod=#b_literal{val=Mod},
996                            name=#b_literal{val=Func}} |
997                            CallArgs]},
998               _Src, Ts, _Sub) ->
999            ArgTypes = normalized_types(CallArgs, Ts),
1000            beam_call_types:will_succeed(Mod, Func, ArgTypes);
1001
1002will_succeed_1(#b_set{op=get_hd}, _Src, _Ts, _Sub) ->
1003    yes;
1004will_succeed_1(#b_set{op=get_tl}, _Src, _Ts, _Sub) ->
1005    yes;
1006will_succeed_1(#b_set{op=has_map_field}, _Src, _Ts, _Sub) ->
1007    yes;
1008will_succeed_1(#b_set{op=get_tuple_element}, _Src, _Ts, _Sub) ->
1009    yes;
1010will_succeed_1(#b_set{op=put_tuple}, _Src, _Ts, _Sub) ->
1011    yes;
1012
1013%% Remove the success branch from binary operations with invalid
1014%% sizes. That will remove subsequent bs_put and bs_match instructions,
1015%% which are probably not loadable.
1016will_succeed_1(#b_set{op=bs_add,args=[Arg1,Arg2,_]},
1017               _Src, _Ts, _Sub) ->
1018    case all(fun(#b_literal{val=Size}) -> is_integer(Size) andalso Size >= 0;
1019                (#b_var{}) -> true
1020             end, [Arg1,Arg2]) of
1021        true -> maybe;
1022        false -> no
1023    end;
1024will_succeed_1(#b_set{op=bs_init,
1025                      args=[#b_literal{val=new},#b_literal{val=Size},_Unit]},
1026               _Src, _Ts, _Sub) ->
1027    if
1028        is_integer(Size), Size >= 0 ->
1029            maybe;
1030        true ->
1031            no
1032    end;
1033will_succeed_1(#b_set{op=bs_init,
1034                      args=[#b_literal{},_,#b_literal{val=Size},_Unit]},
1035               _Src, _Ts, _Sub) ->
1036    if
1037        is_integer(Size), Size >= 0 ->
1038            maybe;
1039        true ->
1040            no
1041    end;
1042will_succeed_1(#b_set{op=bs_match,
1043                      args=[#b_literal{val=Type},_,_,#b_literal{val=Size},_]},
1044               _Src, _Ts, _Sub) ->
1045    if
1046        is_integer(Size), Size >= 0 ->
1047            maybe;
1048        Type =:= binary, Size =:= all ->
1049            %% `all` is a legal size for binary segments at the end of
1050            %% a binary pattern.
1051            maybe;
1052        true ->
1053            %% Invalid size. Matching will fail.
1054            no
1055    end;
1056
1057%% These operations may fail even though we know their return value on success.
1058will_succeed_1(#b_set{op=call}, _Src, _Ts, _Sub) ->
1059    maybe;
1060will_succeed_1(#b_set{op=get_map_element}, _Src, _Ts, _Sub) ->
1061    maybe;
1062
1063will_succeed_1(#b_set{op=wait}, _Src, _Ts, _Sub) ->
1064    no;
1065
1066will_succeed_1(#b_set{}, Src, Ts, Sub) ->
1067    case simplify_arg(Src, Ts, Sub) of
1068        #b_var{}=Src ->
1069            %% No substitution; might fail at runtime.
1070            maybe;
1071        _ ->
1072            %% Substituted with literal or other variable; always succeeds.
1073            yes
1074    end.
1075
1076simplify_is_record(I, #t_tuple{exact=Exact,
1077                               size=Size,
1078                               elements=Es},
1079                   RecSize, #b_literal{val=TagVal}=RecTag, Ts) ->
1080    TagType = maps:get(1, Es, any),
1081    TagMatch = case beam_types:get_singleton_value(TagType) of
1082                   {ok, TagVal} -> yes;
1083                   {ok, _} -> no;
1084                   error ->
1085                       %% Is it at all possible for the tag to match?
1086                       case beam_types:meet(raw_type(RecTag, Ts), TagType) of
1087                           none -> no;
1088                           _ -> maybe
1089                       end
1090               end,
1091    if
1092        Size =/= RecSize, Exact; Size > RecSize; TagMatch =:= no ->
1093            #b_literal{val=false};
1094        Size =:= RecSize, Exact, TagMatch =:= yes ->
1095            #b_literal{val=true};
1096        true ->
1097            I
1098    end;
1099simplify_is_record(I, any, _Size, _Tag, _Ts) ->
1100    I;
1101simplify_is_record(_I, _Type, _Size, _Tag, _Ts) ->
1102    #b_literal{val=false}.
1103
1104simplify_switch_bool(#b_switch{arg=B,fail=Fail,list=List0}, Ts, Ds, Sub) ->
1105    FalseVal = #b_literal{val=false},
1106    TrueVal = #b_literal{val=true},
1107    List1 = List0 ++ [{FalseVal,Fail},{TrueVal,Fail}],
1108    {_,FalseLbl} = keyfind(FalseVal, 1, List1),
1109    {_,TrueLbl} = keyfind(TrueVal, 1, List1),
1110    Br = #b_br{bool=B,succ=TrueLbl,fail=FalseLbl},
1111    simplify_terminator(Br, Ts, Ds, Sub).
1112
1113simplify_not(#b_br{bool=#b_var{}=V,succ=Succ,fail=Fail}=Br0, Ts, Ds, Sub) ->
1114    case Ds of
1115        #{V:=#b_set{op={bif,'not'},args=[Bool]}} ->
1116            case beam_types:is_boolean_type(raw_type(Bool, Ts)) of
1117                true ->
1118                    Br = Br0#b_br{bool=Bool,succ=Fail,fail=Succ},
1119                    simplify_terminator(Br, Ts, Ds, Sub);
1120                false ->
1121                    Br0
1122            end;
1123        #{} ->
1124            Br0
1125    end;
1126simplify_not(#b_br{bool=#b_literal{}}=Br, _Sub, _Ts, _Ds) ->
1127    Br.
1128
1129simplify_phi_args([{Arg0, From} | Rest], Ls, Sub, Type0, Args) ->
1130    case Ls of
1131        #{ From := Outgoing } ->
1132            {outgoing, Ts} = Outgoing,          %Assertion.
1133
1134            Arg = simplify_arg(Arg0, Ts, Sub),
1135            Type = beam_types:join(raw_type(Arg, Ts), Type0),
1136            Phi = {Arg, From},
1137
1138            simplify_phi_args(Rest, Ls, Sub, Type, [Phi | Args]);
1139        #{} ->
1140            simplify_phi_args(Rest, Ls, Sub, Type0, Args)
1141    end;
1142simplify_phi_args([], _Ls, _Sub, Type, Args) ->
1143    %% We return the arguments in their incoming order so that they won't
1144    %% change back and forth and ruin fixpoint iteration in beam_ssa_opt.
1145    {Type, reverse(Args)}.
1146
1147phi_all_same([{Arg, _From} | Phis]) ->
1148    phi_all_same_1(Phis, Arg).
1149
1150phi_all_same_1([{Arg, _From} | Phis], Arg) ->
1151    phi_all_same_1(Phis, Arg);
1152phi_all_same_1([], _Arg) ->
1153    true;
1154phi_all_same_1(_Phis, _Arg) ->
1155    false.
1156
1157%% Simplify a remote call to a pure BIF.
1158simplify_remote_call(erlang, '++', [#b_literal{val=[]},Tl], _I) ->
1159    Tl;
1160simplify_remote_call(erlang, setelement,
1161                     [#b_literal{val=Pos},
1162                      #b_literal{val=Tuple},
1163                      #b_var{}=Value], I)
1164  when is_integer(Pos), 1 =< Pos, Pos =< tuple_size(Tuple) ->
1165    %% Position is a literal integer and the shape of the
1166    %% tuple is known.
1167    Els0 = [#b_literal{val=El} || El <- tuple_to_list(Tuple)],
1168    {Bef,[_|Aft]} = split(Pos - 1, Els0),
1169    Els = Bef ++ [Value|Aft],
1170    I#b_set{op=put_tuple,args=Els};
1171simplify_remote_call(Mod, Name, Args0, I) ->
1172    case make_literal_list(Args0) of
1173        none ->
1174            I;
1175        Args ->
1176            %% The arguments are literals. Try to evaluate the BIF.
1177            try apply(Mod, Name, Args) of
1178                Val ->
1179                    case cerl:is_literal_term(Val) of
1180                        true ->
1181                            #b_literal{val=Val};
1182                        false ->
1183                            %% The value can't be expressed as a literal
1184                            %% (e.g. a pid).
1185                            I
1186                    end
1187            catch
1188                _:_ ->
1189                    %% Failed. Don't bother trying to optimize
1190                    %% the call.
1191                    I
1192            end
1193    end.
1194
1195any_non_numeric_argument([#b_literal{val=Lit}|_], _Ts) ->
1196    is_non_numeric(Lit);
1197any_non_numeric_argument([#b_var{}=V|T], Ts) ->
1198    is_non_numeric_type(raw_type(V, Ts)) orelse any_non_numeric_argument(T, Ts);
1199any_non_numeric_argument([], _Ts) -> false.
1200
1201is_non_numeric([H|T]) ->
1202    is_non_numeric(H) andalso is_non_numeric(T);
1203is_non_numeric(Tuple) when is_tuple(Tuple) ->
1204    is_non_numeric_tuple(Tuple, tuple_size(Tuple));
1205is_non_numeric(Map) when is_map(Map) ->
1206    %% Starting from OTP 18, map keys are compared using `=:=`.
1207    %% Therefore, we only need to check that the values in the map are
1208    %% non-numeric. (Support for compiling BEAM files for OTP releases
1209    %% older than OTP 18 has been dropped.)
1210    is_non_numeric(maps:values(Map));
1211is_non_numeric(Num) when is_number(Num) ->
1212    false;
1213is_non_numeric(_) -> true.
1214
1215is_non_numeric_tuple(Tuple, El) when El >= 1 ->
1216    is_non_numeric(element(El, Tuple)) andalso
1217        is_non_numeric_tuple(Tuple, El-1);
1218is_non_numeric_tuple(_Tuple, 0) -> true.
1219
1220is_non_numeric_type(#t_atom{}) -> true;
1221is_non_numeric_type(#t_bitstring{}) -> true;
1222is_non_numeric_type(#t_cons{type=Type,terminator=Terminator}) ->
1223    is_non_numeric_type(Type) andalso is_non_numeric_type(Terminator);
1224is_non_numeric_type(#t_list{type=Type,terminator=Terminator}) ->
1225    is_non_numeric_type(Type) andalso is_non_numeric_type(Terminator);
1226is_non_numeric_type(#t_map{super_value=Value}) ->
1227    is_non_numeric_type(Value);
1228is_non_numeric_type(nil) -> true;
1229is_non_numeric_type(#t_tuple{size=Size,exact=true,elements=Types})
1230  when map_size(Types) =:= Size ->
1231    is_non_numeric_tuple_type(Size, Types);
1232is_non_numeric_type(_) -> false.
1233
1234is_non_numeric_tuple_type(0, _Types) ->
1235    true;
1236is_non_numeric_tuple_type(Pos, Types) ->
1237    is_non_numeric_type(map_get(Pos, Types)) andalso
1238        is_non_numeric_tuple_type(Pos - 1, Types).
1239
1240make_literal_list(Args) ->
1241    make_literal_list(Args, []).
1242
1243make_literal_list([#b_literal{val=H}|T], Acc) ->
1244    make_literal_list(T, [H|Acc]);
1245make_literal_list([_|_], _) ->
1246    none;
1247make_literal_list([], Acc) ->
1248    reverse(Acc).
1249
1250is_safe_bool_op([LHS, RHS], Ts) ->
1251    LType = raw_type(LHS, Ts),
1252    RType = raw_type(RHS, Ts),
1253    beam_types:is_boolean_type(LType) andalso
1254        beam_types:is_boolean_type(RType).
1255
1256eval_bif(#b_set{op={bif,Bif},args=Args}=I, Ts) ->
1257    Arity = length(Args),
1258    case erl_bifs:is_pure(erlang, Bif, Arity) of
1259        false ->
1260            I;
1261        true ->
1262            case make_literal_list(Args) of
1263                none ->
1264                    eval_type_test_bif(I, Bif, raw_types(Args, Ts));
1265                LitArgs ->
1266                    try apply(erlang, Bif, LitArgs) of
1267                        Val -> #b_literal{val=Val}
1268                    catch
1269                        error:_ -> I
1270                    end
1271
1272            end
1273    end.
1274
1275eval_type_test_bif(I, is_atom, [Type]) ->
1276    eval_type_test_bif_1(I, Type, #t_atom{});
1277eval_type_test_bif(I, is_binary, [Type]) ->
1278    eval_type_test_bif_1(I, Type, #t_bs_matchable{tail_unit=8});
1279eval_type_test_bif(I, is_bitstring, [Type]) ->
1280    eval_type_test_bif_1(I, Type, #t_bs_matchable{});
1281eval_type_test_bif(I, is_boolean, [Type]) ->
1282    case beam_types:is_boolean_type(Type) of
1283        true ->
1284            #b_literal{val=true};
1285        false ->
1286            case beam_types:meet(Type, #t_atom{}) of
1287                #t_atom{elements=[_|_]=Es} ->
1288                    case any(fun is_boolean/1, Es) of
1289                        true -> I;
1290                        false -> #b_literal{val=false}
1291                    end;
1292                #t_atom{} ->
1293                    I;
1294                none ->
1295                    #b_literal{val=false}
1296            end
1297    end;
1298eval_type_test_bif(I, is_float, [Type]) ->
1299    eval_type_test_bif_1(I, Type, #t_float{});
1300eval_type_test_bif(I, is_function, [Type]) ->
1301    eval_type_test_bif_1(I, Type, #t_fun{});
1302eval_type_test_bif(I, is_integer, [Type]) ->
1303    eval_type_test_bif_1(I, Type, #t_integer{});
1304eval_type_test_bif(I, is_list, [Type]) ->
1305    eval_type_test_bif_1(I, Type, #t_list{});
1306eval_type_test_bif(I, is_map, [Type]) ->
1307    eval_type_test_bif_1(I, Type, #t_map{});
1308eval_type_test_bif(I, is_number, [Type]) ->
1309    eval_type_test_bif_1(I, Type, number);
1310eval_type_test_bif(I, is_tuple, [Type]) ->
1311    eval_type_test_bif_1(I, Type, #t_tuple{});
1312eval_type_test_bif(I, Op, Types) ->
1313    case Types of
1314        [#t_integer{},#t_integer{elements={0,0}}]
1315          when Op =:= '+'; Op =:= '-'; Op =:= 'bor'; Op =:= 'bxor' ->
1316            #b_set{args=[Result,_]} = I,
1317            Result;
1318        [#t_integer{},#t_integer{elements={0,0}}] when Op =:= '*'; Op =:= 'band' ->
1319            #b_literal{val=0};
1320        [#t_integer{},#t_integer{elements={1,1}}] when Op =:= '*'; Op =:= 'div' ->
1321            #b_set{args=[Result,_]} = I,
1322            Result;
1323        [#t_integer{elements={LMin,LMax}},#t_integer{elements={RMin,RMax}}] ->
1324            case is_inequality_op(Op) of
1325                true ->
1326                    case {erlang:Op(LMin, RMin),erlang:Op(LMax, RMin),
1327                          erlang:Op(LMin, RMax),erlang:Op(LMax, RMax)} of
1328                        {Bool,Bool,Bool,Bool} ->
1329                            #b_literal{val=Bool};
1330                        _ ->
1331                            I
1332                    end;
1333                false ->
1334                    I
1335            end;
1336        _ ->
1337            I
1338    end.
1339
1340is_inequality_op('<') -> true;
1341is_inequality_op('=<') -> true;
1342is_inequality_op('>') -> true;
1343is_inequality_op('>=') -> true;
1344is_inequality_op(_) -> false.
1345
1346eval_type_test_bif_1(I, ArgType, Required) ->
1347    case beam_types:meet(ArgType, Required) of
1348        ArgType -> #b_literal{val=true};
1349        none -> #b_literal{val=false};
1350        _ -> I
1351    end.
1352
1353simplify_args(Args, Ts, Sub) ->
1354    [simplify_arg(Arg, Ts, Sub) || Arg <- Args].
1355
1356simplify_arg(#b_var{}=Arg0, Ts, Sub) ->
1357    case sub_arg(Arg0, Sub) of
1358        #b_literal{}=LitArg ->
1359            LitArg;
1360        #b_var{}=Arg ->
1361            case beam_types:get_singleton_value(raw_type(Arg, Ts)) of
1362                {ok, Val} -> #b_literal{val=Val};
1363                error -> Arg
1364            end
1365    end;
1366simplify_arg(#b_remote{mod=Mod,name=Name}=Rem, Ts, Sub) ->
1367    Rem#b_remote{mod=simplify_arg(Mod, Ts, Sub),
1368                 name=simplify_arg(Name, Ts, Sub)};
1369simplify_arg(Arg, _Ts, _Sub) -> Arg.
1370
1371sub_arg(#b_var{}=Old, Sub) ->
1372    case Sub of
1373        #{Old:=New} -> New;
1374        #{} -> Old
1375    end.
1376
1377is_float_op('-', [#t_float{}]) ->
1378    true;
1379is_float_op('/', [_,_]) ->
1380    true;
1381is_float_op(Op, [#t_float{},_Other]) ->
1382    is_float_op_1(Op);
1383is_float_op(Op, [_Other,#t_float{}]) ->
1384    is_float_op_1(Op);
1385is_float_op(_, _) -> false.
1386
1387is_float_op_1('+') -> true;
1388is_float_op_1('-') -> true;
1389is_float_op_1('*') -> true;
1390is_float_op_1(_) -> false.
1391
1392anno_float_arg(#t_float{}) -> float;
1393anno_float_arg(_) -> convert.
1394
1395%%%
1396%%% Type helpers
1397%%%
1398
1399%% Returns the narrowest possible return type for the given success types and
1400%% arguments.
1401return_type(SuccTypes0, CallArgs0) ->
1402    SuccTypes = st_filter_reachable(SuccTypes0, CallArgs0, [], []),
1403    st_join_return_types(SuccTypes, none).
1404
1405st_filter_reachable([{SuccArgs, {call_self, SelfArgs}}=SuccType | Rest],
1406                    CallArgs0, Deferred, Acc) ->
1407    case st_is_reachable(SuccArgs, CallArgs0) of
1408        true ->
1409            %% If we return a call to ourselves, we need to join our current
1410            %% argument types with that of the call to ensure all possible
1411            %% return paths are covered.
1412            CallArgs = parallel_join(SelfArgs, CallArgs0),
1413            st_filter_reachable(Rest, CallArgs, Deferred, Acc);
1414        false ->
1415            %% This may be reachable after we've joined another self-call, so
1416            %% we defer it until we've gone through all other self-calls.
1417            st_filter_reachable(Rest, CallArgs0, [SuccType | Deferred], Acc)
1418    end;
1419st_filter_reachable([SuccType | Rest], CallArgs, Deferred, Acc) ->
1420    st_filter_reachable(Rest, CallArgs, Deferred, [SuccType | Acc]);
1421st_filter_reachable([], CallArgs, Deferred, Acc) ->
1422    case st_any_reachable(Deferred, CallArgs) of
1423        true ->
1424            %% Handle all deferred self calls that may be reachable now that
1425            %% we've expanded our argument types.
1426            st_filter_reachable(Deferred, CallArgs, [], Acc);
1427        false ->
1428            %% We have no reachable self calls, so we know our argument types
1429            %% can't expand any further. Filter out our reachable sites and
1430            %% return.
1431            [ST || {SuccArgs, _}=ST <- Acc, st_is_reachable(SuccArgs, CallArgs)]
1432    end.
1433
1434st_join_return_types([{_SuccArgs, SuccRet} | Rest], Acc0) ->
1435    st_join_return_types(Rest, beam_types:join(SuccRet, Acc0));
1436st_join_return_types([], Acc) ->
1437    Acc.
1438
1439st_any_reachable([{SuccArgs, _} | SuccType], CallArgs) ->
1440    case st_is_reachable(SuccArgs, CallArgs) of
1441        true -> true;
1442        false -> st_any_reachable(SuccType, CallArgs)
1443    end;
1444st_any_reachable([], _CallArgs) ->
1445    false.
1446
1447st_is_reachable([A | SuccArgs], [B | CallArgs]) ->
1448    case beam_types:meet(A, B) of
1449        none -> false;
1450        _Other -> st_is_reachable(SuccArgs, CallArgs)
1451    end;
1452st_is_reachable([], []) ->
1453    true.
1454
1455update_success_types(#b_ret{arg=Arg}, Ts, Ds, Meta, SuccTypes) ->
1456    #metadata{ func_id=FuncId,
1457               limit_return=Limited,
1458               params=Params } = Meta,
1459
1460    RetType = case Ds of
1461                  #{ Arg := #b_set{op=call,args=[FuncId | Args]} } ->
1462                      {call_self, argument_types(Args, Ts)};
1463                  #{} ->
1464                      argument_type(Arg, Ts)
1465              end,
1466    ArgTypes = argument_types(Params, Ts),
1467
1468    case Limited of
1469        true -> ust_limited(SuccTypes, ArgTypes, RetType);
1470        false -> ust_unlimited(SuccTypes, ArgTypes, RetType)
1471    end;
1472update_success_types(_Last, _Ts, _Ds, _Meta, SuccTypes) ->
1473    SuccTypes.
1474
1475%% See ?RETURN_LIMIT for details.
1476ust_limited(SuccTypes, CallArgs, {call_self, SelfArgs}) ->
1477    NewArgs = parallel_join(CallArgs, SelfArgs),
1478    ust_limited_1(SuccTypes, NewArgs, none);
1479ust_limited(SuccTypes, CallArgs, CallRet) ->
1480    ust_limited_1(SuccTypes, CallArgs, CallRet).
1481
1482ust_limited_1([], ArgTypes, RetType) ->
1483    [{ArgTypes, RetType}];
1484ust_limited_1([{SuccArgs, SuccRet}], CallArgs, CallRet) ->
1485    NewTypes = parallel_join(SuccArgs, CallArgs),
1486    NewType = beam_types:join(SuccRet, CallRet),
1487    [{NewTypes, NewType}].
1488
1489%% Adds a new success type. Note that we no longer try to keep the list short
1490%% by combining entries with the same return type, as that can make effective
1491%% return types less specific as analysis goes on, which may cause endless
1492%% loops or render previous optimizations unsafe.
1493%%
1494%% See beam_type_SUITE:success_type_oscillation/1 for more details.
1495ust_unlimited(SuccTypes, _CallArgs, none) ->
1496    %% 'none' is implied since functions can always fail.
1497    SuccTypes;
1498ust_unlimited([{SameArgs, SameType} | _]=SuccTypes, SameArgs, SameType) ->
1499    %% Already covered, return as-is.
1500    SuccTypes;
1501ust_unlimited([SuccType | SuccTypes], CallArgs, CallRet) ->
1502    [SuccType | ust_unlimited(SuccTypes, CallArgs, CallRet)];
1503ust_unlimited([], CallArgs, CallRet) ->
1504    [{CallArgs, CallRet}].
1505
1506update_successors(#b_br{bool=#b_literal{val=true},succ=Succ}=Last,
1507                  Ts, _Ds, Ls, _UsedOnce) ->
1508    {Last, update_successor(Succ, Ts, Ls)};
1509update_successors(#b_br{bool=#b_var{}=Bool,succ=Succ,fail=Fail}=Last0,
1510                  Ts, Ds, Ls0, UsedOnce) ->
1511    IsTempVar = cerl_sets:is_element(Bool, UsedOnce),
1512    case infer_types_br(Bool, Ts, IsTempVar, Ds) of
1513        {#{}=SuccTs, #{}=FailTs} ->
1514            Ls1 = update_successor(Succ, SuccTs, Ls0),
1515            Ls = update_successor(Fail, FailTs, Ls1),
1516            {Last0, Ls};
1517        {#{}=SuccTs, none} ->
1518            Last = Last0#b_br{bool=#b_literal{val=true},fail=Succ},
1519            {Last, update_successor(Succ, SuccTs, Ls0)};
1520        {none, #{}=FailTs} ->
1521            Last = Last0#b_br{bool=#b_literal{val=true},succ=Fail},
1522            {Last, update_successor(Fail, FailTs, Ls0)}
1523    end;
1524update_successors(#b_switch{arg=#b_var{}=V,fail=Fail0,list=List0}=Last0,
1525                  Ts, Ds, Ls0, UsedOnce) ->
1526    IsTempVar = cerl_sets:is_element(V, UsedOnce),
1527
1528    {List1, FailTs, Ls1} =
1529        update_switch(List0, V, raw_type(V, Ts), Ts, Ds, Ls0, IsTempVar, []),
1530
1531    case FailTs of
1532        none ->
1533            %% The fail block is unreachable; swap it with one of the choices.
1534            case List1 of
1535                [{#b_literal{val=0},_}|_] ->
1536                    %% Swap with the last choice in order to keep the zero the
1537                    %% first choice. If the loader can substitute a jump table
1538                    %% instruction, then a shorter version of the jump table
1539                    %% instruction can be used if the first value is zero.
1540                    {List, [{_,Fail}]} = split(length(List1)-1, List1),
1541                    Last = Last0#b_switch{fail=Fail,list=List},
1542                    {Last, Ls1};
1543                [{_,Fail}|List] ->
1544                    %% Swap with the first choice in the list.
1545                    Last = Last0#b_switch{fail=Fail,list=List},
1546                    {Last, Ls1}
1547            end;
1548        #{} ->
1549            Ls = update_successor(Fail0, FailTs, Ls1),
1550            Last = Last0#b_switch{list=List1},
1551            {Last, Ls}
1552    end;
1553update_successors(#b_ret{}=Last, _Ts, _Ds, Ls, _UsedOnce) ->
1554    {Last, Ls}.
1555
1556update_switch([{Val, Lbl}=Sw | List],
1557              V, FailType0, Ts, Ds, Ls0, IsTempVar, Acc) ->
1558    FailType = beam_types:subtract(FailType0, raw_type(Val, Ts)),
1559    case infer_types_switch(V, Val, Ts, IsTempVar, Ds) of
1560        none ->
1561            update_switch(List, V, FailType, Ts, Ds, Ls0, IsTempVar, Acc);
1562        SwTs ->
1563            Ls = update_successor(Lbl, SwTs, Ls0),
1564            update_switch(List, V, FailType, Ts, Ds, Ls, IsTempVar, [Sw | Acc])
1565    end;
1566update_switch([], _V, none, _Ts, _Ds, Ls, _IsTempVar, Acc) ->
1567    %% Fail label is unreachable.
1568    {reverse(Acc), none, Ls};
1569update_switch([], V, FailType, Ts, Ds, Ls, IsTempVar, Acc) ->
1570    %% Fail label is reachable, see if we can narrow the type down further.
1571    FailTs = case beam_types:get_singleton_value(FailType) of
1572                 {ok, Value} ->
1573                     %% This is the only possible value at the fail label, so
1574                     %% we can infer types as if we matched it directly.
1575                     Lit = #b_literal{val=Value},
1576                     infer_types_switch(V, Lit, Ts, IsTempVar, Ds);
1577                 error when IsTempVar ->
1578                     ts_remove_var(V, Ts);
1579                 error ->
1580                     Ts#{ V := FailType }
1581             end,
1582    {reverse(Acc), FailTs, Ls}.
1583
1584update_successor(?EXCEPTION_BLOCK, _Ts, Ls) ->
1585    %% We KNOW that no variables are used in the ?EXCEPTION_BLOCK,
1586    %% so there is no need to update the type information. That
1587    %% can be a huge timesaver for huge functions.
1588    Ls;
1589update_successor(S, Ts0, Ls) ->
1590    case Ls of
1591        #{ S := {outgoing, _} } ->
1592            %% We're in a receive loop or similar; the target block will not be
1593            %% revisited.
1594            Ls;
1595        #{ S := {incoming, InTs} } ->
1596            Ts = join_types(Ts0, InTs),
1597            Ls#{ S := {incoming, Ts} };
1598        #{} ->
1599            Ls#{ S => {incoming, Ts0} }
1600    end.
1601
1602update_types(#b_set{op=Op,dst=Dst,anno=Anno,args=Args}, Ts, Ds) ->
1603    T = type(Op, Args, Anno, Ts, Ds),
1604    Ts#{Dst=>T}.
1605
1606type({bif,Bif}, Args, _Anno, Ts, _Ds) ->
1607    ArgTypes = normalized_types(Args, Ts),
1608    {RetType, _, _} = beam_call_types:types(erlang, Bif, ArgTypes),
1609    RetType;
1610type(bs_init, _Args, _Anno, _Ts, _Ds) ->
1611    #t_bitstring{};
1612type(bs_extract, [Ctx], _Anno, _Ts, Ds) ->
1613    #b_set{op=bs_match,args=Args} = map_get(Ctx, Ds),
1614    bs_match_type(Args);
1615type(bs_start_match, [_, Src], _Anno, Ts, _Ds) ->
1616    case beam_types:meet(#t_bs_matchable{}, raw_type(Src, Ts)) of
1617        none ->
1618            none;
1619        T ->
1620            Unit = beam_types:get_bs_matchable_unit(T),
1621            #t_bs_context{tail_unit=Unit}
1622    end;
1623type(bs_match, [#b_literal{val=binary}, Ctx, _Flags,
1624                #b_literal{val=all}, #b_literal{val=OpUnit}],
1625     _Anno, Ts, _Ds) ->
1626
1627    %% This is an explicit tail unit test which does not advance the match
1628    %% position.
1629    CtxType = raw_type(Ctx, Ts),
1630    OpType = #t_bs_context{tail_unit=OpUnit},
1631
1632    beam_types:meet(CtxType, OpType);
1633type(bs_match, Args, _Anno, Ts, _Ds) ->
1634    [_, Ctx | _] = Args,
1635
1636    %% Matches advance the current position without testing the tail unit. We
1637    %% try to retain unit information by taking the GCD of our current unit and
1638    %% the increments we know the match will advance by.
1639    #t_bs_context{tail_unit=CtxUnit} = raw_type(Ctx, Ts),
1640    OpUnit = bs_match_stride(Args, Ts),
1641
1642    #t_bs_context{tail_unit=gcd(OpUnit, CtxUnit)};
1643type(bs_get_tail, [Ctx], _Anno, Ts, _Ds) ->
1644    #t_bs_context{tail_unit=Unit} = raw_type(Ctx, Ts),
1645    #t_bitstring{size_unit=Unit};
1646type(call, [#b_remote{mod=#b_literal{val=Mod},
1647                      name=#b_literal{val=Name}}|Args], _Anno, Ts, _Ds) ->
1648    ArgTypes = normalized_types(Args, Ts),
1649    {RetType, _, _} = beam_call_types:types(Mod, Name, ArgTypes),
1650    RetType;
1651type(call, [#b_remote{} | _Args], _Anno, _Ts, _Ds) ->
1652    %% Remote call with variable Module and/or Function.
1653    any;
1654type(call, [#b_local{} | _Args], Anno, _Ts, _Ds) ->
1655    case Anno of
1656        #{ result_type := Type } -> Type;
1657        #{} -> any
1658    end;
1659type(call, [#b_var{} | _Args], Anno, _Ts, _Ds) ->
1660    case Anno of
1661        #{ result_type := Type } -> Type;
1662        #{} -> any
1663    end;
1664type(call, [#b_literal{val=Fun} | Args], _Anno, _Ts, _Ds) ->
1665    case is_function(Fun, length(Args)) of
1666        true ->
1667            %% This is an external fun literal (fun M:F/A).
1668            any;
1669        false ->
1670            %% This is either not a fun literal or the number of
1671            %% arguments is wrong.
1672            none
1673    end;
1674type(get_hd, [Src], _Anno, Ts, _Ds) ->
1675    SrcType = #t_cons{} = normalized_type(Src, Ts), %Assertion.
1676    {RetType, _, _} = beam_call_types:types(erlang, hd, [SrcType]),
1677    RetType;
1678type(get_tl, [Src], _Anno, Ts, _Ds) ->
1679    SrcType = #t_cons{} = normalized_type(Src, Ts), %Assertion.
1680    {RetType, _, _} = beam_call_types:types(erlang, tl, [SrcType]),
1681    RetType;
1682type(get_map_element, [_, _]=Args0, _Anno, Ts, _Ds) ->
1683    [#t_map{}=Map, Key] = normalized_types(Args0, Ts), %Assertion.
1684    {RetType, _, _} = beam_call_types:types(erlang, map_get, [Key, Map]),
1685    RetType;
1686type(get_tuple_element, [Tuple, Offset], _Anno, Ts, _Ds) ->
1687    #t_tuple{size=Size,elements=Es} = normalized_type(Tuple, Ts),
1688    #b_literal{val=N} = Offset,
1689    true = Size > N, %Assertion.
1690    beam_types:get_tuple_element(N + 1, Es);
1691type(has_map_field, [_, _]=Args0, _Anno, Ts, _Ds) ->
1692    [#t_map{}=Map, Key] = normalized_types(Args0, Ts), %Assertion.
1693    {RetType, _, _} = beam_call_types:types(erlang, is_map_key, [Key, Map]),
1694    RetType;
1695type(is_nonempty_list, [_], _Anno, _Ts, _Ds) ->
1696    beam_types:make_boolean();
1697type(is_tagged_tuple, [_,#b_literal{},#b_literal{}], _Anno, _Ts, _Ds) ->
1698    beam_types:make_boolean();
1699type(make_fun, [#b_local{arity=TotalArity} | Env], Anno, _Ts, _Ds) ->
1700    RetType = case Anno of
1701                  #{ result_type := Type } -> Type;
1702                  #{} -> any
1703              end,
1704    #t_fun{arity=TotalArity - length(Env), type=RetType};
1705type(put_map, [_Kind, Map | Ss], _Anno, Ts, _Ds) ->
1706    put_map_type(Map, Ss, Ts);
1707type(put_list, [Head, Tail], _Anno, Ts, _Ds) ->
1708    HeadType = raw_type(Head, Ts),
1709    TailType = raw_type(Tail, Ts),
1710    beam_types:make_cons(HeadType, TailType);
1711type(put_tuple, Args, _Anno, Ts, _Ds) ->
1712    {Es, _} = foldl(fun(Arg, {Es0, Index}) ->
1713                            Type = raw_type(Arg, Ts),
1714                            Es = beam_types:set_tuple_element(Index, Type, Es0),
1715                            {Es, Index + 1}
1716                    end, {#{}, 1}, Args),
1717    #t_tuple{exact=true,size=length(Args),elements=Es};
1718type(resume, [_, _], _Anno, _Ts, _Ds) ->
1719    none;
1720type(_, _, _, _, _) -> any.
1721
1722put_map_type(Map, Ss, Ts) ->
1723    pmt_1(Ss, Ts, normalized_type(Map, Ts)).
1724
1725pmt_1([Key0, Value0 | Ss], Ts, Acc0) ->
1726    Key = normalized_type(Key0, Ts),
1727    Value = normalized_type(Value0, Ts),
1728    {Acc, _, _} = beam_call_types:types(maps, put, [Key, Value, Acc0]),
1729    pmt_1(Ss, Ts, Acc);
1730pmt_1([], _Ts, Acc) ->
1731    Acc.
1732
1733%% We seldom know how far a match operation may advance, but we can often tell
1734%% which increment it will advance by.
1735bs_match_stride([#b_literal{val=Type} | Args], Ts) ->
1736    bs_match_stride(Type, Args, Ts).
1737
1738bs_match_stride(_, [_,_,Size,#b_literal{val=Unit}], Ts) ->
1739    case raw_type(Size, Ts) of
1740        #t_integer{elements={Sz, Sz}} when is_integer(Sz) ->
1741            Sz * Unit;
1742        _ ->
1743            Unit
1744    end;
1745bs_match_stride(string, [_,#b_literal{val=String}], _) ->
1746    bit_size(String);
1747bs_match_stride(utf8, _, _) ->
1748    8;
1749bs_match_stride(utf16, _, _) ->
1750    16;
1751bs_match_stride(utf32, _, _) ->
1752    32;
1753bs_match_stride(_, _, _) ->
1754    1.
1755
1756-define(UNICODE_MAX, (16#10FFFF)).
1757
1758bs_match_type([#b_literal{val=Type}|Args]) ->
1759    bs_match_type(Type, Args).
1760
1761bs_match_type(binary, Args) ->
1762    [_,_,_,#b_literal{val=U}] = Args,
1763    #t_bitstring{size_unit=U};
1764bs_match_type(float, _) ->
1765    #t_float{};
1766bs_match_type(integer, Args) ->
1767    case Args of
1768        [_,
1769         #b_literal{val=Flags},
1770         #b_literal{val=Size},
1771         #b_literal{val=Unit}] when Size * Unit < 64 ->
1772            NumBits = Size * Unit,
1773            case member(unsigned, Flags) of
1774                true ->
1775                    beam_types:make_integer(0, (1 bsl NumBits)-1);
1776                false ->
1777                    %% Signed integer. Don't bother.
1778                    #t_integer{}
1779            end;
1780        [_|_] ->
1781            #t_integer{}
1782    end;
1783bs_match_type(skip, _) ->
1784    any;
1785bs_match_type(string, _) ->
1786    any;
1787bs_match_type(utf8, _) ->
1788    beam_types:make_integer(0, ?UNICODE_MAX);
1789bs_match_type(utf16, _) ->
1790    beam_types:make_integer(0, ?UNICODE_MAX);
1791bs_match_type(utf32, _) ->
1792    beam_types:make_integer(0, ?UNICODE_MAX).
1793
1794normalized_types(Values, Ts) ->
1795    [normalized_type(Val, Ts) || Val <- Values].
1796
1797normalized_type(V, Ts) ->
1798    beam_types:normalize(raw_type(V, Ts)).
1799
1800argument_types(Values, Ts) ->
1801    [argument_type(Val, Ts) || Val <- Values].
1802
1803-spec argument_type(beam_ssa:value(), type_db()) -> type().
1804
1805argument_type(V, Ts) ->
1806    beam_types:limit_depth(raw_type(V, Ts)).
1807
1808raw_types(Values, Ts) ->
1809    [raw_type(Val, Ts) || Val <- Values].
1810
1811-spec raw_type(beam_ssa:value(), type_db()) -> type().
1812
1813raw_type(#b_literal{val=Value}, _Ts) ->
1814    beam_types:make_type_from_value(Value);
1815raw_type(V, Ts) ->
1816    map_get(V, Ts).
1817
1818%% infer_types(Var, Types, #d{}) -> {SuccTypes,FailTypes}
1819%%  Looking at the expression that defines the variable Var, infer
1820%%  the types for the variables in the arguments. Return the updated
1821%%  type database for the case that the expression evaluates to
1822%%  true, and and for the case that it evaluates to false.
1823%%
1824%%  Here is an example. The variable being asked about is
1825%%  the variable Bool, which is defined like this:
1826%%
1827%%     Bool = is_nonempty_list L
1828%%
1829%%  If 'is_nonempty_list L' evaluates to 'true', L must
1830%%  must be cons. The meet of the previously known type of L and 'cons'
1831%%  will be added to SuccTypes.
1832%%
1833%%  On the other hand, if 'is_nonempty_list L' evaluates to false, L
1834%%  is not cons and cons can be subtracted from the previously known
1835%%  type for L. For example, if L was known to be 'list', subtracting
1836%%  'cons' would give 'nil' as the only possible type. The result of the
1837%%  subtraction for L will be added to FailTypes.
1838
1839infer_types_br(#b_var{}=V, Ts, IsTempVar, Ds) ->
1840    #{V:=#b_set{op=Op,args=Args}} = Ds,
1841
1842    {PosTypes, NegTypes} = infer_type(Op, Args, Ts, Ds),
1843
1844    SuccTs0 = meet_types(PosTypes, Ts),
1845    FailTs0 = subtract_types(NegTypes, Ts),
1846
1847    case IsTempVar of
1848        true ->
1849            %% The branch variable is defined in this block and is only
1850            %% referenced by this terminator. Therefore, there is no need to
1851            %% include it in the type database passed on to the successors of
1852            %% of this block.
1853            SuccTs = ts_remove_var(V, SuccTs0),
1854            FailTs = ts_remove_var(V, FailTs0),
1855            {SuccTs, FailTs};
1856        false ->
1857            SuccTs = infer_br_value(V, true, SuccTs0),
1858            FailTs = infer_br_value(V, false, FailTs0),
1859            {SuccTs, FailTs}
1860    end.
1861
1862infer_br_value(_V, _Bool, none) ->
1863    none;
1864infer_br_value(V, Bool, NewTs) ->
1865    #{ V := T } = NewTs,
1866    case beam_types:is_boolean_type(T) of
1867        true ->
1868            NewTs#{ V := beam_types:make_atom(Bool) };
1869        false ->
1870            %% V is a try/catch tag or similar, leave it alone.
1871            NewTs
1872    end.
1873
1874infer_types_switch(V, Lit, Ts0, IsTempVar, Ds) ->
1875    {PosTypes, _} = infer_type({bif,'=:='}, [V, Lit], Ts0, Ds),
1876    Ts = meet_types(PosTypes, Ts0),
1877    case IsTempVar of
1878        true -> ts_remove_var(V, Ts);
1879        false -> Ts
1880    end.
1881
1882ts_remove_var(_V, none) -> none;
1883ts_remove_var(V, Ts) -> maps:remove(V, Ts).
1884
1885infer_type({succeeded,_}, [#b_var{}=Src], Ts, Ds) ->
1886    #b_set{op=Op,args=Args} = maps:get(Src, Ds),
1887    infer_success_type(Op, Args, Ts, Ds);
1888
1889%% Type tests are handled separately from other BIFs as we're inferring types
1890%% based on their result, so we know that subtraction is safe even if we're
1891%% not branching on 'succeeded'.
1892infer_type(is_tagged_tuple, [#b_var{}=Src,#b_literal{val=Size},
1893                             #b_literal{}=Tag], _Ts, _Ds) ->
1894    Es = beam_types:set_tuple_element(1, raw_type(Tag, #{}), #{}),
1895    T = {Src,#t_tuple{exact=true,size=Size,elements=Es}},
1896    {[T], [T]};
1897infer_type(is_nonempty_list, [#b_var{}=Src], _Ts, _Ds) ->
1898    T = {Src,#t_cons{}},
1899    {[T], [T]};
1900infer_type({bif,is_atom}, [Arg], _Ts, _Ds) ->
1901    T = {Arg, #t_atom{}},
1902    {[T], [T]};
1903infer_type({bif,is_binary}, [Arg], _Ts, _Ds) ->
1904    T = {Arg, #t_bitstring{size_unit=8}},
1905    {[T], [T]};
1906infer_type({bif,is_bitstring}, [Arg], _Ts, _Ds) ->
1907    T = {Arg, #t_bitstring{}},
1908    {[T], [T]};
1909infer_type({bif,is_boolean}, [Arg], _Ts, _Ds) ->
1910    T = {Arg, beam_types:make_boolean()},
1911    {[T], [T]};
1912infer_type({bif,is_float}, [Arg], _Ts, _Ds) ->
1913    T = {Arg, #t_float{}},
1914    {[T], [T]};
1915infer_type({bif,is_integer}, [Arg], _Ts, _Ds) ->
1916    T = {Arg, #t_integer{}},
1917    {[T], [T]};
1918infer_type({bif,is_list}, [Arg], _Ts, _Ds) ->
1919    T = {Arg, #t_list{}},
1920    {[T], [T]};
1921infer_type({bif,is_map}, [Arg], _Ts, _Ds) ->
1922    T = {Arg, #t_map{}},
1923    {[T], [T]};
1924infer_type({bif,is_number}, [Arg], _Ts, _Ds) ->
1925    T = {Arg, number},
1926    {[T], [T]};
1927infer_type({bif,is_tuple}, [Arg], _Ts, _Ds) ->
1928    T = {Arg, #t_tuple{}},
1929    {[T], [T]};
1930infer_type({bif,'=:='}, [#b_var{}=LHS,#b_var{}=RHS], Ts, _Ds) ->
1931    %% As an example, assume that L1 is known to be 'list', and L2 is
1932    %% known to be 'cons'. Then if 'L1 =:= L2' evaluates to 'true', it can
1933    %% be inferred that L1 is 'cons' (the meet of 'cons' and 'list').
1934    LType = raw_type(LHS, Ts),
1935    RType = raw_type(RHS, Ts),
1936    Type = beam_types:meet(LType, RType),
1937
1938    PosTypes = [{V,Type} || {V, OrigType} <- [{LHS, LType}, {RHS, RType}],
1939                            OrigType =/= Type],
1940
1941    %% We must be careful with types inferred from '=:='.
1942    %%
1943    %% If we have seen L =:= [a], we know that L is 'cons' if the
1944    %% comparison succeeds. However, if the comparison fails, L could
1945    %% still be 'cons'. Therefore, we must not subtract 'cons' from the
1946    %% previous type of L.
1947    %%
1948    %% However, it is safe to subtract a type inferred from '=:=' if
1949    %% it is single-valued, e.g. if it is [] or the atom 'true'.
1950    %%
1951    %% Note that we subtract the left-hand type from the right-hand
1952    %% value and vice versa. We must not subtract the meet of the two
1953    %% as it may be too specific. See beam_type_SUITE:type_subtraction/1
1954    %% for details.
1955    NegTypes = [T || {_, OtherType}=T <- [{RHS, LType}, {LHS, RType}],
1956                     beam_types:is_singleton_type(OtherType)],
1957
1958    {PosTypes, NegTypes};
1959infer_type({bif,'=:='}, [#b_var{}=Src,#b_literal{}=Lit], Ts, Ds) ->
1960    Def = maps:get(Src, Ds),
1961    LitType = raw_type(Lit, Ts),
1962    PosTypes = [{Src, LitType} | infer_eq_lit(Def, LitType)],
1963
1964    %% Subtraction is only safe if LitType is single-valued.
1965    NegTypes = case beam_types:is_singleton_type(LitType) of
1966                    true -> PosTypes;
1967                    false -> []
1968               end,
1969
1970    {PosTypes, NegTypes};
1971infer_type(_Op, _Args, _Ts, _Ds) ->
1972    {[], []}.
1973
1974infer_success_type({bif,Op}, Args, Ts, _Ds) ->
1975    ArgTypes = normalized_types(Args, Ts),
1976
1977    {_, PosTypes0, CanSubtract} = beam_call_types:types(erlang, Op, ArgTypes),
1978    PosTypes = [T || {#b_var{},_}=T <- zip(Args, PosTypes0)],
1979
1980    case CanSubtract of
1981        true -> {PosTypes, PosTypes};
1982        false -> {PosTypes, []}
1983    end;
1984infer_success_type(call, [#b_var{}=Fun|Args], _Ts, _Ds) ->
1985    T = {Fun, #t_fun{arity=length(Args)}},
1986    {[T], []};
1987infer_success_type(bs_start_match, [_, #b_var{}=Src], _Ts, _Ds) ->
1988    T = {Src,#t_bs_matchable{}},
1989    {[T], [T]};
1990infer_success_type(bs_match, [#b_literal{val=binary},
1991                              Ctx, _Flags,
1992                              #b_literal{val=all},
1993                              #b_literal{val=OpUnit}],
1994                   _Ts, _Ds) ->
1995    %% This is an explicit tail unit test which does not advance the match
1996    %% position, so we know that Ctx has the same unit.
1997    T = {Ctx, #t_bs_context{tail_unit=OpUnit}},
1998    {[T], [T]};
1999infer_success_type(_Op, _Args, _Ts, _Ds) ->
2000    {[], []}.
2001
2002infer_eq_lit(#b_set{op={bif,tuple_size},args=[#b_var{}=Tuple]},
2003             #t_integer{elements={Size,Size}}) ->
2004    [{Tuple,#t_tuple{exact=true,size=Size}}];
2005infer_eq_lit(#b_set{op=get_tuple_element,
2006                    args=[#b_var{}=Tuple,#b_literal{val=N}]},
2007             LitType) ->
2008    Index = N + 1,
2009    case beam_types:set_tuple_element(Index, LitType, #{}) of
2010        #{ Index := _ }=Es ->
2011            [{Tuple,#t_tuple{size=Index,elements=Es}}];
2012        #{} ->
2013            %% Index was above the element limit; subtraction is not safe.
2014            []
2015    end;
2016infer_eq_lit(_, _) ->
2017    [].
2018
2019join_types(Ts, Ts) ->
2020    Ts;
2021join_types(LHS, RHS) ->
2022    if
2023        map_size(LHS) < map_size(RHS) ->
2024            join_types_1(maps:keys(LHS), RHS, LHS);
2025        true ->
2026            join_types_1(maps:keys(RHS), LHS, RHS)
2027    end.
2028
2029%% Joins two type maps, keeping the variables that are common to both maps.
2030join_types_1([V | Vs], Bigger, Smaller) ->
2031    case {Bigger, Smaller} of
2032        {#{ V := Same }, #{ V := Same }} ->
2033            join_types_1(Vs, Bigger, Smaller);
2034        {#{ V := LHS }, #{ V := RHS }} ->
2035            T = beam_types:join(LHS, RHS),
2036            join_types_1(Vs, Bigger, Smaller#{ V := T });
2037        {#{}, #{ V := _ }} ->
2038            join_types_1(Vs, Bigger, maps:remove(V, Smaller))
2039    end;
2040join_types_1([], _Bigger, Smaller) ->
2041    Smaller.
2042
2043meet_types([{V,T0}|Vs], Ts) ->
2044    #{V:=T1} = Ts,
2045    case beam_types:meet(T0, T1) of
2046        none -> none;
2047        T1 -> meet_types(Vs, Ts);
2048        T -> meet_types(Vs, Ts#{V:=T})
2049    end;
2050meet_types([], Ts) -> Ts.
2051
2052subtract_types([{V,T0}|Vs], Ts) ->
2053    #{V:=T1} = Ts,
2054    case beam_types:subtract(T1, T0) of
2055        none -> none;
2056        T1 -> subtract_types(Vs, Ts);
2057        T -> subtract_types(Vs, Ts#{V:=T})
2058    end;
2059subtract_types([], Ts) -> Ts.
2060
2061parallel_join([A | As], [B | Bs]) ->
2062    [beam_types:join(A, B) | parallel_join(As, Bs)];
2063parallel_join([], []) ->
2064    [].
2065
2066gcd(A, B) ->
2067    case A rem B of
2068        0 -> B;
2069        X -> gcd(B, X)
2070    end.
2071
2072%%%
2073%%% Helpers
2074%%%
2075
2076init_metadata(FuncId, Linear, Params) ->
2077    {RetCounter, Map0} = init_metadata_1(reverse(Linear), 0, #{}),
2078    Map = maps:without(Params, Map0),
2079    UsedOnce = cerl_sets:from_list(maps:keys(Map)),
2080
2081    #metadata{ func_id = FuncId,
2082               limit_return = (RetCounter >= ?RETURN_LIMIT),
2083               params = Params,
2084               used_once = UsedOnce }.
2085
2086init_metadata_1([{L,#b_blk{is=Is,last=Last}} | Bs], RetCounter0, Uses0) ->
2087    %% Track the number of return terminators in use. See ?RETURN_LIMIT for
2088    %% details.
2089    RetCounter = case Last of
2090                     #b_ret{} -> RetCounter0 + 1;
2091                     _ -> RetCounter0
2092                 end,
2093
2094    %% Calculate the set of variables that are only used once in the terminator
2095    %% of the block that defines them. That will allow us to discard type
2096    %% information discard type information for variables that will never be
2097    %% referenced by the successor blocks, potentially improving compilation
2098    %% times.
2099
2100    Uses1 = used_once_last_uses(beam_ssa:used(Last), L, Uses0),
2101    Uses = used_once_2(reverse(Is), L, Uses1),
2102    init_metadata_1(Bs, RetCounter, Uses);
2103init_metadata_1([], RetCounter, Uses) ->
2104    {RetCounter, Uses}.
2105
2106used_once_2([#b_set{dst=Dst}=I|Is], L, Uses0) ->
2107    Uses = used_once_uses(beam_ssa:used(I), L, Uses0),
2108    case Uses of
2109        #{Dst:=[L]} ->
2110            used_once_2(Is, L, Uses);
2111        #{} ->
2112            %% Used more than once or used once in
2113            %% in another block.
2114            used_once_2(Is, L, maps:remove(Dst, Uses))
2115    end;
2116used_once_2([], _, Uses) -> Uses.
2117
2118used_once_uses([V|Vs], L, Uses) ->
2119    case Uses of
2120        #{V:=more_than_once} ->
2121            used_once_uses(Vs, L, Uses);
2122        #{} ->
2123            %% Already used or first use is not in
2124            %% a terminator.
2125            used_once_uses(Vs, L, Uses#{V=>more_than_once})
2126    end;
2127used_once_uses([], _, Uses) -> Uses.
2128
2129used_once_last_uses([V|Vs], L, Uses) ->
2130    case Uses of
2131        #{V:=[_]} ->
2132            %% Second time this variable is used.
2133            used_once_last_uses(Vs, L, Uses#{V:=more_than_once});
2134        #{V:=more_than_once} ->
2135            %% Used at least twice before.
2136            used_once_last_uses(Vs, L, Uses);
2137        #{} ->
2138            %% First time this variable is used.
2139            used_once_last_uses(Vs, L, Uses#{V=>[L]})
2140    end;
2141used_once_last_uses([], _, Uses) -> Uses.
2142
2143%%
2144%% Ordered worklist used in signatures/2.
2145%%
2146%% This is equivalent to consing (wl_add) and appending (wl_defer_list)
2147%% to a regular list, but avoids uneccessary work by reordering elements.
2148%%
2149%% We can do this since a function only needs to be visited *once* for all
2150%% prior updates to take effect, so if an element is added to the front, then
2151%% all earlier instances of the same element are redundant.
2152%%
2153
2154-record(worklist,
2155        { counter = 0 :: integer(),
2156          elements = gb_trees:empty() :: gb_trees:tree(integer(), term()),
2157          indexes = #{} :: #{ term() => integer() } }).
2158
2159-type worklist() :: #worklist{}.
2160
2161wl_new() -> #worklist{}.
2162
2163%% Adds an element to the worklist, or moves it to the front if it's already
2164%% present.
2165wl_add(Element, #worklist{counter=Counter,elements=Es,indexes=Is}) ->
2166    case Is of
2167        #{ Element := Index } ->
2168            wl_add_1(Element, Counter, gb_trees:delete(Index, Es), Is);
2169        #{} ->
2170            wl_add_1(Element, Counter, Es, Is)
2171    end.
2172
2173wl_add_1(Element, Counter0, Es0, Is0) ->
2174    Counter = Counter0 + 1,
2175    Es = gb_trees:insert(Counter, Element, Es0),
2176    Is = Is0#{ Element => Counter },
2177    #worklist{counter=Counter,elements=Es,indexes=Is}.
2178
2179%% All mutations bump the counter, so we can check for changes without a deep
2180%% comparison.
2181wl_changed(#worklist{counter=Same}, #worklist{counter=Same}) -> false;
2182wl_changed(#worklist{}, #worklist{}) -> true.
2183
2184%% Adds the given elements to the back of the worklist, skipping the elements
2185%% that are already present. This lets us append elements arbitrarly after the
2186%% current front without changing the work order.
2187wl_defer_list(Elements, #worklist{counter=Counter,elements=Es,indexes=Is}) ->
2188    wl_defer_list_1(Elements, Counter, Es, Is).
2189
2190wl_defer_list_1([Element | Elements], Counter0, Es0, Is0) ->
2191    case Is0 of
2192        #{ Element := _ } ->
2193            wl_defer_list_1(Elements, Counter0, Es0, Is0);
2194        #{} ->
2195            Counter = Counter0 + 1,
2196            Es = gb_trees:insert(-Counter, Element, Es0),
2197            Is = Is0#{ Element => -Counter },
2198            wl_defer_list_1(Elements, Counter, Es, Is)
2199    end;
2200wl_defer_list_1([], Counter, Es, Is) ->
2201    #worklist{counter=Counter,elements=Es,indexes=Is}.
2202
2203wl_next(#worklist{indexes=Is}) when Is =:= #{} ->
2204    empty;
2205wl_next(#worklist{elements=Es,indexes=Is}) when Is =/= #{} ->
2206    {_Key, Element} = gb_trees:largest(Es),
2207    {ok, Element}.
2208
2209%% Removes the front of the worklist.
2210wl_pop(Element, #worklist{counter=Counter0,elements=Es0,indexes=Is0}=Wl) ->
2211    Counter = Counter0 + 1,
2212    {_Key, Element, Es} = gb_trees:take_largest(Es0), %Assertion.
2213    Is = maps:remove(Element, Is0),
2214    Wl#worklist{counter=Counter,elements=Es,indexes=Is}.
2215