Hi,
this PR is about bug in my update to predict_paths_for_bb when handing abnormal 
edges.
Abnormal edges can not be predicted and thus the funcition is trying to predict 
paths
leading to the source BB of the edge instead. This however may lead to infinite 
loop
when two regions are mutually reachable by abnormals.

Bootstrapped/regtested x86_64-linux. Will commit it shortly.
My apologies for ignoring the PR for so long.

Honza

        PR middle-end/48600
        * predict.c (predict_paths_for_bb): Prevent looping.
        (predict_paths_leading_to_edge, predict_paths_leading_to): Update.
        * g++.dg/torture/pr48600.C: New testcase.
Index: gcc/testsuite/g++.dg/torture/pr48600.C
===================================================================
*** gcc/testsuite/g++.dg/torture/pr48600.C      (revision 0)
--- gcc/testsuite/g++.dg/torture/pr48600.C      (revision 0)
***************
*** 0 ****
--- 1,16 ----
+ /* { dg-do compile } */
+ 
+ class mx {
+ public:
+     mx();
+ };
+ 
+ int main()
+ {
+   while (true) {
+       mx *bar = new mx;
+       mx *baz = new mx;
+       continue;
+   }
+   return 0;
+ }
Index: gcc/predict.c
===================================================================
*** gcc/predict.c       (revision 184016)
--- gcc/predict.c       (working copy)
*************** tree_estimate_probability_driver (void)
*** 1827,1833 ****
  static void
  predict_paths_for_bb (basic_block cur, basic_block bb,
                      enum br_predictor pred,
!                     enum prediction taken)
  {
    edge e;
    edge_iterator ei;
--- 1827,1834 ----
  static void
  predict_paths_for_bb (basic_block cur, basic_block bb,
                      enum br_predictor pred,
!                     enum prediction taken,
!                     bitmap visited)
  {
    edge e;
    edge_iterator ei;
*************** predict_paths_for_bb (basic_block cur, b
*** 1848,1854 ****
        continue;
        gcc_assert (bb == cur || dominated_by_p (CDI_POST_DOMINATORS, cur, bb));
  
!       /* See if there is how many edge from e->src that is not abnormal
         and does not lead to BB.  */
        FOR_EACH_EDGE (e2, ei2, e->src->succs)
        if (e2 != e
--- 1849,1855 ----
        continue;
        gcc_assert (bb == cur || dominated_by_p (CDI_POST_DOMINATORS, cur, bb));
  
!       /* See if there is an edge from e->src that is not abnormal
         and does not lead to BB.  */
        FOR_EACH_EDGE (e2, ei2, e->src->succs)
        if (e2 != e
*************** predict_paths_for_bb (basic_block cur, b
*** 1861,1876 ****
  
        /* If there is non-abnormal path leaving e->src, predict edge
         using predictor.  Otherwise we need to look for paths
!        leading to e->src.  */
        if (found)
          predict_edge_def (e, pred, taken);
!       else
!       predict_paths_for_bb (e->src, e->src, pred, taken);
      }
    for (son = first_dom_son (CDI_POST_DOMINATORS, cur);
         son;
         son = next_dom_son (CDI_POST_DOMINATORS, son))
!     predict_paths_for_bb (son, bb, pred, taken);
  }
  
  /* Sets branch probabilities according to PREDiction and
--- 1862,1881 ----
  
        /* If there is non-abnormal path leaving e->src, predict edge
         using predictor.  Otherwise we need to look for paths
!        leading to e->src.
! 
!        The second may lead to infinite loop in the case we are predicitng
!        regions that are only reachable by abnormal edges.  We simply
!        prevent visiting given BB twice.  */
        if (found)
          predict_edge_def (e, pred, taken);
!       else if (!bitmap_set_bit (visited, e->src->index))
!       predict_paths_for_bb (e->src, e->src, pred, taken, visited);
      }
    for (son = first_dom_son (CDI_POST_DOMINATORS, cur);
         son;
         son = next_dom_son (CDI_POST_DOMINATORS, son))
!     predict_paths_for_bb (son, bb, pred, taken, visited);
  }
  
  /* Sets branch probabilities according to PREDiction and
*************** static void
*** 1880,1886 ****
  predict_paths_leading_to (basic_block bb, enum br_predictor pred,
                          enum prediction taken)
  {
!   predict_paths_for_bb (bb, bb, pred, taken);
  }
  
  /* Like predict_paths_leading_to but take edge instead of basic block.  */
--- 1885,1893 ----
  predict_paths_leading_to (basic_block bb, enum br_predictor pred,
                          enum prediction taken)
  {
!   bitmap visited = BITMAP_ALLOC (NULL);
!   predict_paths_for_bb (bb, bb, pred, taken, visited);
!   BITMAP_FREE (visited);
  }
  
  /* Like predict_paths_leading_to but take edge instead of basic block.  */
*************** predict_paths_leading_to_edge (edge e, e
*** 1903,1909 ****
        break;
        }
    if (!has_nonloop_edge)
!     predict_paths_for_bb (bb, bb, pred, taken);
    else
      predict_edge_def (e, pred, taken);
  }
--- 1910,1920 ----
        break;
        }
    if (!has_nonloop_edge)
!     {
!       bitmap visited = BITMAP_ALLOC (NULL);
!       predict_paths_for_bb (bb, bb, pred, taken, visited);
!       BITMAP_FREE (visited);
!     }
    else
      predict_edge_def (e, pred, taken);
  }
Index: libcpp/macro.c
===================================================================
*** libcpp/macro.c      (revision 184016)
--- libcpp/macro.c      (working copy)
*************** tokens_buff_last_token_ptr (_cpp_buff *b
*** 1878,1884 ****
     If VIRT_LOCS_BUFF is non-NULL,  it should point at the buffer
     containing the virtual locations of the tokens in TOKENS_BUFF; in
     which case the function updates that buffer as well.   */
! static inline void
  tokens_buff_remove_last_token (_cpp_buff *tokens_buff)
  
  {
--- 1878,1884 ----
     If VIRT_LOCS_BUFF is non-NULL,  it should point at the buffer
     containing the virtual locations of the tokens in TOKENS_BUFF; in
     which case the function updates that buffer as well.   */
! static void
  tokens_buff_remove_last_token (_cpp_buff *tokens_buff)
  
  {

Reply via email to