GCC Middle and Back End API Reference
|
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "tree.h"
#include "gimple.h"
#include "cfghooks.h"
#include "tree-pass.h"
#include "ssa.h"
#include "gimple-pretty-print.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "cfganal.h"
#include "gimple-iterator.h"
#include "tree-cfg.h"
#include "cfgloop.h"
#include "tree-eh.h"
#include "tree-ssa-live.h"
Functions | |
static basic_block | find_bb_for_arg (gphi *phi, tree def) |
static bool | all_immediate_uses_same_place (def_operand_p def_p) |
static basic_block | nearest_common_dominator_of_uses (def_operand_p def_p, bool *debug_stmts) |
static bool | do_not_sink (gimple *stmt, basic_block early_bb, basic_block best_bb) |
static basic_block | select_best_block (basic_block early_bb, basic_block late_bb, gimple *stmt) |
static bool | statement_sink_location (gimple *stmt, basic_block frombb, gimple_stmt_iterator *togsi, bool *zero_uses_p, virtual_operand_live &vop_live) |
static unsigned | sink_common_stores_to_bb (basic_block bb) |
static unsigned | sink_code_in_bb (basic_block bb, virtual_operand_live &vop_live) |
gimple_opt_pass * | make_pass_sink_code (gcc::context *ctxt) |
Variables | ||
struct { | ||
int sunk | ||
int commoned | ||
} | sink_stats | |
|
static |
When the first immediate use is in a statement, then return true if all immediate uses in IMM are in the same statement. We could also do the case where the first immediate use is in a phi node, and all the other uses are in phis in the same basic block, but this requires some expensive checking later (you have to make sure no def/vdef in the statement occurs for multiple edges in the various phi nodes it's used in, so that you only have one place you can sink it to.
References DEF_FROM_PTR, FOR_EACH_IMM_USE_FAST, is_gimple_debug(), NULL, and USE_STMT.
Referenced by statement_sink_location().
|
static |
Return whether sinking STMT from EARLY_BB to BEST_BB should be avoided.
References bb_has_abnormal_pred(), CDI_DOMINATORS, cfun, dominated_by_p(), empty_block_p(), gimple_vdef(), gimple_vuse(), loop::inner, loop::latch, basic_block_def::loop_father, loop_outer(), and PROP_loop_opts_done.
Referenced by select_best_block().
|
static |
Given a PHI, and one of its arguments (DEF), find the edge for that argument and return it. If the argument occurs twice in the PHI node, we return NULL.
References gimple_phi_arg_edge(), gimple_phi_num_args(), i, NULL, and PHI_ARG_DEF.
Referenced by statement_sink_location().
gimple_opt_pass * make_pass_sink_code | ( | gcc::context * | ctxt | ) |
|
static |
Find the nearest common dominator of all of the immediate uses in IMM.
References BASIC_BLOCK_FOR_FN, bitmap_first_set_bit(), bitmap_set_bit, CDI_DOMINATORS, cfun, DEF_FROM_PTR, dyn_cast(), ENTRY_BLOCK_PTR_FOR_FN, EXECUTE_IF_SET_IN_BITMAP, FOR_EACH_IMM_USE_FAST, gimple_bb(), gimple_phi_arg_edge(), basic_block_def::index, is_gimple_debug(), nearest_common_dominator(), NULL, PHI_ARG_INDEX_FROM_USE, and USE_STMT.
Referenced by statement_sink_location().
|
static |
Given EARLY_BB and LATE_BB, two blocks in a path through the dominator tree, return the best basic block between them (inclusive) to place statements. We want the most control dependent block in the shallowest loop nest. If the resulting block is in a shallower loop nest, then use it.
References profile_probability::always(), bb_loop_depth(), CDI_DOMINATORS, CDI_POST_DOMINATORS, do_not_sink(), dominated_by_p(), gcc_checking_assert, get_immediate_dominator(), single_pred_edge(), and single_pred_p().
Referenced by statement_sink_location().
|
static |
Perform code sinking on BB
References CDI_DOMINATORS, cfun, dominated_by_p(), dump_file, first_dom_son(), FOR_EACH_EDGE, FOR_EACH_IMM_USE_ON_STMT, FOR_EACH_IMM_USE_STMT, gimple_bb(), gimple_vdef(), gimple_vuse(), gsi_bb(), gsi_end_p(), gsi_last_bb(), gsi_move_before(), gsi_move_to_bb_end(), gsi_prev(), gsi_remove(), gsi_stmt(), basic_block_def::index, last, NULL, print_gimple_stmt(), release_defs(), SET_USE, sink_common_stores_to_bb(), sink_stats, statement_sink_location(), stmt_could_throw_p(), basic_block_def::succs, TDF_VOPS, and todo.
|
static |
Very simplistic code to sink common stores from the predecessor through our virtual PHI. We do this before sinking stmts from BB as it might expose sinking opportunities of the merged stores. Once we have partial dead code elimination through sth like SSU-PRE this should be moved there.
References add_phi_arg(), cfun, create_phi_node(), dump_enabled_p(), dump_generic_expr(), dump_printf(), dump_printf_loc(), EDGE_COUNT, EDGE_PRED, FOR_EACH_IMM_USE_FAST, get_virtual_phi(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_set_rhs1(), gimple_clobber_p(), gimple_phi_arg_def(), gimple_phi_arg_edge(), gimple_phi_num_args(), gimple_phi_result(), gimple_phi_set_result(), gimple_set_vdef(), gimple_set_vuse(), gimple_vdef(), gimple_vop(), gsi_after_labels(), gsi_for_stmt(), gsi_insert_before(), gsi_remove(), GSI_SAME_STMT, i, is_gimple_assign(), is_gimple_reg_type(), make_ssa_name(), MSG_OPTIMIZED_LOCATIONS, NULL, operand_equal_p(), basic_block_def::preds, release_defs(), sink_stats, SSA_NAME_DEF_STMT, stmt_can_throw_internal(), TDF_SLIM, todo, TODO_cleanup_cfg, TREE_TYPE, TREE_VISITED, UNKNOWN_LOCATION, unlink_stmt_vdef(), and USE_STMT.
Referenced by sink_code_in_bb().
|
static |
Given a statement (STMT) and the basic block it is currently in (FROMBB), determine the location to sink the statement to, if any. Returns true if there is such location; in that case, TOGSI points to the statement before that STMT should be moved.
References all_immediate_uses_same_place(), as_a(), CDI_DOMINATORS, CDI_POST_DOMINATORS, cfun, DECL_HARD_REGISTER, DEF_FROM_PTR, dominated_by_p(), ECF_CONST, ECF_LOOPING_CONST_OR_PURE, ECF_PURE, ECF_RETURNS_TWICE, find_bb_for_arg(), FOR_EACH_IMM_USE_FAST, FOR_EACH_SSA_USE_OPERAND, get_immediate_dominator(), virtual_operand_live::get_live_in(), gimple_assign_rhs1(), gimple_assign_single_p(), gimple_bb(), gimple_call_flags(), gimple_get_lhs(), gimple_has_lhs(), gimple_has_side_effects(), gimple_vdef(), gimple_vuse(), gsi_after_labels(), has_zero_uses(), is_gimple_assign(), is_gimple_call(), is_gimple_debug(), nearest_common_dominator_of_uses(), NULL, NULL_DEF_OPERAND_P, NULL_USE_OPERAND_P, operand_equal_p(), ref_maybe_used_by_stmt_p(), select_best_block(), single_ssa_def_operand(), SSA_NAME_OCCURS_IN_ABNORMAL_PHI, SSA_OP_ALL_DEFS, SSA_OP_ALL_USES, stmt_ends_bb_p(), stmt_kills_ref_p(), TREE_TYPE, TYPE_MODE, USE_FROM_PTR, USE_STMT, VAR_P, and virtual_operand_p().
Referenced by sink_code_in_bb().
int commoned |
struct { ... } sink_stats |
Code sinking for trees Copyright (C) 2001-2024 Free Software Foundation, Inc. Contributed by Daniel Berlin <dan@dberlin.org> This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>.
TODO: 1. Sinking store only using scalar promotion (IE without moving the RHS): *q = p; p = p + 1; if (something) *q = <not p>; else y = *q; should become sinktemp = p; p = p + 1; if (something) *q = <not p>; else { *q = sinktemp; y = *q } Store copy propagation will take care of the store elimination above. 2. Sinking using Partial Dead Code Elimination.
Referenced by sink_code_in_bb(), and sink_common_stores_to_bb().
int sunk |
Referenced by sink_clobbers().