Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:24
erlang
6441-beam_ssa_opt-Merge-consecutive-record-upda...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 6441-beam_ssa_opt-Merge-consecutive-record-updates.patch of Package erlang
From 8c7370ec31782f6a7f1fcab44e6f13e133928ad5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20H=C3=B6gberg?= <john@erlang.org> Date: Tue, 11 Jul 2023 11:16:44 +0200 Subject: [PATCH] beam_ssa_opt: Merge consecutive record updates --- lib/compiler/src/beam_ssa_opt.erl | 45 +++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/lib/compiler/src/beam_ssa_opt.erl b/lib/compiler/src/beam_ssa_opt.erl index 63525b8600..06c1e79f20 100644 --- a/lib/compiler/src/beam_ssa_opt.erl +++ b/lib/compiler/src/beam_ssa_opt.erl @@ -273,6 +273,7 @@ repeated_passes(Opts) -> ?PASS(ssa_opt_tail_phis), ?PASS(ssa_opt_sink), ?PASS(ssa_opt_tuple_size), + ?PASS(ssa_opt_merge_updates), ?PASS(ssa_opt_record), ?PASS(ssa_opt_try), ?PASS(ssa_opt_type_continue)], %Must run after ssa_opt_dead to @@ -455,6 +456,50 @@ ssa_opt_merge_blocks({#opt_st{ssa=Blocks0}=St, FuncDb}) -> Blocks = beam_ssa:merge_blocks(RPO, Blocks0), {St#opt_st{ssa=Blocks}, FuncDb}. +%%% +%%% Merges updates that cannot fail, for example two consecutive updates of the +%%% same record. +%%% + +ssa_opt_merge_updates({#opt_st{ssa=Linear0}=St, FuncDb}) -> + Linear = merge_updates_bs(Linear0), + {St#opt_st{ssa=Linear}, FuncDb}. + +%% As update_record is always converted from setelement/3 operations they can +%% only occur alone in their blocks at this point, so we don't need to look +%% deeper than this. +merge_updates_bs([{LblA, + #b_blk{is=[#b_set{op=update_record, + dst=DstA, + args=[SpecA, Size, Src | ListA]}], + last=#b_br{bool=#b_literal{val=true}, + succ=LblB}}=BlkA}, + {LblB, + #b_blk{is=[#b_set{op=update_record, + args=[SpecB, Size, DstA | ListB]}=Update0] + }=BlkB} | Bs]) -> + Spec = case SpecA =:= SpecB of + true -> SpecA; + false -> #b_literal{val=copy} + end, + List = merge_update_record_lists(ListA ++ ListB, #{}), + Update = Update0#b_set{args=[Spec, Size, Src | List]}, + + %% Note that we retain the first update_record in case it's used elsewhere, + %% it's too rare to warrant special handling here. + [{LblA, BlkA}, {LblB, BlkB#b_blk{is=[Update]}}| merge_updates_bs(Bs)]; +merge_updates_bs([{Lbl, Blk} | Bs]) -> + [{Lbl, Blk} | merge_updates_bs(Bs)]; +merge_updates_bs([]) -> + []. + +merge_update_record_lists([Index, Value | List], Updates) -> + merge_update_record_lists(List, Updates#{ Index => Value }); +merge_update_record_lists([], Updates) -> + maps:fold(fun(K, V, Acc) -> + [K, V | Acc] + end, [], Updates). + %%% %%% Split blocks before certain instructions to enable more optimizations. %%% -- 2.35.3
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor