From 582a80ed70add44bb7f15a4a0501588adf4e7f36 Mon Sep 17 00:00:00 2001 From: vries Date: Sat, 17 Dec 2011 11:39:43 +0000 Subject: [PATCH] 2011-12-17 Tom de Vries PR tree-optimization/51491 * tree-ssa-ccp.c (insert_clobber_before_stack_restore) (gsi_prev_dom_bb_nondebug, insert_clobbers_for_var): New function. (ccp_fold_stmt): Use insert_clobbers_for_var after a successful fold_builtin_alloca_with_align. (ccp_visit_stmt): Calculate and free dominator info. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@182432 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 9 +++++ gcc/tree-ssa-ccp.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 106 insertions(+), 3 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1c8b3a2..e38ab91 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2011-12-17 Tom de Vries + + PR tree-optimization/51491 + * tree-ssa-ccp.c (insert_clobber_before_stack_restore) + (gsi_prev_dom_bb_nondebug, insert_clobbers_for_var): New function. + (ccp_fold_stmt): Use insert_clobbers_for_var after a successful + fold_builtin_alloca_with_align. + (ccp_visit_stmt): Calculate and free dominator info. + 2011-12-16 Eric Botcazou * config/sparc/sparc.md (UNSPEC_FRAME_BLOCKAGE): New constant. diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index 31c31c1..a9c38ee 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -1690,6 +1690,96 @@ evaluate_stmt (gimple stmt) return val; } +/* Given a BUILT_IN_STACK_SAVE value SAVED_VAL, insert a clobber of VAR before + each matching BUILT_IN_STACK_RESTORE. Mark visited phis in VISITED. */ + +static void +insert_clobber_before_stack_restore (tree saved_val, tree var, htab_t *visited) +{ + gimple stmt, clobber_stmt; + tree clobber; + imm_use_iterator iter; + gimple_stmt_iterator i; + gimple *slot; + + FOR_EACH_IMM_USE_STMT (stmt, iter, saved_val) + if (gimple_call_builtin_p (stmt, BUILT_IN_STACK_RESTORE)) + { + clobber = build_constructor (TREE_TYPE (var), NULL); + TREE_THIS_VOLATILE (clobber) = 1; + clobber_stmt = gimple_build_assign (var, clobber); + + i = gsi_for_stmt (stmt); + gsi_insert_before (&i, clobber_stmt, GSI_SAME_STMT); + } + else if (gimple_code (stmt) == GIMPLE_PHI) + { + if (*visited == NULL) + *visited = htab_create (10, htab_hash_pointer, htab_eq_pointer, NULL); + + slot = (gimple *)htab_find_slot (*visited, stmt, INSERT); + if (*slot != NULL) + continue; + + *slot = stmt; + insert_clobber_before_stack_restore (gimple_phi_result (stmt), var, + visited); + } + else + gcc_assert (is_gimple_debug (stmt)); +} + +/* Advance the iterator to the previous non-debug gimple statement in the same + or dominating basic block. */ + +static inline void +gsi_prev_dom_bb_nondebug (gimple_stmt_iterator *i) +{ + basic_block dom; + + gsi_prev_nondebug (i); + while (gsi_end_p (*i)) + { + dom = get_immediate_dominator (CDI_DOMINATORS, i->bb); + if (dom == NULL || dom == ENTRY_BLOCK_PTR) + return; + + *i = gsi_last_bb (dom); + } +} + +/* Find a BUILT_IN_STACK_SAVE dominating gsi_stmt (I), and insert + a clobber of VAR before each matching BUILT_IN_STACK_RESTORE. */ + +static void +insert_clobbers_for_var (gimple_stmt_iterator i, tree var) +{ + bool save_found; + gimple stmt; + tree saved_val; + htab_t visited = NULL; + + for (save_found = false; !gsi_end_p (i); gsi_prev_dom_bb_nondebug (&i)) + { + stmt = gsi_stmt (i); + + if (!gimple_call_builtin_p (stmt, BUILT_IN_STACK_SAVE)) + continue; + save_found = true; + + saved_val = gimple_call_lhs (stmt); + if (saved_val == NULL_TREE) + continue; + + insert_clobber_before_stack_restore (saved_val, var, &visited); + break; + } + + if (visited != NULL) + htab_delete (visited); + gcc_assert (save_found); +} + /* Detects a __builtin_alloca_with_align with constant size argument. Declares fixed-size array and returns the address, if found, otherwise returns NULL_TREE. */ @@ -1824,7 +1914,9 @@ ccp_fold_stmt (gimple_stmt_iterator *gsi) if (new_rhs) { bool res = update_call_from_tree (gsi, new_rhs); + tree var = TREE_OPERAND (TREE_OPERAND (new_rhs, 0),0); gcc_assert (res); + insert_clobbers_for_var (*gsi, var); return true; } } @@ -2024,12 +2116,14 @@ ccp_visit_stmt (gimple stmt, edge *taken_edge_p, tree *output_p) static unsigned int do_ssa_ccp (void) { + unsigned int todo = 0; + calculate_dominance_info (CDI_DOMINATORS); ccp_initialize (); ssa_propagate (ccp_visit_stmt, ccp_visit_phi_node); if (ccp_finalize ()) - return (TODO_cleanup_cfg | TODO_update_ssa | TODO_remove_unused_locals); - else - return 0; + todo = (TODO_cleanup_cfg | TODO_update_ssa | TODO_remove_unused_locals); + free_dominance_info (CDI_DOMINATORS); + return todo; } -- 2.7.4