diff options
Diffstat (limited to 'gcc/tree-ssa-phiopt.c')
-rw-r--r-- | gcc/tree-ssa-phiopt.c | 134 |
1 files changed, 69 insertions, 65 deletions
diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index 54002996cc4..5c11000e97d 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -1466,17 +1466,79 @@ ssa_names_hasher::equal (const value_type *n1, const compare_type *n2) && n1->size == n2->size; } -/* The hash table for remembering what we've seen. */ -static hash_table <ssa_names_hasher> seen_ssa_names; +class nontrapping_dom_walker : public dom_walker +{ +public: + nontrapping_dom_walker (cdi_direction direction, pointer_set_t *ps) + : dom_walker (direction), m_nontrapping (ps), m_seen_ssa_names (128) {} + + virtual void before_dom_children (basic_block); + virtual void after_dom_children (basic_block); + +private: + + /* We see the expression EXP in basic block BB. If it's an interesting + expression (an MEM_REF through an SSA_NAME) possibly insert the + expression into the set NONTRAP or the hash table of seen expressions. + STORE is true if this expression is on the LHS, otherwise it's on + the RHS. */ + void add_or_mark_expr (basic_block, tree, bool); + + pointer_set_t *m_nontrapping; + + /* The hash table for remembering what we've seen. */ + hash_table<ssa_names_hasher> m_seen_ssa_names; +}; + +/* Called by walk_dominator_tree, when entering the block BB. */ +void +nontrapping_dom_walker::before_dom_children (basic_block bb) +{ + edge e; + edge_iterator ei; + gimple_stmt_iterator gsi; + + /* If we haven't seen all our predecessors, clear the hash-table. */ + FOR_EACH_EDGE (e, ei, bb->preds) + if ((((size_t)e->src->aux) & 2) == 0) + { + nt_call_phase++; + break; + } + + /* Mark this BB as being on the path to dominator root and as visited. */ + bb->aux = (void*)(1 | 2); + + /* And walk the statements in order. */ + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + { + gimple stmt = gsi_stmt (gsi); + + if (is_gimple_call (stmt) && !nonfreeing_call_p (stmt)) + nt_call_phase++; + else if (gimple_assign_single_p (stmt) && !gimple_has_volatile_ops (stmt)) + { + add_or_mark_expr (bb, gimple_assign_lhs (stmt), true); + add_or_mark_expr (bb, gimple_assign_rhs1 (stmt), false); + } + } +} + +/* Called by walk_dominator_tree, when basic block BB is exited. */ +void +nontrapping_dom_walker::after_dom_children (basic_block bb) +{ + /* This BB isn't on the path to dominator root anymore. */ + bb->aux = (void*)2; +} /* We see the expression EXP in basic block BB. If it's an interesting expression (an MEM_REF through an SSA_NAME) possibly insert the expression into the set NONTRAP or the hash table of seen expressions. STORE is true if this expression is on the LHS, otherwise it's on the RHS. */ -static void -add_or_mark_expr (basic_block bb, tree exp, - struct pointer_set_t *nontrap, bool store) +void +nontrapping_dom_walker::add_or_mark_expr (basic_block bb, tree exp, bool store) { HOST_WIDE_INT size; @@ -1500,7 +1562,7 @@ add_or_mark_expr (basic_block bb, tree exp, map.offset = tree_to_shwi (TREE_OPERAND (exp, 1)); map.size = size; - slot = seen_ssa_names.find_slot (&map, INSERT); + slot = m_seen_ssa_names.find_slot (&map, INSERT); n2bb = *slot; if (n2bb && n2bb->phase >= nt_call_phase) found_bb = n2bb->bb; @@ -1510,7 +1572,7 @@ add_or_mark_expr (basic_block bb, tree exp, then we can't trap. */ if (found_bb && (((size_t)found_bb->aux) & 1) == 1) { - pointer_set_insert (nontrap, exp); + pointer_set_insert (m_nontrapping, exp); } else { @@ -1535,61 +1597,6 @@ add_or_mark_expr (basic_block bb, tree exp, } } -class nontrapping_dom_walker : public dom_walker -{ -public: - nontrapping_dom_walker (cdi_direction direction, pointer_set_t *ps) - : dom_walker (direction), m_nontrapping (ps) {} - - virtual void before_dom_children (basic_block); - virtual void after_dom_children (basic_block); - -private: - pointer_set_t *m_nontrapping; -}; - -/* Called by walk_dominator_tree, when entering the block BB. */ -void -nontrapping_dom_walker::before_dom_children (basic_block bb) -{ - edge e; - edge_iterator ei; - gimple_stmt_iterator gsi; - - /* If we haven't seen all our predecessors, clear the hash-table. */ - FOR_EACH_EDGE (e, ei, bb->preds) - if ((((size_t)e->src->aux) & 2) == 0) - { - nt_call_phase++; - break; - } - - /* Mark this BB as being on the path to dominator root and as visited. */ - bb->aux = (void*)(1 | 2); - - /* And walk the statements in order. */ - for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - { - gimple stmt = gsi_stmt (gsi); - - if (is_gimple_call (stmt) && !nonfreeing_call_p (stmt)) - nt_call_phase++; - else if (gimple_assign_single_p (stmt) && !gimple_has_volatile_ops (stmt)) - { - add_or_mark_expr (bb, gimple_assign_lhs (stmt), m_nontrapping, true); - add_or_mark_expr (bb, gimple_assign_rhs1 (stmt), m_nontrapping, false); - } - } -} - -/* Called by walk_dominator_tree, when basic block BB is exited. */ -void -nontrapping_dom_walker::after_dom_children (basic_block bb) -{ - /* This BB isn't on the path to dominator root anymore. */ - bb->aux = (void*)2; -} - /* This is the entry point of gathering non trapping memory accesses. It will do a dominator walk over the whole function, and it will make use of the bb->aux pointers. It returns a set of trees @@ -1599,7 +1606,6 @@ get_non_trapping (void) { nt_call_phase = 0; pointer_set_t *nontrap = pointer_set_create (); - seen_ssa_names.create (128); /* We're going to do a dominator walk, so ensure that we have dominance information. */ calculate_dominance_info (CDI_DOMINATORS); @@ -1607,8 +1613,6 @@ get_non_trapping (void) nontrapping_dom_walker (CDI_DOMINATORS, nontrap) .walk (cfun->cfg->x_entry_block_ptr); - seen_ssa_names.dispose (); - clear_aux_for_blocks (); return nontrap; } |