1 | /* Function integration definitions for GNU C-Compiler |
---|
2 | Copyright (C) 1990 Free Software Foundation, Inc. |
---|
3 | |
---|
4 | This file is part of GNU CC. |
---|
5 | |
---|
6 | GNU CC is free software; you can redistribute it and/or modify |
---|
7 | it under the terms of the GNU General Public License as published by |
---|
8 | the Free Software Foundation; either version 2, or (at your option) |
---|
9 | any later version. |
---|
10 | |
---|
11 | GNU CC is distributed in the hope that it will be useful, |
---|
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
14 | GNU General Public License for more details. |
---|
15 | |
---|
16 | You should have received a copy of the GNU General Public License |
---|
17 | along with GNU CC; see the file COPYING. If not, write to |
---|
18 | the Free Software Foundation, 59 Temple Place - Suite 330, |
---|
19 | Boston, MA 02111-1307, USA. */ |
---|
20 | |
---|
21 | /* This structure is used to remap objects in the function being inlined to |
---|
22 | those belonging to the calling function. It is passed by |
---|
23 | expand_inline_function to its children. |
---|
24 | |
---|
25 | This structure is also used when unrolling loops and otherwise |
---|
26 | replicating code, although not all fields are needed in this case; |
---|
27 | only those fields needed by copy_rtx_and_substitute() and its children |
---|
28 | are used. |
---|
29 | |
---|
30 | This structure is used instead of static variables because |
---|
31 | expand_inline_function may be called recursively via expand_expr. */ |
---|
32 | |
---|
33 | struct inline_remap |
---|
34 | { |
---|
35 | /* True if we are doing function integration, false otherwise. |
---|
36 | Used to control whether RTX_UNCHANGING bits are copied by |
---|
37 | copy_rtx_and_substitute. */ |
---|
38 | int integrating; |
---|
39 | /* Definition of function be inlined. */ |
---|
40 | union tree_node *fndecl; |
---|
41 | /* Place to put insns needed at start of function. */ |
---|
42 | rtx insns_at_start; |
---|
43 | /* Mapping from old registers to new registers. |
---|
44 | It is allocated and deallocated in `expand_inline_function' */ |
---|
45 | rtx *reg_map; |
---|
46 | /* Mapping from old code-labels to new code-labels. |
---|
47 | The first element of this map is label_map[min_labelno]. */ |
---|
48 | rtx *label_map; |
---|
49 | /* Mapping from old insn uid's to copied insns. The first element |
---|
50 | of this map is insn_map[min_insnno]; the last element is |
---|
51 | insn_map[max_insnno]. We keep the bounds here for when the map |
---|
52 | only covers a partial range of insns (such as loop unrolling or |
---|
53 | code replication). */ |
---|
54 | rtx *insn_map; |
---|
55 | int min_insnno, max_insnno; |
---|
56 | |
---|
57 | /* Map pseudo reg number in calling function to equivalent constant. We |
---|
58 | cannot in general substitute constants into parameter pseudo registers, |
---|
59 | since some machine descriptions (many RISCs) won't always handle |
---|
60 | the resulting insns. So if an incoming parameter has a constant |
---|
61 | equivalent, we record it here, and if the resulting insn is |
---|
62 | recognizable, we go with it. |
---|
63 | |
---|
64 | We also use this mechanism to convert references to incoming arguments |
---|
65 | and stacked variables. copy_rtx_and_substitute will replace the virtual |
---|
66 | incoming argument and virtual stacked variables registers with new |
---|
67 | pseudos that contain pointers into the replacement area allocated for |
---|
68 | this inline instance. These pseudos are then marked as being equivalent |
---|
69 | to the appropriate address and substituted if valid. */ |
---|
70 | rtx *const_equiv_map; |
---|
71 | /* Number of entries in const_equiv_map and const_arg_map. */ |
---|
72 | int const_equiv_map_size; |
---|
73 | /* This is incremented for each new basic block. |
---|
74 | It is used to store in const_age_map to record the domain of validity |
---|
75 | of each entry in const_equiv_map. |
---|
76 | A value of -1 indicates an entry for a reg which is a parm. |
---|
77 | All other values are "positive". */ |
---|
78 | #define CONST_AGE_PARM (-1) |
---|
79 | unsigned int const_age; |
---|
80 | /* In parallel with const_equiv_map, record the valid age for each entry. |
---|
81 | The entry is invalid if its age is less than const_age. */ |
---|
82 | unsigned int *const_age_map; |
---|
83 | /* Target of the inline function being expanded, or NULL if none. */ |
---|
84 | rtx inline_target; |
---|
85 | /* When an insn is being copied by copy_rtx_and_substitute, |
---|
86 | this is nonzero if we have copied an ASM_OPERANDS. |
---|
87 | In that case, it is the original input-operand vector. */ |
---|
88 | rtvec orig_asm_operands_vector; |
---|
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 copied input-operand vector. */ |
---|
92 | rtvec copy_asm_operands_vector; |
---|
93 | /* Likewise, this is the copied constraints vector. */ |
---|
94 | rtvec copy_asm_constraints_vector; |
---|
95 | |
---|
96 | /* The next few fields are used for subst_constants to record the SETs |
---|
97 | that it saw. */ |
---|
98 | int num_sets; |
---|
99 | struct equiv_table |
---|
100 | { |
---|
101 | rtx dest; |
---|
102 | rtx equiv; |
---|
103 | } equiv_sets[MAX_RECOG_OPERANDS]; |
---|
104 | /* Record the last thing assigned to pc. This is used for folded |
---|
105 | conditional branch insns. */ |
---|
106 | rtx last_pc_value; |
---|
107 | #ifdef HAVE_cc0 |
---|
108 | /* Record the last thing assigned to cc0. */ |
---|
109 | rtx last_cc0_value; |
---|
110 | #endif |
---|
111 | }; |
---|
112 | |
---|
113 | /* Return a copy of an rtx (as needed), substituting pseudo-register, |
---|
114 | labels, and frame-pointer offsets as necessary. */ |
---|
115 | extern rtx copy_rtx_and_substitute PROTO((rtx, struct inline_remap *)); |
---|
116 | |
---|
117 | extern void try_constants PROTO((rtx, struct inline_remap *)); |
---|
118 | |
---|
119 | extern void mark_stores PROTO((rtx, rtx)); |
---|
120 | |
---|
121 | /* Unfortunately, we need a global copy of const_equiv map for communication |
---|
122 | with a function called from note_stores. Be *very* careful that this |
---|
123 | is used properly in the presence of recursion. */ |
---|
124 | |
---|
125 | extern rtx *global_const_equiv_map; |
---|
126 | extern int global_const_equiv_map_size; |
---|