aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2017-10-04 20:44:47 +0200
committerBjörn Gustavsson <[email protected]>2017-10-09 11:28:40 +0200
commitc2e746117b24235b8f2c508ef8f90e35ad422bf2 (patch)
treeb9ae6f61acdf136018fdeb4667bbd9e0281668c1 /erts
parenta71ffb9c1b9de6ccc7b8d2278361474b373802c3 (diff)
downloadotp-c2e746117b24235b8f2c508ef8f90e35ad422bf2.tar.gz
otp-c2e746117b24235b8f2c508ef8f90e35ad422bf2.tar.bz2
otp-c2e746117b24235b8f2c508ef8f90e35ad422bf2.zip
Pack operands for combined instructions into the instruction word
The operands for the first part of a combined instruction (the entry point following the OpCase() label) can safely be packed into the instruction word. This commit will make each of the following instructions one word shorter: bs_context_to_binary_x i_band_xcjtd i_bs_get_binary_all_reuse_xft i_bs_get_integer_imm_xWtftx i_bs_get_integer_small_imm_xWftx i_bs_init_bits_fail_xjtx i_bs_init_bits_fail_yjtx i_bs_init_bits_fail_heap_sIjtx i_bs_init_bits_heap_WItx i_bs_init_fail_xjtx i_bs_init_fail_yjtx i_bs_init_fail_heap_sIjtx i_bs_init_heap_WItx i_bs_start_match2_xfttx i_bs_start_match2_yfttx i_element_xjsd i_element_yjsd i_fast_element_xjId i_fast_element_yjId i_increment_xWtd i_increment_yWtd i_jump_on_val_xfIW i_jump_on_val_yfIW i_jump_on_val_zero_xfI i_jump_on_val_zero_yfI i_minus_xxjtd i_plus_xxjtd i_plus_xyjtd i_put_tuple_xI i_put_tuple_yI i_rem_xxjtd i_select_tuple_arity_xfI i_select_tuple_arity_yfI i_select_tuple_arity2_xfAA i_select_tuple_arity2_yfAA i_select_val2_xfcc i_select_val2_yfcc i_select_val_bins_xfI i_select_val_bins_yfI i_select_val_lins_xfI i_select_val_lins_yfI
Diffstat (limited to 'erts')
-rwxr-xr-xerts/emulator/utils/beam_makeops41
1 files changed, 32 insertions, 9 deletions
diff --git a/erts/emulator/utils/beam_makeops b/erts/emulator/utils/beam_makeops
index 50dd534828..d7791d23fa 100755
--- a/erts/emulator/utils/beam_makeops
+++ b/erts/emulator/utils/beam_makeops
@@ -1129,9 +1129,28 @@ sub combine_instruction_group {
# Variables.
my %offsets;
my @instrs;
- my %num_references;
+ my %num_references; # Number of references from other sub instructions.
my $group_size = 999;
+ #
+ # Calculate the number of references from other sub instructions.
+ # This number is useful in several ways:
+ #
+ # * If this number is 0, it is only used as the entry point for a
+ # function, implying that it does not need a label and that operands
+ # can be packed into the instruction word.
+ #
+ # * We'll use this number in the sort key, as a tie breaker for sub instructions
+ # at the same instruction offset.
+ #
+ foreach my $ref_instr (@in_instrs) {
+ my(undef,undef,$first_sub,@other_subs) = @$ref_instr;
+ $num_references{$first_sub} += 0; # Make sure it is defined.
+ foreach my $sub (@other_subs) {
+ $num_references{$sub}++;
+ }
+ }
+
# Do basic error checking. Associate operands of instructions
# with the correct micro instructions. Calculate offsets for micro
# instructions.
@@ -1157,12 +1176,13 @@ sub combine_instruction_group {
foreach (0..$#c_args) {
push @first, shift @rest;
}
- my $size = cg_combined_size(name => $s, args => \@first);
+ my $size = cg_combined_size(name => $s,
+ first => $num_references{$s} == 0,
+ args => \@first);
$offsets{$s} = $offset
unless defined $offsets{$s} and $offsets{$s} < $offset;
$offset += $size - 1;
my $label = micro_label($s);
- $num_references{$label} = 0;
push @new_subs, [$opcase,$label,$s,$size-1,@first];
$opcase = '';
}
@@ -1181,9 +1201,8 @@ sub combine_instruction_group {
my($opcase,$label,$s,$size,@args) = @{$subs[$i]};
my $next = '';
(undef,$next) = @{$subs[$i+1]} if $i < $#subs;
- $num_references{$next}++ if $next;
my $instr_info = "$opcase:$label:$next:$s:$size:@args";
- push @all_instrs, [$label,$offsets{$s},$instr_info];
+ push @all_instrs, [$label,$s,$offsets{$s},$instr_info];
}
}
@@ -1191,8 +1210,8 @@ sub combine_instruction_group {
my %label_to_offset;
my %order_to_offset;
foreach my $instr (@all_instrs) {
- my($label,$offset,$instr_info) = @$instr;
- my $sort_key = sprintf("%02d.%02d", $offset, $num_references{$label});
+ my($label,$s,$offset,$instr_info) = @$instr;
+ my $sort_key = sprintf("%02d.%02d", $offset, $num_references{$s});
push @{$order_to_instrs{$sort_key}}, $instr_info;
$label_to_offset{$label} = $offset;
$order_to_offset{$sort_key} = $offset;
@@ -1231,7 +1250,7 @@ sub combine_instruction_group {
$gcode .= "OpCase($opcase):\n";
push @opcase_labels, $opcase;
}
- if ($num_references{$label}) {
+ if ($num_references{$s}) {
$gcode .= "$label:\n";
}
@@ -1249,6 +1268,7 @@ sub combine_instruction_group {
my($gen_code,$down,$up) =
cg_combined_code(name => $s,
+ first => $num_references{$s} == 0,
extra_comments => $flags,
offset => $offset,
comp_size => $group_size-$offset,
@@ -1314,6 +1334,8 @@ sub cg_basic {
sub cg_combined_size {
my %params = (@_, pack_options => \@basic_pack_options);
+ $params{pack_options} = \@extended_pack_options
+ if $params{first};
my($size) = code_gen(%params);
$size;
}
@@ -1324,7 +1346,8 @@ sub cg_combined_size {
sub cg_combined_code {
my %params = (@_, pack_options => \@basic_pack_options);
-
+ $params{pack_options} = \@extended_pack_options
+ if $params{first};
my($size,$code,$pack_spec) = code_gen(%params);
if ($pack_spec eq '') {
($code,'','');