mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-06 02:20:34 +08:00
rtlanal.c (insn_rtx_cost): New function, moved and renamed from combine.c's combine_insn_cost.
* rtlanal.c (insn_rtx_cost): New function, moved and renamed from combine.c's combine_insn_cost. * rtl.h (insn_rtx_cost): Prototype here. * combine.c (combine_insn_cost): Delete function. (combine_validate_cost): Update callers of combine_insn_cost to call insn_rtx_cost instead. (combine_instructions): Likewise. Use NONJUMP_INSN_P to avoid requesting the rtx_cost of call and/or jump instructions. * ifcvt.c (total_bb_rtx_cost): Use insn_rtx_cost instead of calling rtx_cost directly. Don't request/use the cost of call or jump instructions. Return -1 if the cost of any instruction can't be determined (or the BB contains a function call). (find_if_case_1): Abort transformation if total_bb_rtx_cost returns -1 (i.e. can't determine the cost of any instruction or the basic block contains a subroutine call). (find_if_case_2): Likewise. From-SVN: r84513
This commit is contained in:
parent
06a67bdd66
commit
6fd21094e5
@ -1,3 +1,23 @@
|
||||
2004-07-11 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
* rtlanal.c (insn_rtx_cost): New function, moved and renamed from
|
||||
combine.c's combine_insn_cost.
|
||||
* rtl.h (insn_rtx_cost): Prototype here.
|
||||
* combine.c (combine_insn_cost): Delete function.
|
||||
(combine_validate_cost): Update callers of combine_insn_cost to
|
||||
call insn_rtx_cost instead.
|
||||
(combine_instructions): Likewise. Use NONJUMP_INSN_P to avoid
|
||||
requesting the rtx_cost of call and/or jump instructions.
|
||||
|
||||
* ifcvt.c (total_bb_rtx_cost): Use insn_rtx_cost instead of calling
|
||||
rtx_cost directly. Don't request/use the cost of call or jump
|
||||
instructions. Return -1 if the cost of any instruction can't be
|
||||
determined (or the BB contains a function call).
|
||||
(find_if_case_1): Abort transformation if total_bb_rtx_cost returns
|
||||
-1 (i.e. can't determine the cost of any instruction or the basic
|
||||
block contains a subroutine call).
|
||||
(find_if_case_2): Likewise.
|
||||
|
||||
2004-07-11 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
* rs6000.c (struct processor_costs): Change semantics of fields to
|
||||
|
@ -284,7 +284,7 @@ static basic_block this_basic_block;
|
||||
those blocks as starting points. */
|
||||
static sbitmap refresh_blocks;
|
||||
|
||||
/* The following array records the combine_insn_cost for every insn
|
||||
/* The following array records the insn_rtx_cost for every insn
|
||||
in the instruction stream. */
|
||||
|
||||
static int *uid_insn_cost;
|
||||
@ -515,44 +515,8 @@ do_SUBST_INT (int *into, int newval)
|
||||
|
||||
#define SUBST_INT(INTO, NEWVAL) do_SUBST_INT(&(INTO), (NEWVAL))
|
||||
|
||||
/* Calculate the rtx_cost of a single instruction. A return value of zero
|
||||
indicates an instruction without a known cost. */
|
||||
|
||||
static int
|
||||
combine_insn_cost (rtx pat)
|
||||
{
|
||||
int i, cost;
|
||||
rtx set;
|
||||
|
||||
/* Extract the single set rtx from the instruction pattern.
|
||||
We can't use single_set since we only have the pattern. */
|
||||
if (GET_CODE (pat) == SET)
|
||||
set = pat;
|
||||
else if (GET_CODE (pat) == PARALLEL)
|
||||
{
|
||||
set = NULL_RTX;
|
||||
for (i = 0; i < XVECLEN (pat, 0); i++)
|
||||
{
|
||||
rtx x = XVECEXP (pat, 0, i);
|
||||
if (GET_CODE (x) == SET)
|
||||
{
|
||||
if (set)
|
||||
return 0;
|
||||
set = x;
|
||||
}
|
||||
}
|
||||
if (!set)
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
|
||||
cost = rtx_cost (SET_SRC (set), SET);
|
||||
return cost > 0 ? cost : COSTS_N_INSNS (1);
|
||||
}
|
||||
|
||||
/* Subroutine of try_combine. Determine whether the combine replacement
|
||||
patterns NEWPAT and NEWI2PAT are cheaper according to combine_insn_cost
|
||||
patterns NEWPAT and NEWI2PAT are cheaper according to insn_rtx_cost
|
||||
that the original instruction sequence I1, I2 and I3. Note that I1
|
||||
and/or NEWI2PAT may be NULL_RTX. This function returns false, if the
|
||||
costs of all instructions can be estimated, and the replacements are
|
||||
@ -565,7 +529,7 @@ combine_validate_cost (rtx i1, rtx i2, rtx i3, rtx newpat, rtx newi2pat)
|
||||
int new_i2_cost, new_i3_cost;
|
||||
int old_cost, new_cost;
|
||||
|
||||
/* Lookup the original combine_insn_costs. */
|
||||
/* Lookup the original insn_rtx_costs. */
|
||||
i2_cost = INSN_UID (i2) <= last_insn_cost
|
||||
? uid_insn_cost[INSN_UID (i2)] : 0;
|
||||
i3_cost = INSN_UID (i3) <= last_insn_cost
|
||||
@ -584,11 +548,11 @@ combine_validate_cost (rtx i1, rtx i2, rtx i3, rtx newpat, rtx newi2pat)
|
||||
i1_cost = 0;
|
||||
}
|
||||
|
||||
/* Calculate the replacement combine_insn_costs. */
|
||||
new_i3_cost = combine_insn_cost (newpat);
|
||||
/* Calculate the replacement insn_rtx_costs. */
|
||||
new_i3_cost = insn_rtx_cost (newpat);
|
||||
if (newi2pat)
|
||||
{
|
||||
new_i2_cost = combine_insn_cost (newi2pat);
|
||||
new_i2_cost = insn_rtx_cost (newi2pat);
|
||||
new_cost = (new_i2_cost > 0 && new_i3_cost > 0)
|
||||
? new_i2_cost + new_i3_cost : 0;
|
||||
}
|
||||
@ -708,7 +672,7 @@ combine_instructions (rtx f, unsigned int nregs)
|
||||
refresh_blocks = sbitmap_alloc (last_basic_block);
|
||||
sbitmap_zero (refresh_blocks);
|
||||
|
||||
/* Allocate array of current combine_insn_costs. */
|
||||
/* Allocate array of current insn_rtx_costs. */
|
||||
uid_insn_cost = xcalloc (max_uid_cuid + 1, sizeof (int));
|
||||
last_insn_cost = max_uid_cuid;
|
||||
|
||||
@ -731,8 +695,9 @@ combine_instructions (rtx f, unsigned int nregs)
|
||||
NULL);
|
||||
#endif
|
||||
|
||||
/* Record the current combine_insn_cost of this instruction. */
|
||||
uid_insn_cost[INSN_UID (insn)] = combine_insn_cost (PATTERN (insn));
|
||||
/* Record the current insn_rtx_cost of this instruction. */
|
||||
if (NONJUMP_INSN_P (insn))
|
||||
uid_insn_cost[INSN_UID (insn)] = insn_rtx_cost (PATTERN (insn));
|
||||
if (dump_file)
|
||||
fprintf(dump_file, "insn_cost %d: %d\n",
|
||||
INSN_UID (insn), uid_insn_cost[INSN_UID (insn)]);
|
||||
@ -2655,7 +2620,7 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Only allow this combination if combine_insn_costs reports that the
|
||||
/* Only allow this combination if insn_rtx_costs reports that the
|
||||
replacement instructions are cheaper than the originals. */
|
||||
if (!combine_validate_cost (i1, i2, i3, newpat, newi2pat))
|
||||
{
|
||||
|
26
gcc/ifcvt.c
26
gcc/ifcvt.c
@ -161,7 +161,9 @@ count_bb_insns (basic_block bb)
|
||||
return count;
|
||||
}
|
||||
|
||||
/* Count the total rtx_cost of non-jump active insns in BB. */
|
||||
/* Count the total insn_rtx_cost of non-jump active insns in BB.
|
||||
This function returns -1, if the cost of any instruction could
|
||||
not be estimated. */
|
||||
|
||||
static int
|
||||
total_bb_rtx_cost (basic_block bb)
|
||||
@ -171,9 +173,16 @@ total_bb_rtx_cost (basic_block bb)
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == INSN)
|
||||
count += rtx_cost (PATTERN (insn), 0);
|
||||
|
||||
if (NONJUMP_INSN_P (insn))
|
||||
{
|
||||
int cost = insn_rtx_cost (PATTERN (insn));
|
||||
if (cost == 0)
|
||||
return -1;
|
||||
count += cost;
|
||||
}
|
||||
else if (CALL_P (insn))
|
||||
return -1;
|
||||
|
||||
if (insn == BB_END (bb))
|
||||
break;
|
||||
insn = NEXT_INSN (insn);
|
||||
@ -2867,7 +2876,7 @@ find_if_case_1 (basic_block test_bb, edge then_edge, edge else_edge)
|
||||
basic_block then_bb = then_edge->dest;
|
||||
basic_block else_bb = else_edge->dest, new_bb;
|
||||
edge then_succ = then_bb->succ;
|
||||
int then_bb_index;
|
||||
int then_bb_index, bb_cost;
|
||||
|
||||
/* If we are partitioning hot/cold basic blocks, we don't want to
|
||||
mess up unconditional or indirect jumps that cross between hot
|
||||
@ -2904,7 +2913,8 @@ find_if_case_1 (basic_block test_bb, edge then_edge, edge else_edge)
|
||||
test_bb->index, then_bb->index);
|
||||
|
||||
/* THEN is small. */
|
||||
if (total_bb_rtx_cost (then_bb) >= COSTS_N_INSNS (BRANCH_COST))
|
||||
bb_cost = total_bb_rtx_cost (then_bb);
|
||||
if (bb_cost < 0 || bb_cost >= COSTS_N_INSNS (BRANCH_COST))
|
||||
return FALSE;
|
||||
|
||||
/* Registers set are dead, or are predicable. */
|
||||
@ -2947,6 +2957,7 @@ find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge)
|
||||
basic_block then_bb = then_edge->dest;
|
||||
basic_block else_bb = else_edge->dest;
|
||||
edge else_succ = else_bb->succ;
|
||||
int bb_cost;
|
||||
rtx note;
|
||||
|
||||
/* If we are partitioning hot/cold basic blocks, we don't want to
|
||||
@ -2995,7 +3006,8 @@ find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge)
|
||||
test_bb->index, else_bb->index);
|
||||
|
||||
/* ELSE is small. */
|
||||
if (total_bb_rtx_cost (else_bb) >= COSTS_N_INSNS (BRANCH_COST))
|
||||
bb_cost = total_bb_rtx_cost (else_bb);
|
||||
if (bb_cost < 0 || bb_cost >= COSTS_N_INSNS (BRANCH_COST))
|
||||
return FALSE;
|
||||
|
||||
/* Registers set are dead, or are predicable. */
|
||||
|
@ -1879,6 +1879,7 @@ extern int loc_mentioned_in_p (rtx *, rtx);
|
||||
extern rtx find_first_parameter_load (rtx, rtx);
|
||||
extern bool keep_with_call_p (rtx);
|
||||
extern bool label_is_jump_target_p (rtx, rtx);
|
||||
extern int insn_rtx_cost (rtx);
|
||||
|
||||
/* flow.c */
|
||||
|
||||
|
@ -4785,3 +4785,39 @@ num_sign_bit_copies1 (rtx x, enum machine_mode mode, rtx known_x,
|
||||
return nonzero & ((HOST_WIDE_INT) 1 << (bitwidth - 1))
|
||||
? 1 : bitwidth - floor_log2 (nonzero) - 1;
|
||||
}
|
||||
|
||||
/* Calculate the rtx_cost of a single instruction. A return value of
|
||||
zero indicates an instruction pattern without a known cost. */
|
||||
|
||||
int
|
||||
insn_rtx_cost (rtx pat)
|
||||
{
|
||||
int i, cost;
|
||||
rtx set;
|
||||
|
||||
/* Extract the single set rtx from the instruction pattern.
|
||||
We can't use single_set since we only have the pattern. */
|
||||
if (GET_CODE (pat) == SET)
|
||||
set = pat;
|
||||
else if (GET_CODE (pat) == PARALLEL)
|
||||
{
|
||||
set = NULL_RTX;
|
||||
for (i = 0; i < XVECLEN (pat, 0); i++)
|
||||
{
|
||||
rtx x = XVECEXP (pat, 0, i);
|
||||
if (GET_CODE (x) == SET)
|
||||
{
|
||||
if (set)
|
||||
return 0;
|
||||
set = x;
|
||||
}
|
||||
}
|
||||
if (!set)
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
|
||||
cost = rtx_cost (SET_SRC (set), SET);
|
||||
return cost > 0 ? cost : COSTS_N_INSNS (1);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user