-/* We have finished processing the dominator children of BB, perform
- any finalization actions in preparation for leaving this node in
- the dominator tree. */
-
-static void
-dom_opt_finalize_block (struct dom_walk_data *walk_data, basic_block bb)
-{
- gimple last;
-
- /* If we have an outgoing edge to a block with multiple incoming and
- outgoing edges, then we may be able to thread the edge, i.e., we
- may be able to statically determine which of the outgoing edges
- will be traversed when the incoming edge from BB is traversed. */
- if (single_succ_p (bb)
- && (single_succ_edge (bb)->flags & EDGE_ABNORMAL) == 0
- && potentially_threadable_block (single_succ (bb)))
- {
- dom_thread_across_edge (walk_data, single_succ_edge (bb));
- }
- else if ((last = last_stmt (bb))
- && gimple_code (last) == GIMPLE_COND
- && EDGE_COUNT (bb->succs) == 2
- && (EDGE_SUCC (bb, 0)->flags & EDGE_ABNORMAL) == 0
- && (EDGE_SUCC (bb, 1)->flags & EDGE_ABNORMAL) == 0)
- {
- edge true_edge, false_edge;
-
- extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
-
- /* Only try to thread the edge if it reaches a target block with
- more than one predecessor and more than one successor. */
- if (potentially_threadable_block (true_edge->dest))
- {
- struct edge_info *edge_info;
- unsigned int i;
-
- /* Push a marker onto the available expression stack so that we
- unwind any expressions related to the TRUE arm before processing
- the false arm below. */
- VEC_safe_push (expr_hash_elt_t, heap, avail_exprs_stack, NULL);
- VEC_safe_push (tree, heap, const_and_copies_stack, NULL_TREE);
-
- edge_info = (struct edge_info *) true_edge->aux;
-
- /* If we have info associated with this edge, record it into
- our equivalence tables. */
- if (edge_info)
- {
- struct cond_equivalence *cond_equivalences = edge_info->cond_equivalences;
- tree lhs = edge_info->lhs;
- tree rhs = edge_info->rhs;
-
- /* If we have a simple NAME = VALUE equivalence, record it. */
- if (lhs && TREE_CODE (lhs) == SSA_NAME)
- record_const_or_copy (lhs, rhs);
-
- /* If we have 0 = COND or 1 = COND equivalences, record them
- into our expression hash tables. */
- if (cond_equivalences)
- for (i = 0; i < edge_info->max_cond_equivalences; i++)
- record_cond (&cond_equivalences[i]);
- }
-
- dom_thread_across_edge (walk_data, true_edge);
-
- /* And restore the various tables to their state before
- we threaded this edge. */
- remove_local_expressions_from_table ();
- }
-
- /* Similarly for the ELSE arm. */
- if (potentially_threadable_block (false_edge->dest))
- {
- struct edge_info *edge_info;
- unsigned int i;
-
- VEC_safe_push (tree, heap, const_and_copies_stack, NULL_TREE);
- edge_info = (struct edge_info *) false_edge->aux;
-
- /* If we have info associated with this edge, record it into
- our equivalence tables. */
- if (edge_info)
- {
- struct cond_equivalence *cond_equivalences = edge_info->cond_equivalences;
- tree lhs = edge_info->lhs;
- tree rhs = edge_info->rhs;
-
- /* If we have a simple NAME = VALUE equivalence, record it. */
- if (lhs && TREE_CODE (lhs) == SSA_NAME)
- record_const_or_copy (lhs, rhs);
-
- /* If we have 0 = COND or 1 = COND equivalences, record them
- into our expression hash tables. */
- if (cond_equivalences)
- for (i = 0; i < edge_info->max_cond_equivalences; i++)
- record_cond (&cond_equivalences[i]);
- }
-
- /* Now thread the edge. */
- dom_thread_across_edge (walk_data, false_edge);
-
- /* No need to remove local expressions from our tables
- or restore vars to their original value as that will
- be done immediately below. */
- }
- }
-
- remove_local_expressions_from_table ();
- restore_vars_to_original_value ();
-
- /* If we queued any statements to rescan in this block, then
- go ahead and rescan them now. */
- while (VEC_length (gimple_p, stmts_to_rescan) > 0)
- {
- gimple *stmt_p = VEC_last (gimple_p, stmts_to_rescan);
- gimple stmt = *stmt_p;
- basic_block stmt_bb = gimple_bb (stmt);
-
- if (stmt_bb != bb)
- break;
-
- VEC_pop (gimple_p, stmts_to_rescan);
- pop_stmt_changes (stmt_p);
- }
-}
-