integrate.h revision 117395
1/* Function integration definitions for GNU C-Compiler
2   Copyright (C) 1990, 1995, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 2, or (at your option) any later
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING.  If not, write to the Free
18Software Foundation, 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA.  */
20
21#include "varray.h"
22
23/* This structure is used to remap objects in the function being inlined to
24   those belonging to the calling function.  It is passed by
25   expand_inline_function to its children.
26
27   This structure is also used when unrolling loops and otherwise
28   replicating code, although not all fields are needed in this case;
29   only those fields needed by copy_rtx_and_substitute() and its children
30   are used.
31
32   This structure is used instead of static variables because
33   expand_inline_function may be called recursively via expand_expr.  */
34
35struct inline_remap
36{
37  /* True if we are doing function integration, false otherwise.
38     Used to control whether RTX_UNCHANGING bits are copied by
39     copy_rtx_and_substitute.  */
40  int integrating;
41  /* Definition of function be inlined.  */
42  union tree_node *fndecl;
43  /* Place to put insns needed at start of function.  */
44  rtx insns_at_start;
45  /* Mapping from old BLOCKs to new BLOCKs.  */
46  varray_type block_map;
47  /* Mapping from old registers to new registers.
48     It is allocated and deallocated in `expand_inline_function' */
49  rtx *reg_map;
50#if defined (LEAF_REGISTERS) && defined (LEAF_REG_REMAP)
51  /* Mapping from old leaf registers to new leaf registers.  */
52  rtx leaf_reg_map[FIRST_PSEUDO_REGISTER][NUM_MACHINE_MODES];
53#endif
54  /* Mapping from old code-labels to new code-labels.
55     The first element of this map is label_map[min_labelno].  */
56  rtx *label_map;
57  /* Mapping from old insn uid's to copied insns.  The first element
58   of this map is insn_map[min_insnno]; the last element is
59   insn_map[max_insnno].  We keep the bounds here for when the map
60   only covers a partial range of insns (such as loop unrolling or
61   code replication).  */
62  rtx *insn_map;
63  int min_insnno, max_insnno;
64
65  /* Map pseudo reg number in calling function to equivalent constant.  We
66     cannot in general substitute constants into parameter pseudo registers,
67     since some machine descriptions (many RISCs) won't always handle
68     the resulting insns.  So if an incoming parameter has a constant
69     equivalent, we record it here, and if the resulting insn is
70     recognizable, we go with it.
71
72     We also use this mechanism to convert references to incoming arguments
73     and stacked variables.  copy_rtx_and_substitute will replace the virtual
74     incoming argument and virtual stacked variables registers with new
75     pseudos that contain pointers into the replacement area allocated for
76     this inline instance.  These pseudos are then marked as being equivalent
77     to the appropriate address and substituted if valid.  */
78  varray_type const_equiv_varray;
79  /* This is incremented for each new basic block.
80     It is used to store in the age field to record the domain of validity
81     of each entry in const_equiv_varray.
82     A value of -1 indicates an entry for a reg which is a parm.
83     All other values are "positive".  */
84#define CONST_AGE_PARM (-1)
85  unsigned int const_age;
86
87  /* Target of the inline function being expanded, or NULL if none.  */
88  rtx inline_target;
89  /* When an insn is being copied by copy_rtx_and_substitute,
90     this is nonzero if we have copied an ASM_OPERANDS.
91     In that case, it is the original input-operand vector.  */
92  rtvec orig_asm_operands_vector;
93  /* When an insn is being copied by copy_rtx_and_substitute,
94     this is nonzero if we have copied an ASM_OPERANDS.
95     In that case, it is the copied input-operand vector.  */
96  rtvec copy_asm_operands_vector;
97  /* Likewise, this is the copied constraints vector.  */
98  rtvec copy_asm_constraints_vector;
99
100  /* Target of a return insn, if needed and inlining.  */
101  rtx local_return_label;
102
103  /* Indications for regs being pointers and their alignment.  */
104  unsigned char *regno_pointer_align;
105  rtx *x_regno_reg_rtx;
106
107  /* The next few fields are used for subst_constants to record the SETs
108     that it saw.  */
109  int num_sets;
110  struct equiv_table
111    {
112      rtx dest;
113      rtx equiv;
114    }  equiv_sets[MAX_RECOG_OPERANDS];
115  /* Record the last thing assigned to pc.  This is used for folded
116     conditional branch insns.  */
117  rtx last_pc_value;
118#ifdef HAVE_cc0
119  /* Record the last thing assigned to cc0.  */
120  rtx last_cc0_value;
121#endif
122  /* Note mode of COMPARE if the mode would be otherwise lost (comparing of
123     two VOIDmode constants.  */
124  rtx compare_src;
125  enum machine_mode compare_mode;
126};
127
128/* Return a copy of an rtx (as needed), substituting pseudo-register,
129   labels, and frame-pointer offsets as necessary.  */
130extern rtx copy_rtx_and_substitute PARAMS ((rtx, struct inline_remap *, int));
131
132/* Return a pseudo that corresponds to the value in the specified hard
133   reg as of the start of the function (for inlined functions, the
134   value at the start of the parent function).  */
135extern rtx get_hard_reg_initial_val		PARAMS ((enum machine_mode, int));
136/* Likewise, but for a different than the current function, or
137   arbitrary expression.  */
138extern rtx get_func_hard_reg_initial_val	PARAMS ((struct function *, rtx));
139/* Likewise, but iff someone else has caused it to become allocated.  */
140extern rtx has_func_hard_reg_initial_val	PARAMS ((struct function *, rtx));
141/* Likewise, but for common cases.  */
142extern rtx has_hard_reg_initial_val		PARAMS ((enum machine_mode, int));
143/* If a pseudo represents an initial hard reg (or expression), return
144   it, else return NULL_RTX.  */
145extern rtx get_hard_reg_initial_reg		PARAMS ((struct function *, rtx));
146/* Called from rest_of_compilation.  */
147extern void emit_initial_value_sets		PARAMS ((void));
148extern void allocate_initial_values		PARAMS ((rtx *));
149
150/* Copy a declaration when one function is substituted inline into
151   another.  */
152extern union tree_node *copy_decl_for_inlining PARAMS ((union tree_node *,
153						      union tree_node *,
154						      union tree_node *));
155
156/* Check whether there's any attribute in a function declaration that
157   makes the function uninlinable.  Returns false if it finds any,
158   true otherwise.  */
159extern bool function_attribute_inlinable_p PARAMS ((union tree_node *));
160
161extern void try_constants PARAMS ((rtx, struct inline_remap *));
162
163/* Return the label indicated.  */
164extern rtx get_label_from_map PARAMS ((struct inline_remap *, int));
165
166/* Set the label indicated.  */
167#define set_label_in_map(MAP, I, X) ((MAP)->label_map[I] = (X))
168
169/* Unfortunately, we need a global copy of const_equiv varray for
170   communication with a function called from note_stores.  Be *very*
171   careful that this is used properly in the presence of recursion.  */
172
173extern varray_type global_const_equiv_varray;
174
175#define MAYBE_EXTEND_CONST_EQUIV_VARRAY(MAP,MAX)			\
176  {									\
177    if ((size_t)(MAX) >= VARRAY_SIZE ((MAP)->const_equiv_varray))	\
178      {									\
179        int is_global = (global_const_equiv_varray			\
180			 == (MAP)->const_equiv_varray);			\
181        VARRAY_GROW ((MAP)->const_equiv_varray, (MAX)+1);		\
182	if (is_global)							\
183	   global_const_equiv_varray = (MAP)->const_equiv_varray;	\
184      }									\
185  }
186
187#define SET_CONST_EQUIV_DATA(MAP,REG,RTX,AGE)				\
188  {									\
189    struct const_equiv_data *p;						\
190    MAYBE_EXTEND_CONST_EQUIV_VARRAY ((MAP), REGNO (REG));		\
191    p = &VARRAY_CONST_EQUIV ((MAP)->const_equiv_varray, REGNO (REG));	\
192    p->rtx = (RTX);							\
193    p->age = (AGE);							\
194  }
195