diff options
author | Jan Hubicka <jh@suse.cz> | 2002-01-10 21:37:43 +0100 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2002-01-10 20:37:43 +0000 |
commit | b446e5a266b232e701fd4a9a7bd48f0aab8fc2c5 (patch) | |
tree | 19471938dee687744538e8ca3cc2eb35fdb507c2 /gcc | |
parent | a01da83b2291abdccd8abe66eff604c50e3c71f0 (diff) | |
download | gcc-b446e5a266b232e701fd4a9a7bd48f0aab8fc2c5.zip gcc-b446e5a266b232e701fd4a9a7bd48f0aab8fc2c5.tar.gz gcc-b446e5a266b232e701fd4a9a7bd48f0aab8fc2c5.tar.bz2 |
basic-block.h (update_br_prob_note): Declare.
* basic-block.h (update_br_prob_note): Declare.
* cfgcleanup.c (try_simplify_condjump): Call update_br_prob_note.
(try_forward_edges): Care negative frequencies and update note.
(outgoing_edges_match): Tweek conditional merging heuristics.
(try_crossjump_to_edge): use update_br_prob_note.
* cfglayout.c (fixup_reorder_chain): Likewise.
* cfrtl.c (update_br_prob_note): New.
* ifcvt.c (dead_or_predicable): Call update_br_prob_note.
* i386.c (ix86_decompose_address): Return -1 if address contains
shift.
(legitimate_address_p): Require ix86_decompose_address to return 1.
* gcse.c (hash_scan_set): Use CONSTANT_INSN_P.
(cprop_insn): Likewise.
From-SVN: r48750
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 18 | ||||
-rw-r--r-- | gcc/basic-block.h | 1 | ||||
-rw-r--r-- | gcc/cfgcleanup.c | 68 | ||||
-rw-r--r-- | gcc/cfglayout.c | 2 | ||||
-rw-r--r-- | gcc/cfgrtl.c | 13 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 20 | ||||
-rw-r--r-- | gcc/gcse.c | 7 | ||||
-rw-r--r-- | gcc/ifcvt.c | 1 |
8 files changed, 89 insertions, 41 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8935aff..ee9b1d2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +Thu Jan 10 22:35:54 CET 2002 Jan Hubicka <jh@suse.cz> + + * basic-block.h (update_br_prob_note): Declare. + * cfgcleanup.c (try_simplify_condjump): Call update_br_prob_note. + (try_forward_edges): Care negative frequencies and update note. + (outgoing_edges_match): Tweek conditional merging heuristics. + (try_crossjump_to_edge): use update_br_prob_note. + * cfglayout.c (fixup_reorder_chain): Likewise. + * cfrtl.c (update_br_prob_note): New. + * ifcvt.c (dead_or_predicable): Call update_br_prob_note. + + * i386.c (ix86_decompose_address): Return -1 if address contains + shift. + (legitimate_address_p): Require ix86_decompose_address to return 1. + + * gcse.c (hash_scan_set): Use CONSTANT_INSN_P. + (cprop_insn): Likewise. + 2002-01-10 Kazu Hirata <kazu@hxi.com> * toplev.c: Fix formatting. diff --git a/gcc/basic-block.h b/gcc/basic-block.h index 338763f..29df84a 100644 --- a/gcc/basic-block.h +++ b/gcc/basic-block.h @@ -687,6 +687,7 @@ extern conflict_graph conflict_graph_compute PARAMS ((regset, partition)); extern bool mark_dfs_back_edges PARAMS ((void)); +extern void update_br_prob_note PARAMS ((basic_block)); /* In dominance.c */ diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c index 0af87b4..5015c81 100644 --- a/gcc/cfgcleanup.c +++ b/gcc/cfgcleanup.c @@ -177,6 +177,7 @@ try_simplify_condjump (cbranch_block) jump_dest_block); cbranch_jump_edge->flags |= EDGE_FALLTHRU; cbranch_fallthru_edge->flags &= ~EDGE_FALLTHRU; + update_br_prob_note (cbranch_block); /* Delete the block with the unconditional jump, and clean up the mess. */ flow_delete_block (jump_block); @@ -521,7 +522,11 @@ try_forward_edges (mode, b) edge t; first->count -= edge_count; + if (first->count < 0) + first->count = 0; first->frequency -= edge_frequency; + if (first->frequency < 0) + first->frequency = 0; if (first->succ->succ_next) { edge e; @@ -535,9 +540,11 @@ try_forward_edges (mode, b) prob = edge_frequency * REG_BR_PROB_BASE / first->frequency; else prob = 0; + if (prob > t->probability) + prob = t->probability; t->probability -= prob; prob = REG_BR_PROB_BASE - prob; - if (prob == 0) + if (prob <= 0) { first->succ->probability = REG_BR_PROB_BASE; first->succ->succ_next->probability = 0; @@ -546,6 +553,7 @@ try_forward_edges (mode, b) for (e = first->succ; e; e = e->succ_next) e->probability = ((e->probability * REG_BR_PROB_BASE) / (double) prob); + update_br_prob_note (first); } else { @@ -558,8 +566,10 @@ try_forward_edges (mode, b) n++; t = first->succ; } - t->count -= edge_count; + t->count -= edge_count; + if (t->count < 0) + t->count = 0; first = t->dest; } while (first != target); @@ -745,6 +755,7 @@ merge_blocks (e, b, c, mode) /* If B has a fallthru edge to C, no need to move anything. */ if (e->flags & EDGE_FALLTHRU) { + int b_index = b->index, c_index = c->index; /* We need to update liveness in case C already has broken liveness or B ends by conditional jump to next instructions that will be removed. */ @@ -756,7 +767,7 @@ merge_blocks (e, b, c, mode) if (rtl_dump_file) fprintf (rtl_dump_file, "Merged %d and %d without moving.\n", - b->index, c->index); + b_index, c_index); return true; } @@ -1147,32 +1158,30 @@ outgoing_edges_match (mode, bb1, bb2) we will only have one branch prediction bit to work with. Thus we require the existing branches to have probabilities that are roughly similar. */ - /* ??? We should use bb->frequency to allow merging in infrequently - executed blocks, but at the moment it is not available when - cleanup_cfg is run. */ - if (match && !optimize_size) + if (match + && !optimize_size + && bb1->frequency > BB_FREQ_MAX / 1000 + && bb2->frequency > BB_FREQ_MAX / 1000) { - rtx note1, note2; - int prob1, prob2; + int prob2; - note1 = find_reg_note (bb1->end, REG_BR_PROB, 0); - note2 = find_reg_note (bb2->end, REG_BR_PROB, 0); + if (b1->dest == b2->dest) + prob2 = b2->probability; + else + /* Do not use f2 probability as f2 may be forwarded. */ + prob2 = REG_BR_PROB_BASE - b2->probability; - if (note1 && note2) + /* Fail if the difference in probabilities is + greater than 5%. */ + if (abs (b1->probability - prob2) > REG_BR_PROB_BASE / 20) { - prob1 = INTVAL (XEXP (note1, 0)); - prob2 = INTVAL (XEXP (note2, 0)); - if (reverse) - prob2 = REG_BR_PROB_BASE - prob2; - - /* Fail if the difference in probabilities is - greater than 5%. */ - if (abs (prob1 - prob2) > REG_BR_PROB_BASE / 20) - return false; - } + if (rtl_dump_file) + fprintf (rtl_dump_file, + "Outcomes of branch in bb %i and %i differs to much (%i %i)\n", + bb1->index, bb2->index, b1->probability, prob2); - else if (note1 || note2) - return false; + return false; + } } if (rtl_dump_file && match) @@ -1259,7 +1268,6 @@ try_crossjump_to_edge (mode, e1, e2) edge s; rtx last; rtx label; - rtx note; /* Search backward through forwarder blocks. We don't need to worry about multiple entry or chained forwarders, as they will be optimized @@ -1356,8 +1364,14 @@ try_crossjump_to_edge (mode, e1, e2) if (FORWARDER_BLOCK_P (s2->dest)) { s2->dest->succ->count -= s2->count; + if (s2->dest->succ->count < 0) + s2->dest->succ->count = 0; s2->dest->count -= s2->count; s2->dest->frequency -= EDGE_FREQUENCY (s); + if (s2->dest->frequency < 0) + s2->dest->frequency = 0; + if (s2->dest->count < 0) + s2->dest->count = 0; } if (!redirect_to->frequency && !src1->frequency) @@ -1369,9 +1383,7 @@ try_crossjump_to_edge (mode, e1, e2) / (redirect_to->frequency + src1->frequency)); } - note = find_reg_note (redirect_to->end, REG_BR_PROB, 0); - if (note) - XEXP (note, 0) = GEN_INT (BRANCH_EDGE (redirect_to)->probability); + update_br_prob_note (redirect_to); /* Edit SRC1 to go to REDIRECT_TO at NEWPOS1. */ diff --git a/gcc/cfglayout.c b/gcc/cfglayout.c index ef5206b..329e9f8 100644 --- a/gcc/cfglayout.c +++ b/gcc/cfglayout.c @@ -412,6 +412,7 @@ fixup_reorder_chain () { e_fall->flags &= ~EDGE_FALLTHRU; e_taken->flags |= EDGE_FALLTHRU; + update_br_prob_note (bb); e = e_fall, e_fall = e_taken, e_taken = e; } } @@ -423,6 +424,7 @@ fixup_reorder_chain () { e_fall->flags &= ~EDGE_FALLTHRU; e_taken->flags |= EDGE_FALLTHRU; + update_br_prob_note (bb); continue; } } diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index 56b3bf2..a4f25f8 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -1510,6 +1510,19 @@ print_rtl_with_bb (outf, rtx_first) } } +void +update_br_prob_note (bb) + basic_block bb; +{ + rtx note; + if (GET_CODE (bb->end) != JUMP_INSN) + return; + note = find_reg_note (bb->end, REG_BR_PROB, NULL_RTX); + if (!note || INTVAL (XEXP (note, 0)) == BRANCH_EDGE (bb)->probability) + return; + XEXP (note, 0) = GEN_INT (BRANCH_EDGE (bb)->probability); +} + /* Verify the CFG consistency. This function check some CFG invariants and aborts when something is wrong. Hope that this function will help to convert many optimization passes to preserve CFG consistent. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 91ccb8c..4d04780 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -4349,8 +4349,10 @@ ix86_expand_epilogue (style) } /* Extract the parts of an RTL expression that is a valid memory address - for an instruction. Return false if the structure of the address is - grossly off. */ + for an instruction. Return 0 if the structure of the address is + grossly off. Return -1 if the address contains ASHIFT, so it is not + strictly valid, but still used for computing length of lea instruction. + */ static int ix86_decompose_address (addr, out) @@ -4362,6 +4364,7 @@ ix86_decompose_address (addr, out) rtx disp = NULL_RTX; HOST_WIDE_INT scale = 1; rtx scale_rtx = NULL_RTX; + int retval = 1; if (GET_CODE (addr) == REG || GET_CODE (addr) == SUBREG) base = addr; @@ -4402,7 +4405,7 @@ ix86_decompose_address (addr, out) disp = op1; } else - return FALSE; + return 0; } else if (GET_CODE (addr) == MULT) { @@ -4417,11 +4420,12 @@ ix86_decompose_address (addr, out) index = XEXP (addr, 0); tmp = XEXP (addr, 1); if (GET_CODE (tmp) != CONST_INT) - return FALSE; + return 0; scale = INTVAL (tmp); if ((unsigned HOST_WIDE_INT) scale > 3) - return FALSE; + return 0; scale = 1 << scale; + retval = -1; } else disp = addr; /* displacement */ @@ -4430,7 +4434,7 @@ ix86_decompose_address (addr, out) if (scale_rtx) { if (GET_CODE (scale_rtx) != CONST_INT) - return FALSE; + return 0; scale = INTVAL (scale_rtx); } @@ -4471,7 +4475,7 @@ ix86_decompose_address (addr, out) out->disp = disp; out->scale = scale; - return TRUE; + return retval; } /* Return cost of the memory address x. @@ -4684,7 +4688,7 @@ legitimate_address_p (mode, addr, strict) debug_rtx (addr); } - if (! ix86_decompose_address (addr, &parts)) + if (ix86_decompose_address (addr, &parts) <= 0) { reason = "decomposition failed"; goto report_error; @@ -2204,9 +2204,7 @@ hash_scan_set (pat, insn, set_p) && REGNO (src) >= FIRST_PSEUDO_REGISTER && can_copy_p [GET_MODE (dest)] && REGNO (src) != regno) - || GET_CODE (src) == CONST_INT - || GET_CODE (src) == SYMBOL_REF - || GET_CODE (src) == CONST_DOUBLE) + || CONSTANT_P (src)) /* A copy is not available if its src or dest is subsequently modified. Here we want to search from INSN+1 on, but oprs_available_p searches from INSN on. */ @@ -4155,8 +4153,7 @@ cprop_insn (bb, insn, alter_jumps) src = SET_SRC (pat); /* Constant propagation. */ - if (GET_CODE (src) == CONST_INT || GET_CODE (src) == CONST_DOUBLE - || GET_CODE (src) == SYMBOL_REF) + if (CONSTANT_P (src)) { /* Handle normal insns first. */ if (GET_CODE (insn) == INSN diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index f6a07e9..2939de4 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -2657,6 +2657,7 @@ dead_or_predicable (test_bb, merge_bb, other_bb, new_dest, reversep) probability = BRANCH_EDGE (test_bb)->probability; BRANCH_EDGE (test_bb)->probability = FALLTHRU_EDGE (test_bb)->probability; FALLTHRU_EDGE (test_bb)->probability = probability; + update_br_prob_note (test_bb); } /* Move the insns out of MERGE_BB to before the branch. */ |