]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR rtl-optimization/10056 ([HP-PA] ICE at -O2 when building c++ code from doxygen)
authorJan Hubicka <jh@suse.cz>
Tue, 25 Mar 2003 19:20:34 +0000 (20:20 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Tue, 25 Mar 2003 19:20:34 +0000 (19:20 +0000)
PR opt/10056
* cfglayout.c (fixup_reorder_chain):  Fix dealing with the conditional
jump jumping to the next instruction.
* cfgrtl.c (force_nonfallthru_and_redirect):  Likewise.

From-SVN: r64854

gcc/ChangeLog
gcc/cfglayout.c
gcc/cfgrtl.c

index 2e6bc1cf3041af4c078126e594cb05980984dcf1..ff7624a8ec67f4f174b3686322a76be53e52e69e 100644 (file)
@@ -1,3 +1,10 @@
+Mon Mar 24 20:03:03 CET 2003  Jan Hubicka  <jh@suse.cz>
+
+       PR opt/10056
+       * cfglayout.c (fixup_reorder_chain):  Fix dealing with the conditional
+       jump jumping to the next instruction.
+       * cfgrtl.c (force_nonfallthru_and_redirect):  Likewise.
+
 2003-03-25  Gerald Pfeifer  <pfeifer@dbai.tuwien.ac.at>
 
        * doc/passes.texi (Passes): Properly document that we do not
index 1f4f8fc5b9f2cb0eaa10644f2f2975cef1fbf047..c95ac3845356e6b7b3b921581b1caf24a05d378d 100644 (file)
@@ -465,11 +465,43 @@ fixup_reorder_chain ()
                      && e_fall->dest == EXIT_BLOCK_PTR))
                continue;
 
+             /* The degenerated case of conditional jump jumping to the next
+                instruction can happen on target having jumps with side
+                effects.  
+
+                Create temporarily the duplicated edge representing branch.
+                It will get unidentified by force_nonfallthru_and_redirect
+                that would otherwise get confused by fallthru edge not pointing
+                to the next basic block.  */
+             if (!e_taken)
+               {
+                 rtx note;
+                 edge e_fake;
+
+                 e_fake = unchecked_make_edge (bb, e_fall->dest, 0);
+
+                 if (!redirect_jump (bb->end, block_label (bb), 0))
+                   abort ();
+                 note = find_reg_note (bb->end, REG_BR_PROB, NULL_RTX);
+                 if (note)
+                   {
+                     int prob = INTVAL (XEXP (note, 0));
+
+                     e_fake->probability = prob;
+                     e_fake->count = e_fall->count * prob / REG_BR_PROB_BASE;
+                     e_fall->probability -= e_fall->probability;
+                     e_fall->count -= e_fake->count;
+                     if (e_fall->probability < 0)
+                       e_fall->probability = 0;
+                     if (e_fall->count < 0)
+                       e_fall->count = 0;
+                   }
+               }
              /* There is one special case: if *neither* block is next,
                 such as happens at the very end of a function, then we'll
                 need to add a new unconditional jump.  Choose the taken
                 edge based on known or assumed probability.  */
-             if (RBI (bb)->next != e_taken->dest)
+             else if (RBI (bb)->next != e_taken->dest)
                {
                  rtx note = find_reg_note (bb_end_insn, REG_BR_PROB, 0);
 
index 01b7e92c2cb08fc6e1a02b034dc64541546d483a..5e47236b4cea58448478ec2ed245f0ae2d4c477c 100644 (file)
@@ -78,7 +78,7 @@ static void commit_one_edge_insertion PARAMS ((edge, int));
 static bool try_redirect_by_replacing_jump PARAMS ((edge, basic_block));
 static rtx last_loop_beg_note          PARAMS ((rtx));
 static bool back_edge_of_syntactic_loop_p PARAMS ((basic_block, basic_block));
-static basic_block force_nonfallthru_and_redirect PARAMS ((edge, basic_block));
+basic_block force_nonfallthru_and_redirect PARAMS ((edge, basic_block));
 \f
 /* Return true if NOTE is not one of the ones that must be kept paired,
    so that we may simply delete it.  */
@@ -930,7 +930,7 @@ redirect_edge_and_branch (e, target)
 /* Like force_nonfallthru below, but additionally performs redirection
    Used by redirect_edge_and_branch_force.  */
 
-static basic_block
+basic_block
 force_nonfallthru_and_redirect (e, target)
      edge e;
      basic_block target;
@@ -940,6 +940,34 @@ force_nonfallthru_and_redirect (e, target)
   edge new_edge;
   int abnormal_edge_flags = 0;
 
+  /* In the case the last instruction is conditional jump to the next
+     instruction, first redirect the jump itself and then continue
+     by creating an basic block afterwards to redirect fallthru edge.  */
+  if (e->src != ENTRY_BLOCK_PTR && e->dest != EXIT_BLOCK_PTR
+      && any_condjump_p (e->src->end)
+      && JUMP_LABEL (e->src->end) == e->dest->head)
+    {
+      rtx note;
+      edge b = make_edge (e->src, target, 0);
+
+      if (!redirect_jump (e->src->end, block_label (target), 0))
+       abort ();
+      note = find_reg_note (e->src->end, REG_BR_PROB, NULL_RTX);
+      if (note)
+       {
+         int prob = INTVAL (XEXP (note, 0));
+
+         b->probability = prob;
+         b->count = e->count * prob / REG_BR_PROB_BASE;
+         e->probability -= e->probability;
+         e->count -= b->count;
+         if (e->probability < 0)
+           e->probability = 0;
+         if (e->count < 0)
+           e->count = 0;
+       }
+    }
+
   if (e->flags & EDGE_ABNORMAL)
     {
       /* Irritating special case - fallthru edge to the same block as abnormal