This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: RFA: autoincrement patches for gcc 4 - updated patch
I've appended a patch with the simple solution to the 3-address add
problem. A quick
re-run of CSiBE after regenerating cc1/cc1plus/cc1obj gives a total size of
3511488, i.e. 8 bytes code size decrease from the baseline. I'm not
sure if re-building
the libraries will give a different result, though.
Add this to the ChangeLog:
* (have_3addr_const_add): New variable.
... and this patch on top:
*** regmove.c-20050518-1 2005-05-18 10:26:14.000000000 +0100
--- regmove.c 2005-05-18 14:43:30.000000000 +0100
*************** static struct obstack related_obstack;
*** 597,602 ****
--- 597,603 ----
them out. */
static HOST_WIDE_INT add_limits[NUM_MACHINE_MODES][2];
+ static char have_3addr_const_add[NUM_MACHINE_MODES];
/* Try to find a related value with offset OFFSET from the base
register belonging to REGNO, using a register with preferred class
*************** link_chains (struct rel_use_chain *pred_
*** 1548,1553 ****
--- 1549,1555 ----
pred_chain->uses->class)
/* add_limits is not valid for MODE_PARTIAL_INT . */
&& GET_MODE_CLASS (base_mode) == MODE_INT
+ && !have_3addr_const_add[(int) base_mode]
&& (succ_chain->uses->offset - pred_chain->match_offset
>= add_limits[(int) base_mode][0])
&& (succ_chain->uses->offset - pred_chain->match_offset
*************** optimize_related_values_1 (struct relate
*** 1725,1730 ****
--- 1727,1733 ----
struct rel_use_chain *chain = chain_starttab[i];
if (! chain->reg
&& chain->start_luid
+ && (!have_3addr_const_add[(int) mode] || !chain->uses->offset)
&& chain->uses->offset >= add_limits[(int) mode][0]
&& chain->uses->offset <= add_limits[(int) mode][1]
/* Also can't use this chain if its register is clobbered
*************** optimize_related_values_1 (struct relate
*** 1787,1800 ****
however, if the base register is allocated to a chain
(i.e. rel_base_reg_user != 0), we don't need a move insn to start
that chain.
We do the optimization if we save instructions, or if we
stay with the same number of instructions, but save registers.
We also require that we have enough registers available for reuse.
Moreover, we have to check that we can add the offset for
rel_base_reg_user, in case it is a mandatory allocated register. */
! if ((2 * num_regs
! > ((2 * num_chains - num_linked - (rel_base_reg_user != 0))
! - (num_linked != 0)))
&& num_av_regs + (rel_base_reg_user != 0) >= num_chains - num_linked
&& rel_base_reg_user_offset >= add_limits[(int) mode][0]
&& rel_base_reg_user_offset <= add_limits[(int) mode][1])
--- 1790,1807 ----
however, if the base register is allocated to a chain
(i.e. rel_base_reg_user != 0), we don't need a move insn to start
that chain.
+ If we have a three-address add, however, the cost per value / chain
+ is just one insn, and linking chains is pointless.
We do the optimization if we save instructions, or if we
stay with the same number of instructions, but save registers.
We also require that we have enough registers available for reuse.
Moreover, we have to check that we can add the offset for
rel_base_reg_user, in case it is a mandatory allocated register. */
! if ((have_3addr_const_add[(int) mode]
! ? (num_regs > num_chains - (rel_base_reg_user != 0))
! : (2 * num_regs
! > ((2 * num_chains - num_linked - (rel_base_reg_user != 0))
! - (num_linked != 0))))
&& num_av_regs + (rel_base_reg_user != 0) >= num_chains - num_linked
&& rel_base_reg_user_offset >= add_limits[(int) mode][0]
&& rel_base_reg_user_offset <= add_limits[(int) mode][1])
*************** init_add_limits (void)
*** 2058,2076 ****
mode = GET_MODE_WIDER_MODE (mode))
{
rtx reg = gen_rtx_REG (mode, LAST_VIRTUAL_REGISTER+1);
int icode = (int) add_optab->handlers[(int) mode].insn_code;
HOST_WIDE_INT tmp;
rtx add = NULL, set = NULL;
int p, p_max;
add_limits[(int) mode][0] = 0;
add_limits[(int) mode][1] = 0;
if (icode == CODE_FOR_nothing
|| ! (*insn_data[icode].operand[0].predicate) (reg, mode)
! || ! (*insn_data[icode].operand[1].predicate) (reg, mode))
continue;
p_max = GET_MODE_BITSIZE (mode) - 1;
if (p_max > HOST_BITS_PER_WIDE_INT - 2)
--- 2065,2091 ----
mode = GET_MODE_WIDER_MODE (mode))
{
rtx reg = gen_rtx_REG (mode, LAST_VIRTUAL_REGISTER+1);
+ rtx reg2 = gen_rtx_REG (mode, LAST_VIRTUAL_REGISTER+2);
int icode = (int) add_optab->handlers[(int) mode].insn_code;
HOST_WIDE_INT tmp;
rtx add = NULL, set = NULL;
int p, p_max;
+ rtx tmp_add;
+ have_3addr_const_add[(int) mode] = 0;
add_limits[(int) mode][0] = 0;
add_limits[(int) mode][1] = 0;
if (icode == CODE_FOR_nothing
|| ! (*insn_data[icode].operand[0].predicate) (reg, mode)
! || ! (*insn_data[icode].operand[1].predicate) (reg, mode)
! || ! (*insn_data[icode].operand[2].predicate) (const1_rtx, mode))
continue;
+ tmp_add = GEN_FCN (icode) (reg, reg2, const1_rtx);
+ if (tmp_add != NULL_RTX && !NEXT_INSN (tmp_add))
+ have_3addr_const_add[(int) mode] = 1;
+
p_max = GET_MODE_BITSIZE (mode) - 1;
if (p_max > HOST_BITS_PER_WIDE_INT - 2)
*************** init_add_limits (void)
*** 2079,2085 ****
for (p = 1; p < p_max; p++)
{
rtx add_const = GEN_INT (((HOST_WIDE_INT) 1 << p) - 1);
- rtx tmp_add;
if (! (*insn_data[icode].operand[2].predicate) (add_const, mode))
break;
--- 2094,2099 ----