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) {