+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
those blocks as starting points. */
static sbitmap refresh_blocks;
\f
-/* 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;
#define SUBST_INT(INTO, NEWVAL) do_SUBST_INT(&(INTO), (NEWVAL))
\f
-/* 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
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
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;
}
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;
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)]);
}
#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))
{
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)
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);
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
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. */
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
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. */
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 */
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);
+}