annotate gcc/tree-if-conv.c @ 158:494b0b89df80 default tip

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