diff options
-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 8935aff4931..ee9b1d2f6b9 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 338763f3b2c..29df84af335 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 0af87b4b3a4..5015c814941 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 ef5206bb69a..329e9f80b18 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 56b3bf28e6a..a4f25f8964c 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 91ccb8ce400..4d047809f79 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; diff --git a/gcc/gcse.c b/gcc/gcse.c index e8361fc5aab..af3b29e4ca6 100644 --- a/gcc/gcse.c +++ b/gcc/gcse.c @@ -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 f6a07e96670..2939de4483e 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. */ |