Hi, This patch adds a bounds lifetime reduction into checker optimization.
Thanks, Ilya -- 2014-10-08 Ilya Enkovich <ilya.enkov...@intel.com> * tree-chkp.c (chkp_reduce_bounds_lifetime): New. (chkp_opt_execute): Run bounds lifetime reduction algorithm. diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c index 37ab729..60e4c11 100644 --- a/gcc/tree-chkp.c +++ b/gcc/tree-chkp.c @@ -5420,6 +5420,155 @@ chkp_optimize_string_function_calls (void) } } +/* Intrumentation pass inserts most of bounds creation code + in the header of the function. We want to move bounds + creation closer to bounds usage to reduce bounds lifetime. + We also try to avoid bounds creation code on paths where + bounds are not used. */ +void +chkp_reduce_bounds_lifetime (void) +{ + basic_block bb = FALLTHRU_EDGE (ENTRY_BLOCK_PTR_FOR_FN (cfun))->dest; + gimple_stmt_iterator i; + + for (i = gsi_start_bb (bb); !gsi_end_p (i); ) + { + gimple dom_use, use_stmt, stmt = gsi_stmt (i); + basic_block dom_bb; + ssa_op_iter iter; + imm_use_iterator use_iter; + use_operand_p use_p; + tree op; + bool want_move = false; + bool deps = false; + + if (gimple_code (stmt) == GIMPLE_CALL + && gimple_call_fndecl (stmt) == chkp_bndmk_fndecl) + want_move = true; + + if (gimple_code (stmt) == GIMPLE_ASSIGN + && POINTER_BOUNDS_P (gimple_assign_lhs (stmt)) + && gimple_assign_rhs_code (stmt) == VAR_DECL) + want_move = true; + + if (!want_move) + { + gsi_next (&i); + continue; + } + + /* Check we do not increase other values lifetime. */ + FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE) + { + op = USE_FROM_PTR (use_p); + + if (TREE_CODE (op) == SSA_NAME + && gimple_code (SSA_NAME_DEF_STMT (op)) != GIMPLE_NOP) + deps = true; + } + + if (deps) + { + gsi_next (&i); + continue; + } + + /* Check all usages of bounds. */ + if (gimple_code (stmt) == GIMPLE_CALL) + op = gimple_call_lhs (stmt); + else + { + gcc_assert (gimple_code (stmt) == GIMPLE_ASSIGN); + op = gimple_assign_lhs (stmt); + } + + dom_use = NULL; + dom_bb = NULL; + + FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, op) + { + if (dom_bb && + dominated_by_p (CDI_DOMINATORS, + dom_bb, gimple_bb (use_stmt))) + { + dom_use = use_stmt; + dom_bb = NULL; + } + else if (dom_bb) + dom_bb = nearest_common_dominator (CDI_DOMINATORS, dom_bb, + gimple_bb (use_stmt)); + else if (!dom_use) + dom_use = use_stmt; + else if (stmt_dominates_stmt_p (use_stmt, dom_use)) + dom_use = use_stmt; + else if (!stmt_dominates_stmt_p (dom_use, use_stmt) + /* If dom_use and use_stmt are PHI nodes in one BB + then it is OK to keep any of them as dom_use. + stmt_dominates_stmt_p returns 0 for such + combination, so check it here manually. */ + && (gimple_code (dom_use) != GIMPLE_PHI + || gimple_code (use_stmt) != GIMPLE_PHI + || gimple_bb (use_stmt) != gimple_bb (dom_use)) + ) + { + dom_bb = nearest_common_dominator (CDI_DOMINATORS, + gimple_bb (use_stmt), + gimple_bb (dom_use)); + dom_use = NULL; + } + } + + /* In case there is a single use, just move bounds + creation to the use. */ + if (dom_use || dom_bb) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Moving creation of "); + print_generic_expr (dump_file, op, 0); + fprintf (dump_file, " down to its use.\n"); + } + + if (dom_use && gimple_code (dom_use) == GIMPLE_PHI) + { + dom_bb = get_immediate_dominator (CDI_DOMINATORS, + gimple_bb (dom_use)); + dom_use = NULL; + } + + if (dom_bb == bb + || (dom_use && gimple_bb (dom_use) == bb)) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "Cannot move statement bacause there is no " + "suitable dominator block other than entry block.\n"); + + gsi_next (&i); + } + else + { + if (dom_bb) + { + gimple_stmt_iterator last = gsi_last_bb (dom_bb); + if (!gsi_end_p (last) && stmt_ends_bb_p (gsi_stmt (last))) + gsi_move_before (&i, &last); + else + gsi_move_after (&i, &last); + } + else + { + gimple_stmt_iterator gsi = gsi_for_stmt (dom_use); + gsi_move_before (&i, &gsi); + } + + update_stmt (stmt); + } + } + else + gsi_next (&i); + } +} + /* Initilize checker optimization pass. */ void chkp_opt_init (void) @@ -5464,6 +5613,8 @@ chkp_opt_execute (void) chkp_remove_redundant_checks (); + chkp_reduce_bounds_lifetime (); + chkp_release_check_info (); chkp_opt_fini ();