annotate gcc/cfgloop.h @ 120:f93fa5091070

fix conv1.c
author mir3636
date Thu, 08 Mar 2018 14:53:42 +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 /* Natural loop functions
111
kono
parents: 67
diff changeset
2 Copyright (C) 1987-2017 Free Software Foundation, Inc.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
4 This file is part of GCC.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
5
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 under
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 the terms of the GNU General Public License as published by the Free
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 Software Foundation; either version 3, or (at your option) any later
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 version.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
10
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 ANY
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 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.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
15
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 #ifndef GCC_CFGLOOP_H
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 #define GCC_CFGLOOP_H
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
22
111
kono
parents: 67
diff changeset
23 #include "cfgloopmanip.h"
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
24
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 /* Structure to hold decision about unrolling/peeling. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 enum lpt_dec
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
27 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
28 LPT_NONE,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
29 LPT_UNROLL_CONSTANT,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
30 LPT_UNROLL_RUNTIME,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
31 LPT_UNROLL_STUPID
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
32 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
33
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
34 struct GTY (()) lpt_decision {
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
35 enum lpt_dec decision;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 unsigned times;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
37 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
38
111
kono
parents: 67
diff changeset
39 /* The type of extend applied to an IV. */
kono
parents: 67
diff changeset
40 enum iv_extend_code
kono
parents: 67
diff changeset
41 {
kono
parents: 67
diff changeset
42 IV_SIGN_EXTEND,
kono
parents: 67
diff changeset
43 IV_ZERO_EXTEND,
kono
parents: 67
diff changeset
44 IV_UNKNOWN_EXTEND
kono
parents: 67
diff changeset
45 };
kono
parents: 67
diff changeset
46
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
47 /* The structure describing a bound on number of iterations of a loop. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
48
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
49 struct GTY ((chain_next ("%h.next"))) nb_iter_bound {
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 /* The statement STMT is executed at most ... */
111
kono
parents: 67
diff changeset
51 gimple *stmt;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
52
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
53 /* ... BOUND + 1 times (BOUND must be an unsigned constant).
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
54 The + 1 is added for the following reasons:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
55
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
56 a) 0 would otherwise be unused, while we would need to care more about
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
57 overflows (as MAX + 1 is sometimes produced as the estimate on number
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
58 of executions of STMT).
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
59 b) it is consistent with the result of number_of_iterations_exit. */
111
kono
parents: 67
diff changeset
60 widest_int bound;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
61
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
62 /* True if the statement will cause the loop to be leaved the (at most)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
63 BOUND + 1-st time it is executed, that is, all the statements after it
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
64 are executed at most BOUND times. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
65 bool is_exit;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
66
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
67 /* The next bound in the list. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
68 struct nb_iter_bound *next;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
69 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
70
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
71 /* Description of the loop exit. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
72
111
kono
parents: 67
diff changeset
73 struct GTY ((for_user)) loop_exit {
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
74 /* The exit edge. */
111
kono
parents: 67
diff changeset
75 edge e;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
76
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
77 /* Previous and next exit in the list of the exits of the loop. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
78 struct loop_exit *prev;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
79 struct loop_exit *next;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
80
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
81 /* Next element in the list of loops from that E exits. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
82 struct loop_exit *next_e;
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
111
kono
parents: 67
diff changeset
85 struct loop_exit_hasher : ggc_ptr_hash<loop_exit>
kono
parents: 67
diff changeset
86 {
kono
parents: 67
diff changeset
87 typedef edge compare_type;
kono
parents: 67
diff changeset
88
kono
parents: 67
diff changeset
89 static hashval_t hash (loop_exit *);
kono
parents: 67
diff changeset
90 static bool equal (loop_exit *, edge);
kono
parents: 67
diff changeset
91 static void remove (loop_exit *);
kono
parents: 67
diff changeset
92 };
kono
parents: 67
diff changeset
93
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
94 typedef struct loop *loop_p;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
95
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
96 /* An integer estimation of the number of iterations. Estimate_state
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
97 describes what is the state of the estimation. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
98 enum loop_estimation
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
99 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
100 /* Estimate was not computed yet. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
101 EST_NOT_COMPUTED,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
102 /* Estimate is ready. */
111
kono
parents: 67
diff changeset
103 EST_AVAILABLE,
kono
parents: 67
diff changeset
104 EST_LAST
kono
parents: 67
diff changeset
105 };
kono
parents: 67
diff changeset
106
kono
parents: 67
diff changeset
107 /* The structure describing non-overflow control induction variable for
kono
parents: 67
diff changeset
108 loop's exit edge. */
kono
parents: 67
diff changeset
109 struct GTY ((chain_next ("%h.next"))) control_iv {
kono
parents: 67
diff changeset
110 tree base;
kono
parents: 67
diff changeset
111 tree step;
kono
parents: 67
diff changeset
112 struct control_iv *next;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
113 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
114
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
115 /* Structure to hold information for each natural loop. */
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
116 struct GTY ((chain_next ("%h.next"))) loop {
111
kono
parents: 67
diff changeset
117 /* Index into loops array. Note indices will never be reused after loop
kono
parents: 67
diff changeset
118 is destroyed. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
119 int num;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
120
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
121 /* Number of loop insns. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
122 unsigned ninsns;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
123
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
124 /* Basic block of loop header. */
111
kono
parents: 67
diff changeset
125 basic_block header;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
126
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
127 /* Basic block of loop latch. */
111
kono
parents: 67
diff changeset
128 basic_block latch;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
129
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
130 /* For loop unrolling/peeling decision. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
131 struct lpt_decision lpt_decision;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
132
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
133 /* Average number of executed insns per iteration. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
134 unsigned av_ninsns;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
135
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
136 /* Number of blocks contained within the loop. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
137 unsigned num_nodes;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
138
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
139 /* Superloops of the loop, starting with the outermost loop. */
111
kono
parents: 67
diff changeset
140 vec<loop_p, va_gc> *superloops;
0
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 /* The first inner (child) loop or NULL if innermost loop. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
143 struct loop *inner;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
144
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
145 /* Link to the next (sibling) loop. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
146 struct loop *next;
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 /* Auxiliary info specific to a pass. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
149 PTR GTY ((skip (""))) aux;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
150
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
151 /* The number of times the latch of the loop is executed. This can be an
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
152 INTEGER_CST, or a symbolic expression representing the number of
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
153 iterations like "N - 1", or a COND_EXPR containing the runtime
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
154 conditions under which the number of iterations is non zero.
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
155
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
156 Don't access this field directly: number_of_latch_executions
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
157 computes and caches the computed information in this field. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
158 tree nb_iterations;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
159
111
kono
parents: 67
diff changeset
160 /* An integer guaranteed to be greater or equal to nb_iterations. Only
kono
parents: 67
diff changeset
161 valid if any_upper_bound is true. */
kono
parents: 67
diff changeset
162 widest_int nb_iterations_upper_bound;
kono
parents: 67
diff changeset
163
kono
parents: 67
diff changeset
164 widest_int nb_iterations_likely_upper_bound;
kono
parents: 67
diff changeset
165
kono
parents: 67
diff changeset
166 /* An integer giving an estimate on nb_iterations. Unlike
kono
parents: 67
diff changeset
167 nb_iterations_upper_bound, there is no guarantee that it is at least
kono
parents: 67
diff changeset
168 nb_iterations. */
kono
parents: 67
diff changeset
169 widest_int nb_iterations_estimate;
kono
parents: 67
diff changeset
170
kono
parents: 67
diff changeset
171 /* If > 0, an integer, where the user asserted that for any
kono
parents: 67
diff changeset
172 I in [ 0, nb_iterations ) and for any J in
kono
parents: 67
diff changeset
173 [ I, min ( I + safelen, nb_iterations ) ), the Ith and Jth iterations
kono
parents: 67
diff changeset
174 of the loop can be safely evaluated concurrently. */
kono
parents: 67
diff changeset
175 int safelen;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
176
111
kono
parents: 67
diff changeset
177 /* Constraints are generally set by consumers and affect certain
kono
parents: 67
diff changeset
178 semantics of niter analyzer APIs. Currently the APIs affected are
kono
parents: 67
diff changeset
179 number_of_iterations_exit* functions and their callers. One typical
kono
parents: 67
diff changeset
180 use case of constraints is to vectorize possibly infinite loop:
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
181
111
kono
parents: 67
diff changeset
182 1) Compute niter->assumptions by calling niter analyzer API and
kono
parents: 67
diff changeset
183 record it as possible condition for loop versioning.
kono
parents: 67
diff changeset
184 2) Clear buffered result of niter/scev analyzer.
kono
parents: 67
diff changeset
185 3) Set constraint LOOP_C_FINITE assuming the loop is finite.
kono
parents: 67
diff changeset
186 4) Analyze data references. Since data reference analysis depends
kono
parents: 67
diff changeset
187 on niter/scev analyzer, the point is that niter/scev analysis
kono
parents: 67
diff changeset
188 is done under circumstance of LOOP_C_FINITE constraint.
kono
parents: 67
diff changeset
189 5) Version the loop with niter->assumptions computed in step 1).
kono
parents: 67
diff changeset
190 6) Vectorize the versioned loop in which niter->assumptions is
kono
parents: 67
diff changeset
191 checked to be true.
kono
parents: 67
diff changeset
192 7) Update constraints in versioned loops so that niter analyzer
kono
parents: 67
diff changeset
193 in following passes can use it.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
194
111
kono
parents: 67
diff changeset
195 Note consumers are usually the loop optimizers and it is consumers'
kono
parents: 67
diff changeset
196 responsibility to set/clear constraints correctly. Failing to do
kono
parents: 67
diff changeset
197 that might result in hard to track down bugs in niter/scev consumers. */
kono
parents: 67
diff changeset
198 unsigned constraints;
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
199
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
200 /* An integer estimation of the number of iterations. Estimate_state
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
201 describes what is the state of the estimation. */
111
kono
parents: 67
diff changeset
202 ENUM_BITFIELD(loop_estimation) estimate_state : 8;
kono
parents: 67
diff changeset
203
kono
parents: 67
diff changeset
204 unsigned any_upper_bound : 1;
kono
parents: 67
diff changeset
205 unsigned any_estimate : 1;
kono
parents: 67
diff changeset
206 unsigned any_likely_upper_bound : 1;
kono
parents: 67
diff changeset
207
kono
parents: 67
diff changeset
208 /* True if the loop can be parallel. */
kono
parents: 67
diff changeset
209 unsigned can_be_parallel : 1;
kono
parents: 67
diff changeset
210
kono
parents: 67
diff changeset
211 /* True if -Waggressive-loop-optimizations warned about this loop
kono
parents: 67
diff changeset
212 already. */
kono
parents: 67
diff changeset
213 unsigned warned_aggressive_loop_optimizations : 1;
kono
parents: 67
diff changeset
214
kono
parents: 67
diff changeset
215 /* True if this loop should never be vectorized. */
kono
parents: 67
diff changeset
216 unsigned dont_vectorize : 1;
kono
parents: 67
diff changeset
217
kono
parents: 67
diff changeset
218 /* True if we should try harder to vectorize this loop. */
kono
parents: 67
diff changeset
219 unsigned force_vectorize : 1;
kono
parents: 67
diff changeset
220
kono
parents: 67
diff changeset
221 /* True if the loop is part of an oacc kernels region. */
kono
parents: 67
diff changeset
222 unsigned in_oacc_kernels_region : 1;
kono
parents: 67
diff changeset
223
kono
parents: 67
diff changeset
224 /* For SIMD loops, this is a unique identifier of the loop, referenced
kono
parents: 67
diff changeset
225 by IFN_GOMP_SIMD_VF, IFN_GOMP_SIMD_LANE and IFN_GOMP_SIMD_LAST_LANE
kono
parents: 67
diff changeset
226 builtins. */
kono
parents: 67
diff changeset
227 tree simduid;
kono
parents: 67
diff changeset
228
kono
parents: 67
diff changeset
229 /* In loop optimization, it's common to generate loops from the original
kono
parents: 67
diff changeset
230 loop. This field records the index of the original loop which can be
kono
parents: 67
diff changeset
231 used to track the original loop from newly generated loops. This can
kono
parents: 67
diff changeset
232 be done by calling function get_loop (cfun, orig_loop_num). Note the
kono
parents: 67
diff changeset
233 original loop could be destroyed for various reasons thus no longer
kono
parents: 67
diff changeset
234 exists, as a result, function call to get_loop returns NULL pointer.
kono
parents: 67
diff changeset
235 In this case, this field should not be used and needs to be cleared
kono
parents: 67
diff changeset
236 whenever possible. */
kono
parents: 67
diff changeset
237 int orig_loop_num;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
238
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
239 /* Upper bound on number of iterations of a loop. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
240 struct nb_iter_bound *bounds;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
241
111
kono
parents: 67
diff changeset
242 /* Non-overflow control ivs of a loop. */
kono
parents: 67
diff changeset
243 struct control_iv *control_ivs;
kono
parents: 67
diff changeset
244
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
245 /* Head of the cyclic list of the exits of the loop. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
246 struct loop_exit *exits;
111
kono
parents: 67
diff changeset
247
kono
parents: 67
diff changeset
248 /* Number of iteration analysis data for RTL. */
kono
parents: 67
diff changeset
249 struct niter_desc *simple_loop_desc;
kono
parents: 67
diff changeset
250
kono
parents: 67
diff changeset
251 /* For sanity checking during loop fixup we record here the former
kono
parents: 67
diff changeset
252 loop header for loops marked for removal. Note that this prevents
kono
parents: 67
diff changeset
253 the basic-block from being collected but its index can still be
kono
parents: 67
diff changeset
254 reused. */
kono
parents: 67
diff changeset
255 basic_block former_header;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
256 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
257
111
kono
parents: 67
diff changeset
258 /* Set if the loop is known to be infinite. */
kono
parents: 67
diff changeset
259 #define LOOP_C_INFINITE (1 << 0)
kono
parents: 67
diff changeset
260 /* Set if the loop is known to be finite without any assumptions. */
kono
parents: 67
diff changeset
261 #define LOOP_C_FINITE (1 << 1)
kono
parents: 67
diff changeset
262
kono
parents: 67
diff changeset
263 /* Set C to the LOOP constraint. */
kono
parents: 67
diff changeset
264 static inline void
kono
parents: 67
diff changeset
265 loop_constraint_set (struct loop *loop, unsigned c)
kono
parents: 67
diff changeset
266 {
kono
parents: 67
diff changeset
267 loop->constraints |= c;
kono
parents: 67
diff changeset
268 }
kono
parents: 67
diff changeset
269
kono
parents: 67
diff changeset
270 /* Clear C from the LOOP constraint. */
kono
parents: 67
diff changeset
271 static inline void
kono
parents: 67
diff changeset
272 loop_constraint_clear (struct loop *loop, unsigned c)
kono
parents: 67
diff changeset
273 {
kono
parents: 67
diff changeset
274 loop->constraints &= ~c;
kono
parents: 67
diff changeset
275 }
kono
parents: 67
diff changeset
276
kono
parents: 67
diff changeset
277 /* Check if C is set in the LOOP constraint. */
kono
parents: 67
diff changeset
278 static inline bool
kono
parents: 67
diff changeset
279 loop_constraint_set_p (struct loop *loop, unsigned c)
kono
parents: 67
diff changeset
280 {
kono
parents: 67
diff changeset
281 return (loop->constraints & c) == c;
kono
parents: 67
diff changeset
282 }
kono
parents: 67
diff changeset
283
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
284 /* Flags for state of loop structure. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
285 enum
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
286 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
287 LOOPS_HAVE_PREHEADERS = 1,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
288 LOOPS_HAVE_SIMPLE_LATCHES = 2,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
289 LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS = 4,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
290 LOOPS_HAVE_RECORDED_EXITS = 8,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
291 LOOPS_MAY_HAVE_MULTIPLE_LATCHES = 16,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
292 LOOP_CLOSED_SSA = 32,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
293 LOOPS_NEED_FIXUP = 64,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
294 LOOPS_HAVE_FALLTHRU_PREHEADERS = 128
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
295 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
296
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
297 #define LOOPS_NORMAL (LOOPS_HAVE_PREHEADERS | LOOPS_HAVE_SIMPLE_LATCHES \
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
298 | LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
299 #define AVOID_CFG_MODIFICATIONS (LOOPS_MAY_HAVE_MULTIPLE_LATCHES)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
300
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
301 /* Structure to hold CFG information about natural loops within a function. */
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
302 struct GTY (()) loops {
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
303 /* State of loops. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
304 int state;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
305
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
306 /* Array of the loops. */
111
kono
parents: 67
diff changeset
307 vec<loop_p, va_gc> *larray;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
308
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
309 /* Maps edges to the list of their descriptions as loop exits. Edges
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
310 whose sources or destinations have loop_father == NULL (which may
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
311 happen during the cfg manipulations) should not appear in EXITS. */
111
kono
parents: 67
diff changeset
312 hash_table<loop_exit_hasher> *GTY(()) exits;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
313
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
314 /* Pointer to root of loop hierarchy tree. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
315 struct loop *tree_root;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
316 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
317
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
318 /* Loop recognition. */
111
kono
parents: 67
diff changeset
319 bool bb_loop_header_p (basic_block);
kono
parents: 67
diff changeset
320 void init_loops_structure (struct function *, struct loops *, unsigned);
kono
parents: 67
diff changeset
321 extern struct loops *flow_loops_find (struct loops *);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
322 extern void disambiguate_loops_with_multiple_latches (void);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
323 extern void flow_loops_free (struct loops *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
324 extern void flow_loops_dump (FILE *,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
325 void (*)(const struct loop *, FILE *, int), int);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
326 extern void flow_loop_dump (const struct loop *, FILE *,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
327 void (*)(const struct loop *, FILE *, int), int);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
328 struct loop *alloc_loop (void);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
329 extern void flow_loop_free (struct loop *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
330 int flow_loop_nodes_find (basic_block, struct loop *);
111
kono
parents: 67
diff changeset
331 unsigned fix_loop_structure (bitmap changed_bbs);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
332 bool mark_irreducible_loops (void);
111
kono
parents: 67
diff changeset
333 void release_recorded_exits (function *);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
334 void record_loop_exits (void);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
335 void rescan_loop_exit (edge, bool, bool);
111
kono
parents: 67
diff changeset
336 void sort_sibling_loops (function *);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
337
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
338 /* Loop data structure manipulation/querying. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
339 extern void flow_loop_tree_node_add (struct loop *, struct loop *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
340 extern void flow_loop_tree_node_remove (struct loop *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
341 extern bool flow_loop_nested_p (const struct loop *, const struct loop *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
342 extern bool flow_bb_inside_loop_p (const struct loop *, const_basic_block);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
343 extern struct loop * find_common_loop (struct loop *, struct loop *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
344 struct loop *superloop_at_depth (struct loop *, unsigned);
111
kono
parents: 67
diff changeset
345 struct eni_weights;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
346 extern int num_loop_insns (const struct loop *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
347 extern int average_num_loop_insns (const struct loop *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
348 extern unsigned get_loop_level (const struct loop *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
349 extern bool loop_exit_edge_p (const struct loop *, const_edge);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
350 extern bool loop_exits_to_bb_p (struct loop *, basic_block);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
351 extern bool loop_exits_from_bb_p (struct loop *, basic_block);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
352 extern void mark_loop_exit_edges (void);
111
kono
parents: 67
diff changeset
353 extern location_t get_loop_location (struct loop *loop);
0
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 /* Loops & cfg manipulation. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
356 extern basic_block *get_loop_body (const struct loop *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
357 extern unsigned get_loop_body_with_size (const struct loop *, basic_block *,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
358 unsigned);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
359 extern basic_block *get_loop_body_in_dom_order (const struct loop *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
360 extern basic_block *get_loop_body_in_bfs_order (const struct loop *);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
361 extern basic_block *get_loop_body_in_custom_order (const struct loop *,
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
362 int (*) (const void *, const void *));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
363
111
kono
parents: 67
diff changeset
364 extern vec<edge> get_loop_exit_edges (const struct loop *);
kono
parents: 67
diff changeset
365 extern edge single_exit (const struct loop *);
kono
parents: 67
diff changeset
366 extern edge single_likely_exit (struct loop *loop);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
367 extern unsigned num_loop_branches (const struct loop *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
368
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
369 extern edge loop_preheader_edge (const struct loop *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
370 extern edge loop_latch_edge (const struct loop *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
371
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
372 extern void add_bb_to_loop (basic_block, struct loop *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
373 extern void remove_bb_from_loops (basic_block);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
374
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
375 extern void cancel_loop_tree (struct loop *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
376 extern void delete_loop (struct loop *);
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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
379 extern void verify_loop_structure (void);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
380
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
381 /* Loop analysis. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
382 extern bool just_once_each_iteration_p (const struct loop *, const_basic_block);
111
kono
parents: 67
diff changeset
383 gcov_type expected_loop_iterations_unbounded (const struct loop *,
kono
parents: 67
diff changeset
384 bool *read_profile_p = NULL);
kono
parents: 67
diff changeset
385 extern unsigned expected_loop_iterations (struct loop *);
kono
parents: 67
diff changeset
386 extern rtx doloop_condition_get (rtx_insn *);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
387
111
kono
parents: 67
diff changeset
388 void mark_loop_for_removal (loop_p);
0
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 /* Induction variable analysis. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
391
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
392 /* The description of induction variable. The things are a bit complicated
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
393 due to need to handle subregs and extends. The value of the object described
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
394 by it can be obtained as follows (all computations are done in extend_mode):
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
395
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
396 Value in i-th iteration is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
397 delta + mult * extend_{extend_mode} (subreg_{mode} (base + i * step)).
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 If first_special is true, the value in the first iteration is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
400 delta + mult * base
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
401
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
402 If extend = UNKNOWN, first_special must be false, delta 0, mult 1 and value is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
403 subreg_{mode} (base + i * step)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
404
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
405 The get_iv_value function can be used to obtain these expressions.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
406
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
407 ??? Add a third mode field that would specify the mode in that inner
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
408 computation is done, which would enable it to be different from the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
409 outer one? */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
410
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
411 struct rtx_iv
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 /* Its base and step (mode of base and step is supposed to be extend_mode,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
414 see the description above). */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
415 rtx base, step;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
416
111
kono
parents: 67
diff changeset
417 /* The type of extend applied to it (IV_SIGN_EXTEND, IV_ZERO_EXTEND,
kono
parents: 67
diff changeset
418 or IV_UNKNOWN_EXTEND). */
kono
parents: 67
diff changeset
419 enum iv_extend_code extend;
0
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 /* Operations applied in the extended mode. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
422 rtx delta, mult;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
423
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
424 /* The mode it is extended to. */
111
kono
parents: 67
diff changeset
425 scalar_int_mode extend_mode;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
426
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
427 /* The mode the variable iterates in. */
111
kono
parents: 67
diff changeset
428 scalar_int_mode mode;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
429
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
430 /* Whether the first iteration needs to be handled specially. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
431 unsigned first_special : 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
432 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
433
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
434 /* The description of an exit from the loop and of the number of iterations
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
435 till we take the exit. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
436
111
kono
parents: 67
diff changeset
437 struct GTY(()) niter_desc
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
438 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
439 /* The edge out of the loop. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
440 edge out_edge;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
441
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
442 /* The other edge leading from the condition. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
443 edge in_edge;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
444
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
445 /* True if we are able to say anything about number of iterations of the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
446 loop. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
447 bool simple_p;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
448
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
449 /* True if the loop iterates the constant number of times. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
450 bool const_iter;
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 /* Number of iterations if constant. */
111
kono
parents: 67
diff changeset
453 uint64_t niter;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
454
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
455 /* Assumptions under that the rest of the information is valid. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
456 rtx assumptions;
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 /* Assumptions under that the loop ends before reaching the latch,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
459 even if value of niter_expr says otherwise. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
460 rtx noloop_assumptions;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
461
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
462 /* Condition under that the loop is infinite. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
463 rtx infinite;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
464
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
465 /* Whether the comparison is signed. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
466 bool signed_p;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
467
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
468 /* The mode in that niter_expr should be computed. */
111
kono
parents: 67
diff changeset
469 scalar_int_mode mode;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
470
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
471 /* The number of iterations of the loop. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
472 rtx niter_expr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
473 };
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 extern void iv_analysis_loop_init (struct loop *);
111
kono
parents: 67
diff changeset
476 extern bool iv_analyze (rtx_insn *, scalar_int_mode, rtx, struct rtx_iv *);
kono
parents: 67
diff changeset
477 extern bool iv_analyze_result (rtx_insn *, rtx, struct rtx_iv *);
kono
parents: 67
diff changeset
478 extern bool iv_analyze_expr (rtx_insn *, scalar_int_mode, rtx,
kono
parents: 67
diff changeset
479 struct rtx_iv *);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
480 extern rtx get_iv_value (struct rtx_iv *, rtx);
111
kono
parents: 67
diff changeset
481 extern bool biv_p (rtx_insn *, scalar_int_mode, rtx);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
482 extern void find_simple_exit (struct loop *, struct niter_desc *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
483 extern void iv_analysis_done (void);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
484
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
485 extern struct niter_desc *get_simple_loop_desc (struct loop *loop);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
486 extern void free_simple_loop_desc (struct loop *loop);
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 static inline struct niter_desc *
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
489 simple_loop_desc (struct loop *loop)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
490 {
111
kono
parents: 67
diff changeset
491 return loop->simple_loop_desc;
0
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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
494 /* Accessors for the loop structures. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
495
111
kono
parents: 67
diff changeset
496 /* Returns the loop with index NUM from FNs loop tree. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
497
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
498 static inline struct loop *
111
kono
parents: 67
diff changeset
499 get_loop (struct function *fn, unsigned num)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
500 {
111
kono
parents: 67
diff changeset
501 return (*loops_for_fn (fn)->larray)[num];
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
502 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
503
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
504 /* Returns the number of superloops of LOOP. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
505
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
506 static inline unsigned
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
507 loop_depth (const struct loop *loop)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
508 {
111
kono
parents: 67
diff changeset
509 return vec_safe_length (loop->superloops);
0
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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
512 /* Returns the immediate superloop of LOOP, or NULL if LOOP is the outermost
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
513 loop. */
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 static inline struct loop *
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
516 loop_outer (const struct loop *loop)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
517 {
111
kono
parents: 67
diff changeset
518 unsigned n = vec_safe_length (loop->superloops);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
519
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
520 if (n == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
521 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
522
111
kono
parents: 67
diff changeset
523 return (*loop->superloops)[n - 1];
kono
parents: 67
diff changeset
524 }
kono
parents: 67
diff changeset
525
kono
parents: 67
diff changeset
526 /* Returns true if LOOP has at least one exit edge. */
kono
parents: 67
diff changeset
527
kono
parents: 67
diff changeset
528 static inline bool
kono
parents: 67
diff changeset
529 loop_has_exit_edges (const struct loop *loop)
kono
parents: 67
diff changeset
530 {
kono
parents: 67
diff changeset
531 return loop->exits->next->e != NULL;
0
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
111
kono
parents: 67
diff changeset
534 /* Returns the list of loops in FN. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
535
111
kono
parents: 67
diff changeset
536 inline vec<loop_p, va_gc> *
kono
parents: 67
diff changeset
537 get_loops (struct function *fn)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
538 {
111
kono
parents: 67
diff changeset
539 struct loops *loops = loops_for_fn (fn);
kono
parents: 67
diff changeset
540 if (!loops)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
541 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
542
111
kono
parents: 67
diff changeset
543 return loops->larray;
0
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
111
kono
parents: 67
diff changeset
546 /* Returns the number of loops in FN (including the removed
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
547 ones and the fake loop that forms the root of the loop tree). */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
548
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
549 static inline unsigned
111
kono
parents: 67
diff changeset
550 number_of_loops (struct function *fn)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
551 {
111
kono
parents: 67
diff changeset
552 struct loops *loops = loops_for_fn (fn);
kono
parents: 67
diff changeset
553 if (!loops)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
554 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
555
111
kono
parents: 67
diff changeset
556 return vec_safe_length (loops->larray);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
557 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
558
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
559 /* Returns true if state of the loops satisfies all properties
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
560 described by FLAGS. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
561
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
562 static inline bool
111
kono
parents: 67
diff changeset
563 loops_state_satisfies_p (function *fn, unsigned flags)
kono
parents: 67
diff changeset
564 {
kono
parents: 67
diff changeset
565 return (loops_for_fn (fn)->state & flags) == flags;
kono
parents: 67
diff changeset
566 }
kono
parents: 67
diff changeset
567
kono
parents: 67
diff changeset
568 static inline bool
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
569 loops_state_satisfies_p (unsigned flags)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
570 {
111
kono
parents: 67
diff changeset
571 return loops_state_satisfies_p (cfun, flags);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
572 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
573
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
574 /* Sets FLAGS to the loops state. */
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 static inline void
111
kono
parents: 67
diff changeset
577 loops_state_set (function *fn, unsigned flags)
kono
parents: 67
diff changeset
578 {
kono
parents: 67
diff changeset
579 loops_for_fn (fn)->state |= flags;
kono
parents: 67
diff changeset
580 }
kono
parents: 67
diff changeset
581
kono
parents: 67
diff changeset
582 static inline void
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
583 loops_state_set (unsigned flags)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
584 {
111
kono
parents: 67
diff changeset
585 loops_state_set (cfun, flags);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
586 }
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 /* Clears FLAGS from the loops state. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
589
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
590 static inline void
111
kono
parents: 67
diff changeset
591 loops_state_clear (function *fn, unsigned flags)
kono
parents: 67
diff changeset
592 {
kono
parents: 67
diff changeset
593 loops_for_fn (fn)->state &= ~flags;
kono
parents: 67
diff changeset
594 }
kono
parents: 67
diff changeset
595
kono
parents: 67
diff changeset
596 static inline void
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
597 loops_state_clear (unsigned flags)
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 if (!current_loops)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
600 return;
111
kono
parents: 67
diff changeset
601 loops_state_clear (cfun, flags);
kono
parents: 67
diff changeset
602 }
kono
parents: 67
diff changeset
603
kono
parents: 67
diff changeset
604 /* Check loop structure invariants, if internal consistency checks are
kono
parents: 67
diff changeset
605 enabled. */
kono
parents: 67
diff changeset
606
kono
parents: 67
diff changeset
607 static inline void
kono
parents: 67
diff changeset
608 checking_verify_loop_structure (void)
kono
parents: 67
diff changeset
609 {
kono
parents: 67
diff changeset
610 /* VERIFY_LOOP_STRUCTURE essentially asserts that no loops need fixups.
kono
parents: 67
diff changeset
611
kono
parents: 67
diff changeset
612 The loop optimizers should never make changes to the CFG which
kono
parents: 67
diff changeset
613 require loop fixups. But the low level CFG manipulation code may
kono
parents: 67
diff changeset
614 set the flag conservatively.
kono
parents: 67
diff changeset
615
kono
parents: 67
diff changeset
616 Go ahead and clear the flag here. That avoids the assert inside
kono
parents: 67
diff changeset
617 VERIFY_LOOP_STRUCTURE, and if there is an inconsistency in the loop
kono
parents: 67
diff changeset
618 structures VERIFY_LOOP_STRUCTURE will detect it.
kono
parents: 67
diff changeset
619
kono
parents: 67
diff changeset
620 This also avoid the compile time cost of excessive fixups. */
kono
parents: 67
diff changeset
621 loops_state_clear (LOOPS_NEED_FIXUP);
kono
parents: 67
diff changeset
622 if (flag_checking)
kono
parents: 67
diff changeset
623 verify_loop_structure ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
624 }
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 /* Loop iterators. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
627
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
628 /* Flags for loop iteration. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
629
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
630 enum li_flags
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 LI_INCLUDE_ROOT = 1, /* Include the fake root of the loop tree. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
633 LI_FROM_INNERMOST = 2, /* Iterate over the loops in the reverse order,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
634 starting from innermost ones. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
635 LI_ONLY_INNERMOST = 4 /* Iterate only over innermost loops. */
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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
638 /* The iterator for loops. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
639
111
kono
parents: 67
diff changeset
640 struct loop_iterator
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
641 {
111
kono
parents: 67
diff changeset
642 loop_iterator (function *fn, loop_p *loop, unsigned flags);
kono
parents: 67
diff changeset
643 ~loop_iterator ();
kono
parents: 67
diff changeset
644
kono
parents: 67
diff changeset
645 inline loop_p next ();
kono
parents: 67
diff changeset
646
kono
parents: 67
diff changeset
647 /* The function we are visiting. */
kono
parents: 67
diff changeset
648 function *fn;
kono
parents: 67
diff changeset
649
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
650 /* The list of loops to visit. */
111
kono
parents: 67
diff changeset
651 vec<int> to_visit;
0
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 /* The index of the actual loop. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
654 unsigned idx;
111
kono
parents: 67
diff changeset
655 };
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
656
111
kono
parents: 67
diff changeset
657 inline loop_p
kono
parents: 67
diff changeset
658 loop_iterator::next ()
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
659 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
660 int anum;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
661
111
kono
parents: 67
diff changeset
662 while (this->to_visit.iterate (this->idx, &anum))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
663 {
111
kono
parents: 67
diff changeset
664 this->idx++;
kono
parents: 67
diff changeset
665 loop_p loop = get_loop (fn, anum);
kono
parents: 67
diff changeset
666 if (loop)
kono
parents: 67
diff changeset
667 return loop;
0
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
111
kono
parents: 67
diff changeset
670 return NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
671 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
672
111
kono
parents: 67
diff changeset
673 inline
kono
parents: 67
diff changeset
674 loop_iterator::loop_iterator (function *fn, loop_p *loop, unsigned flags)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
675 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
676 struct loop *aloop;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
677 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
678 int mn;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
679
111
kono
parents: 67
diff changeset
680 this->idx = 0;
kono
parents: 67
diff changeset
681 this->fn = fn;
kono
parents: 67
diff changeset
682 if (!loops_for_fn (fn))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
683 {
111
kono
parents: 67
diff changeset
684 this->to_visit.create (0);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
685 *loop = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
686 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
687 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
688
111
kono
parents: 67
diff changeset
689 this->to_visit.create (number_of_loops (fn));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
690 mn = (flags & LI_INCLUDE_ROOT) ? 0 : 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
691
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
692 if (flags & LI_ONLY_INNERMOST)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
693 {
111
kono
parents: 67
diff changeset
694 for (i = 0; vec_safe_iterate (loops_for_fn (fn)->larray, i, &aloop); i++)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
695 if (aloop != NULL
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
696 && aloop->inner == NULL
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
697 && aloop->num >= mn)
111
kono
parents: 67
diff changeset
698 this->to_visit.quick_push (aloop->num);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
699 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
700 else if (flags & LI_FROM_INNERMOST)
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 /* Push the loops to LI->TO_VISIT in postorder. */
111
kono
parents: 67
diff changeset
703 for (aloop = loops_for_fn (fn)->tree_root;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
704 aloop->inner != NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
705 aloop = aloop->inner)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
706 continue;
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 while (1)
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 (aloop->num >= mn)
111
kono
parents: 67
diff changeset
711 this->to_visit.quick_push (aloop->num);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
712
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
713 if (aloop->next)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
714 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
715 for (aloop = aloop->next;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
716 aloop->inner != NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
717 aloop = aloop->inner)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
718 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
719 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
720 else if (!loop_outer (aloop))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
721 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
722 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
723 aloop = loop_outer (aloop);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
724 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
725 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
726 else
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 /* Push the loops to LI->TO_VISIT in preorder. */
111
kono
parents: 67
diff changeset
729 aloop = loops_for_fn (fn)->tree_root;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
730 while (1)
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 if (aloop->num >= mn)
111
kono
parents: 67
diff changeset
733 this->to_visit.quick_push (aloop->num);
0
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 if (aloop->inner != NULL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
736 aloop = aloop->inner;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
737 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
738 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
739 while (aloop != NULL && aloop->next == NULL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
740 aloop = loop_outer (aloop);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
741 if (aloop == NULL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
742 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
743 aloop = aloop->next;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
744 }
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
111
kono
parents: 67
diff changeset
748 *loop = this->next ();
kono
parents: 67
diff changeset
749 }
kono
parents: 67
diff changeset
750
kono
parents: 67
diff changeset
751 inline
kono
parents: 67
diff changeset
752 loop_iterator::~loop_iterator ()
kono
parents: 67
diff changeset
753 {
kono
parents: 67
diff changeset
754 this->to_visit.release ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
755 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
756
111
kono
parents: 67
diff changeset
757 #define FOR_EACH_LOOP(LOOP, FLAGS) \
kono
parents: 67
diff changeset
758 for (loop_iterator li(cfun, &(LOOP), FLAGS); \
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
759 (LOOP); \
111
kono
parents: 67
diff changeset
760 (LOOP) = li.next ())
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
761
111
kono
parents: 67
diff changeset
762 #define FOR_EACH_LOOP_FN(FN, LOOP, FLAGS) \
kono
parents: 67
diff changeset
763 for (loop_iterator li(fn, &(LOOP), FLAGS); \
kono
parents: 67
diff changeset
764 (LOOP); \
kono
parents: 67
diff changeset
765 (LOOP) = li.next ())
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
766
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
767 /* The properties of the target. */
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
768 struct target_cfgloop {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
769 /* Number of available registers. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
770 unsigned x_target_avail_regs;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
771
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
772 /* Number of available registers that are call-clobbered. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
773 unsigned x_target_clobbered_regs;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
774
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
775 /* Number of registers reserved for temporary expressions. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
776 unsigned x_target_res_regs;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
777
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
778 /* The cost for register when there still is some reserve, but we are
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
779 approaching the number of available registers. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
780 unsigned x_target_reg_cost[2];
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
781
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
782 /* The cost for register when we need to spill. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
783 unsigned x_target_spill_cost[2];
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
784 };
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
785
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
786 extern struct target_cfgloop default_target_cfgloop;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
787 #if SWITCHABLE_TARGET
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
788 extern struct target_cfgloop *this_target_cfgloop;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
789 #else
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
790 #define this_target_cfgloop (&default_target_cfgloop)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
791 #endif
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
792
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
793 #define target_avail_regs \
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
794 (this_target_cfgloop->x_target_avail_regs)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
795 #define target_clobbered_regs \
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
796 (this_target_cfgloop->x_target_clobbered_regs)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
797 #define target_res_regs \
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
798 (this_target_cfgloop->x_target_res_regs)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
799 #define target_reg_cost \
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
800 (this_target_cfgloop->x_target_reg_cost)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
801 #define target_spill_cost \
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
802 (this_target_cfgloop->x_target_spill_cost)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
803
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
804 /* Register pressure estimation for induction variable optimizations & loop
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
805 invariant motion. */
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
806 extern unsigned estimate_reg_pressure_cost (unsigned, unsigned, bool, bool);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
807 extern void init_set_costs (void);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
808
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
809 /* Loop optimizer initialization. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
810 extern void loop_optimizer_init (unsigned);
111
kono
parents: 67
diff changeset
811 extern void loop_optimizer_finalize (function *);
kono
parents: 67
diff changeset
812 inline void
kono
parents: 67
diff changeset
813 loop_optimizer_finalize ()
kono
parents: 67
diff changeset
814 {
kono
parents: 67
diff changeset
815 loop_optimizer_finalize (cfun);
kono
parents: 67
diff changeset
816 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
817
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
818 /* Optimization passes. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
819 enum
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
820 {
111
kono
parents: 67
diff changeset
821 UAP_UNROLL = 1, /* Enables unrolling of loops if it seems profitable. */
kono
parents: 67
diff changeset
822 UAP_UNROLL_ALL = 2 /* Enables unrolling of all loops. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
823 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
824
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
825 extern void doloop_optimize_loops (void);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
826 extern void move_loop_invariants (void);
111
kono
parents: 67
diff changeset
827 extern vec<basic_block> get_loop_hot_path (const struct loop *loop);
kono
parents: 67
diff changeset
828
kono
parents: 67
diff changeset
829 /* Returns the outermost loop of the loop nest that contains LOOP.*/
kono
parents: 67
diff changeset
830 static inline struct loop *
kono
parents: 67
diff changeset
831 loop_outermost (struct loop *loop)
kono
parents: 67
diff changeset
832 {
kono
parents: 67
diff changeset
833 unsigned n = vec_safe_length (loop->superloops);
kono
parents: 67
diff changeset
834
kono
parents: 67
diff changeset
835 if (n <= 1)
kono
parents: 67
diff changeset
836 return loop;
kono
parents: 67
diff changeset
837
kono
parents: 67
diff changeset
838 return (*loop->superloops)[1];
kono
parents: 67
diff changeset
839 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
840
111
kono
parents: 67
diff changeset
841 extern void record_niter_bound (struct loop *, const widest_int &, bool, bool);
kono
parents: 67
diff changeset
842 extern HOST_WIDE_INT get_estimated_loop_iterations_int (struct loop *);
kono
parents: 67
diff changeset
843 extern HOST_WIDE_INT get_max_loop_iterations_int (const struct loop *);
kono
parents: 67
diff changeset
844 extern HOST_WIDE_INT get_likely_max_loop_iterations_int (struct loop *);
kono
parents: 67
diff changeset
845 extern bool get_estimated_loop_iterations (struct loop *loop, widest_int *nit);
kono
parents: 67
diff changeset
846 extern bool get_max_loop_iterations (const struct loop *loop, widest_int *nit);
kono
parents: 67
diff changeset
847 extern bool get_likely_max_loop_iterations (struct loop *loop, widest_int *nit);
kono
parents: 67
diff changeset
848 extern int bb_loop_depth (const_basic_block);
kono
parents: 67
diff changeset
849
kono
parents: 67
diff changeset
850 /* Converts VAL to widest_int. */
kono
parents: 67
diff changeset
851
kono
parents: 67
diff changeset
852 static inline widest_int
kono
parents: 67
diff changeset
853 gcov_type_to_wide_int (gcov_type val)
kono
parents: 67
diff changeset
854 {
kono
parents: 67
diff changeset
855 HOST_WIDE_INT a[2];
kono
parents: 67
diff changeset
856
kono
parents: 67
diff changeset
857 a[0] = (unsigned HOST_WIDE_INT) val;
kono
parents: 67
diff changeset
858 /* If HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_WIDEST_INT, avoid shifting by
kono
parents: 67
diff changeset
859 the size of type. */
kono
parents: 67
diff changeset
860 val >>= HOST_BITS_PER_WIDE_INT - 1;
kono
parents: 67
diff changeset
861 val >>= 1;
kono
parents: 67
diff changeset
862 a[1] = (unsigned HOST_WIDE_INT) val;
kono
parents: 67
diff changeset
863
kono
parents: 67
diff changeset
864 return widest_int::from_array (a, 2);
kono
parents: 67
diff changeset
865 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
866 #endif /* GCC_CFGLOOP_H */