basic-block.h (update_br_prob_note): Declare.
authorJan Hubicka <jh@suse.cz>
Thu, 10 Jan 2002 20:37:43 +0000 (21:37 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Thu, 10 Jan 2002 20:37:43 +0000 (20:37 +0000)
* 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

gcc/ChangeLog
gcc/basic-block.h
gcc/cfgcleanup.c
gcc/cfglayout.c
gcc/cfgrtl.c
gcc/config/i386/i386.c
gcc/gcse.c
gcc/ifcvt.c

index 8935aff49311879a253a7143d6b712c796aee77a..ee9b1d2f6b9c4cc4619b38b9619df1fe7de320aa 100644 (file)
@@ -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.
index 338763f3b2cfd13244e81e15ce26149de026c2c4..29df84af3350496c5dd93c983dc511907c5b9aac 100644 (file)
@@ -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 */
 
index 0af87b4b3a48da6a5ecd3acd28cab165ed6a5669..5015c81494129bf133bd64bd2b8278bada628cdb 100644 (file)
@@ -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.  */
 
index ef5206bb69aa6a155c5e3e14b7bb3fbf779293f5..329e9f80b18cc738bcd6efc44c723b9da93ca218 100644 (file)
@@ -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;
                }
            }
index 56b3bf28e6a2473039bb18b837656a172da7e734..a4f25f8964cb584ec9e62027c3e9f7221a8d3e6d 100644 (file)
@@ -1510,6 +1510,19 @@ print_rtl_with_bb (outf, rtx_first)
     }
 }
 \f
+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);
+}
+\f
 /* 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.
index 91ccb8ce4005b2f4e6ce6af70da279a1e4188f95..4d047809f79f8a5038a93612303d3b5e66357e37 100644 (file)
@@ -4349,8 +4349,10 @@ ix86_expand_epilogue (style)
 }
 \f
 /* 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;
 }
 \f
 /* 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;
index e8361fc5aab6486341256af2c7fb1e6e0021f7d1..af3b29e4ca68ea89c89a98fc822ff55cc21d8105 100644 (file)
@@ -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
index f6a07e9667078ff54b667b9cec32389170f6fdf7..2939de4483e677f05a3719917712702f22f323ed 100644 (file)
@@ -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.  */