+/* Initialization of block data structures for the incremental SSA
+ update pass. Create a block local stack of reaching definitions
+ for new SSA names produced in this block (BLOCK_DEFS). Register
+ new definitions for every PHI node in the block. */
+
+static void
+rewrite_update_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
+ basic_block bb)
+{
+ edge e;
+ edge_iterator ei;
+ bool is_abnormal_phi;
+ gimple_stmt_iterator gsi;
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "\n\nRegistering new PHI nodes in block #%d\n\n",
+ bb->index);
+
+ /* Mark the unwind point for this block. */
+ VEC_safe_push (tree, heap, block_defs_stack, NULL_TREE);
+
+ if (!bitmap_bit_p (blocks_to_update, bb->index))
+ return;
+
+ /* Mark the LHS if any of the arguments flows through an abnormal
+ edge. */
+ is_abnormal_phi = false;
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ if (e->flags & EDGE_ABNORMAL)
+ {
+ is_abnormal_phi = true;
+ break;
+ }
+
+ /* If any of the PHI nodes is a replacement for a name in
+ OLD_SSA_NAMES or it's one of the names in NEW_SSA_NAMES, then
+ register it as a new definition for its corresponding name. Also
+ register definitions for names whose underlying symbols are
+ marked for renaming. */
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ tree lhs, lhs_sym;
+ gimple phi = gsi_stmt (gsi);
+
+ if (!register_defs_p (phi))
+ continue;
+
+ lhs = gimple_phi_result (phi);
+ lhs_sym = SSA_NAME_VAR (lhs);
+
+ if (symbol_marked_for_renaming (lhs_sym))
+ register_new_update_single (lhs, lhs_sym);
+ else
+ {
+
+ /* If LHS is a new name, register a new definition for all
+ the names replaced by LHS. */
+ if (is_new_name (lhs))
+ register_new_update_set (lhs, names_replaced_by (lhs));
+
+ /* If LHS is an OLD name, register it as a new definition
+ for itself. */
+ if (is_old_name (lhs))
+ register_new_update_single (lhs, lhs);
+ }
+
+ if (is_abnormal_phi)
+ SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs) = 1;
+ }
+
+ /* Step 2. Rewrite every variable used in each statement in the block. */
+ if (TEST_BIT (interesting_blocks, bb->index))
+ {
+ gcc_assert (bitmap_bit_p (blocks_to_update, bb->index));
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ rewrite_update_stmt (gsi_stmt (gsi), gsi);
+ }
+
+ /* Step 3. Update PHI nodes. */
+ rewrite_update_phi_arguments (bb);
+}
+
+/* Called after visiting block BB. Unwind BLOCK_DEFS_STACK to restore
+ the current reaching definition of every name re-written in BB to
+ the original reaching definition before visiting BB. This
+ unwinding must be done in the opposite order to what is done in
+ register_new_update_set. */
+
+static void
+rewrite_update_leave_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
+ basic_block bb ATTRIBUTE_UNUSED)
+{
+ while (VEC_length (tree, block_defs_stack) > 0)
+ {
+ tree var = VEC_pop (tree, block_defs_stack);
+ tree saved_def;
+
+ /* NULL indicates the unwind stop point for this block (see
+ rewrite_update_enter_block). */
+ if (var == NULL)
+ return;
+
+ saved_def = VEC_pop (tree, block_defs_stack);
+ set_current_def (var, saved_def);
+ }
+}
+
+