This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
ifcvt conditional execution and rtx_cost
- From: David Edelsohn <dje at watson dot ibm dot com>
- To: Roger Sayle <roger at eyesopen dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Tue, 06 Jul 2004 15:11:31 -0400
- Subject: ifcvt conditional execution and rtx_cost
Roger,
With all of your recent rtx_cost changes and your patch for
ifcvt.c, I would like to get your opinion on the appended ifcvt.c patch.
ifcvt.c's current analysis for conditional execution tests the number of
instructions, not the cost of the instructions. I have a patch that
converts to use rtx_cost(). The patch corrects a performance regression
that was discovered with Apple's Skidmarks benchmark. The patch already
was approved by Richard Henderson, but I could not find other instances
where it provided a benefit. Do you think the patch could be more useful
now?
Thanks, David
Index: ifcvt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ifcvt.c,v
retrieving revision 1.153
diff -c -p -r1.153 ifcvt.c
*** ifcvt.c 4 Jul 2004 14:57:34 -0000 1.153
--- ifcvt.c 6 Jul 2004 18:52:00 -0000
*************** mark_loop_exit_edges (void)
*** 139,145 ****
flow_loops_free (&loops);
}
! /* Count the number of non-jump active insns in BB. */
static int
count_bb_insns (basic_block bb)
--- 139,145 ----
flow_loops_free (&loops);
}
! /* Count the total rtx_cost of non-jump active insns in BB. */
static int
count_bb_insns (basic_block bb)
*************** count_bb_insns (basic_block bb)
*** 150,156 ****
while (1)
{
if (GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == INSN)
! count++;
if (insn == BB_END (bb))
break;
--- 150,156 ----
while (1)
{
if (GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == INSN)
! count += rtx_cost (PATTERN (insn), 0);
if (insn == BB_END (bb))
break;
*************** cond_exec_process_if_block (ce_if_block_
*** 398,408 ****
/* Collect the bounds of where we're to search, skipping any labels, jumps
and notes at the beginning and end of the block. Then count the total
! number of insns and see if it is small enough to convert. */
then_start = first_active_insn (then_bb);
then_end = last_active_insn (then_bb, TRUE);
n_insns = ce_info->num_then_insns = count_bb_insns (then_bb);
! max = MAX_CONDITIONAL_EXECUTE;
if (else_bb)
{
--- 398,409 ----
/* Collect the bounds of where we're to search, skipping any labels, jumps
and notes at the beginning and end of the block. Then count the total
! number of insns and see if it is small enough to convert. Scale
! MAX_CONDITIONAL_EXECUTE by COSTS_N_INSNS to compare with rtx_cost. */
then_start = first_active_insn (then_bb);
then_end = last_active_insn (then_bb, TRUE);
n_insns = ce_info->num_then_insns = count_bb_insns (then_bb);
! max = COSTS_N_INSNS (MAX_CONDITIONAL_EXECUTE);
if (else_bb)
{
*************** find_if_header (basic_block test_bb, int
*** 2339,2346 ****
/* Return true if a block has two edges, one of which falls through to the next
block, and the other jumps to a specific block, so that we can tell if the
! block is part of an && test or an || test. Returns either -1 or the number
! of non-note, non-jump, non-USE/CLOBBER insns in the block. */
static int
block_jumps_and_fallthru_p (basic_block cur_bb, basic_block target_bb)
--- 2340,2347 ----
/* Return true if a block has two edges, one of which falls through to the next
block, and the other jumps to a specific block, so that we can tell if the
! block is part of an && test or an || test. Returns either -1 or the total
! rtx_cost of non-note, non-jump, non-USE/CLOBBER insns in the block. */
static int
block_jumps_and_fallthru_p (basic_block cur_bb, basic_block target_bb)
*************** block_jumps_and_fallthru_p (basic_block
*** 2396,2402 ****
&& GET_CODE (insn) != JUMP_INSN
&& GET_CODE (PATTERN (insn)) != USE
&& GET_CODE (PATTERN (insn)) != CLOBBER)
! n_insns++;
if (insn == end)
break;
--- 2397,2403 ----
&& GET_CODE (insn) != JUMP_INSN
&& GET_CODE (PATTERN (insn)) != USE
&& GET_CODE (PATTERN (insn)) != CLOBBER)
! n_insns += rtx_cost (PATTERN (insn), 0);
if (insn == end)
break;
*************** find_if_block (struct ce_if_block * ce_i
*** 2437,2443 ****
{
basic_block bb = test_bb->pred->src;
basic_block target_bb;
! int max_insns = MAX_CONDITIONAL_EXECUTE;
int n_insns;
/* Determine if the preceding block is an && or || block. */
--- 2438,2444 ----
{
basic_block bb = test_bb->pred->src;
basic_block target_bb;
! int max_insns = COSTS_N_INSNS (MAX_CONDITIONAL_EXECUTE);
int n_insns;
/* Determine if the preceding block is an && or || block. */
*************** find_if_case_1 (basic_block test_bb, edg
*** 2877,2883 ****
test_bb->index, then_bb->index);
/* THEN is small. */
! if (count_bb_insns (then_bb) > BRANCH_COST)
return FALSE;
/* Registers set are dead, or are predicable. */
--- 2878,2884 ----
test_bb->index, then_bb->index);
/* THEN is small. */
! if (count_bb_insns (then_bb) >= COSTS_N_INSNS (MAX_CONDITIONAL_EXECUTE))
return FALSE;
/* Registers set are dead, or are predicable. */
*************** find_if_case_2 (basic_block test_bb, edg
*** 2968,2974 ****
test_bb->index, else_bb->index);
/* ELSE is small. */
! if (count_bb_insns (else_bb) > BRANCH_COST)
return FALSE;
/* Registers set are dead, or are predicable. */
--- 2969,2975 ----
test_bb->index, else_bb->index);
/* ELSE is small. */
! if (count_bb_insns (else_bb) >= COSTS_N_INSNS (MAX_CONDITIONAL_EXECUTE))
return FALSE;
/* Registers set are dead, or are predicable. */