GCC Middle and Back End API Reference
|
Data Structures | |
struct | inc_insn |
struct | mem_insn |
Enumerations | |
enum | form { FORM_PRE_ADD, FORM_PRE_INC, FORM_POST_ADD, FORM_POST_INC, FORM_last } |
enum | inc_state { INC_ZERO, INC_NEG_SIZE, INC_POS_SIZE, INC_NEG_ANY, INC_POS_ANY, INC_REG, INC_last } |
enum | gen_form { NOTHING, SIMPLE_PRE_INC, SIMPLE_POST_INC, SIMPLE_PRE_DEC, SIMPLE_POST_DEC, DISP_PRE, DISP_POST, REG_PRE, REG_POST } |
Functions | |
static enum inc_state | set_inc_state () |
static void | init_decision_table () |
static void | dump_inc_insn () |
static void | dump_mem_insn () |
static void | move_dead_notes () |
static rtx | insert_move_insn_before () |
static bool | attempt_change () |
static bool | try_merge () |
static rtx | get_next_ref () |
static void | reverse_mem () |
static void | reverse_inc () |
static bool | parse_add_or_inc () |
static int | find_address () |
static bool | find_inc () |
static bool | find_mem () |
static void | merge_in_block () |
static unsigned int | rest_of_handle_auto_inc_dec () |
static bool | gate_auto_inc_dec () |
rtl_opt_pass * | make_pass_inc_dec () |
Variables | |
static rtx | mem_tmp |
static bool | initialized = false |
static enum gen_form | decision_table [INC_last][INC_last][FORM_last] |
static struct inc_insn | inc_insn |
static struct mem_insn | mem_insn |
static rtx * | reg_next_use = NULL |
static rtx * | reg_next_inc_use = NULL |
static rtx * | reg_next_def = NULL |
enum form |
@verbatim Discovery of auto-inc and auto-dec instructions.
Copyright (C) 2006-2013 Free Software Foundation, Inc. Contributed by Kenneth Zadeck zadec k@na tural brid ge.co m
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 was originally removed from flow.c. However there is almost nothing that remains of that code. There are (4) basic forms that are matched: (1) FORM_PRE_ADD a <- b + c ... *a becomes a <- b ... *(a += c) pre (2) FORM_PRE_INC a += c ... *a becomes *(a += c) pre (3) FORM_POST_ADD *a ... b <- a + c (For this case to be true, b must not be assigned or used between the *a and the assignment to b. B must also be a Pmode reg.) becomes b <- a ... *(b += c) post (4) FORM_POST_INC *a ... a <- a + c becomes *(a += c) post There are three types of values of c. 1) c is a constant equal to the width of the value being accessed by the pointer. This is useful for machines that have HAVE_PRE_INCREMENT, HAVE_POST_INCREMENT, HAVE_PRE_DECREMENT or HAVE_POST_DECREMENT defined. 2) c is a constant not equal to the width of the value being accessed by the pointer. This is useful for machines that have HAVE_PRE_MODIFY_DISP, HAVE_POST_MODIFY_DISP defined. 3) c is a register. This is useful for machines that have HAVE_PRE_MODIFY_REG, HAVE_POST_MODIFY_REG The is one special case: if a already had an offset equal to it +- its width and that offset is equal to -c when the increment was before the ref or +c if the increment was after the ref, then if we can do the combination but switch the pre/post bit.
enum gen_form |
enum inc_state |
The states of the second operands of mem refs and inc insns. If no second operand of the mem_ref was found, it is assumed to just be ZERO. SIZE is the size of the mode accessed in the memref. The ANY is used for constants that are not +-size or 0. REG is used if the forms are reg1 + reg2.
|
static |
Change mem_insn.mem_loc so that uses NEW_ADDR which has an increment of INC_REG. To have reached this point, the change is a legitimate one from a dataflow point of view. The only questions are is this a valid change to the instruction and is this a profitable change to the instruction.
References add_reg_note(), delete_insn(), df_recompute_luids(), dump_file, dump_insn_slim(), inc_insn::form, FORM_last, FORM_POST_ADD, FORM_POST_INC, FORM_PRE_ADD, FORM_PRE_INC, insert_move_insn_before(), inc_insn::insn, mem_insn::insn, mem_insn::mem_loc, mem_tmp, move_dead_notes(), new_cost(), optimize_bb_for_speed_p(), inc_insn::reg0, inc_insn::reg1, inc_insn::reg1_is_const, reg_next_def, reg_next_inc_use, reg_next_use, inc_insn::reg_res, replace_equiv_address_nv(), set_rtx_cost(), set_src_cost(), and validate_change().
Referenced by try_merge().
|
static |
Dump the parsed inc insn to FILE.
References dump_insn_slim(), inc_insn::form, FORM_POST_ADD, FORM_POST_INC, FORM_PRE_ADD, FORM_PRE_INC, inc_insn::insn, inc_insn::reg0, inc_insn::reg1, inc_insn::reg1_is_const, inc_insn::reg1_val, and inc_insn::reg_res.
Referenced by find_inc(), and merge_in_block().
|
static |
Dump the parsed mem insn to FILE.
References dump_insn_slim(), mem_insn::insn, mem_insn::reg0, mem_insn::reg1, mem_insn::reg1_is_const, and mem_insn::reg1_val.
Referenced by find_inc(), and merge_in_block().
|
static |
A recursive function that checks all of the mem uses in ADDRESS_OF_X to see if any single one of them is compatible with what has been found in inc_insn. -1 is returned for success. 0 is returned if nothing was found and 1 is returned for failure.
References HOST_WIDE_INT, mem_insn::mem_loc, mem_insn::reg0, inc_insn::reg1, mem_insn::reg1, inc_insn::reg1_is_const, mem_insn::reg1_is_const, inc_insn::reg1_val, mem_insn::reg1_val, inc_insn::reg_res, and rtx_equal_p().
Referenced by merge_in_block().
|
static |
Once a suitable mem reference has been found and the MEM_INSN structure has been filled in, FIND_INC is called to see if there is a suitable add or inc insn that follows the mem reference and determine if it is suitable to merge. In the case where the MEM_INSN has two registers in the reference, this function may be called recursively. The first time looking for an add of the first register, and if that fails, looking for an add of the second register. The FIRST_TRY parameter is used to only allow the parameters to be reversed once.
References count_occurrences(), dump_file, dump_inc_insn(), dump_mem_insn(), inc_insn::form, FORM_POST_ADD, FORM_POST_INC, get_next_ref(), inc_insn::insn, mem_insn::insn, mem_insn::mem_loc, parse_add_or_inc(), inc_insn::reg0, mem_insn::reg0, inc_insn::reg1, mem_insn::reg1, inc_insn::reg1_is_const, mem_insn::reg1_is_const, inc_insn::reg1_val, mem_insn::reg1_val, reg_next_def, reg_next_inc_use, reg_next_use, reg_overlap_mentioned_p(), inc_insn::reg_res, reverse_inc(), reverse_mem(), rtx_equal_p(), targetm, and try_merge().
Referenced by find_mem().
|
static |
A recursive function that walks ADDRESS_OF_X to find all of the mem uses in pat that could be used as an auto inc or dec. It then calls FIND_INC for each one.
References find_inc(), mem_insn::mem_loc, mem_insn::reg0, mem_insn::reg1, mem_insn::reg1_is_const, and mem_insn::reg1_val.
Referenced by merge_in_block().
|
static |
Discover auto-inc auto-dec instructions.
|
static |
Return the next insn that uses (if reg_next_use is passed in NEXT_ARRAY) or defines (if reg_next_def is passed in NEXT_ARRAY) REGNO in BB.
Referenced by find_inc(), and merge_in_block().
|
static |
References decision_table, DISP_POST, DISP_PRE, FORM_POST_ADD, FORM_POST_INC, FORM_PRE_ADD, FORM_PRE_INC, INC_NEG_ANY, INC_NEG_SIZE, INC_POS_ANY, INC_POS_SIZE, INC_REG, INC_ZERO, initialized, REG_POST, REG_PRE, SIMPLE_POST_DEC, SIMPLE_POST_INC, SIMPLE_PRE_DEC, and SIMPLE_PRE_INC.
Referenced by rest_of_handle_auto_inc_dec().
|
static |
Create a mov insn DEST_REG <- SRC_REG and insert it before NEXT_INSN.
References emit_insn_before(), emit_move_insn(), end_sequence(), get_insns(), and start_sequence().
Referenced by attempt_change().
rtl_opt_pass* make_pass_inc_dec | ( | ) |
|
static |
Try to combine all incs and decs by constant values with memory references in BB.
References df_recompute_luids(), dump_file, dump_inc_insn(), dump_insn_slim(), dump_mem_insn(), find_address(), find_mem(), inc_insn::form, FORM_PRE_INC, get_next_ref(), basic_block_def::index, mem_insn::insn, memset(), parse_add_or_inc(), inc_insn::reg1, inc_insn::reg1_is_const, reg_next_def, reg_next_inc_use, reg_next_use, inc_insn::reg_res, and try_merge().
Referenced by rest_of_handle_auto_inc_dec().
|
static |
Move dead note that match PATTERN to TO_INSN from FROM_INSN. We do not really care about moving any other notes from the inc or add insn. Moving the REG_EQUAL and REG_EQUIV is clearly wrong and it does not appear that there are any other kinds of relevant notes.
Referenced by attempt_change().
|
static |
Return true if INSN is of a form "a = b op c" where a and b are regs. op is + if c is a reg and +|- if c is a const. Fill in INC_INSN with what is found. This function is called in two contexts, if BEFORE_MEM is true, this is called for each insn in the basic block. If BEFORE_MEM is false, it is called for the instruction in the block that uses the index register for some memory reference that is currently being processed.
References inc_insn::form, FORM_POST_ADD, FORM_POST_INC, FORM_PRE_ADD, FORM_PRE_INC, inc_insn::insn, inc_insn::pat, inc_insn::reg0, inc_insn::reg1, inc_insn::reg1_is_const, inc_insn::reg1_val, inc_insn::reg_res, reverse_inc(), and rtx_equal_p().
Referenced by find_inc(), and merge_in_block().
|
static |
|
static |
Reverse the operands in a inc insn.
References inc_insn::reg0, and inc_insn::reg1.
Referenced by find_inc(), and parse_add_or_inc().
|
static |
Reverse the operands in a mem insn.
References mem_insn::reg0, and mem_insn::reg1.
Referenced by find_inc().
|
static |
References INC_NEG_ANY, INC_NEG_SIZE, INC_POS_ANY, INC_POS_SIZE, and INC_ZERO.
Referenced by try_merge().
|
static |
Try to combine the instruction in INC_INSN with the instruction in MEM_INSN. First the form is determined using the DECISION_TABLE and the results of parsing the INC_INSN and the MEM_INSN. Assuming the form is ok, a prototype new address is built which is passed to ATTEMPT_CHANGE for final processing.
References attempt_change(), dbg_cnt(), decision_table, DISP_POST, DISP_PRE, dump_file, find_regno_note(), inc_insn::form, FORM_last, FORM_POST_ADD, FORM_POST_INC, FORM_PRE_ADD, FORM_PRE_INC, INC_REG, inc_insn::insn, mem_insn::insn, mem_insn::mem_loc, NOTHING, mem_insn::reg0, inc_insn::reg1, inc_insn::reg1_is_const, mem_insn::reg1_is_const, inc_insn::reg1_state, mem_insn::reg1_state, inc_insn::reg1_val, mem_insn::reg1_val, reg_mode, REG_POST, REG_PRE, inc_insn::reg_res, set_inc_state(), SIMPLE_POST_DEC, SIMPLE_POST_INC, SIMPLE_PRE_DEC, and SIMPLE_PRE_INC.
Referenced by find_inc(), and merge_in_block().
Referenced by init_decision_table(), and try_merge().
|
static |
The DECISION_TABLE that describes what form, if any, the increment or decrement will take. It is a three dimensional table. The first index is the type of constant or register found as the second operand of the inc insn. The second index is the type of constant or register found as the second operand of the memory reference (if no second operand exists, 0 is used). The third index is the form and location (relative to the mem reference) of inc insn.
Referenced by alloc_aux_for_blocks(), alloc_aux_for_edges(), df_set_blocks(), dw_loc_list(), dw_sra_loc_expr(), emit_note_insn_var_location(), init_decision_table(), rest_of_handle_auto_inc_dec(), set_slot_part(), and unshare_variable().
|
static |
Tmp mem rtx for use in cost modeling.
Referenced by attempt_change(), and rest_of_handle_auto_inc_dec().
|
static |
Referenced by attempt_change(), find_inc(), merge_in_block(), and rest_of_handle_auto_inc_dec().
|
static |
Referenced by attempt_change(), find_inc(), merge_in_block(), and rest_of_handle_auto_inc_dec().
|
static |
The following three arrays contain pointers to instructions. They are indexed by REGNO. At any point in the basic block where we are looking these three arrays contain, respectively, the next insn that uses REGNO, the next inc or add insn that uses REGNO and the next insn that sets REGNO. The arrays are not cleared when we move from block to block so whenever an insn is retrieved from these arrays, it's block number must be compared with the current block.
Referenced by attempt_change(), find_inc(), merge_in_block(), and rest_of_handle_auto_inc_dec().