Mercurial > hg > CbC > CbC_gcc
annotate gcc/tree-if-conv.c @ 116:367f9f4f266e
fix gimple.h
author | mir3636 |
---|---|
date | Tue, 28 Nov 2017 20:22:01 +0900 |
parents | 04ced10e8804 |
children | 84e7813d76e9 |
rev | line source |
---|---|
0 | 1 /* If-conversion for vectorizer. |
111 | 2 Copyright (C) 2004-2017 Free Software Foundation, Inc. |
0 | 3 Contributed by Devang Patel <dpatel@apple.com> |
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 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
21 /* This pass implements a tree level if-conversion of loops. Its |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
22 initial goal is to help the vectorizer to vectorize loops with |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
23 conditions. |
0 | 24 |
25 A short description of if-conversion: | |
26 | |
27 o Decide if a loop is if-convertible or not. | |
28 o Walk all loop basic blocks in breadth first order (BFS order). | |
29 o Remove conditional statements (at the end of basic block) | |
30 and propagate condition into destination basic blocks' | |
31 predicate list. | |
32 o Replace modify expression with conditional modify expression | |
33 using current basic block's condition. | |
34 o Merge all basic blocks | |
35 o Replace phi nodes with conditional modify expr | |
36 o Merge all basic blocks into header | |
37 | |
38 Sample transformation: | |
39 | |
40 INPUT | |
41 ----- | |
42 | |
43 # i_23 = PHI <0(0), i_18(10)>; | |
44 <L0>:; | |
45 j_15 = A[i_23]; | |
46 if (j_15 > 41) goto <L1>; else goto <L17>; | |
47 | |
48 <L17>:; | |
49 goto <bb 3> (<L3>); | |
50 | |
51 <L1>:; | |
52 | |
53 # iftmp.2_4 = PHI <0(8), 42(2)>; | |
54 <L3>:; | |
55 A[i_23] = iftmp.2_4; | |
56 i_18 = i_23 + 1; | |
57 if (i_18 <= 15) goto <L19>; else goto <L18>; | |
58 | |
59 <L19>:; | |
60 goto <bb 1> (<L0>); | |
61 | |
62 <L18>:; | |
63 | |
64 OUTPUT | |
65 ------ | |
66 | |
67 # i_23 = PHI <0(0), i_18(10)>; | |
68 <L0>:; | |
69 j_15 = A[i_23]; | |
70 | |
71 <L3>:; | |
72 iftmp.2_4 = j_15 > 41 ? 42 : 0; | |
73 A[i_23] = iftmp.2_4; | |
74 i_18 = i_23 + 1; | |
75 if (i_18 <= 15) goto <L19>; else goto <L18>; | |
76 | |
77 <L19>:; | |
78 goto <bb 1> (<L0>); | |
79 | |
80 <L18>:; | |
81 */ | |
82 | |
83 #include "config.h" | |
84 #include "system.h" | |
85 #include "coretypes.h" | |
111 | 86 #include "backend.h" |
87 #include "rtl.h" | |
0 | 88 #include "tree.h" |
111 | 89 #include "gimple.h" |
90 #include "cfghooks.h" | |
91 #include "tree-pass.h" | |
92 #include "ssa.h" | |
93 #include "expmed.h" | |
94 #include "optabs-query.h" | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
95 #include "gimple-pretty-print.h" |
111 | 96 #include "alias.h" |
97 #include "fold-const.h" | |
98 #include "stor-layout.h" | |
99 #include "gimple-fold.h" | |
100 #include "gimplify.h" | |
101 #include "gimple-iterator.h" | |
102 #include "gimplify-me.h" | |
103 #include "tree-cfg.h" | |
104 #include "tree-into-ssa.h" | |
105 #include "tree-ssa.h" | |
0 | 106 #include "cfgloop.h" |
107 #include "tree-data-ref.h" | |
108 #include "tree-scalar-evolution.h" | |
111 | 109 #include "tree-ssa-loop.h" |
110 #include "tree-ssa-loop-niter.h" | |
111 #include "tree-ssa-loop-ivopts.h" | |
112 #include "tree-ssa-address.h" | |
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
|
113 #include "dbgcnt.h" |
111 | 114 #include "tree-hash-traits.h" |
115 #include "varasm.h" | |
116 #include "builtins.h" | |
117 #include "params.h" | |
118 #include "cfganal.h" | |
119 | |
120 /* Only handle PHIs with no more arguments unless we are asked to by | |
121 simd pragma. */ | |
122 #define MAX_PHI_ARG_NUM \ | |
123 ((unsigned) PARAM_VALUE (PARAM_MAX_TREE_IF_CONVERSION_PHI_ARGS)) | |
124 | |
125 /* Indicate if new load/store that needs to be predicated is introduced | |
126 during if conversion. */ | |
127 static bool any_pred_load_store; | |
128 | |
129 /* Indicate if there are any complicated PHIs that need to be handled in | |
130 if-conversion. Complicated PHI has more than two arguments and can't | |
131 be degenerated to two arguments PHI. See more information in comment | |
132 before phi_convertible_by_degenerating_args. */ | |
133 static bool any_complicated_phi; | |
134 | |
135 /* Hash for struct innermost_loop_behavior. It depends on the user to | |
136 free the memory. */ | |
137 | |
138 struct innermost_loop_behavior_hash : nofree_ptr_hash <innermost_loop_behavior> | |
139 { | |
140 static inline hashval_t hash (const value_type &); | |
141 static inline bool equal (const value_type &, | |
142 const compare_type &); | |
143 }; | |
144 | |
145 inline hashval_t | |
146 innermost_loop_behavior_hash::hash (const value_type &e) | |
147 { | |
148 hashval_t hash; | |
149 | |
150 hash = iterative_hash_expr (e->base_address, 0); | |
151 hash = iterative_hash_expr (e->offset, hash); | |
152 hash = iterative_hash_expr (e->init, hash); | |
153 return iterative_hash_expr (e->step, hash); | |
154 } | |
155 | |
156 inline bool | |
157 innermost_loop_behavior_hash::equal (const value_type &e1, | |
158 const compare_type &e2) | |
159 { | |
160 if ((e1->base_address && !e2->base_address) | |
161 || (!e1->base_address && e2->base_address) | |
162 || (!e1->offset && e2->offset) | |
163 || (e1->offset && !e2->offset) | |
164 || (!e1->init && e2->init) | |
165 || (e1->init && !e2->init) | |
166 || (!e1->step && e2->step) | |
167 || (e1->step && !e2->step)) | |
168 return false; | |
169 | |
170 if (e1->base_address && e2->base_address | |
171 && !operand_equal_p (e1->base_address, e2->base_address, 0)) | |
172 return false; | |
173 if (e1->offset && e2->offset | |
174 && !operand_equal_p (e1->offset, e2->offset, 0)) | |
175 return false; | |
176 if (e1->init && e2->init | |
177 && !operand_equal_p (e1->init, e2->init, 0)) | |
178 return false; | |
179 if (e1->step && e2->step | |
180 && !operand_equal_p (e1->step, e2->step, 0)) | |
181 return false; | |
182 | |
183 return true; | |
184 } | |
0 | 185 |
186 /* List of basic blocks in if-conversion-suitable order. */ | |
187 static basic_block *ifc_bbs; | |
188 | |
111 | 189 /* Hash table to store <DR's innermost loop behavior, DR> pairs. */ |
190 static hash_map<innermost_loop_behavior_hash, | |
191 data_reference_p> *innermost_DR_map; | |
192 | |
193 /* Hash table to store <base reference, DR> pairs. */ | |
194 static hash_map<tree_operand_hash, data_reference_p> *baseref_DR_map; | |
195 | |
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
|
196 /* Structure used to predicate basic blocks. This is attached to the |
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
|
197 ->aux field of the BBs in the loop to be if-converted. */ |
111 | 198 struct bb_predicate { |
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
|
199 |
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
|
200 /* The condition under which this basic block is executed. */ |
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
|
201 tree predicate; |
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
|
202 |
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
|
203 /* PREDICATE is gimplified, and the sequence of statements is |
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
|
204 recorded here, in order to avoid the duplication of computations |
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
|
205 that occur in previous conditions. See PR44483. */ |
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
|
206 gimple_seq predicate_gimplified_stmts; |
111 | 207 }; |
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
|
208 |
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
|
209 /* Returns true when the basic block BB has a predicate. */ |
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
|
210 |
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
|
211 static inline bool |
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
|
212 bb_has_predicate (basic_block bb) |
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
|
213 { |
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
|
214 return bb->aux != NULL; |
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
|
215 } |
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
|
216 |
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
|
217 /* Returns the gimplified predicate for basic block BB. */ |
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
|
218 |
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
|
219 static inline tree |
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
|
220 bb_predicate (basic_block bb) |
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
|
221 { |
111 | 222 return ((struct bb_predicate *) bb->aux)->predicate; |
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
|
223 } |
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
|
224 |
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
|
225 /* Sets the gimplified predicate COND for basic block BB. */ |
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
|
226 |
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
|
227 static inline void |
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
|
228 set_bb_predicate (basic_block bb, tree cond) |
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
|
229 { |
111 | 230 gcc_assert ((TREE_CODE (cond) == TRUTH_NOT_EXPR |
231 && is_gimple_condexpr (TREE_OPERAND (cond, 0))) | |
232 || is_gimple_condexpr (cond)); | |
233 ((struct bb_predicate *) bb->aux)->predicate = cond; | |
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
|
234 } |
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
|
235 |
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
|
236 /* Returns the sequence of statements of the gimplification of the |
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
|
237 predicate for basic block BB. */ |
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
|
238 |
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
|
239 static inline gimple_seq |
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
|
240 bb_predicate_gimplified_stmts (basic_block bb) |
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
|
241 { |
111 | 242 return ((struct bb_predicate *) bb->aux)->predicate_gimplified_stmts; |
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
|
243 } |
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
|
244 |
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
|
245 /* Sets the sequence of statements STMTS of the gimplification of the |
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
|
246 predicate for basic block BB. */ |
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
|
247 |
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
|
248 static inline void |
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
|
249 set_bb_predicate_gimplified_stmts (basic_block bb, gimple_seq stmts) |
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
|
250 { |
111 | 251 ((struct bb_predicate *) bb->aux)->predicate_gimplified_stmts = stmts; |
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
|
252 } |
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
|
253 |
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
|
254 /* Adds the sequence of statements STMTS to the sequence of statements |
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
|
255 of the predicate for basic block BB. */ |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
256 |
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
|
257 static inline void |
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
|
258 add_bb_predicate_gimplified_stmts (basic_block bb, gimple_seq stmts) |
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
|
259 { |
111 | 260 gimple_seq_add_seq_without_update |
261 (&(((struct bb_predicate *) bb->aux)->predicate_gimplified_stmts), stmts); | |
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
|
262 } |
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
|
263 |
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
|
264 /* Initializes to TRUE the predicate of basic block BB. */ |
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
|
265 |
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
|
266 static inline void |
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
|
267 init_bb_predicate (basic_block bb) |
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
|
268 { |
111 | 269 bb->aux = XNEW (struct bb_predicate); |
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
|
270 set_bb_predicate_gimplified_stmts (bb, NULL); |
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
|
271 set_bb_predicate (bb, boolean_true_node); |
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
|
272 } |
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
|
273 |
111 | 274 /* Release the SSA_NAMEs associated with the predicate of basic block BB, |
275 but don't actually free it. */ | |
276 | |
277 static inline void | |
278 release_bb_predicate (basic_block bb) | |
279 { | |
280 gimple_seq stmts = bb_predicate_gimplified_stmts (bb); | |
281 if (stmts) | |
282 { | |
283 if (flag_checking) | |
284 for (gimple_stmt_iterator i = gsi_start (stmts); | |
285 !gsi_end_p (i); gsi_next (&i)) | |
286 gcc_assert (! gimple_use_ops (gsi_stmt (i))); | |
287 | |
288 set_bb_predicate_gimplified_stmts (bb, NULL); | |
289 } | |
290 } | |
291 | |
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
|
292 /* Free the predicate of basic block BB. */ |
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
|
293 |
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
|
294 static inline void |
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
|
295 free_bb_predicate (basic_block bb) |
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
|
296 { |
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
|
297 if (!bb_has_predicate (bb)) |
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
|
298 return; |
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
|
299 |
111 | 300 release_bb_predicate (bb); |
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
|
301 free (bb->aux); |
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
|
302 bb->aux = NULL; |
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
|
303 } |
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
|
304 |
111 | 305 /* Reinitialize predicate of BB with the true predicate. */ |
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
|
306 |
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
|
307 static inline void |
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
|
308 reset_bb_predicate (basic_block bb) |
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
|
309 { |
111 | 310 if (!bb_has_predicate (bb)) |
311 init_bb_predicate (bb); | |
312 else | |
313 { | |
314 release_bb_predicate (bb); | |
315 set_bb_predicate (bb, boolean_true_node); | |
316 } | |
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
|
317 } |
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
|
318 |
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
|
319 /* Returns a new SSA_NAME of type TYPE that is assigned the value of |
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
|
320 the expression EXPR. Inserts the statement created for this |
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
|
321 computation before GSI and leaves the iterator GSI at the same |
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
|
322 statement. */ |
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
|
323 |
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
|
324 static tree |
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
|
325 ifc_temp_var (tree type, tree expr, gimple_stmt_iterator *gsi) |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
326 { |
111 | 327 tree new_name = make_temp_ssa_name (type, NULL, "_ifc_"); |
328 gimple *stmt = gimple_build_assign (new_name, expr); | |
329 gimple_set_vuse (stmt, gimple_vuse (gsi_stmt (*gsi))); | |
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
|
330 gsi_insert_before (gsi, stmt, GSI_SAME_STMT); |
111 | 331 return new_name; |
332 } | |
333 | |
334 /* Return true when COND is a false predicate. */ | |
335 | |
336 static inline bool | |
337 is_false_predicate (tree cond) | |
338 { | |
339 return (cond != NULL_TREE | |
340 && (cond == boolean_false_node | |
341 || integer_zerop (cond))); | |
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
|
342 } |
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
|
343 |
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
|
344 /* Return true when COND is a true predicate. */ |
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
|
345 |
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
|
346 static inline bool |
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
|
347 is_true_predicate (tree cond) |
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
|
348 { |
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
|
349 return (cond == NULL_TREE |
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
|
350 || cond == boolean_true_node |
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
|
351 || integer_onep (cond)); |
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
|
352 } |
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
|
353 |
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
|
354 /* Returns true when BB has a predicate that is not trivial: true or |
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
|
355 NULL_TREE. */ |
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
|
356 |
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
|
357 static inline bool |
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
|
358 is_predicated (basic_block bb) |
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
|
359 { |
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
|
360 return !is_true_predicate (bb_predicate (bb)); |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
361 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
362 |
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
|
363 /* Parses the predicate COND and returns its comparison code and |
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
|
364 operands OP0 and OP1. */ |
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
|
365 |
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
|
366 static enum tree_code |
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
|
367 parse_predicate (tree cond, tree *op0, tree *op1) |
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
|
368 { |
111 | 369 gimple *s; |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
370 |
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
|
371 if (TREE_CODE (cond) == SSA_NAME |
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
|
372 && is_gimple_assign (s = SSA_NAME_DEF_STMT (cond))) |
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
|
373 { |
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
|
374 if (TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison) |
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
|
375 { |
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
|
376 *op0 = gimple_assign_rhs1 (s); |
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
|
377 *op1 = gimple_assign_rhs2 (s); |
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
|
378 return gimple_assign_rhs_code (s); |
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
|
379 } |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
380 |
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
|
381 else if (gimple_assign_rhs_code (s) == TRUTH_NOT_EXPR) |
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
|
382 { |
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
|
383 tree op = gimple_assign_rhs1 (s); |
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
|
384 tree type = TREE_TYPE (op); |
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
|
385 enum tree_code code = parse_predicate (op, op0, op1); |
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
|
386 |
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
|
387 return code == ERROR_MARK ? ERROR_MARK |
111 | 388 : invert_tree_comparison (code, HONOR_NANS (type)); |
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
|
389 } |
0 | 390 |
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
|
391 return ERROR_MARK; |
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
|
392 } |
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
|
393 |
111 | 394 if (COMPARISON_CLASS_P (cond)) |
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
|
395 { |
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
|
396 *op0 = TREE_OPERAND (cond, 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
|
397 *op1 = TREE_OPERAND (cond, 1); |
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
|
398 return TREE_CODE (cond); |
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
|
399 } |
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
|
400 |
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
|
401 return ERROR_MARK; |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
402 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
403 |
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
|
404 /* Returns the fold of predicate C1 OR C2 at location LOC. */ |
0 | 405 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
406 static tree |
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
|
407 fold_or_predicates (location_t loc, tree c1, tree c2) |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
408 { |
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
|
409 tree op1a, op1b, op2a, op2b; |
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
|
410 enum tree_code code1 = parse_predicate (c1, &op1a, &op1b); |
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
|
411 enum tree_code code2 = parse_predicate (c2, &op2a, &op2b); |
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
|
412 |
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
|
413 if (code1 != ERROR_MARK && code2 != ERROR_MARK) |
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
|
414 { |
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
|
415 tree t = maybe_fold_or_comparisons (code1, op1a, op1b, |
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
|
416 code2, op2a, op2b); |
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
|
417 if (t) |
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
|
418 return t; |
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
|
419 } |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
420 |
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
|
421 return fold_build2_loc (loc, TRUTH_OR_EXPR, boolean_type_node, c1, c2); |
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
|
422 } |
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
|
423 |
111 | 424 /* Returns either a COND_EXPR or the folded expression if the folded |
425 expression is a MIN_EXPR, a MAX_EXPR, an ABS_EXPR, | |
426 a constant or a SSA_NAME. */ | |
427 | |
428 static tree | |
429 fold_build_cond_expr (tree type, tree cond, tree rhs, tree lhs) | |
430 { | |
431 tree rhs1, lhs1, cond_expr; | |
432 | |
433 /* If COND is comparison r != 0 and r has boolean type, convert COND | |
434 to SSA_NAME to accept by vect bool pattern. */ | |
435 if (TREE_CODE (cond) == NE_EXPR) | |
436 { | |
437 tree op0 = TREE_OPERAND (cond, 0); | |
438 tree op1 = TREE_OPERAND (cond, 1); | |
439 if (TREE_CODE (op0) == SSA_NAME | |
440 && TREE_CODE (TREE_TYPE (op0)) == BOOLEAN_TYPE | |
441 && (integer_zerop (op1))) | |
442 cond = op0; | |
443 } | |
444 cond_expr = fold_ternary (COND_EXPR, type, cond, rhs, lhs); | |
445 | |
446 if (cond_expr == NULL_TREE) | |
447 return build3 (COND_EXPR, type, cond, rhs, lhs); | |
448 | |
449 STRIP_USELESS_TYPE_CONVERSION (cond_expr); | |
450 | |
451 if (is_gimple_val (cond_expr)) | |
452 return cond_expr; | |
453 | |
454 if (TREE_CODE (cond_expr) == ABS_EXPR) | |
455 { | |
456 rhs1 = TREE_OPERAND (cond_expr, 1); | |
457 STRIP_USELESS_TYPE_CONVERSION (rhs1); | |
458 if (is_gimple_val (rhs1)) | |
459 return build1 (ABS_EXPR, type, rhs1); | |
460 } | |
461 | |
462 if (TREE_CODE (cond_expr) == MIN_EXPR | |
463 || TREE_CODE (cond_expr) == MAX_EXPR) | |
464 { | |
465 lhs1 = TREE_OPERAND (cond_expr, 0); | |
466 STRIP_USELESS_TYPE_CONVERSION (lhs1); | |
467 rhs1 = TREE_OPERAND (cond_expr, 1); | |
468 STRIP_USELESS_TYPE_CONVERSION (rhs1); | |
469 if (is_gimple_val (rhs1) && is_gimple_val (lhs1)) | |
470 return build2 (TREE_CODE (cond_expr), type, lhs1, rhs1); | |
471 } | |
472 return build3 (COND_EXPR, type, cond, rhs, lhs); | |
473 } | |
474 | |
475 /* Add condition NC to the predicate list of basic block BB. LOOP is | |
476 the loop to be if-converted. Use predicate of cd-equivalent block | |
477 for join bb if it exists: we call basic blocks bb1 and bb2 | |
478 cd-equivalent if they are executed under the same condition. */ | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
479 |
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
|
480 static inline void |
111 | 481 add_to_predicate_list (struct loop *loop, basic_block bb, tree nc) |
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
|
482 { |
111 | 483 tree bc, *tp; |
484 basic_block dom_bb; | |
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
|
485 |
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
|
486 if (is_true_predicate (nc)) |
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
|
487 return; |
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
|
488 |
111 | 489 /* If dominance tells us this basic block is always executed, |
490 don't record any predicates for it. */ | |
491 if (dominated_by_p (CDI_DOMINATORS, loop->latch, bb)) | |
492 return; | |
493 | |
494 dom_bb = get_immediate_dominator (CDI_DOMINATORS, bb); | |
495 /* We use notion of cd equivalence to get simpler predicate for | |
496 join block, e.g. if join block has 2 predecessors with predicates | |
497 p1 & p2 and p1 & !p2, we'd like to get p1 for it instead of | |
498 p1 & p2 | p1 & !p2. */ | |
499 if (dom_bb != loop->header | |
500 && get_immediate_dominator (CDI_POST_DOMINATORS, dom_bb) == bb) | |
501 { | |
502 gcc_assert (flow_bb_inside_loop_p (loop, dom_bb)); | |
503 bc = bb_predicate (dom_bb); | |
504 if (!is_true_predicate (bc)) | |
505 set_bb_predicate (bb, bc); | |
506 else | |
507 gcc_assert (is_true_predicate (bb_predicate (bb))); | |
508 if (dump_file && (dump_flags & TDF_DETAILS)) | |
509 fprintf (dump_file, "Use predicate of bb#%d for bb#%d\n", | |
510 dom_bb->index, bb->index); | |
511 return; | |
512 } | |
513 | |
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
|
514 if (!is_predicated (bb)) |
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
|
515 bc = nc; |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
516 else |
0 | 517 { |
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
|
518 bc = bb_predicate (bb); |
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
|
519 bc = fold_or_predicates (EXPR_LOCATION (bc), nc, bc); |
111 | 520 if (is_true_predicate (bc)) |
521 { | |
522 reset_bb_predicate (bb); | |
523 return; | |
524 } | |
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
|
525 } |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
526 |
111 | 527 /* Allow a TRUTH_NOT_EXPR around the main predicate. */ |
528 if (TREE_CODE (bc) == TRUTH_NOT_EXPR) | |
529 tp = &TREE_OPERAND (bc, 0); | |
530 else | |
531 tp = &bc; | |
532 if (!is_gimple_condexpr (*tp)) | |
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
|
533 { |
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
|
534 gimple_seq stmts; |
111 | 535 *tp = force_gimple_operand_1 (*tp, &stmts, is_gimple_condexpr, NULL_TREE); |
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
|
536 add_bb_predicate_gimplified_stmts (bb, stmts); |
0 | 537 } |
111 | 538 set_bb_predicate (bb, bc); |
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
|
539 } |
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
|
540 |
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
|
541 /* Add the condition COND to the previous condition PREV_COND, and add |
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
|
542 this to the predicate list of the destination of edge E. LOOP is |
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
|
543 the loop to be if-converted. */ |
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
|
544 |
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
|
545 static void |
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
|
546 add_to_dst_predicate_list (struct loop *loop, edge e, |
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
|
547 tree prev_cond, tree cond) |
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
|
548 { |
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
|
549 if (!flow_bb_inside_loop_p (loop, e->dest)) |
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
|
550 return; |
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
|
551 |
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
|
552 if (!is_true_predicate (prev_cond)) |
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
|
553 cond = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, |
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
|
554 prev_cond, cond); |
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
|
555 |
111 | 556 if (!dominated_by_p (CDI_DOMINATORS, loop->latch, e->dest)) |
557 add_to_predicate_list (loop, e->dest, cond); | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
558 } |
0 | 559 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
560 /* Return true if one of the successor edges of BB exits LOOP. */ |
0 | 561 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
562 static bool |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
563 bb_with_exit_edge_p (struct loop *loop, basic_block bb) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
564 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
565 edge e; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
566 edge_iterator ei; |
0 | 567 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
568 FOR_EACH_EDGE (e, ei, bb->succs) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
569 if (loop_exit_edge_p (loop, e)) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
570 return true; |
0 | 571 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
572 return false; |
0 | 573 } |
574 | |
111 | 575 /* Given PHI which has more than two arguments, this function checks if |
576 it's if-convertible by degenerating its arguments. Specifically, if | |
577 below two conditions are satisfied: | |
578 | |
579 1) Number of PHI arguments with different values equals to 2 and one | |
580 argument has the only occurrence. | |
581 2) The edge corresponding to the unique argument isn't critical edge. | |
582 | |
583 Such PHI can be handled as PHIs have only two arguments. For example, | |
584 below PHI: | |
585 | |
586 res = PHI <A_1(e1), A_1(e2), A_2(e3)>; | |
587 | |
588 can be transformed into: | |
589 | |
590 res = (predicate of e3) ? A_2 : A_1; | |
591 | |
592 Return TRUE if it is the case, FALSE otherwise. */ | |
0 | 593 |
594 static bool | |
111 | 595 phi_convertible_by_degenerating_args (gphi *phi) |
596 { | |
597 edge e; | |
598 tree arg, t1 = NULL, t2 = NULL; | |
599 unsigned int i, i1 = 0, i2 = 0, n1 = 0, n2 = 0; | |
600 unsigned int num_args = gimple_phi_num_args (phi); | |
601 | |
602 gcc_assert (num_args > 2); | |
603 | |
604 for (i = 0; i < num_args; i++) | |
605 { | |
606 arg = gimple_phi_arg_def (phi, i); | |
607 if (t1 == NULL || operand_equal_p (t1, arg, 0)) | |
608 { | |
609 n1++; | |
610 i1 = i; | |
611 t1 = arg; | |
612 } | |
613 else if (t2 == NULL || operand_equal_p (t2, arg, 0)) | |
614 { | |
615 n2++; | |
616 i2 = i; | |
617 t2 = arg; | |
618 } | |
619 else | |
620 return false; | |
621 } | |
622 | |
623 if (n1 != 1 && n2 != 1) | |
624 return false; | |
625 | |
626 /* Check if the edge corresponding to the unique arg is critical. */ | |
627 e = gimple_phi_arg_edge (phi, (n1 == 1) ? i1 : i2); | |
628 if (EDGE_COUNT (e->src->succs) > 1) | |
629 return false; | |
630 | |
631 return true; | |
632 } | |
633 | |
634 /* Return true when PHI is if-convertible. PHI is part of loop LOOP | |
635 and it belongs to basic block BB. Note at this point, it is sure | |
636 that PHI is if-convertible. This function updates global variable | |
637 ANY_COMPLICATED_PHI if PHI is complicated. */ | |
638 | |
639 static bool | |
640 if_convertible_phi_p (struct loop *loop, basic_block bb, gphi *phi) | |
0 | 641 { |
642 if (dump_file && (dump_flags & TDF_DETAILS)) | |
643 { | |
644 fprintf (dump_file, "-------------------------\n"); | |
645 print_gimple_stmt (dump_file, phi, 0, TDF_SLIM); | |
646 } | |
647 | |
111 | 648 if (bb != loop->header |
649 && gimple_phi_num_args (phi) > 2 | |
650 && !phi_convertible_by_degenerating_args (phi)) | |
651 any_complicated_phi = true; | |
0 | 652 |
653 return true; | |
654 } | |
655 | |
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
|
656 /* Records the status of a data reference. This struct is attached to |
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
|
657 each DR->aux field. */ |
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
|
658 |
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
|
659 struct ifc_dr { |
111 | 660 bool rw_unconditionally; |
661 bool w_unconditionally; | |
662 bool written_at_least_once; | |
663 | |
664 tree rw_predicate; | |
665 tree w_predicate; | |
666 tree base_w_predicate; | |
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
|
667 }; |
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
|
668 |
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
|
669 #define IFC_DR(DR) ((struct ifc_dr *) (DR)->aux) |
111 | 670 #define DR_BASE_W_UNCONDITIONALLY(DR) (IFC_DR (DR)->written_at_least_once) |
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
|
671 #define DR_RW_UNCONDITIONALLY(DR) (IFC_DR (DR)->rw_unconditionally) |
111 | 672 #define DR_W_UNCONDITIONALLY(DR) (IFC_DR (DR)->w_unconditionally) |
673 | |
674 /* Iterates over DR's and stores refs, DR and base refs, DR pairs in | |
675 HASH tables. While storing them in HASH table, it checks if the | |
676 reference is unconditionally read or written and stores that as a flag | |
677 information. For base reference it checks if it is written atlest once | |
678 unconditionally and stores it as flag information along with DR. | |
679 In other words for every data reference A in STMT there exist other | |
680 accesses to a data reference with the same base with predicates that | |
681 add up (OR-up) to the true predicate: this ensures that the data | |
682 reference A is touched (read or written) on every iteration of the | |
683 if-converted loop. */ | |
684 static void | |
685 hash_memrefs_baserefs_and_store_DRs_read_written_info (data_reference_p a) | |
686 { | |
687 | |
688 data_reference_p *master_dr, *base_master_dr; | |
689 tree base_ref = DR_BASE_OBJECT (a); | |
690 innermost_loop_behavior *innermost = &DR_INNERMOST (a); | |
691 tree ca = bb_predicate (gimple_bb (DR_STMT (a))); | |
692 bool exist1, exist2; | |
693 | |
694 master_dr = &innermost_DR_map->get_or_insert (innermost, &exist1); | |
695 if (!exist1) | |
696 *master_dr = a; | |
697 | |
698 if (DR_IS_WRITE (a)) | |
699 { | |
700 IFC_DR (*master_dr)->w_predicate | |
701 = fold_or_predicates (UNKNOWN_LOCATION, ca, | |
702 IFC_DR (*master_dr)->w_predicate); | |
703 if (is_true_predicate (IFC_DR (*master_dr)->w_predicate)) | |
704 DR_W_UNCONDITIONALLY (*master_dr) = true; | |
705 } | |
706 IFC_DR (*master_dr)->rw_predicate | |
707 = fold_or_predicates (UNKNOWN_LOCATION, ca, | |
708 IFC_DR (*master_dr)->rw_predicate); | |
709 if (is_true_predicate (IFC_DR (*master_dr)->rw_predicate)) | |
710 DR_RW_UNCONDITIONALLY (*master_dr) = true; | |
711 | |
712 if (DR_IS_WRITE (a)) | |
713 { | |
714 base_master_dr = &baseref_DR_map->get_or_insert (base_ref, &exist2); | |
715 if (!exist2) | |
716 *base_master_dr = a; | |
717 IFC_DR (*base_master_dr)->base_w_predicate | |
718 = fold_or_predicates (UNKNOWN_LOCATION, ca, | |
719 IFC_DR (*base_master_dr)->base_w_predicate); | |
720 if (is_true_predicate (IFC_DR (*base_master_dr)->base_w_predicate)) | |
721 DR_BASE_W_UNCONDITIONALLY (*base_master_dr) = true; | |
722 } | |
723 } | |
724 | |
725 /* Return TRUE if can prove the index IDX of an array reference REF is | |
726 within array bound. Return false otherwise. */ | |
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
|
727 |
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
|
728 static bool |
111 | 729 idx_within_array_bound (tree ref, tree *idx, void *dta) |
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
|
730 { |
111 | 731 bool overflow; |
732 widest_int niter, valid_niter, delta, wi_step; | |
733 tree ev, init, step; | |
734 tree low, high; | |
735 struct loop *loop = (struct loop*) dta; | |
736 | |
737 /* Only support within-bound access for array references. */ | |
738 if (TREE_CODE (ref) != ARRAY_REF) | |
739 return false; | |
740 | |
741 /* For arrays at the end of the structure, we are not guaranteed that they | |
742 do not really extend over their declared size. However, for arrays of | |
743 size greater than one, this is unlikely to be intended. */ | |
744 if (array_at_struct_end_p (ref)) | |
745 return false; | |
746 | |
747 ev = analyze_scalar_evolution (loop, *idx); | |
748 ev = instantiate_parameters (loop, ev); | |
749 init = initial_condition (ev); | |
750 step = evolution_part_in_loop_num (ev, loop->num); | |
751 | |
752 if (!init || TREE_CODE (init) != INTEGER_CST | |
753 || (step && TREE_CODE (step) != INTEGER_CST)) | |
754 return false; | |
755 | |
756 low = array_ref_low_bound (ref); | |
757 high = array_ref_up_bound (ref); | |
758 | |
759 /* The case of nonconstant bounds could be handled, but it would be | |
760 complicated. */ | |
761 if (TREE_CODE (low) != INTEGER_CST | |
762 || !high || TREE_CODE (high) != INTEGER_CST) | |
763 return false; | |
764 | |
765 /* Check if the intial idx is within bound. */ | |
766 if (wi::to_widest (init) < wi::to_widest (low) | |
767 || wi::to_widest (init) > wi::to_widest (high)) | |
768 return false; | |
769 | |
770 /* The idx is always within bound. */ | |
771 if (!step || integer_zerop (step)) | |
772 return true; | |
773 | |
774 if (!max_loop_iterations (loop, &niter)) | |
775 return false; | |
776 | |
777 if (wi::to_widest (step) < 0) | |
778 { | |
779 delta = wi::to_widest (init) - wi::to_widest (low); | |
780 wi_step = -wi::to_widest (step); | |
781 } | |
782 else | |
783 { | |
784 delta = wi::to_widest (high) - wi::to_widest (init); | |
785 wi_step = wi::to_widest (step); | |
786 } | |
787 | |
788 valid_niter = wi::div_floor (delta, wi_step, SIGNED, &overflow); | |
789 /* The iteration space of idx is within array bound. */ | |
790 if (!overflow && niter <= valid_niter) | |
791 return true; | |
792 | |
793 return false; | |
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
|
794 } |
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
|
795 |
111 | 796 /* Return TRUE if ref is a within bound array reference. */ |
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
|
797 |
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
|
798 static bool |
111 | 799 ref_within_array_bound (gimple *stmt, tree ref) |
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
|
800 { |
111 | 801 struct loop *loop = loop_containing_stmt (stmt); |
802 | |
803 gcc_assert (loop != NULL); | |
804 return for_each_index (&ref, idx_within_array_bound, loop); | |
805 } | |
806 | |
807 | |
808 /* Given a memory reference expression T, return TRUE if base object | |
809 it refers to is writable. The base object of a memory reference | |
810 is the main object being referenced, which is returned by function | |
811 get_base_address. */ | |
812 | |
813 static bool | |
814 base_object_writable (tree ref) | |
815 { | |
816 tree base_tree = get_base_address (ref); | |
817 | |
818 return (base_tree | |
819 && DECL_P (base_tree) | |
820 && decl_binds_to_current_def_p (base_tree) | |
821 && !TREE_READONLY (base_tree)); | |
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
|
822 } |
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
|
823 |
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
|
824 /* Return true when the memory references of STMT won't trap in the |
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
|
825 if-converted code. There are two things that we have to check for: |
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
|
826 |
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
|
827 - writes to memory occur to writable memory: if-conversion of |
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
|
828 memory writes transforms the conditional memory writes into |
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
|
829 unconditional writes, i.e. "if (cond) A[i] = foo" is transformed |
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
|
830 into "A[i] = cond ? foo : A[i]", and as the write to memory may not |
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
|
831 be executed at all in the original code, it may be a readonly |
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
|
832 memory. To check that A is not const-qualified, we check that |
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
|
833 there exists at least an unconditional write to A in the current |
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
|
834 function. |
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
|
835 |
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
|
836 - reads or writes to memory are valid memory accesses for every |
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
|
837 iteration. To check that the memory accesses are correctly formed |
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
|
838 and that we are allowed to read and write in these locations, we |
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
|
839 check that the memory accesses to be if-converted occur at every |
111 | 840 iteration unconditionally. |
841 | |
842 Returns true for the memory reference in STMT, same memory reference | |
843 is read or written unconditionally atleast once and the base memory | |
844 reference is written unconditionally once. This is to check reference | |
845 will not write fault. Also retuns true if the memory reference is | |
846 unconditionally read once then we are conditionally writing to memory | |
847 which is defined as read and write and is bound to the definition | |
848 we are seeing. */ | |
849 static bool | |
850 ifcvt_memrefs_wont_trap (gimple *stmt, vec<data_reference_p> drs) | |
851 { | |
852 data_reference_p *master_dr, *base_master_dr; | |
853 data_reference_p a = drs[gimple_uid (stmt) - 1]; | |
854 | |
855 tree base = DR_BASE_OBJECT (a); | |
856 innermost_loop_behavior *innermost = &DR_INNERMOST (a); | |
857 | |
858 gcc_assert (DR_STMT (a) == stmt); | |
859 gcc_assert (DR_BASE_ADDRESS (a) || DR_OFFSET (a) | |
860 || DR_INIT (a) || DR_STEP (a)); | |
861 | |
862 master_dr = innermost_DR_map->get (innermost); | |
863 gcc_assert (master_dr != NULL); | |
864 | |
865 base_master_dr = baseref_DR_map->get (base); | |
866 | |
867 /* If a is unconditionally written to it doesn't trap. */ | |
868 if (DR_W_UNCONDITIONALLY (*master_dr)) | |
869 return true; | |
870 | |
871 /* If a is unconditionally accessed then ... | |
872 | |
873 Even a is conditional access, we can treat it as an unconditional | |
874 one if it's an array reference and all its index are within array | |
875 bound. */ | |
876 if (DR_RW_UNCONDITIONALLY (*master_dr) | |
877 || ref_within_array_bound (stmt, DR_REF (a))) | |
878 { | |
879 /* an unconditional read won't trap. */ | |
880 if (DR_IS_READ (a)) | |
881 return true; | |
882 | |
883 /* an unconditionaly write won't trap if the base is written | |
884 to unconditionally. */ | |
885 if (base_master_dr | |
886 && DR_BASE_W_UNCONDITIONALLY (*base_master_dr)) | |
887 return PARAM_VALUE (PARAM_ALLOW_STORE_DATA_RACES); | |
888 /* or the base is known to be not readonly. */ | |
889 else if (base_object_writable (DR_REF (a))) | |
890 return PARAM_VALUE (PARAM_ALLOW_STORE_DATA_RACES); | |
891 } | |
892 | |
893 return false; | |
894 } | |
895 | |
896 /* Return true if STMT could be converted into a masked load or store | |
897 (conditional load or store based on a mask computed from bb predicate). */ | |
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
|
898 |
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
|
899 static bool |
111 | 900 ifcvt_can_use_mask_load_store (gimple *stmt) |
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
|
901 { |
111 | 902 tree lhs, ref; |
903 machine_mode mode; | |
904 basic_block bb = gimple_bb (stmt); | |
905 bool is_load; | |
906 | |
907 if (!(flag_tree_loop_vectorize || bb->loop_father->force_vectorize) | |
908 || bb->loop_father->dont_vectorize | |
909 || !gimple_assign_single_p (stmt) | |
910 || gimple_has_volatile_ops (stmt)) | |
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
|
911 return false; |
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
|
912 |
111 | 913 /* Check whether this is a load or store. */ |
914 lhs = gimple_assign_lhs (stmt); | |
915 if (gimple_store_p (stmt)) | |
916 { | |
917 if (!is_gimple_val (gimple_assign_rhs1 (stmt))) | |
918 return false; | |
919 is_load = false; | |
920 ref = lhs; | |
921 } | |
922 else if (gimple_assign_load_p (stmt)) | |
923 { | |
924 is_load = true; | |
925 ref = gimple_assign_rhs1 (stmt); | |
926 } | |
927 else | |
928 return false; | |
929 | |
930 if (may_be_nonaddressable_p (ref)) | |
931 return false; | |
932 | |
933 /* Mask should be integer mode of the same size as the load/store | |
934 mode. */ | |
935 mode = TYPE_MODE (TREE_TYPE (lhs)); | |
936 if (!int_mode_for_mode (mode).exists () || VECTOR_MODE_P (mode)) | |
937 return false; | |
938 | |
939 if (can_vec_mask_load_store_p (mode, VOIDmode, is_load)) | |
940 return true; | |
941 | |
942 return false; | |
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
|
943 } |
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 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
945 /* Return true when STMT is if-convertible. |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
946 |
0 | 947 GIMPLE_ASSIGN statement is not if-convertible if, |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
948 - it is not movable, |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
949 - it could trap, |
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
|
950 - LHS is not var decl. */ |
0 | 951 |
952 static bool | |
111 | 953 if_convertible_gimple_assign_stmt_p (gimple *stmt, |
954 vec<data_reference_p> refs) | |
0 | 955 { |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
956 tree lhs = gimple_assign_lhs (stmt); |
0 | 957 |
958 if (dump_file && (dump_flags & TDF_DETAILS)) | |
959 { | |
960 fprintf (dump_file, "-------------------------\n"); | |
961 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); | |
962 } | |
963 | |
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
|
964 if (!is_gimple_reg_type (TREE_TYPE (lhs))) |
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 return false; |
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 |
0 | 967 /* Some of these constrains might be too conservative. */ |
968 if (stmt_ends_bb_p (stmt) | |
969 || gimple_has_volatile_ops (stmt) | |
970 || (TREE_CODE (lhs) == SSA_NAME | |
971 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs)) | |
972 || gimple_has_side_effects (stmt)) | |
973 { | |
974 if (dump_file && (dump_flags & TDF_DETAILS)) | |
975 fprintf (dump_file, "stmt not suitable for ifcvt\n"); | |
976 return false; | |
977 } | |
978 | |
111 | 979 /* tree-into-ssa.c uses GF_PLF_1, so avoid it, because |
980 in between if_convertible_loop_p and combine_blocks | |
981 we can perform loop versioning. */ | |
982 gimple_set_plf (stmt, GF_PLF_2, false); | |
983 | |
984 if ((! gimple_vuse (stmt) | |
985 || gimple_could_trap_p_1 (stmt, false, false) | |
986 || ! ifcvt_memrefs_wont_trap (stmt, refs)) | |
987 && gimple_could_trap_p (stmt)) | |
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
|
988 { |
111 | 989 if (ifcvt_can_use_mask_load_store (stmt)) |
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
|
990 { |
111 | 991 gimple_set_plf (stmt, GF_PLF_2, true); |
992 any_pred_load_store = true; | |
993 return true; | |
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
|
994 } |
0 | 995 if (dump_file && (dump_flags & TDF_DETAILS)) |
996 fprintf (dump_file, "tree could trap...\n"); | |
997 return false; | |
998 } | |
999 | |
111 | 1000 /* When if-converting stores force versioning, likewise if we |
1001 ended up generating store data races. */ | |
1002 if (gimple_vdef (stmt)) | |
1003 any_pred_load_store = true; | |
0 | 1004 |
1005 return true; | |
1006 } | |
1007 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1008 /* Return true when STMT is if-convertible. |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1009 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1010 A statement is if-convertible if: |
111 | 1011 - it is an if-convertible GIMPLE_ASSIGN, |
1012 - it is a GIMPLE_LABEL or a GIMPLE_COND, | |
1013 - it is builtins call. */ | |
0 | 1014 |
1015 static bool | |
111 | 1016 if_convertible_stmt_p (gimple *stmt, vec<data_reference_p> refs) |
0 | 1017 { |
1018 switch (gimple_code (stmt)) | |
1019 { | |
1020 case GIMPLE_LABEL: | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1021 case GIMPLE_DEBUG: |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1022 case GIMPLE_COND: |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1023 return true; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1024 |
0 | 1025 case GIMPLE_ASSIGN: |
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
|
1026 return if_convertible_gimple_assign_stmt_p (stmt, refs); |
0 | 1027 |
111 | 1028 case GIMPLE_CALL: |
1029 { | |
1030 tree fndecl = gimple_call_fndecl (stmt); | |
1031 if (fndecl) | |
1032 { | |
1033 int flags = gimple_call_flags (stmt); | |
1034 if ((flags & ECF_CONST) | |
1035 && !(flags & ECF_LOOPING_CONST_OR_PURE) | |
1036 /* We can only vectorize some builtins at the moment, | |
1037 so restrict if-conversion to those. */ | |
1038 && DECL_BUILT_IN (fndecl)) | |
1039 return true; | |
1040 } | |
1041 return false; | |
1042 } | |
1043 | |
0 | 1044 default: |
1045 /* Don't know what to do with 'em so don't do anything. */ | |
1046 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1047 { | |
1048 fprintf (dump_file, "don't know what to do\n"); | |
1049 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); | |
1050 } | |
1051 return false; | |
1052 } | |
1053 | |
1054 return true; | |
1055 } | |
1056 | |
111 | 1057 /* Assumes that BB has more than 1 predecessors. |
1058 Returns false if at least one successor is not on critical edge | |
1059 and true otherwise. */ | |
1060 | |
1061 static inline bool | |
1062 all_preds_critical_p (basic_block bb) | |
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
|
1063 { |
111 | 1064 edge e; |
1065 edge_iterator ei; | |
1066 | |
1067 FOR_EACH_EDGE (e, ei, bb->preds) | |
1068 if (EDGE_COUNT (e->src->succs) == 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
|
1069 return false; |
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
|
1070 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
|
1071 } |
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
|
1072 |
111 | 1073 /* Returns true if at least one successor in on critical edge. */ |
1074 static inline bool | |
1075 has_pred_critical_p (basic_block bb) | |
1076 { | |
1077 edge e; | |
1078 edge_iterator ei; | |
1079 | |
1080 FOR_EACH_EDGE (e, ei, bb->preds) | |
1081 if (EDGE_COUNT (e->src->succs) > 1) | |
1082 return true; | |
1083 return false; | |
1084 } | |
1085 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1086 /* Return true when BB is if-convertible. This routine does not check |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1087 basic block's statements and phis. |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1088 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1089 A basic block is not if-convertible if: |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1090 - it is non-empty and it is after the exit block (in BFS order), |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1091 - it is after the exit block but before the latch, |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1092 - its edges are not normal. |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1093 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1094 EXIT_BB is the basic block containing the exit of the LOOP. BB is |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1095 inside LOOP. */ |
0 | 1096 |
1097 static bool | |
1098 if_convertible_bb_p (struct loop *loop, basic_block bb, basic_block exit_bb) | |
1099 { | |
1100 edge e; | |
1101 edge_iterator ei; | |
1102 | |
1103 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1104 fprintf (dump_file, "----------[%d]-------------\n", bb->index); | |
1105 | |
111 | 1106 if (EDGE_COUNT (bb->succs) > 2) |
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
|
1107 return false; |
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 |
0 | 1109 if (exit_bb) |
1110 { | |
1111 if (bb != loop->latch) | |
1112 { | |
1113 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1114 fprintf (dump_file, "basic block after exit bb but before latch\n"); | |
1115 return false; | |
1116 } | |
1117 else if (!empty_block_p (bb)) | |
1118 { | |
1119 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1120 fprintf (dump_file, "non empty basic block after exit bb\n"); | |
1121 return false; | |
1122 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1123 else if (bb == loop->latch |
0 | 1124 && bb != exit_bb |
1125 && !dominated_by_p (CDI_DOMINATORS, bb, exit_bb)) | |
1126 { | |
1127 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1128 fprintf (dump_file, "latch is not dominated by exit_block\n"); | |
1129 return false; | |
1130 } | |
1131 } | |
1132 | |
1133 /* Be less adventurous and handle only normal edges. */ | |
1134 FOR_EACH_EDGE (e, ei, bb->succs) | |
111 | 1135 if (e->flags & (EDGE_EH | EDGE_ABNORMAL | EDGE_IRREDUCIBLE_LOOP)) |
0 | 1136 { |
1137 if (dump_file && (dump_flags & TDF_DETAILS)) | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1138 fprintf (dump_file, "Difficult to handle edges\n"); |
0 | 1139 return false; |
1140 } | |
1141 | |
1142 return true; | |
1143 } | |
1144 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1145 /* Return true when all predecessor blocks of BB are visited. The |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1146 VISITED bitmap keeps track of the visited blocks. */ |
0 | 1147 |
1148 static bool | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1149 pred_blocks_visited_p (basic_block bb, bitmap *visited) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1150 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1151 edge e; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1152 edge_iterator ei; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1153 FOR_EACH_EDGE (e, ei, bb->preds) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1154 if (!bitmap_bit_p (*visited, e->src->index)) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1155 return false; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1156 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1157 return true; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1158 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1159 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1160 /* Get body of a LOOP in suitable order for if-conversion. It is |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1161 caller's responsibility to deallocate basic block list. |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1162 If-conversion suitable order is, breadth first sort (BFS) order |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1163 with an additional constraint: select a block only if all its |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1164 predecessors are already selected. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1165 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1166 static basic_block * |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1167 get_loop_body_in_if_conv_order (const struct loop *loop) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1168 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1169 basic_block *blocks, *blocks_in_bfs_order; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1170 basic_block bb; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1171 bitmap visited; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1172 unsigned int index = 0; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1173 unsigned int visited_count = 0; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1174 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1175 gcc_assert (loop->num_nodes); |
111 | 1176 gcc_assert (loop->latch != EXIT_BLOCK_PTR_FOR_FN (cfun)); |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1177 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1178 blocks = XCNEWVEC (basic_block, loop->num_nodes); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1179 visited = BITMAP_ALLOC (NULL); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1180 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1181 blocks_in_bfs_order = get_loop_body_in_bfs_order (loop); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1182 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1183 index = 0; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1184 while (index < loop->num_nodes) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1185 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1186 bb = blocks_in_bfs_order [index]; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1187 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1188 if (bb->flags & BB_IRREDUCIBLE_LOOP) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1189 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1190 free (blocks_in_bfs_order); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1191 BITMAP_FREE (visited); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1192 free (blocks); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1193 return NULL; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1194 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1195 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1196 if (!bitmap_bit_p (visited, bb->index)) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1197 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1198 if (pred_blocks_visited_p (bb, &visited) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1199 || bb == loop->header) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1200 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1201 /* This block is now visited. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1202 bitmap_set_bit (visited, bb->index); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1203 blocks[visited_count++] = bb; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1204 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1205 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1206 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1207 index++; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1208 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1209 if (index == loop->num_nodes |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1210 && visited_count != loop->num_nodes) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1211 /* Not done yet. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1212 index = 0; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1213 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1214 free (blocks_in_bfs_order); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1215 BITMAP_FREE (visited); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1216 return blocks; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1217 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1218 |
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
|
1219 /* Returns true when the analysis of the predicates for all the basic |
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
|
1220 blocks in LOOP succeeded. |
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
|
1221 |
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
|
1222 predicate_bbs first allocates the predicates of the basic blocks. |
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
|
1223 These fields are then initialized with the tree expressions |
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
|
1224 representing the predicates under which a basic block is executed |
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
|
1225 in the LOOP. As the loop->header is executed at each iteration, it |
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
|
1226 has the "true" predicate. Other statements executed under a |
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
|
1227 condition are predicated with that condition, for example |
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
|
1228 |
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
|
1229 | if (x) |
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
|
1230 | S1; |
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
|
1231 | 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
|
1232 | S2; |
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
|
1233 |
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
|
1234 S1 will be predicated with "x", and |
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
|
1235 S2 will be predicated with "!x". */ |
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
|
1236 |
111 | 1237 static void |
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
|
1238 predicate_bbs (loop_p loop) |
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
|
1239 { |
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
|
1240 unsigned int i; |
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
|
1241 |
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
|
1242 for (i = 0; i < loop->num_nodes; i++) |
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
|
1243 init_bb_predicate (ifc_bbs[i]); |
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
|
1244 |
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
|
1245 for (i = 0; i < loop->num_nodes; i++) |
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
|
1246 { |
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
|
1247 basic_block bb = ifc_bbs[i]; |
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
|
1248 tree cond; |
111 | 1249 gimple *stmt; |
1250 | |
1251 /* The loop latch and loop exit block are always executed and | |
1252 have no extra conditions to be processed: skip them. */ | |
1253 if (bb == loop->latch | |
1254 || bb_with_exit_edge_p (loop, bb)) | |
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
|
1255 { |
111 | 1256 reset_bb_predicate (bb); |
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
|
1257 continue; |
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
|
1258 } |
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
|
1259 |
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
|
1260 cond = bb_predicate (bb); |
111 | 1261 stmt = last_stmt (bb); |
1262 if (stmt && gimple_code (stmt) == GIMPLE_COND) | |
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
|
1263 { |
111 | 1264 tree c2; |
1265 edge true_edge, false_edge; | |
1266 location_t loc = gimple_location (stmt); | |
1267 tree c = build2_loc (loc, gimple_cond_code (stmt), | |
1268 boolean_type_node, | |
1269 gimple_cond_lhs (stmt), | |
1270 gimple_cond_rhs (stmt)); | |
1271 | |
1272 /* Add new condition into destination's predicate list. */ | |
1273 extract_true_false_edges_from_block (gimple_bb (stmt), | |
1274 &true_edge, &false_edge); | |
1275 | |
1276 /* If C is true, then TRUE_EDGE is taken. */ | |
1277 add_to_dst_predicate_list (loop, true_edge, unshare_expr (cond), | |
1278 unshare_expr (c)); | |
1279 | |
1280 /* If C is false, then FALSE_EDGE is taken. */ | |
1281 c2 = build1_loc (loc, TRUTH_NOT_EXPR, boolean_type_node, | |
1282 unshare_expr (c)); | |
1283 add_to_dst_predicate_list (loop, false_edge, | |
1284 unshare_expr (cond), c2); | |
1285 | |
1286 cond = NULL_TREE; | |
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
|
1287 } |
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
|
1288 |
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
|
1289 /* If current bb has only one successor, then consider it as an |
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
|
1290 unconditional goto. */ |
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
|
1291 if (single_succ_p (bb)) |
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
|
1292 { |
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
|
1293 basic_block bb_n = single_succ (bb); |
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
|
1294 |
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
|
1295 /* The successor bb inherits the predicate of its |
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
|
1296 predecessor. If there is no predicate in the predecessor |
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
|
1297 bb, then consider the successor bb as always executed. */ |
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
|
1298 if (cond == NULL_TREE) |
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
|
1299 cond = boolean_true_node; |
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 |
111 | 1301 add_to_predicate_list (loop, bb_n, cond); |
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
|
1302 } |
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
|
1303 } |
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
|
1304 |
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
|
1305 /* The loop header is always executed. */ |
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
|
1306 reset_bb_predicate (loop->header); |
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
|
1307 gcc_assert (bb_predicate_gimplified_stmts (loop->header) == NULL |
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
|
1308 && bb_predicate_gimplified_stmts (loop->latch) == NULL); |
111 | 1309 } |
1310 | |
1311 /* Build region by adding loop pre-header and post-header blocks. */ | |
1312 | |
1313 static vec<basic_block> | |
1314 build_region (struct loop *loop) | |
1315 { | |
1316 vec<basic_block> region = vNULL; | |
1317 basic_block exit_bb = NULL; | |
1318 | |
1319 gcc_assert (ifc_bbs); | |
1320 /* The first element is loop pre-header. */ | |
1321 region.safe_push (loop_preheader_edge (loop)->src); | |
1322 | |
1323 for (unsigned int i = 0; i < loop->num_nodes; i++) | |
1324 { | |
1325 basic_block bb = ifc_bbs[i]; | |
1326 region.safe_push (bb); | |
1327 /* Find loop postheader. */ | |
1328 edge e; | |
1329 edge_iterator ei; | |
1330 FOR_EACH_EDGE (e, ei, bb->succs) | |
1331 if (loop_exit_edge_p (loop, e)) | |
1332 { | |
1333 exit_bb = e->dest; | |
1334 break; | |
1335 } | |
1336 } | |
1337 /* The last element is loop post-header. */ | |
1338 gcc_assert (exit_bb); | |
1339 region.safe_push (exit_bb); | |
1340 return region; | |
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
|
1341 } |
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
|
1342 |
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
|
1343 /* Return true when LOOP is if-convertible. This is a helper function |
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
|
1344 for if_convertible_loop_p. REFS and DDRS are initialized and freed |
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
|
1345 in if_convertible_loop_p. */ |
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
|
1346 |
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
|
1347 static bool |
111 | 1348 if_convertible_loop_p_1 (struct loop *loop, vec<data_reference_p> *refs) |
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
|
1349 { |
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
|
1350 unsigned int i; |
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
|
1351 basic_block exit_bb = NULL; |
111 | 1352 vec<basic_block> region; |
1353 | |
1354 if (find_data_references_in_loop (loop, refs) == chrec_dont_know) | |
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
|
1355 return false; |
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
|
1356 |
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
|
1357 calculate_dominance_info (CDI_DOMINATORS); |
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
|
1358 |
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
|
1359 /* Allow statements that can be handled during if-conversion. */ |
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
|
1360 ifc_bbs = get_loop_body_in_if_conv_order (loop); |
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
|
1361 if (!ifc_bbs) |
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
|
1362 { |
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
|
1363 if (dump_file && (dump_flags & TDF_DETAILS)) |
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
|
1364 fprintf (dump_file, "Irreducible loop\n"); |
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
|
1365 return false; |
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
|
1366 } |
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
|
1367 |
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
|
1368 for (i = 0; i < loop->num_nodes; i++) |
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
|
1369 { |
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
|
1370 basic_block bb = ifc_bbs[i]; |
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
|
1371 |
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
|
1372 if (!if_convertible_bb_p (loop, bb, exit_bb)) |
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
|
1373 return false; |
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
|
1374 |
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
|
1375 if (bb_with_exit_edge_p (loop, bb)) |
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
|
1376 exit_bb = bb; |
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
|
1377 } |
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
|
1378 |
111 | 1379 for (i = 0; i < loop->num_nodes; i++) |
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
|
1380 { |
111 | 1381 basic_block bb = ifc_bbs[i]; |
1382 gimple_stmt_iterator gsi; | |
1383 | |
1384 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) | |
1385 switch (gimple_code (gsi_stmt (gsi))) | |
1386 { | |
1387 case GIMPLE_LABEL: | |
1388 case GIMPLE_ASSIGN: | |
1389 case GIMPLE_CALL: | |
1390 case GIMPLE_DEBUG: | |
1391 case GIMPLE_COND: | |
1392 gimple_set_uid (gsi_stmt (gsi), 0); | |
1393 break; | |
1394 default: | |
1395 return false; | |
1396 } | |
1397 } | |
1398 | |
1399 data_reference_p dr; | |
1400 | |
1401 innermost_DR_map | |
1402 = new hash_map<innermost_loop_behavior_hash, data_reference_p>; | |
1403 baseref_DR_map = new hash_map<tree_operand_hash, data_reference_p>; | |
1404 | |
1405 /* Compute post-dominator tree locally. */ | |
1406 region = build_region (loop); | |
1407 calculate_dominance_info_for_region (CDI_POST_DOMINATORS, region); | |
1408 | |
1409 predicate_bbs (loop); | |
1410 | |
1411 /* Free post-dominator tree since it is not used after predication. */ | |
1412 free_dominance_info_for_region (cfun, CDI_POST_DOMINATORS, region); | |
1413 region.release (); | |
1414 | |
1415 for (i = 0; refs->iterate (i, &dr); i++) | |
1416 { | |
1417 tree ref = DR_REF (dr); | |
1418 | |
1419 dr->aux = XNEW (struct ifc_dr); | |
1420 DR_BASE_W_UNCONDITIONALLY (dr) = false; | |
1421 DR_RW_UNCONDITIONALLY (dr) = false; | |
1422 DR_W_UNCONDITIONALLY (dr) = false; | |
1423 IFC_DR (dr)->rw_predicate = boolean_false_node; | |
1424 IFC_DR (dr)->w_predicate = boolean_false_node; | |
1425 IFC_DR (dr)->base_w_predicate = boolean_false_node; | |
1426 if (gimple_uid (DR_STMT (dr)) == 0) | |
1427 gimple_set_uid (DR_STMT (dr), i + 1); | |
1428 | |
1429 /* If DR doesn't have innermost loop behavior or it's a compound | |
1430 memory reference, we synthesize its innermost loop behavior | |
1431 for hashing. */ | |
1432 if (TREE_CODE (ref) == COMPONENT_REF | |
1433 || TREE_CODE (ref) == IMAGPART_EXPR | |
1434 || TREE_CODE (ref) == REALPART_EXPR | |
1435 || !(DR_BASE_ADDRESS (dr) || DR_OFFSET (dr) | |
1436 || DR_INIT (dr) || DR_STEP (dr))) | |
1437 { | |
1438 while (TREE_CODE (ref) == COMPONENT_REF | |
1439 || TREE_CODE (ref) == IMAGPART_EXPR | |
1440 || TREE_CODE (ref) == REALPART_EXPR) | |
1441 ref = TREE_OPERAND (ref, 0); | |
1442 | |
1443 memset (&DR_INNERMOST (dr), 0, sizeof (DR_INNERMOST (dr))); | |
1444 DR_BASE_ADDRESS (dr) = ref; | |
1445 } | |
1446 hash_memrefs_baserefs_and_store_DRs_read_written_info (dr); | |
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 } |
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
|
1448 |
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
|
1449 for (i = 0; i < loop->num_nodes; i++) |
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
|
1450 { |
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
|
1451 basic_block bb = ifc_bbs[i]; |
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 gimple_stmt_iterator itr; |
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
|
1453 |
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 /* Check the if-convertibility of statements in predicated BBs. */ |
111 | 1455 if (!dominated_by_p (CDI_DOMINATORS, loop->latch, bb)) |
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 for (itr = gsi_start_bb (bb); !gsi_end_p (itr); gsi_next (&itr)) |
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
|
1457 if (!if_convertible_stmt_p (gsi_stmt (itr), *refs)) |
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
|
1458 return false; |
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
|
1459 } |
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
|
1460 |
111 | 1461 /* Checking PHIs needs to be done after stmts, as the fact whether there |
1462 are any masked loads or stores affects the tests. */ | |
1463 for (i = 0; i < loop->num_nodes; i++) | |
1464 { | |
1465 basic_block bb = ifc_bbs[i]; | |
1466 gphi_iterator itr; | |
1467 | |
1468 for (itr = gsi_start_phis (bb); !gsi_end_p (itr); gsi_next (&itr)) | |
1469 if (!if_convertible_phi_p (loop, bb, itr.phi ())) | |
1470 return false; | |
1471 } | |
1472 | |
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 if (dump_file) |
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
|
1474 fprintf (dump_file, "Applying if-conversion\n"); |
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
|
1475 |
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
|
1476 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
|
1477 } |
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
|
1478 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1479 /* Return true when LOOP is if-convertible. |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1480 LOOP is if-convertible if: |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1481 - it is innermost, |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1482 - it has two or more basic blocks, |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1483 - it has only one exit, |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1484 - loop header is not the exit edge, |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1485 - if its basic blocks and phi nodes are if convertible. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1486 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1487 static bool |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1488 if_convertible_loop_p (struct loop *loop) |
0 | 1489 { |
1490 edge e; | |
1491 edge_iterator ei; | |
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
|
1492 bool res = false; |
111 | 1493 vec<data_reference_p> refs; |
0 | 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 /* Handle only innermost loop. */ |
0 | 1496 if (!loop || loop->inner) |
1497 { | |
1498 if (dump_file && (dump_flags & TDF_DETAILS)) | |
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
|
1499 fprintf (dump_file, "not innermost loop\n"); |
0 | 1500 return false; |
1501 } | |
1502 | |
1503 /* If only one block, no need for if-conversion. */ | |
1504 if (loop->num_nodes <= 2) | |
1505 { | |
1506 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1507 fprintf (dump_file, "less than 2 basic blocks\n"); | |
1508 return false; | |
1509 } | |
1510 | |
1511 /* More than one loop exit is too much to handle. */ | |
1512 if (!single_exit (loop)) | |
1513 { | |
1514 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1515 fprintf (dump_file, "multiple exits\n"); | |
1516 return false; | |
1517 } | |
1518 | |
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
|
1519 /* If one of the loop header's edge is an exit edge then do not |
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
|
1520 apply if-conversion. */ |
0 | 1521 FOR_EACH_EDGE (e, ei, loop->header->succs) |
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
|
1522 if (loop_exit_edge_p (loop, e)) |
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
|
1523 return false; |
0 | 1524 |
111 | 1525 refs.create (5); |
1526 res = if_convertible_loop_p_1 (loop, &refs); | |
1527 | |
1528 data_reference_p dr; | |
1529 unsigned int i; | |
1530 for (i = 0; refs.iterate (i, &dr); i++) | |
1531 free (dr->aux); | |
1532 | |
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
|
1533 free_data_refs (refs); |
111 | 1534 |
1535 delete innermost_DR_map; | |
1536 innermost_DR_map = NULL; | |
1537 | |
1538 delete baseref_DR_map; | |
1539 baseref_DR_map = NULL; | |
1540 | |
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
|
1541 return res; |
0 | 1542 } |
1543 | |
111 | 1544 /* Returns true if def-stmt for phi argument ARG is simple increment/decrement |
1545 which is in predicated basic block. | |
1546 In fact, the following PHI pattern is searching: | |
1547 loop-header: | |
1548 reduc_1 = PHI <..., reduc_2> | |
1549 ... | |
1550 if (...) | |
1551 reduc_3 = ... | |
1552 reduc_2 = PHI <reduc_1, reduc_3> | |
1553 | |
1554 ARG_0 and ARG_1 are correspondent PHI arguments. | |
1555 REDUC, OP0 and OP1 contain reduction stmt and its operands. | |
1556 EXTENDED is true if PHI has > 2 arguments. */ | |
1557 | |
1558 static bool | |
1559 is_cond_scalar_reduction (gimple *phi, gimple **reduc, tree arg_0, tree arg_1, | |
1560 tree *op0, tree *op1, bool extended) | |
0 | 1561 { |
111 | 1562 tree lhs, r_op1, r_op2; |
1563 gimple *stmt; | |
1564 gimple *header_phi = NULL; | |
1565 enum tree_code reduction_op; | |
1566 basic_block bb = gimple_bb (phi); | |
1567 struct loop *loop = bb->loop_father; | |
1568 edge latch_e = loop_latch_edge (loop); | |
1569 imm_use_iterator imm_iter; | |
1570 use_operand_p use_p; | |
1571 edge e; | |
1572 edge_iterator ei; | |
1573 bool result = false; | |
1574 if (TREE_CODE (arg_0) != SSA_NAME || TREE_CODE (arg_1) != SSA_NAME) | |
1575 return false; | |
1576 | |
1577 if (!extended && gimple_code (SSA_NAME_DEF_STMT (arg_0)) == GIMPLE_PHI) | |
0 | 1578 { |
111 | 1579 lhs = arg_1; |
1580 header_phi = SSA_NAME_DEF_STMT (arg_0); | |
1581 stmt = SSA_NAME_DEF_STMT (arg_1); | |
0 | 1582 } |
111 | 1583 else if (gimple_code (SSA_NAME_DEF_STMT (arg_1)) == GIMPLE_PHI) |
0 | 1584 { |
111 | 1585 lhs = arg_0; |
1586 header_phi = SSA_NAME_DEF_STMT (arg_1); | |
1587 stmt = SSA_NAME_DEF_STMT (arg_0); | |
0 | 1588 } |
1589 else | |
111 | 1590 return false; |
1591 if (gimple_bb (header_phi) != loop->header) | |
1592 return false; | |
1593 | |
1594 if (PHI_ARG_DEF_FROM_EDGE (header_phi, latch_e) != PHI_RESULT (phi)) | |
1595 return false; | |
1596 | |
1597 if (gimple_code (stmt) != GIMPLE_ASSIGN | |
1598 || gimple_has_volatile_ops (stmt)) | |
1599 return false; | |
1600 | |
1601 if (!flow_bb_inside_loop_p (loop, gimple_bb (stmt))) | |
1602 return false; | |
1603 | |
1604 if (!is_predicated (gimple_bb (stmt))) | |
1605 return false; | |
1606 | |
1607 /* Check that stmt-block is predecessor of phi-block. */ | |
1608 FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->succs) | |
1609 if (e->dest == bb) | |
1610 { | |
1611 result = true; | |
1612 break; | |
1613 } | |
1614 if (!result) | |
1615 return false; | |
1616 | |
1617 if (!has_single_use (lhs)) | |
1618 return false; | |
1619 | |
1620 reduction_op = gimple_assign_rhs_code (stmt); | |
1621 if (reduction_op != PLUS_EXPR && reduction_op != MINUS_EXPR) | |
1622 return false; | |
1623 r_op1 = gimple_assign_rhs1 (stmt); | |
1624 r_op2 = gimple_assign_rhs2 (stmt); | |
1625 | |
1626 /* Make R_OP1 to hold reduction variable. */ | |
1627 if (r_op2 == PHI_RESULT (header_phi) | |
1628 && reduction_op == PLUS_EXPR) | |
1629 std::swap (r_op1, r_op2); | |
1630 else if (r_op1 != PHI_RESULT (header_phi)) | |
1631 return false; | |
1632 | |
1633 /* Check that R_OP1 is used in reduction stmt or in PHI only. */ | |
1634 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, r_op1) | |
1635 { | |
1636 gimple *use_stmt = USE_STMT (use_p); | |
1637 if (is_gimple_debug (use_stmt)) | |
1638 continue; | |
1639 if (use_stmt == stmt) | |
1640 continue; | |
1641 if (gimple_code (use_stmt) != GIMPLE_PHI) | |
1642 return false; | |
1643 } | |
1644 | |
1645 *op0 = r_op1; *op1 = r_op2; | |
1646 *reduc = stmt; | |
1647 return true; | |
1648 } | |
1649 | |
1650 /* Converts conditional scalar reduction into unconditional form, e.g. | |
1651 bb_4 | |
1652 if (_5 != 0) goto bb_5 else goto bb_6 | |
1653 end_bb_4 | |
1654 bb_5 | |
1655 res_6 = res_13 + 1; | |
1656 end_bb_5 | |
1657 bb_6 | |
1658 # res_2 = PHI <res_13(4), res_6(5)> | |
1659 end_bb_6 | |
1660 | |
1661 will be converted into sequence | |
1662 _ifc__1 = _5 != 0 ? 1 : 0; | |
1663 res_2 = res_13 + _ifc__1; | |
1664 Argument SWAP tells that arguments of conditional expression should be | |
1665 swapped. | |
1666 Returns rhs of resulting PHI assignment. */ | |
1667 | |
1668 static tree | |
1669 convert_scalar_cond_reduction (gimple *reduc, gimple_stmt_iterator *gsi, | |
1670 tree cond, tree op0, tree op1, bool swap) | |
1671 { | |
1672 gimple_stmt_iterator stmt_it; | |
1673 gimple *new_assign; | |
1674 tree rhs; | |
1675 tree rhs1 = gimple_assign_rhs1 (reduc); | |
1676 tree tmp = make_temp_ssa_name (TREE_TYPE (rhs1), NULL, "_ifc_"); | |
1677 tree c; | |
1678 tree zero = build_zero_cst (TREE_TYPE (rhs1)); | |
1679 | |
1680 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1681 { | |
1682 fprintf (dump_file, "Found cond scalar reduction.\n"); | |
1683 print_gimple_stmt (dump_file, reduc, 0, TDF_SLIM); | |
1684 } | |
1685 | |
1686 /* Build cond expression using COND and constant operand | |
1687 of reduction rhs. */ | |
1688 c = fold_build_cond_expr (TREE_TYPE (rhs1), | |
1689 unshare_expr (cond), | |
1690 swap ? zero : op1, | |
1691 swap ? op1 : zero); | |
1692 | |
1693 /* Create assignment stmt and insert it at GSI. */ | |
1694 new_assign = gimple_build_assign (tmp, c); | |
1695 gsi_insert_before (gsi, new_assign, GSI_SAME_STMT); | |
1696 /* Build rhs for unconditional increment/decrement. */ | |
1697 rhs = fold_build2 (gimple_assign_rhs_code (reduc), | |
1698 TREE_TYPE (rhs1), op0, tmp); | |
1699 | |
1700 /* Delete original reduction stmt. */ | |
1701 stmt_it = gsi_for_stmt (reduc); | |
1702 gsi_remove (&stmt_it, true); | |
1703 release_defs (reduc); | |
1704 return rhs; | |
1705 } | |
1706 | |
1707 /* Produce condition for all occurrences of ARG in PHI node. */ | |
1708 | |
1709 static tree | |
1710 gen_phi_arg_condition (gphi *phi, vec<int> *occur, | |
1711 gimple_stmt_iterator *gsi) | |
1712 { | |
1713 int len; | |
1714 int i; | |
1715 tree cond = NULL_TREE; | |
1716 tree c; | |
1717 edge e; | |
1718 | |
1719 len = occur->length (); | |
1720 gcc_assert (len > 0); | |
1721 for (i = 0; i < len; i++) | |
1722 { | |
1723 e = gimple_phi_arg_edge (phi, (*occur)[i]); | |
1724 c = bb_predicate (e->src); | |
1725 if (is_true_predicate (c)) | |
1726 { | |
1727 cond = c; | |
1728 break; | |
1729 } | |
1730 c = force_gimple_operand_gsi_1 (gsi, unshare_expr (c), | |
1731 is_gimple_condexpr, NULL_TREE, | |
1732 true, GSI_SAME_STMT); | |
1733 if (cond != NULL_TREE) | |
1734 { | |
1735 /* Must build OR expression. */ | |
1736 cond = fold_or_predicates (EXPR_LOCATION (c), c, cond); | |
1737 cond = force_gimple_operand_gsi_1 (gsi, unshare_expr (cond), | |
1738 is_gimple_condexpr, NULL_TREE, | |
1739 true, GSI_SAME_STMT); | |
1740 } | |
1741 else | |
1742 cond = c; | |
1743 } | |
1744 gcc_assert (cond != NULL_TREE); | |
1745 return cond; | |
1746 } | |
1747 | |
1748 /* Local valueization callback that follows all-use SSA edges. */ | |
1749 | |
1750 static tree | |
1751 ifcvt_follow_ssa_use_edges (tree val) | |
1752 { | |
1753 return val; | |
0 | 1754 } |
1755 | |
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
|
1756 /* Replace a scalar PHI node with a COND_EXPR using COND as condition. |
111 | 1757 This routine can handle PHI nodes with more than two arguments. |
0 | 1758 |
1759 For example, | |
111 | 1760 S1: A = PHI <x1(1), x2(5)> |
0 | 1761 is converted into, |
1762 S2: A = cond ? x1 : x2; | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1763 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1764 The generated code is inserted at GSI that points to the top of |
111 | 1765 basic block's statement list. |
1766 If PHI node has more than two arguments a chain of conditional | |
1767 expression is produced. */ | |
1768 | |
0 | 1769 |
1770 static void | |
111 | 1771 predicate_scalar_phi (gphi *phi, gimple_stmt_iterator *gsi) |
0 | 1772 { |
111 | 1773 gimple *new_stmt = NULL, *reduc; |
1774 tree rhs, res, arg0, arg1, op0, op1, scev; | |
1775 tree cond; | |
1776 unsigned int index0; | |
1777 unsigned int max, args_len; | |
1778 edge e; | |
0 | 1779 basic_block bb; |
111 | 1780 unsigned int i; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1781 |
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
|
1782 res = gimple_phi_result (phi); |
111 | 1783 if (virtual_operand_p (res)) |
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
|
1784 return; |
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
|
1785 |
111 | 1786 if ((rhs = degenerate_phi_result (phi)) |
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
|
1787 || ((scev = analyze_scalar_evolution (gimple_bb (phi)->loop_father, |
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
|
1788 res)) |
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
|
1789 && !chrec_contains_undetermined (scev) |
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
|
1790 && scev != res |
111 | 1791 && (rhs = gimple_phi_arg_def (phi, 0)))) |
1792 { | |
1793 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1794 { | |
1795 fprintf (dump_file, "Degenerate phi!\n"); | |
1796 print_gimple_stmt (dump_file, phi, 0, TDF_SLIM); | |
1797 } | |
1798 new_stmt = gimple_build_assign (res, rhs); | |
1799 gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT); | |
1800 update_stmt (new_stmt); | |
1801 return; | |
1802 } | |
1803 | |
1804 bb = gimple_bb (phi); | |
1805 if (EDGE_COUNT (bb->preds) == 2) | |
0 | 1806 { |
111 | 1807 /* Predicate ordinary PHI node with 2 arguments. */ |
1808 edge first_edge, second_edge; | |
1809 basic_block true_bb; | |
1810 first_edge = EDGE_PRED (bb, 0); | |
1811 second_edge = EDGE_PRED (bb, 1); | |
1812 cond = bb_predicate (first_edge->src); | |
1813 if (TREE_CODE (cond) == TRUTH_NOT_EXPR) | |
1814 std::swap (first_edge, second_edge); | |
1815 if (EDGE_COUNT (first_edge->src->succs) > 1) | |
1816 { | |
1817 cond = bb_predicate (second_edge->src); | |
1818 if (TREE_CODE (cond) == TRUTH_NOT_EXPR) | |
1819 cond = TREE_OPERAND (cond, 0); | |
1820 else | |
1821 first_edge = second_edge; | |
1822 } | |
1823 else | |
1824 cond = bb_predicate (first_edge->src); | |
1825 /* Gimplify the condition to a valid cond-expr conditonal operand. */ | |
1826 cond = force_gimple_operand_gsi_1 (gsi, unshare_expr (cond), | |
1827 is_gimple_condexpr, NULL_TREE, | |
1828 true, GSI_SAME_STMT); | |
1829 true_bb = first_edge->src; | |
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
|
1830 if (EDGE_PRED (bb, 1)->src == true_bb) |
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
|
1831 { |
111 | 1832 arg0 = gimple_phi_arg_def (phi, 1); |
1833 arg1 = gimple_phi_arg_def (phi, 0); | |
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
|
1834 } |
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
|
1835 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
|
1836 { |
111 | 1837 arg0 = gimple_phi_arg_def (phi, 0); |
1838 arg1 = gimple_phi_arg_def (phi, 1); | |
1839 } | |
1840 if (is_cond_scalar_reduction (phi, &reduc, arg0, arg1, | |
1841 &op0, &op1, false)) | |
1842 /* Convert reduction stmt into vectorizable form. */ | |
1843 rhs = convert_scalar_cond_reduction (reduc, gsi, cond, op0, op1, | |
1844 true_bb != gimple_bb (reduc)); | |
1845 else | |
1846 /* Build new RHS using selected condition and arguments. */ | |
1847 rhs = fold_build_cond_expr (TREE_TYPE (res), unshare_expr (cond), | |
1848 arg0, arg1); | |
1849 new_stmt = gimple_build_assign (res, rhs); | |
1850 gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT); | |
1851 gimple_stmt_iterator new_gsi = gsi_for_stmt (new_stmt); | |
1852 if (fold_stmt (&new_gsi, ifcvt_follow_ssa_use_edges)) | |
1853 { | |
1854 new_stmt = gsi_stmt (new_gsi); | |
1855 update_stmt (new_stmt); | |
1856 } | |
1857 | |
1858 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1859 { | |
1860 fprintf (dump_file, "new phi replacement stmt\n"); | |
1861 print_gimple_stmt (dump_file, new_stmt, 0, TDF_SLIM); | |
1862 } | |
1863 return; | |
1864 } | |
1865 | |
1866 /* Create hashmap for PHI node which contain vector of argument indexes | |
1867 having the same value. */ | |
1868 bool swap = false; | |
1869 hash_map<tree_operand_hash, auto_vec<int> > phi_arg_map; | |
1870 unsigned int num_args = gimple_phi_num_args (phi); | |
1871 int max_ind = -1; | |
1872 /* Vector of different PHI argument values. */ | |
1873 auto_vec<tree> args (num_args); | |
1874 | |
1875 /* Compute phi_arg_map. */ | |
1876 for (i = 0; i < num_args; i++) | |
1877 { | |
1878 tree arg; | |
1879 | |
1880 arg = gimple_phi_arg_def (phi, i); | |
1881 if (!phi_arg_map.get (arg)) | |
1882 args.quick_push (arg); | |
1883 phi_arg_map.get_or_insert (arg).safe_push (i); | |
1884 } | |
1885 | |
1886 /* Determine element with max number of occurrences. */ | |
1887 max_ind = -1; | |
1888 max = 1; | |
1889 args_len = args.length (); | |
1890 for (i = 0; i < args_len; i++) | |
1891 { | |
1892 unsigned int len; | |
1893 if ((len = phi_arg_map.get (args[i])->length ()) > max) | |
1894 { | |
1895 max_ind = (int) i; | |
1896 max = len; | |
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
|
1897 } |
0 | 1898 } |
1899 | |
111 | 1900 /* Put element with max number of occurences to the end of ARGS. */ |
1901 if (max_ind != -1 && max_ind +1 != (int) args_len) | |
1902 std::swap (args[args_len - 1], args[max_ind]); | |
1903 | |
1904 /* Handle one special case when number of arguments with different values | |
1905 is equal 2 and one argument has the only occurrence. Such PHI can be | |
1906 handled as if would have only 2 arguments. */ | |
1907 if (args_len == 2 && phi_arg_map.get (args[0])->length () == 1) | |
1908 { | |
1909 vec<int> *indexes; | |
1910 indexes = phi_arg_map.get (args[0]); | |
1911 index0 = (*indexes)[0]; | |
1912 arg0 = args[0]; | |
1913 arg1 = args[1]; | |
1914 e = gimple_phi_arg_edge (phi, index0); | |
1915 cond = bb_predicate (e->src); | |
1916 if (TREE_CODE (cond) == TRUTH_NOT_EXPR) | |
1917 { | |
1918 swap = true; | |
1919 cond = TREE_OPERAND (cond, 0); | |
1920 } | |
1921 /* Gimplify the condition to a valid cond-expr conditonal operand. */ | |
1922 cond = force_gimple_operand_gsi_1 (gsi, unshare_expr (cond), | |
1923 is_gimple_condexpr, NULL_TREE, | |
1924 true, GSI_SAME_STMT); | |
1925 if (!(is_cond_scalar_reduction (phi, &reduc, arg0 , arg1, | |
1926 &op0, &op1, true))) | |
1927 rhs = fold_build_cond_expr (TREE_TYPE (res), unshare_expr (cond), | |
1928 swap? arg1 : arg0, | |
1929 swap? arg0 : arg1); | |
1930 else | |
1931 /* Convert reduction stmt into vectorizable form. */ | |
1932 rhs = convert_scalar_cond_reduction (reduc, gsi, cond, op0, op1, | |
1933 swap); | |
1934 new_stmt = gimple_build_assign (res, rhs); | |
1935 gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT); | |
1936 update_stmt (new_stmt); | |
1937 } | |
1938 else | |
1939 { | |
1940 /* Common case. */ | |
1941 vec<int> *indexes; | |
1942 tree type = TREE_TYPE (gimple_phi_result (phi)); | |
1943 tree lhs; | |
1944 arg1 = args[1]; | |
1945 for (i = 0; i < args_len; i++) | |
1946 { | |
1947 arg0 = args[i]; | |
1948 indexes = phi_arg_map.get (args[i]); | |
1949 if (i != args_len - 1) | |
1950 lhs = make_temp_ssa_name (type, NULL, "_ifc_"); | |
1951 else | |
1952 lhs = res; | |
1953 cond = gen_phi_arg_condition (phi, indexes, gsi); | |
1954 rhs = fold_build_cond_expr (type, unshare_expr (cond), | |
1955 arg0, arg1); | |
1956 new_stmt = gimple_build_assign (lhs, rhs); | |
1957 gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT); | |
1958 update_stmt (new_stmt); | |
1959 arg1 = lhs; | |
1960 } | |
1961 } | |
0 | 1962 |
1963 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1964 { | |
111 | 1965 fprintf (dump_file, "new extended phi replacement stmt\n"); |
0 | 1966 print_gimple_stmt (dump_file, new_stmt, 0, TDF_SLIM); |
1967 } | |
1968 } | |
1969 | |
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
|
1970 /* Replaces in LOOP all the scalar phi nodes other than those in the |
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
|
1971 LOOP->header block with conditional modify expressions. */ |
0 | 1972 |
1973 static void | |
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
|
1974 predicate_all_scalar_phis (struct loop *loop) |
0 | 1975 { |
1976 basic_block bb; | |
1977 unsigned int orig_loop_num_nodes = loop->num_nodes; | |
1978 unsigned int i; | |
1979 | |
1980 for (i = 1; i < orig_loop_num_nodes; i++) | |
1981 { | |
111 | 1982 gphi *phi; |
1983 gimple_stmt_iterator gsi; | |
1984 gphi_iterator phi_gsi; | |
0 | 1985 bb = ifc_bbs[i]; |
1986 | |
1987 if (bb == loop->header) | |
1988 continue; | |
1989 | |
1990 phi_gsi = gsi_start_phis (bb); | |
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
|
1991 if (gsi_end_p (phi_gsi)) |
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
|
1992 continue; |
0 | 1993 |
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
|
1994 gsi = gsi_after_labels (bb); |
0 | 1995 while (!gsi_end_p (phi_gsi)) |
1996 { | |
111 | 1997 phi = phi_gsi.phi (); |
1998 if (virtual_operand_p (gimple_phi_result (phi))) | |
1999 gsi_next (&phi_gsi); | |
2000 else | |
2001 { | |
2002 predicate_scalar_phi (phi, &gsi); | |
2003 remove_phi_node (&phi_gsi, false); | |
2004 } | |
0 | 2005 } |
2006 } | |
2007 } | |
2008 | |
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
|
2009 /* Insert in each basic block of LOOP the statements produced by the |
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
|
2010 gimplification of the predicates. */ |
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
|
2011 |
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
|
2012 static void |
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
|
2013 insert_gimplified_predicates (loop_p loop) |
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
|
2014 { |
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
|
2015 unsigned int i; |
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
|
2016 |
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
|
2017 for (i = 0; i < loop->num_nodes; i++) |
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
|
2018 { |
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
|
2019 basic_block bb = ifc_bbs[i]; |
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
|
2020 gimple_seq stmts; |
111 | 2021 if (!is_predicated (bb)) |
2022 gcc_assert (bb_predicate_gimplified_stmts (bb) == NULL); | |
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
|
2023 if (!is_predicated (bb)) |
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
|
2024 { |
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
|
2025 /* Do not insert statements for a basic block that is not |
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
|
2026 predicated. Also make sure that the predicate of the |
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
|
2027 basic block is set to 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
|
2028 reset_bb_predicate (bb); |
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
|
2029 continue; |
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
|
2030 } |
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
|
2031 |
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
|
2032 stmts = bb_predicate_gimplified_stmts (bb); |
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
|
2033 if (stmts) |
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
|
2034 { |
111 | 2035 if (any_pred_load_store) |
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
|
2036 { |
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
|
2037 /* Insert the predicate of the BB just after the label, |
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
|
2038 as the if-conversion of memory writes will use this |
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
|
2039 predicate. */ |
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
|
2040 gimple_stmt_iterator gsi = gsi_after_labels (bb); |
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
|
2041 gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT); |
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
|
2042 } |
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
|
2043 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
|
2044 { |
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
|
2045 /* Insert the predicate of the BB at the end of the BB |
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
|
2046 as this would reduce the register pressure: the only |
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
|
2047 use of this predicate will be in successor BBs. */ |
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
|
2048 gimple_stmt_iterator gsi = gsi_last_bb (bb); |
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
|
2049 |
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
|
2050 if (gsi_end_p (gsi) |
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
|
2051 || stmt_ends_bb_p (gsi_stmt (gsi))) |
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
|
2052 gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT); |
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
|
2053 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
|
2054 gsi_insert_seq_after (&gsi, stmts, GSI_SAME_STMT); |
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
|
2055 } |
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
|
2056 |
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
|
2057 /* Once the sequence is code generated, set it to NULL. */ |
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
|
2058 set_bb_predicate_gimplified_stmts (bb, NULL); |
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
|
2059 } |
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
|
2060 } |
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
|
2061 } |
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
|
2062 |
111 | 2063 /* Helper function for predicate_mem_writes. Returns index of existent |
2064 mask if it was created for given SIZE and -1 otherwise. */ | |
2065 | |
2066 static int | |
2067 mask_exists (int size, vec<int> vec) | |
2068 { | |
2069 unsigned int ix; | |
2070 int v; | |
2071 FOR_EACH_VEC_ELT (vec, ix, v) | |
2072 if (v == size) | |
2073 return (int) ix; | |
2074 return -1; | |
2075 } | |
2076 | |
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
|
2077 /* Predicate each write to memory in LOOP. |
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
|
2078 |
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
|
2079 This function transforms control flow constructs containing memory |
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
|
2080 writes of the form: |
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
|
2081 |
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
|
2082 | for (i = 0; i < N; i++) |
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
|
2083 | if (cond) |
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
|
2084 | A[i] = expr; |
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
|
2085 |
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
|
2086 into the following form that does not contain control flow: |
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
|
2087 |
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
|
2088 | for (i = 0; i < N; i++) |
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
|
2089 | A[i] = cond ? expr : A[i]; |
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
|
2090 |
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
|
2091 The original CFG looks like this: |
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
|
2092 |
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
|
2093 | bb_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
|
2094 | i = 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
|
2095 | end_bb_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
|
2096 | |
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
|
2097 | bb_1 |
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
|
2098 | if (i < N) goto bb_5 else goto bb_2 |
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
|
2099 | end_bb_1 |
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
|
2100 | |
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
|
2101 | bb_2 |
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
|
2102 | cond = some_computation; |
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
|
2103 | if (cond) goto bb_3 else goto bb_4 |
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
|
2104 | end_bb_2 |
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
|
2105 | |
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
|
2106 | bb_3 |
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
|
2107 | A[i] = expr; |
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
|
2108 | goto bb_4 |
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
|
2109 | end_bb_3 |
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
|
2110 | |
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
|
2111 | bb_4 |
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
|
2112 | goto bb_1 |
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
|
2113 | end_bb_4 |
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
|
2114 |
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
|
2115 insert_gimplified_predicates inserts the computation of the COND |
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
|
2116 expression at the beginning of the destination basic block: |
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
|
2117 |
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
|
2118 | bb_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
|
2119 | i = 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
|
2120 | end_bb_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
|
2121 | |
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
|
2122 | bb_1 |
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
|
2123 | if (i < N) goto bb_5 else goto bb_2 |
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
|
2124 | end_bb_1 |
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
|
2125 | |
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
|
2126 | bb_2 |
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
|
2127 | cond = some_computation; |
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
|
2128 | if (cond) goto bb_3 else goto bb_4 |
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
|
2129 | end_bb_2 |
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
|
2130 | |
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
|
2131 | bb_3 |
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
|
2132 | cond = some_computation; |
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
|
2133 | A[i] = expr; |
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
|
2134 | goto bb_4 |
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
|
2135 | end_bb_3 |
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
|
2136 | |
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
|
2137 | bb_4 |
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
|
2138 | goto bb_1 |
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
|
2139 | end_bb_4 |
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
|
2140 |
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
|
2141 predicate_mem_writes is then predicating the memory write as follows: |
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
|
2142 |
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
|
2143 | bb_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
|
2144 | i = 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
|
2145 | end_bb_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
|
2146 | |
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
|
2147 | bb_1 |
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
|
2148 | if (i < N) goto bb_5 else goto bb_2 |
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
|
2149 | end_bb_1 |
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
|
2150 | |
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
|
2151 | bb_2 |
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
|
2152 | if (cond) goto bb_3 else goto bb_4 |
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
|
2153 | end_bb_2 |
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
|
2154 | |
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
|
2155 | bb_3 |
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
|
2156 | cond = some_computation; |
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
|
2157 | A[i] = cond ? expr : A[i]; |
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
|
2158 | goto bb_4 |
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
|
2159 | end_bb_3 |
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
|
2160 | |
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
|
2161 | bb_4 |
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
|
2162 | goto bb_1 |
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
|
2163 | end_bb_4 |
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
|
2164 |
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
|
2165 and finally combine_blocks removes the basic block boundaries making |
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
|
2166 the loop vectorizable: |
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
|
2167 |
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
|
2168 | bb_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
|
2169 | i = 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
|
2170 | if (i < N) goto bb_5 else goto bb_1 |
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
|
2171 | end_bb_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
|
2172 | |
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
|
2173 | bb_1 |
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
|
2174 | cond = some_computation; |
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
|
2175 | A[i] = cond ? expr : A[i]; |
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
|
2176 | if (i < N) goto bb_5 else goto bb_4 |
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
|
2177 | end_bb_1 |
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
|
2178 | |
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
|
2179 | bb_4 |
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
|
2180 | goto bb_1 |
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
|
2181 | end_bb_4 |
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
|
2182 */ |
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
|
2183 |
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
|
2184 static void |
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
|
2185 predicate_mem_writes (loop_p loop) |
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
|
2186 { |
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
|
2187 unsigned int i, orig_loop_num_nodes = loop->num_nodes; |
111 | 2188 auto_vec<int, 1> vect_sizes; |
2189 auto_vec<tree, 1> vect_masks; | |
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
|
2190 |
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
|
2191 for (i = 1; i < orig_loop_num_nodes; i++) |
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
|
2192 { |
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
|
2193 gimple_stmt_iterator gsi; |
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
|
2194 basic_block bb = ifc_bbs[i]; |
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
|
2195 tree cond = bb_predicate (bb); |
111 | 2196 bool swap; |
2197 gimple *stmt; | |
2198 int index; | |
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
|
2199 |
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
|
2200 if (is_true_predicate (cond)) |
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
|
2201 continue; |
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
|
2202 |
111 | 2203 swap = false; |
2204 if (TREE_CODE (cond) == TRUTH_NOT_EXPR) | |
2205 { | |
2206 swap = true; | |
2207 cond = TREE_OPERAND (cond, 0); | |
2208 } | |
2209 | |
2210 vect_sizes.truncate (0); | |
2211 vect_masks.truncate (0); | |
2212 | |
2213 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);) | |
2214 { | |
2215 if (!gimple_assign_single_p (stmt = gsi_stmt (gsi))) | |
2216 ; | |
2217 else if (is_false_predicate (cond) | |
2218 && gimple_vdef (stmt)) | |
2219 { | |
2220 unlink_stmt_vdef (stmt); | |
2221 gsi_remove (&gsi, true); | |
2222 release_defs (stmt); | |
2223 continue; | |
2224 } | |
2225 else if (gimple_plf (stmt, GF_PLF_2)) | |
2226 { | |
2227 tree lhs = gimple_assign_lhs (stmt); | |
2228 tree rhs = gimple_assign_rhs1 (stmt); | |
2229 tree ref, addr, ptr, mask; | |
2230 gcall *new_stmt; | |
2231 gimple_seq stmts = NULL; | |
2232 int bitsize = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (lhs))); | |
2233 ref = TREE_CODE (lhs) == SSA_NAME ? rhs : lhs; | |
2234 mark_addressable (ref); | |
2235 addr = force_gimple_operand_gsi (&gsi, build_fold_addr_expr (ref), | |
2236 true, NULL_TREE, true, | |
2237 GSI_SAME_STMT); | |
2238 if (!vect_sizes.is_empty () | |
2239 && (index = mask_exists (bitsize, vect_sizes)) != -1) | |
2240 /* Use created mask. */ | |
2241 mask = vect_masks[index]; | |
2242 else | |
2243 { | |
2244 if (COMPARISON_CLASS_P (cond)) | |
2245 mask = gimple_build (&stmts, TREE_CODE (cond), | |
2246 boolean_type_node, | |
2247 TREE_OPERAND (cond, 0), | |
2248 TREE_OPERAND (cond, 1)); | |
2249 else | |
2250 { | |
2251 gcc_assert (TREE_CODE (cond) == SSA_NAME); | |
2252 mask = cond; | |
2253 } | |
2254 | |
2255 if (swap) | |
2256 { | |
2257 tree true_val | |
2258 = constant_boolean_node (true, TREE_TYPE (mask)); | |
2259 mask = gimple_build (&stmts, BIT_XOR_EXPR, | |
2260 TREE_TYPE (mask), mask, true_val); | |
2261 } | |
2262 gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT); | |
2263 | |
2264 mask = ifc_temp_var (TREE_TYPE (mask), mask, &gsi); | |
2265 /* Save mask and its size for further use. */ | |
2266 vect_sizes.safe_push (bitsize); | |
2267 vect_masks.safe_push (mask); | |
2268 } | |
2269 ptr = build_int_cst (reference_alias_ptr_type (ref), | |
2270 get_object_alignment (ref)); | |
2271 /* Copy points-to info if possible. */ | |
2272 if (TREE_CODE (addr) == SSA_NAME && !SSA_NAME_PTR_INFO (addr)) | |
2273 copy_ref_info (build2 (MEM_REF, TREE_TYPE (ref), addr, ptr), | |
2274 ref); | |
2275 if (TREE_CODE (lhs) == SSA_NAME) | |
2276 { | |
2277 new_stmt | |
2278 = gimple_build_call_internal (IFN_MASK_LOAD, 3, addr, | |
2279 ptr, mask); | |
2280 gimple_call_set_lhs (new_stmt, lhs); | |
2281 gimple_set_vuse (new_stmt, gimple_vuse (stmt)); | |
2282 } | |
2283 else | |
2284 { | |
2285 new_stmt | |
2286 = gimple_build_call_internal (IFN_MASK_STORE, 4, addr, ptr, | |
2287 mask, rhs); | |
2288 gimple_set_vuse (new_stmt, gimple_vuse (stmt)); | |
2289 gimple_set_vdef (new_stmt, gimple_vdef (stmt)); | |
2290 SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt; | |
2291 } | |
2292 gimple_call_set_nothrow (new_stmt, true); | |
2293 | |
2294 gsi_replace (&gsi, new_stmt, true); | |
2295 } | |
2296 else if (gimple_vdef (stmt)) | |
2297 { | |
2298 tree lhs = gimple_assign_lhs (stmt); | |
2299 tree rhs = gimple_assign_rhs1 (stmt); | |
2300 tree type = TREE_TYPE (lhs); | |
2301 | |
2302 lhs = ifc_temp_var (type, unshare_expr (lhs), &gsi); | |
2303 rhs = ifc_temp_var (type, unshare_expr (rhs), &gsi); | |
2304 if (swap) | |
2305 std::swap (lhs, rhs); | |
2306 cond = force_gimple_operand_gsi_1 (&gsi, unshare_expr (cond), | |
2307 is_gimple_condexpr, NULL_TREE, | |
2308 true, GSI_SAME_STMT); | |
2309 rhs = fold_build_cond_expr (type, unshare_expr (cond), rhs, lhs); | |
2310 gimple_assign_set_rhs1 (stmt, ifc_temp_var (type, rhs, &gsi)); | |
2311 update_stmt (stmt); | |
2312 } | |
2313 gsi_next (&gsi); | |
2314 } | |
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
|
2315 } |
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
|
2316 } |
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
|
2317 |
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
|
2318 /* Remove all GIMPLE_CONDs and GIMPLE_LABELs of all the basic blocks |
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
|
2319 other than the exit and latch of the LOOP. Also resets the |
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
|
2320 GIMPLE_DEBUG information. */ |
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
|
2321 |
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
|
2322 static void |
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
|
2323 remove_conditions_and_labels (loop_p loop) |
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
|
2324 { |
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
|
2325 gimple_stmt_iterator gsi; |
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
|
2326 unsigned int i; |
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
|
2327 |
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
|
2328 for (i = 0; i < loop->num_nodes; i++) |
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
|
2329 { |
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
|
2330 basic_block bb = ifc_bbs[i]; |
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
|
2331 |
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
|
2332 if (bb_with_exit_edge_p (loop, bb) |
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
|
2333 || bb == loop->latch) |
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
|
2334 continue; |
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
|
2335 |
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
|
2336 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); ) |
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
|
2337 switch (gimple_code (gsi_stmt (gsi))) |
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
|
2338 { |
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
|
2339 case GIMPLE_COND: |
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
|
2340 case GIMPLE_LABEL: |
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
|
2341 gsi_remove (&gsi, 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
|
2342 break; |
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
|
2343 |
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
|
2344 case GIMPLE_DEBUG: |
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
|
2345 /* ??? Should there be conditional GIMPLE_DEBUG_BINDs? */ |
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
|
2346 if (gimple_debug_bind_p (gsi_stmt (gsi))) |
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
|
2347 { |
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
|
2348 gimple_debug_bind_reset_value (gsi_stmt (gsi)); |
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
|
2349 update_stmt (gsi_stmt (gsi)); |
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
|
2350 } |
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
|
2351 gsi_next (&gsi); |
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
|
2352 break; |
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
|
2353 |
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
|
2354 default: |
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
|
2355 gsi_next (&gsi); |
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
|
2356 } |
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
|
2357 } |
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
|
2358 } |
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
|
2359 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2360 /* Combine all the basic blocks from LOOP into one or two super basic |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2361 blocks. Replace PHI nodes with conditional modify expressions. */ |
0 | 2362 |
2363 static void | |
2364 combine_blocks (struct loop *loop) | |
2365 { | |
2366 basic_block bb, exit_bb, merge_target_bb; | |
2367 unsigned int orig_loop_num_nodes = loop->num_nodes; | |
2368 unsigned int i; | |
2369 edge e; | |
2370 edge_iterator ei; | |
2371 | |
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
|
2372 remove_conditions_and_labels (loop); |
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
|
2373 insert_gimplified_predicates (loop); |
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
|
2374 predicate_all_scalar_phis (loop); |
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
|
2375 |
111 | 2376 if (any_pred_load_store) |
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
|
2377 predicate_mem_writes (loop); |
0 | 2378 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2379 /* Merge basic blocks: first remove all the edges in the loop, |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2380 except for those from the exit block. */ |
0 | 2381 exit_bb = NULL; |
111 | 2382 bool *predicated = XNEWVEC (bool, orig_loop_num_nodes); |
0 | 2383 for (i = 0; i < orig_loop_num_nodes; i++) |
2384 { | |
2385 bb = ifc_bbs[i]; | |
111 | 2386 predicated[i] = !is_true_predicate (bb_predicate (bb)); |
2387 free_bb_predicate (bb); | |
0 | 2388 if (bb_with_exit_edge_p (loop, bb)) |
2389 { | |
111 | 2390 gcc_assert (exit_bb == NULL); |
0 | 2391 exit_bb = bb; |
2392 } | |
2393 } | |
2394 gcc_assert (exit_bb != loop->latch); | |
2395 | |
2396 for (i = 1; i < orig_loop_num_nodes; i++) | |
2397 { | |
2398 bb = ifc_bbs[i]; | |
2399 | |
2400 for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei));) | |
2401 { | |
2402 if (e->src == exit_bb) | |
2403 ei_next (&ei); | |
2404 else | |
2405 remove_edge (e); | |
2406 } | |
2407 } | |
2408 | |
2409 if (exit_bb != NULL) | |
2410 { | |
2411 if (exit_bb != loop->header) | |
2412 { | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2413 /* Connect this node to loop header. */ |
111 | 2414 make_single_succ_edge (loop->header, exit_bb, EDGE_FALLTHRU); |
0 | 2415 set_immediate_dominator (CDI_DOMINATORS, exit_bb, loop->header); |
2416 } | |
2417 | |
2418 /* Redirect non-exit edges to loop->latch. */ | |
2419 FOR_EACH_EDGE (e, ei, exit_bb->succs) | |
2420 { | |
2421 if (!loop_exit_edge_p (loop, e)) | |
2422 redirect_edge_and_branch (e, loop->latch); | |
2423 } | |
2424 set_immediate_dominator (CDI_DOMINATORS, loop->latch, exit_bb); | |
2425 } | |
2426 else | |
2427 { | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2428 /* If the loop does not have an exit, reconnect header and latch. */ |
0 | 2429 make_edge (loop->header, loop->latch, EDGE_FALLTHRU); |
2430 set_immediate_dominator (CDI_DOMINATORS, loop->latch, loop->header); | |
2431 } | |
2432 | |
2433 merge_target_bb = loop->header; | |
111 | 2434 |
2435 /* Get at the virtual def valid for uses starting at the first block | |
2436 we merge into the header. Without a virtual PHI the loop has the | |
2437 same virtual use on all stmts. */ | |
2438 gphi *vphi = get_virtual_phi (loop->header); | |
2439 tree last_vdef = NULL_TREE; | |
2440 if (vphi) | |
2441 { | |
2442 last_vdef = gimple_phi_result (vphi); | |
2443 for (gimple_stmt_iterator gsi = gsi_start_bb (loop->header); | |
2444 ! gsi_end_p (gsi); gsi_next (&gsi)) | |
2445 if (gimple_vdef (gsi_stmt (gsi))) | |
2446 last_vdef = gimple_vdef (gsi_stmt (gsi)); | |
2447 } | |
0 | 2448 for (i = 1; i < orig_loop_num_nodes; i++) |
2449 { | |
2450 gimple_stmt_iterator gsi; | |
2451 gimple_stmt_iterator last; | |
2452 | |
2453 bb = ifc_bbs[i]; | |
2454 | |
2455 if (bb == exit_bb || bb == loop->latch) | |
2456 continue; | |
2457 | |
111 | 2458 /* We release virtual PHIs late because we have to propagate them |
2459 out using the current VUSE. The def might be the one used | |
2460 after the loop. */ | |
2461 vphi = get_virtual_phi (bb); | |
2462 if (vphi) | |
2463 { | |
2464 imm_use_iterator iter; | |
2465 use_operand_p use_p; | |
2466 gimple *use_stmt; | |
2467 FOR_EACH_IMM_USE_STMT (use_stmt, iter, gimple_phi_result (vphi)) | |
2468 { | |
2469 FOR_EACH_IMM_USE_ON_STMT (use_p, iter) | |
2470 SET_USE (use_p, last_vdef); | |
2471 } | |
2472 gsi = gsi_for_stmt (vphi); | |
2473 remove_phi_node (&gsi, true); | |
2474 } | |
2475 | |
2476 /* Make stmts member of loop->header and clear range info from all stmts | |
2477 in BB which is now no longer executed conditional on a predicate we | |
2478 could have derived it from. */ | |
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
|
2479 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) |
111 | 2480 { |
2481 gimple *stmt = gsi_stmt (gsi); | |
2482 gimple_set_bb (stmt, merge_target_bb); | |
2483 /* Update virtual operands. */ | |
2484 if (last_vdef) | |
2485 { | |
2486 use_operand_p use_p = ssa_vuse_operand (stmt); | |
2487 if (use_p | |
2488 && USE_FROM_PTR (use_p) != last_vdef) | |
2489 SET_USE (use_p, last_vdef); | |
2490 if (gimple_vdef (stmt)) | |
2491 last_vdef = gimple_vdef (stmt); | |
2492 } | |
2493 if (predicated[i]) | |
2494 { | |
2495 ssa_op_iter i; | |
2496 tree op; | |
2497 FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_DEF) | |
2498 reset_flow_sensitive_info (op); | |
2499 } | |
2500 } | |
0 | 2501 |
2502 /* Update stmt list. */ | |
2503 last = gsi_last_bb (merge_target_bb); | |
111 | 2504 gsi_insert_seq_after_without_update (&last, bb_seq (bb), GSI_NEW_STMT); |
0 | 2505 set_bb_seq (bb, NULL); |
2506 | |
2507 delete_basic_block (bb); | |
2508 } | |
2509 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2510 /* If possible, merge loop header to the block with the exit edge. |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2511 This reduces the number of basic blocks to two, to please the |
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
|
2512 vectorizer that handles only loops with two nodes. */ |
0 | 2513 if (exit_bb |
111 | 2514 && exit_bb != loop->header) |
2515 { | |
2516 /* We release virtual PHIs late because we have to propagate them | |
2517 out using the current VUSE. The def might be the one used | |
2518 after the loop. */ | |
2519 vphi = get_virtual_phi (exit_bb); | |
2520 if (vphi) | |
2521 { | |
2522 imm_use_iterator iter; | |
2523 use_operand_p use_p; | |
2524 gimple *use_stmt; | |
2525 FOR_EACH_IMM_USE_STMT (use_stmt, iter, gimple_phi_result (vphi)) | |
2526 { | |
2527 FOR_EACH_IMM_USE_ON_STMT (use_p, iter) | |
2528 SET_USE (use_p, last_vdef); | |
2529 } | |
2530 gimple_stmt_iterator gsi = gsi_for_stmt (vphi); | |
2531 remove_phi_node (&gsi, true); | |
2532 } | |
2533 | |
2534 if (can_merge_blocks_p (loop->header, exit_bb)) | |
2535 merge_blocks (loop->header, exit_bb); | |
2536 } | |
2537 | |
2538 free (ifc_bbs); | |
2539 ifc_bbs = NULL; | |
2540 free (predicated); | |
2541 } | |
2542 | |
2543 /* Version LOOP before if-converting it; the original loop | |
2544 will be if-converted, the new copy of the loop will not, | |
2545 and the LOOP_VECTORIZED internal call will be guarding which | |
2546 loop to execute. The vectorizer pass will fold this | |
2547 internal call into either true or false. | |
2548 | |
2549 Note that this function intentionally invalidates profile. Both edges | |
2550 out of LOOP_VECTORIZED must have 100% probability so the profile remains | |
2551 consistent after the condition is folded in the vectorizer. */ | |
2552 | |
2553 static struct loop * | |
2554 version_loop_for_if_conversion (struct loop *loop) | |
2555 { | |
2556 basic_block cond_bb; | |
2557 tree cond = make_ssa_name (boolean_type_node); | |
2558 struct loop *new_loop; | |
2559 gimple *g; | |
2560 gimple_stmt_iterator gsi; | |
2561 unsigned int save_length; | |
2562 | |
2563 g = gimple_build_call_internal (IFN_LOOP_VECTORIZED, 2, | |
2564 build_int_cst (integer_type_node, loop->num), | |
2565 integer_zero_node); | |
2566 gimple_call_set_lhs (g, cond); | |
2567 | |
2568 /* Save BB->aux around loop_version as that uses the same field. */ | |
2569 save_length = loop->inner ? loop->inner->num_nodes : loop->num_nodes; | |
2570 void **saved_preds = XALLOCAVEC (void *, save_length); | |
2571 for (unsigned i = 0; i < save_length; i++) | |
2572 saved_preds[i] = ifc_bbs[i]->aux; | |
2573 | |
2574 initialize_original_copy_tables (); | |
2575 /* At this point we invalidate porfile confistency until IFN_LOOP_VECTORIZED | |
2576 is re-merged in the vectorizer. */ | |
2577 new_loop = loop_version (loop, cond, &cond_bb, | |
2578 profile_probability::always (), | |
2579 profile_probability::always (), | |
2580 profile_probability::always (), | |
2581 profile_probability::always (), true); | |
2582 free_original_copy_tables (); | |
2583 | |
2584 for (unsigned i = 0; i < save_length; i++) | |
2585 ifc_bbs[i]->aux = saved_preds[i]; | |
2586 | |
2587 if (new_loop == NULL) | |
2588 return NULL; | |
2589 | |
2590 new_loop->dont_vectorize = true; | |
2591 new_loop->force_vectorize = false; | |
2592 gsi = gsi_last_bb (cond_bb); | |
2593 gimple_call_set_arg (g, 1, build_int_cst (integer_type_node, new_loop->num)); | |
2594 gsi_insert_before (&gsi, g, GSI_SAME_STMT); | |
2595 update_ssa (TODO_update_ssa); | |
2596 return new_loop; | |
2597 } | |
2598 | |
2599 /* Return true when LOOP satisfies the follow conditions that will | |
2600 allow it to be recognized by the vectorizer for outer-loop | |
2601 vectorization: | |
2602 - The loop is not the root node of the loop tree. | |
2603 - The loop has exactly one inner loop. | |
2604 - The loop has a single exit. | |
2605 - The loop header has a single successor, which is the inner | |
2606 loop header. | |
2607 - Each of the inner and outer loop latches have a single | |
2608 predecessor. | |
2609 - The loop exit block has a single predecessor, which is the | |
2610 inner loop's exit block. */ | |
2611 | |
2612 static bool | |
2613 versionable_outer_loop_p (struct loop *loop) | |
2614 { | |
2615 if (!loop_outer (loop) | |
2616 || loop->dont_vectorize | |
2617 || !loop->inner | |
2618 || loop->inner->next | |
2619 || !single_exit (loop) | |
2620 || !single_succ_p (loop->header) | |
2621 || single_succ (loop->header) != loop->inner->header | |
2622 || !single_pred_p (loop->latch) | |
2623 || !single_pred_p (loop->inner->latch)) | |
2624 return false; | |
2625 | |
2626 basic_block outer_exit = single_pred (loop->latch); | |
2627 basic_block inner_exit = single_pred (loop->inner->latch); | |
2628 | |
2629 if (!single_pred_p (outer_exit) || single_pred (outer_exit) != inner_exit) | |
2630 return false; | |
2631 | |
2632 if (dump_file) | |
2633 fprintf (dump_file, "Found vectorizable outer loop for versioning\n"); | |
2634 | |
2635 return true; | |
2636 } | |
2637 | |
2638 /* Performs splitting of critical edges. Skip splitting and return false | |
2639 if LOOP will not be converted because: | |
2640 | |
2641 - LOOP is not well formed. | |
2642 - LOOP has PHI with more than MAX_PHI_ARG_NUM arguments. | |
2643 | |
2644 Last restriction is valid only if AGGRESSIVE_IF_CONV is false. */ | |
2645 | |
2646 static bool | |
2647 ifcvt_split_critical_edges (struct loop *loop, bool aggressive_if_conv) | |
2648 { | |
2649 basic_block *body; | |
2650 basic_block bb; | |
2651 unsigned int num = loop->num_nodes; | |
2652 unsigned int i; | |
2653 gimple *stmt; | |
2654 edge e; | |
2655 edge_iterator ei; | |
2656 auto_vec<edge> critical_edges; | |
2657 | |
2658 /* Loop is not well formed. */ | |
2659 if (num <= 2 || loop->inner || !single_exit (loop)) | |
2660 return false; | |
2661 | |
2662 body = get_loop_body (loop); | |
2663 for (i = 0; i < num; i++) | |
2664 { | |
2665 bb = body[i]; | |
2666 if (!aggressive_if_conv | |
2667 && phi_nodes (bb) | |
2668 && EDGE_COUNT (bb->preds) > MAX_PHI_ARG_NUM) | |
2669 { | |
2670 if (dump_file && (dump_flags & TDF_DETAILS)) | |
2671 fprintf (dump_file, | |
2672 "BB %d has complicated PHI with more than %u args.\n", | |
2673 bb->index, MAX_PHI_ARG_NUM); | |
2674 | |
2675 free (body); | |
2676 return false; | |
2677 } | |
2678 if (bb == loop->latch || bb_with_exit_edge_p (loop, bb)) | |
2679 continue; | |
2680 | |
2681 stmt = last_stmt (bb); | |
2682 /* Skip basic blocks not ending with conditional branch. */ | |
2683 if (!stmt || gimple_code (stmt) != GIMPLE_COND) | |
2684 continue; | |
2685 | |
2686 FOR_EACH_EDGE (e, ei, bb->succs) | |
2687 if (EDGE_CRITICAL_P (e) && e->dest->loop_father == loop) | |
2688 critical_edges.safe_push (e); | |
2689 } | |
2690 free (body); | |
2691 | |
2692 while (critical_edges.length () > 0) | |
2693 { | |
2694 e = critical_edges.pop (); | |
2695 /* Don't split if bb can be predicated along non-critical edge. */ | |
2696 if (EDGE_COUNT (e->dest->preds) > 2 || all_preds_critical_p (e->dest)) | |
2697 split_edge (e); | |
2698 } | |
2699 | |
2700 return true; | |
2701 } | |
2702 | |
2703 /* Delete redundant statements produced by predication which prevents | |
2704 loop vectorization. */ | |
2705 | |
2706 static void | |
2707 ifcvt_local_dce (basic_block bb) | |
2708 { | |
2709 gimple *stmt; | |
2710 gimple *stmt1; | |
2711 gimple *phi; | |
2712 gimple_stmt_iterator gsi; | |
2713 auto_vec<gimple *> worklist; | |
2714 enum gimple_code code; | |
2715 use_operand_p use_p; | |
2716 imm_use_iterator imm_iter; | |
2717 | |
2718 worklist.create (64); | |
2719 /* Consider all phi as live statements. */ | |
2720 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) | |
2721 { | |
2722 phi = gsi_stmt (gsi); | |
2723 gimple_set_plf (phi, GF_PLF_2, true); | |
2724 worklist.safe_push (phi); | |
2725 } | |
2726 /* Consider load/store statements, CALL and COND as live. */ | |
2727 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) | |
2728 { | |
2729 stmt = gsi_stmt (gsi); | |
2730 if (gimple_store_p (stmt) | |
2731 || gimple_assign_load_p (stmt) | |
2732 || is_gimple_debug (stmt)) | |
2733 { | |
2734 gimple_set_plf (stmt, GF_PLF_2, true); | |
2735 worklist.safe_push (stmt); | |
2736 continue; | |
2737 } | |
2738 code = gimple_code (stmt); | |
2739 if (code == GIMPLE_COND || code == GIMPLE_CALL) | |
2740 { | |
2741 gimple_set_plf (stmt, GF_PLF_2, true); | |
2742 worklist.safe_push (stmt); | |
2743 continue; | |
2744 } | |
2745 gimple_set_plf (stmt, GF_PLF_2, false); | |
2746 | |
2747 if (code == GIMPLE_ASSIGN) | |
2748 { | |
2749 tree lhs = gimple_assign_lhs (stmt); | |
2750 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs) | |
2751 { | |
2752 stmt1 = USE_STMT (use_p); | |
2753 if (gimple_bb (stmt1) != bb) | |
2754 { | |
2755 gimple_set_plf (stmt, GF_PLF_2, true); | |
2756 worklist.safe_push (stmt); | |
2757 break; | |
2758 } | |
2759 } | |
2760 } | |
2761 } | |
2762 /* Propagate liveness through arguments of live stmt. */ | |
2763 while (worklist.length () > 0) | |
2764 { | |
2765 ssa_op_iter iter; | |
2766 use_operand_p use_p; | |
2767 tree use; | |
2768 | |
2769 stmt = worklist.pop (); | |
2770 FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE) | |
2771 { | |
2772 use = USE_FROM_PTR (use_p); | |
2773 if (TREE_CODE (use) != SSA_NAME) | |
2774 continue; | |
2775 stmt1 = SSA_NAME_DEF_STMT (use); | |
2776 if (gimple_bb (stmt1) != bb | |
2777 || gimple_plf (stmt1, GF_PLF_2)) | |
2778 continue; | |
2779 gimple_set_plf (stmt1, GF_PLF_2, true); | |
2780 worklist.safe_push (stmt1); | |
2781 } | |
2782 } | |
2783 /* Delete dead statements. */ | |
2784 gsi = gsi_start_bb (bb); | |
2785 while (!gsi_end_p (gsi)) | |
2786 { | |
2787 stmt = gsi_stmt (gsi); | |
2788 if (gimple_plf (stmt, GF_PLF_2)) | |
2789 { | |
2790 gsi_next (&gsi); | |
2791 continue; | |
2792 } | |
2793 if (dump_file && (dump_flags & TDF_DETAILS)) | |
2794 { | |
2795 fprintf (dump_file, "Delete dead stmt in bb#%d\n", bb->index); | |
2796 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); | |
2797 } | |
2798 gsi_remove (&gsi, true); | |
2799 release_defs (stmt); | |
2800 } | |
0 | 2801 } |
2802 | |
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
|
2803 /* If-convert LOOP when it is legal. For the moment this pass has no |
111 | 2804 profitability analysis. Returns non-zero todo flags when something |
2805 changed. */ | |
2806 | |
2807 unsigned int | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2808 tree_if_conversion (struct loop *loop) |
0 | 2809 { |
111 | 2810 unsigned int todo = 0; |
2811 bool aggressive_if_conv; | |
2812 struct loop *rloop; | |
2813 | |
2814 again: | |
2815 rloop = NULL; | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2816 ifc_bbs = NULL; |
111 | 2817 any_pred_load_store = false; |
2818 any_complicated_phi = false; | |
2819 | |
2820 /* Apply more aggressive if-conversion when loop or its outer loop were | |
2821 marked with simd pragma. When that's the case, we try to if-convert | |
2822 loop containing PHIs with more than MAX_PHI_ARG_NUM arguments. */ | |
2823 aggressive_if_conv = loop->force_vectorize; | |
2824 if (!aggressive_if_conv) | |
2825 { | |
2826 struct loop *outer_loop = loop_outer (loop); | |
2827 if (outer_loop && outer_loop->force_vectorize) | |
2828 aggressive_if_conv = true; | |
2829 } | |
2830 | |
2831 if (!ifcvt_split_critical_edges (loop, aggressive_if_conv)) | |
2832 goto cleanup; | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2833 |
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
|
2834 if (!if_convertible_loop_p (loop) |
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
|
2835 || !dbg_cnt (if_conversion_tree)) |
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
|
2836 goto cleanup; |
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
|
2837 |
111 | 2838 if ((any_pred_load_store || any_complicated_phi) |
2839 && ((!flag_tree_loop_vectorize && !loop->force_vectorize) | |
2840 || loop->dont_vectorize)) | |
2841 goto cleanup; | |
2842 | |
2843 /* Since we have no cost model, always version loops unless the user | |
2844 specified -ftree-loop-if-convert or unless versioning is required. | |
2845 Either version this loop, or if the pattern is right for outer-loop | |
2846 vectorization, version the outer loop. In the latter case we will | |
2847 still if-convert the original inner loop. */ | |
2848 if (any_pred_load_store | |
2849 || any_complicated_phi | |
2850 || flag_tree_loop_if_convert != 1) | |
2851 { | |
2852 struct loop *vloop | |
2853 = (versionable_outer_loop_p (loop_outer (loop)) | |
2854 ? loop_outer (loop) : loop); | |
2855 struct loop *nloop = version_loop_for_if_conversion (vloop); | |
2856 if (nloop == NULL) | |
2857 goto cleanup; | |
2858 if (vloop != loop) | |
2859 { | |
2860 /* If versionable_outer_loop_p decided to version the | |
2861 outer loop, version also the inner loop of the non-vectorized | |
2862 loop copy. So we transform: | |
2863 loop1 | |
2864 loop2 | |
2865 into: | |
2866 if (LOOP_VECTORIZED (1, 3)) | |
2867 { | |
2868 loop1 | |
2869 loop2 | |
2870 } | |
2871 else | |
2872 loop3 (copy of loop1) | |
2873 if (LOOP_VECTORIZED (4, 5)) | |
2874 loop4 (copy of loop2) | |
2875 else | |
2876 loop5 (copy of loop4) */ | |
2877 gcc_assert (nloop->inner && nloop->inner->next == NULL); | |
2878 rloop = nloop->inner; | |
2879 } | |
2880 } | |
2881 | |
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
|
2882 /* Now all statements are if-convertible. Combine all the basic |
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
|
2883 blocks into one huge basic block doing the if-conversion |
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
|
2884 on-the-fly. */ |
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
|
2885 combine_blocks (loop); |
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
|
2886 |
111 | 2887 /* Delete dead predicate computations. */ |
2888 ifcvt_local_dce (loop->header); | |
2889 | |
2890 todo |= TODO_cleanup_cfg; | |
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
|
2891 |
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
|
2892 cleanup: |
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
|
2893 if (ifc_bbs) |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2894 { |
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
|
2895 unsigned int i; |
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
|
2896 |
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
|
2897 for (i = 0; i < loop->num_nodes; i++) |
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
|
2898 free_bb_predicate (ifc_bbs[i]); |
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
|
2899 |
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
|
2900 free (ifc_bbs); |
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
|
2901 ifc_bbs = NULL; |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2902 } |
111 | 2903 if (rloop != NULL) |
2904 { | |
2905 loop = rloop; | |
2906 goto again; | |
2907 } | |
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
|
2908 |
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
|
2909 return todo; |
0 | 2910 } |
2911 | |
111 | 2912 /* Tree if-conversion pass management. */ |
2913 | |
2914 namespace { | |
2915 | |
2916 const pass_data pass_data_if_conversion = | |
0 | 2917 { |
111 | 2918 GIMPLE_PASS, /* type */ |
2919 "ifcvt", /* name */ | |
2920 OPTGROUP_NONE, /* optinfo_flags */ | |
2921 TV_TREE_LOOP_IFCVT, /* tv_id */ | |
2922 ( PROP_cfg | PROP_ssa ), /* properties_required */ | |
2923 0, /* properties_provided */ | |
2924 0, /* properties_destroyed */ | |
2925 0, /* todo_flags_start */ | |
2926 0, /* todo_flags_finish */ | |
2927 }; | |
2928 | |
2929 class pass_if_conversion : public gimple_opt_pass | |
2930 { | |
2931 public: | |
2932 pass_if_conversion (gcc::context *ctxt) | |
2933 : gimple_opt_pass (pass_data_if_conversion, ctxt) | |
2934 {} | |
2935 | |
2936 /* opt_pass methods: */ | |
2937 virtual bool gate (function *); | |
2938 virtual unsigned int execute (function *); | |
2939 | |
2940 }; // class pass_if_conversion | |
2941 | |
2942 bool | |
2943 pass_if_conversion::gate (function *fun) | |
0 | 2944 { |
111 | 2945 return (((flag_tree_loop_vectorize || fun->has_force_vectorize_loops) |
2946 && flag_tree_loop_if_convert != 0) | |
2947 || flag_tree_loop_if_convert == 1); | |
2948 } | |
2949 | |
2950 unsigned int | |
2951 pass_if_conversion::execute (function *fun) | |
2952 { | |
2953 struct loop *loop; | |
2954 unsigned todo = 0; | |
2955 | |
2956 if (number_of_loops (fun) <= 1) | |
2957 return 0; | |
2958 | |
2959 FOR_EACH_LOOP (loop, 0) | |
2960 if (flag_tree_loop_if_convert == 1 | |
2961 || ((flag_tree_loop_vectorize || loop->force_vectorize) | |
2962 && !loop->dont_vectorize)) | |
2963 todo |= tree_if_conversion (loop); | |
2964 | |
2965 if (flag_checking) | |
2966 { | |
2967 basic_block bb; | |
2968 FOR_EACH_BB_FN (bb, fun) | |
2969 gcc_assert (!bb->aux); | |
2970 } | |
2971 | |
2972 return todo; | |
2973 } | |
2974 | |
2975 } // anon namespace | |
2976 | |
2977 gimple_opt_pass * | |
2978 make_pass_if_conversion (gcc::context *ctxt) | |
2979 { | |
2980 return new pass_if_conversion (ctxt); | |
2981 } |