Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:24
erlang
2865-Move-map-optimizations-from-beam_peep-to-b...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 2865-Move-map-optimizations-from-beam_peep-to-beam_block.patch of Package erlang
From 9bdec7da24722a13c0fe870ffd64c29f3635fff3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org> Date: Fri, 20 Aug 2021 07:07:55 +0200 Subject: [PATCH 5/7] Move map optimizations from beam_peep to beam_block As a preparation for removing the beam_peep pass, move the remaining useful optimizations to beam_block. --- lib/compiler/src/beam_block.erl | 71 ++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/lib/compiler/src/beam_block.erl b/lib/compiler/src/beam_block.erl index e8d024b20b..3b191db676 100644 --- a/lib/compiler/src/beam_block.erl +++ b/lib/compiler/src/beam_block.erl @@ -22,7 +22,8 @@ -module(beam_block). -export([module/2]). --import(lists, [keysort/2,reverse/1,reverse/2,splitwith/2]). +-import(lists, [keysort/2,member/2,reverse/1,reverse/2, + splitwith/2,usort/1]). -spec module(beam_utils:module_code(), [compile:option()]) -> {'ok',beam_utils:module_code()}. @@ -35,7 +36,8 @@ function({function,Name,Arity,CLabel,Is0}) -> try Is1 = swap_opt(Is0), Is2 = blockify(Is1), - Is = embed_lines(Is2), + Is3 = embed_lines(Is2), + Is = opt_maps(Is3), {function,Name,Arity,CLabel,Is} catch Class:Error:Stack -> @@ -216,3 +218,68 @@ sort_on_yreg([{set,[Dst],[Src],move}|_]=Moves) -> {{x,_},{y,_}} -> keysort(3, Moves) end. + +%%% +%%% Coalesce adjacent get_map_elements and has_map_fields instructions. +%%% + +opt_maps(Is) -> + opt_maps(Is, []). + +opt_maps([{get_map_elements,Fail,Src,List}=I|Is], Acc0) -> + case simplify_get_map_elements(Fail, Src, List, Acc0) of + {ok,Acc} -> + opt_maps(Is, Acc); + error -> + opt_maps(Is, [I|Acc0]) + end; +opt_maps([{test,has_map_fields,Fail,Ops}=I|Is], Acc0) -> + case simplify_has_map_fields(Fail, Ops, Acc0) of + {ok,Acc} -> + opt_maps(Is, Acc); + error -> + opt_maps(Is, [I|Acc0]) + end; +opt_maps([I|Is], Acc) -> + opt_maps(Is, [I|Acc]); +opt_maps([], Acc) -> reverse(Acc). + +simplify_get_map_elements(Fail, Src, {list,[Key,Dst]}, + [{get_map_elements,Fail,Src,{list,List1}}|Acc]) -> + case are_keys_literals([Key]) andalso are_keys_literals(List1) andalso + not is_source_overwritten(Src, List1) of + true -> + case member(Key, List1) of + true -> + %% The key is already in the other list. That is + %% very unusual, because there are optimizations to get + %% rid of duplicate keys. Therefore, don't try to + %% do anything smart here; just keep the + %% get_map_elements instructions separate. + error; + false -> + List = [Key,Dst|List1], + {ok,[{get_map_elements,Fail,Src,{list,List}}|Acc]} + end; + false -> + error + end; +simplify_get_map_elements(_, _, _, _) -> error. + +simplify_has_map_fields(Fail, [Src|Keys0], + [{test,has_map_fields,Fail,[Src|Keys1]}|Acc]) -> + case are_keys_literals(Keys0) andalso are_keys_literals(Keys1) of + true -> + Keys = usort(Keys0 ++ Keys1), + {ok,[{test,has_map_fields,Fail,[Src|Keys]}|Acc]}; + false -> + error + end; +simplify_has_map_fields(_, _, _) -> error. + +are_keys_literals([{x,_}|_]) -> false; +are_keys_literals([{y,_}|_]) -> false; +are_keys_literals([_|_]) -> true. + +is_source_overwritten(Src, [_Key,Src]) -> true; +is_source_overwritten(_, _) -> false. -- 2.31.1
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