bc: do not use "(cond ? f1 : f2)(params)" idiom, it messes up static function optimizations

With direct calls, GCC no longer thinks that we take addresses of the functions,
and can use "more optimal" internal ABI for _all_ calls to these functions,
not only at this callsite. On i486, regparm is used, and:

function                                             old     new   delta
zbc_num_inv                                           56      57      +1
zbc_num_k                                            852     851      -1
zbc_program_modexp                                   558     556      -2
zbc_num_d                                            541     539      -2
bc_num_ulong2num                                      59      57      -2
zbc_program_num                                      840     836      -4
bc_num_zero                                           11       7      -4
bc_num_one                                            28      24      -4
bc_program_exec                                     3928    3918     -10
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/8 up/down: 1/-29)             Total: -28 bytes
   text	   data	    bss	    dec	    hex	filename
 982237	    485	   7296	 990018	  f1b42	busybox_old
 982209	    485	   7296	 989990	  f1b26	busybox_unstripped

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2018-12-11 19:29:35 +01:00
parent 7f4daa4f58
commit 09d8df84ee

View File

@ -5943,6 +5943,7 @@ static BcStatus bc_program_logical(char inst)
s = zbc_program_binOpPrep(&opd1, &n1, &opd2, &n2, false);
if (s) return s;
bc_num_init_DEF_SIZE(&res.d.n);
if (inst == BC_INST_BOOL_AND)
@ -5950,50 +5951,31 @@ static BcStatus bc_program_logical(char inst)
else if (inst == BC_INST_BOOL_OR)
cond = bc_num_cmp(n1, &G.prog.zero) || bc_num_cmp(n2, &G.prog.zero);
else {
cmp = bc_num_cmp(n1, n2);
switch (inst) {
case BC_INST_REL_EQ:
{
cond = cmp == 0;
break;
}
case BC_INST_REL_LE:
{
cond = cmp <= 0;
break;
}
case BC_INST_REL_GE:
{
cond = cmp >= 0;
break;
}
case BC_INST_REL_NE:
{
cond = cmp != 0;
break;
}
case BC_INST_REL_LT:
{
cond = cmp < 0;
break;
}
case BC_INST_REL_GT:
{
cond = cmp > 0;
break;
}
}
}
(cond ? bc_num_one : bc_num_zero)(&res.d.n);
if (cond) bc_num_one(&res.d.n);
//else bc_num_zero(&res.d.n); - already is
bc_program_binOpRetire(&res);