GCC Middle and Back End API Reference
regmove.c File Reference

Data Structures

struct  match

Enumerations

enum  match_use { READ, WRITE, READWRITE }

Functions

static int optimize_reg_copy_1 (rtx, rtx, rtx)
static void optimize_reg_copy_2 (rtx, rtx, rtx)
static void optimize_reg_copy_3 (rtx, rtx, rtx)
static void copy_src_to_dest (rtx, rtx, rtx)
static int find_matches (rtx, struct match *)
static int fixup_match_2 (rtx, rtx, rtx, rtx)
static int regclass_compatible_p ()
static rtx find_use_as_address ()
static int try_auto_increment (rtx insn, rtx inc_insn, rtx inc_insn_set, rtx reg, HOST_WIDE_INT increment, int pre)
static int optimize_reg_copy_1 ()
static void optimize_reg_copy_2 ()
static void optimize_reg_copy_3 ()
static void copy_src_to_dest ()
static bool reg_is_remote_constant_p ()
static int fixup_match_2 ()
static void regmove_forward_pass ()
static void regmove_backward_pass ()
static unsigned int regmove_optimize ()
static int find_matches ()
static bool gate_handle_regmove ()
rtl_opt_passmake_pass_regmove ()

Variables

static int * regno_src_regno
static basic_blockreg_set_in_bb
static unsigned int max_reg_computed

Enumeration Type Documentation

enum match_use
Enumerator:
READ 
WRITE 
READWRITE 

Function Documentation

static void copy_src_to_dest ( rtx  ,
rtx  ,
rtx   
)
static

Referenced by regmove_backward_pass().

static void copy_src_to_dest ( )
static
If we were not able to update the users of src to use dest directly, try
   instead moving the value to dest directly before the operation.   

References emit_insn_before(), emit_move_insn(), end_sequence(), find_reg_note(), get_insns(), move_insn(), reg_mentioned_p(), start_sequence(), and validate_replace_rtx().

static int find_matches ( rtx  ,
struct match  
)
static

Referenced by regmove_backward_pass().

static int find_matches ( )
static
Returns nonzero if INSN's pattern has matching constraints for any operand.
   Returns 0 if INSN can't be recognized, or if the alternative can't be
   determined.

   Initialize the info in MATCHP based on the constraints.   

References match::commutative, constrain_operands(), recog_data_d::constraints, match::early_clobber, extract_insn(), recog_data_d::n_operands, READ, READWRITE, recog_data, targetm, match::use, which_alternative, match::with, and WRITE.

static rtx find_use_as_address ( )
static
Find the place in the rtx X where REG is used as a memory address.
   Return the MEM rtx that so uses it.
   If PLUSCONST is nonzero, search instead for a memory address equivalent to
   (plus REG (const_int PLUSCONST)).

   If such an address does not appear, return 0.
   If REG appears more than once, or is used other than in such an address,
   return (rtx) 1.   

Referenced by try_auto_increment().

static int fixup_match_2 ( rtx  ,
rtx  ,
rtx  ,
rtx   
)
static

Referenced by regmove_backward_pass().

static int fixup_match_2 ( )
static
INSN is adding a CONST_INT to a REG.  We search backwards looking for
   another add immediate instruction with the same source and dest registers,
   and if we find one, we change INSN to an increment, and return 1.  If
   no changes are made, we return 0.

   This changes
     (set (reg100) (plus reg1 offset1))
     ...
     (set (reg100) (plus reg1 offset2))
   to
     (set (reg100) (plus reg1 offset1))
     ...
     (set (reg100) (plus reg100 offset2-offset1))   
??? What does this comment mean?   
cse disrupts preincrement / postdecrement sequences when it finds a
   hard register as ultimate source, like the frame pointer.   

References dump_file, find_reg_fusage(), find_regno_note(), gen_add3_insn(), HOST_WIDE_INT, num_calls(), reg_overlap_mentioned_p(), reg_set_p(), remove_death(), try_auto_increment(), and validate_change().

static bool gate_handle_regmove ( )
static
rtl_opt_pass* make_pass_regmove ( )
static int optimize_reg_copy_1 ( rtx  ,
rtx  ,
rtx   
)
static
@verbatim Move registers around to reduce number of move instructions needed.

Copyright (C) 1987-2013 Free Software Foundation, Inc.

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 module makes some simple RTL code transformations which
   improve the subsequent register allocation.   

Referenced by regmove_forward_pass().

static int optimize_reg_copy_1 ( )
static
INSN is a copy from SRC to DEST, both registers, and SRC does not die
   in INSN.

   Search forward to see if SRC dies before either it or DEST is modified,
   but don't scan past the end of a basic block.  If so, we can replace SRC
   with DEST and let SRC die in INSN.

   This will reduce the number of registers live in that range and may enable
   DEST to be tied to SRC, thus often saving one register in addition to a
   register-register copy.   

References asm_noperands(), dead_or_set_p(), find_reg_fusage(), find_regno_note(), next_real_insn(), reg_mentioned_p(), reg_overlap_mentioned_p(), reg_set_p(), remove_note(), targetm, and validate_replace_rtx().

static void optimize_reg_copy_2 ( rtx  ,
rtx  ,
rtx   
)
static

Referenced by regmove_forward_pass().

static void optimize_reg_copy_2 ( )
static
INSN is a copy of SRC to DEST, in which SRC dies.  See if we now have
   a sequence of insns that modify DEST followed by an insn that sets
   SRC to DEST in which DEST dies, with no prior modification of DEST.
   (There is no need to check if the insns in between actually modify
   DEST.  We should not have cases where DEST is not modified, but
   the optimization is safe if no such modification is detected.)
   In that case, we can replace all uses of DEST, starting with INSN and
   ending with the set of SRC to DEST, with SRC.  We do not do this
   optimization if a CALL_INSN is crossed unless SRC already crosses a
   call or if DEST dies before the copy back to SRC.

   It is assumed that DEST and SRC are pseudos; it is too complicated to do
   this for hard registers since the substitutions we may make might fail.   

References add_reg_note(), df_insn_rescan(), find_reg_note(), reg_mentioned_p(), reg_set_p(), remove_note(), and replace_rtx().

static void optimize_reg_copy_3 ( rtx  ,
rtx  ,
rtx   
)
static

Referenced by regmove_forward_pass().

static void optimize_reg_copy_3 ( )
static
INSN is a ZERO_EXTEND or SIGN_EXTEND of SRC to DEST.
   Look if SRC dies there, and if it is only set once, by loading
   it from memory.  If so, try to incorporate the zero/sign extension
   into the memory read, change SRC to the mode of DEST, and alter
   the remaining accesses to use the appropriate SUBREG.  This allows
   SRC and DEST to be tied later.   

References apply_change_group(), df_notes_rescan(), find_reg_note(), gen_lowpart_SUBREG(), REG_N_SETS(), reg_set_p(), remove_note(), rtx_equal_p(), validate_change(), and validate_replace_rtx_group().

static bool reg_is_remote_constant_p ( )
static
Return whether REG is set in only one location, and is set to a
   constant, but is set in a different basic block from INSN (an
   instructions which uses REG).  In this case REG is equivalent to a
   constant, and we don't want to break that equivalence, because that
   may increase register pressure and make reload harder.  If REG is
   set in the same basic block as INSN, we don't worry about it,
   because we'll probably need a register anyhow (??? but what if REG
   is used in a different basic block as well as this one?).   

References find_reg_note(), max_reg_computed, max_reg_num(), and REG_N_SETS().

Referenced by regmove_backward_pass().

static int regclass_compatible_p ( )
static
Return nonzero if registers with CLASS1 and CLASS2 can be merged without
   causing too much register allocation problems.   

References reg_class_subset_p(), and targetm.

Referenced by regmove_backward_pass().

static void regmove_forward_pass ( )
static
A forward pass.  Replace output operands with input operands.   

References dump_file, find_reg_note(), optimize_reg_copy_1(), optimize_reg_copy_2(), optimize_reg_copy_3(), and regno_src_regno.

Referenced by regmove_optimize().

static int try_auto_increment ( rtx  insn,
rtx  inc_insn,
rtx  inc_insn_set,
rtx  reg,
HOST_WIDE_INT  increment,
int  pre 
)
static
INC_INSN is an instruction that adds INCREMENT to REG.
   Try to fold INC_INSN as a post/pre in/decrement into INSN.
   Iff INC_INSN_SET is nonzero, inc_insn has a destination different from src.
   Return nonzero for success.   

References add_reg_note(), apply_change_group(), delete_insn(), find_reg_note(), find_use_as_address(), and validate_change().

Referenced by fixup_match_2().


Variable Documentation

unsigned int max_reg_computed
static
Size of reg_set_in_bb array.   

Referenced by reg_is_remote_constant_p().

basic_block* reg_set_in_bb
static
reg_set_in_bb[REGNO] points to basic block iff the register is set
   only once in the given block and has REG_EQUAL note.   
int* regno_src_regno
static