- unsigned bb_index;
- VEC(int,heap) *work_stack;
- bitmap phi_insertion_points;
-
- work_stack = VEC_alloc (int, heap, n_basic_blocks);
- phi_insertion_points = BITMAP_ALLOC (NULL);
-
- /* Seed the work list with all the blocks in DEF_BLOCKS. */
- EXECUTE_IF_SET_IN_BITMAP (def_blocks, 0, bb_index, bi)
- /* We use VEC_quick_push here for speed. This is safe because we
- know that the number of definition blocks is no greater than
- the number of basic blocks, which is the initial capacity of
- WORK_STACK. */
- VEC_quick_push (int, work_stack, bb_index);
-
- /* Pop a block off the worklist, add every block that appears in
- the original block's DF that we have not already processed to
- the worklist. Iterate until the worklist is empty. Blocks
- which are added to the worklist are potential sites for
- PHI nodes. */
- while (VEC_length (int, work_stack) > 0)
- {
- bb_index = VEC_pop (int, work_stack);
-
- /* Since the registration of NEW -> OLD name mappings is done
- separately from the call to update_ssa, when updating the SSA
- form, the basic blocks where new and/or old names are defined
- may have disappeared by CFG cleanup calls. In this case,
- we may pull a non-existing block from the work stack. */
- gcc_assert (bb_index < (unsigned) last_basic_block);
-
- EXECUTE_IF_AND_COMPL_IN_BITMAP (dfs[bb_index], phi_insertion_points,
- 0, bb_index, bi)
+ unsigned i, b, p, u, top;
+ bitmap live_phis;
+ basic_block def_bb, use_bb;
+ edge e;
+ edge_iterator ei;
+ bitmap to_remove;
+ struct dom_dfsnum *defs;
+ unsigned n_defs, adef;
+
+ if (bitmap_empty_p (uses))
+ {
+ bitmap_clear (phis);
+ return;
+ }
+
+ /* The phi must dominate a use, or an argument of a live phi. Also, we
+ do not create any phi nodes in def blocks, unless they are also livein. */
+ to_remove = BITMAP_ALLOC (NULL);
+ bitmap_and_compl (to_remove, kills, uses);
+ bitmap_and_compl_into (phis, to_remove);
+ if (bitmap_empty_p (phis))
+ {
+ BITMAP_FREE (to_remove);
+ return;
+ }
+
+ /* We want to remove the unnecessary phi nodes, but we do not want to compute
+ liveness information, as that may be linear in the size of CFG, and if
+ there are lot of different variables to rewrite, this may lead to quadratic
+ behavior.
+
+ Instead, we basically emulate standard dce. We put all uses to worklist,
+ then for each of them find the nearest def that dominates them. If this
+ def is a phi node, we mark it live, and if it was not live before, we
+ add the predecessors of its basic block to the worklist.
+
+ To quickly locate the nearest def that dominates use, we use dfs numbering
+ of the dominance tree (that is already available in order to speed up
+ queries). For each def, we have the interval given by the dfs number on
+ entry to and on exit from the corresponding subtree in the dominance tree.
+ The nearest dominator for a given use is the smallest of these intervals
+ that contains entry and exit dfs numbers for the basic block with the use.
+ If we store the bounds for all the uses to an array and sort it, we can
+ locate the nearest dominating def in logarithmic time by binary search.*/
+ bitmap_ior (to_remove, kills, phis);
+ n_defs = bitmap_count_bits (to_remove);
+ defs = XNEWVEC (struct dom_dfsnum, 2 * n_defs + 1);
+ defs[0].bb_index = 1;
+ defs[0].dfs_num = 0;
+ adef = 1;
+ EXECUTE_IF_SET_IN_BITMAP (to_remove, 0, i, bi)
+ {
+ def_bb = BASIC_BLOCK (i);
+ defs[adef].bb_index = i;
+ defs[adef].dfs_num = bb_dom_dfs_in (CDI_DOMINATORS, def_bb);
+ defs[adef + 1].bb_index = i;
+ defs[adef + 1].dfs_num = bb_dom_dfs_out (CDI_DOMINATORS, def_bb);
+ adef += 2;
+ }
+ BITMAP_FREE (to_remove);
+ gcc_assert (adef == 2 * n_defs + 1);
+ qsort (defs, adef, sizeof (struct dom_dfsnum), cmp_dfsnum);
+ gcc_assert (defs[0].bb_index == 1);
+
+ /* Now each DEFS entry contains the number of the basic block to that the
+ dfs number corresponds. Change them to the number of basic block that
+ corresponds to the interval following the dfs number. Also, for the
+ dfs_out numbers, increase the dfs number by one (so that it corresponds
+ to the start of the following interval, not to the end of the current
+ one). We use WORKLIST as a stack. */
+ worklist = VEC_alloc (int, heap, n_defs + 1);
+ VEC_quick_push (int, worklist, 1);
+ top = 1;
+ n_defs = 1;
+ for (i = 1; i < adef; i++)
+ {
+ b = defs[i].bb_index;
+ if (b == top)