annotate gcc/tree-predcom.c @ 128:fe568345ddd5

fix CbC-example
author mir3636
date Wed, 11 Apr 2018 19:32:28 +0900
parents 04ced10e8804
children 84e7813d76e9
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.
111
kono
parents: 67
diff changeset
2 Copyright (C) 2005-2017 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
kono
parents: 67
diff changeset
195 TODO: For now, we don't support store-store chains in multi-exit loops. We
kono
parents: 67
diff changeset
196 force to not unroll in case of store-store chain even if other chains might
kono
parents: 67
diff changeset
197 ask for unroll.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
198
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
199 Predictive commoning can be generalized for arbitrary computations (not
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
200 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
201 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
202
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
203 #include "config.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
204 #include "system.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
205 #include "coretypes.h"
111
kono
parents: 67
diff changeset
206 #include "backend.h"
kono
parents: 67
diff changeset
207 #include "rtl.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
208 #include "tree.h"
111
kono
parents: 67
diff changeset
209 #include "gimple.h"
kono
parents: 67
diff changeset
210 #include "predict.h"
kono
parents: 67
diff changeset
211 #include "tree-pass.h"
kono
parents: 67
diff changeset
212 #include "ssa.h"
kono
parents: 67
diff changeset
213 #include "gimple-pretty-print.h"
kono
parents: 67
diff changeset
214 #include "alias.h"
kono
parents: 67
diff changeset
215 #include "fold-const.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
216 #include "cfgloop.h"
111
kono
parents: 67
diff changeset
217 #include "tree-eh.h"
kono
parents: 67
diff changeset
218 #include "gimplify.h"
kono
parents: 67
diff changeset
219 #include "gimple-iterator.h"
kono
parents: 67
diff changeset
220 #include "gimplify-me.h"
kono
parents: 67
diff changeset
221 #include "tree-ssa-loop-ivopts.h"
kono
parents: 67
diff changeset
222 #include "tree-ssa-loop-manip.h"
kono
parents: 67
diff changeset
223 #include "tree-ssa-loop-niter.h"
kono
parents: 67
diff changeset
224 #include "tree-ssa-loop.h"
kono
parents: 67
diff changeset
225 #include "tree-into-ssa.h"
kono
parents: 67
diff changeset
226 #include "tree-dfa.h"
kono
parents: 67
diff changeset
227 #include "tree-ssa.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
228 #include "tree-data-ref.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
229 #include "tree-scalar-evolution.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
230 #include "params.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
231 #include "tree-affine.h"
111
kono
parents: 67
diff changeset
232 #include "builtins.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
233
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
234 /* The maximum number of iterations between the considered memory
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
235 references. */
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 #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
238
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
239 /* 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
240 loop iterations). */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
241
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
242 typedef struct dref_d
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
243 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
244 /* The reference itself. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
245 struct data_reference *ref;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
246
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
247 /* The statement in that the reference appears. */
111
kono
parents: 67
diff changeset
248 gimple *stmt;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
249
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
250 /* 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
251 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
252 pointing to phi node that got reallocated in the meantime). */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
253 tree name_defined_by_phi;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
254
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
255 /* 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
256 iterations of the loop). */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
257 unsigned distance;
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 /* Number of iterations offset from the first reference in the component. */
111
kono
parents: 67
diff changeset
260 widest_int offset;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
261
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
262 /* Number of the reference in a component, in dominance ordering. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
263 unsigned pos;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
264
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
265 /* 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
266 entered. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
267 unsigned always_accessed : 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
268 } *dref;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
269
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
270
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
271 /* Type of the chain of the references. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
272
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
273 enum chain_type
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 /* The addresses of the references in the chain are constant. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
276 CT_INVARIANT,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
277
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
278 /* There are only loads in the chain. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
279 CT_LOAD,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
280
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
281 /* Root of the chain is store, the rest are loads. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
282 CT_STORE_LOAD,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
283
111
kono
parents: 67
diff changeset
284 /* There are only stores in the chain. */
kono
parents: 67
diff changeset
285 CT_STORE_STORE,
kono
parents: 67
diff changeset
286
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
287 /* A combination of two chains. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
288 CT_COMBINATION
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
289 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
290
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
291 /* Chains of data references. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
292
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
293 typedef struct chain
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 /* Type of the chain. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
296 enum chain_type type;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
297
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
298 /* 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
299 combined, and the type of the result. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
300 enum tree_code op;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
301 tree rslt_type;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
302 struct chain *ch1, *ch2;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
303
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
304 /* The references in the chain. */
111
kono
parents: 67
diff changeset
305 vec<dref> refs;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
306
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
307 /* 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
308 unsigned length;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
309
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
310 /* The variables used to copy the value throughout iterations. */
111
kono
parents: 67
diff changeset
311 vec<tree> vars;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
312
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
313 /* Initializers for the variables. */
111
kono
parents: 67
diff changeset
314 vec<tree> inits;
kono
parents: 67
diff changeset
315
kono
parents: 67
diff changeset
316 /* Finalizers for the eliminated stores. */
kono
parents: 67
diff changeset
317 vec<tree> finis;
kono
parents: 67
diff changeset
318
kono
parents: 67
diff changeset
319 /* gimple stmts intializing the initial variables of the chain. */
kono
parents: 67
diff changeset
320 gimple_seq init_seq;
kono
parents: 67
diff changeset
321
kono
parents: 67
diff changeset
322 /* gimple stmts finalizing the eliminated stores of the chain. */
kono
parents: 67
diff changeset
323 gimple_seq fini_seq;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
324
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
325 /* 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
326 that comes after the root in the loop. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
327 unsigned has_max_use_after : 1;
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 all the memory references in the chain are always accessed. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
330 unsigned all_always_accessed : 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
331
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
332 /* 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
333 unsigned combined : 1;
111
kono
parents: 67
diff changeset
334
kono
parents: 67
diff changeset
335 /* True if this is store elimination chain and eliminated stores store
kono
parents: 67
diff changeset
336 loop invariant value into memory. */
kono
parents: 67
diff changeset
337 unsigned inv_store_elimination : 1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
338 } *chain_p;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
339
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
340
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
341 /* 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
342 the component. */
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 enum ref_step_type
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
345 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
346 /* The step is zero. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
347 RS_INVARIANT,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
348
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
349 /* The step is nonzero. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
350 RS_NONZERO,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
351
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
352 /* The step may or may not be nonzero. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
353 RS_ANY
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
354 };
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 /* Components of the data dependence graph. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
357
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
358 struct component
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 /* The references in the component. */
111
kono
parents: 67
diff changeset
361 vec<dref> refs;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
362
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
363 /* 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
364 enum ref_step_type comp_step;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
365
111
kono
parents: 67
diff changeset
366 /* True if all references in component are stores and we try to do
kono
parents: 67
diff changeset
367 intra/inter loop iteration dead store elimination. */
kono
parents: 67
diff changeset
368 bool eliminate_store_p;
kono
parents: 67
diff changeset
369
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
370 /* Next component in the list. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
371 struct component *next;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
372 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
373
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
374 /* 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
375
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
376 static bitmap looparound_phis;
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 /* Cache used by tree_to_aff_combination_expand. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
379
111
kono
parents: 67
diff changeset
380 static hash_map<tree, name_expansion *> *name_expansions;
0
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 /* Dumps data reference REF to FILE. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
383
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
384 extern void dump_dref (FILE *, dref);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
385 void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
386 dump_dref (FILE *file, dref ref)
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 if (ref->ref)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
389 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
390 fprintf (file, " ");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
391 print_generic_expr (file, DR_REF (ref->ref), TDF_SLIM);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
392 fprintf (file, " (id %u%s)\n", ref->pos,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
393 DR_IS_READ (ref->ref) ? "" : ", write");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
394
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
395 fprintf (file, " offset ");
111
kono
parents: 67
diff changeset
396 print_decs (ref->offset, file);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
397 fprintf (file, "\n");
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, " distance %u\n", ref->distance);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
400 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
401 else
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 if (gimple_code (ref->stmt) == GIMPLE_PHI)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
404 fprintf (file, " looparound ref\n");
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 fprintf (file, " combination ref\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
407 fprintf (file, " in statement ");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
408 print_gimple_stmt (file, ref->stmt, 0, TDF_SLIM);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
409 fprintf (file, "\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
410 fprintf (file, " distance %u\n", ref->distance);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
411 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
412
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
413 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
414
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
415 /* Dumps CHAIN to FILE. */
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 extern void dump_chain (FILE *, chain_p);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
418 void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
419 dump_chain (FILE *file, chain_p chain)
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 dref a;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
422 const char *chain_type;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
423 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
424 tree var;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
425
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
426 switch (chain->type)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
427 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
428 case CT_INVARIANT:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
429 chain_type = "Load motion";
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
430 break;
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_LOAD:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
433 chain_type = "Loads-only";
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_STORE_LOAD:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
437 chain_type = "Store-loads";
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
111
kono
parents: 67
diff changeset
440 case CT_STORE_STORE:
kono
parents: 67
diff changeset
441 chain_type = "Store-stores";
kono
parents: 67
diff changeset
442 break;
kono
parents: 67
diff changeset
443
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
444 case CT_COMBINATION:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
445 chain_type = "Combination";
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
446 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
447
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
448 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
449 gcc_unreachable ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
450 }
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 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
453 chain->combined ? " (combined)" : "");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
454 if (chain->type != CT_INVARIANT)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
455 fprintf (file, " max distance %u%s\n", chain->length,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
456 chain->has_max_use_after ? "" : ", may reuse first");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
457
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
458 if (chain->type == CT_COMBINATION)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
459 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
460 fprintf (file, " equal to %p %s %p in type ",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
461 (void *) chain->ch1, op_symbol_code (chain->op),
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
462 (void *) chain->ch2);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
463 print_generic_expr (file, chain->rslt_type, TDF_SLIM);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
464 fprintf (file, "\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
465 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
466
111
kono
parents: 67
diff changeset
467 if (chain->vars.exists ())
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
468 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
469 fprintf (file, " vars");
111
kono
parents: 67
diff changeset
470 FOR_EACH_VEC_ELT (chain->vars, i, var)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
471 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
472 fprintf (file, " ");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
473 print_generic_expr (file, var, TDF_SLIM);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
474 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
475 fprintf (file, "\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
476 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
477
111
kono
parents: 67
diff changeset
478 if (chain->inits.exists ())
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
479 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
480 fprintf (file, " inits");
111
kono
parents: 67
diff changeset
481 FOR_EACH_VEC_ELT (chain->inits, i, var)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
482 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
483 fprintf (file, " ");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
484 print_generic_expr (file, var, TDF_SLIM);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
485 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
486 fprintf (file, "\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
487 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
488
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
489 fprintf (file, " references:\n");
111
kono
parents: 67
diff changeset
490 FOR_EACH_VEC_ELT (chain->refs, i, a)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
491 dump_dref (file, a);
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, "\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
494 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
495
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
496 /* Dumps CHAINS to FILE. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
497
111
kono
parents: 67
diff changeset
498 extern void dump_chains (FILE *, vec<chain_p> );
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
499 void
111
kono
parents: 67
diff changeset
500 dump_chains (FILE *file, vec<chain_p> chains)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
501 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
502 chain_p chain;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
503 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
504
111
kono
parents: 67
diff changeset
505 FOR_EACH_VEC_ELT (chains, i, chain)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
506 dump_chain (file, chain);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
507 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
508
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
509 /* Dumps COMP to FILE. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
510
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
511 extern void dump_component (FILE *, struct component *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
512 void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
513 dump_component (FILE *file, struct component *comp)
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 dref a;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
516 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
517
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
518 fprintf (file, "Component%s:\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
519 comp->comp_step == RS_INVARIANT ? " (invariant)" : "");
111
kono
parents: 67
diff changeset
520 FOR_EACH_VEC_ELT (comp->refs, i, a)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
521 dump_dref (file, a);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
522 fprintf (file, "\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
523 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
524
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
525 /* Dumps COMPS to FILE. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
526
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
527 extern void dump_components (FILE *, struct component *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
528 void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
529 dump_components (FILE *file, struct component *comps)
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 struct component *comp;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
532
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
533 for (comp = comps; comp; comp = comp->next)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
534 dump_component (file, comp);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
535 }
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 /* Frees a chain CHAIN. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
538
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
539 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
540 release_chain (chain_p chain)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
541 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
542 dref ref;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
543 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
544
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
545 if (chain == NULL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
546 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
547
111
kono
parents: 67
diff changeset
548 FOR_EACH_VEC_ELT (chain->refs, i, ref)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
549 free (ref);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
550
111
kono
parents: 67
diff changeset
551 chain->refs.release ();
kono
parents: 67
diff changeset
552 chain->vars.release ();
kono
parents: 67
diff changeset
553 chain->inits.release ();
kono
parents: 67
diff changeset
554 if (chain->init_seq)
kono
parents: 67
diff changeset
555 gimple_seq_discard (chain->init_seq);
kono
parents: 67
diff changeset
556
kono
parents: 67
diff changeset
557 chain->finis.release ();
kono
parents: 67
diff changeset
558 if (chain->fini_seq)
kono
parents: 67
diff changeset
559 gimple_seq_discard (chain->fini_seq);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
560
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
561 free (chain);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
562 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
563
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
564 /* Frees CHAINS. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
565
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
566 static void
111
kono
parents: 67
diff changeset
567 release_chains (vec<chain_p> chains)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
568 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
569 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
570 chain_p chain;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
571
111
kono
parents: 67
diff changeset
572 FOR_EACH_VEC_ELT (chains, i, chain)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
573 release_chain (chain);
111
kono
parents: 67
diff changeset
574 chains.release ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
575 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
576
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
577 /* Frees a component COMP. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
578
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
579 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
580 release_component (struct component *comp)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
581 {
111
kono
parents: 67
diff changeset
582 comp->refs.release ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
583 free (comp);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
584 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
585
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
586 /* Frees list of components COMPS. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
587
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
588 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
589 release_components (struct component *comps)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
590 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
591 struct component *act, *next;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
592
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
593 for (act = comps; act; act = next)
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 next = act->next;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
596 release_component (act);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
597 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
598 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
599
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
600 /* 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
601 shortening. */
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 static unsigned
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
604 component_of (unsigned fathers[], unsigned a)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
605 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
606 unsigned root, n;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
607
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
608 for (root = a; root != fathers[root]; root = fathers[root])
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
609 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
610
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
611 for (; a != root; a = n)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
612 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
613 n = fathers[a];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
614 fathers[a] = root;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
615 }
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 return root;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
618 }
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 /* 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
621 components, A and B are components to merge. */
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 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
624 merge_comps (unsigned fathers[], unsigned sizes[], unsigned a, unsigned b)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
625 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
626 unsigned ca = component_of (fathers, a);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
627 unsigned cb = component_of (fathers, b);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
628
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
629 if (ca == cb)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
630 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
631
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
632 if (sizes[ca] < sizes[cb])
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
633 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
634 sizes[cb] += sizes[ca];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
635 fathers[ca] = cb;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
636 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
637 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
638 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
639 sizes[ca] += sizes[cb];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
640 fathers[cb] = ca;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
641 }
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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
644 /* 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
645 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
646 step of the reference A. */
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 static bool
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
649 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
650 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
651 tree ref = DR_REF (a), step = DR_STEP (a);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
652
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
653 if (!step
111
kono
parents: 67
diff changeset
654 || TREE_THIS_VOLATILE (ref)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
655 || !is_gimple_reg_type (TREE_TYPE (ref))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
656 || tree_could_throw_p (ref))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
657 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
658
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
659 if (integer_zerop (step))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
660 *ref_step = RS_INVARIANT;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
661 else if (integer_nonzerop (step))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
662 *ref_step = RS_NONZERO;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
663 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
664 *ref_step = RS_ANY;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
665
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
666 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
667 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
668
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
669 /* Stores DR_OFFSET (DR) + DR_INIT (DR) to OFFSET. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
670
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
671 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
672 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
673 {
111
kono
parents: 67
diff changeset
674 tree type = TREE_TYPE (DR_OFFSET (dr));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
675 aff_tree delta;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
676
111
kono
parents: 67
diff changeset
677 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
678 &name_expansions);
111
kono
parents: 67
diff changeset
679 aff_combination_const (&delta, type, wi::to_widest (DR_INIT (dr)));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
680 aff_combination_add (offset, &delta);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
681 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
682
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
683 /* 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
684 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
685 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
686 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
687 satisfy suitable_reference_p. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
688
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
689 static bool
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
690 determine_offset (struct data_reference *a, struct data_reference *b,
111
kono
parents: 67
diff changeset
691 widest_int *off)
0
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 aff_tree diff, baseb, step;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
694 tree typea, typeb;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
695
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
696 /* 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
697 typea = TREE_TYPE (DR_REF (a));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
698 typeb = TREE_TYPE (DR_REF (b));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
699 if (!useless_type_conversion_p (typeb, typea))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
700 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
701
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
702 /* 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
703 same. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
704 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
705 || !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
706 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
707
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
708 if (integer_zerop (DR_STEP (a)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
709 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
710 /* 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
711 exactly the same location. */
111
kono
parents: 67
diff changeset
712 *off = 0;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
713 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
714 && operand_equal_p (DR_INIT (a), DR_INIT (b), 0));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
715 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
716
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
717 /* 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
718 is a multiple of step. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
719 aff_combination_dr_offset (a, &diff);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
720 aff_combination_dr_offset (b, &baseb);
111
kono
parents: 67
diff changeset
721 aff_combination_scale (&baseb, -1);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
722 aff_combination_add (&diff, &baseb);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
723
111
kono
parents: 67
diff changeset
724 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
725 &step, &name_expansions);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
726 return aff_combination_constant_multiple_p (&diff, &step, off);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
727 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
728
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
729 /* 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
730 it is executed whenever the loop is entered. */
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 static basic_block
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
733 last_always_executed_block (struct loop *loop)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
734 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
735 unsigned i;
111
kono
parents: 67
diff changeset
736 vec<edge> exits = get_loop_exit_edges (loop);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
737 edge ex;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
738 basic_block last = loop->latch;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
739
111
kono
parents: 67
diff changeset
740 FOR_EACH_VEC_ELT (exits, i, ex)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
741 last = nearest_common_dominator (CDI_DOMINATORS, last, ex->src);
111
kono
parents: 67
diff changeset
742 exits.release ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
743
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
744 return last;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
745 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
746
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
747 /* Splits dependence graph on DATAREFS described by DEPENDS to components. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
748
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
749 static struct component *
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
750 split_data_refs_to_components (struct loop *loop,
111
kono
parents: 67
diff changeset
751 vec<data_reference_p> datarefs,
kono
parents: 67
diff changeset
752 vec<ddr_p> depends)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
753 {
111
kono
parents: 67
diff changeset
754 unsigned i, n = datarefs.length ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
755 unsigned ca, ia, ib, bad;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
756 unsigned *comp_father = XNEWVEC (unsigned, n + 1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
757 unsigned *comp_size = XNEWVEC (unsigned, n + 1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
758 struct component **comps;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
759 struct data_reference *dr, *dra, *drb;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
760 struct data_dependence_relation *ddr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
761 struct component *comp_list = NULL, *comp;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
762 dref dataref;
111
kono
parents: 67
diff changeset
763 /* Don't do store elimination if loop has multiple exit edges. */
kono
parents: 67
diff changeset
764 bool eliminate_store_p = single_exit (loop) != NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
765 basic_block last_always_executed = last_always_executed_block (loop);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
766
111
kono
parents: 67
diff changeset
767 FOR_EACH_VEC_ELT (datarefs, i, dr)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
768 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
769 if (!DR_REF (dr))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
770 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
771 /* 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
772 just fail. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
773 goto end;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
774 }
111
kono
parents: 67
diff changeset
775 /* predcom pass isn't prepared to handle calls with data references. */
kono
parents: 67
diff changeset
776 if (is_gimple_call (DR_STMT (dr)))
kono
parents: 67
diff changeset
777 goto end;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
778 dr->aux = (void *) (size_t) i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
779 comp_father[i] = i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
780 comp_size[i] = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
781 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
782
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
783 /* A component reserved for the "bad" data references. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
784 comp_father[n] = n;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
785 comp_size[n] = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
786
111
kono
parents: 67
diff changeset
787 FOR_EACH_VEC_ELT (datarefs, i, dr)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
788 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
789 enum ref_step_type dummy;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
790
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
791 if (!suitable_reference_p (dr, &dummy))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
792 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
793 ia = (unsigned) (size_t) dr->aux;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
794 merge_comps (comp_father, comp_size, n, ia);
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 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
797
111
kono
parents: 67
diff changeset
798 FOR_EACH_VEC_ELT (depends, i, ddr)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
799 {
111
kono
parents: 67
diff changeset
800 widest_int dummy_off;
0
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 if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
803 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
804
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
805 dra = DDR_A (ddr);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
806 drb = DDR_B (ddr);
111
kono
parents: 67
diff changeset
807
kono
parents: 67
diff changeset
808 /* Don't do store elimination if there is any unknown dependence for
kono
parents: 67
diff changeset
809 any store data reference. */
kono
parents: 67
diff changeset
810 if ((DR_IS_WRITE (dra) || DR_IS_WRITE (drb))
kono
parents: 67
diff changeset
811 && (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know
kono
parents: 67
diff changeset
812 || DDR_NUM_DIST_VECTS (ddr) == 0))
kono
parents: 67
diff changeset
813 eliminate_store_p = false;
kono
parents: 67
diff changeset
814
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
815 ia = component_of (comp_father, (unsigned) (size_t) dra->aux);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
816 ib = component_of (comp_father, (unsigned) (size_t) drb->aux);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
817 if (ia == ib)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
818 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
819
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
820 bad = component_of (comp_father, n);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
821
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
822 /* If both A and B are reads, we may ignore unsuitable dependences. */
111
kono
parents: 67
diff changeset
823 if (DR_IS_READ (dra) && DR_IS_READ (drb))
kono
parents: 67
diff changeset
824 {
kono
parents: 67
diff changeset
825 if (ia == bad || ib == bad
kono
parents: 67
diff changeset
826 || !determine_offset (dra, drb, &dummy_off))
kono
parents: 67
diff changeset
827 continue;
kono
parents: 67
diff changeset
828 }
kono
parents: 67
diff changeset
829 /* If A is read and B write or vice versa and there is unsuitable
kono
parents: 67
diff changeset
830 dependence, instead of merging both components into a component
kono
parents: 67
diff changeset
831 that will certainly not pass suitable_component_p, just put the
kono
parents: 67
diff changeset
832 read into bad component, perhaps at least the write together with
kono
parents: 67
diff changeset
833 all the other data refs in it's component will be optimizable. */
kono
parents: 67
diff changeset
834 else if (DR_IS_READ (dra) && ib != bad)
kono
parents: 67
diff changeset
835 {
kono
parents: 67
diff changeset
836 if (ia == bad)
kono
parents: 67
diff changeset
837 continue;
kono
parents: 67
diff changeset
838 else if (!determine_offset (dra, drb, &dummy_off))
kono
parents: 67
diff changeset
839 {
kono
parents: 67
diff changeset
840 merge_comps (comp_father, comp_size, bad, ia);
kono
parents: 67
diff changeset
841 continue;
kono
parents: 67
diff changeset
842 }
kono
parents: 67
diff changeset
843 }
kono
parents: 67
diff changeset
844 else if (DR_IS_READ (drb) && ia != bad)
kono
parents: 67
diff changeset
845 {
kono
parents: 67
diff changeset
846 if (ib == bad)
kono
parents: 67
diff changeset
847 continue;
kono
parents: 67
diff changeset
848 else if (!determine_offset (dra, drb, &dummy_off))
kono
parents: 67
diff changeset
849 {
kono
parents: 67
diff changeset
850 merge_comps (comp_father, comp_size, bad, ib);
kono
parents: 67
diff changeset
851 continue;
kono
parents: 67
diff changeset
852 }
kono
parents: 67
diff changeset
853 }
kono
parents: 67
diff changeset
854 else if (DR_IS_WRITE (dra) && DR_IS_WRITE (drb)
kono
parents: 67
diff changeset
855 && ia != bad && ib != bad
kono
parents: 67
diff changeset
856 && !determine_offset (dra, drb, &dummy_off))
kono
parents: 67
diff changeset
857 {
kono
parents: 67
diff changeset
858 merge_comps (comp_father, comp_size, bad, ia);
kono
parents: 67
diff changeset
859 merge_comps (comp_father, comp_size, bad, ib);
kono
parents: 67
diff changeset
860 continue;
kono
parents: 67
diff changeset
861 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
862
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
863 merge_comps (comp_father, comp_size, ia, ib);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
864 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
865
111
kono
parents: 67
diff changeset
866 if (eliminate_store_p)
kono
parents: 67
diff changeset
867 {
kono
parents: 67
diff changeset
868 tree niters = number_of_latch_executions (loop);
kono
parents: 67
diff changeset
869
kono
parents: 67
diff changeset
870 /* Don't do store elimination if niters info is unknown because stores
kono
parents: 67
diff changeset
871 in the last iteration can't be eliminated and we need to recover it
kono
parents: 67
diff changeset
872 after loop. */
kono
parents: 67
diff changeset
873 eliminate_store_p = (niters != NULL_TREE && niters != chrec_dont_know);
kono
parents: 67
diff changeset
874 }
kono
parents: 67
diff changeset
875
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
876 comps = XCNEWVEC (struct component *, n);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
877 bad = component_of (comp_father, n);
111
kono
parents: 67
diff changeset
878 FOR_EACH_VEC_ELT (datarefs, i, dr)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
879 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
880 ia = (unsigned) (size_t) dr->aux;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
881 ca = component_of (comp_father, ia);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
882 if (ca == bad)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
883 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
884
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
885 comp = comps[ca];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
886 if (!comp)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
887 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
888 comp = XCNEW (struct component);
111
kono
parents: 67
diff changeset
889 comp->refs.create (comp_size[ca]);
kono
parents: 67
diff changeset
890 comp->eliminate_store_p = eliminate_store_p;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
891 comps[ca] = comp;
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
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
894 dataref = XCNEW (struct dref_d);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
895 dataref->ref = dr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
896 dataref->stmt = DR_STMT (dr);
111
kono
parents: 67
diff changeset
897 dataref->offset = 0;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
898 dataref->distance = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
899
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
900 dataref->always_accessed
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
901 = dominated_by_p (CDI_DOMINATORS, last_always_executed,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
902 gimple_bb (dataref->stmt));
111
kono
parents: 67
diff changeset
903 dataref->pos = comp->refs.length ();
kono
parents: 67
diff changeset
904 comp->refs.quick_push (dataref);
kono
parents: 67
diff changeset
905 if (DR_IS_READ (dr))
kono
parents: 67
diff changeset
906 comp->eliminate_store_p = false;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
907 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
908
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
909 for (i = 0; i < n; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
910 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
911 comp = comps[i];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
912 if (comp)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
913 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
914 comp->next = comp_list;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
915 comp_list = comp;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
916 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
917 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
918 free (comps);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
919
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
920 end:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
921 free (comp_father);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
922 free (comp_size);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
923 return comp_list;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
924 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
925
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
926 /* Returns true if the component COMP satisfies the conditions
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
927 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
928 loop. */
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
929
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
930 static bool
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
931 suitable_component_p (struct loop *loop, struct component *comp)
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 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
934 dref a, first;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
935 basic_block ba, bp = loop->header;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
936 bool ok, has_write = false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
937
111
kono
parents: 67
diff changeset
938 FOR_EACH_VEC_ELT (comp->refs, i, a)
0
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 ba = gimple_bb (a->stmt);
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 if (!just_once_each_iteration_p (loop, ba))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
943 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
944
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
945 gcc_assert (dominated_by_p (CDI_DOMINATORS, ba, bp));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
946 bp = ba;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
947
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
948 if (DR_IS_WRITE (a->ref))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
949 has_write = true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
950 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
951
111
kono
parents: 67
diff changeset
952 first = comp->refs[0];
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
953 ok = suitable_reference_p (first->ref, &comp->comp_step);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
954 gcc_assert (ok);
111
kono
parents: 67
diff changeset
955 first->offset = 0;
kono
parents: 67
diff changeset
956
kono
parents: 67
diff changeset
957 for (i = 1; comp->refs.iterate (i, &a); i++)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
958 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
959 if (!determine_offset (first->ref, a->ref, &a->offset))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
960 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
961
111
kono
parents: 67
diff changeset
962 enum ref_step_type a_step;
kono
parents: 67
diff changeset
963 gcc_checking_assert (suitable_reference_p (a->ref, &a_step)
kono
parents: 67
diff changeset
964 && a_step == comp->comp_step);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
965 }
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 /* 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
968 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
969 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
970 or the previous one. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
971 if (has_write && comp->comp_step == RS_ANY)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
972 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
973
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
974 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
975 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
976
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
977 /* Check the conditions on references inside each of components COMPS,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
978 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
979 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
980 the beginning of this file. LOOP is the current loop. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
981
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
982 static struct component *
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
983 filter_suitable_components (struct loop *loop, struct component *comps)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
984 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
985 struct component **comp, *act;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
986
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
987 for (comp = &comps; *comp; )
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
988 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
989 act = *comp;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
990 if (suitable_component_p (loop, act))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
991 comp = &act->next;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
992 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
993 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
994 dref ref;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
995 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
996
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
997 *comp = act->next;
111
kono
parents: 67
diff changeset
998 FOR_EACH_VEC_ELT (act->refs, i, ref)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
999 free (ref);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1000 release_component (act);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1001 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1002 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1003
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1004 return comps;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1005 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1006
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1007 /* 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
1008 qsort. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1009
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1010 static int
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1011 order_drefs (const void *a, const void *b)
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 const dref *const da = (const dref *) a;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1014 const dref *const db = (const dref *) b;
111
kono
parents: 67
diff changeset
1015 int offcmp = wi::cmps ((*da)->offset, (*db)->offset);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1016
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1017 if (offcmp != 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1018 return offcmp;
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 return (*da)->pos - (*db)->pos;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1021 }
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 /* Returns root of the CHAIN. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1024
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1025 static inline dref
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1026 get_chain_root (chain_p chain)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1027 {
111
kono
parents: 67
diff changeset
1028 return chain->refs[0];
kono
parents: 67
diff changeset
1029 }
kono
parents: 67
diff changeset
1030
kono
parents: 67
diff changeset
1031 /* Given CHAIN, returns the last ref at DISTANCE, or NULL if it doesn't
kono
parents: 67
diff changeset
1032 exist. */
kono
parents: 67
diff changeset
1033
kono
parents: 67
diff changeset
1034 static inline dref
kono
parents: 67
diff changeset
1035 get_chain_last_ref_at (chain_p chain, unsigned distance)
kono
parents: 67
diff changeset
1036 {
kono
parents: 67
diff changeset
1037 unsigned i;
kono
parents: 67
diff changeset
1038
kono
parents: 67
diff changeset
1039 for (i = chain->refs.length (); i > 0; i--)
kono
parents: 67
diff changeset
1040 if (distance == chain->refs[i - 1]->distance)
kono
parents: 67
diff changeset
1041 break;
kono
parents: 67
diff changeset
1042
kono
parents: 67
diff changeset
1043 return (i > 0) ? chain->refs[i - 1] : NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1044 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1045
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1046 /* Adds REF to the chain CHAIN. */
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 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1049 add_ref_to_chain (chain_p chain, dref ref)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1050 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1051 dref root = get_chain_root (chain);
111
kono
parents: 67
diff changeset
1052
kono
parents: 67
diff changeset
1053 gcc_assert (wi::les_p (root->offset, ref->offset));
kono
parents: 67
diff changeset
1054 widest_int dist = ref->offset - root->offset;
kono
parents: 67
diff changeset
1055 if (wi::leu_p (MAX_DISTANCE, dist))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1056 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1057 free (ref);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1058 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1059 }
111
kono
parents: 67
diff changeset
1060 gcc_assert (wi::fits_uhwi_p (dist));
kono
parents: 67
diff changeset
1061
kono
parents: 67
diff changeset
1062 chain->refs.safe_push (ref);
kono
parents: 67
diff changeset
1063
kono
parents: 67
diff changeset
1064 ref->distance = dist.to_uhwi ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1065
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1066 if (ref->distance >= chain->length)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1067 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1068 chain->length = ref->distance;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1069 chain->has_max_use_after = false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1070 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1071
111
kono
parents: 67
diff changeset
1072 /* Don't set the flag for store-store chain since there is no use. */
kono
parents: 67
diff changeset
1073 if (chain->type != CT_STORE_STORE
kono
parents: 67
diff changeset
1074 && ref->distance == chain->length
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1075 && ref->pos > root->pos)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1076 chain->has_max_use_after = true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1077
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1078 chain->all_always_accessed &= ref->always_accessed;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1079 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1080
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1081 /* Returns the chain for invariant component COMP. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1082
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1083 static chain_p
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1084 make_invariant_chain (struct component *comp)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1085 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1086 chain_p chain = XCNEW (struct chain);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1087 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1088 dref ref;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1089
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1090 chain->type = CT_INVARIANT;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1091
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1092 chain->all_always_accessed = true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1093
111
kono
parents: 67
diff changeset
1094 FOR_EACH_VEC_ELT (comp->refs, i, ref)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1095 {
111
kono
parents: 67
diff changeset
1096 chain->refs.safe_push (ref);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1097 chain->all_always_accessed &= ref->always_accessed;
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
111
kono
parents: 67
diff changeset
1100 chain->inits = vNULL;
kono
parents: 67
diff changeset
1101 chain->finis = vNULL;
kono
parents: 67
diff changeset
1102
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1103 return chain;
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
111
kono
parents: 67
diff changeset
1106 /* 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
1107
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1108 static chain_p
111
kono
parents: 67
diff changeset
1109 make_rooted_chain (dref ref, enum chain_type type)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1110 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1111 chain_p chain = XCNEW (struct chain);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1112
111
kono
parents: 67
diff changeset
1113 chain->type = type;
kono
parents: 67
diff changeset
1114 chain->refs.safe_push (ref);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1115 chain->all_always_accessed = ref->always_accessed;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1116 ref->distance = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1117
111
kono
parents: 67
diff changeset
1118 chain->inits = vNULL;
kono
parents: 67
diff changeset
1119 chain->finis = vNULL;
kono
parents: 67
diff changeset
1120
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1121 return chain;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1122 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1123
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1124 /* Returns true if CHAIN is not trivial. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1125
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1126 static bool
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1127 nontrivial_chain_p (chain_p chain)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1128 {
111
kono
parents: 67
diff changeset
1129 return chain != NULL && chain->refs.length () > 1;
0
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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1132 /* 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
1133 is no such name. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1134
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1135 static tree
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1136 name_for_ref (dref ref)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1137 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1138 tree name;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1139
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1140 if (is_gimple_assign (ref->stmt))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1141 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1142 if (!ref->ref || DR_IS_READ (ref->ref))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1143 name = gimple_assign_lhs (ref->stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1144 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1145 name = gimple_assign_rhs1 (ref->stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1146 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1147 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1148 name = PHI_RESULT (ref->stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1149
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1150 return (TREE_CODE (name) == SSA_NAME ? name : NULL_TREE);
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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1153 /* 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
1154 iterations of the innermost enclosing loop). */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1155
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1156 static bool
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1157 valid_initializer_p (struct data_reference *ref,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1158 unsigned distance, struct data_reference *root)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1159 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1160 aff_tree diff, base, step;
111
kono
parents: 67
diff changeset
1161 widest_int off;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1162
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1163 /* Both REF and ROOT must be accessing the same object. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1164 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
1165 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1166
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1167 /* 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
1168 invariant inside the loop. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1169 gcc_assert (integer_zerop (DR_STEP (ref)));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1170
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1171 /* 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
1172 exactly the same location. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1173 if (integer_zerop (DR_STEP (root)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1174 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
1175 && operand_equal_p (DR_INIT (ref), DR_INIT (root), 0));
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 /* 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
1178 -DISTANCE-th iteration. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1179 aff_combination_dr_offset (root, &diff);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1180 aff_combination_dr_offset (ref, &base);
111
kono
parents: 67
diff changeset
1181 aff_combination_scale (&base, -1);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1182 aff_combination_add (&diff, &base);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1183
111
kono
parents: 67
diff changeset
1184 tree_to_aff_combination_expand (DR_STEP (root), TREE_TYPE (DR_STEP (root)),
kono
parents: 67
diff changeset
1185 &step, &name_expansions);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1186 if (!aff_combination_constant_multiple_p (&diff, &step, &off))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1187 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1188
111
kono
parents: 67
diff changeset
1189 if (off != distance)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1190 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1191
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1192 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1193 }
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 /* 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
1196 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
1197 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
1198 is the root of the current chain. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1199
111
kono
parents: 67
diff changeset
1200 static gphi *
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1201 find_looparound_phi (struct loop *loop, dref ref, dref root)
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 tree name, init, init_ref;
111
kono
parents: 67
diff changeset
1204 gphi *phi = NULL;
kono
parents: 67
diff changeset
1205 gimple *init_stmt;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1206 edge latch = loop_latch_edge (loop);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1207 struct data_reference init_dr;
111
kono
parents: 67
diff changeset
1208 gphi_iterator psi;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1209
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1210 if (is_gimple_assign (ref->stmt))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1211 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1212 if (DR_IS_READ (ref->ref))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1213 name = gimple_assign_lhs (ref->stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1214 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1215 name = gimple_assign_rhs1 (ref->stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1216 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1217 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1218 name = PHI_RESULT (ref->stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1219 if (!name)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1220 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1221
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1222 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
1223 {
111
kono
parents: 67
diff changeset
1224 phi = psi.phi ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1225 if (PHI_ARG_DEF_FROM_EDGE (phi, latch) == name)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1226 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1227 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1228
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1229 if (gsi_end_p (psi))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1230 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1231
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1232 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
1233 if (TREE_CODE (init) != SSA_NAME)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1234 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1235 init_stmt = SSA_NAME_DEF_STMT (init);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1236 if (gimple_code (init_stmt) != GIMPLE_ASSIGN)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1237 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1238 gcc_assert (gimple_assign_lhs (init_stmt) == init);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1239
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1240 init_ref = gimple_assign_rhs1 (init_stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1241 if (!REFERENCE_CLASS_P (init_ref)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1242 && !DECL_P (init_ref))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1243 return NULL;
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 /* 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
1246 loop enclosing PHI). */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1247 memset (&init_dr, 0, sizeof (struct data_reference));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1248 DR_REF (&init_dr) = init_ref;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1249 DR_STMT (&init_dr) = phi;
111
kono
parents: 67
diff changeset
1250 if (!dr_analyze_innermost (&DR_INNERMOST (&init_dr), init_ref, loop))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1251 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1252
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1253 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
1254 return NULL;
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 return phi;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1257 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1258
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1259 /* 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
1260
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1261 static void
111
kono
parents: 67
diff changeset
1262 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
1263 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1264 dref nw = XCNEW (struct dref_d), aref;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1265 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1266
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1267 nw->stmt = phi;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1268 nw->distance = ref->distance + 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1269 nw->always_accessed = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1270
111
kono
parents: 67
diff changeset
1271 FOR_EACH_VEC_ELT (chain->refs, i, aref)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1272 if (aref->distance >= nw->distance)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1273 break;
111
kono
parents: 67
diff changeset
1274 chain->refs.safe_insert (i, nw);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1275
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1276 if (nw->distance > chain->length)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1277 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1278 chain->length = nw->distance;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1279 chain->has_max_use_after = false;
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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1283 /* 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
1284 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
1285 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
1286 (also, it may allow us to combine chains together). */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1287
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1288 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1289 add_looparound_copies (struct loop *loop, chain_p chain)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1290 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1291 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1292 dref ref, root = get_chain_root (chain);
111
kono
parents: 67
diff changeset
1293 gphi *phi;
kono
parents: 67
diff changeset
1294
kono
parents: 67
diff changeset
1295 if (chain->type == CT_STORE_STORE)
kono
parents: 67
diff changeset
1296 return;
kono
parents: 67
diff changeset
1297
kono
parents: 67
diff changeset
1298 FOR_EACH_VEC_ELT (chain->refs, i, ref)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1299 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1300 phi = find_looparound_phi (loop, ref, root);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1301 if (!phi)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1302 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1303
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1304 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
1305 insert_looparound_copy (chain, ref, phi);
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 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1308
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1309 /* 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
1310 The references are redistributed into CHAINS. LOOP is the current
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1311 loop. */
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 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1314 determine_roots_comp (struct loop *loop,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1315 struct component *comp,
111
kono
parents: 67
diff changeset
1316 vec<chain_p> *chains)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1317 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1318 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1319 dref a;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1320 chain_p chain = NULL;
111
kono
parents: 67
diff changeset
1321 widest_int last_ofs = 0;
kono
parents: 67
diff changeset
1322 enum chain_type type;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1323
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1324 /* Invariants are handled specially. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1325 if (comp->comp_step == RS_INVARIANT)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1326 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1327 chain = make_invariant_chain (comp);
111
kono
parents: 67
diff changeset
1328 chains->safe_push (chain);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1329 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1330 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1331
111
kono
parents: 67
diff changeset
1332 /* Trivial component. */
kono
parents: 67
diff changeset
1333 if (comp->refs.length () <= 1)
kono
parents: 67
diff changeset
1334 return;
kono
parents: 67
diff changeset
1335
kono
parents: 67
diff changeset
1336 comp->refs.qsort (order_drefs);
kono
parents: 67
diff changeset
1337 FOR_EACH_VEC_ELT (comp->refs, i, a)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1338 {
111
kono
parents: 67
diff changeset
1339 if (!chain
kono
parents: 67
diff changeset
1340 || (!comp->eliminate_store_p && DR_IS_WRITE (a->ref))
kono
parents: 67
diff changeset
1341 || wi::leu_p (MAX_DISTANCE, a->offset - last_ofs))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1342 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1343 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
1344 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1345 add_looparound_copies (loop, chain);
111
kono
parents: 67
diff changeset
1346 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
1347 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1348 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1349 release_chain (chain);
111
kono
parents: 67
diff changeset
1350
kono
parents: 67
diff changeset
1351 if (DR_IS_READ (a->ref))
kono
parents: 67
diff changeset
1352 type = CT_LOAD;
kono
parents: 67
diff changeset
1353 else
kono
parents: 67
diff changeset
1354 type = comp->eliminate_store_p ? CT_STORE_STORE : CT_STORE_LOAD;
kono
parents: 67
diff changeset
1355
kono
parents: 67
diff changeset
1356 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
1357 last_ofs = a->offset;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1358 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1359 }
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 add_ref_to_chain (chain, a);
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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1364 if (nontrivial_chain_p (chain))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1365 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1366 add_looparound_copies (loop, chain);
111
kono
parents: 67
diff changeset
1367 chains->safe_push (chain);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1368 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1369 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1370 release_chain (chain);
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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1373 /* 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
1374 separates the references to CHAINS. LOOP is the current loop. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1375
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1376 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1377 determine_roots (struct loop *loop,
111
kono
parents: 67
diff changeset
1378 struct component *comps, vec<chain_p> *chains)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1379 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1380 struct component *comp;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1381
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1382 for (comp = comps; comp; comp = comp->next)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1383 determine_roots_comp (loop, comp, chains);
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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1386 /* Replace the reference in statement STMT with temporary variable
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1387 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
1388 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
1389 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
1390
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1391 static void
111
kono
parents: 67
diff changeset
1392 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
1393 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1394 tree val;
111
kono
parents: 67
diff changeset
1395 gassign *new_stmt;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1396 gimple_stmt_iterator bsi, psi;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1397
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1398 if (gimple_code (stmt) == GIMPLE_PHI)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1399 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1400 gcc_assert (!in_lhs && !set);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1401
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1402 val = PHI_RESULT (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1403 bsi = gsi_after_labels (gimple_bb (stmt));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1404 psi = gsi_for_stmt (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1405 remove_phi_node (&psi, false);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1406
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1407 /* Turn the phi node into GIMPLE_ASSIGN. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1408 new_stmt = gimple_build_assign (val, new_tree);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1409 gsi_insert_before (&bsi, new_stmt, GSI_NEW_STMT);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1410 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1411 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1412
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1413 /* 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
1414 appear as lhs or rhs of modify statement. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1415 gcc_assert (is_gimple_assign (stmt));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1416
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1417 bsi = gsi_for_stmt (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1418
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1419 /* 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
1420 if (!set)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1421 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1422 gcc_assert (!in_lhs);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1423 gimple_assign_set_rhs_from_tree (&bsi, new_tree);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1424 stmt = gsi_stmt (bsi);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1425 update_stmt (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1426 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1427 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1428
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1429 if (in_lhs)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1430 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1431 /* 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
1432
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1433 OLD = VAL
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1434
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1435 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
1436 this to
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1437
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1438 OLD = VAL
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1439 NEW = VAL
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1440
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1441 Otherwise, we are replacing a combination chain,
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1442 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
1443 SSA name. In this case, we transform the assignment to
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 OLD = VAL
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1446 NEW = OLD
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1447
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1448 */
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 val = gimple_assign_lhs (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1451 if (TREE_CODE (val) != SSA_NAME)
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 val = gimple_assign_rhs1 (stmt);
111
kono
parents: 67
diff changeset
1454 gcc_assert (gimple_assign_single_p (stmt));
kono
parents: 67
diff changeset
1455 if (TREE_CLOBBER_P (val))
kono
parents: 67
diff changeset
1456 val = get_or_create_ssa_default_def (cfun, SSA_NAME_VAR (new_tree));
kono
parents: 67
diff changeset
1457 else
kono
parents: 67
diff changeset
1458 gcc_assert (gimple_assign_copy_p (stmt));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1459 }
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 else
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 /* VAL = OLD
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1464
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1465 is transformed to
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 VAL = OLD
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1468 NEW = VAL */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1469
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1470 val = gimple_assign_lhs (stmt);
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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1473 new_stmt = gimple_build_assign (new_tree, unshare_expr (val));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1474 gsi_insert_after (&bsi, new_stmt, GSI_NEW_STMT);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1475 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1476
111
kono
parents: 67
diff changeset
1477 /* Returns a memory reference to DR in the (NITERS + ITER)-th iteration
kono
parents: 67
diff changeset
1478 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
1479
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1480 static tree
111
kono
parents: 67
diff changeset
1481 ref_at_iteration (data_reference_p dr, int iter,
kono
parents: 67
diff changeset
1482 gimple_seq *stmts, tree niters = NULL_TREE)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1483 {
111
kono
parents: 67
diff changeset
1484 tree off = DR_OFFSET (dr);
kono
parents: 67
diff changeset
1485 tree coff = DR_INIT (dr);
kono
parents: 67
diff changeset
1486 tree ref = DR_REF (dr);
kono
parents: 67
diff changeset
1487 enum tree_code ref_code = ERROR_MARK;
kono
parents: 67
diff changeset
1488 tree ref_type = NULL_TREE;
kono
parents: 67
diff changeset
1489 tree ref_op1 = NULL_TREE;
kono
parents: 67
diff changeset
1490 tree ref_op2 = NULL_TREE;
kono
parents: 67
diff changeset
1491 tree new_offset;
kono
parents: 67
diff changeset
1492
kono
parents: 67
diff changeset
1493 if (iter != 0)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1494 {
111
kono
parents: 67
diff changeset
1495 new_offset = size_binop (MULT_EXPR, DR_STEP (dr), ssize_int (iter));
kono
parents: 67
diff changeset
1496 if (TREE_CODE (new_offset) == INTEGER_CST)
kono
parents: 67
diff changeset
1497 coff = size_binop (PLUS_EXPR, coff, new_offset);
kono
parents: 67
diff changeset
1498 else
kono
parents: 67
diff changeset
1499 off = size_binop (PLUS_EXPR, off, new_offset);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1500 }
111
kono
parents: 67
diff changeset
1501
kono
parents: 67
diff changeset
1502 if (niters != NULL_TREE)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1503 {
111
kono
parents: 67
diff changeset
1504 niters = fold_convert (ssizetype, niters);
kono
parents: 67
diff changeset
1505 new_offset = size_binop (MULT_EXPR, DR_STEP (dr), niters);
kono
parents: 67
diff changeset
1506 if (TREE_CODE (niters) == INTEGER_CST)
kono
parents: 67
diff changeset
1507 coff = size_binop (PLUS_EXPR, coff, new_offset);
kono
parents: 67
diff changeset
1508 else
kono
parents: 67
diff changeset
1509 off = size_binop (PLUS_EXPR, off, new_offset);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1510 }
111
kono
parents: 67
diff changeset
1511
kono
parents: 67
diff changeset
1512 /* While data-ref analysis punts on bit offsets it still handles
kono
parents: 67
diff changeset
1513 bitfield accesses at byte boundaries. Cope with that. Note that
kono
parents: 67
diff changeset
1514 if the bitfield object also starts at a byte-boundary we can simply
kono
parents: 67
diff changeset
1515 replicate the COMPONENT_REF, but we have to subtract the component's
kono
parents: 67
diff changeset
1516 byte-offset from the MEM_REF address first.
kono
parents: 67
diff changeset
1517 Otherwise we simply build a BIT_FIELD_REF knowing that the bits
kono
parents: 67
diff changeset
1518 start at offset zero. */
kono
parents: 67
diff changeset
1519 if (TREE_CODE (ref) == COMPONENT_REF
kono
parents: 67
diff changeset
1520 && DECL_BIT_FIELD (TREE_OPERAND (ref, 1)))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1521 {
111
kono
parents: 67
diff changeset
1522 unsigned HOST_WIDE_INT boff;
kono
parents: 67
diff changeset
1523 tree field = TREE_OPERAND (ref, 1);
kono
parents: 67
diff changeset
1524 tree offset = component_ref_field_offset (ref);
kono
parents: 67
diff changeset
1525 ref_type = TREE_TYPE (ref);
kono
parents: 67
diff changeset
1526 boff = tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field));
kono
parents: 67
diff changeset
1527 /* This can occur in Ada. See the comment in get_bit_range. */
kono
parents: 67
diff changeset
1528 if (boff % BITS_PER_UNIT != 0
kono
parents: 67
diff changeset
1529 || !tree_fits_uhwi_p (offset))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1530 {
111
kono
parents: 67
diff changeset
1531 ref_code = BIT_FIELD_REF;
kono
parents: 67
diff changeset
1532 ref_op1 = DECL_SIZE (field);
kono
parents: 67
diff changeset
1533 ref_op2 = bitsize_zero_node;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1534 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1535 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1536 {
111
kono
parents: 67
diff changeset
1537 boff >>= LOG2_BITS_PER_UNIT;
kono
parents: 67
diff changeset
1538 boff += tree_to_uhwi (offset);
kono
parents: 67
diff changeset
1539 coff = size_binop (MINUS_EXPR, coff, ssize_int (boff));
kono
parents: 67
diff changeset
1540 ref_code = COMPONENT_REF;
kono
parents: 67
diff changeset
1541 ref_op1 = field;
kono
parents: 67
diff changeset
1542 ref_op2 = TREE_OPERAND (ref, 2);
kono
parents: 67
diff changeset
1543 ref = TREE_OPERAND (ref, 0);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1544 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1545 }
111
kono
parents: 67
diff changeset
1546 tree addr = fold_build_pointer_plus (DR_BASE_ADDRESS (dr), off);
kono
parents: 67
diff changeset
1547 addr = force_gimple_operand_1 (unshare_expr (addr), stmts,
kono
parents: 67
diff changeset
1548 is_gimple_mem_ref_addr, NULL_TREE);
kono
parents: 67
diff changeset
1549 tree alias_ptr = fold_convert (reference_alias_ptr_type (ref), coff);
kono
parents: 67
diff changeset
1550 tree type = build_aligned_type (TREE_TYPE (ref),
kono
parents: 67
diff changeset
1551 get_object_alignment (ref));
kono
parents: 67
diff changeset
1552 ref = build2 (MEM_REF, type, addr, alias_ptr);
kono
parents: 67
diff changeset
1553 if (ref_type)
kono
parents: 67
diff changeset
1554 ref = build3 (ref_code, ref_type, ref, ref_op1, ref_op2);
kono
parents: 67
diff changeset
1555 return ref;
0
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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1558 /* Get the initialization expression for the INDEX-th temporary variable
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1559 of CHAIN. */
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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1562 get_init_expr (chain_p chain, unsigned index)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1563 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1564 if (chain->type == CT_COMBINATION)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1565 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1566 tree e1 = get_init_expr (chain->ch1, index);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1567 tree e2 = get_init_expr (chain->ch2, index);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1568
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1569 return fold_build2 (chain->op, chain->rslt_type, e1, e2);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1570 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1571 else
111
kono
parents: 67
diff changeset
1572 return chain->inits[index];
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1573 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1574
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1575 /* 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
1576 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
1577
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1578 static tree
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1579 predcom_tmp_var (tree ref, unsigned i, bitmap tmp_vars)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1580 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1581 tree type = TREE_TYPE (ref);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1582 /* 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
1583 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
1584 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
1585 bitmap_set_bit (tmp_vars, DECL_UID (var));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1586 return var;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1587 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1588
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1589 /* 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
1590 initialization on entry to LOOP. Uids of the newly created
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1591 temporary variables are marked in TMP_VARS. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1592
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1593 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1594 initialize_root_vars (struct loop *loop, chain_p chain, bitmap tmp_vars)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1595 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1596 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1597 unsigned n = chain->length;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1598 dref root = get_chain_root (chain);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1599 bool reuse_first = !chain->has_max_use_after;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1600 tree ref, init, var, next;
111
kono
parents: 67
diff changeset
1601 gphi *phi;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1602 gimple_seq stmts;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1603 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
1604
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1605 /* 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
1606 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
1607 gcc_assert (n > 0 || !reuse_first);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1608
111
kono
parents: 67
diff changeset
1609 chain->vars.create (n + 1);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1610
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1611 if (chain->type == CT_COMBINATION)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1612 ref = gimple_assign_lhs (root->stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1613 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1614 ref = DR_REF (root->ref);
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 for (i = 0; i < n + (reuse_first ? 0 : 1); i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1617 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1618 var = predcom_tmp_var (ref, i, tmp_vars);
111
kono
parents: 67
diff changeset
1619 chain->vars.quick_push (var);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1620 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1621 if (reuse_first)
111
kono
parents: 67
diff changeset
1622 chain->vars.quick_push (chain->vars[0]);
kono
parents: 67
diff changeset
1623
kono
parents: 67
diff changeset
1624 FOR_EACH_VEC_ELT (chain->vars, i, var)
kono
parents: 67
diff changeset
1625 chain->vars[i] = make_ssa_name (var);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1626
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1627 for (i = 0; i < n; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1628 {
111
kono
parents: 67
diff changeset
1629 var = chain->vars[i];
kono
parents: 67
diff changeset
1630 next = chain->vars[i + 1];
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1631 init = get_init_expr (chain, i);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1632
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1633 init = force_gimple_operand (init, &stmts, true, NULL_TREE);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1634 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
1635 gsi_insert_seq_on_edge_immediate (entry, stmts);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1636
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1637 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
1638 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
1639 add_phi_arg (phi, next, latch, UNKNOWN_LOCATION);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1640 }
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
111
kono
parents: 67
diff changeset
1643 /* For inter-iteration store elimination CHAIN in LOOP, returns true if
kono
parents: 67
diff changeset
1644 all stores to be eliminated store loop invariant values into memory.
kono
parents: 67
diff changeset
1645 In this case, we can use these invariant values directly after LOOP. */
kono
parents: 67
diff changeset
1646
kono
parents: 67
diff changeset
1647 static bool
kono
parents: 67
diff changeset
1648 is_inv_store_elimination_chain (struct loop *loop, chain_p chain)
kono
parents: 67
diff changeset
1649 {
kono
parents: 67
diff changeset
1650 if (chain->length == 0 || chain->type != CT_STORE_STORE)
kono
parents: 67
diff changeset
1651 return false;
kono
parents: 67
diff changeset
1652
kono
parents: 67
diff changeset
1653 gcc_assert (!chain->has_max_use_after);
kono
parents: 67
diff changeset
1654
kono
parents: 67
diff changeset
1655 /* If loop iterates for unknown times or fewer times than chain->lenght,
kono
parents: 67
diff changeset
1656 we still need to setup root variable and propagate it with PHI node. */
kono
parents: 67
diff changeset
1657 tree niters = number_of_latch_executions (loop);
kono
parents: 67
diff changeset
1658 if (TREE_CODE (niters) != INTEGER_CST
kono
parents: 67
diff changeset
1659 || wi::leu_p (wi::to_wide (niters), chain->length))
kono
parents: 67
diff changeset
1660 return false;
kono
parents: 67
diff changeset
1661
kono
parents: 67
diff changeset
1662 /* Check stores in chain for elimination if they only store loop invariant
kono
parents: 67
diff changeset
1663 values. */
kono
parents: 67
diff changeset
1664 for (unsigned i = 0; i < chain->length; i++)
kono
parents: 67
diff changeset
1665 {
kono
parents: 67
diff changeset
1666 dref a = get_chain_last_ref_at (chain, i);
kono
parents: 67
diff changeset
1667 if (a == NULL)
kono
parents: 67
diff changeset
1668 continue;
kono
parents: 67
diff changeset
1669
kono
parents: 67
diff changeset
1670 gimple *def_stmt, *stmt = a->stmt;
kono
parents: 67
diff changeset
1671 if (!gimple_assign_single_p (stmt))
kono
parents: 67
diff changeset
1672 return false;
kono
parents: 67
diff changeset
1673
kono
parents: 67
diff changeset
1674 tree val = gimple_assign_rhs1 (stmt);
kono
parents: 67
diff changeset
1675 if (TREE_CLOBBER_P (val))
kono
parents: 67
diff changeset
1676 return false;
kono
parents: 67
diff changeset
1677
kono
parents: 67
diff changeset
1678 if (CONSTANT_CLASS_P (val))
kono
parents: 67
diff changeset
1679 continue;
kono
parents: 67
diff changeset
1680
kono
parents: 67
diff changeset
1681 if (TREE_CODE (val) != SSA_NAME)
kono
parents: 67
diff changeset
1682 return false;
kono
parents: 67
diff changeset
1683
kono
parents: 67
diff changeset
1684 def_stmt = SSA_NAME_DEF_STMT (val);
kono
parents: 67
diff changeset
1685 if (gimple_nop_p (def_stmt))
kono
parents: 67
diff changeset
1686 continue;
kono
parents: 67
diff changeset
1687
kono
parents: 67
diff changeset
1688 if (flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)))
kono
parents: 67
diff changeset
1689 return false;
kono
parents: 67
diff changeset
1690 }
kono
parents: 67
diff changeset
1691 return true;
kono
parents: 67
diff changeset
1692 }
kono
parents: 67
diff changeset
1693
kono
parents: 67
diff changeset
1694 /* Creates root variables for store elimination CHAIN in which stores for
kono
parents: 67
diff changeset
1695 elimination only store loop invariant values. In this case, we neither
kono
parents: 67
diff changeset
1696 need to load root variables before loop nor propagate it with PHI nodes. */
kono
parents: 67
diff changeset
1697
kono
parents: 67
diff changeset
1698 static void
kono
parents: 67
diff changeset
1699 initialize_root_vars_store_elim_1 (chain_p chain)
kono
parents: 67
diff changeset
1700 {
kono
parents: 67
diff changeset
1701 tree var;
kono
parents: 67
diff changeset
1702 unsigned i, n = chain->length;
kono
parents: 67
diff changeset
1703
kono
parents: 67
diff changeset
1704 chain->vars.create (n);
kono
parents: 67
diff changeset
1705 chain->vars.safe_grow_cleared (n);
kono
parents: 67
diff changeset
1706
kono
parents: 67
diff changeset
1707 /* Initialize root value for eliminated stores at each distance. */
kono
parents: 67
diff changeset
1708 for (i = 0; i < n; i++)
kono
parents: 67
diff changeset
1709 {
kono
parents: 67
diff changeset
1710 dref a = get_chain_last_ref_at (chain, i);
kono
parents: 67
diff changeset
1711 if (a == NULL)
kono
parents: 67
diff changeset
1712 continue;
kono
parents: 67
diff changeset
1713
kono
parents: 67
diff changeset
1714 var = gimple_assign_rhs1 (a->stmt);
kono
parents: 67
diff changeset
1715 chain->vars[a->distance] = var;
kono
parents: 67
diff changeset
1716 }
kono
parents: 67
diff changeset
1717
kono
parents: 67
diff changeset
1718 /* We don't propagate values with PHI nodes, so manually propagate value
kono
parents: 67
diff changeset
1719 to bubble positions. */
kono
parents: 67
diff changeset
1720 var = chain->vars[0];
kono
parents: 67
diff changeset
1721 for (i = 1; i < n; i++)
kono
parents: 67
diff changeset
1722 {
kono
parents: 67
diff changeset
1723 if (chain->vars[i] != NULL_TREE)
kono
parents: 67
diff changeset
1724 {
kono
parents: 67
diff changeset
1725 var = chain->vars[i];
kono
parents: 67
diff changeset
1726 continue;
kono
parents: 67
diff changeset
1727 }
kono
parents: 67
diff changeset
1728 chain->vars[i] = var;
kono
parents: 67
diff changeset
1729 }
kono
parents: 67
diff changeset
1730
kono
parents: 67
diff changeset
1731 /* Revert the vector. */
kono
parents: 67
diff changeset
1732 for (i = 0; i < n / 2; i++)
kono
parents: 67
diff changeset
1733 std::swap (chain->vars[i], chain->vars[n - i - 1]);
kono
parents: 67
diff changeset
1734 }
kono
parents: 67
diff changeset
1735
kono
parents: 67
diff changeset
1736 /* Creates root variables for store elimination CHAIN in which stores for
kono
parents: 67
diff changeset
1737 elimination store loop variant values. In this case, we may need to
kono
parents: 67
diff changeset
1738 load root variables before LOOP and propagate it with PHI nodes. Uids
kono
parents: 67
diff changeset
1739 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
1740
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1741 static void
111
kono
parents: 67
diff changeset
1742 initialize_root_vars_store_elim_2 (struct loop *loop,
kono
parents: 67
diff changeset
1743 chain_p chain, bitmap tmp_vars)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1744 {
111
kono
parents: 67
diff changeset
1745 unsigned i, n = chain->length;
kono
parents: 67
diff changeset
1746 tree ref, init, var, next, val, phi_result;
kono
parents: 67
diff changeset
1747 gimple *stmt;
kono
parents: 67
diff changeset
1748 gimple_seq stmts;
kono
parents: 67
diff changeset
1749
kono
parents: 67
diff changeset
1750 chain->vars.create (n);
kono
parents: 67
diff changeset
1751
kono
parents: 67
diff changeset
1752 ref = DR_REF (get_chain_root (chain)->ref);
kono
parents: 67
diff changeset
1753 for (i = 0; i < n; i++)
kono
parents: 67
diff changeset
1754 {
kono
parents: 67
diff changeset
1755 var = predcom_tmp_var (ref, i, tmp_vars);
kono
parents: 67
diff changeset
1756 chain->vars.quick_push (var);
kono
parents: 67
diff changeset
1757 }
kono
parents: 67
diff changeset
1758
kono
parents: 67
diff changeset
1759 FOR_EACH_VEC_ELT (chain->vars, i, var)
kono
parents: 67
diff changeset
1760 chain->vars[i] = make_ssa_name (var);
kono
parents: 67
diff changeset
1761
kono
parents: 67
diff changeset
1762 /* Root values are either rhs operand of stores to be eliminated, or
kono
parents: 67
diff changeset
1763 loaded from memory before loop. */
kono
parents: 67
diff changeset
1764 auto_vec<tree> vtemps;
kono
parents: 67
diff changeset
1765 vtemps.safe_grow_cleared (n);
kono
parents: 67
diff changeset
1766 for (i = 0; i < n; i++)
kono
parents: 67
diff changeset
1767 {
kono
parents: 67
diff changeset
1768 init = get_init_expr (chain, i);
kono
parents: 67
diff changeset
1769 if (init == NULL_TREE)
kono
parents: 67
diff changeset
1770 {
kono
parents: 67
diff changeset
1771 /* Root value is rhs operand of the store to be eliminated if
kono
parents: 67
diff changeset
1772 it isn't loaded from memory before loop. */
kono
parents: 67
diff changeset
1773 dref a = get_chain_last_ref_at (chain, i);
kono
parents: 67
diff changeset
1774 val = gimple_assign_rhs1 (a->stmt);
kono
parents: 67
diff changeset
1775 if (TREE_CLOBBER_P (val))
kono
parents: 67
diff changeset
1776 val = get_or_create_ssa_default_def (cfun, SSA_NAME_VAR (var));
kono
parents: 67
diff changeset
1777
kono
parents: 67
diff changeset
1778 vtemps[n - i - 1] = val;
kono
parents: 67
diff changeset
1779 }
kono
parents: 67
diff changeset
1780 else
kono
parents: 67
diff changeset
1781 {
kono
parents: 67
diff changeset
1782 edge latch = loop_latch_edge (loop);
kono
parents: 67
diff changeset
1783 edge entry = loop_preheader_edge (loop);
kono
parents: 67
diff changeset
1784
kono
parents: 67
diff changeset
1785 /* Root value is loaded from memory before loop, we also need
kono
parents: 67
diff changeset
1786 to add PHI nodes to propagate the value across iterations. */
kono
parents: 67
diff changeset
1787 init = force_gimple_operand (init, &stmts, true, NULL_TREE);
kono
parents: 67
diff changeset
1788 if (stmts)
kono
parents: 67
diff changeset
1789 gsi_insert_seq_on_edge_immediate (entry, stmts);
kono
parents: 67
diff changeset
1790
kono
parents: 67
diff changeset
1791 next = chain->vars[n - i];
kono
parents: 67
diff changeset
1792 phi_result = copy_ssa_name (next);
kono
parents: 67
diff changeset
1793 gphi *phi = create_phi_node (phi_result, loop->header);
kono
parents: 67
diff changeset
1794 add_phi_arg (phi, init, entry, UNKNOWN_LOCATION);
kono
parents: 67
diff changeset
1795 add_phi_arg (phi, next, latch, UNKNOWN_LOCATION);
kono
parents: 67
diff changeset
1796 vtemps[n - i - 1] = phi_result;
kono
parents: 67
diff changeset
1797 }
kono
parents: 67
diff changeset
1798 }
kono
parents: 67
diff changeset
1799
kono
parents: 67
diff changeset
1800 /* Find the insertion position. */
kono
parents: 67
diff changeset
1801 dref last = get_chain_root (chain);
kono
parents: 67
diff changeset
1802 for (i = 0; i < chain->refs.length (); i++)
kono
parents: 67
diff changeset
1803 {
kono
parents: 67
diff changeset
1804 if (chain->refs[i]->pos > last->pos)
kono
parents: 67
diff changeset
1805 last = chain->refs[i];
kono
parents: 67
diff changeset
1806 }
kono
parents: 67
diff changeset
1807
kono
parents: 67
diff changeset
1808 gimple_stmt_iterator gsi = gsi_for_stmt (last->stmt);
kono
parents: 67
diff changeset
1809
kono
parents: 67
diff changeset
1810 /* Insert statements copying root value to root variable. */
kono
parents: 67
diff changeset
1811 for (i = 0; i < n; i++)
kono
parents: 67
diff changeset
1812 {
kono
parents: 67
diff changeset
1813 var = chain->vars[i];
kono
parents: 67
diff changeset
1814 val = vtemps[i];
kono
parents: 67
diff changeset
1815 stmt = gimple_build_assign (var, val);
kono
parents: 67
diff changeset
1816 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
kono
parents: 67
diff changeset
1817 }
kono
parents: 67
diff changeset
1818 }
kono
parents: 67
diff changeset
1819
kono
parents: 67
diff changeset
1820 /* Generates stores for CHAIN's eliminated stores in LOOP's last
kono
parents: 67
diff changeset
1821 (CHAIN->length - 1) iterations. */
kono
parents: 67
diff changeset
1822
kono
parents: 67
diff changeset
1823 static void
kono
parents: 67
diff changeset
1824 finalize_eliminated_stores (struct loop *loop, chain_p chain)
kono
parents: 67
diff changeset
1825 {
kono
parents: 67
diff changeset
1826 unsigned i, n = chain->length;
kono
parents: 67
diff changeset
1827
kono
parents: 67
diff changeset
1828 for (i = 0; i < n; i++)
kono
parents: 67
diff changeset
1829 {
kono
parents: 67
diff changeset
1830 tree var = chain->vars[i];
kono
parents: 67
diff changeset
1831 tree fini = chain->finis[n - i - 1];
kono
parents: 67
diff changeset
1832 gimple *stmt = gimple_build_assign (fini, var);
kono
parents: 67
diff changeset
1833
kono
parents: 67
diff changeset
1834 gimple_seq_add_stmt_without_update (&chain->fini_seq, stmt);
kono
parents: 67
diff changeset
1835 }
kono
parents: 67
diff changeset
1836
kono
parents: 67
diff changeset
1837 if (chain->fini_seq)
kono
parents: 67
diff changeset
1838 {
kono
parents: 67
diff changeset
1839 gsi_insert_seq_on_edge_immediate (single_exit (loop), chain->fini_seq);
kono
parents: 67
diff changeset
1840 chain->fini_seq = NULL;
kono
parents: 67
diff changeset
1841 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1842 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1843
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1844 /* 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
1845 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
1846 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
1847 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
1848 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
1849 initializer. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1850
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1851 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1852 initialize_root_vars_lm (struct loop *loop, dref root, bool written,
111
kono
parents: 67
diff changeset
1853 vec<tree> *vars, vec<tree> inits,
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1854 bitmap tmp_vars)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1855 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1856 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1857 tree ref = DR_REF (root->ref), init, var, next;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1858 gimple_seq stmts;
111
kono
parents: 67
diff changeset
1859 gphi *phi;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1860 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
1861
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1862 /* 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
1863 trap. */
111
kono
parents: 67
diff changeset
1864 init = inits[0];
kono
parents: 67
diff changeset
1865
kono
parents: 67
diff changeset
1866 vars->create (written ? 2 : 1);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1867 var = predcom_tmp_var (ref, 0, tmp_vars);
111
kono
parents: 67
diff changeset
1868 vars->quick_push (var);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1869 if (written)
111
kono
parents: 67
diff changeset
1870 vars->quick_push ((*vars)[0]);
kono
parents: 67
diff changeset
1871
kono
parents: 67
diff changeset
1872 FOR_EACH_VEC_ELT (*vars, i, var)
kono
parents: 67
diff changeset
1873 (*vars)[i] = make_ssa_name (var);
kono
parents: 67
diff changeset
1874
kono
parents: 67
diff changeset
1875 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
1876
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1877 init = force_gimple_operand (init, &stmts, written, NULL_TREE);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1878 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
1879 gsi_insert_seq_on_edge_immediate (entry, stmts);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1880
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1881 if (written)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1882 {
111
kono
parents: 67
diff changeset
1883 next = (*vars)[1];
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1884 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
1885 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
1886 add_phi_arg (phi, next, latch, UNKNOWN_LOCATION);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1887 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1888 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1889 {
111
kono
parents: 67
diff changeset
1890 gassign *init_stmt = gimple_build_assign (var, init);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1891 gsi_insert_on_edge_immediate (entry, init_stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1892 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1893 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1894
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1895
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1896 /* 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
1897 created temporary variables are marked in TMP_VARS. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1898
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1899 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1900 execute_load_motion (struct loop *loop, chain_p chain, bitmap tmp_vars)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1901 {
111
kono
parents: 67
diff changeset
1902 auto_vec<tree> vars;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1903 dref a;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1904 unsigned n_writes = 0, ridx, i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1905 tree var;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1906
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1907 gcc_assert (chain->type == CT_INVARIANT);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1908 gcc_assert (!chain->combined);
111
kono
parents: 67
diff changeset
1909 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
1910 if (DR_IS_WRITE (a->ref))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1911 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
1912
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1913 /* If there are no reads in the loop, there is nothing to do. */
111
kono
parents: 67
diff changeset
1914 if (n_writes == chain->refs.length ())
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1915 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1916
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1917 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
1918 &vars, chain->inits, tmp_vars);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1919
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1920 ridx = 0;
111
kono
parents: 67
diff changeset
1921 FOR_EACH_VEC_ELT (chain->refs, i, a)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1922 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1923 bool is_read = DR_IS_READ (a->ref);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1924
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
1925 if (DR_IS_WRITE (a->ref))
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 n_writes--;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1928 if (n_writes)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1929 {
111
kono
parents: 67
diff changeset
1930 var = vars[0];
kono
parents: 67
diff changeset
1931 var = make_ssa_name (SSA_NAME_VAR (var));
kono
parents: 67
diff changeset
1932 vars[0] = var;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1933 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1934 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1935 ridx = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1936 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1937
111
kono
parents: 67
diff changeset
1938 replace_ref_with (a->stmt, vars[ridx],
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1939 !is_read, !is_read);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1940 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1941 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1942
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1943 /* Returns the single statement in that NAME is used, excepting
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1944 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
1945 such statement, or more statements, NULL is returned. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1946
111
kono
parents: 67
diff changeset
1947 static gimple *
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1948 single_nonlooparound_use (tree name)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1949 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1950 use_operand_p use;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1951 imm_use_iterator it;
111
kono
parents: 67
diff changeset
1952 gimple *stmt, *ret = NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1953
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1954 FOR_EACH_IMM_USE_FAST (use, it, name)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1955 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1956 stmt = USE_STMT (use);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1957
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1958 if (gimple_code (stmt) == GIMPLE_PHI)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1959 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1960 /* 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
1961 could not be processed anyway, so just fail for them. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1962 if (bitmap_bit_p (looparound_phis,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1963 SSA_NAME_VERSION (PHI_RESULT (stmt))))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1964 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1965
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1966 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1967 }
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
1968 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
1969 continue;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1970 else if (ret != NULL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1971 return NULL;
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 ret = stmt;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1974 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1975
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1976 return ret;
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 /* 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
1980 used. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1981
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1982 static void
111
kono
parents: 67
diff changeset
1983 remove_stmt (gimple *stmt)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1984 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1985 tree name;
111
kono
parents: 67
diff changeset
1986 gimple *next;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1987 gimple_stmt_iterator psi;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1988
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1989 if (gimple_code (stmt) == GIMPLE_PHI)
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 name = PHI_RESULT (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1992 next = single_nonlooparound_use (name);
111
kono
parents: 67
diff changeset
1993 reset_debug_uses (stmt);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1994 psi = gsi_for_stmt (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1995 remove_phi_node (&psi, true);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1996
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1997 if (!next
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1998 || !gimple_assign_ssa_name_copy_p (next)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1999 || gimple_assign_rhs1 (next) != name)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2000 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2001
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2002 stmt = next;
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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2005 while (1)
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 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
2008
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2009 bsi = gsi_for_stmt (stmt);
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 name = gimple_assign_lhs (stmt);
111
kono
parents: 67
diff changeset
2012 if (TREE_CODE (name) == SSA_NAME)
kono
parents: 67
diff changeset
2013 {
kono
parents: 67
diff changeset
2014 next = single_nonlooparound_use (name);
kono
parents: 67
diff changeset
2015 reset_debug_uses (stmt);
kono
parents: 67
diff changeset
2016 }
kono
parents: 67
diff changeset
2017 else
kono
parents: 67
diff changeset
2018 {
kono
parents: 67
diff changeset
2019 /* This is a store to be eliminated. */
kono
parents: 67
diff changeset
2020 gcc_assert (gimple_vdef (stmt) != NULL);
kono
parents: 67
diff changeset
2021 next = NULL;
kono
parents: 67
diff changeset
2022 }
kono
parents: 67
diff changeset
2023
kono
parents: 67
diff changeset
2024 unlink_stmt_vdef (stmt);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2025 gsi_remove (&bsi, true);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2026 release_defs (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2027
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2028 if (!next
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2029 || !gimple_assign_ssa_name_copy_p (next)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2030 || gimple_assign_rhs1 (next) != name)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2031 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2032
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2033 stmt = next;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2034 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2035 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2036
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2037 /* Perform the predictive commoning optimization for a chain CHAIN.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2038 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
2039
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2040 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2041 execute_pred_commoning_chain (struct loop *loop, chain_p chain,
111
kono
parents: 67
diff changeset
2042 bitmap tmp_vars)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2043 {
111
kono
parents: 67
diff changeset
2044 unsigned i, n;
kono
parents: 67
diff changeset
2045 dref a;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2046 tree var;
111
kono
parents: 67
diff changeset
2047 bool in_lhs;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2048
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2049 if (chain->combined)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2050 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2051 /* For combined chains, just remove the statements that are used to
111
kono
parents: 67
diff changeset
2052 compute the values of the expression (except for the root one).
kono
parents: 67
diff changeset
2053 We delay this until after all chains are processed. */
kono
parents: 67
diff changeset
2054 }
kono
parents: 67
diff changeset
2055 else if (chain->type == CT_STORE_STORE)
kono
parents: 67
diff changeset
2056 {
kono
parents: 67
diff changeset
2057 if (chain->length > 0)
kono
parents: 67
diff changeset
2058 {
kono
parents: 67
diff changeset
2059 if (chain->inv_store_elimination)
kono
parents: 67
diff changeset
2060 {
kono
parents: 67
diff changeset
2061 /* If dead stores in this chain only store loop invariant
kono
parents: 67
diff changeset
2062 values, we can simply record the invariant value and use
kono
parents: 67
diff changeset
2063 it directly after loop. */
kono
parents: 67
diff changeset
2064 initialize_root_vars_store_elim_1 (chain);
kono
parents: 67
diff changeset
2065 }
kono
parents: 67
diff changeset
2066 else
kono
parents: 67
diff changeset
2067 {
kono
parents: 67
diff changeset
2068 /* If dead stores in this chain store loop variant values,
kono
parents: 67
diff changeset
2069 we need to set up the variables by loading from memory
kono
parents: 67
diff changeset
2070 before loop and propagating it with PHI nodes. */
kono
parents: 67
diff changeset
2071 initialize_root_vars_store_elim_2 (loop, chain, tmp_vars);
kono
parents: 67
diff changeset
2072 }
kono
parents: 67
diff changeset
2073
kono
parents: 67
diff changeset
2074 /* For inter-iteration store elimination chain, stores at each
kono
parents: 67
diff changeset
2075 distance in loop's last (chain->length - 1) iterations can't
kono
parents: 67
diff changeset
2076 be eliminated, because there is no following killing store.
kono
parents: 67
diff changeset
2077 We need to generate these stores after loop. */
kono
parents: 67
diff changeset
2078 finalize_eliminated_stores (loop, chain);
kono
parents: 67
diff changeset
2079 }
kono
parents: 67
diff changeset
2080
kono
parents: 67
diff changeset
2081 /* Eliminate the stores killed by following store. */
kono
parents: 67
diff changeset
2082 n = chain->refs.length ();
kono
parents: 67
diff changeset
2083 for (i = 0; i < n - 1; i++)
kono
parents: 67
diff changeset
2084 remove_stmt (chain->refs[i]->stmt);
0
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 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2087 {
111
kono
parents: 67
diff changeset
2088 /* For non-combined chains, set up the variables that hold its value. */
kono
parents: 67
diff changeset
2089 initialize_root_vars (loop, chain, tmp_vars);
kono
parents: 67
diff changeset
2090 a = get_chain_root (chain);
kono
parents: 67
diff changeset
2091 in_lhs = (chain->type == CT_STORE_LOAD
kono
parents: 67
diff changeset
2092 || chain->type == CT_COMBINATION);
kono
parents: 67
diff changeset
2093 replace_ref_with (a->stmt, chain->vars[chain->length], true, in_lhs);
kono
parents: 67
diff changeset
2094
kono
parents: 67
diff changeset
2095 /* Replace the uses of the original references by these variables. */
kono
parents: 67
diff changeset
2096 for (i = 1; chain->refs.iterate (i, &a); i++)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2097 {
111
kono
parents: 67
diff changeset
2098 var = chain->vars[chain->length - a->distance];
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2099 replace_ref_with (a->stmt, var, false, false);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2100 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2101 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2102 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2103
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2104 /* 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
2105 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
2106 optimized. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2107
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2108 static unsigned
111
kono
parents: 67
diff changeset
2109 determine_unroll_factor (vec<chain_p> chains)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2110 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2111 chain_p chain;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2112 unsigned factor = 1, af, nfactor, i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2113 unsigned max = PARAM_VALUE (PARAM_MAX_UNROLL_TIMES);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2114
111
kono
parents: 67
diff changeset
2115 FOR_EACH_VEC_ELT (chains, i, chain)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2116 {
111
kono
parents: 67
diff changeset
2117 if (chain->type == CT_INVARIANT)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2118 continue;
111
kono
parents: 67
diff changeset
2119 /* For now we can't handle unrolling when eliminating stores. */
kono
parents: 67
diff changeset
2120 else if (chain->type == CT_STORE_STORE)
kono
parents: 67
diff changeset
2121 return 1;
kono
parents: 67
diff changeset
2122
kono
parents: 67
diff changeset
2123 if (chain->combined)
kono
parents: 67
diff changeset
2124 {
kono
parents: 67
diff changeset
2125 /* For combined chains, we can't handle unrolling if we replace
kono
parents: 67
diff changeset
2126 looparound PHIs. */
kono
parents: 67
diff changeset
2127 dref a;
kono
parents: 67
diff changeset
2128 unsigned j;
kono
parents: 67
diff changeset
2129 for (j = 1; chain->refs.iterate (j, &a); j++)
kono
parents: 67
diff changeset
2130 if (gimple_code (a->stmt) == GIMPLE_PHI)
kono
parents: 67
diff changeset
2131 return 1;
kono
parents: 67
diff changeset
2132 continue;
kono
parents: 67
diff changeset
2133 }
0
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 /* 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
2136 temporary variables that we create for it. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2137 af = chain->length;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2138 if (chain->has_max_use_after)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2139 af++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2140
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2141 nfactor = factor * af / gcd (factor, af);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2142 if (nfactor <= max)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2143 factor = nfactor;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2144 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2145
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2146 return factor;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2147 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2148
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2149 /* Perform the predictive commoning optimization for CHAINS.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2150 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
2151
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2152 static void
111
kono
parents: 67
diff changeset
2153 execute_pred_commoning (struct loop *loop, vec<chain_p> chains,
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2154 bitmap tmp_vars)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2155 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2156 chain_p chain;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2157 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2158
111
kono
parents: 67
diff changeset
2159 FOR_EACH_VEC_ELT (chains, i, chain)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2160 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2161 if (chain->type == CT_INVARIANT)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2162 execute_load_motion (loop, chain, tmp_vars);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2163 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2164 execute_pred_commoning_chain (loop, chain, tmp_vars);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2165 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2166
111
kono
parents: 67
diff changeset
2167 FOR_EACH_VEC_ELT (chains, i, chain)
kono
parents: 67
diff changeset
2168 {
kono
parents: 67
diff changeset
2169 if (chain->type == CT_INVARIANT)
kono
parents: 67
diff changeset
2170 ;
kono
parents: 67
diff changeset
2171 else if (chain->combined)
kono
parents: 67
diff changeset
2172 {
kono
parents: 67
diff changeset
2173 /* For combined chains, just remove the statements that are used to
kono
parents: 67
diff changeset
2174 compute the values of the expression (except for the root one). */
kono
parents: 67
diff changeset
2175 dref a;
kono
parents: 67
diff changeset
2176 unsigned j;
kono
parents: 67
diff changeset
2177 for (j = 1; chain->refs.iterate (j, &a); j++)
kono
parents: 67
diff changeset
2178 remove_stmt (a->stmt);
kono
parents: 67
diff changeset
2179 }
kono
parents: 67
diff changeset
2180 }
kono
parents: 67
diff changeset
2181
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2182 update_ssa (TODO_update_ssa_only_virtuals);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2183 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2184
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2185 /* For each reference in CHAINS, if its defining statement is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2186 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
2187
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2188 static void
111
kono
parents: 67
diff changeset
2189 replace_phis_by_defined_names (vec<chain_p> chains)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2190 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2191 chain_p chain;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2192 dref a;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2193 unsigned i, j;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2194
111
kono
parents: 67
diff changeset
2195 FOR_EACH_VEC_ELT (chains, i, chain)
kono
parents: 67
diff changeset
2196 FOR_EACH_VEC_ELT (chain->refs, j, a)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2197 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2198 if (gimple_code (a->stmt) == GIMPLE_PHI)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2199 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2200 a->name_defined_by_phi = PHI_RESULT (a->stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2201 a->stmt = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2202 }
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 /* 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
2207 NULL, use it to set the stmt field. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2208
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2209 static void
111
kono
parents: 67
diff changeset
2210 replace_names_by_phis (vec<chain_p> chains)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2211 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2212 chain_p chain;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2213 dref a;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2214 unsigned i, j;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2215
111
kono
parents: 67
diff changeset
2216 FOR_EACH_VEC_ELT (chains, i, chain)
kono
parents: 67
diff changeset
2217 FOR_EACH_VEC_ELT (chain->refs, j, a)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2218 if (a->stmt == NULL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2219 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2220 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
2221 gcc_assert (gimple_code (a->stmt) == GIMPLE_PHI);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2222 a->name_defined_by_phi = NULL_TREE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2223 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2224 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2225
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2226 /* 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
2227 to tree_transform_and_unroll_loop. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2228
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2229 struct epcc_data
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2230 {
111
kono
parents: 67
diff changeset
2231 vec<chain_p> chains;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2232 bitmap tmp_vars;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2233 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2234
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2235 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2236 execute_pred_commoning_cbck (struct loop *loop, void *data)
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 struct epcc_data *const dta = (struct epcc_data *) data;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2239
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2240 /* Restore phi nodes that were replaced by ssa names before
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2241 tree_transform_and_unroll_loop (see detailed description in
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2242 tree_predictive_commoning_loop). */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2243 replace_names_by_phis (dta->chains);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2244 execute_pred_commoning (loop, dta->chains, dta->tmp_vars);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2245 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2246
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2247 /* 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
2248 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
2249 the header of the LOOP. */
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 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2252 base_names_in_chain_on (struct loop *loop, tree name, tree var)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2253 {
111
kono
parents: 67
diff changeset
2254 gimple *stmt, *phi;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2255 imm_use_iterator iter;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2256
111
kono
parents: 67
diff changeset
2257 replace_ssa_name_symbol (name, var);
0
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 while (1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2260 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2261 phi = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2262 FOR_EACH_IMM_USE_STMT (stmt, iter, name)
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 (gimple_code (stmt) == GIMPLE_PHI
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2265 && flow_bb_inside_loop_p (loop, gimple_bb (stmt)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2266 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2267 phi = stmt;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2268 BREAK_FROM_IMM_USE_STMT (iter);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2269 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2270 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2271 if (!phi)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2272 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2273
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2274 name = PHI_RESULT (phi);
111
kono
parents: 67
diff changeset
2275 replace_ssa_name_symbol (name, var);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2276 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2277 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2278
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2279 /* Given an unrolled LOOP after predictive commoning, remove the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2280 register copies arising from phi nodes by changing the base
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2281 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
2282 for those we want to perform this. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2283
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2284 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2285 eliminate_temp_copies (struct loop *loop, bitmap tmp_vars)
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 edge e;
111
kono
parents: 67
diff changeset
2288 gphi *phi;
kono
parents: 67
diff changeset
2289 gimple *stmt;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2290 tree name, use, var;
111
kono
parents: 67
diff changeset
2291 gphi_iterator psi;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2292
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2293 e = loop_latch_edge (loop);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2294 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
2295 {
111
kono
parents: 67
diff changeset
2296 phi = psi.phi ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2297 name = PHI_RESULT (phi);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2298 var = SSA_NAME_VAR (name);
111
kono
parents: 67
diff changeset
2299 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
2300 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2301 use = PHI_ARG_DEF_FROM_EDGE (phi, e);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2302 gcc_assert (TREE_CODE (use) == SSA_NAME);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2303
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2304 /* 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
2305 stmt = SSA_NAME_DEF_STMT (use);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2306 while (gimple_code (stmt) == GIMPLE_PHI
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2307 /* 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
2308 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
2309 statement (in that case, some register copies will be present
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2310 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
2311 created looparound phi nodes). */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2312 && gimple_bb (stmt) != loop->header)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2313 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2314 gcc_assert (single_pred_p (gimple_bb (stmt)));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2315 use = PHI_ARG_DEF (stmt, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2316 stmt = SSA_NAME_DEF_STMT (use);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2317 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2318
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2319 base_names_in_chain_on (loop, use, var);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2320 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2321 }
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 /* Returns true if CHAIN is suitable to be combined. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2324
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2325 static bool
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2326 chain_can_be_combined_p (chain_p chain)
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 return (!chain->combined
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2329 && (chain->type == CT_LOAD || chain->type == CT_COMBINATION));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2330 }
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 /* Returns the modify statement that uses NAME. Skips over assignment
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2333 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
2334 statement. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2335
111
kono
parents: 67
diff changeset
2336 static gimple *
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2337 find_use_stmt (tree *name)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2338 {
111
kono
parents: 67
diff changeset
2339 gimple *stmt;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2340 tree rhs, lhs;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2341
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2342 /* Skip over assignments. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2343 while (1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2344 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2345 stmt = single_nonlooparound_use (*name);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2346 if (!stmt)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2347 return NULL;
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 if (gimple_code (stmt) != GIMPLE_ASSIGN)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2350 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2351
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2352 lhs = gimple_assign_lhs (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2353 if (TREE_CODE (lhs) != SSA_NAME)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2354 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2355
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2356 if (gimple_assign_copy_p (stmt))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2357 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2358 rhs = gimple_assign_rhs1 (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2359 if (rhs != *name)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2360 return NULL;
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 *name = lhs;
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 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
2365 == GIMPLE_BINARY_RHS)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2366 return stmt;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2367 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2368 return NULL;
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 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2371
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2372 /* 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
2373
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2374 static bool
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2375 may_reassociate_p (tree type, enum tree_code code)
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 if (FLOAT_TYPE_P (type)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2378 && !flag_unsafe_math_optimizations)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2379 return false;
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 return (commutative_tree_code (code)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2382 && associative_tree_code (code));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2383 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2384
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2385 /* 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
2386 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
2387 is stored in DISTANCE. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2388
111
kono
parents: 67
diff changeset
2389 static gimple *
kono
parents: 67
diff changeset
2390 find_associative_operation_root (gimple *stmt, unsigned *distance)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2391 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2392 tree lhs;
111
kono
parents: 67
diff changeset
2393 gimple *next;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2394 enum tree_code code = gimple_assign_rhs_code (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2395 tree type = TREE_TYPE (gimple_assign_lhs (stmt));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2396 unsigned dist = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2397
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2398 if (!may_reassociate_p (type, code))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2399 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2400
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2401 while (1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2402 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2403 lhs = gimple_assign_lhs (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2404 gcc_assert (TREE_CODE (lhs) == SSA_NAME);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2405
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2406 next = find_use_stmt (&lhs);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2407 if (!next
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2408 || gimple_assign_rhs_code (next) != code)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2409 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2410
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2411 stmt = next;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2412 dist++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2413 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2414
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2415 if (distance)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2416 *distance = dist;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2417 return stmt;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2418 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2419
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2420 /* 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
2421 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
2422 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
2423 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
2424 NAME2. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2425
111
kono
parents: 67
diff changeset
2426 static gimple *
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2427 find_common_use_stmt (tree *name1, tree *name2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2428 {
111
kono
parents: 67
diff changeset
2429 gimple *stmt1, *stmt2;
0
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 stmt1 = find_use_stmt (name1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2432 if (!stmt1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2433 return NULL;
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 stmt2 = find_use_stmt (name2);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2436 if (!stmt2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2437 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2438
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2439 if (stmt1 == stmt2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2440 return stmt1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2441
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2442 stmt1 = find_associative_operation_root (stmt1, NULL);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2443 if (!stmt1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2444 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2445 stmt2 = find_associative_operation_root (stmt2, NULL);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2446 if (!stmt2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2447 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2448
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2449 return (stmt1 == stmt2 ? stmt1 : NULL);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2450 }
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 /* 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
2453 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
2454 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
2455
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2456 static bool
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2457 combinable_refs_p (dref r1, dref r2,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2458 enum tree_code *code, bool *swap, tree *rslt_type)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2459 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2460 enum tree_code acode;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2461 bool aswap;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2462 tree atype;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2463 tree name1, name2;
111
kono
parents: 67
diff changeset
2464 gimple *stmt;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2465
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2466 name1 = name_for_ref (r1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2467 name2 = name_for_ref (r2);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2468 gcc_assert (name1 != NULL_TREE && name2 != NULL_TREE);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2469
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2470 stmt = find_common_use_stmt (&name1, &name2);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2471
111
kono
parents: 67
diff changeset
2472 if (!stmt
kono
parents: 67
diff changeset
2473 /* A simple post-dominance check - make sure the combination
kono
parents: 67
diff changeset
2474 is executed under the same condition as the references. */
kono
parents: 67
diff changeset
2475 || (gimple_bb (stmt) != gimple_bb (r1->stmt)
kono
parents: 67
diff changeset
2476 && gimple_bb (stmt) != gimple_bb (r2->stmt)))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2477 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2478
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2479 acode = gimple_assign_rhs_code (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2480 aswap = (!commutative_tree_code (acode)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2481 && gimple_assign_rhs1 (stmt) != name1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2482 atype = TREE_TYPE (gimple_assign_lhs (stmt));
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 if (*code == ERROR_MARK)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2485 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2486 *code = acode;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2487 *swap = aswap;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2488 *rslt_type = atype;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2489 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2490 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2491
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2492 return (*code == acode
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2493 && *swap == aswap
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2494 && *rslt_type == atype);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2495 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2496
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2497 /* 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
2498 an assignment of the remaining operand. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2499
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2500 static void
111
kono
parents: 67
diff changeset
2501 remove_name_from_operation (gimple *stmt, tree op)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2502 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2503 tree other_op;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2504 gimple_stmt_iterator si;
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 gcc_assert (is_gimple_assign (stmt));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2507
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2508 if (gimple_assign_rhs1 (stmt) == op)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2509 other_op = gimple_assign_rhs2 (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2510 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2511 other_op = gimple_assign_rhs1 (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2512
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2513 si = gsi_for_stmt (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2514 gimple_assign_set_rhs_from_tree (&si, other_op);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2515
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2516 /* We should not have reallocated STMT. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2517 gcc_assert (gsi_stmt (si) == stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2518
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2519 update_stmt (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2520 }
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 /* Reassociates the expression in that NAME1 and NAME2 are used so that they
111
kono
parents: 67
diff changeset
2523 are combined in a single statement, and returns this statement. Note the
kono
parents: 67
diff changeset
2524 statement is inserted before INSERT_BEFORE if it's not NULL. */
kono
parents: 67
diff changeset
2525
kono
parents: 67
diff changeset
2526 static gimple *
kono
parents: 67
diff changeset
2527 reassociate_to_the_same_stmt (tree name1, tree name2, gimple *insert_before)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2528 {
111
kono
parents: 67
diff changeset
2529 gimple *stmt1, *stmt2, *root1, *root2, *s1, *s2;
kono
parents: 67
diff changeset
2530 gassign *new_stmt, *tmp_stmt;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2531 tree new_name, tmp_name, var, r1, r2;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2532 unsigned dist1, dist2;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2533 enum tree_code code;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2534 tree type = TREE_TYPE (name1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2535 gimple_stmt_iterator bsi;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2536
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2537 stmt1 = find_use_stmt (&name1);
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 root1 = find_associative_operation_root (stmt1, &dist1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2540 root2 = find_associative_operation_root (stmt2, &dist2);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2541 code = gimple_assign_rhs_code (stmt1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2542
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2543 gcc_assert (root1 && root2 && root1 == root2
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2544 && code == gimple_assign_rhs_code (stmt2));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2545
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2546 /* 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
2547 are used. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2548 r1 = name1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2549 s1 = stmt1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2550 r2 = name2;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2551 s2 = stmt2;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2552
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2553 while (dist1 > dist2)
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 s1 = find_use_stmt (&r1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2556 r1 = gimple_assign_lhs (s1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2557 dist1--;
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 while (dist2 > dist1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2560 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2561 s2 = find_use_stmt (&r2);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2562 r2 = gimple_assign_lhs (s2);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2563 dist2--;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2564 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2565
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2566 while (s1 != s2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2567 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2568 s1 = find_use_stmt (&r1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2569 r1 = gimple_assign_lhs (s1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2570 s2 = find_use_stmt (&r2);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2571 r2 = gimple_assign_lhs (s2);
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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2574 /* 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
2575 currently. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2576 remove_name_from_operation (stmt1, name1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2577 remove_name_from_operation (stmt2, name2);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2578
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2579 /* 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
2580 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
2581 var = create_tmp_reg (type, "predreastmp");
111
kono
parents: 67
diff changeset
2582 new_name = make_ssa_name (var);
kono
parents: 67
diff changeset
2583 new_stmt = gimple_build_assign (new_name, code, name1, name2);
kono
parents: 67
diff changeset
2584 if (insert_before && stmt_dominates_stmt_p (insert_before, s1))
kono
parents: 67
diff changeset
2585 bsi = gsi_for_stmt (insert_before);
kono
parents: 67
diff changeset
2586 else
kono
parents: 67
diff changeset
2587 bsi = gsi_for_stmt (s1);
kono
parents: 67
diff changeset
2588
kono
parents: 67
diff changeset
2589 gsi_insert_before (&bsi, new_stmt, GSI_SAME_STMT);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2590
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2591 var = create_tmp_reg (type, "predreastmp");
111
kono
parents: 67
diff changeset
2592 tmp_name = make_ssa_name (var);
0
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 /* 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
2595 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
2596 so that name1 or name2 was removed from it). */
111
kono
parents: 67
diff changeset
2597 tmp_stmt = gimple_build_assign (tmp_name, gimple_assign_rhs_code (s1),
kono
parents: 67
diff changeset
2598 gimple_assign_rhs1 (s1),
kono
parents: 67
diff changeset
2599 gimple_assign_rhs2 (s1));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2600
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2601 bsi = gsi_for_stmt (s1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2602 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
2603 s1 = gsi_stmt (bsi);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2604 update_stmt (s1);
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 gsi_insert_before (&bsi, tmp_stmt, GSI_SAME_STMT);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2607
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2608 return new_stmt;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2609 }
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 /* 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
2612 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
2613 associative and commutative operation in the same expression, reassociate
111
kono
parents: 67
diff changeset
2614 the expression so that they are used in the same statement. The combined
kono
parents: 67
diff changeset
2615 statement is inserted before INSERT_BEFORE if it's not NULL. */
kono
parents: 67
diff changeset
2616
kono
parents: 67
diff changeset
2617 static gimple *
kono
parents: 67
diff changeset
2618 stmt_combining_refs (dref r1, dref r2, gimple *insert_before)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2619 {
111
kono
parents: 67
diff changeset
2620 gimple *stmt1, *stmt2;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2621 tree name1 = name_for_ref (r1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2622 tree name2 = name_for_ref (r2);
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 stmt1 = find_use_stmt (&name1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2625 stmt2 = find_use_stmt (&name2);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2626 if (stmt1 == stmt2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2627 return stmt1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2628
111
kono
parents: 67
diff changeset
2629 return reassociate_to_the_same_stmt (name1, name2, insert_before);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2630 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2631
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2632 /* 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
2633 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
2634
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2635 static chain_p
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2636 combine_chains (chain_p ch1, chain_p ch2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2637 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2638 dref r1, r2, nw;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2639 enum tree_code op = ERROR_MARK;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2640 bool swap = false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2641 chain_p new_chain;
111
kono
parents: 67
diff changeset
2642 int i, j, num;
kono
parents: 67
diff changeset
2643 gimple *root_stmt;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2644 tree rslt_type = NULL_TREE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2645
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2646 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
2647 return NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2648 if (ch1->length != ch2->length)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2649 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2650
111
kono
parents: 67
diff changeset
2651 if (ch1->refs.length () != ch2->refs.length ())
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2652 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2653
111
kono
parents: 67
diff changeset
2654 for (i = 0; (ch1->refs.iterate (i, &r1)
kono
parents: 67
diff changeset
2655 && ch2->refs.iterate (i, &r2)); i++)
0
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 if (r1->distance != r2->distance)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2658 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2659
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2660 if (!combinable_refs_p (r1, r2, &op, &swap, &rslt_type))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2661 return NULL;
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
111
kono
parents: 67
diff changeset
2664 ch1->combined = true;
kono
parents: 67
diff changeset
2665 ch2->combined = true;
kono
parents: 67
diff changeset
2666
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2667 if (swap)
111
kono
parents: 67
diff changeset
2668 std::swap (ch1, ch2);
0
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 new_chain = XCNEW (struct chain);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2671 new_chain->type = CT_COMBINATION;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2672 new_chain->op = op;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2673 new_chain->ch1 = ch1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2674 new_chain->ch2 = ch2;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2675 new_chain->rslt_type = rslt_type;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2676 new_chain->length = ch1->length;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2677
111
kono
parents: 67
diff changeset
2678 gimple *insert = NULL;
kono
parents: 67
diff changeset
2679 num = ch1->refs.length ();
kono
parents: 67
diff changeset
2680 i = (new_chain->length == 0) ? num - 1 : 0;
kono
parents: 67
diff changeset
2681 j = (new_chain->length == 0) ? -1 : 1;
kono
parents: 67
diff changeset
2682 /* For ZERO length chain, process refs in reverse order so that dominant
kono
parents: 67
diff changeset
2683 position is ready when it comes to the root ref.
kono
parents: 67
diff changeset
2684 For non-ZERO length chain, process refs in order. See PR79663. */
kono
parents: 67
diff changeset
2685 for (; num > 0; num--, i += j)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2686 {
111
kono
parents: 67
diff changeset
2687 r1 = ch1->refs[i];
kono
parents: 67
diff changeset
2688 r2 = ch2->refs[i];
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2689 nw = XCNEW (struct dref_d);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2690 nw->distance = r1->distance;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2691
111
kono
parents: 67
diff changeset
2692 /* For ZERO length chain, insert combined stmt of root ref at dominant
kono
parents: 67
diff changeset
2693 position. */
kono
parents: 67
diff changeset
2694 nw->stmt = stmt_combining_refs (r1, r2, i == 0 ? insert : NULL);
kono
parents: 67
diff changeset
2695 /* For ZERO length chain, record dominant position where combined stmt
kono
parents: 67
diff changeset
2696 of root ref should be inserted. In this case, though all root refs
kono
parents: 67
diff changeset
2697 dominate following ones, it's possible that combined stmt doesn't.
kono
parents: 67
diff changeset
2698 See PR70754. */
kono
parents: 67
diff changeset
2699 if (new_chain->length == 0
kono
parents: 67
diff changeset
2700 && (insert == NULL || stmt_dominates_stmt_p (nw->stmt, insert)))
kono
parents: 67
diff changeset
2701 insert = nw->stmt;
kono
parents: 67
diff changeset
2702
kono
parents: 67
diff changeset
2703 new_chain->refs.safe_push (nw);
kono
parents: 67
diff changeset
2704 }
kono
parents: 67
diff changeset
2705 if (new_chain->length == 0)
kono
parents: 67
diff changeset
2706 {
kono
parents: 67
diff changeset
2707 /* Restore the order for ZERO length chain's refs. */
kono
parents: 67
diff changeset
2708 num = new_chain->refs.length () >> 1;
kono
parents: 67
diff changeset
2709 for (i = 0, j = new_chain->refs.length () - 1; i < num; i++, j--)
kono
parents: 67
diff changeset
2710 std::swap (new_chain->refs[i], new_chain->refs[j]);
kono
parents: 67
diff changeset
2711
kono
parents: 67
diff changeset
2712 /* For ZERO length chain, has_max_use_after must be true since root
kono
parents: 67
diff changeset
2713 combined stmt must dominates others. */
kono
parents: 67
diff changeset
2714 new_chain->has_max_use_after = true;
kono
parents: 67
diff changeset
2715 return new_chain;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2716 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2717
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2718 new_chain->has_max_use_after = false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2719 root_stmt = get_chain_root (new_chain)->stmt;
111
kono
parents: 67
diff changeset
2720 for (i = 1; new_chain->refs.iterate (i, &nw); i++)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2721 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2722 if (nw->distance == new_chain->length
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2723 && !stmt_dominates_stmt_p (nw->stmt, root_stmt))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2724 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2725 new_chain->has_max_use_after = true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2726 break;
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 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2729
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2730 return new_chain;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2731 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2732
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2733 /* Try to combine the CHAINS. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2734
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2735 static void
111
kono
parents: 67
diff changeset
2736 try_combine_chains (vec<chain_p> *chains)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2737 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2738 unsigned i, j;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2739 chain_p ch1, ch2, cch;
111
kono
parents: 67
diff changeset
2740 auto_vec<chain_p> worklist;
kono
parents: 67
diff changeset
2741
kono
parents: 67
diff changeset
2742 FOR_EACH_VEC_ELT (*chains, i, ch1)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2743 if (chain_can_be_combined_p (ch1))
111
kono
parents: 67
diff changeset
2744 worklist.safe_push (ch1);
kono
parents: 67
diff changeset
2745
kono
parents: 67
diff changeset
2746 while (!worklist.is_empty ())
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2747 {
111
kono
parents: 67
diff changeset
2748 ch1 = worklist.pop ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2749 if (!chain_can_be_combined_p (ch1))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2750 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2751
111
kono
parents: 67
diff changeset
2752 FOR_EACH_VEC_ELT (*chains, j, ch2)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2753 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2754 if (!chain_can_be_combined_p (ch2))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2755 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2756
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2757 cch = combine_chains (ch1, ch2);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2758 if (cch)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2759 {
111
kono
parents: 67
diff changeset
2760 worklist.safe_push (cch);
kono
parents: 67
diff changeset
2761 chains->safe_push (cch);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2762 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2763 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2764 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2765 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2766 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2767
111
kono
parents: 67
diff changeset
2768 /* Prepare initializers for store elimination CHAIN in LOOP. Returns false
kono
parents: 67
diff changeset
2769 if this is impossible because one of these initializers may trap, true
kono
parents: 67
diff changeset
2770 otherwise. */
kono
parents: 67
diff changeset
2771
kono
parents: 67
diff changeset
2772 static bool
kono
parents: 67
diff changeset
2773 prepare_initializers_chain_store_elim (struct loop *loop, chain_p chain)
kono
parents: 67
diff changeset
2774 {
kono
parents: 67
diff changeset
2775 unsigned i, n = chain->length;
kono
parents: 67
diff changeset
2776
kono
parents: 67
diff changeset
2777 /* For now we can't eliminate stores if some of them are conditional
kono
parents: 67
diff changeset
2778 executed. */
kono
parents: 67
diff changeset
2779 if (!chain->all_always_accessed)
kono
parents: 67
diff changeset
2780 return false;
kono
parents: 67
diff changeset
2781
kono
parents: 67
diff changeset
2782 /* Nothing to intialize for intra-iteration store elimination. */
kono
parents: 67
diff changeset
2783 if (n == 0 && chain->type == CT_STORE_STORE)
kono
parents: 67
diff changeset
2784 return true;
kono
parents: 67
diff changeset
2785
kono
parents: 67
diff changeset
2786 /* For store elimination chain, there is nothing to initialize if stores
kono
parents: 67
diff changeset
2787 to be eliminated only store loop invariant values into memory. */
kono
parents: 67
diff changeset
2788 if (chain->type == CT_STORE_STORE
kono
parents: 67
diff changeset
2789 && is_inv_store_elimination_chain (loop, chain))
kono
parents: 67
diff changeset
2790 {
kono
parents: 67
diff changeset
2791 chain->inv_store_elimination = true;
kono
parents: 67
diff changeset
2792 return true;
kono
parents: 67
diff changeset
2793 }
kono
parents: 67
diff changeset
2794
kono
parents: 67
diff changeset
2795 chain->inits.create (n);
kono
parents: 67
diff changeset
2796 chain->inits.safe_grow_cleared (n);
kono
parents: 67
diff changeset
2797
kono
parents: 67
diff changeset
2798 /* For store eliminatin chain like below:
kono
parents: 67
diff changeset
2799
kono
parents: 67
diff changeset
2800 for (i = 0; i < len; i++)
kono
parents: 67
diff changeset
2801 {
kono
parents: 67
diff changeset
2802 a[i] = 1;
kono
parents: 67
diff changeset
2803 // a[i + 1] = ...
kono
parents: 67
diff changeset
2804 a[i + 2] = 3;
kono
parents: 67
diff changeset
2805 }
kono
parents: 67
diff changeset
2806
kono
parents: 67
diff changeset
2807 store to a[i + 1] is missed in loop body, it acts like bubbles. The
kono
parents: 67
diff changeset
2808 content of a[i + 1] remain the same if the loop iterates fewer times
kono
parents: 67
diff changeset
2809 than chain->length. We need to set up root variables for such stores
kono
parents: 67
diff changeset
2810 by loading from memory before loop. Note we only need to load bubble
kono
parents: 67
diff changeset
2811 elements because loop body is guaranteed to be executed at least once
kono
parents: 67
diff changeset
2812 after loop's preheader edge. */
kono
parents: 67
diff changeset
2813 auto_vec<bool> bubbles;
kono
parents: 67
diff changeset
2814 bubbles.safe_grow_cleared (n + 1);
kono
parents: 67
diff changeset
2815 for (i = 0; i < chain->refs.length (); i++)
kono
parents: 67
diff changeset
2816 bubbles[chain->refs[i]->distance] = true;
kono
parents: 67
diff changeset
2817
kono
parents: 67
diff changeset
2818 struct data_reference *dr = get_chain_root (chain)->ref;
kono
parents: 67
diff changeset
2819 for (i = 0; i < n; i++)
kono
parents: 67
diff changeset
2820 {
kono
parents: 67
diff changeset
2821 if (bubbles[i])
kono
parents: 67
diff changeset
2822 continue;
kono
parents: 67
diff changeset
2823
kono
parents: 67
diff changeset
2824 gimple_seq stmts = NULL;
kono
parents: 67
diff changeset
2825
kono
parents: 67
diff changeset
2826 tree init = ref_at_iteration (dr, (int) 0 - i, &stmts);
kono
parents: 67
diff changeset
2827 if (stmts)
kono
parents: 67
diff changeset
2828 gimple_seq_add_seq_without_update (&chain->init_seq, stmts);
kono
parents: 67
diff changeset
2829
kono
parents: 67
diff changeset
2830 chain->inits[i] = init;
kono
parents: 67
diff changeset
2831 }
kono
parents: 67
diff changeset
2832
kono
parents: 67
diff changeset
2833 return true;
kono
parents: 67
diff changeset
2834 }
kono
parents: 67
diff changeset
2835
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2836 /* 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
2837 impossible because one of these initializers may trap, true otherwise. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2838
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2839 static bool
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2840 prepare_initializers_chain (struct loop *loop, chain_p chain)
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 unsigned i, n = (chain->type == CT_INVARIANT) ? 1 : chain->length;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2843 struct data_reference *dr = get_chain_root (chain)->ref;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2844 tree init;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2845 dref laref;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2846 edge entry = loop_preheader_edge (loop);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2847
111
kono
parents: 67
diff changeset
2848 if (chain->type == CT_STORE_STORE)
kono
parents: 67
diff changeset
2849 return prepare_initializers_chain_store_elim (loop, chain);
kono
parents: 67
diff changeset
2850
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2851 /* 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
2852 trap. */
111
kono
parents: 67
diff changeset
2853 chain->inits.create (n);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2854 for (i = 0; i < n; i++)
111
kono
parents: 67
diff changeset
2855 chain->inits.quick_push (NULL_TREE);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2856
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2857 /* 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
2858 instead of creating our own. */
111
kono
parents: 67
diff changeset
2859 FOR_EACH_VEC_ELT (chain->refs, i, laref)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2860 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2861 if (gimple_code (laref->stmt) != GIMPLE_PHI)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2862 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2863
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2864 gcc_assert (laref->distance > 0);
111
kono
parents: 67
diff changeset
2865 chain->inits[n - laref->distance]
kono
parents: 67
diff changeset
2866 = PHI_ARG_DEF_FROM_EDGE (laref->stmt, entry);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2867 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2868
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2869 for (i = 0; i < n; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2870 {
111
kono
parents: 67
diff changeset
2871 gimple_seq stmts = NULL;
kono
parents: 67
diff changeset
2872
kono
parents: 67
diff changeset
2873 if (chain->inits[i] != NULL_TREE)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2874 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2875
111
kono
parents: 67
diff changeset
2876 init = ref_at_iteration (dr, (int) i - n, &stmts);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2877 if (!chain->all_always_accessed && tree_could_trap_p (init))
111
kono
parents: 67
diff changeset
2878 {
kono
parents: 67
diff changeset
2879 gimple_seq_discard (stmts);
kono
parents: 67
diff changeset
2880 return false;
kono
parents: 67
diff changeset
2881 }
kono
parents: 67
diff changeset
2882
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2883 if (stmts)
111
kono
parents: 67
diff changeset
2884 gimple_seq_add_seq_without_update (&chain->init_seq, stmts);
kono
parents: 67
diff changeset
2885
kono
parents: 67
diff changeset
2886 chain->inits[i] = init;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2887 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2888
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2889 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2890 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2891
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2892 /* 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
2893 be used because the initializers might trap. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2894
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2895 static void
111
kono
parents: 67
diff changeset
2896 prepare_initializers (struct loop *loop, vec<chain_p> chains)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2897 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2898 chain_p chain;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2899 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2900
111
kono
parents: 67
diff changeset
2901 for (i = 0; i < chains.length (); )
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2902 {
111
kono
parents: 67
diff changeset
2903 chain = chains[i];
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2904 if (prepare_initializers_chain (loop, chain))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2905 i++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2906 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2907 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2908 release_chain (chain);
111
kono
parents: 67
diff changeset
2909 chains.unordered_remove (i);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2910 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2911 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2912 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2913
111
kono
parents: 67
diff changeset
2914 /* Generates finalizer memory references for CHAIN in LOOP. Returns true
kono
parents: 67
diff changeset
2915 if finalizer code for CHAIN can be generated, otherwise false. */
kono
parents: 67
diff changeset
2916
kono
parents: 67
diff changeset
2917 static bool
kono
parents: 67
diff changeset
2918 prepare_finalizers_chain (struct loop *loop, chain_p chain)
kono
parents: 67
diff changeset
2919 {
kono
parents: 67
diff changeset
2920 unsigned i, n = chain->length;
kono
parents: 67
diff changeset
2921 struct data_reference *dr = get_chain_root (chain)->ref;
kono
parents: 67
diff changeset
2922 tree fini, niters = number_of_latch_executions (loop);
kono
parents: 67
diff changeset
2923
kono
parents: 67
diff changeset
2924 /* For now we can't eliminate stores if some of them are conditional
kono
parents: 67
diff changeset
2925 executed. */
kono
parents: 67
diff changeset
2926 if (!chain->all_always_accessed)
kono
parents: 67
diff changeset
2927 return false;
kono
parents: 67
diff changeset
2928
kono
parents: 67
diff changeset
2929 chain->finis.create (n);
kono
parents: 67
diff changeset
2930 for (i = 0; i < n; i++)
kono
parents: 67
diff changeset
2931 chain->finis.quick_push (NULL_TREE);
kono
parents: 67
diff changeset
2932
kono
parents: 67
diff changeset
2933 /* We never use looparound phi node for store elimination chains. */
kono
parents: 67
diff changeset
2934
kono
parents: 67
diff changeset
2935 /* Find the finalizers for the variables, and check that they cannot
kono
parents: 67
diff changeset
2936 trap. */
kono
parents: 67
diff changeset
2937 for (i = 0; i < n; i++)
kono
parents: 67
diff changeset
2938 {
kono
parents: 67
diff changeset
2939 gimple_seq stmts = NULL;
kono
parents: 67
diff changeset
2940 gcc_assert (chain->finis[i] == NULL_TREE);
kono
parents: 67
diff changeset
2941
kono
parents: 67
diff changeset
2942 if (TREE_CODE (niters) != INTEGER_CST && TREE_CODE (niters) != SSA_NAME)
kono
parents: 67
diff changeset
2943 {
kono
parents: 67
diff changeset
2944 niters = unshare_expr (niters);
kono
parents: 67
diff changeset
2945 niters = force_gimple_operand (niters, &stmts, true, NULL);
kono
parents: 67
diff changeset
2946 if (stmts)
kono
parents: 67
diff changeset
2947 {
kono
parents: 67
diff changeset
2948 gimple_seq_add_seq_without_update (&chain->fini_seq, stmts);
kono
parents: 67
diff changeset
2949 stmts = NULL;
kono
parents: 67
diff changeset
2950 }
kono
parents: 67
diff changeset
2951 }
kono
parents: 67
diff changeset
2952 fini = ref_at_iteration (dr, (int) 0 - i, &stmts, niters);
kono
parents: 67
diff changeset
2953 if (stmts)
kono
parents: 67
diff changeset
2954 gimple_seq_add_seq_without_update (&chain->fini_seq, stmts);
kono
parents: 67
diff changeset
2955
kono
parents: 67
diff changeset
2956 chain->finis[i] = fini;
kono
parents: 67
diff changeset
2957 }
kono
parents: 67
diff changeset
2958
kono
parents: 67
diff changeset
2959 return true;
kono
parents: 67
diff changeset
2960 }
kono
parents: 67
diff changeset
2961
kono
parents: 67
diff changeset
2962 /* Generates finalizer memory reference for CHAINS in LOOP. Returns true
kono
parents: 67
diff changeset
2963 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
2964
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2965 static bool
111
kono
parents: 67
diff changeset
2966 prepare_finalizers (struct loop *loop, vec<chain_p> chains)
kono
parents: 67
diff changeset
2967 {
kono
parents: 67
diff changeset
2968 chain_p chain;
kono
parents: 67
diff changeset
2969 unsigned i;
kono
parents: 67
diff changeset
2970 bool loop_closed_ssa = false;
kono
parents: 67
diff changeset
2971
kono
parents: 67
diff changeset
2972 for (i = 0; i < chains.length ();)
kono
parents: 67
diff changeset
2973 {
kono
parents: 67
diff changeset
2974 chain = chains[i];
kono
parents: 67
diff changeset
2975
kono
parents: 67
diff changeset
2976 /* Finalizer is only necessary for inter-iteration store elimination
kono
parents: 67
diff changeset
2977 chains. */
kono
parents: 67
diff changeset
2978 if (chain->length == 0 || chain->type != CT_STORE_STORE)
kono
parents: 67
diff changeset
2979 {
kono
parents: 67
diff changeset
2980 i++;
kono
parents: 67
diff changeset
2981 continue;
kono
parents: 67
diff changeset
2982 }
kono
parents: 67
diff changeset
2983
kono
parents: 67
diff changeset
2984 if (prepare_finalizers_chain (loop, chain))
kono
parents: 67
diff changeset
2985 {
kono
parents: 67
diff changeset
2986 i++;
kono
parents: 67
diff changeset
2987 /* Be conservative, assume loop closed ssa form is corrupted
kono
parents: 67
diff changeset
2988 by store-store chain. Though it's not always the case if
kono
parents: 67
diff changeset
2989 eliminated stores only store loop invariant values into
kono
parents: 67
diff changeset
2990 memory. */
kono
parents: 67
diff changeset
2991 loop_closed_ssa = true;
kono
parents: 67
diff changeset
2992 }
kono
parents: 67
diff changeset
2993 else
kono
parents: 67
diff changeset
2994 {
kono
parents: 67
diff changeset
2995 release_chain (chain);
kono
parents: 67
diff changeset
2996 chains.unordered_remove (i);
kono
parents: 67
diff changeset
2997 }
kono
parents: 67
diff changeset
2998 }
kono
parents: 67
diff changeset
2999 return loop_closed_ssa;
kono
parents: 67
diff changeset
3000 }
kono
parents: 67
diff changeset
3001
kono
parents: 67
diff changeset
3002 /* Insert all initializing gimple stmts into loop's entry edge. */
kono
parents: 67
diff changeset
3003
kono
parents: 67
diff changeset
3004 static void
kono
parents: 67
diff changeset
3005 insert_init_seqs (struct loop *loop, vec<chain_p> chains)
kono
parents: 67
diff changeset
3006 {
kono
parents: 67
diff changeset
3007 unsigned i;
kono
parents: 67
diff changeset
3008 edge entry = loop_preheader_edge (loop);
kono
parents: 67
diff changeset
3009
kono
parents: 67
diff changeset
3010 for (i = 0; i < chains.length (); ++i)
kono
parents: 67
diff changeset
3011 if (chains[i]->init_seq)
kono
parents: 67
diff changeset
3012 {
kono
parents: 67
diff changeset
3013 gsi_insert_seq_on_edge_immediate (entry, chains[i]->init_seq);
kono
parents: 67
diff changeset
3014 chains[i]->init_seq = NULL;
kono
parents: 67
diff changeset
3015 }
kono
parents: 67
diff changeset
3016 }
kono
parents: 67
diff changeset
3017
kono
parents: 67
diff changeset
3018 /* Performs predictive commoning for LOOP. Sets bit 1<<0 of return value
kono
parents: 67
diff changeset
3019 if LOOP was unrolled; Sets bit 1<<1 of return value if loop closed ssa
kono
parents: 67
diff changeset
3020 form was corrupted. */
kono
parents: 67
diff changeset
3021
kono
parents: 67
diff changeset
3022 static unsigned
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3023 tree_predictive_commoning_loop (struct loop *loop)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3024 {
111
kono
parents: 67
diff changeset
3025 vec<data_reference_p> datarefs;
kono
parents: 67
diff changeset
3026 vec<ddr_p> dependences;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3027 struct component *components;
111
kono
parents: 67
diff changeset
3028 vec<chain_p> chains = vNULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3029 unsigned unroll_factor;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3030 struct tree_niter_desc desc;
111
kono
parents: 67
diff changeset
3031 bool unroll = false, loop_closed_ssa = false;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3032 edge exit;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3033
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3034 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3035 fprintf (dump_file, "Processing loop %d\n", loop->num);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3036
111
kono
parents: 67
diff changeset
3037 /* Nothing for predicitive commoning if loop only iterates 1 time. */
kono
parents: 67
diff changeset
3038 if (get_max_loop_iterations_int (loop) == 0)
kono
parents: 67
diff changeset
3039 {
kono
parents: 67
diff changeset
3040 if (dump_file && (dump_flags & TDF_DETAILS))
kono
parents: 67
diff changeset
3041 fprintf (dump_file, "Loop iterates only 1 time, nothing to do.\n");
kono
parents: 67
diff changeset
3042
kono
parents: 67
diff changeset
3043 return 0;
kono
parents: 67
diff changeset
3044 }
kono
parents: 67
diff changeset
3045
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3046 /* 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
3047 dependence relations. */
111
kono
parents: 67
diff changeset
3048 auto_vec<loop_p, 3> loop_nest;
kono
parents: 67
diff changeset
3049 dependences.create (10);
kono
parents: 67
diff changeset
3050 datarefs.create (10);
kono
parents: 67
diff changeset
3051 if (! compute_data_dependences_for_loop (loop, true, &loop_nest, &datarefs,
kono
parents: 67
diff changeset
3052 &dependences))
kono
parents: 67
diff changeset
3053 {
kono
parents: 67
diff changeset
3054 if (dump_file && (dump_flags & TDF_DETAILS))
kono
parents: 67
diff changeset
3055 fprintf (dump_file, "Cannot analyze data dependencies\n");
kono
parents: 67
diff changeset
3056 free_data_refs (datarefs);
kono
parents: 67
diff changeset
3057 free_dependence_relations (dependences);
kono
parents: 67
diff changeset
3058 return 0;
kono
parents: 67
diff changeset
3059 }
kono
parents: 67
diff changeset
3060
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3061 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3062 dump_data_dependence_relations (dump_file, dependences);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3063
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3064 components = split_data_refs_to_components (loop, datarefs, dependences);
111
kono
parents: 67
diff changeset
3065 loop_nest.release ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3066 free_dependence_relations (dependences);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3067 if (!components)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3068 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3069 free_data_refs (datarefs);
111
kono
parents: 67
diff changeset
3070 free_affine_expand_cache (&name_expansions);
kono
parents: 67
diff changeset
3071 return 0;
0
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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3074 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3075 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3076 fprintf (dump_file, "Initial state:\n\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3077 dump_components (dump_file, components);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3078 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3079
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3080 /* Find the suitable components and split them into chains. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3081 components = filter_suitable_components (loop, components);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3082
111
kono
parents: 67
diff changeset
3083 auto_bitmap tmp_vars;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3084 looparound_phis = BITMAP_ALLOC (NULL);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3085 determine_roots (loop, components, &chains);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3086 release_components (components);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3087
111
kono
parents: 67
diff changeset
3088 if (!chains.exists ())
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3089 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3090 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3091 fprintf (dump_file,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3092 "Predictive commoning failed: no suitable chains\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3093 goto end;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3094 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3095 prepare_initializers (loop, chains);
111
kono
parents: 67
diff changeset
3096 loop_closed_ssa = prepare_finalizers (loop, chains);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3097
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3098 /* Try to combine the chains that are always worked with together. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3099 try_combine_chains (&chains);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3100
111
kono
parents: 67
diff changeset
3101 insert_init_seqs (loop, chains);
kono
parents: 67
diff changeset
3102
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3103 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3104 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3105 fprintf (dump_file, "Before commoning:\n\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3106 dump_chains (dump_file, chains);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3107 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3108
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3109 /* 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
3110 that its number of iterations is divisible by the factor. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3111 unroll_factor = determine_unroll_factor (chains);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3112 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
3113 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
3114 && can_unroll_loop_p (loop, unroll_factor, &desc));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3115 exit = single_dom_exit (loop);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3116
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3117 /* Execute the predictive commoning transformations, and possibly unroll the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3118 loop. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3119 if (unroll)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3120 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3121 struct epcc_data dta;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3122
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3123 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3124 fprintf (dump_file, "Unrolling %u times.\n", unroll_factor);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3125
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3126 dta.chains = chains;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3127 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
3128
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3129 update_ssa (TODO_update_ssa_only_virtuals);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3130
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3131 /* Cfg manipulations performed in tree_transform_and_unroll_loop before
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3132 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
3133 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
3134 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
3135 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
3136 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
3137 replace_phis_by_defined_names (chains);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3138
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3139 tree_transform_and_unroll_loop (loop, unroll_factor, exit, &desc,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3140 execute_pred_commoning_cbck, &dta);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3141 eliminate_temp_copies (loop, tmp_vars);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3142 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3143 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3144 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3145 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3146 fprintf (dump_file,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3147 "Executing predictive commoning without unrolling.\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3148 execute_pred_commoning (loop, chains, tmp_vars);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3149 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3150
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3151 end: ;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3152 release_chains (chains);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3153 free_data_refs (datarefs);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3154 BITMAP_FREE (looparound_phis);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3155
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3156 free_affine_expand_cache (&name_expansions);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3157
111
kono
parents: 67
diff changeset
3158 return (unroll ? 1 : 0) | (loop_closed_ssa ? 2 : 0);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3159 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3160
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3161 /* Runs predictive commoning. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3162
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3163 unsigned
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3164 tree_predictive_commoning (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3165 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3166 struct loop *loop;
111
kono
parents: 67
diff changeset
3167 unsigned ret = 0, changed = 0;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3168
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3169 initialize_original_copy_tables ();
111
kono
parents: 67
diff changeset
3170 FOR_EACH_LOOP (loop, LI_ONLY_INNERMOST)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3171 if (optimize_loop_for_speed_p (loop))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3172 {
111
kono
parents: 67
diff changeset
3173 changed |= tree_predictive_commoning_loop (loop);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3174 }
111
kono
parents: 67
diff changeset
3175 free_original_copy_tables ();
kono
parents: 67
diff changeset
3176
kono
parents: 67
diff changeset
3177 if (changed > 0)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3178 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3179 scev_reset ();
111
kono
parents: 67
diff changeset
3180
kono
parents: 67
diff changeset
3181 if (changed > 1)
kono
parents: 67
diff changeset
3182 rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
kono
parents: 67
diff changeset
3183
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3184 ret = TODO_cleanup_cfg;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3185 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3186
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3187 return ret;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3188 }
111
kono
parents: 67
diff changeset
3189
kono
parents: 67
diff changeset
3190 /* Predictive commoning Pass. */
kono
parents: 67
diff changeset
3191
kono
parents: 67
diff changeset
3192 static unsigned
kono
parents: 67
diff changeset
3193 run_tree_predictive_commoning (struct function *fun)
kono
parents: 67
diff changeset
3194 {
kono
parents: 67
diff changeset
3195 if (number_of_loops (fun) <= 1)
kono
parents: 67
diff changeset
3196 return 0;
kono
parents: 67
diff changeset
3197
kono
parents: 67
diff changeset
3198 return tree_predictive_commoning ();
kono
parents: 67
diff changeset
3199 }
kono
parents: 67
diff changeset
3200
kono
parents: 67
diff changeset
3201 namespace {
kono
parents: 67
diff changeset
3202
kono
parents: 67
diff changeset
3203 const pass_data pass_data_predcom =
kono
parents: 67
diff changeset
3204 {
kono
parents: 67
diff changeset
3205 GIMPLE_PASS, /* type */
kono
parents: 67
diff changeset
3206 "pcom", /* name */
kono
parents: 67
diff changeset
3207 OPTGROUP_LOOP, /* optinfo_flags */
kono
parents: 67
diff changeset
3208 TV_PREDCOM, /* tv_id */
kono
parents: 67
diff changeset
3209 PROP_cfg, /* properties_required */
kono
parents: 67
diff changeset
3210 0, /* properties_provided */
kono
parents: 67
diff changeset
3211 0, /* properties_destroyed */
kono
parents: 67
diff changeset
3212 0, /* todo_flags_start */
kono
parents: 67
diff changeset
3213 TODO_update_ssa_only_virtuals, /* todo_flags_finish */
kono
parents: 67
diff changeset
3214 };
kono
parents: 67
diff changeset
3215
kono
parents: 67
diff changeset
3216 class pass_predcom : public gimple_opt_pass
kono
parents: 67
diff changeset
3217 {
kono
parents: 67
diff changeset
3218 public:
kono
parents: 67
diff changeset
3219 pass_predcom (gcc::context *ctxt)
kono
parents: 67
diff changeset
3220 : gimple_opt_pass (pass_data_predcom, ctxt)
kono
parents: 67
diff changeset
3221 {}
kono
parents: 67
diff changeset
3222
kono
parents: 67
diff changeset
3223 /* opt_pass methods: */
kono
parents: 67
diff changeset
3224 virtual bool gate (function *) { return flag_predictive_commoning != 0; }
kono
parents: 67
diff changeset
3225 virtual unsigned int execute (function *fun)
kono
parents: 67
diff changeset
3226 {
kono
parents: 67
diff changeset
3227 return run_tree_predictive_commoning (fun);
kono
parents: 67
diff changeset
3228 }
kono
parents: 67
diff changeset
3229
kono
parents: 67
diff changeset
3230 }; // class pass_predcom
kono
parents: 67
diff changeset
3231
kono
parents: 67
diff changeset
3232 } // anon namespace
kono
parents: 67
diff changeset
3233
kono
parents: 67
diff changeset
3234 gimple_opt_pass *
kono
parents: 67
diff changeset
3235 make_pass_predcom (gcc::context *ctxt)
kono
parents: 67
diff changeset
3236 {
kono
parents: 67
diff changeset
3237 return new pass_predcom (ctxt);
kono
parents: 67
diff changeset
3238 }
kono
parents: 67
diff changeset
3239
kono
parents: 67
diff changeset
3240