annotate gcc/tree-predcom.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 /* Predictive commoning.
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2 Copyright (C) 2005-2020 Free Software Foundation, Inc.
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
3
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
4 This file is part of GCC.
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
5
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 GCC is free software; you can redistribute it and/or modify it
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 under the terms of the GNU General Public License as published by the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 Free Software Foundation; either version 3, or (at your option) any
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 later version.
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
10
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
11 GCC is distributed in the hope that it will be useful, but WITHOUT
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 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
14 for more details.
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
15
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
16 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
17 along with GCC; see the file COPYING3. If not see
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 <http://www.gnu.org/licenses/>. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
19
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
20 /* This file implements the predictive commoning optimization. Predictive
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 commoning can be viewed as CSE around a loop, and with some improvements,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 as generalized strength reduction-- i.e., reusing values computed in
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 earlier iterations of a loop in the later ones. So far, the pass only
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
24 handles the most useful case, that is, reusing values of memory references.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 If you think this is all just a special case of PRE, you are sort of right;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 however, concentrating on loops is simpler, and makes it possible to
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
27 incorporate data dependence analysis to detect the opportunities, perform
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
28 loop unrolling to avoid copies together with renaming immediately,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
29 and if needed, we could also take register pressure into account.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
30
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
31 Let us demonstrate what is done on an example:
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
32
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
33 for (i = 0; i < 100; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
34 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
35 a[i+2] = a[i] + a[i+1];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 b[10] = b[10] + i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
37 c[i] = c[99 - i];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 d[i] = d[i + 1];
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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
41 1) We find data references in the loop, and split them to mutually
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
42 independent groups (i.e., we find components of a data dependence
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
43 graph). We ignore read-read dependences whose distance is not constant.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
44 (TODO -- we could also ignore antidependences). In this example, we
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
45 find the following groups:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
46
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
47 a[i]{read}, a[i+1]{read}, a[i+2]{write}
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
48 b[10]{read}, b[10]{write}
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
49 c[99 - i]{read}, c[i]{write}
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 d[i + 1]{read}, d[i]{write}
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
51
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
52 2) Inside each of the group, we verify several conditions:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
53 a) all the references must differ in indices only, and the indices
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
54 must all have the same step
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
55 b) the references must dominate loop latch (and thus, they must be
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
56 ordered by dominance relation).
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
57 c) the distance of the indices must be a small multiple of the step
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
58 We are then able to compute the difference of the references (# of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
59 iterations before they point to the same place as the first of them).
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
60 Also, in case there are writes in the loop, we split the groups into
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
61 chains whose head is the write whose values are used by the reads in
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
62 the same chain. The chains are then processed independently,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
63 making the further transformations simpler. Also, the shorter chains
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
64 need the same number of registers, but may require lower unrolling
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
65 factor in order to get rid of the copies on the loop latch.
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
66
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
67 In our example, we get the following chains (the chain for c is invalid).
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
68
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
69 a[i]{read,+0}, a[i+1]{read,-1}, a[i+2]{write,-2}
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
70 b[10]{read,+0}, b[10]{write,+0}
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
71 d[i + 1]{read,+0}, d[i]{write,+1}
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
72
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
73 3) For each read, we determine the read or write whose value it reuses,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
74 together with the distance of this reuse. I.e. we take the last
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
75 reference before it with distance 0, or the last of the references
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
76 with the smallest positive distance to the read. Then, we remove
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
77 the references that are not used in any of these chains, discard the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
78 empty groups, and propagate all the links so that they point to the
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
79 single root reference of the chain (adjusting their distance
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
80 appropriately). Some extra care needs to be taken for references with
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
81 step 0. In our example (the numbers indicate the distance of the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
82 reuse),
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
83
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
84 a[i] --> (*) 2, a[i+1] --> (*) 1, a[i+2] (*)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
85 b[10] --> (*) 1, b[10] (*)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
86
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
87 4) The chains are combined together if possible. If the corresponding
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
88 elements of two chains are always combined together with the same
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
89 operator, we remember just the result of this combination, instead
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
90 of remembering the values separately. We may need to perform
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
91 reassociation to enable combining, for example
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
92
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
93 e[i] + f[i+1] + e[i+1] + f[i]
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
94
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
95 can be reassociated as
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
96
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
97 (e[i] + f[i]) + (e[i+1] + f[i+1])
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
98
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
99 and we can combine the chains for e and f into one chain.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
100
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
101 5) For each root reference (end of the chain) R, let N be maximum distance
111
kono
parents: 67
diff changeset
102 of a reference reusing its value. Variables R0 up to RN are created,
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
103 together with phi nodes that transfer values from R1 .. RN to
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
104 R0 .. R(N-1).
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
105 Initial values are loaded to R0..R(N-1) (in case not all references
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
106 must necessarily be accessed and they may trap, we may fail here;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
107 TODO sometimes, the loads could be guarded by a check for the number
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
108 of iterations). Values loaded/stored in roots are also copied to
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
109 RN. Other reads are replaced with the appropriate variable Ri.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
110 Everything is put to SSA form.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
111
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
112 As a small improvement, if R0 is dead after the root (i.e., all uses of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
113 the value with the maximum distance dominate the root), we can avoid
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
114 creating RN and use R0 instead of it.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
115
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
116 In our example, we get (only the parts concerning a and b are shown):
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
117 for (i = 0; i < 100; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
118 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
119 f = phi (a[0], s);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
120 s = phi (a[1], f);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
121 x = phi (b[10], x);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
122
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
123 f = f + s;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
124 a[i+2] = f;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
125 x = x + i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
126 b[10] = x;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
127 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
128
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
129 6) Factor F for unrolling is determined as the smallest common multiple of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
130 (N + 1) for each root reference (N for references for that we avoided
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
131 creating RN). If F and the loop is small enough, loop is unrolled F
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
132 times. The stores to RN (R0) in the copies of the loop body are
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
133 periodically replaced with R0, R1, ... (R1, R2, ...), so that they can
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
134 be coalesced and the copies can be eliminated.
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
135
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
136 TODO -- copy propagation and other optimizations may change the live
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
137 ranges of the temporary registers and prevent them from being coalesced;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
138 this may increase the register pressure.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
139
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
140 In our case, F = 2 and the (main loop of the) result is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
141
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
142 for (i = 0; i < ...; i += 2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
143 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
144 f = phi (a[0], f);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
145 s = phi (a[1], s);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
146 x = phi (b[10], x);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
147
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
148 f = f + s;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
149 a[i+2] = f;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
150 x = x + i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
151 b[10] = x;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
152
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
153 s = s + f;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
154 a[i+3] = s;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
155 x = x + i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
156 b[10] = x;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
157 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
158
111
kono
parents: 67
diff changeset
159 Apart from predictive commoning on Load-Load and Store-Load chains, we
kono
parents: 67
diff changeset
160 also support Store-Store chains -- stores killed by other store can be
kono
parents: 67
diff changeset
161 eliminated. Given below example:
kono
parents: 67
diff changeset
162
kono
parents: 67
diff changeset
163 for (i = 0; i < n; i++)
kono
parents: 67
diff changeset
164 {
kono
parents: 67
diff changeset
165 a[i] = 1;
kono
parents: 67
diff changeset
166 a[i+2] = 2;
kono
parents: 67
diff changeset
167 }
kono
parents: 67
diff changeset
168
kono
parents: 67
diff changeset
169 It can be replaced with:
kono
parents: 67
diff changeset
170
kono
parents: 67
diff changeset
171 t0 = a[0];
kono
parents: 67
diff changeset
172 t1 = a[1];
kono
parents: 67
diff changeset
173 for (i = 0; i < n; i++)
kono
parents: 67
diff changeset
174 {
kono
parents: 67
diff changeset
175 a[i] = 1;
kono
parents: 67
diff changeset
176 t2 = 2;
kono
parents: 67
diff changeset
177 t0 = t1;
kono
parents: 67
diff changeset
178 t1 = t2;
kono
parents: 67
diff changeset
179 }
kono
parents: 67
diff changeset
180 a[n] = t0;
kono
parents: 67
diff changeset
181 a[n+1] = t1;
kono
parents: 67
diff changeset
182
kono
parents: 67
diff changeset
183 If the loop runs more than 1 iterations, it can be further simplified into:
kono
parents: 67
diff changeset
184
kono
parents: 67
diff changeset
185 for (i = 0; i < n; i++)
kono
parents: 67
diff changeset
186 {
kono
parents: 67
diff changeset
187 a[i] = 1;
kono
parents: 67
diff changeset
188 }
kono
parents: 67
diff changeset
189 a[n] = 2;
kono
parents: 67
diff changeset
190 a[n+1] = 2;
kono
parents: 67
diff changeset
191
kono
parents: 67
diff changeset
192 The interesting part is this can be viewed either as general store motion
kono
parents: 67
diff changeset
193 or general dead store elimination in either intra/inter-iterations way.
kono
parents: 67
diff changeset
194
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
195 With trivial effort, we also support load inside Store-Store chains if the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
196 load is dominated by a store statement in the same iteration of loop. You
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
197 can see this as a restricted Store-Mixed-Load-Store chain.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
198
111
kono
parents: 67
diff changeset
199 TODO: For now, we don't support store-store chains in multi-exit loops. We
kono
parents: 67
diff changeset
200 force to not unroll in case of store-store chain even if other chains might
kono
parents: 67
diff changeset
201 ask for unroll.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
202
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
203 Predictive commoning can be generalized for arbitrary computations (not
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
204 just memory loads), and also nontrivial transfer functions (e.g., replacing
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
205 i * i with ii_last + 2 * i + 1), to generalize strength reduction. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
206
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
207 #include "config.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
208 #include "system.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
209 #include "coretypes.h"
111
kono
parents: 67
diff changeset
210 #include "backend.h"
kono
parents: 67
diff changeset
211 #include "rtl.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
212 #include "tree.h"
111
kono
parents: 67
diff changeset
213 #include "gimple.h"
kono
parents: 67
diff changeset
214 #include "predict.h"
kono
parents: 67
diff changeset
215 #include "tree-pass.h"
kono
parents: 67
diff changeset
216 #include "ssa.h"
kono
parents: 67
diff changeset
217 #include "gimple-pretty-print.h"
kono
parents: 67
diff changeset
218 #include "alias.h"
kono
parents: 67
diff changeset
219 #include "fold-const.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
220 #include "cfgloop.h"
111
kono
parents: 67
diff changeset
221 #include "tree-eh.h"
kono
parents: 67
diff changeset
222 #include "gimplify.h"
kono
parents: 67
diff changeset
223 #include "gimple-iterator.h"
kono
parents: 67
diff changeset
224 #include "gimplify-me.h"
kono
parents: 67
diff changeset
225 #include "tree-ssa-loop-ivopts.h"
kono
parents: 67
diff changeset
226 #include "tree-ssa-loop-manip.h"
kono
parents: 67
diff changeset
227 #include "tree-ssa-loop-niter.h"
kono
parents: 67
diff changeset
228 #include "tree-ssa-loop.h"
kono
parents: 67
diff changeset
229 #include "tree-into-ssa.h"
kono
parents: 67
diff changeset
230 #include "tree-dfa.h"
kono
parents: 67
diff changeset
231 #include "tree-ssa.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
232 #include "tree-data-ref.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
233 #include "tree-scalar-evolution.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
234 #include "tree-affine.h"
111
kono
parents: 67
diff changeset
235 #include "builtins.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
236
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
237 /* The maximum number of iterations between the considered memory
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
238 references. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
239
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
240 #define MAX_DISTANCE (target_avail_regs < 16 ? 4 : 8)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
241
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
242 /* Data references (or phi nodes that carry data reference values across
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
243 loop iterations). */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
244
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
245 typedef class dref_d
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
246 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
247 public:
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
248 /* The reference itself. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
249 struct data_reference *ref;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
250
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
251 /* The statement in that the reference appears. */
111
kono
parents: 67
diff changeset
252 gimple *stmt;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
253
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
254 /* In case that STMT is a phi node, this field is set to the SSA name
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
255 defined by it in replace_phis_by_defined_names (in order to avoid
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
256 pointing to phi node that got reallocated in the meantime). */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
257 tree name_defined_by_phi;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
258
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
259 /* Distance of the reference from the root of the chain (in number of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
260 iterations of the loop). */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
261 unsigned distance;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
262
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
263 /* Number of iterations offset from the first reference in the component. */
111
kono
parents: 67
diff changeset
264 widest_int offset;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
265
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
266 /* Number of the reference in a component, in dominance ordering. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
267 unsigned pos;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
268
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
269 /* True if the memory reference is always accessed when the loop is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
270 entered. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
271 unsigned always_accessed : 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
272 } *dref;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
273
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
274
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
275 /* Type of the chain of the references. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
276
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
277 enum chain_type
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
278 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
279 /* The addresses of the references in the chain are constant. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
280 CT_INVARIANT,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
281
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
282 /* There are only loads in the chain. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
283 CT_LOAD,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
284
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
285 /* Root of the chain is store, the rest are loads. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
286 CT_STORE_LOAD,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
287
111
kono
parents: 67
diff changeset
288 /* There are only stores in the chain. */
kono
parents: 67
diff changeset
289 CT_STORE_STORE,
kono
parents: 67
diff changeset
290
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
291 /* A combination of two chains. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
292 CT_COMBINATION
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
293 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
294
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
295 /* Chains of data references. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
296
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
297 typedef struct chain
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
298 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
299 /* Type of the chain. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
300 enum chain_type type;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
301
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
302 /* For combination chains, the operator and the two chains that are
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
303 combined, and the type of the result. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
304 enum tree_code op;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
305 tree rslt_type;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
306 struct chain *ch1, *ch2;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
307
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
308 /* The references in the chain. */
111
kono
parents: 67
diff changeset
309 vec<dref> refs;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
310
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
311 /* The maximum distance of the reference in the chain from the root. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
312 unsigned length;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
313
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
314 /* The variables used to copy the value throughout iterations. */
111
kono
parents: 67
diff changeset
315 vec<tree> vars;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
316
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
317 /* Initializers for the variables. */
111
kono
parents: 67
diff changeset
318 vec<tree> inits;
kono
parents: 67
diff changeset
319
kono
parents: 67
diff changeset
320 /* Finalizers for the eliminated stores. */
kono
parents: 67
diff changeset
321 vec<tree> finis;
kono
parents: 67
diff changeset
322
kono
parents: 67
diff changeset
323 /* gimple stmts intializing the initial variables of the chain. */
kono
parents: 67
diff changeset
324 gimple_seq init_seq;
kono
parents: 67
diff changeset
325
kono
parents: 67
diff changeset
326 /* gimple stmts finalizing the eliminated stores of the chain. */
kono
parents: 67
diff changeset
327 gimple_seq fini_seq;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
328
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
329 /* True if there is a use of a variable with the maximal distance
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
330 that comes after the root in the loop. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
331 unsigned has_max_use_after : 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
332
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
333 /* True if all the memory references in the chain are always accessed. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
334 unsigned all_always_accessed : 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
335
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
336 /* True if this chain was combined together with some other chain. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
337 unsigned combined : 1;
111
kono
parents: 67
diff changeset
338
kono
parents: 67
diff changeset
339 /* True if this is store elimination chain and eliminated stores store
kono
parents: 67
diff changeset
340 loop invariant value into memory. */
kono
parents: 67
diff changeset
341 unsigned inv_store_elimination : 1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
342 } *chain_p;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
343
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
344
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
345 /* Describes the knowledge about the step of the memory references in
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
346 the component. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
347
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
348 enum ref_step_type
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
349 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
350 /* The step is zero. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
351 RS_INVARIANT,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
352
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
353 /* The step is nonzero. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
354 RS_NONZERO,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
355
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
356 /* The step may or may not be nonzero. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
357 RS_ANY
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
358 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
359
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
360 /* Components of the data dependence graph. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
361
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
362 struct component
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
363 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
364 /* The references in the component. */
111
kono
parents: 67
diff changeset
365 vec<dref> refs;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
366
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
367 /* What we know about the step of the references in the component. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
368 enum ref_step_type comp_step;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
369
111
kono
parents: 67
diff changeset
370 /* True if all references in component are stores and we try to do
kono
parents: 67
diff changeset
371 intra/inter loop iteration dead store elimination. */
kono
parents: 67
diff changeset
372 bool eliminate_store_p;
kono
parents: 67
diff changeset
373
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
374 /* Next component in the list. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
375 struct component *next;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
376 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
377
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
378 /* Bitmap of ssa names defined by looparound phi nodes covered by chains. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
379
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
380 static bitmap looparound_phis;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
381
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
382 /* Cache used by tree_to_aff_combination_expand. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
383
111
kono
parents: 67
diff changeset
384 static hash_map<tree, name_expansion *> *name_expansions;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
385
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
386 /* Dumps data reference REF to FILE. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
387
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
388 extern void dump_dref (FILE *, dref);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
389 void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
390 dump_dref (FILE *file, dref ref)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
391 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
392 if (ref->ref)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
393 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
394 fprintf (file, " ");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
395 print_generic_expr (file, DR_REF (ref->ref), TDF_SLIM);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
396 fprintf (file, " (id %u%s)\n", ref->pos,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
397 DR_IS_READ (ref->ref) ? "" : ", write");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
398
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
399 fprintf (file, " offset ");
111
kono
parents: 67
diff changeset
400 print_decs (ref->offset, file);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
401 fprintf (file, "\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
402
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
403 fprintf (file, " distance %u\n", ref->distance);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
404 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
405 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
406 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
407 if (gimple_code (ref->stmt) == GIMPLE_PHI)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
408 fprintf (file, " looparound ref\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
409 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
410 fprintf (file, " combination ref\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
411 fprintf (file, " in statement ");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
412 print_gimple_stmt (file, ref->stmt, 0, TDF_SLIM);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
413 fprintf (file, "\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
414 fprintf (file, " distance %u\n", ref->distance);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
415 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
416
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
417 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
418
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
419 /* Dumps CHAIN to FILE. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
420
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
421 extern void dump_chain (FILE *, chain_p);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
422 void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
423 dump_chain (FILE *file, chain_p chain)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
424 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
425 dref a;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
426 const char *chain_type;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
427 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
428 tree var;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
429
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
430 switch (chain->type)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
431 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
432 case CT_INVARIANT:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
433 chain_type = "Load motion";
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
434 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
435
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
436 case CT_LOAD:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
437 chain_type = "Loads-only";
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
438 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
439
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
440 case CT_STORE_LOAD:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
441 chain_type = "Store-loads";
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
442 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
443
111
kono
parents: 67
diff changeset
444 case CT_STORE_STORE:
kono
parents: 67
diff changeset
445 chain_type = "Store-stores";
kono
parents: 67
diff changeset
446 break;
kono
parents: 67
diff changeset
447
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
448 case CT_COMBINATION:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
449 chain_type = "Combination";
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
450 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
451
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
452 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
453 gcc_unreachable ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
454 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
455
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
456 fprintf (file, "%s chain %p%s\n", chain_type, (void *) chain,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
457 chain->combined ? " (combined)" : "");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
458 if (chain->type != CT_INVARIANT)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
459 fprintf (file, " max distance %u%s\n", chain->length,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
460 chain->has_max_use_after ? "" : ", may reuse first");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
461
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
462 if (chain->type == CT_COMBINATION)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
463 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
464 fprintf (file, " equal to %p %s %p in type ",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
465 (void *) chain->ch1, op_symbol_code (chain->op),
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
466 (void *) chain->ch2);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
467 print_generic_expr (file, chain->rslt_type, TDF_SLIM);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
468 fprintf (file, "\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
469 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
470
111
kono
parents: 67
diff changeset
471 if (chain->vars.exists ())
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
472 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
473 fprintf (file, " vars");
111
kono
parents: 67
diff changeset
474 FOR_EACH_VEC_ELT (chain->vars, i, var)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
475 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
476 fprintf (file, " ");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
477 print_generic_expr (file, var, TDF_SLIM);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
478 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
479 fprintf (file, "\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
480 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
481
111
kono
parents: 67
diff changeset
482 if (chain->inits.exists ())
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
483 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
484 fprintf (file, " inits");
111
kono
parents: 67
diff changeset
485 FOR_EACH_VEC_ELT (chain->inits, i, var)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
486 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
487 fprintf (file, " ");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
488 print_generic_expr (file, var, TDF_SLIM);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
489 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
490 fprintf (file, "\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
491 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
492
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
493 fprintf (file, " references:\n");
111
kono
parents: 67
diff changeset
494 FOR_EACH_VEC_ELT (chain->refs, i, a)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
495 dump_dref (file, a);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
496
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
497 fprintf (file, "\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
498 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
499
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
500 /* Dumps CHAINS to FILE. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
501
111
kono
parents: 67
diff changeset
502 extern void dump_chains (FILE *, vec<chain_p> );
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
503 void
111
kono
parents: 67
diff changeset
504 dump_chains (FILE *file, vec<chain_p> chains)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
505 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
506 chain_p chain;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
507 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
508
111
kono
parents: 67
diff changeset
509 FOR_EACH_VEC_ELT (chains, i, chain)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
510 dump_chain (file, chain);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
511 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
512
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
513 /* Dumps COMP to FILE. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
514
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
515 extern void dump_component (FILE *, struct component *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
516 void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
517 dump_component (FILE *file, struct component *comp)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
518 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
519 dref a;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
520 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
521
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
522 fprintf (file, "Component%s:\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
523 comp->comp_step == RS_INVARIANT ? " (invariant)" : "");
111
kono
parents: 67
diff changeset
524 FOR_EACH_VEC_ELT (comp->refs, i, a)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
525 dump_dref (file, a);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
526 fprintf (file, "\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
527 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
528
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
529 /* Dumps COMPS to FILE. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
530
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
531 extern void dump_components (FILE *, struct component *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
532 void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
533 dump_components (FILE *file, struct component *comps)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
534 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
535 struct component *comp;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
536
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
537 for (comp = comps; comp; comp = comp->next)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
538 dump_component (file, comp);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
539 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
540
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
541 /* Frees a chain CHAIN. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
542
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
543 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
544 release_chain (chain_p chain)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
545 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
546 dref ref;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
547 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
548
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
549 if (chain == NULL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
550 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
551
111
kono
parents: 67
diff changeset
552 FOR_EACH_VEC_ELT (chain->refs, i, ref)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
553 free (ref);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
554
111
kono
parents: 67
diff changeset
555 chain->refs.release ();
kono
parents: 67
diff changeset
556 chain->vars.release ();
kono
parents: 67
diff changeset
557 chain->inits.release ();
kono
parents: 67
diff changeset
558 if (chain->init_seq)
kono
parents: 67
diff changeset
559 gimple_seq_discard (chain->init_seq);
kono
parents: 67
diff changeset
560
kono
parents: 67
diff changeset
561 chain->finis.release ();
kono
parents: 67
diff changeset
562 if (chain->fini_seq)
kono
parents: 67
diff changeset
563 gimple_seq_discard (chain->fini_seq);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
564
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
565 free (chain);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
566 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
567
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
568 /* Frees CHAINS. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
569
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
570 static void
111
kono
parents: 67
diff changeset
571 release_chains (vec<chain_p> chains)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
572 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
573 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
574 chain_p chain;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
575
111
kono
parents: 67
diff changeset
576 FOR_EACH_VEC_ELT (chains, i, chain)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
577 release_chain (chain);
111
kono
parents: 67
diff changeset
578 chains.release ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
579 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
580
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
581 /* Frees a component COMP. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
582
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
583 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
584 release_component (struct component *comp)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
585 {
111
kono
parents: 67
diff changeset
586 comp->refs.release ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
587 free (comp);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
588 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
589
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
590 /* Frees list of components COMPS. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
591
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
592 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
593 release_components (struct component *comps)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
594 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
595 struct component *act, *next;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
596
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
597 for (act = comps; act; act = next)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
598 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
599 next = act->next;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
600 release_component (act);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
601 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
602 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
603
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
604 /* Finds a root of tree given by FATHERS containing A, and performs path
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
605 shortening. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
606
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
607 static unsigned
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
608 component_of (unsigned fathers[], unsigned a)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
609 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
610 unsigned root, n;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
611
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
612 for (root = a; root != fathers[root]; root = fathers[root])
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
613 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
614
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
615 for (; a != root; a = n)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
616 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
617 n = fathers[a];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
618 fathers[a] = root;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
619 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
620
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
621 return root;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
622 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
623
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
624 /* Join operation for DFU. FATHERS gives the tree, SIZES are sizes of the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
625 components, A and B are components to merge. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
626
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
627 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
628 merge_comps (unsigned fathers[], unsigned sizes[], unsigned a, unsigned b)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
629 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
630 unsigned ca = component_of (fathers, a);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
631 unsigned cb = component_of (fathers, b);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
632
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
633 if (ca == cb)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
634 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
635
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
636 if (sizes[ca] < sizes[cb])
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
637 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
638 sizes[cb] += sizes[ca];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
639 fathers[ca] = cb;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
640 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
641 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
642 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
643 sizes[ca] += sizes[cb];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
644 fathers[cb] = ca;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
645 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
646 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
647
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
648 /* Returns true if A is a reference that is suitable for predictive commoning
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
649 in the innermost loop that contains it. REF_STEP is set according to the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
650 step of the reference A. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
651
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
652 static bool
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
653 suitable_reference_p (struct data_reference *a, enum ref_step_type *ref_step)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
654 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
655 tree ref = DR_REF (a), step = DR_STEP (a);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
656
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
657 if (!step
111
kono
parents: 67
diff changeset
658 || TREE_THIS_VOLATILE (ref)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
659 || !is_gimple_reg_type (TREE_TYPE (ref))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
660 || tree_could_throw_p (ref))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
661 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
662
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
663 if (integer_zerop (step))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
664 *ref_step = RS_INVARIANT;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
665 else if (integer_nonzerop (step))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
666 *ref_step = RS_NONZERO;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
667 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
668 *ref_step = RS_ANY;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
669
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
670 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
671 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
672
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
673 /* Stores DR_OFFSET (DR) + DR_INIT (DR) to OFFSET. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
674
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
675 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
676 aff_combination_dr_offset (struct data_reference *dr, aff_tree *offset)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
677 {
111
kono
parents: 67
diff changeset
678 tree type = TREE_TYPE (DR_OFFSET (dr));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
679 aff_tree delta;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
680
111
kono
parents: 67
diff changeset
681 tree_to_aff_combination_expand (DR_OFFSET (dr), type, offset,
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
682 &name_expansions);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
683 aff_combination_const (&delta, type, wi::to_poly_widest (DR_INIT (dr)));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
684 aff_combination_add (offset, &delta);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
685 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
686
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
687 /* Determines number of iterations of the innermost enclosing loop before B
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
688 refers to exactly the same location as A and stores it to OFF. If A and
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
689 B do not have the same step, they never meet, or anything else fails,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
690 returns false, otherwise returns true. Both A and B are assumed to
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
691 satisfy suitable_reference_p. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
692
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
693 static bool
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
694 determine_offset (struct data_reference *a, struct data_reference *b,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
695 poly_widest_int *off)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
696 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
697 aff_tree diff, baseb, step;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
698 tree typea, typeb;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
699
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
700 /* Check that both the references access the location in the same type. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
701 typea = TREE_TYPE (DR_REF (a));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
702 typeb = TREE_TYPE (DR_REF (b));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
703 if (!useless_type_conversion_p (typeb, typea))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
704 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
705
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
706 /* Check whether the base address and the step of both references is the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
707 same. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
708 if (!operand_equal_p (DR_STEP (a), DR_STEP (b), 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
709 || !operand_equal_p (DR_BASE_ADDRESS (a), DR_BASE_ADDRESS (b), 0))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
710 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
711
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
712 if (integer_zerop (DR_STEP (a)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
713 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
714 /* If the references have loop invariant address, check that they access
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
715 exactly the same location. */
111
kono
parents: 67
diff changeset
716 *off = 0;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
717 return (operand_equal_p (DR_OFFSET (a), DR_OFFSET (b), 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
718 && operand_equal_p (DR_INIT (a), DR_INIT (b), 0));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
719 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
720
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
721 /* Compare the offsets of the addresses, and check whether the difference
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
722 is a multiple of step. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
723 aff_combination_dr_offset (a, &diff);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
724 aff_combination_dr_offset (b, &baseb);
111
kono
parents: 67
diff changeset
725 aff_combination_scale (&baseb, -1);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
726 aff_combination_add (&diff, &baseb);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
727
111
kono
parents: 67
diff changeset
728 tree_to_aff_combination_expand (DR_STEP (a), TREE_TYPE (DR_STEP (a)),
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
729 &step, &name_expansions);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
730 return aff_combination_constant_multiple_p (&diff, &step, off);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
731 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
732
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
733 /* Returns the last basic block in LOOP for that we are sure that
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
734 it is executed whenever the loop is entered. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
735
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
736 static basic_block
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
737 last_always_executed_block (class loop *loop)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
738 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
739 unsigned i;
111
kono
parents: 67
diff changeset
740 vec<edge> exits = get_loop_exit_edges (loop);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
741 edge ex;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
742 basic_block last = loop->latch;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
743
111
kono
parents: 67
diff changeset
744 FOR_EACH_VEC_ELT (exits, i, ex)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
745 last = nearest_common_dominator (CDI_DOMINATORS, last, ex->src);
111
kono
parents: 67
diff changeset
746 exits.release ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
747
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
748 return last;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
749 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
750
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
751 /* Splits dependence graph on DATAREFS described by DEPENDS to components. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
752
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
753 static struct component *
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
754 split_data_refs_to_components (class loop *loop,
111
kono
parents: 67
diff changeset
755 vec<data_reference_p> datarefs,
kono
parents: 67
diff changeset
756 vec<ddr_p> depends)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
757 {
111
kono
parents: 67
diff changeset
758 unsigned i, n = datarefs.length ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
759 unsigned ca, ia, ib, bad;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
760 unsigned *comp_father = XNEWVEC (unsigned, n + 1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
761 unsigned *comp_size = XNEWVEC (unsigned, n + 1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
762 struct component **comps;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
763 struct data_reference *dr, *dra, *drb;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
764 struct data_dependence_relation *ddr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
765 struct component *comp_list = NULL, *comp;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
766 dref dataref;
111
kono
parents: 67
diff changeset
767 /* Don't do store elimination if loop has multiple exit edges. */
kono
parents: 67
diff changeset
768 bool eliminate_store_p = single_exit (loop) != NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
769 basic_block last_always_executed = last_always_executed_block (loop);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
770 auto_bitmap no_store_store_comps;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
771
111
kono
parents: 67
diff changeset
772 FOR_EACH_VEC_ELT (datarefs, i, dr)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
773 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
774 if (!DR_REF (dr))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
775 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
776 /* A fake reference for call or asm_expr that may clobber memory;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
777 just fail. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
778 goto end;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
779 }
111
kono
parents: 67
diff changeset
780 /* predcom pass isn't prepared to handle calls with data references. */
kono
parents: 67
diff changeset
781 if (is_gimple_call (DR_STMT (dr)))
kono
parents: 67
diff changeset
782 goto end;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
783 dr->aux = (void *) (size_t) i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
784 comp_father[i] = i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
785 comp_size[i] = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
786 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
787
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
788 /* A component reserved for the "bad" data references. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
789 comp_father[n] = n;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
790 comp_size[n] = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
791
111
kono
parents: 67
diff changeset
792 FOR_EACH_VEC_ELT (datarefs, i, dr)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
793 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
794 enum ref_step_type dummy;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
795
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
796 if (!suitable_reference_p (dr, &dummy))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
797 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
798 ia = (unsigned) (size_t) dr->aux;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
799 merge_comps (comp_father, comp_size, n, ia);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
800 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
801 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
802
111
kono
parents: 67
diff changeset
803 FOR_EACH_VEC_ELT (depends, i, ddr)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
804 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
805 poly_widest_int dummy_off;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
806
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
807 if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
808 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
809
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
810 dra = DDR_A (ddr);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
811 drb = DDR_B (ddr);
111
kono
parents: 67
diff changeset
812
kono
parents: 67
diff changeset
813 /* Don't do store elimination if there is any unknown dependence for
kono
parents: 67
diff changeset
814 any store data reference. */
kono
parents: 67
diff changeset
815 if ((DR_IS_WRITE (dra) || DR_IS_WRITE (drb))
kono
parents: 67
diff changeset
816 && (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know
kono
parents: 67
diff changeset
817 || DDR_NUM_DIST_VECTS (ddr) == 0))
kono
parents: 67
diff changeset
818 eliminate_store_p = false;
kono
parents: 67
diff changeset
819
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
820 ia = component_of (comp_father, (unsigned) (size_t) dra->aux);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
821 ib = component_of (comp_father, (unsigned) (size_t) drb->aux);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
822 if (ia == ib)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
823 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
824
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
825 bad = component_of (comp_father, n);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
826
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
827 /* If both A and B are reads, we may ignore unsuitable dependences. */
111
kono
parents: 67
diff changeset
828 if (DR_IS_READ (dra) && DR_IS_READ (drb))
kono
parents: 67
diff changeset
829 {
kono
parents: 67
diff changeset
830 if (ia == bad || ib == bad
kono
parents: 67
diff changeset
831 || !determine_offset (dra, drb, &dummy_off))
kono
parents: 67
diff changeset
832 continue;
kono
parents: 67
diff changeset
833 }
kono
parents: 67
diff changeset
834 /* If A is read and B write or vice versa and there is unsuitable
kono
parents: 67
diff changeset
835 dependence, instead of merging both components into a component
kono
parents: 67
diff changeset
836 that will certainly not pass suitable_component_p, just put the
kono
parents: 67
diff changeset
837 read into bad component, perhaps at least the write together with
kono
parents: 67
diff changeset
838 all the other data refs in it's component will be optimizable. */
kono
parents: 67
diff changeset
839 else if (DR_IS_READ (dra) && ib != bad)
kono
parents: 67
diff changeset
840 {
kono
parents: 67
diff changeset
841 if (ia == bad)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
842 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
843 bitmap_set_bit (no_store_store_comps, ib);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
844 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
845 }
111
kono
parents: 67
diff changeset
846 else if (!determine_offset (dra, drb, &dummy_off))
kono
parents: 67
diff changeset
847 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
848 bitmap_set_bit (no_store_store_comps, ib);
111
kono
parents: 67
diff changeset
849 merge_comps (comp_father, comp_size, bad, ia);
kono
parents: 67
diff changeset
850 continue;
kono
parents: 67
diff changeset
851 }
kono
parents: 67
diff changeset
852 }
kono
parents: 67
diff changeset
853 else if (DR_IS_READ (drb) && ia != bad)
kono
parents: 67
diff changeset
854 {
kono
parents: 67
diff changeset
855 if (ib == bad)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
856 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
857 bitmap_set_bit (no_store_store_comps, ia);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
858 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
859 }
111
kono
parents: 67
diff changeset
860 else if (!determine_offset (dra, drb, &dummy_off))
kono
parents: 67
diff changeset
861 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
862 bitmap_set_bit (no_store_store_comps, ia);
111
kono
parents: 67
diff changeset
863 merge_comps (comp_father, comp_size, bad, ib);
kono
parents: 67
diff changeset
864 continue;
kono
parents: 67
diff changeset
865 }
kono
parents: 67
diff changeset
866 }
kono
parents: 67
diff changeset
867 else if (DR_IS_WRITE (dra) && DR_IS_WRITE (drb)
kono
parents: 67
diff changeset
868 && ia != bad && ib != bad
kono
parents: 67
diff changeset
869 && !determine_offset (dra, drb, &dummy_off))
kono
parents: 67
diff changeset
870 {
kono
parents: 67
diff changeset
871 merge_comps (comp_father, comp_size, bad, ia);
kono
parents: 67
diff changeset
872 merge_comps (comp_father, comp_size, bad, ib);
kono
parents: 67
diff changeset
873 continue;
kono
parents: 67
diff changeset
874 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
875
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
876 merge_comps (comp_father, comp_size, ia, ib);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
877 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
878
111
kono
parents: 67
diff changeset
879 if (eliminate_store_p)
kono
parents: 67
diff changeset
880 {
kono
parents: 67
diff changeset
881 tree niters = number_of_latch_executions (loop);
kono
parents: 67
diff changeset
882
kono
parents: 67
diff changeset
883 /* Don't do store elimination if niters info is unknown because stores
kono
parents: 67
diff changeset
884 in the last iteration can't be eliminated and we need to recover it
kono
parents: 67
diff changeset
885 after loop. */
kono
parents: 67
diff changeset
886 eliminate_store_p = (niters != NULL_TREE && niters != chrec_dont_know);
kono
parents: 67
diff changeset
887 }
kono
parents: 67
diff changeset
888
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
889 comps = XCNEWVEC (struct component *, n);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
890 bad = component_of (comp_father, n);
111
kono
parents: 67
diff changeset
891 FOR_EACH_VEC_ELT (datarefs, i, dr)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
892 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
893 ia = (unsigned) (size_t) dr->aux;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
894 ca = component_of (comp_father, ia);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
895 if (ca == bad)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
896 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
897
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
898 comp = comps[ca];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
899 if (!comp)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
900 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
901 comp = XCNEW (struct component);
111
kono
parents: 67
diff changeset
902 comp->refs.create (comp_size[ca]);
kono
parents: 67
diff changeset
903 comp->eliminate_store_p = eliminate_store_p;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
904 comps[ca] = comp;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
905 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
906
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
907 dataref = XCNEW (class dref_d);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
908 dataref->ref = dr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
909 dataref->stmt = DR_STMT (dr);
111
kono
parents: 67
diff changeset
910 dataref->offset = 0;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
911 dataref->distance = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
912
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
913 dataref->always_accessed
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
914 = dominated_by_p (CDI_DOMINATORS, last_always_executed,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
915 gimple_bb (dataref->stmt));
111
kono
parents: 67
diff changeset
916 dataref->pos = comp->refs.length ();
kono
parents: 67
diff changeset
917 comp->refs.quick_push (dataref);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
918 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
919
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
920 if (eliminate_store_p)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
921 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
922 bitmap_iterator bi;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
923 EXECUTE_IF_SET_IN_BITMAP (no_store_store_comps, 0, ia, bi)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
924 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
925 ca = component_of (comp_father, ia);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
926 if (ca != bad)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
927 comps[ca]->eliminate_store_p = false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
928 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
929 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
930
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
931 for (i = 0; i < n; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
932 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
933 comp = comps[i];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
934 if (comp)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
935 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
936 comp->next = comp_list;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
937 comp_list = comp;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
938 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
939 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
940 free (comps);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
941
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
942 end:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
943 free (comp_father);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
944 free (comp_size);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
945 return comp_list;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
946 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
947
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
948 /* Returns true if the component COMP satisfies the conditions
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
949 described in 2) at the beginning of this file. LOOP is the current
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
950 loop. */
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
951
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
952 static bool
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
953 suitable_component_p (class loop *loop, struct component *comp)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
954 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
955 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
956 dref a, first;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
957 basic_block ba, bp = loop->header;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
958 bool ok, has_write = false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
959
111
kono
parents: 67
diff changeset
960 FOR_EACH_VEC_ELT (comp->refs, i, a)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
961 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
962 ba = gimple_bb (a->stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
963
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
964 if (!just_once_each_iteration_p (loop, ba))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
965 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
966
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
967 gcc_assert (dominated_by_p (CDI_DOMINATORS, ba, bp));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
968 bp = ba;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
969
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
970 if (DR_IS_WRITE (a->ref))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
971 has_write = true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
972 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
973
111
kono
parents: 67
diff changeset
974 first = comp->refs[0];
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
975 ok = suitable_reference_p (first->ref, &comp->comp_step);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
976 gcc_assert (ok);
111
kono
parents: 67
diff changeset
977 first->offset = 0;
kono
parents: 67
diff changeset
978
kono
parents: 67
diff changeset
979 for (i = 1; comp->refs.iterate (i, &a); i++)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
980 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
981 /* Polynomial offsets are no use, since we need to know the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
982 gap between iteration numbers at compile time. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
983 poly_widest_int offset;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
984 if (!determine_offset (first->ref, a->ref, &offset)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
985 || !offset.is_constant (&a->offset))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
986 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
987
111
kono
parents: 67
diff changeset
988 enum ref_step_type a_step;
kono
parents: 67
diff changeset
989 gcc_checking_assert (suitable_reference_p (a->ref, &a_step)
kono
parents: 67
diff changeset
990 && a_step == comp->comp_step);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
991 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
992
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
993 /* If there is a write inside the component, we must know whether the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
994 step is nonzero or not -- we would not otherwise be able to recognize
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
995 whether the value accessed by reads comes from the OFFSET-th iteration
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
996 or the previous one. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
997 if (has_write && comp->comp_step == RS_ANY)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
998 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
999
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1000 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1001 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1002
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1003 /* Check the conditions on references inside each of components COMPS,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1004 and remove the unsuitable components from the list. The new list
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1005 of components is returned. The conditions are described in 2) at
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1006 the beginning of this file. LOOP is the current loop. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1007
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1008 static struct component *
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1009 filter_suitable_components (class loop *loop, struct component *comps)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1010 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1011 struct component **comp, *act;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1012
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1013 for (comp = &comps; *comp; )
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1014 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1015 act = *comp;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1016 if (suitable_component_p (loop, act))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1017 comp = &act->next;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1018 else
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 dref ref;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1021 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1022
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1023 *comp = act->next;
111
kono
parents: 67
diff changeset
1024 FOR_EACH_VEC_ELT (act->refs, i, ref)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1025 free (ref);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1026 release_component (act);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1027 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1028 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1029
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1030 return comps;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1031 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1032
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1033 /* Compares two drefs A and B by their offset and position. Callback for
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1034 qsort. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1035
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1036 static int
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1037 order_drefs (const void *a, const void *b)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1038 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1039 const dref *const da = (const dref *) a;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1040 const dref *const db = (const dref *) b;
111
kono
parents: 67
diff changeset
1041 int offcmp = wi::cmps ((*da)->offset, (*db)->offset);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1042
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1043 if (offcmp != 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1044 return offcmp;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1045
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1046 return (*da)->pos - (*db)->pos;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1047 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1048
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1049 /* Compares two drefs A and B by their position. Callback for qsort. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1050
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1051 static int
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1052 order_drefs_by_pos (const void *a, const void *b)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1053 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1054 const dref *const da = (const dref *) a;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1055 const dref *const db = (const dref *) b;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1056
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1057 return (*da)->pos - (*db)->pos;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1058 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1059
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1060 /* Returns root of the CHAIN. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1061
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1062 static inline dref
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1063 get_chain_root (chain_p chain)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1064 {
111
kono
parents: 67
diff changeset
1065 return chain->refs[0];
kono
parents: 67
diff changeset
1066 }
kono
parents: 67
diff changeset
1067
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1068 /* Given CHAIN, returns the last write ref at DISTANCE, or NULL if it doesn't
111
kono
parents: 67
diff changeset
1069 exist. */
kono
parents: 67
diff changeset
1070
kono
parents: 67
diff changeset
1071 static inline dref
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1072 get_chain_last_write_at (chain_p chain, unsigned distance)
111
kono
parents: 67
diff changeset
1073 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1074 for (unsigned i = chain->refs.length (); i > 0; i--)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1075 if (DR_IS_WRITE (chain->refs[i - 1]->ref)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1076 && distance == chain->refs[i - 1]->distance)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1077 return chain->refs[i - 1];
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1078
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1079 return NULL;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1080 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1081
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1082 /* Given CHAIN, returns the last write ref with the same distance before load
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1083 at index LOAD_IDX, or NULL if it doesn't exist. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1084
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1085 static inline dref
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1086 get_chain_last_write_before_load (chain_p chain, unsigned load_idx)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1087 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1088 gcc_assert (load_idx < chain->refs.length ());
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1089
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1090 unsigned distance = chain->refs[load_idx]->distance;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1091
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1092 for (unsigned i = load_idx; i > 0; i--)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1093 if (DR_IS_WRITE (chain->refs[i - 1]->ref)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1094 && distance == chain->refs[i - 1]->distance)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1095 return chain->refs[i - 1];
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1096
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1097 return NULL;
0
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 /* Adds REF to the chain CHAIN. */
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 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1103 add_ref_to_chain (chain_p chain, dref ref)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1104 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1105 dref root = get_chain_root (chain);
111
kono
parents: 67
diff changeset
1106
kono
parents: 67
diff changeset
1107 gcc_assert (wi::les_p (root->offset, ref->offset));
kono
parents: 67
diff changeset
1108 widest_int dist = ref->offset - root->offset;
kono
parents: 67
diff changeset
1109 gcc_assert (wi::fits_uhwi_p (dist));
kono
parents: 67
diff changeset
1110
kono
parents: 67
diff changeset
1111 chain->refs.safe_push (ref);
kono
parents: 67
diff changeset
1112
kono
parents: 67
diff changeset
1113 ref->distance = dist.to_uhwi ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1114
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1115 if (ref->distance >= chain->length)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1116 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1117 chain->length = ref->distance;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1118 chain->has_max_use_after = false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1119 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1120
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1121 /* Promote this chain to CT_STORE_STORE if it has multiple stores. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1122 if (DR_IS_WRITE (ref->ref))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1123 chain->type = CT_STORE_STORE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1124
111
kono
parents: 67
diff changeset
1125 /* Don't set the flag for store-store chain since there is no use. */
kono
parents: 67
diff changeset
1126 if (chain->type != CT_STORE_STORE
kono
parents: 67
diff changeset
1127 && ref->distance == chain->length
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1128 && ref->pos > root->pos)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1129 chain->has_max_use_after = true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1130
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1131 chain->all_always_accessed &= ref->always_accessed;
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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1134 /* Returns the chain for invariant component COMP. */
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 static chain_p
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1137 make_invariant_chain (struct component *comp)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1138 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1139 chain_p chain = XCNEW (struct chain);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1140 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1141 dref ref;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1142
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1143 chain->type = CT_INVARIANT;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1144
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1145 chain->all_always_accessed = true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1146
111
kono
parents: 67
diff changeset
1147 FOR_EACH_VEC_ELT (comp->refs, i, ref)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1148 {
111
kono
parents: 67
diff changeset
1149 chain->refs.safe_push (ref);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1150 chain->all_always_accessed &= ref->always_accessed;
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
111
kono
parents: 67
diff changeset
1153 chain->inits = vNULL;
kono
parents: 67
diff changeset
1154 chain->finis = vNULL;
kono
parents: 67
diff changeset
1155
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1156 return chain;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1157 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1158
111
kono
parents: 67
diff changeset
1159 /* Make a new chain of type TYPE rooted at REF. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1160
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1161 static chain_p
111
kono
parents: 67
diff changeset
1162 make_rooted_chain (dref ref, enum chain_type type)
0
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 chain_p chain = XCNEW (struct chain);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1165
111
kono
parents: 67
diff changeset
1166 chain->type = type;
kono
parents: 67
diff changeset
1167 chain->refs.safe_push (ref);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1168 chain->all_always_accessed = ref->always_accessed;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1169 ref->distance = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1170
111
kono
parents: 67
diff changeset
1171 chain->inits = vNULL;
kono
parents: 67
diff changeset
1172 chain->finis = vNULL;
kono
parents: 67
diff changeset
1173
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1174 return chain;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1175 }
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 /* Returns true if CHAIN is not trivial. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1178
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1179 static bool
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1180 nontrivial_chain_p (chain_p chain)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1181 {
111
kono
parents: 67
diff changeset
1182 return chain != NULL && chain->refs.length () > 1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1183 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1184
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1185 /* Returns the ssa name that contains the value of REF, or NULL_TREE if there
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1186 is no such name. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1187
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1188 static tree
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1189 name_for_ref (dref ref)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1190 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1191 tree name;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1192
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1193 if (is_gimple_assign (ref->stmt))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1194 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1195 if (!ref->ref || DR_IS_READ (ref->ref))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1196 name = gimple_assign_lhs (ref->stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1197 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1198 name = gimple_assign_rhs1 (ref->stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1199 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1200 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1201 name = PHI_RESULT (ref->stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1202
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1203 return (TREE_CODE (name) == SSA_NAME ? name : NULL_TREE);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1204 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1205
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1206 /* Returns true if REF is a valid initializer for ROOT with given DISTANCE (in
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1207 iterations of the innermost enclosing loop). */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1208
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1209 static bool
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1210 valid_initializer_p (struct data_reference *ref,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1211 unsigned distance, struct data_reference *root)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1212 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1213 aff_tree diff, base, step;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1214 poly_widest_int off;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1215
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1216 /* Both REF and ROOT must be accessing the same object. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1217 if (!operand_equal_p (DR_BASE_ADDRESS (ref), DR_BASE_ADDRESS (root), 0))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1218 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1219
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1220 /* The initializer is defined outside of loop, hence its address must be
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1221 invariant inside the loop. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1222 gcc_assert (integer_zerop (DR_STEP (ref)));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1223
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1224 /* If the address of the reference is invariant, initializer must access
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1225 exactly the same location. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1226 if (integer_zerop (DR_STEP (root)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1227 return (operand_equal_p (DR_OFFSET (ref), DR_OFFSET (root), 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1228 && operand_equal_p (DR_INIT (ref), DR_INIT (root), 0));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1229
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1230 /* Verify that this index of REF is equal to the root's index at
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1231 -DISTANCE-th iteration. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1232 aff_combination_dr_offset (root, &diff);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1233 aff_combination_dr_offset (ref, &base);
111
kono
parents: 67
diff changeset
1234 aff_combination_scale (&base, -1);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1235 aff_combination_add (&diff, &base);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1236
111
kono
parents: 67
diff changeset
1237 tree_to_aff_combination_expand (DR_STEP (root), TREE_TYPE (DR_STEP (root)),
kono
parents: 67
diff changeset
1238 &step, &name_expansions);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1239 if (!aff_combination_constant_multiple_p (&diff, &step, &off))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1240 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1241
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1242 if (maybe_ne (off, distance))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1243 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1244
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1245 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1246 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1247
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1248 /* Finds looparound phi node of LOOP that copies the value of REF, and if its
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1249 initial value is correct (equal to initial value of REF shifted by one
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1250 iteration), returns the phi node. Otherwise, NULL_TREE is returned. ROOT
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1251 is the root of the current chain. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1252
111
kono
parents: 67
diff changeset
1253 static gphi *
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1254 find_looparound_phi (class loop *loop, dref ref, dref root)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1255 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1256 tree name, init, init_ref;
111
kono
parents: 67
diff changeset
1257 gphi *phi = NULL;
kono
parents: 67
diff changeset
1258 gimple *init_stmt;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1259 edge latch = loop_latch_edge (loop);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1260 struct data_reference init_dr;
111
kono
parents: 67
diff changeset
1261 gphi_iterator psi;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1262
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1263 if (is_gimple_assign (ref->stmt))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1264 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1265 if (DR_IS_READ (ref->ref))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1266 name = gimple_assign_lhs (ref->stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1267 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1268 name = gimple_assign_rhs1 (ref->stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1269 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1270 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1271 name = PHI_RESULT (ref->stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1272 if (!name)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1273 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1274
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1275 for (psi = gsi_start_phis (loop->header); !gsi_end_p (psi); gsi_next (&psi))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1276 {
111
kono
parents: 67
diff changeset
1277 phi = psi.phi ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1278 if (PHI_ARG_DEF_FROM_EDGE (phi, latch) == name)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1279 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1280 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1281
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1282 if (gsi_end_p (psi))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1283 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1284
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1285 init = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (loop));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1286 if (TREE_CODE (init) != SSA_NAME)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1287 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1288 init_stmt = SSA_NAME_DEF_STMT (init);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1289 if (gimple_code (init_stmt) != GIMPLE_ASSIGN)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1290 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1291 gcc_assert (gimple_assign_lhs (init_stmt) == init);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1292
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1293 init_ref = gimple_assign_rhs1 (init_stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1294 if (!REFERENCE_CLASS_P (init_ref)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1295 && !DECL_P (init_ref))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1296 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1297
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1298 /* Analyze the behavior of INIT_REF with respect to LOOP (innermost
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1299 loop enclosing PHI). */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1300 memset (&init_dr, 0, sizeof (struct data_reference));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1301 DR_REF (&init_dr) = init_ref;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1302 DR_STMT (&init_dr) = phi;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1303 if (!dr_analyze_innermost (&DR_INNERMOST (&init_dr), init_ref, loop,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1304 init_stmt))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1305 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1306
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1307 if (!valid_initializer_p (&init_dr, ref->distance + 1, root->ref))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1308 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1309
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1310 return phi;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1311 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1312
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1313 /* Adds a reference for the looparound copy of REF in PHI to CHAIN. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1314
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1315 static void
111
kono
parents: 67
diff changeset
1316 insert_looparound_copy (chain_p chain, dref ref, gphi *phi)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1317 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1318 dref nw = XCNEW (class dref_d), aref;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1319 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1320
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1321 nw->stmt = phi;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1322 nw->distance = ref->distance + 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1323 nw->always_accessed = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1324
111
kono
parents: 67
diff changeset
1325 FOR_EACH_VEC_ELT (chain->refs, i, aref)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1326 if (aref->distance >= nw->distance)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1327 break;
111
kono
parents: 67
diff changeset
1328 chain->refs.safe_insert (i, nw);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1329
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1330 if (nw->distance > chain->length)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1331 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1332 chain->length = nw->distance;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1333 chain->has_max_use_after = false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1334 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1335 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1336
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1337 /* For references in CHAIN that are copied around the LOOP (created previously
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1338 by PRE, or by user), add the results of such copies to the chain. This
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1339 enables us to remove the copies by unrolling, and may need less registers
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1340 (also, it may allow us to combine chains together). */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1341
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1342 static void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1343 add_looparound_copies (class loop *loop, chain_p chain)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1344 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1345 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1346 dref ref, root = get_chain_root (chain);
111
kono
parents: 67
diff changeset
1347 gphi *phi;
kono
parents: 67
diff changeset
1348
kono
parents: 67
diff changeset
1349 if (chain->type == CT_STORE_STORE)
kono
parents: 67
diff changeset
1350 return;
kono
parents: 67
diff changeset
1351
kono
parents: 67
diff changeset
1352 FOR_EACH_VEC_ELT (chain->refs, i, ref)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1353 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1354 phi = find_looparound_phi (loop, ref, root);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1355 if (!phi)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1356 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1357
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1358 bitmap_set_bit (looparound_phis, SSA_NAME_VERSION (PHI_RESULT (phi)));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1359 insert_looparound_copy (chain, ref, phi);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1360 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1361 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1362
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1363 /* Find roots of the values and determine distances in the component COMP.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1364 The references are redistributed into CHAINS. LOOP is the current
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1365 loop. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1366
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1367 static void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1368 determine_roots_comp (class loop *loop,
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1369 struct component *comp,
111
kono
parents: 67
diff changeset
1370 vec<chain_p> *chains)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1371 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1372 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1373 dref a;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1374 chain_p chain = NULL;
111
kono
parents: 67
diff changeset
1375 widest_int last_ofs = 0;
kono
parents: 67
diff changeset
1376 enum chain_type type;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1377
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1378 /* Invariants are handled specially. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1379 if (comp->comp_step == RS_INVARIANT)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1380 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1381 chain = make_invariant_chain (comp);
111
kono
parents: 67
diff changeset
1382 chains->safe_push (chain);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1383 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1384 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1385
111
kono
parents: 67
diff changeset
1386 /* Trivial component. */
kono
parents: 67
diff changeset
1387 if (comp->refs.length () <= 1)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1388 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1389 if (comp->refs.length () == 1)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1390 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1391 free (comp->refs[0]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1392 comp->refs.truncate (0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1393 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1394 return;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1395 }
111
kono
parents: 67
diff changeset
1396
kono
parents: 67
diff changeset
1397 comp->refs.qsort (order_drefs);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1398
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1399 /* For Store-Store chain, we only support load if it is dominated by a
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1400 store statement in the same iteration of loop. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1401 if (comp->eliminate_store_p)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1402 for (a = NULL, i = 0; i < comp->refs.length (); i++)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1403 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1404 if (DR_IS_WRITE (comp->refs[i]->ref))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1405 a = comp->refs[i];
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1406 else if (a == NULL || a->offset != comp->refs[i]->offset)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1407 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1408 /* If there is load that is not dominated by a store in the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1409 same iteration of loop, clear the flag so no Store-Store
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1410 chain is generated for this component. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1411 comp->eliminate_store_p = false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1412 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1413 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1414 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1415
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1416 /* Determine roots and create chains for components. */
111
kono
parents: 67
diff changeset
1417 FOR_EACH_VEC_ELT (comp->refs, i, a)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1418 {
111
kono
parents: 67
diff changeset
1419 if (!chain
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1420 || (chain->type == CT_LOAD && DR_IS_WRITE (a->ref))
111
kono
parents: 67
diff changeset
1421 || (!comp->eliminate_store_p && DR_IS_WRITE (a->ref))
kono
parents: 67
diff changeset
1422 || wi::leu_p (MAX_DISTANCE, a->offset - last_ofs))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1423 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1424 if (nontrivial_chain_p (chain))
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1425 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1426 add_looparound_copies (loop, chain);
111
kono
parents: 67
diff changeset
1427 chains->safe_push (chain);
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1428 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1429 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1430 release_chain (chain);
111
kono
parents: 67
diff changeset
1431
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1432 /* Determine type of the chain. If the root reference is a load,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1433 this can only be a CT_LOAD chain; other chains are intialized
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1434 to CT_STORE_LOAD and might be promoted to CT_STORE_STORE when
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1435 new reference is added. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1436 type = DR_IS_READ (a->ref) ? CT_LOAD : CT_STORE_LOAD;
111
kono
parents: 67
diff changeset
1437 chain = make_rooted_chain (a, type);
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1438 last_ofs = a->offset;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1439 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1440 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1441
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1442 add_ref_to_chain (chain, a);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1443 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1444
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1445 if (nontrivial_chain_p (chain))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1446 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1447 add_looparound_copies (loop, chain);
111
kono
parents: 67
diff changeset
1448 chains->safe_push (chain);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1449 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1450 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1451 release_chain (chain);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1452 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1453
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1454 /* Find roots of the values and determine distances in components COMPS, and
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1455 separates the references to CHAINS. LOOP is the current loop. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1456
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1457 static void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1458 determine_roots (class loop *loop,
111
kono
parents: 67
diff changeset
1459 struct component *comps, vec<chain_p> *chains)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1460 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1461 struct component *comp;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1462
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1463 for (comp = comps; comp; comp = comp->next)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1464 determine_roots_comp (loop, comp, chains);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1465 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1466
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1467 /* Replace the reference in statement STMT with temporary variable
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1468 NEW_TREE. If SET is true, NEW_TREE is instead initialized to the value of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1469 the reference in the statement. IN_LHS is true if the reference
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1470 is in the lhs of STMT, false if it is in rhs. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1471
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1472 static void
111
kono
parents: 67
diff changeset
1473 replace_ref_with (gimple *stmt, tree new_tree, bool set, bool in_lhs)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1474 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1475 tree val;
111
kono
parents: 67
diff changeset
1476 gassign *new_stmt;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1477 gimple_stmt_iterator bsi, psi;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1478
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1479 if (gimple_code (stmt) == GIMPLE_PHI)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1480 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1481 gcc_assert (!in_lhs && !set);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1482
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1483 val = PHI_RESULT (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1484 bsi = gsi_after_labels (gimple_bb (stmt));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1485 psi = gsi_for_stmt (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1486 remove_phi_node (&psi, false);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1487
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1488 /* Turn the phi node into GIMPLE_ASSIGN. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1489 new_stmt = gimple_build_assign (val, new_tree);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1490 gsi_insert_before (&bsi, new_stmt, GSI_NEW_STMT);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1491 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1492 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1493
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1494 /* Since the reference is of gimple_reg type, it should only
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1495 appear as lhs or rhs of modify statement. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1496 gcc_assert (is_gimple_assign (stmt));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1497
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1498 bsi = gsi_for_stmt (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1499
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1500 /* If we do not need to initialize NEW_TREE, just replace the use of OLD. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1501 if (!set)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1502 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1503 gcc_assert (!in_lhs);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1504 gimple_assign_set_rhs_from_tree (&bsi, new_tree);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1505 stmt = gsi_stmt (bsi);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1506 update_stmt (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1507 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1508 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1509
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1510 if (in_lhs)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1511 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1512 /* We have statement
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1513
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1514 OLD = VAL
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1515
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1516 If OLD is a memory reference, then VAL is gimple_val, and we transform
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1517 this to
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1518
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1519 OLD = VAL
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1520 NEW = VAL
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1521
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1522 Otherwise, we are replacing a combination chain,
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1523 VAL is the expression that performs the combination, and OLD is an
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1524 SSA name. In this case, we transform the assignment to
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1525
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1526 OLD = VAL
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1527 NEW = OLD
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1528
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1529 */
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 val = gimple_assign_lhs (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1532 if (TREE_CODE (val) != SSA_NAME)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1533 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1534 val = gimple_assign_rhs1 (stmt);
111
kono
parents: 67
diff changeset
1535 gcc_assert (gimple_assign_single_p (stmt));
kono
parents: 67
diff changeset
1536 if (TREE_CLOBBER_P (val))
kono
parents: 67
diff changeset
1537 val = get_or_create_ssa_default_def (cfun, SSA_NAME_VAR (new_tree));
kono
parents: 67
diff changeset
1538 else
kono
parents: 67
diff changeset
1539 gcc_assert (gimple_assign_copy_p (stmt));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1540 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1541 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1542 else
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 /* VAL = OLD
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1545
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1546 is transformed to
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1547
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1548 VAL = OLD
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1549 NEW = VAL */
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 val = gimple_assign_lhs (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1552 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1553
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1554 new_stmt = gimple_build_assign (new_tree, unshare_expr (val));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1555 gsi_insert_after (&bsi, new_stmt, GSI_NEW_STMT);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1556 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1557
111
kono
parents: 67
diff changeset
1558 /* Returns a memory reference to DR in the (NITERS + ITER)-th iteration
kono
parents: 67
diff changeset
1559 of the loop it was analyzed in. Append init stmts to STMTS. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1560
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1561 static tree
111
kono
parents: 67
diff changeset
1562 ref_at_iteration (data_reference_p dr, int iter,
kono
parents: 67
diff changeset
1563 gimple_seq *stmts, tree niters = NULL_TREE)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1564 {
111
kono
parents: 67
diff changeset
1565 tree off = DR_OFFSET (dr);
kono
parents: 67
diff changeset
1566 tree coff = DR_INIT (dr);
kono
parents: 67
diff changeset
1567 tree ref = DR_REF (dr);
kono
parents: 67
diff changeset
1568 enum tree_code ref_code = ERROR_MARK;
kono
parents: 67
diff changeset
1569 tree ref_type = NULL_TREE;
kono
parents: 67
diff changeset
1570 tree ref_op1 = NULL_TREE;
kono
parents: 67
diff changeset
1571 tree ref_op2 = NULL_TREE;
kono
parents: 67
diff changeset
1572 tree new_offset;
kono
parents: 67
diff changeset
1573
kono
parents: 67
diff changeset
1574 if (iter != 0)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1575 {
111
kono
parents: 67
diff changeset
1576 new_offset = size_binop (MULT_EXPR, DR_STEP (dr), ssize_int (iter));
kono
parents: 67
diff changeset
1577 if (TREE_CODE (new_offset) == INTEGER_CST)
kono
parents: 67
diff changeset
1578 coff = size_binop (PLUS_EXPR, coff, new_offset);
kono
parents: 67
diff changeset
1579 else
kono
parents: 67
diff changeset
1580 off = size_binop (PLUS_EXPR, off, new_offset);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1581 }
111
kono
parents: 67
diff changeset
1582
kono
parents: 67
diff changeset
1583 if (niters != NULL_TREE)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1584 {
111
kono
parents: 67
diff changeset
1585 niters = fold_convert (ssizetype, niters);
kono
parents: 67
diff changeset
1586 new_offset = size_binop (MULT_EXPR, DR_STEP (dr), niters);
kono
parents: 67
diff changeset
1587 if (TREE_CODE (niters) == INTEGER_CST)
kono
parents: 67
diff changeset
1588 coff = size_binop (PLUS_EXPR, coff, new_offset);
kono
parents: 67
diff changeset
1589 else
kono
parents: 67
diff changeset
1590 off = size_binop (PLUS_EXPR, off, new_offset);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1591 }
111
kono
parents: 67
diff changeset
1592
kono
parents: 67
diff changeset
1593 /* While data-ref analysis punts on bit offsets it still handles
kono
parents: 67
diff changeset
1594 bitfield accesses at byte boundaries. Cope with that. Note that
kono
parents: 67
diff changeset
1595 if the bitfield object also starts at a byte-boundary we can simply
kono
parents: 67
diff changeset
1596 replicate the COMPONENT_REF, but we have to subtract the component's
kono
parents: 67
diff changeset
1597 byte-offset from the MEM_REF address first.
kono
parents: 67
diff changeset
1598 Otherwise we simply build a BIT_FIELD_REF knowing that the bits
kono
parents: 67
diff changeset
1599 start at offset zero. */
kono
parents: 67
diff changeset
1600 if (TREE_CODE (ref) == COMPONENT_REF
kono
parents: 67
diff changeset
1601 && DECL_BIT_FIELD (TREE_OPERAND (ref, 1)))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1602 {
111
kono
parents: 67
diff changeset
1603 unsigned HOST_WIDE_INT boff;
kono
parents: 67
diff changeset
1604 tree field = TREE_OPERAND (ref, 1);
kono
parents: 67
diff changeset
1605 tree offset = component_ref_field_offset (ref);
kono
parents: 67
diff changeset
1606 ref_type = TREE_TYPE (ref);
kono
parents: 67
diff changeset
1607 boff = tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field));
kono
parents: 67
diff changeset
1608 /* This can occur in Ada. See the comment in get_bit_range. */
kono
parents: 67
diff changeset
1609 if (boff % BITS_PER_UNIT != 0
kono
parents: 67
diff changeset
1610 || !tree_fits_uhwi_p (offset))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1611 {
111
kono
parents: 67
diff changeset
1612 ref_code = BIT_FIELD_REF;
kono
parents: 67
diff changeset
1613 ref_op1 = DECL_SIZE (field);
kono
parents: 67
diff changeset
1614 ref_op2 = bitsize_zero_node;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1615 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1616 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1617 {
111
kono
parents: 67
diff changeset
1618 boff >>= LOG2_BITS_PER_UNIT;
kono
parents: 67
diff changeset
1619 boff += tree_to_uhwi (offset);
kono
parents: 67
diff changeset
1620 coff = size_binop (MINUS_EXPR, coff, ssize_int (boff));
kono
parents: 67
diff changeset
1621 ref_code = COMPONENT_REF;
kono
parents: 67
diff changeset
1622 ref_op1 = field;
kono
parents: 67
diff changeset
1623 ref_op2 = TREE_OPERAND (ref, 2);
kono
parents: 67
diff changeset
1624 ref = TREE_OPERAND (ref, 0);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1625 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1626 }
111
kono
parents: 67
diff changeset
1627 tree addr = fold_build_pointer_plus (DR_BASE_ADDRESS (dr), off);
kono
parents: 67
diff changeset
1628 addr = force_gimple_operand_1 (unshare_expr (addr), stmts,
kono
parents: 67
diff changeset
1629 is_gimple_mem_ref_addr, NULL_TREE);
kono
parents: 67
diff changeset
1630 tree alias_ptr = fold_convert (reference_alias_ptr_type (ref), coff);
kono
parents: 67
diff changeset
1631 tree type = build_aligned_type (TREE_TYPE (ref),
kono
parents: 67
diff changeset
1632 get_object_alignment (ref));
kono
parents: 67
diff changeset
1633 ref = build2 (MEM_REF, type, addr, alias_ptr);
kono
parents: 67
diff changeset
1634 if (ref_type)
kono
parents: 67
diff changeset
1635 ref = build3 (ref_code, ref_type, ref, ref_op1, ref_op2);
kono
parents: 67
diff changeset
1636 return ref;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1637 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1638
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1639 /* Get the initialization expression for the INDEX-th temporary variable
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1640 of CHAIN. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1641
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1642 static tree
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1643 get_init_expr (chain_p chain, unsigned index)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1644 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1645 if (chain->type == CT_COMBINATION)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1646 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1647 tree e1 = get_init_expr (chain->ch1, index);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1648 tree e2 = get_init_expr (chain->ch2, index);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1649
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1650 return fold_build2 (chain->op, chain->rslt_type, e1, e2);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1651 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1652 else
111
kono
parents: 67
diff changeset
1653 return chain->inits[index];
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1654 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1655
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1656 /* Returns a new temporary variable used for the I-th variable carrying
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1657 value of REF. The variable's uid is marked in TMP_VARS. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1658
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1659 static tree
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1660 predcom_tmp_var (tree ref, unsigned i, bitmap tmp_vars)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1661 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1662 tree type = TREE_TYPE (ref);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1663 /* We never access the components of the temporary variable in predictive
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1664 commoning. */
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1665 tree var = create_tmp_reg (type, get_lsm_tmp_name (ref, i));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1666 bitmap_set_bit (tmp_vars, DECL_UID (var));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1667 return var;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1668 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1669
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1670 /* Creates the variables for CHAIN, as well as phi nodes for them and
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1671 initialization on entry to LOOP. Uids of the newly created
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1672 temporary variables are marked in TMP_VARS. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1673
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1674 static void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1675 initialize_root_vars (class loop *loop, chain_p chain, bitmap tmp_vars)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1676 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1677 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1678 unsigned n = chain->length;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1679 dref root = get_chain_root (chain);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1680 bool reuse_first = !chain->has_max_use_after;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1681 tree ref, init, var, next;
111
kono
parents: 67
diff changeset
1682 gphi *phi;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1683 gimple_seq stmts;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1684 edge entry = loop_preheader_edge (loop), latch = loop_latch_edge (loop);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1685
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1686 /* If N == 0, then all the references are within the single iteration. And
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1687 since this is an nonempty chain, reuse_first cannot be true. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1688 gcc_assert (n > 0 || !reuse_first);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1689
111
kono
parents: 67
diff changeset
1690 chain->vars.create (n + 1);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1691
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1692 if (chain->type == CT_COMBINATION)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1693 ref = gimple_assign_lhs (root->stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1694 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1695 ref = DR_REF (root->ref);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1696
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1697 for (i = 0; i < n + (reuse_first ? 0 : 1); i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1698 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1699 var = predcom_tmp_var (ref, i, tmp_vars);
111
kono
parents: 67
diff changeset
1700 chain->vars.quick_push (var);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1701 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1702 if (reuse_first)
111
kono
parents: 67
diff changeset
1703 chain->vars.quick_push (chain->vars[0]);
kono
parents: 67
diff changeset
1704
kono
parents: 67
diff changeset
1705 FOR_EACH_VEC_ELT (chain->vars, i, var)
kono
parents: 67
diff changeset
1706 chain->vars[i] = make_ssa_name (var);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1707
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1708 for (i = 0; i < n; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1709 {
111
kono
parents: 67
diff changeset
1710 var = chain->vars[i];
kono
parents: 67
diff changeset
1711 next = chain->vars[i + 1];
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1712 init = get_init_expr (chain, i);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1713
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1714 init = force_gimple_operand (init, &stmts, true, NULL_TREE);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1715 if (stmts)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1716 gsi_insert_seq_on_edge_immediate (entry, stmts);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1717
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1718 phi = create_phi_node (var, loop->header);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1719 add_phi_arg (phi, init, entry, UNKNOWN_LOCATION);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1720 add_phi_arg (phi, next, latch, UNKNOWN_LOCATION);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1721 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1722 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1723
111
kono
parents: 67
diff changeset
1724 /* For inter-iteration store elimination CHAIN in LOOP, returns true if
kono
parents: 67
diff changeset
1725 all stores to be eliminated store loop invariant values into memory.
kono
parents: 67
diff changeset
1726 In this case, we can use these invariant values directly after LOOP. */
kono
parents: 67
diff changeset
1727
kono
parents: 67
diff changeset
1728 static bool
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1729 is_inv_store_elimination_chain (class loop *loop, chain_p chain)
111
kono
parents: 67
diff changeset
1730 {
kono
parents: 67
diff changeset
1731 if (chain->length == 0 || chain->type != CT_STORE_STORE)
kono
parents: 67
diff changeset
1732 return false;
kono
parents: 67
diff changeset
1733
kono
parents: 67
diff changeset
1734 gcc_assert (!chain->has_max_use_after);
kono
parents: 67
diff changeset
1735
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1736 /* If loop iterates for unknown times or fewer times than chain->length,
111
kono
parents: 67
diff changeset
1737 we still need to setup root variable and propagate it with PHI node. */
kono
parents: 67
diff changeset
1738 tree niters = number_of_latch_executions (loop);
kono
parents: 67
diff changeset
1739 if (TREE_CODE (niters) != INTEGER_CST
kono
parents: 67
diff changeset
1740 || wi::leu_p (wi::to_wide (niters), chain->length))
kono
parents: 67
diff changeset
1741 return false;
kono
parents: 67
diff changeset
1742
kono
parents: 67
diff changeset
1743 /* Check stores in chain for elimination if they only store loop invariant
kono
parents: 67
diff changeset
1744 values. */
kono
parents: 67
diff changeset
1745 for (unsigned i = 0; i < chain->length; i++)
kono
parents: 67
diff changeset
1746 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1747 dref a = get_chain_last_write_at (chain, i);
111
kono
parents: 67
diff changeset
1748 if (a == NULL)
kono
parents: 67
diff changeset
1749 continue;
kono
parents: 67
diff changeset
1750
kono
parents: 67
diff changeset
1751 gimple *def_stmt, *stmt = a->stmt;
kono
parents: 67
diff changeset
1752 if (!gimple_assign_single_p (stmt))
kono
parents: 67
diff changeset
1753 return false;
kono
parents: 67
diff changeset
1754
kono
parents: 67
diff changeset
1755 tree val = gimple_assign_rhs1 (stmt);
kono
parents: 67
diff changeset
1756 if (TREE_CLOBBER_P (val))
kono
parents: 67
diff changeset
1757 return false;
kono
parents: 67
diff changeset
1758
kono
parents: 67
diff changeset
1759 if (CONSTANT_CLASS_P (val))
kono
parents: 67
diff changeset
1760 continue;
kono
parents: 67
diff changeset
1761
kono
parents: 67
diff changeset
1762 if (TREE_CODE (val) != SSA_NAME)
kono
parents: 67
diff changeset
1763 return false;
kono
parents: 67
diff changeset
1764
kono
parents: 67
diff changeset
1765 def_stmt = SSA_NAME_DEF_STMT (val);
kono
parents: 67
diff changeset
1766 if (gimple_nop_p (def_stmt))
kono
parents: 67
diff changeset
1767 continue;
kono
parents: 67
diff changeset
1768
kono
parents: 67
diff changeset
1769 if (flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)))
kono
parents: 67
diff changeset
1770 return false;
kono
parents: 67
diff changeset
1771 }
kono
parents: 67
diff changeset
1772 return true;
kono
parents: 67
diff changeset
1773 }
kono
parents: 67
diff changeset
1774
kono
parents: 67
diff changeset
1775 /* Creates root variables for store elimination CHAIN in which stores for
kono
parents: 67
diff changeset
1776 elimination only store loop invariant values. In this case, we neither
kono
parents: 67
diff changeset
1777 need to load root variables before loop nor propagate it with PHI nodes. */
kono
parents: 67
diff changeset
1778
kono
parents: 67
diff changeset
1779 static void
kono
parents: 67
diff changeset
1780 initialize_root_vars_store_elim_1 (chain_p chain)
kono
parents: 67
diff changeset
1781 {
kono
parents: 67
diff changeset
1782 tree var;
kono
parents: 67
diff changeset
1783 unsigned i, n = chain->length;
kono
parents: 67
diff changeset
1784
kono
parents: 67
diff changeset
1785 chain->vars.create (n);
kono
parents: 67
diff changeset
1786 chain->vars.safe_grow_cleared (n);
kono
parents: 67
diff changeset
1787
kono
parents: 67
diff changeset
1788 /* Initialize root value for eliminated stores at each distance. */
kono
parents: 67
diff changeset
1789 for (i = 0; i < n; i++)
kono
parents: 67
diff changeset
1790 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1791 dref a = get_chain_last_write_at (chain, i);
111
kono
parents: 67
diff changeset
1792 if (a == NULL)
kono
parents: 67
diff changeset
1793 continue;
kono
parents: 67
diff changeset
1794
kono
parents: 67
diff changeset
1795 var = gimple_assign_rhs1 (a->stmt);
kono
parents: 67
diff changeset
1796 chain->vars[a->distance] = var;
kono
parents: 67
diff changeset
1797 }
kono
parents: 67
diff changeset
1798
kono
parents: 67
diff changeset
1799 /* We don't propagate values with PHI nodes, so manually propagate value
kono
parents: 67
diff changeset
1800 to bubble positions. */
kono
parents: 67
diff changeset
1801 var = chain->vars[0];
kono
parents: 67
diff changeset
1802 for (i = 1; i < n; i++)
kono
parents: 67
diff changeset
1803 {
kono
parents: 67
diff changeset
1804 if (chain->vars[i] != NULL_TREE)
kono
parents: 67
diff changeset
1805 {
kono
parents: 67
diff changeset
1806 var = chain->vars[i];
kono
parents: 67
diff changeset
1807 continue;
kono
parents: 67
diff changeset
1808 }
kono
parents: 67
diff changeset
1809 chain->vars[i] = var;
kono
parents: 67
diff changeset
1810 }
kono
parents: 67
diff changeset
1811
kono
parents: 67
diff changeset
1812 /* Revert the vector. */
kono
parents: 67
diff changeset
1813 for (i = 0; i < n / 2; i++)
kono
parents: 67
diff changeset
1814 std::swap (chain->vars[i], chain->vars[n - i - 1]);
kono
parents: 67
diff changeset
1815 }
kono
parents: 67
diff changeset
1816
kono
parents: 67
diff changeset
1817 /* Creates root variables for store elimination CHAIN in which stores for
kono
parents: 67
diff changeset
1818 elimination store loop variant values. In this case, we may need to
kono
parents: 67
diff changeset
1819 load root variables before LOOP and propagate it with PHI nodes. Uids
kono
parents: 67
diff changeset
1820 of the newly created root variables are marked in TMP_VARS. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1821
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1822 static void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1823 initialize_root_vars_store_elim_2 (class loop *loop,
111
kono
parents: 67
diff changeset
1824 chain_p chain, bitmap tmp_vars)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1825 {
111
kono
parents: 67
diff changeset
1826 unsigned i, n = chain->length;
kono
parents: 67
diff changeset
1827 tree ref, init, var, next, val, phi_result;
kono
parents: 67
diff changeset
1828 gimple *stmt;
kono
parents: 67
diff changeset
1829 gimple_seq stmts;
kono
parents: 67
diff changeset
1830
kono
parents: 67
diff changeset
1831 chain->vars.create (n);
kono
parents: 67
diff changeset
1832
kono
parents: 67
diff changeset
1833 ref = DR_REF (get_chain_root (chain)->ref);
kono
parents: 67
diff changeset
1834 for (i = 0; i < n; i++)
kono
parents: 67
diff changeset
1835 {
kono
parents: 67
diff changeset
1836 var = predcom_tmp_var (ref, i, tmp_vars);
kono
parents: 67
diff changeset
1837 chain->vars.quick_push (var);
kono
parents: 67
diff changeset
1838 }
kono
parents: 67
diff changeset
1839
kono
parents: 67
diff changeset
1840 FOR_EACH_VEC_ELT (chain->vars, i, var)
kono
parents: 67
diff changeset
1841 chain->vars[i] = make_ssa_name (var);
kono
parents: 67
diff changeset
1842
kono
parents: 67
diff changeset
1843 /* Root values are either rhs operand of stores to be eliminated, or
kono
parents: 67
diff changeset
1844 loaded from memory before loop. */
kono
parents: 67
diff changeset
1845 auto_vec<tree> vtemps;
kono
parents: 67
diff changeset
1846 vtemps.safe_grow_cleared (n);
kono
parents: 67
diff changeset
1847 for (i = 0; i < n; i++)
kono
parents: 67
diff changeset
1848 {
kono
parents: 67
diff changeset
1849 init = get_init_expr (chain, i);
kono
parents: 67
diff changeset
1850 if (init == NULL_TREE)
kono
parents: 67
diff changeset
1851 {
kono
parents: 67
diff changeset
1852 /* Root value is rhs operand of the store to be eliminated if
kono
parents: 67
diff changeset
1853 it isn't loaded from memory before loop. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1854 dref a = get_chain_last_write_at (chain, i);
111
kono
parents: 67
diff changeset
1855 val = gimple_assign_rhs1 (a->stmt);
kono
parents: 67
diff changeset
1856 if (TREE_CLOBBER_P (val))
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1857 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1858 val = get_or_create_ssa_default_def (cfun, SSA_NAME_VAR (var));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1859 gimple_assign_set_rhs1 (a->stmt, val);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1860 }
111
kono
parents: 67
diff changeset
1861
kono
parents: 67
diff changeset
1862 vtemps[n - i - 1] = val;
kono
parents: 67
diff changeset
1863 }
kono
parents: 67
diff changeset
1864 else
kono
parents: 67
diff changeset
1865 {
kono
parents: 67
diff changeset
1866 edge latch = loop_latch_edge (loop);
kono
parents: 67
diff changeset
1867 edge entry = loop_preheader_edge (loop);
kono
parents: 67
diff changeset
1868
kono
parents: 67
diff changeset
1869 /* Root value is loaded from memory before loop, we also need
kono
parents: 67
diff changeset
1870 to add PHI nodes to propagate the value across iterations. */
kono
parents: 67
diff changeset
1871 init = force_gimple_operand (init, &stmts, true, NULL_TREE);
kono
parents: 67
diff changeset
1872 if (stmts)
kono
parents: 67
diff changeset
1873 gsi_insert_seq_on_edge_immediate (entry, stmts);
kono
parents: 67
diff changeset
1874
kono
parents: 67
diff changeset
1875 next = chain->vars[n - i];
kono
parents: 67
diff changeset
1876 phi_result = copy_ssa_name (next);
kono
parents: 67
diff changeset
1877 gphi *phi = create_phi_node (phi_result, loop->header);
kono
parents: 67
diff changeset
1878 add_phi_arg (phi, init, entry, UNKNOWN_LOCATION);
kono
parents: 67
diff changeset
1879 add_phi_arg (phi, next, latch, UNKNOWN_LOCATION);
kono
parents: 67
diff changeset
1880 vtemps[n - i - 1] = phi_result;
kono
parents: 67
diff changeset
1881 }
kono
parents: 67
diff changeset
1882 }
kono
parents: 67
diff changeset
1883
kono
parents: 67
diff changeset
1884 /* Find the insertion position. */
kono
parents: 67
diff changeset
1885 dref last = get_chain_root (chain);
kono
parents: 67
diff changeset
1886 for (i = 0; i < chain->refs.length (); i++)
kono
parents: 67
diff changeset
1887 {
kono
parents: 67
diff changeset
1888 if (chain->refs[i]->pos > last->pos)
kono
parents: 67
diff changeset
1889 last = chain->refs[i];
kono
parents: 67
diff changeset
1890 }
kono
parents: 67
diff changeset
1891
kono
parents: 67
diff changeset
1892 gimple_stmt_iterator gsi = gsi_for_stmt (last->stmt);
kono
parents: 67
diff changeset
1893
kono
parents: 67
diff changeset
1894 /* Insert statements copying root value to root variable. */
kono
parents: 67
diff changeset
1895 for (i = 0; i < n; i++)
kono
parents: 67
diff changeset
1896 {
kono
parents: 67
diff changeset
1897 var = chain->vars[i];
kono
parents: 67
diff changeset
1898 val = vtemps[i];
kono
parents: 67
diff changeset
1899 stmt = gimple_build_assign (var, val);
kono
parents: 67
diff changeset
1900 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
kono
parents: 67
diff changeset
1901 }
kono
parents: 67
diff changeset
1902 }
kono
parents: 67
diff changeset
1903
kono
parents: 67
diff changeset
1904 /* Generates stores for CHAIN's eliminated stores in LOOP's last
kono
parents: 67
diff changeset
1905 (CHAIN->length - 1) iterations. */
kono
parents: 67
diff changeset
1906
kono
parents: 67
diff changeset
1907 static void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1908 finalize_eliminated_stores (class loop *loop, chain_p chain)
111
kono
parents: 67
diff changeset
1909 {
kono
parents: 67
diff changeset
1910 unsigned i, n = chain->length;
kono
parents: 67
diff changeset
1911
kono
parents: 67
diff changeset
1912 for (i = 0; i < n; i++)
kono
parents: 67
diff changeset
1913 {
kono
parents: 67
diff changeset
1914 tree var = chain->vars[i];
kono
parents: 67
diff changeset
1915 tree fini = chain->finis[n - i - 1];
kono
parents: 67
diff changeset
1916 gimple *stmt = gimple_build_assign (fini, var);
kono
parents: 67
diff changeset
1917
kono
parents: 67
diff changeset
1918 gimple_seq_add_stmt_without_update (&chain->fini_seq, stmt);
kono
parents: 67
diff changeset
1919 }
kono
parents: 67
diff changeset
1920
kono
parents: 67
diff changeset
1921 if (chain->fini_seq)
kono
parents: 67
diff changeset
1922 {
kono
parents: 67
diff changeset
1923 gsi_insert_seq_on_edge_immediate (single_exit (loop), chain->fini_seq);
kono
parents: 67
diff changeset
1924 chain->fini_seq = NULL;
kono
parents: 67
diff changeset
1925 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1926 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1927
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1928 /* Initializes a variable for load motion for ROOT and prepares phi nodes and
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1929 initialization on entry to LOOP if necessary. The ssa name for the variable
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1930 is stored in VARS. If WRITTEN is true, also a phi node to copy its value
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1931 around the loop is created. Uid of the newly created temporary variable
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1932 is marked in TMP_VARS. INITS is the list containing the (single)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1933 initializer. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1934
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1935 static void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1936 initialize_root_vars_lm (class loop *loop, dref root, bool written,
111
kono
parents: 67
diff changeset
1937 vec<tree> *vars, vec<tree> inits,
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1938 bitmap tmp_vars)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1939 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1940 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1941 tree ref = DR_REF (root->ref), init, var, next;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1942 gimple_seq stmts;
111
kono
parents: 67
diff changeset
1943 gphi *phi;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1944 edge entry = loop_preheader_edge (loop), latch = loop_latch_edge (loop);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1945
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1946 /* Find the initializer for the variable, and check that it cannot
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1947 trap. */
111
kono
parents: 67
diff changeset
1948 init = inits[0];
kono
parents: 67
diff changeset
1949
kono
parents: 67
diff changeset
1950 vars->create (written ? 2 : 1);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1951 var = predcom_tmp_var (ref, 0, tmp_vars);
111
kono
parents: 67
diff changeset
1952 vars->quick_push (var);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1953 if (written)
111
kono
parents: 67
diff changeset
1954 vars->quick_push ((*vars)[0]);
kono
parents: 67
diff changeset
1955
kono
parents: 67
diff changeset
1956 FOR_EACH_VEC_ELT (*vars, i, var)
kono
parents: 67
diff changeset
1957 (*vars)[i] = make_ssa_name (var);
kono
parents: 67
diff changeset
1958
kono
parents: 67
diff changeset
1959 var = (*vars)[0];
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1960
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1961 init = force_gimple_operand (init, &stmts, written, NULL_TREE);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1962 if (stmts)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1963 gsi_insert_seq_on_edge_immediate (entry, stmts);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1964
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1965 if (written)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1966 {
111
kono
parents: 67
diff changeset
1967 next = (*vars)[1];
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1968 phi = create_phi_node (var, loop->header);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1969 add_phi_arg (phi, init, entry, UNKNOWN_LOCATION);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1970 add_phi_arg (phi, next, latch, UNKNOWN_LOCATION);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1971 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1972 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1973 {
111
kono
parents: 67
diff changeset
1974 gassign *init_stmt = gimple_build_assign (var, init);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1975 gsi_insert_on_edge_immediate (entry, init_stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1976 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1977 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1978
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1979
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1980 /* Execute load motion for references in chain CHAIN. Uids of the newly
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1981 created temporary variables are marked in TMP_VARS. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1982
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1983 static void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1984 execute_load_motion (class loop *loop, chain_p chain, bitmap tmp_vars)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1985 {
111
kono
parents: 67
diff changeset
1986 auto_vec<tree> vars;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1987 dref a;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1988 unsigned n_writes = 0, ridx, i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1989 tree var;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1990
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1991 gcc_assert (chain->type == CT_INVARIANT);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1992 gcc_assert (!chain->combined);
111
kono
parents: 67
diff changeset
1993 FOR_EACH_VEC_ELT (chain->refs, i, a)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1994 if (DR_IS_WRITE (a->ref))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1995 n_writes++;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1996
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1997 /* If there are no reads in the loop, there is nothing to do. */
111
kono
parents: 67
diff changeset
1998 if (n_writes == chain->refs.length ())
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1999 return;
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 initialize_root_vars_lm (loop, get_chain_root (chain), n_writes > 0,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2002 &vars, chain->inits, tmp_vars);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2003
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2004 ridx = 0;
111
kono
parents: 67
diff changeset
2005 FOR_EACH_VEC_ELT (chain->refs, i, a)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2006 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2007 bool is_read = DR_IS_READ (a->ref);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2008
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2009 if (DR_IS_WRITE (a->ref))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2010 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2011 n_writes--;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2012 if (n_writes)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2013 {
111
kono
parents: 67
diff changeset
2014 var = vars[0];
kono
parents: 67
diff changeset
2015 var = make_ssa_name (SSA_NAME_VAR (var));
kono
parents: 67
diff changeset
2016 vars[0] = var;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2017 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2018 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2019 ridx = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2020 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2021
111
kono
parents: 67
diff changeset
2022 replace_ref_with (a->stmt, vars[ridx],
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2023 !is_read, !is_read);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2024 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2025 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2026
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2027 /* Returns the single statement in that NAME is used, excepting
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2028 the looparound phi nodes contained in one of the chains. If there is no
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2029 such statement, or more statements, NULL is returned. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2030
111
kono
parents: 67
diff changeset
2031 static gimple *
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2032 single_nonlooparound_use (tree name)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2033 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2034 use_operand_p use;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2035 imm_use_iterator it;
111
kono
parents: 67
diff changeset
2036 gimple *stmt, *ret = NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2037
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2038 FOR_EACH_IMM_USE_FAST (use, it, name)
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 stmt = USE_STMT (use);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2041
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2042 if (gimple_code (stmt) == GIMPLE_PHI)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2043 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2044 /* Ignore uses in looparound phi nodes. Uses in other phi nodes
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2045 could not be processed anyway, so just fail for them. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2046 if (bitmap_bit_p (looparound_phis,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2047 SSA_NAME_VERSION (PHI_RESULT (stmt))))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2048 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2049
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2050 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2051 }
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
2052 else if (is_gimple_debug (stmt))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2053 continue;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2054 else if (ret != NULL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2055 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2056 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2057 ret = stmt;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2058 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2059
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2060 return ret;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2061 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2062
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2063 /* Remove statement STMT, as well as the chain of assignments in that it is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2064 used. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2065
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2066 static void
111
kono
parents: 67
diff changeset
2067 remove_stmt (gimple *stmt)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2068 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2069 tree name;
111
kono
parents: 67
diff changeset
2070 gimple *next;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2071 gimple_stmt_iterator psi;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2072
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2073 if (gimple_code (stmt) == GIMPLE_PHI)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2074 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2075 name = PHI_RESULT (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2076 next = single_nonlooparound_use (name);
111
kono
parents: 67
diff changeset
2077 reset_debug_uses (stmt);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2078 psi = gsi_for_stmt (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2079 remove_phi_node (&psi, true);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2080
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2081 if (!next
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2082 || !gimple_assign_ssa_name_copy_p (next)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2083 || gimple_assign_rhs1 (next) != name)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2084 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2085
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2086 stmt = next;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2087 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2088
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2089 while (1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2090 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2091 gimple_stmt_iterator bsi;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2092
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2093 bsi = gsi_for_stmt (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2094
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2095 name = gimple_assign_lhs (stmt);
111
kono
parents: 67
diff changeset
2096 if (TREE_CODE (name) == SSA_NAME)
kono
parents: 67
diff changeset
2097 {
kono
parents: 67
diff changeset
2098 next = single_nonlooparound_use (name);
kono
parents: 67
diff changeset
2099 reset_debug_uses (stmt);
kono
parents: 67
diff changeset
2100 }
kono
parents: 67
diff changeset
2101 else
kono
parents: 67
diff changeset
2102 {
kono
parents: 67
diff changeset
2103 /* This is a store to be eliminated. */
kono
parents: 67
diff changeset
2104 gcc_assert (gimple_vdef (stmt) != NULL);
kono
parents: 67
diff changeset
2105 next = NULL;
kono
parents: 67
diff changeset
2106 }
kono
parents: 67
diff changeset
2107
kono
parents: 67
diff changeset
2108 unlink_stmt_vdef (stmt);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2109 gsi_remove (&bsi, true);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2110 release_defs (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2111
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2112 if (!next
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2113 || !gimple_assign_ssa_name_copy_p (next)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2114 || gimple_assign_rhs1 (next) != name)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2115 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2116
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2117 stmt = next;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2118 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2119 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2120
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2121 /* Perform the predictive commoning optimization for a chain CHAIN.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2122 Uids of the newly created temporary variables are marked in TMP_VARS.*/
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2123
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2124 static void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2125 execute_pred_commoning_chain (class loop *loop, chain_p chain,
111
kono
parents: 67
diff changeset
2126 bitmap tmp_vars)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2127 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2128 unsigned i;
111
kono
parents: 67
diff changeset
2129 dref a;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2130 tree var;
111
kono
parents: 67
diff changeset
2131 bool in_lhs;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2132
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2133 if (chain->combined)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2134 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2135 /* For combined chains, just remove the statements that are used to
111
kono
parents: 67
diff changeset
2136 compute the values of the expression (except for the root one).
kono
parents: 67
diff changeset
2137 We delay this until after all chains are processed. */
kono
parents: 67
diff changeset
2138 }
kono
parents: 67
diff changeset
2139 else if (chain->type == CT_STORE_STORE)
kono
parents: 67
diff changeset
2140 {
kono
parents: 67
diff changeset
2141 if (chain->length > 0)
kono
parents: 67
diff changeset
2142 {
kono
parents: 67
diff changeset
2143 if (chain->inv_store_elimination)
kono
parents: 67
diff changeset
2144 {
kono
parents: 67
diff changeset
2145 /* If dead stores in this chain only store loop invariant
kono
parents: 67
diff changeset
2146 values, we can simply record the invariant value and use
kono
parents: 67
diff changeset
2147 it directly after loop. */
kono
parents: 67
diff changeset
2148 initialize_root_vars_store_elim_1 (chain);
kono
parents: 67
diff changeset
2149 }
kono
parents: 67
diff changeset
2150 else
kono
parents: 67
diff changeset
2151 {
kono
parents: 67
diff changeset
2152 /* If dead stores in this chain store loop variant values,
kono
parents: 67
diff changeset
2153 we need to set up the variables by loading from memory
kono
parents: 67
diff changeset
2154 before loop and propagating it with PHI nodes. */
kono
parents: 67
diff changeset
2155 initialize_root_vars_store_elim_2 (loop, chain, tmp_vars);
kono
parents: 67
diff changeset
2156 }
kono
parents: 67
diff changeset
2157
kono
parents: 67
diff changeset
2158 /* For inter-iteration store elimination chain, stores at each
kono
parents: 67
diff changeset
2159 distance in loop's last (chain->length - 1) iterations can't
kono
parents: 67
diff changeset
2160 be eliminated, because there is no following killing store.
kono
parents: 67
diff changeset
2161 We need to generate these stores after loop. */
kono
parents: 67
diff changeset
2162 finalize_eliminated_stores (loop, chain);
kono
parents: 67
diff changeset
2163 }
kono
parents: 67
diff changeset
2164
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2165 bool last_store_p = true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2166 for (i = chain->refs.length (); i > 0; i--)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2167 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2168 a = chain->refs[i - 1];
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2169 /* Preserve the last store of the chain. Eliminate other stores
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2170 which are killed by the last one. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2171 if (DR_IS_WRITE (a->ref))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2172 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2173 if (last_store_p)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2174 last_store_p = false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2175 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2176 remove_stmt (a->stmt);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2177
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2178 continue;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2179 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2180
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2181 /* Any load in Store-Store chain must be dominated by a previous
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2182 store, we replace the load reference with rhs of the store. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2183 dref b = get_chain_last_write_before_load (chain, i - 1);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2184 gcc_assert (b != NULL);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2185 var = gimple_assign_rhs1 (b->stmt);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2186 replace_ref_with (a->stmt, var, false, false);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2187 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2188 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2189 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2190 {
111
kono
parents: 67
diff changeset
2191 /* For non-combined chains, set up the variables that hold its value. */
kono
parents: 67
diff changeset
2192 initialize_root_vars (loop, chain, tmp_vars);
kono
parents: 67
diff changeset
2193 a = get_chain_root (chain);
kono
parents: 67
diff changeset
2194 in_lhs = (chain->type == CT_STORE_LOAD
kono
parents: 67
diff changeset
2195 || chain->type == CT_COMBINATION);
kono
parents: 67
diff changeset
2196 replace_ref_with (a->stmt, chain->vars[chain->length], true, in_lhs);
kono
parents: 67
diff changeset
2197
kono
parents: 67
diff changeset
2198 /* Replace the uses of the original references by these variables. */
kono
parents: 67
diff changeset
2199 for (i = 1; chain->refs.iterate (i, &a); i++)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2200 {
111
kono
parents: 67
diff changeset
2201 var = chain->vars[chain->length - a->distance];
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2202 replace_ref_with (a->stmt, var, false, false);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2203 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2204 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2205 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2206
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2207 /* Determines the unroll factor necessary to remove as many temporary variable
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2208 copies as possible. CHAINS is the list of chains that will be
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2209 optimized. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2210
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2211 static unsigned
111
kono
parents: 67
diff changeset
2212 determine_unroll_factor (vec<chain_p> chains)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2213 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2214 chain_p chain;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2215 unsigned factor = 1, af, nfactor, i;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2216 unsigned max = param_max_unroll_times;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2217
111
kono
parents: 67
diff changeset
2218 FOR_EACH_VEC_ELT (chains, i, chain)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2219 {
111
kono
parents: 67
diff changeset
2220 if (chain->type == CT_INVARIANT)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2221 continue;
111
kono
parents: 67
diff changeset
2222 /* For now we can't handle unrolling when eliminating stores. */
kono
parents: 67
diff changeset
2223 else if (chain->type == CT_STORE_STORE)
kono
parents: 67
diff changeset
2224 return 1;
kono
parents: 67
diff changeset
2225
kono
parents: 67
diff changeset
2226 if (chain->combined)
kono
parents: 67
diff changeset
2227 {
kono
parents: 67
diff changeset
2228 /* For combined chains, we can't handle unrolling if we replace
kono
parents: 67
diff changeset
2229 looparound PHIs. */
kono
parents: 67
diff changeset
2230 dref a;
kono
parents: 67
diff changeset
2231 unsigned j;
kono
parents: 67
diff changeset
2232 for (j = 1; chain->refs.iterate (j, &a); j++)
kono
parents: 67
diff changeset
2233 if (gimple_code (a->stmt) == GIMPLE_PHI)
kono
parents: 67
diff changeset
2234 return 1;
kono
parents: 67
diff changeset
2235 continue;
kono
parents: 67
diff changeset
2236 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2237
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2238 /* The best unroll factor for this chain is equal to the number of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2239 temporary variables that we create for it. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2240 af = chain->length;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2241 if (chain->has_max_use_after)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2242 af++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2243
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2244 nfactor = factor * af / gcd (factor, af);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2245 if (nfactor <= max)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2246 factor = nfactor;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2247 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2248
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2249 return factor;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2250 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2251
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2252 /* Perform the predictive commoning optimization for CHAINS.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2253 Uids of the newly created temporary variables are marked in TMP_VARS. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2254
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2255 static void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2256 execute_pred_commoning (class loop *loop, vec<chain_p> chains,
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2257 bitmap tmp_vars)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2258 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2259 chain_p chain;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2260 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2261
111
kono
parents: 67
diff changeset
2262 FOR_EACH_VEC_ELT (chains, i, chain)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2263 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2264 if (chain->type == CT_INVARIANT)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2265 execute_load_motion (loop, chain, tmp_vars);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2266 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2267 execute_pred_commoning_chain (loop, chain, tmp_vars);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2268 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2269
111
kono
parents: 67
diff changeset
2270 FOR_EACH_VEC_ELT (chains, i, chain)
kono
parents: 67
diff changeset
2271 {
kono
parents: 67
diff changeset
2272 if (chain->type == CT_INVARIANT)
kono
parents: 67
diff changeset
2273 ;
kono
parents: 67
diff changeset
2274 else if (chain->combined)
kono
parents: 67
diff changeset
2275 {
kono
parents: 67
diff changeset
2276 /* For combined chains, just remove the statements that are used to
kono
parents: 67
diff changeset
2277 compute the values of the expression (except for the root one). */
kono
parents: 67
diff changeset
2278 dref a;
kono
parents: 67
diff changeset
2279 unsigned j;
kono
parents: 67
diff changeset
2280 for (j = 1; chain->refs.iterate (j, &a); j++)
kono
parents: 67
diff changeset
2281 remove_stmt (a->stmt);
kono
parents: 67
diff changeset
2282 }
kono
parents: 67
diff changeset
2283 }
kono
parents: 67
diff changeset
2284
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2285 update_ssa (TODO_update_ssa_only_virtuals);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2286 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2287
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2288 /* For each reference in CHAINS, if its defining statement is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2289 phi node, record the ssa name that is defined by it. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2290
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2291 static void
111
kono
parents: 67
diff changeset
2292 replace_phis_by_defined_names (vec<chain_p> chains)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2293 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2294 chain_p chain;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2295 dref a;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2296 unsigned i, j;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2297
111
kono
parents: 67
diff changeset
2298 FOR_EACH_VEC_ELT (chains, i, chain)
kono
parents: 67
diff changeset
2299 FOR_EACH_VEC_ELT (chain->refs, j, a)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2300 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2301 if (gimple_code (a->stmt) == GIMPLE_PHI)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2302 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2303 a->name_defined_by_phi = PHI_RESULT (a->stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2304 a->stmt = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2305 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2306 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2307 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2308
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2309 /* For each reference in CHAINS, if name_defined_by_phi is not
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2310 NULL, use it to set the stmt field. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2311
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2312 static void
111
kono
parents: 67
diff changeset
2313 replace_names_by_phis (vec<chain_p> chains)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2314 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2315 chain_p chain;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2316 dref a;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2317 unsigned i, j;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2318
111
kono
parents: 67
diff changeset
2319 FOR_EACH_VEC_ELT (chains, i, chain)
kono
parents: 67
diff changeset
2320 FOR_EACH_VEC_ELT (chain->refs, j, a)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2321 if (a->stmt == NULL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2322 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2323 a->stmt = SSA_NAME_DEF_STMT (a->name_defined_by_phi);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2324 gcc_assert (gimple_code (a->stmt) == GIMPLE_PHI);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2325 a->name_defined_by_phi = NULL_TREE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2326 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2327 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2328
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2329 /* Wrapper over execute_pred_commoning, to pass it as a callback
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2330 to tree_transform_and_unroll_loop. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2331
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2332 struct epcc_data
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2333 {
111
kono
parents: 67
diff changeset
2334 vec<chain_p> chains;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2335 bitmap tmp_vars;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2336 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2337
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2338 static void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2339 execute_pred_commoning_cbck (class loop *loop, void *data)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2340 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2341 struct epcc_data *const dta = (struct epcc_data *) data;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2342
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2343 /* Restore phi nodes that were replaced by ssa names before
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2344 tree_transform_and_unroll_loop (see detailed description in
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2345 tree_predictive_commoning_loop). */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2346 replace_names_by_phis (dta->chains);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2347 execute_pred_commoning (loop, dta->chains, dta->tmp_vars);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2348 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2349
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2350 /* Base NAME and all the names in the chain of phi nodes that use it
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2351 on variable VAR. The phi nodes are recognized by being in the copies of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2352 the header of the LOOP. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2353
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2354 static void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2355 base_names_in_chain_on (class loop *loop, tree name, tree var)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2356 {
111
kono
parents: 67
diff changeset
2357 gimple *stmt, *phi;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2358 imm_use_iterator iter;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2359
111
kono
parents: 67
diff changeset
2360 replace_ssa_name_symbol (name, var);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2361
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2362 while (1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2363 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2364 phi = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2365 FOR_EACH_IMM_USE_STMT (stmt, iter, name)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2366 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2367 if (gimple_code (stmt) == GIMPLE_PHI
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2368 && flow_bb_inside_loop_p (loop, gimple_bb (stmt)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2369 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2370 phi = stmt;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2371 BREAK_FROM_IMM_USE_STMT (iter);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2372 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2373 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2374 if (!phi)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2375 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2376
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2377 name = PHI_RESULT (phi);
111
kono
parents: 67
diff changeset
2378 replace_ssa_name_symbol (name, var);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2379 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2380 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2381
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2382 /* Given an unrolled LOOP after predictive commoning, remove the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2383 register copies arising from phi nodes by changing the base
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2384 variables of SSA names. TMP_VARS is the set of the temporary variables
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2385 for those we want to perform this. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2386
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2387 static void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2388 eliminate_temp_copies (class loop *loop, bitmap tmp_vars)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2389 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2390 edge e;
111
kono
parents: 67
diff changeset
2391 gphi *phi;
kono
parents: 67
diff changeset
2392 gimple *stmt;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2393 tree name, use, var;
111
kono
parents: 67
diff changeset
2394 gphi_iterator psi;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2395
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2396 e = loop_latch_edge (loop);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2397 for (psi = gsi_start_phis (loop->header); !gsi_end_p (psi); gsi_next (&psi))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2398 {
111
kono
parents: 67
diff changeset
2399 phi = psi.phi ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2400 name = PHI_RESULT (phi);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2401 var = SSA_NAME_VAR (name);
111
kono
parents: 67
diff changeset
2402 if (!var || !bitmap_bit_p (tmp_vars, DECL_UID (var)))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2403 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2404 use = PHI_ARG_DEF_FROM_EDGE (phi, e);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2405 gcc_assert (TREE_CODE (use) == SSA_NAME);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2406
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2407 /* Base all the ssa names in the ud and du chain of NAME on VAR. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2408 stmt = SSA_NAME_DEF_STMT (use);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2409 while (gimple_code (stmt) == GIMPLE_PHI
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2410 /* In case we could not unroll the loop enough to eliminate
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2411 all copies, we may reach the loop header before the defining
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2412 statement (in that case, some register copies will be present
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2413 in loop latch in the final code, corresponding to the newly
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2414 created looparound phi nodes). */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2415 && gimple_bb (stmt) != loop->header)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2416 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2417 gcc_assert (single_pred_p (gimple_bb (stmt)));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2418 use = PHI_ARG_DEF (stmt, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2419 stmt = SSA_NAME_DEF_STMT (use);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2420 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2421
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2422 base_names_in_chain_on (loop, use, var);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2423 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2424 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2425
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2426 /* Returns true if CHAIN is suitable to be combined. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2427
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2428 static bool
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2429 chain_can_be_combined_p (chain_p chain)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2430 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2431 return (!chain->combined
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2432 && (chain->type == CT_LOAD || chain->type == CT_COMBINATION));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2433 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2434
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2435 /* Returns the modify statement that uses NAME. Skips over assignment
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2436 statements, NAME is replaced with the actual name used in the returned
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2437 statement. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2438
111
kono
parents: 67
diff changeset
2439 static gimple *
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2440 find_use_stmt (tree *name)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2441 {
111
kono
parents: 67
diff changeset
2442 gimple *stmt;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2443 tree rhs, lhs;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2444
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2445 /* Skip over assignments. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2446 while (1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2447 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2448 stmt = single_nonlooparound_use (*name);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2449 if (!stmt)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2450 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2451
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2452 if (gimple_code (stmt) != GIMPLE_ASSIGN)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2453 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2454
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2455 lhs = gimple_assign_lhs (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2456 if (TREE_CODE (lhs) != SSA_NAME)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2457 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2458
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2459 if (gimple_assign_copy_p (stmt))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2460 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2461 rhs = gimple_assign_rhs1 (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2462 if (rhs != *name)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2463 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2464
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2465 *name = lhs;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2466 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2467 else if (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2468 == GIMPLE_BINARY_RHS)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2469 return stmt;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2470 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2471 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2472 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2473 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2474
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2475 /* Returns true if we may perform reassociation for operation CODE in TYPE. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2476
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2477 static bool
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2478 may_reassociate_p (tree type, enum tree_code code)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2479 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2480 if (FLOAT_TYPE_P (type)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2481 && !flag_unsafe_math_optimizations)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2482 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2483
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2484 return (commutative_tree_code (code)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2485 && associative_tree_code (code));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2486 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2487
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2488 /* If the operation used in STMT is associative and commutative, go through the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2489 tree of the same operations and returns its root. Distance to the root
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2490 is stored in DISTANCE. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2491
111
kono
parents: 67
diff changeset
2492 static gimple *
kono
parents: 67
diff changeset
2493 find_associative_operation_root (gimple *stmt, unsigned *distance)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2494 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2495 tree lhs;
111
kono
parents: 67
diff changeset
2496 gimple *next;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2497 enum tree_code code = gimple_assign_rhs_code (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2498 tree type = TREE_TYPE (gimple_assign_lhs (stmt));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2499 unsigned dist = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2500
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2501 if (!may_reassociate_p (type, code))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2502 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2503
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2504 while (1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2505 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2506 lhs = gimple_assign_lhs (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2507 gcc_assert (TREE_CODE (lhs) == SSA_NAME);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2508
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2509 next = find_use_stmt (&lhs);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2510 if (!next
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2511 || gimple_assign_rhs_code (next) != code)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2512 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2513
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2514 stmt = next;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2515 dist++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2516 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2517
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2518 if (distance)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2519 *distance = dist;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2520 return stmt;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2521 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2522
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2523 /* Returns the common statement in that NAME1 and NAME2 have a use. If there
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2524 is no such statement, returns NULL_TREE. In case the operation used on
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2525 NAME1 and NAME2 is associative and commutative, returns the root of the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2526 tree formed by this operation instead of the statement that uses NAME1 or
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2527 NAME2. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2528
111
kono
parents: 67
diff changeset
2529 static gimple *
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2530 find_common_use_stmt (tree *name1, tree *name2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2531 {
111
kono
parents: 67
diff changeset
2532 gimple *stmt1, *stmt2;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2533
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2534 stmt1 = find_use_stmt (name1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2535 if (!stmt1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2536 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2537
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2538 stmt2 = find_use_stmt (name2);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2539 if (!stmt2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2540 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2541
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2542 if (stmt1 == stmt2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2543 return stmt1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2544
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2545 stmt1 = find_associative_operation_root (stmt1, NULL);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2546 if (!stmt1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2547 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2548 stmt2 = find_associative_operation_root (stmt2, NULL);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2549 if (!stmt2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2550 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2551
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2552 return (stmt1 == stmt2 ? stmt1 : NULL);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2553 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2554
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2555 /* Checks whether R1 and R2 are combined together using CODE, with the result
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2556 in RSLT_TYPE, in order R1 CODE R2 if SWAP is false and in order R2 CODE R1
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2557 if it is true. If CODE is ERROR_MARK, set these values instead. */
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 static bool
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2560 combinable_refs_p (dref r1, dref r2,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2561 enum tree_code *code, bool *swap, tree *rslt_type)
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 enum tree_code acode;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2564 bool aswap;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2565 tree atype;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2566 tree name1, name2;
111
kono
parents: 67
diff changeset
2567 gimple *stmt;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2568
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2569 name1 = name_for_ref (r1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2570 name2 = name_for_ref (r2);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2571 gcc_assert (name1 != NULL_TREE && name2 != NULL_TREE);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2572
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2573 stmt = find_common_use_stmt (&name1, &name2);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2574
111
kono
parents: 67
diff changeset
2575 if (!stmt
kono
parents: 67
diff changeset
2576 /* A simple post-dominance check - make sure the combination
kono
parents: 67
diff changeset
2577 is executed under the same condition as the references. */
kono
parents: 67
diff changeset
2578 || (gimple_bb (stmt) != gimple_bb (r1->stmt)
kono
parents: 67
diff changeset
2579 && gimple_bb (stmt) != gimple_bb (r2->stmt)))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2580 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2581
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2582 acode = gimple_assign_rhs_code (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2583 aswap = (!commutative_tree_code (acode)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2584 && gimple_assign_rhs1 (stmt) != name1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2585 atype = TREE_TYPE (gimple_assign_lhs (stmt));
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 if (*code == ERROR_MARK)
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 *code = acode;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2590 *swap = aswap;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2591 *rslt_type = atype;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2592 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2593 }
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 return (*code == acode
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2596 && *swap == aswap
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2597 && *rslt_type == atype);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2598 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2599
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2600 /* Remove OP from the operation on rhs of STMT, and replace STMT with
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2601 an assignment of the remaining operand. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2602
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2603 static void
111
kono
parents: 67
diff changeset
2604 remove_name_from_operation (gimple *stmt, tree op)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2605 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2606 tree other_op;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2607 gimple_stmt_iterator si;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2608
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2609 gcc_assert (is_gimple_assign (stmt));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2610
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2611 if (gimple_assign_rhs1 (stmt) == op)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2612 other_op = gimple_assign_rhs2 (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2613 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2614 other_op = gimple_assign_rhs1 (stmt);
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 si = gsi_for_stmt (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2617 gimple_assign_set_rhs_from_tree (&si, other_op);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2618
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2619 /* We should not have reallocated STMT. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2620 gcc_assert (gsi_stmt (si) == stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2621
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2622 update_stmt (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2623 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2624
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2625 /* Reassociates the expression in that NAME1 and NAME2 are used so that they
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2626 are combined in a single statement, and returns this statement. */
111
kono
parents: 67
diff changeset
2627
kono
parents: 67
diff changeset
2628 static gimple *
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2629 reassociate_to_the_same_stmt (tree name1, tree name2)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2630 {
111
kono
parents: 67
diff changeset
2631 gimple *stmt1, *stmt2, *root1, *root2, *s1, *s2;
kono
parents: 67
diff changeset
2632 gassign *new_stmt, *tmp_stmt;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2633 tree new_name, tmp_name, var, r1, r2;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2634 unsigned dist1, dist2;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2635 enum tree_code code;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2636 tree type = TREE_TYPE (name1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2637 gimple_stmt_iterator bsi;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2638
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2639 stmt1 = find_use_stmt (&name1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2640 stmt2 = find_use_stmt (&name2);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2641 root1 = find_associative_operation_root (stmt1, &dist1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2642 root2 = find_associative_operation_root (stmt2, &dist2);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2643 code = gimple_assign_rhs_code (stmt1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2644
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2645 gcc_assert (root1 && root2 && root1 == root2
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2646 && code == gimple_assign_rhs_code (stmt2));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2647
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2648 /* Find the root of the nearest expression in that both NAME1 and NAME2
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2649 are used. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2650 r1 = name1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2651 s1 = stmt1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2652 r2 = name2;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2653 s2 = stmt2;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2654
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2655 while (dist1 > dist2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2656 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2657 s1 = find_use_stmt (&r1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2658 r1 = gimple_assign_lhs (s1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2659 dist1--;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2660 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2661 while (dist2 > dist1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2662 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2663 s2 = find_use_stmt (&r2);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2664 r2 = gimple_assign_lhs (s2);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2665 dist2--;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2666 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2667
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2668 while (s1 != s2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2669 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2670 s1 = find_use_stmt (&r1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2671 r1 = gimple_assign_lhs (s1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2672 s2 = find_use_stmt (&r2);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2673 r2 = gimple_assign_lhs (s2);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2674 }
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 /* Remove NAME1 and NAME2 from the statements in that they are used
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2677 currently. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2678 remove_name_from_operation (stmt1, name1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2679 remove_name_from_operation (stmt2, name2);
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 /* Insert the new statement combining NAME1 and NAME2 before S1, and
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2682 combine it with the rhs of S1. */
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2683 var = create_tmp_reg (type, "predreastmp");
111
kono
parents: 67
diff changeset
2684 new_name = make_ssa_name (var);
kono
parents: 67
diff changeset
2685 new_stmt = gimple_build_assign (new_name, code, name1, name2);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2686
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2687 var = create_tmp_reg (type, "predreastmp");
111
kono
parents: 67
diff changeset
2688 tmp_name = make_ssa_name (var);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2689
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2690 /* Rhs of S1 may now be either a binary expression with operation
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2691 CODE, or gimple_val (in case that stmt1 == s1 or stmt2 == s1,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2692 so that name1 or name2 was removed from it). */
111
kono
parents: 67
diff changeset
2693 tmp_stmt = gimple_build_assign (tmp_name, gimple_assign_rhs_code (s1),
kono
parents: 67
diff changeset
2694 gimple_assign_rhs1 (s1),
kono
parents: 67
diff changeset
2695 gimple_assign_rhs2 (s1));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2696
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2697 bsi = gsi_for_stmt (s1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2698 gimple_assign_set_rhs_with_ops (&bsi, code, new_name, tmp_name);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2699 s1 = gsi_stmt (bsi);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2700 update_stmt (s1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2701
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2702 gsi_insert_before (&bsi, new_stmt, GSI_SAME_STMT);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2703 gsi_insert_before (&bsi, tmp_stmt, GSI_SAME_STMT);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2704
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2705 return new_stmt;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2706 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2707
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2708 /* Returns the statement that combines references R1 and R2. In case R1
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2709 and R2 are not used in the same statement, but they are used with an
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2710 associative and commutative operation in the same expression, reassociate
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2711 the expression so that they are used in the same statement. */
111
kono
parents: 67
diff changeset
2712
kono
parents: 67
diff changeset
2713 static gimple *
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2714 stmt_combining_refs (dref r1, dref r2)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2715 {
111
kono
parents: 67
diff changeset
2716 gimple *stmt1, *stmt2;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2717 tree name1 = name_for_ref (r1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2718 tree name2 = name_for_ref (r2);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2719
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2720 stmt1 = find_use_stmt (&name1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2721 stmt2 = find_use_stmt (&name2);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2722 if (stmt1 == stmt2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2723 return stmt1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2724
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2725 return reassociate_to_the_same_stmt (name1, name2);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2726 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2727
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2728 /* Tries to combine chains CH1 and CH2 together. If this succeeds, the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2729 description of the new chain is returned, otherwise we return NULL. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2730
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2731 static chain_p
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2732 combine_chains (chain_p ch1, chain_p ch2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2733 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2734 dref r1, r2, nw;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2735 enum tree_code op = ERROR_MARK;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2736 bool swap = false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2737 chain_p new_chain;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2738 unsigned i;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2739 tree rslt_type = NULL_TREE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2740
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2741 if (ch1 == ch2)
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2742 return NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2743 if (ch1->length != ch2->length)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2744 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2745
111
kono
parents: 67
diff changeset
2746 if (ch1->refs.length () != ch2->refs.length ())
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2747 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2748
111
kono
parents: 67
diff changeset
2749 for (i = 0; (ch1->refs.iterate (i, &r1)
kono
parents: 67
diff changeset
2750 && ch2->refs.iterate (i, &r2)); i++)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2751 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2752 if (r1->distance != r2->distance)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2753 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2754
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2755 if (!combinable_refs_p (r1, r2, &op, &swap, &rslt_type))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2756 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2757 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2758
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2759 if (swap)
111
kono
parents: 67
diff changeset
2760 std::swap (ch1, ch2);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2761
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2762 new_chain = XCNEW (struct chain);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2763 new_chain->type = CT_COMBINATION;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2764 new_chain->op = op;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2765 new_chain->ch1 = ch1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2766 new_chain->ch2 = ch2;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2767 new_chain->rslt_type = rslt_type;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2768 new_chain->length = ch1->length;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2769
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2770 for (i = 0; (ch1->refs.iterate (i, &r1)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2771 && ch2->refs.iterate (i, &r2)); i++)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2772 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2773 nw = XCNEW (class dref_d);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2774 nw->stmt = stmt_combining_refs (r1, r2);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2775 nw->distance = r1->distance;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2776
111
kono
parents: 67
diff changeset
2777 new_chain->refs.safe_push (nw);
kono
parents: 67
diff changeset
2778 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2779
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2780 ch1->combined = true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2781 ch2->combined = true;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2782 return new_chain;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2783 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2784
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2785 /* Recursively update position information of all offspring chains to ROOT
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2786 chain's position information. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2787
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2788 static void
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2789 update_pos_for_combined_chains (chain_p root)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2790 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2791 chain_p ch1 = root->ch1, ch2 = root->ch2;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2792 dref ref, ref1, ref2;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2793 for (unsigned j = 0; (root->refs.iterate (j, &ref)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2794 && ch1->refs.iterate (j, &ref1)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2795 && ch2->refs.iterate (j, &ref2)); ++j)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2796 ref1->pos = ref2->pos = ref->pos;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2797
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2798 if (ch1->type == CT_COMBINATION)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2799 update_pos_for_combined_chains (ch1);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2800 if (ch2->type == CT_COMBINATION)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2801 update_pos_for_combined_chains (ch2);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2802 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2803
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2804 /* Returns true if statement S1 dominates statement S2. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2805
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2806 static bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2807 pcom_stmt_dominates_stmt_p (gimple *s1, gimple *s2)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2808 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2809 basic_block bb1 = gimple_bb (s1), bb2 = gimple_bb (s2);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2810
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2811 if (!bb1 || s1 == s2)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2812 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2813
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2814 if (bb1 == bb2)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2815 return gimple_uid (s1) < gimple_uid (s2);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2816
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2817 return dominated_by_p (CDI_DOMINATORS, bb2, bb1);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2818 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2819
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2820 /* Try to combine the CHAINS in LOOP. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2821
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2822 static void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2823 try_combine_chains (class loop *loop, vec<chain_p> *chains)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2824 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2825 unsigned i, j;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2826 chain_p ch1, ch2, cch;
111
kono
parents: 67
diff changeset
2827 auto_vec<chain_p> worklist;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2828 bool combined_p = false;
111
kono
parents: 67
diff changeset
2829
kono
parents: 67
diff changeset
2830 FOR_EACH_VEC_ELT (*chains, i, ch1)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2831 if (chain_can_be_combined_p (ch1))
111
kono
parents: 67
diff changeset
2832 worklist.safe_push (ch1);
kono
parents: 67
diff changeset
2833
kono
parents: 67
diff changeset
2834 while (!worklist.is_empty ())
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2835 {
111
kono
parents: 67
diff changeset
2836 ch1 = worklist.pop ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2837 if (!chain_can_be_combined_p (ch1))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2838 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2839
111
kono
parents: 67
diff changeset
2840 FOR_EACH_VEC_ELT (*chains, j, ch2)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2841 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2842 if (!chain_can_be_combined_p (ch2))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2843 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2844
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2845 cch = combine_chains (ch1, ch2);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2846 if (cch)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2847 {
111
kono
parents: 67
diff changeset
2848 worklist.safe_push (cch);
kono
parents: 67
diff changeset
2849 chains->safe_push (cch);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2850 combined_p = true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2851 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2852 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2853 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2854 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2855 if (!combined_p)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2856 return;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2857
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2858 /* Setup UID for all statements in dominance order. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2859 basic_block *bbs = get_loop_body_in_dom_order (loop);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2860 renumber_gimple_stmt_uids_in_blocks (bbs, loop->num_nodes);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2861 free (bbs);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2862
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2863 /* Re-association in combined chains may generate statements different to
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2864 order of references of the original chain. We need to keep references
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2865 of combined chain in dominance order so that all uses will be inserted
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2866 after definitions. Note:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2867 A) This is necessary for all combined chains.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2868 B) This is only necessary for ZERO distance references because other
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2869 references inherit value from loop carried PHIs.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2870
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2871 We first update position information for all combined chains. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2872 dref ref;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2873 for (i = 0; chains->iterate (i, &ch1); ++i)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2874 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2875 if (ch1->type != CT_COMBINATION || ch1->combined)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2876 continue;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2877
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2878 for (j = 0; ch1->refs.iterate (j, &ref); ++j)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2879 ref->pos = gimple_uid (ref->stmt);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2880
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2881 update_pos_for_combined_chains (ch1);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2882 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2883 /* Then sort references according to newly updated position information. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2884 for (i = 0; chains->iterate (i, &ch1); ++i)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2885 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2886 if (ch1->type != CT_COMBINATION && !ch1->combined)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2887 continue;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2888
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2889 /* Find the first reference with non-ZERO distance. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2890 if (ch1->length == 0)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2891 j = ch1->refs.length();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2892 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2893 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2894 for (j = 0; ch1->refs.iterate (j, &ref); ++j)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2895 if (ref->distance != 0)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2896 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2897 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2898
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2899 /* Sort all ZERO distance references by position. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2900 qsort (&ch1->refs[0], j, sizeof (ch1->refs[0]), order_drefs_by_pos);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2901
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2902 if (ch1->combined)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2903 continue;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2904
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2905 /* For ZERO length chain, has_max_use_after must be true since root
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2906 combined stmt must dominates others. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2907 if (ch1->length == 0)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2908 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2909 ch1->has_max_use_after = true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2910 continue;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2911 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2912 /* Check if there is use at max distance after root for combined chains
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2913 and set flag accordingly. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2914 ch1->has_max_use_after = false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2915 gimple *root_stmt = get_chain_root (ch1)->stmt;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2916 for (j = 1; ch1->refs.iterate (j, &ref); ++j)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2917 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2918 if (ref->distance == ch1->length
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2919 && !pcom_stmt_dominates_stmt_p (ref->stmt, root_stmt))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2920 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2921 ch1->has_max_use_after = true;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2922 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2923 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2924 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2925 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2926 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2927
111
kono
parents: 67
diff changeset
2928 /* Prepare initializers for store elimination CHAIN in LOOP. Returns false
kono
parents: 67
diff changeset
2929 if this is impossible because one of these initializers may trap, true
kono
parents: 67
diff changeset
2930 otherwise. */
kono
parents: 67
diff changeset
2931
kono
parents: 67
diff changeset
2932 static bool
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2933 prepare_initializers_chain_store_elim (class loop *loop, chain_p chain)
111
kono
parents: 67
diff changeset
2934 {
kono
parents: 67
diff changeset
2935 unsigned i, n = chain->length;
kono
parents: 67
diff changeset
2936
kono
parents: 67
diff changeset
2937 /* For now we can't eliminate stores if some of them are conditional
kono
parents: 67
diff changeset
2938 executed. */
kono
parents: 67
diff changeset
2939 if (!chain->all_always_accessed)
kono
parents: 67
diff changeset
2940 return false;
kono
parents: 67
diff changeset
2941
kono
parents: 67
diff changeset
2942 /* Nothing to intialize for intra-iteration store elimination. */
kono
parents: 67
diff changeset
2943 if (n == 0 && chain->type == CT_STORE_STORE)
kono
parents: 67
diff changeset
2944 return true;
kono
parents: 67
diff changeset
2945
kono
parents: 67
diff changeset
2946 /* For store elimination chain, there is nothing to initialize if stores
kono
parents: 67
diff changeset
2947 to be eliminated only store loop invariant values into memory. */
kono
parents: 67
diff changeset
2948 if (chain->type == CT_STORE_STORE
kono
parents: 67
diff changeset
2949 && is_inv_store_elimination_chain (loop, chain))
kono
parents: 67
diff changeset
2950 {
kono
parents: 67
diff changeset
2951 chain->inv_store_elimination = true;
kono
parents: 67
diff changeset
2952 return true;
kono
parents: 67
diff changeset
2953 }
kono
parents: 67
diff changeset
2954
kono
parents: 67
diff changeset
2955 chain->inits.create (n);
kono
parents: 67
diff changeset
2956 chain->inits.safe_grow_cleared (n);
kono
parents: 67
diff changeset
2957
kono
parents: 67
diff changeset
2958 /* For store eliminatin chain like below:
kono
parents: 67
diff changeset
2959
kono
parents: 67
diff changeset
2960 for (i = 0; i < len; i++)
kono
parents: 67
diff changeset
2961 {
kono
parents: 67
diff changeset
2962 a[i] = 1;
kono
parents: 67
diff changeset
2963 // a[i + 1] = ...
kono
parents: 67
diff changeset
2964 a[i + 2] = 3;
kono
parents: 67
diff changeset
2965 }
kono
parents: 67
diff changeset
2966
kono
parents: 67
diff changeset
2967 store to a[i + 1] is missed in loop body, it acts like bubbles. The
kono
parents: 67
diff changeset
2968 content of a[i + 1] remain the same if the loop iterates fewer times
kono
parents: 67
diff changeset
2969 than chain->length. We need to set up root variables for such stores
kono
parents: 67
diff changeset
2970 by loading from memory before loop. Note we only need to load bubble
kono
parents: 67
diff changeset
2971 elements because loop body is guaranteed to be executed at least once
kono
parents: 67
diff changeset
2972 after loop's preheader edge. */
kono
parents: 67
diff changeset
2973 auto_vec<bool> bubbles;
kono
parents: 67
diff changeset
2974 bubbles.safe_grow_cleared (n + 1);
kono
parents: 67
diff changeset
2975 for (i = 0; i < chain->refs.length (); i++)
kono
parents: 67
diff changeset
2976 bubbles[chain->refs[i]->distance] = true;
kono
parents: 67
diff changeset
2977
kono
parents: 67
diff changeset
2978 struct data_reference *dr = get_chain_root (chain)->ref;
kono
parents: 67
diff changeset
2979 for (i = 0; i < n; i++)
kono
parents: 67
diff changeset
2980 {
kono
parents: 67
diff changeset
2981 if (bubbles[i])
kono
parents: 67
diff changeset
2982 continue;
kono
parents: 67
diff changeset
2983
kono
parents: 67
diff changeset
2984 gimple_seq stmts = NULL;
kono
parents: 67
diff changeset
2985
kono
parents: 67
diff changeset
2986 tree init = ref_at_iteration (dr, (int) 0 - i, &stmts);
kono
parents: 67
diff changeset
2987 if (stmts)
kono
parents: 67
diff changeset
2988 gimple_seq_add_seq_without_update (&chain->init_seq, stmts);
kono
parents: 67
diff changeset
2989
kono
parents: 67
diff changeset
2990 chain->inits[i] = init;
kono
parents: 67
diff changeset
2991 }
kono
parents: 67
diff changeset
2992
kono
parents: 67
diff changeset
2993 return true;
kono
parents: 67
diff changeset
2994 }
kono
parents: 67
diff changeset
2995
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2996 /* Prepare initializers for CHAIN in LOOP. Returns false if this is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2997 impossible because one of these initializers may trap, true otherwise. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2998
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2999 static bool
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3000 prepare_initializers_chain (class loop *loop, chain_p chain)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3001 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3002 unsigned i, n = (chain->type == CT_INVARIANT) ? 1 : chain->length;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3003 struct data_reference *dr = get_chain_root (chain)->ref;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3004 tree init;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3005 dref laref;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3006 edge entry = loop_preheader_edge (loop);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3007
111
kono
parents: 67
diff changeset
3008 if (chain->type == CT_STORE_STORE)
kono
parents: 67
diff changeset
3009 return prepare_initializers_chain_store_elim (loop, chain);
kono
parents: 67
diff changeset
3010
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3011 /* Find the initializers for the variables, and check that they cannot
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3012 trap. */
111
kono
parents: 67
diff changeset
3013 chain->inits.create (n);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3014 for (i = 0; i < n; i++)
111
kono
parents: 67
diff changeset
3015 chain->inits.quick_push (NULL_TREE);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3016
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3017 /* If we have replaced some looparound phi nodes, use their initializers
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3018 instead of creating our own. */
111
kono
parents: 67
diff changeset
3019 FOR_EACH_VEC_ELT (chain->refs, i, laref)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3020 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3021 if (gimple_code (laref->stmt) != GIMPLE_PHI)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3022 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3023
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3024 gcc_assert (laref->distance > 0);
111
kono
parents: 67
diff changeset
3025 chain->inits[n - laref->distance]
kono
parents: 67
diff changeset
3026 = PHI_ARG_DEF_FROM_EDGE (laref->stmt, entry);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3027 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3028
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3029 for (i = 0; i < n; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3030 {
111
kono
parents: 67
diff changeset
3031 gimple_seq stmts = NULL;
kono
parents: 67
diff changeset
3032
kono
parents: 67
diff changeset
3033 if (chain->inits[i] != NULL_TREE)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3034 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3035
111
kono
parents: 67
diff changeset
3036 init = ref_at_iteration (dr, (int) i - n, &stmts);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3037 if (!chain->all_always_accessed && tree_could_trap_p (init))
111
kono
parents: 67
diff changeset
3038 {
kono
parents: 67
diff changeset
3039 gimple_seq_discard (stmts);
kono
parents: 67
diff changeset
3040 return false;
kono
parents: 67
diff changeset
3041 }
kono
parents: 67
diff changeset
3042
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3043 if (stmts)
111
kono
parents: 67
diff changeset
3044 gimple_seq_add_seq_without_update (&chain->init_seq, stmts);
kono
parents: 67
diff changeset
3045
kono
parents: 67
diff changeset
3046 chain->inits[i] = init;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3047 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3048
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3049 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3050 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3051
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3052 /* Prepare initializers for CHAINS in LOOP, and free chains that cannot
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3053 be used because the initializers might trap. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3054
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3055 static void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3056 prepare_initializers (class loop *loop, vec<chain_p> chains)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3057 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3058 chain_p chain;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3059 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3060
111
kono
parents: 67
diff changeset
3061 for (i = 0; i < chains.length (); )
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3062 {
111
kono
parents: 67
diff changeset
3063 chain = chains[i];
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3064 if (prepare_initializers_chain (loop, chain))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3065 i++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3066 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3067 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3068 release_chain (chain);
111
kono
parents: 67
diff changeset
3069 chains.unordered_remove (i);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3070 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3071 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3072 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3073
111
kono
parents: 67
diff changeset
3074 /* Generates finalizer memory references for CHAIN in LOOP. Returns true
kono
parents: 67
diff changeset
3075 if finalizer code for CHAIN can be generated, otherwise false. */
kono
parents: 67
diff changeset
3076
kono
parents: 67
diff changeset
3077 static bool
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3078 prepare_finalizers_chain (class loop *loop, chain_p chain)
111
kono
parents: 67
diff changeset
3079 {
kono
parents: 67
diff changeset
3080 unsigned i, n = chain->length;
kono
parents: 67
diff changeset
3081 struct data_reference *dr = get_chain_root (chain)->ref;
kono
parents: 67
diff changeset
3082 tree fini, niters = number_of_latch_executions (loop);
kono
parents: 67
diff changeset
3083
kono
parents: 67
diff changeset
3084 /* For now we can't eliminate stores if some of them are conditional
kono
parents: 67
diff changeset
3085 executed. */
kono
parents: 67
diff changeset
3086 if (!chain->all_always_accessed)
kono
parents: 67
diff changeset
3087 return false;
kono
parents: 67
diff changeset
3088
kono
parents: 67
diff changeset
3089 chain->finis.create (n);
kono
parents: 67
diff changeset
3090 for (i = 0; i < n; i++)
kono
parents: 67
diff changeset
3091 chain->finis.quick_push (NULL_TREE);
kono
parents: 67
diff changeset
3092
kono
parents: 67
diff changeset
3093 /* We never use looparound phi node for store elimination chains. */
kono
parents: 67
diff changeset
3094
kono
parents: 67
diff changeset
3095 /* Find the finalizers for the variables, and check that they cannot
kono
parents: 67
diff changeset
3096 trap. */
kono
parents: 67
diff changeset
3097 for (i = 0; i < n; i++)
kono
parents: 67
diff changeset
3098 {
kono
parents: 67
diff changeset
3099 gimple_seq stmts = NULL;
kono
parents: 67
diff changeset
3100 gcc_assert (chain->finis[i] == NULL_TREE);
kono
parents: 67
diff changeset
3101
kono
parents: 67
diff changeset
3102 if (TREE_CODE (niters) != INTEGER_CST && TREE_CODE (niters) != SSA_NAME)
kono
parents: 67
diff changeset
3103 {
kono
parents: 67
diff changeset
3104 niters = unshare_expr (niters);
kono
parents: 67
diff changeset
3105 niters = force_gimple_operand (niters, &stmts, true, NULL);
kono
parents: 67
diff changeset
3106 if (stmts)
kono
parents: 67
diff changeset
3107 {
kono
parents: 67
diff changeset
3108 gimple_seq_add_seq_without_update (&chain->fini_seq, stmts);
kono
parents: 67
diff changeset
3109 stmts = NULL;
kono
parents: 67
diff changeset
3110 }
kono
parents: 67
diff changeset
3111 }
kono
parents: 67
diff changeset
3112 fini = ref_at_iteration (dr, (int) 0 - i, &stmts, niters);
kono
parents: 67
diff changeset
3113 if (stmts)
kono
parents: 67
diff changeset
3114 gimple_seq_add_seq_without_update (&chain->fini_seq, stmts);
kono
parents: 67
diff changeset
3115
kono
parents: 67
diff changeset
3116 chain->finis[i] = fini;
kono
parents: 67
diff changeset
3117 }
kono
parents: 67
diff changeset
3118
kono
parents: 67
diff changeset
3119 return true;
kono
parents: 67
diff changeset
3120 }
kono
parents: 67
diff changeset
3121
kono
parents: 67
diff changeset
3122 /* Generates finalizer memory reference for CHAINS in LOOP. Returns true
kono
parents: 67
diff changeset
3123 if finalizer code generation for CHAINS breaks loop closed ssa form. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3124
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3125 static bool
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3126 prepare_finalizers (class loop *loop, vec<chain_p> chains)
111
kono
parents: 67
diff changeset
3127 {
kono
parents: 67
diff changeset
3128 chain_p chain;
kono
parents: 67
diff changeset
3129 unsigned i;
kono
parents: 67
diff changeset
3130 bool loop_closed_ssa = false;
kono
parents: 67
diff changeset
3131
kono
parents: 67
diff changeset
3132 for (i = 0; i < chains.length ();)
kono
parents: 67
diff changeset
3133 {
kono
parents: 67
diff changeset
3134 chain = chains[i];
kono
parents: 67
diff changeset
3135
kono
parents: 67
diff changeset
3136 /* Finalizer is only necessary for inter-iteration store elimination
kono
parents: 67
diff changeset
3137 chains. */
kono
parents: 67
diff changeset
3138 if (chain->length == 0 || chain->type != CT_STORE_STORE)
kono
parents: 67
diff changeset
3139 {
kono
parents: 67
diff changeset
3140 i++;
kono
parents: 67
diff changeset
3141 continue;
kono
parents: 67
diff changeset
3142 }
kono
parents: 67
diff changeset
3143
kono
parents: 67
diff changeset
3144 if (prepare_finalizers_chain (loop, chain))
kono
parents: 67
diff changeset
3145 {
kono
parents: 67
diff changeset
3146 i++;
kono
parents: 67
diff changeset
3147 /* Be conservative, assume loop closed ssa form is corrupted
kono
parents: 67
diff changeset
3148 by store-store chain. Though it's not always the case if
kono
parents: 67
diff changeset
3149 eliminated stores only store loop invariant values into
kono
parents: 67
diff changeset
3150 memory. */
kono
parents: 67
diff changeset
3151 loop_closed_ssa = true;
kono
parents: 67
diff changeset
3152 }
kono
parents: 67
diff changeset
3153 else
kono
parents: 67
diff changeset
3154 {
kono
parents: 67
diff changeset
3155 release_chain (chain);
kono
parents: 67
diff changeset
3156 chains.unordered_remove (i);
kono
parents: 67
diff changeset
3157 }
kono
parents: 67
diff changeset
3158 }
kono
parents: 67
diff changeset
3159 return loop_closed_ssa;
kono
parents: 67
diff changeset
3160 }
kono
parents: 67
diff changeset
3161
kono
parents: 67
diff changeset
3162 /* Insert all initializing gimple stmts into loop's entry edge. */
kono
parents: 67
diff changeset
3163
kono
parents: 67
diff changeset
3164 static void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3165 insert_init_seqs (class loop *loop, vec<chain_p> chains)
111
kono
parents: 67
diff changeset
3166 {
kono
parents: 67
diff changeset
3167 unsigned i;
kono
parents: 67
diff changeset
3168 edge entry = loop_preheader_edge (loop);
kono
parents: 67
diff changeset
3169
kono
parents: 67
diff changeset
3170 for (i = 0; i < chains.length (); ++i)
kono
parents: 67
diff changeset
3171 if (chains[i]->init_seq)
kono
parents: 67
diff changeset
3172 {
kono
parents: 67
diff changeset
3173 gsi_insert_seq_on_edge_immediate (entry, chains[i]->init_seq);
kono
parents: 67
diff changeset
3174 chains[i]->init_seq = NULL;
kono
parents: 67
diff changeset
3175 }
kono
parents: 67
diff changeset
3176 }
kono
parents: 67
diff changeset
3177
kono
parents: 67
diff changeset
3178 /* Performs predictive commoning for LOOP. Sets bit 1<<0 of return value
kono
parents: 67
diff changeset
3179 if LOOP was unrolled; Sets bit 1<<1 of return value if loop closed ssa
kono
parents: 67
diff changeset
3180 form was corrupted. */
kono
parents: 67
diff changeset
3181
kono
parents: 67
diff changeset
3182 static unsigned
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3183 tree_predictive_commoning_loop (class loop *loop)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3184 {
111
kono
parents: 67
diff changeset
3185 vec<data_reference_p> datarefs;
kono
parents: 67
diff changeset
3186 vec<ddr_p> dependences;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3187 struct component *components;
111
kono
parents: 67
diff changeset
3188 vec<chain_p> chains = vNULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3189 unsigned unroll_factor;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3190 class tree_niter_desc desc;
111
kono
parents: 67
diff changeset
3191 bool unroll = false, loop_closed_ssa = false;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3192 edge exit;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3193
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3194 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3195 fprintf (dump_file, "Processing loop %d\n", loop->num);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3196
111
kono
parents: 67
diff changeset
3197 /* Nothing for predicitive commoning if loop only iterates 1 time. */
kono
parents: 67
diff changeset
3198 if (get_max_loop_iterations_int (loop) == 0)
kono
parents: 67
diff changeset
3199 {
kono
parents: 67
diff changeset
3200 if (dump_file && (dump_flags & TDF_DETAILS))
kono
parents: 67
diff changeset
3201 fprintf (dump_file, "Loop iterates only 1 time, nothing to do.\n");
kono
parents: 67
diff changeset
3202
kono
parents: 67
diff changeset
3203 return 0;
kono
parents: 67
diff changeset
3204 }
kono
parents: 67
diff changeset
3205
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3206 /* Find the data references and split them into components according to their
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3207 dependence relations. */
111
kono
parents: 67
diff changeset
3208 auto_vec<loop_p, 3> loop_nest;
kono
parents: 67
diff changeset
3209 dependences.create (10);
kono
parents: 67
diff changeset
3210 datarefs.create (10);
kono
parents: 67
diff changeset
3211 if (! compute_data_dependences_for_loop (loop, true, &loop_nest, &datarefs,
kono
parents: 67
diff changeset
3212 &dependences))
kono
parents: 67
diff changeset
3213 {
kono
parents: 67
diff changeset
3214 if (dump_file && (dump_flags & TDF_DETAILS))
kono
parents: 67
diff changeset
3215 fprintf (dump_file, "Cannot analyze data dependencies\n");
kono
parents: 67
diff changeset
3216 free_data_refs (datarefs);
kono
parents: 67
diff changeset
3217 free_dependence_relations (dependences);
kono
parents: 67
diff changeset
3218 return 0;
kono
parents: 67
diff changeset
3219 }
kono
parents: 67
diff changeset
3220
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3221 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3222 dump_data_dependence_relations (dump_file, dependences);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3223
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3224 components = split_data_refs_to_components (loop, datarefs, dependences);
111
kono
parents: 67
diff changeset
3225 loop_nest.release ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3226 free_dependence_relations (dependences);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3227 if (!components)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3228 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3229 free_data_refs (datarefs);
111
kono
parents: 67
diff changeset
3230 free_affine_expand_cache (&name_expansions);
kono
parents: 67
diff changeset
3231 return 0;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3232 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3233
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3234 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3235 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3236 fprintf (dump_file, "Initial state:\n\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3237 dump_components (dump_file, components);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3238 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3239
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3240 /* Find the suitable components and split them into chains. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3241 components = filter_suitable_components (loop, components);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3242
111
kono
parents: 67
diff changeset
3243 auto_bitmap tmp_vars;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3244 looparound_phis = BITMAP_ALLOC (NULL);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3245 determine_roots (loop, components, &chains);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3246 release_components (components);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3247
111
kono
parents: 67
diff changeset
3248 if (!chains.exists ())
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3249 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3250 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3251 fprintf (dump_file,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3252 "Predictive commoning failed: no suitable chains\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3253 goto end;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3254 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3255 prepare_initializers (loop, chains);
111
kono
parents: 67
diff changeset
3256 loop_closed_ssa = prepare_finalizers (loop, chains);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3257
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3258 /* Try to combine the chains that are always worked with together. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3259 try_combine_chains (loop, &chains);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3260
111
kono
parents: 67
diff changeset
3261 insert_init_seqs (loop, chains);
kono
parents: 67
diff changeset
3262
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3263 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3264 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3265 fprintf (dump_file, "Before commoning:\n\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3266 dump_chains (dump_file, chains);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3267 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3268
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3269 /* Determine the unroll factor, and if the loop should be unrolled, ensure
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3270 that its number of iterations is divisible by the factor. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3271 unroll_factor = determine_unroll_factor (chains);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3272 scev_reset ();
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
3273 unroll = (unroll_factor > 1
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
3274 && can_unroll_loop_p (loop, unroll_factor, &desc));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3275 exit = single_dom_exit (loop);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3276
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3277 /* Execute the predictive commoning transformations, and possibly unroll the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3278 loop. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3279 if (unroll)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3280 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3281 struct epcc_data dta;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3282
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3283 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3284 fprintf (dump_file, "Unrolling %u times.\n", unroll_factor);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3285
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3286 dta.chains = chains;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3287 dta.tmp_vars = tmp_vars;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
3288
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3289 update_ssa (TODO_update_ssa_only_virtuals);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3290
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3291 /* Cfg manipulations performed in tree_transform_and_unroll_loop before
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3292 execute_pred_commoning_cbck is called may cause phi nodes to be
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3293 reallocated, which is a problem since CHAINS may point to these
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3294 statements. To fix this, we store the ssa names defined by the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3295 phi nodes here instead of the phi nodes themselves, and restore
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3296 the phi nodes in execute_pred_commoning_cbck. A bit hacky. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3297 replace_phis_by_defined_names (chains);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3298
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3299 tree_transform_and_unroll_loop (loop, unroll_factor, exit, &desc,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3300 execute_pred_commoning_cbck, &dta);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3301 eliminate_temp_copies (loop, tmp_vars);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3302 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3303 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3304 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3305 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3306 fprintf (dump_file,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3307 "Executing predictive commoning without unrolling.\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3308 execute_pred_commoning (loop, chains, tmp_vars);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3309 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3310
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3311 end: ;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3312 release_chains (chains);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3313 free_data_refs (datarefs);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3314 BITMAP_FREE (looparound_phis);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3315
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3316 free_affine_expand_cache (&name_expansions);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3317
111
kono
parents: 67
diff changeset
3318 return (unroll ? 1 : 0) | (loop_closed_ssa ? 2 : 0);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3319 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3320
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3321 /* Runs predictive commoning. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3322
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3323 unsigned
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3324 tree_predictive_commoning (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3325 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3326 class loop *loop;
111
kono
parents: 67
diff changeset
3327 unsigned ret = 0, changed = 0;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3328
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3329 initialize_original_copy_tables ();
111
kono
parents: 67
diff changeset
3330 FOR_EACH_LOOP (loop, LI_ONLY_INNERMOST)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3331 if (optimize_loop_for_speed_p (loop))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3332 {
111
kono
parents: 67
diff changeset
3333 changed |= tree_predictive_commoning_loop (loop);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3334 }
111
kono
parents: 67
diff changeset
3335 free_original_copy_tables ();
kono
parents: 67
diff changeset
3336
kono
parents: 67
diff changeset
3337 if (changed > 0)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3338 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3339 scev_reset ();
111
kono
parents: 67
diff changeset
3340
kono
parents: 67
diff changeset
3341 if (changed > 1)
kono
parents: 67
diff changeset
3342 rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
kono
parents: 67
diff changeset
3343
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3344 ret = TODO_cleanup_cfg;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3345 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3346
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3347 return ret;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3348 }
111
kono
parents: 67
diff changeset
3349
kono
parents: 67
diff changeset
3350 /* Predictive commoning Pass. */
kono
parents: 67
diff changeset
3351
kono
parents: 67
diff changeset
3352 static unsigned
kono
parents: 67
diff changeset
3353 run_tree_predictive_commoning (struct function *fun)
kono
parents: 67
diff changeset
3354 {
kono
parents: 67
diff changeset
3355 if (number_of_loops (fun) <= 1)
kono
parents: 67
diff changeset
3356 return 0;
kono
parents: 67
diff changeset
3357
kono
parents: 67
diff changeset
3358 return tree_predictive_commoning ();
kono
parents: 67
diff changeset
3359 }
kono
parents: 67
diff changeset
3360
kono
parents: 67
diff changeset
3361 namespace {
kono
parents: 67
diff changeset
3362
kono
parents: 67
diff changeset
3363 const pass_data pass_data_predcom =
kono
parents: 67
diff changeset
3364 {
kono
parents: 67
diff changeset
3365 GIMPLE_PASS, /* type */
kono
parents: 67
diff changeset
3366 "pcom", /* name */
kono
parents: 67
diff changeset
3367 OPTGROUP_LOOP, /* optinfo_flags */
kono
parents: 67
diff changeset
3368 TV_PREDCOM, /* tv_id */
kono
parents: 67
diff changeset
3369 PROP_cfg, /* properties_required */
kono
parents: 67
diff changeset
3370 0, /* properties_provided */
kono
parents: 67
diff changeset
3371 0, /* properties_destroyed */
kono
parents: 67
diff changeset
3372 0, /* todo_flags_start */
kono
parents: 67
diff changeset
3373 TODO_update_ssa_only_virtuals, /* todo_flags_finish */
kono
parents: 67
diff changeset
3374 };
kono
parents: 67
diff changeset
3375
kono
parents: 67
diff changeset
3376 class pass_predcom : public gimple_opt_pass
kono
parents: 67
diff changeset
3377 {
kono
parents: 67
diff changeset
3378 public:
kono
parents: 67
diff changeset
3379 pass_predcom (gcc::context *ctxt)
kono
parents: 67
diff changeset
3380 : gimple_opt_pass (pass_data_predcom, ctxt)
kono
parents: 67
diff changeset
3381 {}
kono
parents: 67
diff changeset
3382
kono
parents: 67
diff changeset
3383 /* opt_pass methods: */
kono
parents: 67
diff changeset
3384 virtual bool gate (function *) { return flag_predictive_commoning != 0; }
kono
parents: 67
diff changeset
3385 virtual unsigned int execute (function *fun)
kono
parents: 67
diff changeset
3386 {
kono
parents: 67
diff changeset
3387 return run_tree_predictive_commoning (fun);
kono
parents: 67
diff changeset
3388 }
kono
parents: 67
diff changeset
3389
kono
parents: 67
diff changeset
3390 }; // class pass_predcom
kono
parents: 67
diff changeset
3391
kono
parents: 67
diff changeset
3392 } // anon namespace
kono
parents: 67
diff changeset
3393
kono
parents: 67
diff changeset
3394 gimple_opt_pass *
kono
parents: 67
diff changeset
3395 make_pass_predcom (gcc::context *ctxt)
kono
parents: 67
diff changeset
3396 {
kono
parents: 67
diff changeset
3397 return new pass_predcom (ctxt);
kono
parents: 67
diff changeset
3398 }
kono
parents: 67
diff changeset
3399
kono
parents: 67
diff changeset
3400