GCC Middle and Back End API Reference
|
Enumerations | |
enum | { PR_CAN_APPEAR = 1, PR_HANDLE_MEM = 2, PR_OPTIMIZE_FOR_SPEED = 4 } |
Functions | |
static df_ref | get_def_for_use () |
static void | process_defs () |
static void | process_uses () |
static void | single_def_use_enter_block (struct dom_walk_data *walk_data, basic_block bb) |
static void | single_def_use_leave_block (struct dom_walk_data *walk_data, basic_block bb) |
static void | build_single_def_use_links () |
static bool | can_simplify_addr () |
static void | canonicalize_address () |
static bool | should_replace_address (rtx old_rtx, rtx new_rtx, enum machine_mode mode, addr_space_t as, bool speed) |
static bool | propagate_rtx_1 () |
static int | varying_mem_p () |
static rtx | propagate_rtx (rtx x, enum machine_mode mode, rtx old_rtx, rtx new_rtx, bool speed) |
static bool | local_ref_killed_between_p () |
static bool | use_killed_between () |
static bool | all_uses_available_at () |
static void | register_active_defs () |
static void | update_df_init () |
static void | update_uses () |
static void | update_df () |
static bool | try_fwprop_subst () |
static bool | free_load_extend () |
static bool | forward_propagate_subreg () |
static bool | forward_propagate_asm () |
static bool | forward_propagate_and_simplify () |
static bool | forward_propagate_into () |
static void | fwprop_init () |
static void | fwprop_done () |
static bool | gate_fwprop () |
static unsigned int | fwprop () |
rtl_opt_pass * | make_pass_rtl_fwprop () |
static unsigned int | fwprop_addr () |
rtl_opt_pass * | make_pass_rtl_fwprop_addr () |
Variables | |
static int | num_changes |
static vec< df_ref > | use_def_ref |
static vec< df_ref > | reg_defs |
static vec< df_ref > | reg_defs_stack |
static bitmap | local_md |
static bitmap | local_lr |
static df_ref * | active_defs |
static sparseset | active_defs_check |
anonymous enum |
|
static |
Check if all uses in DEF_INSN can be used in TARGET_INSN. This would require full computation of available expressions; we check only restricted conditions, see use_killed_between.
References rtx_equal_p(), and use_killed_between().
Referenced by forward_propagate_and_simplify(), and forward_propagate_subreg().
|
static |
Build a vector holding the reaching definitions of uses reached by a single dominating definition.
References dom_walk_data::after_dom_children, dom_walk_data::before_dom_children, CDI_DOMINATORS, df_analyze(), DF_EQ_NOTES, df_maybe_reorganize_use_refs(), df_md_add_problem(), df_note_add_problem(), DF_REF_ORDER_BY_INSN_WITH_NOTES, df_set_flags(), fini_walk_dominator_tree(), init_walk_dominator_tree(), dom_walk_data::initialize_block_local_data, max_reg_num(), single_def_use_enter_block(), single_def_use_leave_block(), and walk_dominator_tree().
Referenced by fwprop_init().
|
static |
Do not try to replace constant addresses or addresses of local and argument slots. These MEM expressions are made only once and inserted in many instructions, as well as being used to control symbol table output. It is not safe to clobber them. There are some uncommon cases where the address is already in a register for some reason, but we cannot take advantage of that because we have no easy way to unshare the MEM. In addition, looking up all stack addresses is costly.
Referenced by propagate_rtx_1().
|
static |
Returns a canonical version of X for the address, from the point of view, that all multiplications are represented as MULT instead of the multiply by a power of 2 being represented as ASHIFT. Every ASHIFT we find has been made by simplify_gen_binary and was not there before, so it is not shared. So we can do this in place.
References gen_int_mode(), HOST_WIDE_INT, and shift.
Referenced by propagate_rtx_1().
|
static |
Try to replace USE with SRC (defined in DEF_INSN) and simplify the result.
References all_uses_available_at(), asm_noperands(), avoid_constant_pool_reference(), copy_rtx(), DF_REF_IN_NOTE, DF_REF_REG_MEM_STORE, find_reg_note(), forward_propagate_asm(), optimize_bb_for_speed_p(), propagate_rtx(), reg_mentioned_p(), set_unique_reg_note(), simplify_replace_rtx(), and try_fwprop_subst().
Referenced by forward_propagate_into().
|
static |
Try to replace USE with SRC (defined in DEF_INSN) in __asm.
References apply_change_group(), DF_REF_IN_NOTE, num_changes, num_changes_pending(), optimize_bb_for_speed_p(), propagate_rtx(), SET, update_df(), update_df_init(), and validate_unshare_change().
Referenced by forward_propagate_and_simplify().
|
static |
Given a use USE of an insn, if it has a single reaching definition, try to forward propagate it into that insn. Return true if cfg cleanup will be needed.
References function::can_throw_non_call_exceptions, cfun, DF_REF_IN_NOTE, DF_REF_READ_WRITE, find_reg_note(), forward_propagate_and_simplify(), forward_propagate_subreg(), get_def_for_use(), multiple_sets(), purge_dead_edges(), and reg_mentioned_p().
Referenced by fwprop(), and fwprop_addr().
|
static |
If USE is a subreg, see if it can be replaced by a pseudo.
References all_uses_available_at(), free_load_extend(), subreg_lowpart_p(), targetm, try_fwprop_subst(), and use_reg().
Referenced by forward_propagate_into().
|
static |
For the given single_set INSN, containing SRC known to be a ZERO_EXTEND or SIGN_EXTEND of a register, return true if INSN is redundant due to the register being set by a LOAD_EXTEND_OP load from memory.
References DF_REF_REG_USE, get_def_for_use(), rtx_equal_p(), and SET.
Referenced by forward_propagate_subreg().
|
static |
References cleanup_cfg(), DF_REF_REG_USE, forward_propagate_into(), fwprop_done(), fwprop_init(), and loop_outer().
|
static |
References cleanup_cfg(), DF_REF_REG_USE, forward_propagate_into(), fwprop_done(), fwprop_init(), and loop_outer().
|
static |
References CDI_DOMINATORS, cleanup_cfg(), delete_trivially_dead_insns(), dump_file, free(), free_dominance_info(), get_insns(), loop_optimizer_finalize(), max_reg_num(), and num_changes.
Referenced by fwprop(), and fwprop_addr().
|
static |
References build_single_def_use_links(), calculate_dominance_info(), CDI_DOMINATORS, DF_DEFER_INSN_RESCAN, df_set_flags(), loop_optimizer_init(), max_reg_num(), num_changes, and sparseset_alloc().
Referenced by fwprop(), and fwprop_addr().
|
static |
Main entry point.
|
inlinestatic |
Return the only def in USE's use-def chain, or NULL if there is more than one def in the chain.
Referenced by forward_propagate_into(), free_load_extend(), and register_active_defs().
|
static |
Return true if the register from reference REF is killed between FROM to (but not including) TO.
Referenced by use_killed_between().
rtl_opt_pass* make_pass_rtl_fwprop | ( | ) |
rtl_opt_pass* make_pass_rtl_fwprop_addr | ( | ) |
|
static |
References bitmap_clear_bit(), bitmap_set_bit(), and DF_REF_AT_TOP.
Referenced by single_def_use_enter_block().
|
static |
Fill the use_def_ref vector with values for the uses in USE_REC, taking reaching definitions info from LOCAL_MD and REG_DEFS. TOP_FLAG says which artificials uses should be used, when USE_REC is an artificial use vector.
References bitmap_bit_p(), and DF_REF_AT_TOP.
Referenced by single_def_use_enter_block().
|
static |
Replace all occurrences of OLD in X with NEW and try to simplify the resulting expression (in mode MODE). Return a new expression if it is a constant, otherwise X. Simplifications where occurrences of NEW collapse to a constant are always accepted. All simplifications are accepted if NEW is a pseudo too. Otherwise, we accept simplifications that have a lower or equal cost.
References copy_rtx(), for_each_rtx(), rtl_hooks::gen_lowpart_no_emit, PR_CAN_APPEAR, PR_HANDLE_MEM, PR_OPTIMIZE_FOR_SPEED, propagate_rtx_1(), and varying_mem_p().
Referenced by forward_propagate_and_simplify(), and forward_propagate_asm().
|
static |
Replace all occurrences of OLD in *PX with NEW and try to simplify the resulting expression. Replace *PX with a new RTL expression if an occurrence of OLD was found. This is only a wrapper around simplify-rtx.c: do not add any pattern matching code here. (The sole exception is the handling of LO_SUM, but that is because there is no simplify_gen_* function for LO_SUM).
References can_simplify_addr(), canonicalize_address(), PR_CAN_APPEAR, PR_HANDLE_MEM, PR_OPTIMIZE_FOR_SPEED, replace_equiv_address_nv(), RTX_BIN_ARITH, RTX_BITFIELD_OPS, RTX_COMM_ARITH, RTX_COMM_COMPARE, RTX_COMPARE, rtx_equal_p(), RTX_EXTRA, RTX_OBJ, RTX_TERNARY, RTX_UNARY, should_replace_address(), side_effects_p(), simplify_gen_binary(), simplify_gen_relational(), simplify_gen_subreg(), simplify_gen_ternary(), simplify_gen_unary(), and targetm.
Referenced by propagate_rtx().
|
static |
Fill the ACTIVE_DEFS array with the use->def link for the registers mentioned in USE_REC. Register the valid entries in ACTIVE_DEFS_CHECK too, for checking purposes.
References get_def_for_use(), and sparseset_set_bit().
Referenced by update_df_init().
|
static |
OLD is a memory address. Return whether it is good to use NEW instead, for a memory access in the given MODE.
References address_cost(), memory_address_addr_space_p(), rtx_equal_p(), and set_src_cost().
Referenced by propagate_rtx_1().
|
static |
References bitmap_copy(), df_get_artificial_defs(), df_get_artificial_uses(), df_lr_get_bb_info(), df_md_get_bb_info(), DF_REF_AT_TOP, df_simulate_one_insn_forwards(), df_md_bb_info::in, df_lr_bb_info::in, basic_block_def::index, process_defs(), and process_uses().
Referenced by build_single_def_use_links().
|
static |
Pop the definitions created in this basic block when leaving its dominated parts.
Referenced by build_single_def_use_links().
|
static |
Try substituting NEW into LOC, which originated from forward propagation of USE's value from DEF_INSN. SET_REG_EQUAL says whether we are substituting the whole SET_SRC, so we can set a REG_EQUAL note if the new insn is not recognized. Return whether the substitution was performed.
References cancel_changes(), confirm_change_group(), copy_rtx(), DF_REF_REG_USE, dump_file, df_insn_info::insn, num_changes, optimize_bb_for_speed_p(), print_inline_rtx(), set_src_cost(), set_unique_reg_note(), update_df(), update_df_init(), validate_unshare_change(), and verify_changes().
Referenced by forward_propagate_and_simplify(), and forward_propagate_subreg().
|
static |
Update the USE_DEF_REF array for the uses in INSN. Only update note uses if NOTES_ONLY is true.
References df_insn_rescan(), df_notes_rescan(), DF_REF_IN_NOTE, df_uses_create(), and update_uses().
Referenced by forward_propagate_asm(), and try_fwprop_subst().
|
static |
Build the use->def links that we use to update the dataflow info for new uses. Note that building the links is very cheap and if it were done earlier, they could be used to rule out invalid propagations (in addition to what is done in all_uses_available_at). I'm not doing this yet, though.
References register_active_defs(), and sparseset_clear().
Referenced by forward_propagate_asm(), and try_fwprop_subst().
|
inlinestatic |
Update the USE_DEF_REF array for the given use, using the active definitions in the ACTIVE_DEFS array to match pseudos to their def.
References sparseset_bit_p().
Referenced by update_df().
|
static |
Check if the given DEF is available in INSN. This would require full computation of available expressions; we check only restricted conditions: - if DEF is the sole definition of its register, go ahead; - in the same basic block, we check for no definitions killing the definition of DEF_INSN; - if USE's basic block has DEF's basic block as the sole predecessor, we check if the definition is killed after DEF_INSN or before TARGET_INSN insn, in their respective basic blocks.
References CDI_DOMINATORS, df_bb_regno_first_def_find(), df_bb_regno_last_def_find(), dominated_by_p(), local_ref_killed_between_p(), single_pred(), single_pred_p(), and target_bb.
Referenced by all_uses_available_at().
|
static |
for_each_rtx traversal function that returns 1 if BODY points to a non-constant mem.
Referenced by propagate_rtx().
|
static |
|
static |
|
static |
|
static |
The MD bitmaps are trimmed to include only live registers to cut memory usage on testcases like insn-recog.c. Track live registers in the basic block and do not perform forward propagation if the destination is a dead pseudo occurring in a note.
|
static |
@verbatim RTL-based forward propagation pass for GNU compiler.
Copyright (C) 2005-2013 Free Software Foundation, Inc. Contributed by Paolo Bonzini and Steven Bosscher.
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/.
This pass does simple forward propagation and simplification when an operand of an insn can only come from a single def. This pass uses df.c, so it is global. However, we only do limited analysis of available expressions. 1) The pass tries to propagate the source of the def into the use, and checks if the result is independent of the substituted value. For example, the high word of a (zero_extend:DI (reg:SI M)) is always zero, independent of the source register. In particular, we propagate constants into the use site. Sometimes RTL expansion did not put the constant in the same insn on purpose, to satisfy a predicate, and the result will fail to be recognized; but this happens rarely and in this case we can still create a REG_EQUAL note. For multi-word operations, this (set (subreg:SI (reg:DI 120) 0) (const_int 0)) (set (subreg:SI (reg:DI 120) 4) (const_int -1)) (set (subreg:SI (reg:DI 122) 0) (ior:SI (subreg:SI (reg:DI 119) 0) (subreg:SI (reg:DI 120) 0))) (set (subreg:SI (reg:DI 122) 4) (ior:SI (subreg:SI (reg:DI 119) 4) (subreg:SI (reg:DI 120) 4))) can be simplified to the much simpler (set (subreg:SI (reg:DI 122) 0) (subreg:SI (reg:DI 119))) (set (subreg:SI (reg:DI 122) 4) (const_int -1)) This particular propagation is also effective at putting together complex addressing modes. We are more aggressive inside MEMs, in that all definitions are propagated if the use is in a MEM; if the result is a valid memory address we check address_cost to decide whether the substitution is worthwhile. 2) The pass propagates register copies. This is not as effective as the copy propagation done by CSE's canon_reg, which works by walking the instruction chain, it can help the other transformations. We should consider removing this optimization, and instead reorder the RTL passes, because GCSE does this transformation too. With some luck, the CSE pass at the end of rest_of_handle_gcse could also go away. 3) The pass looks for paradoxical subregs that are actually unnecessary. Things like this: (set (reg:QI 120) (subreg:QI (reg:SI 118) 0)) (set (reg:QI 121) (subreg:QI (reg:SI 119) 0)) (set (reg:SI 122) (plus:SI (subreg:SI (reg:QI 120) 0) (subreg:SI (reg:QI 121) 0))) are very common on machines that can only do word-sized operations. For each use of a paradoxical subreg (subreg:WIDER (reg:NARROW N) 0), if it has a single def and it is (subreg:NARROW (reg:WIDE M) 0), we can replace the paradoxical subreg with simply (reg:WIDE M). The above will simplify this to (set (reg:QI 120) (subreg:QI (reg:SI 118) 0)) (set (reg:QI 121) (subreg:QI (reg:SI 119) 0)) (set (reg:SI 122) (plus:SI (reg:SI 118) (reg:SI 119))) where the first two insns are now dead. We used to use reaching definitions to find which uses have a single reaching definition (sounds obvious...), but this is too complex a problem in nasty testcases like PR33928. Now we use the multiple definitions problem in df-problems.c. The similarity between that problem and SSA form creation is taken further, in that fwprop does a dominator walk to create its chains; however, instead of creating a PHI function where multiple definitions meet I just punt and record only singleton use-def chains, which is all that is needed by fwprop.
Referenced by forward_propagate_asm(), fwprop_done(), fwprop_init(), and try_fwprop_subst().