diff options
author | Richard Biener <rguenther@suse.de> | 2013-03-21 13:53:01 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2013-03-21 13:53:01 +0000 |
commit | 5a2d2a7900124db247d16cae7a751f4b1f19bce4 (patch) | |
tree | e46c2b911cdc5c3e939dcb2d7dd0b392250ee11c /gcc/tree-ssa-loop-im.c | |
parent | 5abe1e053f1b9a685aa6f5505db367f2cad790d0 (diff) | |
download | gcc-5a2d2a7900124db247d16cae7a751f4b1f19bce4.zip gcc-5a2d2a7900124db247d16cae7a751f4b1f19bce4.tar.gz gcc-5a2d2a7900124db247d16cae7a751f4b1f19bce4.tar.bz2 |
re PR middle-end/39326 (Segmentation fault with -O1, out of memory with -O2)
2013-03-21 Richard Biener <rguenther@suse.de>
PR tree-optimization/39326
* tree-ssa-loop-im.c (bb_loop_postorder): New global static.
(sort_bbs_in_loop_postorder_cmp): New function.
(gather_mem_refs_in_loops): Assign mem-ref IDs in loop
postorder.
From-SVN: r196874
Diffstat (limited to 'gcc/tree-ssa-loop-im.c')
-rw-r--r-- | gcc/tree-ssa-loop-im.c | 47 |
1 files changed, 41 insertions, 6 deletions
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c index 2557542..0945d26 100644 --- a/gcc/tree-ssa-loop-im.c +++ b/gcc/tree-ssa-loop-im.c @@ -1622,27 +1622,62 @@ gather_mem_refs_stmt (struct loop *loop, gimple stmt) return; } +static unsigned *bb_loop_postorder; + +/* qsort sort function to sort blocks after their loop fathers postorder. */ + +static int +sort_bbs_in_loop_postorder_cmp (const void *bb1_, const void *bb2_) +{ + basic_block bb1 = *(basic_block *)const_cast<void *>(bb1_); + basic_block bb2 = *(basic_block *)const_cast<void *>(bb2_); + struct loop *loop1 = bb1->loop_father; + struct loop *loop2 = bb2->loop_father; + if (loop1->num == loop2->num) + return 0; + return bb_loop_postorder[loop1->num] < bb_loop_postorder[loop2->num] ? -1 : 1; +} + /* Gathers memory references in loops. */ static void gather_mem_refs_in_loops (void) { gimple_stmt_iterator bsi; - basic_block bb; + basic_block bb, *bbs; struct loop *loop; loop_iterator li; bitmap lrefs, alrefs, alrefso; + unsigned i, n; + /* Initialize bb_loop_postorder with a mapping from loop->num to + its postorder index. */ + i = 0; + bb_loop_postorder = XNEWVEC (unsigned, number_of_loops ()); + FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST) + bb_loop_postorder[loop->num] = i++; + /* Collect all basic-blocks in loops and sort them after their + loops postorder. */ + i = 0; + bbs = XNEWVEC (basic_block, n_basic_blocks - NUM_FIXED_BLOCKS); FOR_EACH_BB (bb) + if (bb->loop_father != current_loops->tree_root) + bbs[i++] = bb; + n = i; + qsort (bbs, n, sizeof (basic_block), sort_bbs_in_loop_postorder_cmp); + free (bb_loop_postorder); + + /* Visit blocks in loop postorder and assign mem-ref IDs in that order. + That results in better locality for all the bitmaps. */ + for (i = 0; i < n; ++i) { - loop = bb->loop_father; - if (loop == current_loops->tree_root) - continue; - + basic_block bb = bbs[i]; for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi)) - gather_mem_refs_stmt (loop, gsi_stmt (bsi)); + gather_mem_refs_stmt (bb->loop_father, gsi_stmt (bsi)); } + free (bbs); + /* Propagate the information about accessed memory references up the loop hierarchy. */ FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST) |