From: Roger Sayle Date: Sun, 11 Jul 2004 14:37:57 +0000 (+0000) Subject: rtlanal.c (insn_rtx_cost): New function, moved and renamed from combine.c's combine_i... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6fd21094e5a9d8517b00bffa08f132759baefbbc;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0eaf63705c2..d52f3517487 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,23 @@ +2004-07-11 Roger Sayle + + * 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 * rs6000.c (struct processor_costs): Change semantics of fields to diff --git a/gcc/combine.c b/gcc/combine.c index 97198b5df4f..1bdceb5ef9c 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -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)) { diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index 457fb37bdf0..ac478af71ba 100644 --- a/gcc/ifcvt.c +++ b/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. */ diff --git a/gcc/rtl.h b/gcc/rtl.h index f9495b53d23..bc87dd280e0 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -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 */ diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index b802e3f55d6..81d4f4024f5 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.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); +}