Mercurial > hg > CbC > CbC_gcc
annotate gcc/fwprop.c @ 158:494b0b89df80 default tip
...
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 25 May 2020 18:13:55 +0900 |
parents | 1830386684a0 |
children |
rev | line source |
---|---|
0 | 1 /* RTL-based forward propagation pass for GNU compiler. |
145 | 2 Copyright (C) 2005-2020 Free Software Foundation, Inc. |
0 | 3 Contributed by Paolo Bonzini and Steven Bosscher. |
4 | |
5 This file is part of GCC. | |
6 | |
7 GCC is free software; you can redistribute it and/or modify it under | |
8 the terms of the GNU General Public License as published by the Free | |
9 Software Foundation; either version 3, or (at your option) any later | |
10 version. | |
11 | |
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
18 along with GCC; see the file COPYING3. If not see | |
19 <http://www.gnu.org/licenses/>. */ | |
20 | |
21 #include "config.h" | |
22 #include "system.h" | |
23 #include "coretypes.h" | |
111 | 24 #include "backend.h" |
25 #include "target.h" | |
0 | 26 #include "rtl.h" |
111 | 27 #include "predict.h" |
28 #include "df.h" | |
29 #include "memmodel.h" | |
0 | 30 #include "tm_p.h" |
31 #include "insn-config.h" | |
111 | 32 #include "emit-rtl.h" |
0 | 33 #include "recog.h" |
111 | 34 |
35 #include "sparseset.h" | |
36 #include "cfgrtl.h" | |
37 #include "cfgcleanup.h" | |
0 | 38 #include "cfgloop.h" |
39 #include "tree-pass.h" | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
40 #include "domwalk.h" |
111 | 41 #include "rtl-iter.h" |
0 | 42 |
43 | |
44 /* This pass does simple forward propagation and simplification when an | |
45 operand of an insn can only come from a single def. This pass uses | |
46 df.c, so it is global. However, we only do limited analysis of | |
47 available expressions. | |
48 | |
49 1) The pass tries to propagate the source of the def into the use, | |
50 and checks if the result is independent of the substituted value. | |
51 For example, the high word of a (zero_extend:DI (reg:SI M)) is always | |
52 zero, independent of the source register. | |
53 | |
54 In particular, we propagate constants into the use site. Sometimes | |
55 RTL expansion did not put the constant in the same insn on purpose, | |
56 to satisfy a predicate, and the result will fail to be recognized; | |
57 but this happens rarely and in this case we can still create a | |
58 REG_EQUAL note. For multi-word operations, this | |
59 | |
60 (set (subreg:SI (reg:DI 120) 0) (const_int 0)) | |
61 (set (subreg:SI (reg:DI 120) 4) (const_int -1)) | |
62 (set (subreg:SI (reg:DI 122) 0) | |
63 (ior:SI (subreg:SI (reg:DI 119) 0) (subreg:SI (reg:DI 120) 0))) | |
64 (set (subreg:SI (reg:DI 122) 4) | |
65 (ior:SI (subreg:SI (reg:DI 119) 4) (subreg:SI (reg:DI 120) 4))) | |
66 | |
67 can be simplified to the much simpler | |
68 | |
69 (set (subreg:SI (reg:DI 122) 0) (subreg:SI (reg:DI 119))) | |
70 (set (subreg:SI (reg:DI 122) 4) (const_int -1)) | |
71 | |
72 This particular propagation is also effective at putting together | |
73 complex addressing modes. We are more aggressive inside MEMs, in | |
74 that all definitions are propagated if the use is in a MEM; if the | |
75 result is a valid memory address we check address_cost to decide | |
76 whether the substitution is worthwhile. | |
77 | |
78 2) The pass propagates register copies. This is not as effective as | |
79 the copy propagation done by CSE's canon_reg, which works by walking | |
80 the instruction chain, it can help the other transformations. | |
81 | |
82 We should consider removing this optimization, and instead reorder the | |
83 RTL passes, because GCSE does this transformation too. With some luck, | |
84 the CSE pass at the end of rest_of_handle_gcse could also go away. | |
85 | |
86 3) The pass looks for paradoxical subregs that are actually unnecessary. | |
87 Things like this: | |
88 | |
89 (set (reg:QI 120) (subreg:QI (reg:SI 118) 0)) | |
90 (set (reg:QI 121) (subreg:QI (reg:SI 119) 0)) | |
91 (set (reg:SI 122) (plus:SI (subreg:SI (reg:QI 120) 0) | |
92 (subreg:SI (reg:QI 121) 0))) | |
93 | |
94 are very common on machines that can only do word-sized operations. | |
95 For each use of a paradoxical subreg (subreg:WIDER (reg:NARROW N) 0), | |
96 if it has a single def and it is (subreg:NARROW (reg:WIDE M) 0), | |
97 we can replace the paradoxical subreg with simply (reg:WIDE M). The | |
98 above will simplify this to | |
99 | |
100 (set (reg:QI 120) (subreg:QI (reg:SI 118) 0)) | |
101 (set (reg:QI 121) (subreg:QI (reg:SI 119) 0)) | |
102 (set (reg:SI 122) (plus:SI (reg:SI 118) (reg:SI 119))) | |
103 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
104 where the first two insns are now dead. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
105 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
106 We used to use reaching definitions to find which uses have a |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
107 single reaching definition (sounds obvious...), but this is too |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
108 complex a problem in nasty testcases like PR33928. Now we use the |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
109 multiple definitions problem in df-problems.c. The similarity |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
110 between that problem and SSA form creation is taken further, in |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
111 that fwprop does a dominator walk to create its chains; however, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
112 instead of creating a PHI function where multiple definitions meet |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
113 I just punt and record only singleton use-def chains, which is |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
114 all that is needed by fwprop. */ |
0 | 115 |
116 | |
117 static int num_changes; | |
118 | |
111 | 119 static vec<df_ref> use_def_ref; |
120 static vec<df_ref> reg_defs; | |
121 static vec<df_ref> reg_defs_stack; | |
122 | |
123 /* The maximum number of propagations that are still allowed. If we do | |
124 more propagations than originally we had uses, we must have ended up | |
125 in a propagation loop, as in PR79405. Until the algorithm fwprop | |
126 uses can obviously not get into such loops we need a workaround like | |
127 this. */ | |
128 static int propagations_left; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
129 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
130 /* The MD bitmaps are trimmed to include only live registers to cut |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
131 memory usage on testcases like insn-recog.c. Track live registers |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
132 in the basic block and do not perform forward propagation if the |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
133 destination is a dead pseudo occurring in a note. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
134 static bitmap local_md; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
135 static bitmap local_lr; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
136 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
137 /* Return the only def in USE's use-def chain, or NULL if there is |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
138 more than one def in the chain. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
139 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
140 static inline df_ref |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
141 get_def_for_use (df_ref use) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
142 { |
111 | 143 return use_def_ref[DF_REF_ID (use)]; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
144 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
145 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
146 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
147 /* Update the reg_defs vector with non-partial definitions in DEF_REC. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
148 TOP_FLAG says which artificials uses should be used, when DEF_REC |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
149 is an artificial def vector. LOCAL_MD is modified as after a |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
150 df_md_simulate_* function; we do more or less the same processing |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
151 done there, so we do not use those functions. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
152 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
153 #define DF_MD_GEN_FLAGS \ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
154 (DF_REF_PARTIAL | DF_REF_CONDITIONAL | DF_REF_MAY_CLOBBER) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
155 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
156 static void |
111 | 157 process_defs (df_ref def, int top_flag) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
158 { |
111 | 159 for (; def; def = DF_REF_NEXT_LOC (def)) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
160 { |
111 | 161 df_ref curr_def = reg_defs[DF_REF_REGNO (def)]; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
162 unsigned int dregno; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
163 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
164 if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) != top_flag) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
165 continue; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
166 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
167 dregno = DF_REF_REGNO (def); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
168 if (curr_def) |
111 | 169 reg_defs_stack.safe_push (curr_def); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
170 else |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
171 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
172 /* Do not store anything if "transitioning" from NULL to NULL. But |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
173 otherwise, push a special entry on the stack to tell the |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
174 leave_block callback that the entry in reg_defs was NULL. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
175 if (DF_REF_FLAGS (def) & DF_MD_GEN_FLAGS) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
176 ; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
177 else |
111 | 178 reg_defs_stack.safe_push (def); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
179 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
180 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
181 if (DF_REF_FLAGS (def) & DF_MD_GEN_FLAGS) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
182 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
183 bitmap_set_bit (local_md, dregno); |
111 | 184 reg_defs[dregno] = NULL; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
185 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
186 else |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
187 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
188 bitmap_clear_bit (local_md, dregno); |
111 | 189 reg_defs[dregno] = def; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
190 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
191 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
192 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
193 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
194 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
195 /* Fill the use_def_ref vector with values for the uses in USE_REC, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
196 taking reaching definitions info from LOCAL_MD and REG_DEFS. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
197 TOP_FLAG says which artificials uses should be used, when USE_REC |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
198 is an artificial use vector. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
199 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
200 static void |
111 | 201 process_uses (df_ref use, int top_flag) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
202 { |
111 | 203 for (; use; use = DF_REF_NEXT_LOC (use)) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
204 if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == top_flag) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
205 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
206 unsigned int uregno = DF_REF_REGNO (use); |
111 | 207 if (reg_defs[uregno] |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
208 && !bitmap_bit_p (local_md, uregno) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
209 && bitmap_bit_p (local_lr, uregno)) |
111 | 210 use_def_ref[DF_REF_ID (use)] = reg_defs[uregno]; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
211 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
212 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
213 |
111 | 214 class single_def_use_dom_walker : public dom_walker |
215 { | |
216 public: | |
217 single_def_use_dom_walker (cdi_direction direction) | |
218 : dom_walker (direction) {} | |
219 virtual edge before_dom_children (basic_block); | |
220 virtual void after_dom_children (basic_block); | |
221 }; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
222 |
111 | 223 edge |
224 single_def_use_dom_walker::before_dom_children (basic_block bb) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
225 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
226 int bb_index = bb->index; |
145 | 227 class df_md_bb_info *md_bb_info = df_md_get_bb_info (bb_index); |
228 class df_lr_bb_info *lr_bb_info = df_lr_get_bb_info (bb_index); | |
111 | 229 rtx_insn *insn; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
230 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
231 bitmap_copy (local_md, &md_bb_info->in); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
232 bitmap_copy (local_lr, &lr_bb_info->in); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
233 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
234 /* Push a marker for the leave_block callback. */ |
111 | 235 reg_defs_stack.safe_push (NULL); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
236 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
237 process_uses (df_get_artificial_uses (bb_index), DF_REF_AT_TOP); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
238 process_defs (df_get_artificial_defs (bb_index), DF_REF_AT_TOP); |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
239 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
240 /* We don't call df_simulate_initialize_forwards, as it may overestimate |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
241 the live registers if there are unused artificial defs. We prefer |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
242 liveness to be underestimated. */ |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
243 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
244 FOR_BB_INSNS (bb, insn) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
245 if (INSN_P (insn)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
246 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
247 unsigned int uid = INSN_UID (insn); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
248 process_uses (DF_INSN_UID_USES (uid), 0); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
249 process_uses (DF_INSN_UID_EQ_USES (uid), 0); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
250 process_defs (DF_INSN_UID_DEFS (uid), 0); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
251 df_simulate_one_insn_forwards (bb, insn, local_lr); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
252 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
253 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
254 process_uses (df_get_artificial_uses (bb_index), 0); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
255 process_defs (df_get_artificial_defs (bb_index), 0); |
111 | 256 |
257 return NULL; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
258 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
259 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
260 /* Pop the definitions created in this basic block when leaving its |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
261 dominated parts. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
262 |
111 | 263 void |
264 single_def_use_dom_walker::after_dom_children (basic_block bb ATTRIBUTE_UNUSED) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
265 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
266 df_ref saved_def; |
111 | 267 while ((saved_def = reg_defs_stack.pop ()) != NULL) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
268 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
269 unsigned int dregno = DF_REF_REGNO (saved_def); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
270 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
271 /* See also process_defs. */ |
111 | 272 if (saved_def == reg_defs[dregno]) |
273 reg_defs[dregno] = NULL; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
274 else |
111 | 275 reg_defs[dregno] = saved_def; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
276 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
277 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
278 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
279 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
280 /* Build a vector holding the reaching definitions of uses reached by a |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
281 single dominating definition. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
282 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
283 static void |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
284 build_single_def_use_links (void) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
285 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
286 /* We use the multiple definitions problem to compute our restricted |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
287 use-def chains. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
288 df_set_flags (DF_EQ_NOTES); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
289 df_md_add_problem (); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
290 df_note_add_problem (); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
291 df_analyze (); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
292 df_maybe_reorganize_use_refs (DF_REF_ORDER_BY_INSN_WITH_NOTES); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
293 |
111 | 294 use_def_ref.create (DF_USES_TABLE_SIZE ()); |
295 use_def_ref.safe_grow_cleared (DF_USES_TABLE_SIZE ()); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
296 |
111 | 297 reg_defs.create (max_reg_num ()); |
298 reg_defs.safe_grow_cleared (max_reg_num ()); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
299 |
111 | 300 reg_defs_stack.create (n_basic_blocks_for_fn (cfun) * 10); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
301 local_md = BITMAP_ALLOC (NULL); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
302 local_lr = BITMAP_ALLOC (NULL); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
303 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
304 /* Walk the dominator tree looking for single reaching definitions |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
305 dominating the uses. This is similar to how SSA form is built. */ |
111 | 306 single_def_use_dom_walker (CDI_DOMINATORS) |
307 .walk (cfun->cfg->x_entry_block_ptr); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
308 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
309 BITMAP_FREE (local_lr); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
310 BITMAP_FREE (local_md); |
111 | 311 reg_defs.release (); |
312 reg_defs_stack.release (); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
313 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
314 |
0 | 315 |
316 /* Do not try to replace constant addresses or addresses of local and | |
317 argument slots. These MEM expressions are made only once and inserted | |
318 in many instructions, as well as being used to control symbol table | |
319 output. It is not safe to clobber them. | |
320 | |
321 There are some uncommon cases where the address is already in a register | |
322 for some reason, but we cannot take advantage of that because we have | |
323 no easy way to unshare the MEM. In addition, looking up all stack | |
324 addresses is costly. */ | |
325 | |
326 static bool | |
327 can_simplify_addr (rtx addr) | |
328 { | |
329 rtx reg; | |
330 | |
331 if (CONSTANT_ADDRESS_P (addr)) | |
332 return false; | |
333 | |
334 if (GET_CODE (addr) == PLUS) | |
335 reg = XEXP (addr, 0); | |
336 else | |
337 reg = addr; | |
338 | |
339 return (!REG_P (reg) | |
340 || (REGNO (reg) != FRAME_POINTER_REGNUM | |
341 && REGNO (reg) != HARD_FRAME_POINTER_REGNUM | |
342 && REGNO (reg) != ARG_POINTER_REGNUM)); | |
343 } | |
344 | |
345 /* Returns a canonical version of X for the address, from the point of view, | |
346 that all multiplications are represented as MULT instead of the multiply | |
347 by a power of 2 being represented as ASHIFT. | |
348 | |
349 Every ASHIFT we find has been made by simplify_gen_binary and was not | |
350 there before, so it is not shared. So we can do this in place. */ | |
351 | |
352 static void | |
353 canonicalize_address (rtx x) | |
354 { | |
355 for (;;) | |
356 switch (GET_CODE (x)) | |
357 { | |
358 case ASHIFT: | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
359 if (CONST_INT_P (XEXP (x, 1)) |
111 | 360 && INTVAL (XEXP (x, 1)) < GET_MODE_UNIT_BITSIZE (GET_MODE (x)) |
361 && INTVAL (XEXP (x, 1)) >= 0) | |
0 | 362 { |
363 HOST_WIDE_INT shift = INTVAL (XEXP (x, 1)); | |
364 PUT_CODE (x, MULT); | |
111 | 365 XEXP (x, 1) = gen_int_mode (HOST_WIDE_INT_1 << shift, |
0 | 366 GET_MODE (x)); |
367 } | |
368 | |
369 x = XEXP (x, 0); | |
370 break; | |
371 | |
372 case PLUS: | |
373 if (GET_CODE (XEXP (x, 0)) == PLUS | |
374 || GET_CODE (XEXP (x, 0)) == ASHIFT | |
375 || GET_CODE (XEXP (x, 0)) == CONST) | |
376 canonicalize_address (XEXP (x, 0)); | |
377 | |
378 x = XEXP (x, 1); | |
379 break; | |
380 | |
381 case CONST: | |
382 x = XEXP (x, 0); | |
383 break; | |
384 | |
385 default: | |
386 return; | |
387 } | |
388 } | |
389 | |
390 /* OLD is a memory address. Return whether it is good to use NEW instead, | |
391 for a memory access in the given MODE. */ | |
392 | |
393 static bool | |
111 | 394 should_replace_address (rtx old_rtx, rtx new_rtx, machine_mode mode, |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
395 addr_space_t as, bool speed) |
0 | 396 { |
397 int gain; | |
398 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
399 if (rtx_equal_p (old_rtx, new_rtx) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
400 || !memory_address_addr_space_p (mode, new_rtx, as)) |
0 | 401 return false; |
402 | |
403 /* Copy propagation is always ok. */ | |
404 if (REG_P (old_rtx) && REG_P (new_rtx)) | |
405 return true; | |
406 | |
407 /* Prefer the new address if it is less expensive. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
408 gain = (address_cost (old_rtx, mode, as, speed) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
409 - address_cost (new_rtx, mode, as, speed)); |
0 | 410 |
411 /* If the addresses have equivalent cost, prefer the new address | |
111 | 412 if it has the highest `set_src_cost'. That has the potential of |
0 | 413 eliminating the most insns without additional costs, and it |
414 is the same that cse.c used to do. */ | |
415 if (gain == 0) | |
111 | 416 gain = (set_src_cost (new_rtx, VOIDmode, speed) |
417 - set_src_cost (old_rtx, VOIDmode, speed)); | |
0 | 418 |
419 return (gain > 0); | |
420 } | |
421 | |
422 | |
423 /* Flags for the last parameter of propagate_rtx_1. */ | |
424 | |
425 enum { | |
426 /* If PR_CAN_APPEAR is true, propagate_rtx_1 always returns true; | |
427 if it is false, propagate_rtx_1 returns false if, for at least | |
428 one occurrence OLD, it failed to collapse the result to a constant. | |
429 For example, (mult:M (reg:M A) (minus:M (reg:M B) (reg:M A))) may | |
430 collapse to zero if replacing (reg:M B) with (reg:M A). | |
431 | |
432 PR_CAN_APPEAR is disregarded inside MEMs: in that case, | |
433 propagate_rtx_1 just tries to make cheaper and valid memory | |
434 addresses. */ | |
435 PR_CAN_APPEAR = 1, | |
436 | |
437 /* If PR_HANDLE_MEM is not set, propagate_rtx_1 won't attempt any replacement | |
438 outside memory addresses. This is needed because propagate_rtx_1 does | |
439 not do any analysis on memory; thus it is very conservative and in general | |
440 it will fail if non-read-only MEMs are found in the source expression. | |
441 | |
442 PR_HANDLE_MEM is set when the source of the propagation was not | |
443 another MEM. Then, it is safe not to treat non-read-only MEMs as | |
444 ``opaque'' objects. */ | |
445 PR_HANDLE_MEM = 2, | |
446 | |
447 /* Set when costs should be optimized for speed. */ | |
448 PR_OPTIMIZE_FOR_SPEED = 4 | |
449 }; | |
450 | |
145 | 451 /* Check that X has a single def. */ |
452 | |
453 static bool | |
454 reg_single_def_p (rtx x) | |
455 { | |
456 if (!REG_P (x)) | |
457 return false; | |
458 | |
459 int regno = REGNO (x); | |
460 return (DF_REG_DEF_COUNT (regno) == 1 | |
461 && !bitmap_bit_p (DF_LR_OUT (ENTRY_BLOCK_PTR_FOR_FN (cfun)), regno)); | |
462 } | |
0 | 463 |
464 /* Replace all occurrences of OLD in *PX with NEW and try to simplify the | |
465 resulting expression. Replace *PX with a new RTL expression if an | |
466 occurrence of OLD was found. | |
467 | |
468 This is only a wrapper around simplify-rtx.c: do not add any pattern | |
469 matching code here. (The sole exception is the handling of LO_SUM, but | |
470 that is because there is no simplify_gen_* function for LO_SUM). */ | |
471 | |
472 static bool | |
473 propagate_rtx_1 (rtx *px, rtx old_rtx, rtx new_rtx, int flags) | |
474 { | |
475 rtx x = *px, tem = NULL_RTX, op0, op1, op2; | |
476 enum rtx_code code = GET_CODE (x); | |
111 | 477 machine_mode mode = GET_MODE (x); |
478 machine_mode op_mode; | |
0 | 479 bool can_appear = (flags & PR_CAN_APPEAR) != 0; |
480 bool valid_ops = true; | |
481 | |
482 if (!(flags & PR_HANDLE_MEM) && MEM_P (x) && !MEM_READONLY_P (x)) | |
483 { | |
484 /* If unsafe, change MEMs to CLOBBERs or SCRATCHes (to preserve whether | |
485 they have side effects or not). */ | |
486 *px = (side_effects_p (x) | |
487 ? gen_rtx_CLOBBER (GET_MODE (x), const0_rtx) | |
488 : gen_rtx_SCRATCH (GET_MODE (x))); | |
489 return false; | |
490 } | |
491 | |
492 /* If X is OLD_RTX, return NEW_RTX. But not if replacing only within an | |
493 address, and we are *not* inside one. */ | |
494 if (x == old_rtx) | |
495 { | |
496 *px = new_rtx; | |
497 return can_appear; | |
498 } | |
499 | |
500 /* If this is an expression, try recursive substitution. */ | |
501 switch (GET_RTX_CLASS (code)) | |
502 { | |
503 case RTX_UNARY: | |
504 op0 = XEXP (x, 0); | |
505 op_mode = GET_MODE (op0); | |
506 valid_ops &= propagate_rtx_1 (&op0, old_rtx, new_rtx, flags); | |
507 if (op0 == XEXP (x, 0)) | |
508 return true; | |
509 tem = simplify_gen_unary (code, mode, op0, op_mode); | |
510 break; | |
511 | |
512 case RTX_BIN_ARITH: | |
513 case RTX_COMM_ARITH: | |
514 op0 = XEXP (x, 0); | |
515 op1 = XEXP (x, 1); | |
516 valid_ops &= propagate_rtx_1 (&op0, old_rtx, new_rtx, flags); | |
517 valid_ops &= propagate_rtx_1 (&op1, old_rtx, new_rtx, flags); | |
518 if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1)) | |
519 return true; | |
520 tem = simplify_gen_binary (code, mode, op0, op1); | |
521 break; | |
522 | |
523 case RTX_COMPARE: | |
524 case RTX_COMM_COMPARE: | |
525 op0 = XEXP (x, 0); | |
526 op1 = XEXP (x, 1); | |
527 op_mode = GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1); | |
528 valid_ops &= propagate_rtx_1 (&op0, old_rtx, new_rtx, flags); | |
529 valid_ops &= propagate_rtx_1 (&op1, old_rtx, new_rtx, flags); | |
530 if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1)) | |
531 return true; | |
532 tem = simplify_gen_relational (code, mode, op_mode, op0, op1); | |
533 break; | |
534 | |
535 case RTX_TERNARY: | |
536 case RTX_BITFIELD_OPS: | |
537 op0 = XEXP (x, 0); | |
538 op1 = XEXP (x, 1); | |
539 op2 = XEXP (x, 2); | |
540 op_mode = GET_MODE (op0); | |
541 valid_ops &= propagate_rtx_1 (&op0, old_rtx, new_rtx, flags); | |
542 valid_ops &= propagate_rtx_1 (&op1, old_rtx, new_rtx, flags); | |
543 valid_ops &= propagate_rtx_1 (&op2, old_rtx, new_rtx, flags); | |
544 if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1) && op2 == XEXP (x, 2)) | |
545 return true; | |
546 if (op_mode == VOIDmode) | |
547 op_mode = GET_MODE (op0); | |
548 tem = simplify_gen_ternary (code, mode, op_mode, op0, op1, op2); | |
549 break; | |
550 | |
551 case RTX_EXTRA: | |
552 /* The only case we try to handle is a SUBREG. */ | |
553 if (code == SUBREG) | |
554 { | |
555 op0 = XEXP (x, 0); | |
556 valid_ops &= propagate_rtx_1 (&op0, old_rtx, new_rtx, flags); | |
557 if (op0 == XEXP (x, 0)) | |
558 return true; | |
559 tem = simplify_gen_subreg (mode, op0, GET_MODE (SUBREG_REG (x)), | |
560 SUBREG_BYTE (x)); | |
561 } | |
145 | 562 |
563 else | |
564 { | |
565 rtvec vec; | |
566 rtvec newvec; | |
567 const char *fmt = GET_RTX_FORMAT (code); | |
568 rtx op; | |
569 | |
570 for (int i = 0; fmt[i]; i++) | |
571 switch (fmt[i]) | |
572 { | |
573 case 'E': | |
574 vec = XVEC (x, i); | |
575 newvec = vec; | |
576 for (int j = 0; j < GET_NUM_ELEM (vec); j++) | |
577 { | |
578 op = RTVEC_ELT (vec, j); | |
579 valid_ops &= propagate_rtx_1 (&op, old_rtx, new_rtx, flags); | |
580 if (op != RTVEC_ELT (vec, j)) | |
581 { | |
582 if (newvec == vec) | |
583 { | |
584 newvec = shallow_copy_rtvec (vec); | |
585 if (!tem) | |
586 tem = shallow_copy_rtx (x); | |
587 XVEC (tem, i) = newvec; | |
588 } | |
589 RTVEC_ELT (newvec, j) = op; | |
590 } | |
591 } | |
592 break; | |
593 | |
594 case 'e': | |
595 if (XEXP (x, i)) | |
596 { | |
597 op = XEXP (x, i); | |
598 valid_ops &= propagate_rtx_1 (&op, old_rtx, new_rtx, flags); | |
599 if (op != XEXP (x, i)) | |
600 { | |
601 if (!tem) | |
602 tem = shallow_copy_rtx (x); | |
603 XEXP (tem, i) = op; | |
604 } | |
605 } | |
606 break; | |
607 } | |
608 } | |
609 | |
0 | 610 break; |
611 | |
612 case RTX_OBJ: | |
613 if (code == MEM && x != new_rtx) | |
614 { | |
615 rtx new_op0; | |
616 op0 = XEXP (x, 0); | |
617 | |
618 /* There are some addresses that we cannot work on. */ | |
619 if (!can_simplify_addr (op0)) | |
620 return true; | |
621 | |
622 op0 = new_op0 = targetm.delegitimize_address (op0); | |
623 valid_ops &= propagate_rtx_1 (&new_op0, old_rtx, new_rtx, | |
624 flags | PR_CAN_APPEAR); | |
625 | |
626 /* Dismiss transformation that we do not want to carry on. */ | |
627 if (!valid_ops | |
628 || new_op0 == op0 | |
629 || !(GET_MODE (new_op0) == GET_MODE (op0) | |
630 || GET_MODE (new_op0) == VOIDmode)) | |
631 return true; | |
632 | |
633 canonicalize_address (new_op0); | |
634 | |
635 /* Copy propagations are always ok. Otherwise check the costs. */ | |
636 if (!(REG_P (old_rtx) && REG_P (new_rtx)) | |
637 && !should_replace_address (op0, new_op0, GET_MODE (x), | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
638 MEM_ADDR_SPACE (x), |
0 | 639 flags & PR_OPTIMIZE_FOR_SPEED)) |
640 return true; | |
641 | |
642 tem = replace_equiv_address_nv (x, new_op0); | |
643 } | |
644 | |
645 else if (code == LO_SUM) | |
646 { | |
647 op0 = XEXP (x, 0); | |
648 op1 = XEXP (x, 1); | |
649 | |
650 /* The only simplification we do attempts to remove references to op0 | |
651 or make it constant -- in both cases, op0's invalidity will not | |
652 make the result invalid. */ | |
653 propagate_rtx_1 (&op0, old_rtx, new_rtx, flags | PR_CAN_APPEAR); | |
654 valid_ops &= propagate_rtx_1 (&op1, old_rtx, new_rtx, flags); | |
655 if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1)) | |
656 return true; | |
657 | |
658 /* (lo_sum (high x) x) -> x */ | |
659 if (GET_CODE (op0) == HIGH && rtx_equal_p (XEXP (op0, 0), op1)) | |
660 tem = op1; | |
661 else | |
662 tem = gen_rtx_LO_SUM (mode, op0, op1); | |
663 | |
664 /* OP1 is likely not a legitimate address, otherwise there would have | |
665 been no LO_SUM. We want it to disappear if it is invalid, return | |
666 false in that case. */ | |
667 return memory_address_p (mode, tem); | |
668 } | |
669 | |
670 else if (code == REG) | |
671 { | |
672 if (rtx_equal_p (x, old_rtx)) | |
673 { | |
674 *px = new_rtx; | |
675 return can_appear; | |
676 } | |
677 } | |
678 break; | |
679 | |
680 default: | |
681 break; | |
682 } | |
683 | |
684 /* No change, no trouble. */ | |
685 if (tem == NULL_RTX) | |
686 return true; | |
687 | |
688 *px = tem; | |
689 | |
111 | 690 /* Allow replacements that simplify operations on a vector or complex |
691 value to a component. The most prominent case is | |
692 (subreg ([vec_]concat ...)). */ | |
693 if (REG_P (tem) && !HARD_REGISTER_P (tem) | |
694 && (VECTOR_MODE_P (GET_MODE (new_rtx)) | |
695 || COMPLEX_MODE_P (GET_MODE (new_rtx))) | |
696 && GET_MODE (tem) == GET_MODE_INNER (GET_MODE (new_rtx))) | |
697 return true; | |
698 | |
0 | 699 /* The replacement we made so far is valid, if all of the recursive |
700 replacements were valid, or we could simplify everything to | |
701 a constant. */ | |
702 return valid_ops || can_appear || CONSTANT_P (tem); | |
703 } | |
704 | |
705 | |
111 | 706 /* Return true if X constains a non-constant mem. */ |
0 | 707 |
111 | 708 static bool |
709 varying_mem_p (const_rtx x) | |
0 | 710 { |
111 | 711 subrtx_iterator::array_type array; |
712 FOR_EACH_SUBRTX (iter, array, x, NONCONST) | |
713 if (MEM_P (*iter) && !MEM_READONLY_P (*iter)) | |
714 return true; | |
715 return false; | |
0 | 716 } |
717 | |
718 | |
719 /* Replace all occurrences of OLD in X with NEW and try to simplify the | |
720 resulting expression (in mode MODE). Return a new expression if it is | |
721 a constant, otherwise X. | |
722 | |
723 Simplifications where occurrences of NEW collapse to a constant are always | |
724 accepted. All simplifications are accepted if NEW is a pseudo too. | |
725 Otherwise, we accept simplifications that have a lower or equal cost. */ | |
726 | |
727 static rtx | |
111 | 728 propagate_rtx (rtx x, machine_mode mode, rtx old_rtx, rtx new_rtx, |
0 | 729 bool speed) |
730 { | |
731 rtx tem; | |
732 bool collapsed; | |
733 int flags; | |
734 | |
735 if (REG_P (new_rtx) && REGNO (new_rtx) < FIRST_PSEUDO_REGISTER) | |
736 return NULL_RTX; | |
737 | |
738 flags = 0; | |
111 | 739 if (REG_P (new_rtx) |
740 || CONSTANT_P (new_rtx) | |
741 || (GET_CODE (new_rtx) == SUBREG | |
742 && REG_P (SUBREG_REG (new_rtx)) | |
145 | 743 && !paradoxical_subreg_p (new_rtx))) |
0 | 744 flags |= PR_CAN_APPEAR; |
111 | 745 if (!varying_mem_p (new_rtx)) |
0 | 746 flags |= PR_HANDLE_MEM; |
747 | |
748 if (speed) | |
749 flags |= PR_OPTIMIZE_FOR_SPEED; | |
750 | |
751 tem = x; | |
752 collapsed = propagate_rtx_1 (&tem, old_rtx, copy_rtx (new_rtx), flags); | |
753 if (tem == x || !collapsed) | |
754 return NULL_RTX; | |
755 | |
756 /* gen_lowpart_common will not be able to process VOIDmode entities other | |
757 than CONST_INTs. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
758 if (GET_MODE (tem) == VOIDmode && !CONST_INT_P (tem)) |
0 | 759 return NULL_RTX; |
760 | |
761 if (GET_MODE (tem) == VOIDmode) | |
762 tem = rtl_hooks.gen_lowpart_no_emit (mode, tem); | |
763 else | |
764 gcc_assert (GET_MODE (tem) == mode); | |
765 | |
766 return tem; | |
767 } | |
768 | |
769 | |
770 | |
771 | |
772 /* Return true if the register from reference REF is killed | |
773 between FROM to (but not including) TO. */ | |
774 | |
775 static bool | |
111 | 776 local_ref_killed_between_p (df_ref ref, rtx_insn *from, rtx_insn *to) |
0 | 777 { |
111 | 778 rtx_insn *insn; |
0 | 779 |
780 for (insn = from; insn != to; insn = NEXT_INSN (insn)) | |
781 { | |
111 | 782 df_ref def; |
0 | 783 if (!INSN_P (insn)) |
784 continue; | |
785 | |
111 | 786 FOR_EACH_INSN_DEF (def, insn) |
787 if (DF_REF_REGNO (ref) == DF_REF_REGNO (def)) | |
788 return true; | |
0 | 789 } |
790 return false; | |
791 } | |
792 | |
793 | |
145 | 794 /* Check if USE is killed between DEF_INSN and TARGET_INSN. This would |
795 require full computation of available expressions; we check only a few | |
796 restricted conditions: | |
797 - if the reg in USE has only one definition, go ahead; | |
798 - in the same basic block, we check for no definitions killing the use; | |
799 - if TARGET_INSN's basic block has DEF_INSN's basic block as its sole | |
800 predecessor, we check if the use is killed after DEF_INSN or before | |
0 | 801 TARGET_INSN insn, in their respective basic blocks. */ |
145 | 802 |
0 | 803 static bool |
111 | 804 use_killed_between (df_ref use, rtx_insn *def_insn, rtx_insn *target_insn) |
0 | 805 { |
806 basic_block def_bb = BLOCK_FOR_INSN (def_insn); | |
807 basic_block target_bb = BLOCK_FOR_INSN (target_insn); | |
808 int regno; | |
809 df_ref def; | |
810 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
811 /* We used to have a def reaching a use that is _before_ the def, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
812 with the def not dominating the use even though the use and def |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
813 are in the same basic block, when a register may be used |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
814 uninitialized in a loop. This should not happen anymore since |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
815 we do not use reaching definitions, but still we test for such |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
816 cases and assume that DEF is not available. */ |
0 | 817 if (def_bb == target_bb |
818 ? DF_INSN_LUID (def_insn) >= DF_INSN_LUID (target_insn) | |
819 : !dominated_by_p (CDI_DOMINATORS, target_bb, def_bb)) | |
820 return true; | |
821 | |
822 /* Check if the reg in USE has only one definition. We already | |
823 know that this definition reaches use, or we wouldn't be here. | |
824 However, this is invalid for hard registers because if they are | |
825 live at the beginning of the function it does not mean that we | |
145 | 826 have an uninitialized access. And we have to check for the case |
827 where a register may be used uninitialized in a loop as above. */ | |
0 | 828 regno = DF_REF_REGNO (use); |
829 def = DF_REG_DEF_CHAIN (regno); | |
830 if (def | |
831 && DF_REF_NEXT_REG (def) == NULL | |
145 | 832 && regno >= FIRST_PSEUDO_REGISTER |
833 && (BLOCK_FOR_INSN (DF_REF_INSN (def)) == def_bb | |
834 ? DF_INSN_LUID (DF_REF_INSN (def)) < DF_INSN_LUID (def_insn) | |
835 : dominated_by_p (CDI_DOMINATORS, | |
836 def_bb, BLOCK_FOR_INSN (DF_REF_INSN (def))))) | |
0 | 837 return false; |
838 | |
839 /* Check locally if we are in the same basic block. */ | |
840 if (def_bb == target_bb) | |
841 return local_ref_killed_between_p (use, def_insn, target_insn); | |
842 | |
843 /* Finally, if DEF_BB is the sole predecessor of TARGET_BB. */ | |
844 if (single_pred_p (target_bb) | |
845 && single_pred (target_bb) == def_bb) | |
846 { | |
847 df_ref x; | |
848 | |
849 /* See if USE is killed between DEF_INSN and the last insn in the | |
850 basic block containing DEF_INSN. */ | |
851 x = df_bb_regno_last_def_find (def_bb, regno); | |
852 if (x && DF_INSN_LUID (DF_REF_INSN (x)) >= DF_INSN_LUID (def_insn)) | |
853 return true; | |
854 | |
855 /* See if USE is killed between TARGET_INSN and the first insn in the | |
856 basic block containing TARGET_INSN. */ | |
857 x = df_bb_regno_first_def_find (target_bb, regno); | |
858 if (x && DF_INSN_LUID (DF_REF_INSN (x)) < DF_INSN_LUID (target_insn)) | |
859 return true; | |
860 | |
861 return false; | |
862 } | |
863 | |
864 /* Otherwise assume the worst case. */ | |
865 return true; | |
866 } | |
867 | |
868 | |
869 /* Check if all uses in DEF_INSN can be used in TARGET_INSN. This | |
870 would require full computation of available expressions; | |
871 we check only restricted conditions, see use_killed_between. */ | |
872 static bool | |
111 | 873 all_uses_available_at (rtx_insn *def_insn, rtx_insn *target_insn) |
0 | 874 { |
111 | 875 df_ref use; |
0 | 876 struct df_insn_info *insn_info = DF_INSN_INFO_GET (def_insn); |
877 rtx def_set = single_set (def_insn); | |
111 | 878 rtx_insn *next; |
0 | 879 |
880 gcc_assert (def_set); | |
881 | |
882 /* If target_insn comes right after def_insn, which is very common | |
111 | 883 for addresses, we can use a quicker test. Ignore debug insns |
884 other than target insns for this. */ | |
885 next = NEXT_INSN (def_insn); | |
886 while (next && next != target_insn && DEBUG_INSN_P (next)) | |
887 next = NEXT_INSN (next); | |
888 if (next == target_insn && REG_P (SET_DEST (def_set))) | |
0 | 889 { |
890 rtx def_reg = SET_DEST (def_set); | |
891 | |
892 /* If the insn uses the reg that it defines, the substitution is | |
893 invalid. */ | |
111 | 894 FOR_EACH_INSN_INFO_USE (use, insn_info) |
895 if (rtx_equal_p (DF_REF_REG (use), def_reg)) | |
896 return false; | |
897 FOR_EACH_INSN_INFO_EQ_USE (use, insn_info) | |
898 if (rtx_equal_p (DF_REF_REG (use), def_reg)) | |
899 return false; | |
0 | 900 } |
901 else | |
902 { | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
903 rtx def_reg = REG_P (SET_DEST (def_set)) ? SET_DEST (def_set) : NULL_RTX; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
904 |
0 | 905 /* Look at all the uses of DEF_INSN, and see if they are not |
906 killed between DEF_INSN and TARGET_INSN. */ | |
111 | 907 FOR_EACH_INSN_INFO_USE (use, insn_info) |
0 | 908 { |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
909 if (def_reg && rtx_equal_p (DF_REF_REG (use), def_reg)) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
910 return false; |
0 | 911 if (use_killed_between (use, def_insn, target_insn)) |
912 return false; | |
913 } | |
111 | 914 FOR_EACH_INSN_INFO_EQ_USE (use, insn_info) |
0 | 915 { |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
916 if (def_reg && rtx_equal_p (DF_REF_REG (use), def_reg)) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
917 return false; |
0 | 918 if (use_killed_between (use, def_insn, target_insn)) |
919 return false; | |
920 } | |
921 } | |
922 | |
923 return true; | |
924 } | |
925 | |
926 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
927 static df_ref *active_defs; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
928 static sparseset active_defs_check; |
0 | 929 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
930 /* Fill the ACTIVE_DEFS array with the use->def link for the registers |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
931 mentioned in USE_REC. Register the valid entries in ACTIVE_DEFS_CHECK |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
932 too, for checking purposes. */ |
0 | 933 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
934 static void |
111 | 935 register_active_defs (df_ref use) |
0 | 936 { |
111 | 937 for (; use; use = DF_REF_NEXT_LOC (use)) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
938 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
939 df_ref def = get_def_for_use (use); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
940 int regno = DF_REF_REGNO (use); |
0 | 941 |
111 | 942 if (flag_checking) |
943 sparseset_set_bit (active_defs_check, regno); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
944 active_defs[regno] = def; |
0 | 945 } |
946 } | |
947 | |
948 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
949 /* Build the use->def links that we use to update the dataflow info |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
950 for new uses. Note that building the links is very cheap and if |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
951 it were done earlier, they could be used to rule out invalid |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
952 propagations (in addition to what is done in all_uses_available_at). |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
953 I'm not doing this yet, though. */ |
0 | 954 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
955 static void |
111 | 956 update_df_init (rtx_insn *def_insn, rtx_insn *insn) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
957 { |
111 | 958 if (flag_checking) |
959 sparseset_clear (active_defs_check); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
960 register_active_defs (DF_INSN_USES (def_insn)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
961 register_active_defs (DF_INSN_USES (insn)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
962 register_active_defs (DF_INSN_EQ_USES (insn)); |
0 | 963 } |
964 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
965 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
966 /* Update the USE_DEF_REF array for the given use, using the active definitions |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
967 in the ACTIVE_DEFS array to match pseudos to their def. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
968 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
969 static inline void |
111 | 970 update_uses (df_ref use) |
0 | 971 { |
111 | 972 for (; use; use = DF_REF_NEXT_LOC (use)) |
0 | 973 { |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
974 int regno = DF_REF_REGNO (use); |
0 | 975 |
976 /* Set up the use-def chain. */ | |
111 | 977 if (DF_REF_ID (use) >= (int) use_def_ref.length ()) |
978 use_def_ref.safe_grow_cleared (DF_REF_ID (use) + 1); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
979 |
111 | 980 if (flag_checking) |
981 gcc_assert (sparseset_bit_p (active_defs_check, regno)); | |
982 use_def_ref[DF_REF_ID (use)] = active_defs[regno]; | |
0 | 983 } |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
984 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
985 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
986 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
987 /* Update the USE_DEF_REF array for the uses in INSN. Only update note |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
988 uses if NOTES_ONLY is true. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
989 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
990 static void |
111 | 991 update_df (rtx_insn *insn, rtx note) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
992 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
993 struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
994 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
995 if (note) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
996 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
997 df_uses_create (&XEXP (note, 0), insn, DF_REF_IN_NOTE); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
998 df_notes_rescan (insn); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
999 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1000 else |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1001 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1002 df_uses_create (&PATTERN (insn), insn, 0); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1003 df_insn_rescan (insn); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1004 update_uses (DF_INSN_INFO_USES (insn_info)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1005 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1006 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1007 update_uses (DF_INSN_INFO_EQ_USES (insn_info)); |
0 | 1008 } |
1009 | |
1010 | |
1011 /* Try substituting NEW into LOC, which originated from forward propagation | |
1012 of USE's value from DEF_INSN. SET_REG_EQUAL says whether we are | |
1013 substituting the whole SET_SRC, so we can set a REG_EQUAL note if the | |
1014 new insn is not recognized. Return whether the substitution was | |
1015 performed. */ | |
1016 | |
1017 static bool | |
111 | 1018 try_fwprop_subst (df_ref use, rtx *loc, rtx new_rtx, rtx_insn *def_insn, |
1019 bool set_reg_equal) | |
0 | 1020 { |
111 | 1021 rtx_insn *insn = DF_REF_INSN (use); |
0 | 1022 rtx set = single_set (insn); |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1023 rtx note = NULL_RTX; |
0 | 1024 bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn)); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1025 int old_cost = 0; |
0 | 1026 bool ok; |
1027 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1028 update_df_init (def_insn, insn); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1029 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1030 /* forward_propagate_subreg may be operating on an instruction with |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1031 multiple sets. If so, assume the cost of the new instruction is |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1032 not greater than the old one. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1033 if (set) |
111 | 1034 old_cost = set_src_cost (SET_SRC (set), GET_MODE (SET_DEST (set)), speed); |
0 | 1035 if (dump_file) |
1036 { | |
1037 fprintf (dump_file, "\nIn insn %d, replacing\n ", INSN_UID (insn)); | |
1038 print_inline_rtx (dump_file, *loc, 2); | |
1039 fprintf (dump_file, "\n with "); | |
1040 print_inline_rtx (dump_file, new_rtx, 2); | |
1041 fprintf (dump_file, "\n"); | |
1042 } | |
1043 | |
1044 validate_unshare_change (insn, loc, new_rtx, true); | |
1045 if (!verify_changes (0)) | |
1046 { | |
1047 if (dump_file) | |
1048 fprintf (dump_file, "Changes to insn %d not recognized\n", | |
1049 INSN_UID (insn)); | |
1050 ok = false; | |
1051 } | |
1052 | |
1053 else if (DF_REF_TYPE (use) == DF_REF_REG_USE | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1054 && set |
111 | 1055 && (set_src_cost (SET_SRC (set), GET_MODE (SET_DEST (set)), speed) |
1056 > old_cost)) | |
0 | 1057 { |
1058 if (dump_file) | |
1059 fprintf (dump_file, "Changes to insn %d not profitable\n", | |
1060 INSN_UID (insn)); | |
1061 ok = false; | |
1062 } | |
1063 | |
1064 else | |
1065 { | |
1066 if (dump_file) | |
1067 fprintf (dump_file, "Changed insn %d\n", INSN_UID (insn)); | |
1068 ok = true; | |
1069 } | |
1070 | |
1071 if (ok) | |
1072 { | |
1073 confirm_change_group (); | |
1074 num_changes++; | |
1075 } | |
1076 else | |
1077 { | |
1078 cancel_changes (0); | |
1079 | |
1080 /* Can also record a simplified value in a REG_EQUAL note, | |
1081 making a new one if one does not already exist. */ | |
1082 if (set_reg_equal) | |
1083 { | |
111 | 1084 /* If there are any paradoxical SUBREGs, don't add REG_EQUAL note, |
1085 because the bits in there can be anything and so might not | |
1086 match the REG_EQUAL note content. See PR70574. */ | |
1087 subrtx_var_iterator::array_type array; | |
1088 FOR_EACH_SUBRTX_VAR (iter, array, *loc, NONCONST) | |
1089 { | |
1090 rtx x = *iter; | |
1091 if (SUBREG_P (x) && paradoxical_subreg_p (x)) | |
1092 { | |
1093 set_reg_equal = false; | |
1094 break; | |
1095 } | |
1096 } | |
0 | 1097 |
111 | 1098 if (set_reg_equal) |
1099 { | |
1100 if (dump_file) | |
1101 fprintf (dump_file, " Setting REG_EQUAL note\n"); | |
1102 | |
1103 note = set_unique_reg_note (insn, REG_EQUAL, copy_rtx (new_rtx)); | |
1104 } | |
0 | 1105 } |
1106 } | |
1107 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1108 if ((ok || note) && !CONSTANT_P (new_rtx)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1109 update_df (insn, note); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1110 |
0 | 1111 return ok; |
1112 } | |
1113 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1114 /* For the given single_set INSN, containing SRC known to be a |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1115 ZERO_EXTEND or SIGN_EXTEND of a register, return true if INSN |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1116 is redundant due to the register being set by a LOAD_EXTEND_OP |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1117 load from memory. */ |
0 | 1118 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1119 static bool |
111 | 1120 free_load_extend (rtx src, rtx_insn *insn) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1121 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1122 rtx reg; |
111 | 1123 df_ref def, use; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1124 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1125 reg = XEXP (src, 0); |
111 | 1126 if (load_extend_op (GET_MODE (reg)) != GET_CODE (src)) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1127 return false; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1128 |
111 | 1129 FOR_EACH_INSN_USE (use, insn) |
1130 if (!DF_REF_IS_ARTIFICIAL (use) | |
1131 && DF_REF_TYPE (use) == DF_REF_REG_USE | |
1132 && DF_REF_REG (use) == reg) | |
1133 break; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1134 if (!use) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1135 return false; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1136 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1137 def = get_def_for_use (use); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1138 if (!def) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1139 return false; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1140 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1141 if (DF_REF_IS_ARTIFICIAL (def)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1142 return false; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1143 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1144 if (NONJUMP_INSN_P (DF_REF_INSN (def))) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1145 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1146 rtx patt = PATTERN (DF_REF_INSN (def)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1147 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1148 if (GET_CODE (patt) == SET |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1149 && GET_CODE (SET_SRC (patt)) == MEM |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1150 && rtx_equal_p (SET_DEST (patt), reg)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1151 return true; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1152 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1153 return false; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1154 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1155 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1156 /* If USE is a subreg, see if it can be replaced by a pseudo. */ |
0 | 1157 |
1158 static bool | |
111 | 1159 forward_propagate_subreg (df_ref use, rtx_insn *def_insn, rtx def_set) |
0 | 1160 { |
1161 rtx use_reg = DF_REF_REG (use); | |
111 | 1162 rtx_insn *use_insn; |
1163 rtx src; | |
1164 scalar_int_mode int_use_mode, src_mode; | |
0 | 1165 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1166 /* Only consider subregs... */ |
111 | 1167 machine_mode use_mode = GET_MODE (use_reg); |
0 | 1168 if (GET_CODE (use_reg) != SUBREG |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1169 || !REG_P (SET_DEST (def_set))) |
0 | 1170 return false; |
1171 | |
111 | 1172 if (paradoxical_subreg_p (use_reg)) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1173 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1174 /* If this is a paradoxical SUBREG, we have no idea what value the |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1175 extra bits would have. However, if the operand is equivalent to |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1176 a SUBREG whose operand is the same as our mode, and all the modes |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1177 are within a word, we can just use the inner operand because |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1178 these SUBREGs just say how to treat the register. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1179 use_insn = DF_REF_INSN (use); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1180 src = SET_SRC (def_set); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1181 if (GET_CODE (src) == SUBREG |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1182 && REG_P (SUBREG_REG (src)) |
111 | 1183 && REGNO (SUBREG_REG (src)) >= FIRST_PSEUDO_REGISTER |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1184 && GET_MODE (SUBREG_REG (src)) == use_mode |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1185 && subreg_lowpart_p (src) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1186 && all_uses_available_at (def_insn, use_insn)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1187 return try_fwprop_subst (use, DF_REF_LOC (use), SUBREG_REG (src), |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1188 def_insn, false); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1189 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1190 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1191 /* If this is a SUBREG of a ZERO_EXTEND or SIGN_EXTEND, and the SUBREG |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1192 is the low part of the reg being extended then just use the inner |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1193 operand. Don't do this if the ZERO_EXTEND or SIGN_EXTEND insn will |
111 | 1194 be removed due to it matching a LOAD_EXTEND_OP load from memory, |
1195 or due to the operation being a no-op when applied to registers. | |
1196 For example, if we have: | |
1197 | |
1198 A: (set (reg:DI X) (sign_extend:DI (reg:SI Y))) | |
1199 B: (... (subreg:SI (reg:DI X)) ...) | |
1200 | |
1201 and mode_rep_extended says that Y is already sign-extended, | |
1202 the backend will typically allow A to be combined with the | |
1203 definition of Y or, failing that, allow A to be deleted after | |
1204 reload through register tying. Introducing more uses of Y | |
1205 prevents both optimisations. */ | |
1206 else if (is_a <scalar_int_mode> (use_mode, &int_use_mode) | |
1207 && subreg_lowpart_p (use_reg)) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1208 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1209 use_insn = DF_REF_INSN (use); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1210 src = SET_SRC (def_set); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1211 if ((GET_CODE (src) == ZERO_EXTEND |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1212 || GET_CODE (src) == SIGN_EXTEND) |
111 | 1213 && is_a <scalar_int_mode> (GET_MODE (src), &src_mode) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1214 && REG_P (XEXP (src, 0)) |
111 | 1215 && REGNO (XEXP (src, 0)) >= FIRST_PSEUDO_REGISTER |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1216 && GET_MODE (XEXP (src, 0)) == use_mode |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1217 && !free_load_extend (src, def_insn) |
111 | 1218 && (targetm.mode_rep_extended (int_use_mode, src_mode) |
1219 != (int) GET_CODE (src)) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1220 && all_uses_available_at (def_insn, use_insn)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1221 return try_fwprop_subst (use, DF_REF_LOC (use), XEXP (src, 0), |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1222 def_insn, false); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1223 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1224 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1225 return false; |
0 | 1226 } |
1227 | |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1228 /* Try to replace USE with SRC (defined in DEF_INSN) in __asm. */ |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1229 |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1230 static bool |
111 | 1231 forward_propagate_asm (df_ref use, rtx_insn *def_insn, rtx def_set, rtx reg) |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1232 { |
111 | 1233 rtx_insn *use_insn = DF_REF_INSN (use); |
1234 rtx src, use_pat, asm_operands, new_rtx, *loc; | |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1235 int speed_p, i; |
111 | 1236 df_ref uses; |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1237 |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1238 gcc_assert ((DF_REF_FLAGS (use) & DF_REF_IN_NOTE) == 0); |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1239 |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1240 src = SET_SRC (def_set); |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1241 use_pat = PATTERN (use_insn); |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1242 |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1243 /* In __asm don't replace if src might need more registers than |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1244 reg, as that could increase register pressure on the __asm. */ |
111 | 1245 uses = DF_INSN_USES (def_insn); |
1246 if (uses && DF_REF_NEXT_LOC (uses)) | |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1247 return false; |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1248 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1249 update_df_init (def_insn, use_insn); |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1250 speed_p = optimize_bb_for_speed_p (BLOCK_FOR_INSN (use_insn)); |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1251 asm_operands = NULL_RTX; |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1252 switch (GET_CODE (use_pat)) |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1253 { |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1254 case ASM_OPERANDS: |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1255 asm_operands = use_pat; |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1256 break; |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1257 case SET: |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1258 if (MEM_P (SET_DEST (use_pat))) |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1259 { |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1260 loc = &SET_DEST (use_pat); |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1261 new_rtx = propagate_rtx (*loc, GET_MODE (*loc), reg, src, speed_p); |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1262 if (new_rtx) |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1263 validate_unshare_change (use_insn, loc, new_rtx, true); |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1264 } |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1265 asm_operands = SET_SRC (use_pat); |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1266 break; |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1267 case PARALLEL: |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1268 for (i = 0; i < XVECLEN (use_pat, 0); i++) |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1269 if (GET_CODE (XVECEXP (use_pat, 0, i)) == SET) |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1270 { |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1271 if (MEM_P (SET_DEST (XVECEXP (use_pat, 0, i)))) |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1272 { |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1273 loc = &SET_DEST (XVECEXP (use_pat, 0, i)); |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1274 new_rtx = propagate_rtx (*loc, GET_MODE (*loc), reg, |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1275 src, speed_p); |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1276 if (new_rtx) |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1277 validate_unshare_change (use_insn, loc, new_rtx, true); |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1278 } |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1279 asm_operands = SET_SRC (XVECEXP (use_pat, 0, i)); |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1280 } |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1281 else if (GET_CODE (XVECEXP (use_pat, 0, i)) == ASM_OPERANDS) |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1282 asm_operands = XVECEXP (use_pat, 0, i); |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1283 break; |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1284 default: |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1285 gcc_unreachable (); |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1286 } |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1287 |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1288 gcc_assert (asm_operands && GET_CODE (asm_operands) == ASM_OPERANDS); |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1289 for (i = 0; i < ASM_OPERANDS_INPUT_LENGTH (asm_operands); i++) |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1290 { |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1291 loc = &ASM_OPERANDS_INPUT (asm_operands, i); |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1292 new_rtx = propagate_rtx (*loc, GET_MODE (*loc), reg, src, speed_p); |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1293 if (new_rtx) |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1294 validate_unshare_change (use_insn, loc, new_rtx, true); |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1295 } |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1296 |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1297 if (num_changes_pending () == 0 || !apply_change_group ()) |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1298 return false; |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1299 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1300 update_df (use_insn, NULL); |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1301 num_changes++; |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1302 return true; |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1303 } |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1304 |
0 | 1305 /* Try to replace USE with SRC (defined in DEF_INSN) and simplify the |
1306 result. */ | |
1307 | |
1308 static bool | |
111 | 1309 forward_propagate_and_simplify (df_ref use, rtx_insn *def_insn, rtx def_set) |
0 | 1310 { |
111 | 1311 rtx_insn *use_insn = DF_REF_INSN (use); |
0 | 1312 rtx use_set = single_set (use_insn); |
1313 rtx src, reg, new_rtx, *loc; | |
1314 bool set_reg_equal; | |
111 | 1315 machine_mode mode; |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1316 int asm_use = -1; |
0 | 1317 |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1318 if (INSN_CODE (use_insn) < 0) |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1319 asm_use = asm_noperands (PATTERN (use_insn)); |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1320 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1321 if (!use_set && asm_use < 0 && !DEBUG_INSN_P (use_insn)) |
0 | 1322 return false; |
1323 | |
1324 /* Do not propagate into PC, CC0, etc. */ | |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1325 if (use_set && GET_MODE (SET_DEST (use_set)) == VOIDmode) |
0 | 1326 return false; |
1327 | |
1328 /* If def and use are subreg, check if they match. */ | |
1329 reg = DF_REF_REG (use); | |
111 | 1330 if (GET_CODE (reg) == SUBREG && GET_CODE (SET_DEST (def_set)) == SUBREG) |
1331 { | |
131 | 1332 if (maybe_ne (SUBREG_BYTE (SET_DEST (def_set)), SUBREG_BYTE (reg))) |
111 | 1333 return false; |
1334 } | |
1335 /* Check if the def had a subreg, but the use has the whole reg. */ | |
1336 else if (REG_P (reg) && GET_CODE (SET_DEST (def_set)) == SUBREG) | |
0 | 1337 return false; |
1338 /* Check if the use has a subreg, but the def had the whole reg. Unlike the | |
1339 previous case, the optimization is possible and often useful indeed. */ | |
111 | 1340 else if (GET_CODE (reg) == SUBREG && REG_P (SET_DEST (def_set))) |
0 | 1341 reg = SUBREG_REG (reg); |
1342 | |
111 | 1343 /* Make sure that we can treat REG as having the same mode as the |
1344 source of DEF_SET. */ | |
1345 if (GET_MODE (SET_DEST (def_set)) != GET_MODE (reg)) | |
1346 return false; | |
1347 | |
0 | 1348 /* Check if the substitution is valid (last, because it's the most |
1349 expensive check!). */ | |
1350 src = SET_SRC (def_set); | |
1351 if (!CONSTANT_P (src) && !all_uses_available_at (def_insn, use_insn)) | |
1352 return false; | |
1353 | |
1354 /* Check if the def is loading something from the constant pool; in this | |
1355 case we would undo optimization such as compress_float_constant. | |
1356 Still, we can set a REG_EQUAL note. */ | |
1357 if (MEM_P (src) && MEM_READONLY_P (src)) | |
1358 { | |
1359 rtx x = avoid_constant_pool_reference (src); | |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1360 if (x != src && use_set) |
0 | 1361 { |
1362 rtx note = find_reg_note (use_insn, REG_EQUAL, NULL_RTX); | |
1363 rtx old_rtx = note ? XEXP (note, 0) : SET_SRC (use_set); | |
1364 rtx new_rtx = simplify_replace_rtx (old_rtx, src, x); | |
1365 if (old_rtx != new_rtx) | |
1366 set_unique_reg_note (use_insn, REG_EQUAL, copy_rtx (new_rtx)); | |
1367 } | |
1368 return false; | |
1369 } | |
1370 | |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1371 if (asm_use >= 0) |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1372 return forward_propagate_asm (use, def_insn, def_set, reg); |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1373 |
0 | 1374 /* Else try simplifying. */ |
1375 | |
1376 if (DF_REF_TYPE (use) == DF_REF_REG_MEM_STORE) | |
1377 { | |
1378 loc = &SET_DEST (use_set); | |
1379 set_reg_equal = false; | |
1380 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1381 else if (!use_set) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1382 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1383 loc = &INSN_VAR_LOCATION_LOC (use_insn); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1384 set_reg_equal = false; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1385 } |
0 | 1386 else |
1387 { | |
1388 rtx note = find_reg_note (use_insn, REG_EQUAL, NULL_RTX); | |
1389 if (DF_REF_FLAGS (use) & DF_REF_IN_NOTE) | |
1390 loc = &XEXP (note, 0); | |
1391 else | |
1392 loc = &SET_SRC (use_set); | |
1393 | |
1394 /* Do not replace an existing REG_EQUAL note if the insn is not | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1395 recognized. Either we're already replacing in the note, or we'll |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1396 separately try plugging the definition in the note and simplifying. |
111 | 1397 And only install a REQ_EQUAL note when the destination is a REG |
1398 that isn't mentioned in USE_SET, as the note would be invalid | |
1399 otherwise. We also don't want to install a note if we are merely | |
1400 propagating a pseudo since verifying that this pseudo isn't dead | |
1401 is a pain; moreover such a note won't help anything. | |
1402 If the use is a paradoxical subreg, make sure we don't add a | |
1403 REG_EQUAL note for it, because it is not equivalent, it is one | |
1404 possible value for it, but we can't rely on it holding that value. | |
1405 See PR70574. */ | |
1406 set_reg_equal = (note == NULL_RTX | |
1407 && REG_P (SET_DEST (use_set)) | |
1408 && !REG_P (src) | |
1409 && !(GET_CODE (src) == SUBREG | |
1410 && REG_P (SUBREG_REG (src))) | |
1411 && !reg_mentioned_p (SET_DEST (use_set), | |
1412 SET_SRC (use_set)) | |
1413 && !paradoxical_subreg_p (DF_REF_REG (use))); | |
0 | 1414 } |
1415 | |
1416 if (GET_MODE (*loc) == VOIDmode) | |
1417 mode = GET_MODE (SET_DEST (use_set)); | |
1418 else | |
1419 mode = GET_MODE (*loc); | |
1420 | |
1421 new_rtx = propagate_rtx (*loc, mode, reg, src, | |
1422 optimize_bb_for_speed_p (BLOCK_FOR_INSN (use_insn))); | |
1423 | |
1424 if (!new_rtx) | |
1425 return false; | |
1426 | |
1427 return try_fwprop_subst (use, loc, new_rtx, def_insn, set_reg_equal); | |
1428 } | |
1429 | |
1430 | |
1431 /* Given a use USE of an insn, if it has a single reaching | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1432 definition, try to forward propagate it into that insn. |
145 | 1433 Return true if cfg cleanup will be needed. |
1434 REG_PROP_ONLY is true if we should only propagate register copies. */ | |
0 | 1435 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1436 static bool |
145 | 1437 forward_propagate_into (df_ref use, bool reg_prop_only = false) |
0 | 1438 { |
1439 df_ref def; | |
111 | 1440 rtx_insn *def_insn, *use_insn; |
1441 rtx def_set; | |
0 | 1442 rtx parent; |
1443 | |
1444 if (DF_REF_FLAGS (use) & DF_REF_READ_WRITE) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1445 return false; |
0 | 1446 if (DF_REF_IS_ARTIFICIAL (use)) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1447 return false; |
0 | 1448 |
1449 /* Only consider uses that have a single definition. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1450 def = get_def_for_use (use); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1451 if (!def) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1452 return false; |
0 | 1453 if (DF_REF_FLAGS (def) & DF_REF_READ_WRITE) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1454 return false; |
0 | 1455 if (DF_REF_IS_ARTIFICIAL (def)) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1456 return false; |
0 | 1457 |
1458 /* Check if the use is still present in the insn! */ | |
1459 use_insn = DF_REF_INSN (use); | |
1460 if (DF_REF_FLAGS (use) & DF_REF_IN_NOTE) | |
1461 parent = find_reg_note (use_insn, REG_EQUAL, NULL_RTX); | |
1462 else | |
1463 parent = PATTERN (use_insn); | |
1464 | |
1465 if (!reg_mentioned_p (DF_REF_REG (use), parent)) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1466 return false; |
0 | 1467 |
1468 def_insn = DF_REF_INSN (def); | |
1469 if (multiple_sets (def_insn)) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1470 return false; |
0 | 1471 def_set = single_set (def_insn); |
1472 if (!def_set) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1473 return false; |
0 | 1474 |
145 | 1475 if (reg_prop_only |
1476 && (!reg_single_def_p (SET_SRC (def_set)) | |
1477 || !reg_single_def_p (SET_DEST (def_set)))) | |
1478 return false; | |
1479 | |
1480 /* Allow propagations into a loop only for reg-to-reg copies, since | |
1481 replacing one register by another shouldn't increase the cost. */ | |
1482 | |
1483 if (DF_REF_BB (def)->loop_father != DF_REF_BB (use)->loop_father | |
1484 && (!reg_single_def_p (SET_SRC (def_set)) | |
1485 || !reg_single_def_p (SET_DEST (def_set)))) | |
1486 return false; | |
1487 | |
0 | 1488 /* Only try one kind of propagation. If two are possible, we'll |
1489 do it on the following iterations. */ | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1490 if (forward_propagate_and_simplify (use, def_insn, def_set) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1491 || forward_propagate_subreg (use, def_insn, def_set)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1492 { |
111 | 1493 propagations_left--; |
1494 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1495 if (cfun->can_throw_non_call_exceptions |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1496 && find_reg_note (use_insn, REG_EH_REGION, NULL_RTX) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1497 && purge_dead_edges (DF_REF_BB (use))) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1498 return true; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1499 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1500 return false; |
0 | 1501 } |
1502 | |
1503 | |
1504 static void | |
1505 fwprop_init (void) | |
1506 { | |
1507 num_changes = 0; | |
1508 calculate_dominance_info (CDI_DOMINATORS); | |
1509 | |
1510 /* We do not always want to propagate into loops, so we have to find | |
111 | 1511 loops and be careful about them. Avoid CFG modifications so that |
1512 we don't have to update dominance information afterwards for | |
1513 build_single_def_use_links. */ | |
1514 loop_optimizer_init (AVOID_CFG_MODIFICATIONS); | |
0 | 1515 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1516 build_single_def_use_links (); |
0 | 1517 df_set_flags (DF_DEFER_INSN_RESCAN); |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1518 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1519 active_defs = XNEWVEC (df_ref, max_reg_num ()); |
111 | 1520 if (flag_checking) |
1521 active_defs_check = sparseset_alloc (max_reg_num ()); | |
1522 | |
1523 propagations_left = DF_USES_TABLE_SIZE (); | |
0 | 1524 } |
1525 | |
1526 static void | |
1527 fwprop_done (void) | |
1528 { | |
1529 loop_optimizer_finalize (); | |
1530 | |
111 | 1531 use_def_ref.release (); |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1532 free (active_defs); |
111 | 1533 if (flag_checking) |
1534 sparseset_free (active_defs_check); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1535 |
0 | 1536 free_dominance_info (CDI_DOMINATORS); |
1537 cleanup_cfg (0); | |
1538 delete_trivially_dead_insns (get_insns (), max_reg_num ()); | |
1539 | |
1540 if (dump_file) | |
1541 fprintf (dump_file, | |
1542 "\nNumber of successful forward propagations: %d\n\n", | |
1543 num_changes); | |
1544 } | |
1545 | |
1546 | |
1547 /* Main entry point. */ | |
1548 | |
1549 static bool | |
1550 gate_fwprop (void) | |
1551 { | |
1552 return optimize > 0 && flag_forward_propagate; | |
1553 } | |
1554 | |
1555 static unsigned int | |
145 | 1556 fwprop (bool fwprop_addr_p) |
0 | 1557 { |
1558 unsigned i; | |
1559 | |
1560 fwprop_init (); | |
1561 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1562 /* Go through all the uses. df_uses_create will create new ones at the |
0 | 1563 end, and we'll go through them as well. |
1564 | |
1565 Do not forward propagate addresses into loops until after unrolling. | |
1566 CSE did so because it was able to fix its own mess, but we are not. */ | |
1567 | |
1568 for (i = 0; i < DF_USES_TABLE_SIZE (); i++) | |
1569 { | |
111 | 1570 if (!propagations_left) |
1571 break; | |
1572 | |
0 | 1573 df_ref use = DF_USES_GET (i); |
1574 if (use) | |
145 | 1575 { |
1576 if (DF_REF_TYPE (use) == DF_REF_REG_USE | |
1577 || DF_REF_BB (use)->loop_father == NULL | |
1578 /* The outer most loop is not really a loop. */ | |
1579 || loop_outer (DF_REF_BB (use)->loop_father) == NULL) | |
1580 forward_propagate_into (use, fwprop_addr_p); | |
1581 | |
1582 else if (fwprop_addr_p) | |
1583 forward_propagate_into (use, false); | |
1584 } | |
0 | 1585 } |
1586 | |
1587 fwprop_done (); | |
1588 return 0; | |
1589 } | |
1590 | |
111 | 1591 namespace { |
1592 | |
1593 const pass_data pass_data_rtl_fwprop = | |
1594 { | |
1595 RTL_PASS, /* type */ | |
1596 "fwprop1", /* name */ | |
1597 OPTGROUP_NONE, /* optinfo_flags */ | |
1598 TV_FWPROP, /* tv_id */ | |
1599 0, /* properties_required */ | |
1600 0, /* properties_provided */ | |
1601 0, /* properties_destroyed */ | |
1602 0, /* todo_flags_start */ | |
1603 TODO_df_finish, /* todo_flags_finish */ | |
1604 }; | |
1605 | |
1606 class pass_rtl_fwprop : public rtl_opt_pass | |
0 | 1607 { |
111 | 1608 public: |
1609 pass_rtl_fwprop (gcc::context *ctxt) | |
1610 : rtl_opt_pass (pass_data_rtl_fwprop, ctxt) | |
1611 {} | |
1612 | |
1613 /* opt_pass methods: */ | |
1614 virtual bool gate (function *) { return gate_fwprop (); } | |
145 | 1615 virtual unsigned int execute (function *) { return fwprop (false); } |
111 | 1616 |
1617 }; // class pass_rtl_fwprop | |
1618 | |
1619 } // anon namespace | |
1620 | |
1621 rtl_opt_pass * | |
1622 make_pass_rtl_fwprop (gcc::context *ctxt) | |
1623 { | |
1624 return new pass_rtl_fwprop (ctxt); | |
1625 } | |
0 | 1626 |
111 | 1627 namespace { |
1628 | |
1629 const pass_data pass_data_rtl_fwprop_addr = | |
1630 { | |
1631 RTL_PASS, /* type */ | |
1632 "fwprop2", /* name */ | |
1633 OPTGROUP_NONE, /* optinfo_flags */ | |
1634 TV_FWPROP, /* tv_id */ | |
1635 0, /* properties_required */ | |
1636 0, /* properties_provided */ | |
1637 0, /* properties_destroyed */ | |
1638 0, /* todo_flags_start */ | |
1639 TODO_df_finish, /* todo_flags_finish */ | |
1640 }; | |
1641 | |
1642 class pass_rtl_fwprop_addr : public rtl_opt_pass | |
0 | 1643 { |
111 | 1644 public: |
1645 pass_rtl_fwprop_addr (gcc::context *ctxt) | |
1646 : rtl_opt_pass (pass_data_rtl_fwprop_addr, ctxt) | |
1647 {} | |
1648 | |
1649 /* opt_pass methods: */ | |
1650 virtual bool gate (function *) { return gate_fwprop (); } | |
145 | 1651 virtual unsigned int execute (function *) { return fwprop (true); } |
111 | 1652 |
1653 }; // class pass_rtl_fwprop_addr | |
1654 | |
1655 } // anon namespace | |
1656 | |
1657 rtl_opt_pass * | |
1658 make_pass_rtl_fwprop_addr (gcc::context *ctxt) | |
1659 { | |
1660 return new pass_rtl_fwprop_addr (ctxt); | |
1661 } |