annotate src/share/vm/opto/loopnode.hpp @ 1145:e018e6884bd8

6631166: CMS: better heuristics when combatting fragmentation Summary: Autonomic per-worker free block cache sizing, tunable coalition policies, fixes to per-size block statistics, retuned gain and bandwidth of some feedback loop filters to allow quicker reactivity to abrupt changes in ambient demand, and other heuristics to reduce fragmentation of the CMS old gen. Also tightened some assertions, including those related to locking. Reviewed-by: jmasa
author ysr
date Wed, 23 Dec 2009 09:23:54 -0800
parents 046932b72aa2
children b2b6a9bf6238
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
921
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
2 * Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 class CmpNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
26 class CountedLoopEndNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
27 class CountedLoopNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
28 class IdealLoopTree;
a61af66fc99e Initial load
duke
parents:
diff changeset
29 class LoopNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
30 class Node;
a61af66fc99e Initial load
duke
parents:
diff changeset
31 class PhaseIdealLoop;
a61af66fc99e Initial load
duke
parents:
diff changeset
32 class VectorSet;
a61af66fc99e Initial load
duke
parents:
diff changeset
33 struct small_cache;
a61af66fc99e Initial load
duke
parents:
diff changeset
34
a61af66fc99e Initial load
duke
parents:
diff changeset
35 //
a61af66fc99e Initial load
duke
parents:
diff changeset
36 // I D E A L I Z E D L O O P S
a61af66fc99e Initial load
duke
parents:
diff changeset
37 //
a61af66fc99e Initial load
duke
parents:
diff changeset
38 // Idealized loops are the set of loops I perform more interesting
a61af66fc99e Initial load
duke
parents:
diff changeset
39 // transformations on, beyond simple hoisting.
a61af66fc99e Initial load
duke
parents:
diff changeset
40
a61af66fc99e Initial load
duke
parents:
diff changeset
41 //------------------------------LoopNode---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
42 // Simple loop header. Fall in path on left, loop-back path on right.
a61af66fc99e Initial load
duke
parents:
diff changeset
43 class LoopNode : public RegionNode {
a61af66fc99e Initial load
duke
parents:
diff changeset
44 // Size is bigger to hold the flags. However, the flags do not change
a61af66fc99e Initial load
duke
parents:
diff changeset
45 // the semantics so it does not appear in the hash & cmp functions.
a61af66fc99e Initial load
duke
parents:
diff changeset
46 virtual uint size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
47 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
48 short _loop_flags;
a61af66fc99e Initial load
duke
parents:
diff changeset
49 // Names for flag bitfields
a61af66fc99e Initial load
duke
parents:
diff changeset
50 enum { pre_post_main=0, inner_loop=8, partial_peel_loop=16, partial_peel_failed=32 };
a61af66fc99e Initial load
duke
parents:
diff changeset
51 char _unswitch_count;
a61af66fc99e Initial load
duke
parents:
diff changeset
52 enum { _unswitch_max=3 };
a61af66fc99e Initial load
duke
parents:
diff changeset
53
a61af66fc99e Initial load
duke
parents:
diff changeset
54 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
55 // Names for edge indices
a61af66fc99e Initial load
duke
parents:
diff changeset
56 enum { Self=0, EntryControl, LoopBackControl };
a61af66fc99e Initial load
duke
parents:
diff changeset
57
a61af66fc99e Initial load
duke
parents:
diff changeset
58 int is_inner_loop() const { return _loop_flags & inner_loop; }
a61af66fc99e Initial load
duke
parents:
diff changeset
59 void set_inner_loop() { _loop_flags |= inner_loop; }
a61af66fc99e Initial load
duke
parents:
diff changeset
60
a61af66fc99e Initial load
duke
parents:
diff changeset
61 int is_partial_peel_loop() const { return _loop_flags & partial_peel_loop; }
a61af66fc99e Initial load
duke
parents:
diff changeset
62 void set_partial_peel_loop() { _loop_flags |= partial_peel_loop; }
a61af66fc99e Initial load
duke
parents:
diff changeset
63 int partial_peel_has_failed() const { return _loop_flags & partial_peel_failed; }
a61af66fc99e Initial load
duke
parents:
diff changeset
64 void mark_partial_peel_failed() { _loop_flags |= partial_peel_failed; }
a61af66fc99e Initial load
duke
parents:
diff changeset
65
a61af66fc99e Initial load
duke
parents:
diff changeset
66 int unswitch_max() { return _unswitch_max; }
a61af66fc99e Initial load
duke
parents:
diff changeset
67 int unswitch_count() { return _unswitch_count; }
a61af66fc99e Initial load
duke
parents:
diff changeset
68 void set_unswitch_count(int val) {
a61af66fc99e Initial load
duke
parents:
diff changeset
69 assert (val <= unswitch_max(), "too many unswitches");
a61af66fc99e Initial load
duke
parents:
diff changeset
70 _unswitch_count = val;
a61af66fc99e Initial load
duke
parents:
diff changeset
71 }
a61af66fc99e Initial load
duke
parents:
diff changeset
72
a61af66fc99e Initial load
duke
parents:
diff changeset
73 LoopNode( Node *entry, Node *backedge ) : RegionNode(3), _loop_flags(0), _unswitch_count(0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
74 init_class_id(Class_Loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
75 init_req(EntryControl, entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
76 init_req(LoopBackControl, backedge);
a61af66fc99e Initial load
duke
parents:
diff changeset
77 }
a61af66fc99e Initial load
duke
parents:
diff changeset
78
a61af66fc99e Initial load
duke
parents:
diff changeset
79 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
a61af66fc99e Initial load
duke
parents:
diff changeset
80 virtual int Opcode() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
81 bool can_be_counted_loop(PhaseTransform* phase) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
82 return req() == 3 && in(0) != NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
83 in(1) != NULL && phase->type(in(1)) != Type::TOP &&
a61af66fc99e Initial load
duke
parents:
diff changeset
84 in(2) != NULL && phase->type(in(2)) != Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
85 }
a61af66fc99e Initial load
duke
parents:
diff changeset
86 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
87 virtual void dump_spec(outputStream *st) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
88 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
89 };
a61af66fc99e Initial load
duke
parents:
diff changeset
90
a61af66fc99e Initial load
duke
parents:
diff changeset
91 //------------------------------Counted Loops----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
92 // Counted loops are all trip-counted loops, with exactly 1 trip-counter exit
a61af66fc99e Initial load
duke
parents:
diff changeset
93 // path (and maybe some other exit paths). The trip-counter exit is always
a61af66fc99e Initial load
duke
parents:
diff changeset
94 // last in the loop. The trip-counter does not have to stride by a constant,
a61af66fc99e Initial load
duke
parents:
diff changeset
95 // but it does have to stride by a loop-invariant amount; the exit value is
a61af66fc99e Initial load
duke
parents:
diff changeset
96 // also loop invariant.
a61af66fc99e Initial load
duke
parents:
diff changeset
97
a61af66fc99e Initial load
duke
parents:
diff changeset
98 // CountedLoopNodes and CountedLoopEndNodes come in matched pairs. The
a61af66fc99e Initial load
duke
parents:
diff changeset
99 // CountedLoopNode has the incoming loop control and the loop-back-control
a61af66fc99e Initial load
duke
parents:
diff changeset
100 // which is always the IfTrue before the matching CountedLoopEndNode. The
a61af66fc99e Initial load
duke
parents:
diff changeset
101 // CountedLoopEndNode has an incoming control (possibly not the
a61af66fc99e Initial load
duke
parents:
diff changeset
102 // CountedLoopNode if there is control flow in the loop), the post-increment
a61af66fc99e Initial load
duke
parents:
diff changeset
103 // trip-counter value, and the limit. The trip-counter value is always of
a61af66fc99e Initial load
duke
parents:
diff changeset
104 // the form (Op old-trip-counter stride). The old-trip-counter is produced
a61af66fc99e Initial load
duke
parents:
diff changeset
105 // by a Phi connected to the CountedLoopNode. The stride is loop invariant.
a61af66fc99e Initial load
duke
parents:
diff changeset
106 // The Op is any commutable opcode, including Add, Mul, Xor. The
a61af66fc99e Initial load
duke
parents:
diff changeset
107 // CountedLoopEndNode also takes in the loop-invariant limit value.
a61af66fc99e Initial load
duke
parents:
diff changeset
108
a61af66fc99e Initial load
duke
parents:
diff changeset
109 // From a CountedLoopNode I can reach the matching CountedLoopEndNode via the
a61af66fc99e Initial load
duke
parents:
diff changeset
110 // loop-back control. From CountedLoopEndNodes I can reach CountedLoopNodes
a61af66fc99e Initial load
duke
parents:
diff changeset
111 // via the old-trip-counter from the Op node.
a61af66fc99e Initial load
duke
parents:
diff changeset
112
a61af66fc99e Initial load
duke
parents:
diff changeset
113 //------------------------------CountedLoopNode--------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
114 // CountedLoopNodes head simple counted loops. CountedLoopNodes have as
a61af66fc99e Initial load
duke
parents:
diff changeset
115 // inputs the incoming loop-start control and the loop-back control, so they
a61af66fc99e Initial load
duke
parents:
diff changeset
116 // act like RegionNodes. They also take in the initial trip counter, the
a61af66fc99e Initial load
duke
parents:
diff changeset
117 // loop-invariant stride and the loop-invariant limit value. CountedLoopNodes
a61af66fc99e Initial load
duke
parents:
diff changeset
118 // produce a loop-body control and the trip counter value. Since
a61af66fc99e Initial load
duke
parents:
diff changeset
119 // CountedLoopNodes behave like RegionNodes I still have a standard CFG model.
a61af66fc99e Initial load
duke
parents:
diff changeset
120
a61af66fc99e Initial load
duke
parents:
diff changeset
121 class CountedLoopNode : public LoopNode {
a61af66fc99e Initial load
duke
parents:
diff changeset
122 // Size is bigger to hold _main_idx. However, _main_idx does not change
a61af66fc99e Initial load
duke
parents:
diff changeset
123 // the semantics so it does not appear in the hash & cmp functions.
a61af66fc99e Initial load
duke
parents:
diff changeset
124 virtual uint size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
125
a61af66fc99e Initial load
duke
parents:
diff changeset
126 // For Pre- and Post-loops during debugging ONLY, this holds the index of
a61af66fc99e Initial load
duke
parents:
diff changeset
127 // the Main CountedLoop. Used to assert that we understand the graph shape.
a61af66fc99e Initial load
duke
parents:
diff changeset
128 node_idx_t _main_idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
129
a61af66fc99e Initial load
duke
parents:
diff changeset
130 // Known trip count calculated by policy_maximally_unroll
a61af66fc99e Initial load
duke
parents:
diff changeset
131 int _trip_count;
a61af66fc99e Initial load
duke
parents:
diff changeset
132
a61af66fc99e Initial load
duke
parents:
diff changeset
133 // Expected trip count from profile data
a61af66fc99e Initial load
duke
parents:
diff changeset
134 float _profile_trip_cnt;
a61af66fc99e Initial load
duke
parents:
diff changeset
135
a61af66fc99e Initial load
duke
parents:
diff changeset
136 // Log2 of original loop bodies in unrolled loop
a61af66fc99e Initial load
duke
parents:
diff changeset
137 int _unrolled_count_log2;
a61af66fc99e Initial load
duke
parents:
diff changeset
138
a61af66fc99e Initial load
duke
parents:
diff changeset
139 // Node count prior to last unrolling - used to decide if
a61af66fc99e Initial load
duke
parents:
diff changeset
140 // unroll,optimize,unroll,optimize,... is making progress
a61af66fc99e Initial load
duke
parents:
diff changeset
141 int _node_count_before_unroll;
a61af66fc99e Initial load
duke
parents:
diff changeset
142
a61af66fc99e Initial load
duke
parents:
diff changeset
143 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
144 CountedLoopNode( Node *entry, Node *backedge )
a61af66fc99e Initial load
duke
parents:
diff changeset
145 : LoopNode(entry, backedge), _trip_count(max_jint),
a61af66fc99e Initial load
duke
parents:
diff changeset
146 _profile_trip_cnt(COUNT_UNKNOWN), _unrolled_count_log2(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
147 _node_count_before_unroll(0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
148 init_class_id(Class_CountedLoop);
a61af66fc99e Initial load
duke
parents:
diff changeset
149 // Initialize _trip_count to the largest possible value.
a61af66fc99e Initial load
duke
parents:
diff changeset
150 // Will be reset (lower) if the loop's trip count is known.
a61af66fc99e Initial load
duke
parents:
diff changeset
151 }
a61af66fc99e Initial load
duke
parents:
diff changeset
152
a61af66fc99e Initial load
duke
parents:
diff changeset
153 virtual int Opcode() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
154 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
a61af66fc99e Initial load
duke
parents:
diff changeset
155
a61af66fc99e Initial load
duke
parents:
diff changeset
156 Node *init_control() const { return in(EntryControl); }
a61af66fc99e Initial load
duke
parents:
diff changeset
157 Node *back_control() const { return in(LoopBackControl); }
a61af66fc99e Initial load
duke
parents:
diff changeset
158 CountedLoopEndNode *loopexit() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
159 Node *init_trip() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
160 Node *stride() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
161 int stride_con() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
162 bool stride_is_con() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
163 Node *limit() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
164 Node *incr() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
165 Node *phi() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
166
a61af66fc99e Initial load
duke
parents:
diff changeset
167 // Match increment with optional truncation
a61af66fc99e Initial load
duke
parents:
diff changeset
168 static Node* match_incr_with_optional_truncation(Node* expr, Node** trunc1, Node** trunc2, const TypeInt** trunc_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
169
a61af66fc99e Initial load
duke
parents:
diff changeset
170 // A 'main' loop has a pre-loop and a post-loop. The 'main' loop
a61af66fc99e Initial load
duke
parents:
diff changeset
171 // can run short a few iterations and may start a few iterations in.
a61af66fc99e Initial load
duke
parents:
diff changeset
172 // It will be RCE'd and unrolled and aligned.
a61af66fc99e Initial load
duke
parents:
diff changeset
173
a61af66fc99e Initial load
duke
parents:
diff changeset
174 // A following 'post' loop will run any remaining iterations. Used
a61af66fc99e Initial load
duke
parents:
diff changeset
175 // during Range Check Elimination, the 'post' loop will do any final
a61af66fc99e Initial load
duke
parents:
diff changeset
176 // iterations with full checks. Also used by Loop Unrolling, where
a61af66fc99e Initial load
duke
parents:
diff changeset
177 // the 'post' loop will do any epilog iterations needed. Basically,
a61af66fc99e Initial load
duke
parents:
diff changeset
178 // a 'post' loop can not profitably be further unrolled or RCE'd.
a61af66fc99e Initial load
duke
parents:
diff changeset
179
a61af66fc99e Initial load
duke
parents:
diff changeset
180 // A preceding 'pre' loop will run at least 1 iteration (to do peeling),
a61af66fc99e Initial load
duke
parents:
diff changeset
181 // it may do under-flow checks for RCE and may do alignment iterations
a61af66fc99e Initial load
duke
parents:
diff changeset
182 // so the following main loop 'knows' that it is striding down cache
a61af66fc99e Initial load
duke
parents:
diff changeset
183 // lines.
a61af66fc99e Initial load
duke
parents:
diff changeset
184
a61af66fc99e Initial load
duke
parents:
diff changeset
185 // A 'main' loop that is ONLY unrolled or peeled, never RCE'd or
a61af66fc99e Initial load
duke
parents:
diff changeset
186 // Aligned, may be missing it's pre-loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
187 enum { Normal=0, Pre=1, Main=2, Post=3, PrePostFlagsMask=3, Main_Has_No_Pre_Loop=4 };
a61af66fc99e Initial load
duke
parents:
diff changeset
188 int is_normal_loop() const { return (_loop_flags&PrePostFlagsMask) == Normal; }
a61af66fc99e Initial load
duke
parents:
diff changeset
189 int is_pre_loop () const { return (_loop_flags&PrePostFlagsMask) == Pre; }
a61af66fc99e Initial load
duke
parents:
diff changeset
190 int is_main_loop () const { return (_loop_flags&PrePostFlagsMask) == Main; }
a61af66fc99e Initial load
duke
parents:
diff changeset
191 int is_post_loop () const { return (_loop_flags&PrePostFlagsMask) == Post; }
a61af66fc99e Initial load
duke
parents:
diff changeset
192 int is_main_no_pre_loop() const { return _loop_flags & Main_Has_No_Pre_Loop; }
a61af66fc99e Initial load
duke
parents:
diff changeset
193 void set_main_no_pre_loop() { _loop_flags |= Main_Has_No_Pre_Loop; }
a61af66fc99e Initial load
duke
parents:
diff changeset
194
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
195 int main_idx() const { return _main_idx; }
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
196
0
a61af66fc99e Initial load
duke
parents:
diff changeset
197
a61af66fc99e Initial load
duke
parents:
diff changeset
198 void set_pre_loop (CountedLoopNode *main) { assert(is_normal_loop(),""); _loop_flags |= Pre ; _main_idx = main->_idx; }
a61af66fc99e Initial load
duke
parents:
diff changeset
199 void set_main_loop ( ) { assert(is_normal_loop(),""); _loop_flags |= Main; }
a61af66fc99e Initial load
duke
parents:
diff changeset
200 void set_post_loop (CountedLoopNode *main) { assert(is_normal_loop(),""); _loop_flags |= Post; _main_idx = main->_idx; }
a61af66fc99e Initial load
duke
parents:
diff changeset
201 void set_normal_loop( ) { _loop_flags &= ~PrePostFlagsMask; }
a61af66fc99e Initial load
duke
parents:
diff changeset
202
a61af66fc99e Initial load
duke
parents:
diff changeset
203 void set_trip_count(int tc) { _trip_count = tc; }
a61af66fc99e Initial load
duke
parents:
diff changeset
204 int trip_count() { return _trip_count; }
a61af66fc99e Initial load
duke
parents:
diff changeset
205
a61af66fc99e Initial load
duke
parents:
diff changeset
206 void set_profile_trip_cnt(float ptc) { _profile_trip_cnt = ptc; }
a61af66fc99e Initial load
duke
parents:
diff changeset
207 float profile_trip_cnt() { return _profile_trip_cnt; }
a61af66fc99e Initial load
duke
parents:
diff changeset
208
a61af66fc99e Initial load
duke
parents:
diff changeset
209 void double_unrolled_count() { _unrolled_count_log2++; }
a61af66fc99e Initial load
duke
parents:
diff changeset
210 int unrolled_count() { return 1 << MIN2(_unrolled_count_log2, BitsPerInt-3); }
a61af66fc99e Initial load
duke
parents:
diff changeset
211
a61af66fc99e Initial load
duke
parents:
diff changeset
212 void set_node_count_before_unroll(int ct) { _node_count_before_unroll = ct; }
a61af66fc99e Initial load
duke
parents:
diff changeset
213 int node_count_before_unroll() { return _node_count_before_unroll; }
a61af66fc99e Initial load
duke
parents:
diff changeset
214
a61af66fc99e Initial load
duke
parents:
diff changeset
215 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
216 virtual void dump_spec(outputStream *st) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
217 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
218 };
a61af66fc99e Initial load
duke
parents:
diff changeset
219
a61af66fc99e Initial load
duke
parents:
diff changeset
220 //------------------------------CountedLoopEndNode-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
221 // CountedLoopEndNodes end simple trip counted loops. They act much like
a61af66fc99e Initial load
duke
parents:
diff changeset
222 // IfNodes.
a61af66fc99e Initial load
duke
parents:
diff changeset
223 class CountedLoopEndNode : public IfNode {
a61af66fc99e Initial load
duke
parents:
diff changeset
224 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
225 enum { TestControl, TestValue };
a61af66fc99e Initial load
duke
parents:
diff changeset
226
a61af66fc99e Initial load
duke
parents:
diff changeset
227 CountedLoopEndNode( Node *control, Node *test, float prob, float cnt )
a61af66fc99e Initial load
duke
parents:
diff changeset
228 : IfNode( control, test, prob, cnt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
229 init_class_id(Class_CountedLoopEnd);
a61af66fc99e Initial load
duke
parents:
diff changeset
230 }
a61af66fc99e Initial load
duke
parents:
diff changeset
231 virtual int Opcode() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
232
a61af66fc99e Initial load
duke
parents:
diff changeset
233 Node *cmp_node() const { return (in(TestValue)->req() >=2) ? in(TestValue)->in(1) : NULL; }
a61af66fc99e Initial load
duke
parents:
diff changeset
234 Node *incr() const { Node *tmp = cmp_node(); return (tmp && tmp->req()==3) ? tmp->in(1) : NULL; }
a61af66fc99e Initial load
duke
parents:
diff changeset
235 Node *limit() const { Node *tmp = cmp_node(); return (tmp && tmp->req()==3) ? tmp->in(2) : NULL; }
a61af66fc99e Initial load
duke
parents:
diff changeset
236 Node *stride() const { Node *tmp = incr (); return (tmp && tmp->req()==3) ? tmp->in(2) : NULL; }
a61af66fc99e Initial load
duke
parents:
diff changeset
237 Node *phi() const { Node *tmp = incr (); return (tmp && tmp->req()==3) ? tmp->in(1) : NULL; }
a61af66fc99e Initial load
duke
parents:
diff changeset
238 Node *init_trip() const { Node *tmp = phi (); return (tmp && tmp->req()==3) ? tmp->in(1) : NULL; }
a61af66fc99e Initial load
duke
parents:
diff changeset
239 int stride_con() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
240 bool stride_is_con() const { Node *tmp = stride (); return (tmp != NULL && tmp->is_Con()); }
a61af66fc99e Initial load
duke
parents:
diff changeset
241 BoolTest::mask test_trip() const { return in(TestValue)->as_Bool()->_test._test; }
a61af66fc99e Initial load
duke
parents:
diff changeset
242 CountedLoopNode *loopnode() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
243 Node *ln = phi()->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
244 assert( ln->Opcode() == Op_CountedLoop, "malformed loop" );
a61af66fc99e Initial load
duke
parents:
diff changeset
245 return (CountedLoopNode*)ln; }
a61af66fc99e Initial load
duke
parents:
diff changeset
246
a61af66fc99e Initial load
duke
parents:
diff changeset
247 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
248 virtual void dump_spec(outputStream *st) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
249 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
250 };
a61af66fc99e Initial load
duke
parents:
diff changeset
251
a61af66fc99e Initial load
duke
parents:
diff changeset
252
a61af66fc99e Initial load
duke
parents:
diff changeset
253 inline CountedLoopEndNode *CountedLoopNode::loopexit() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
254 Node *bc = back_control();
a61af66fc99e Initial load
duke
parents:
diff changeset
255 if( bc == NULL ) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
256 Node *le = bc->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
257 if( le->Opcode() != Op_CountedLoopEnd )
a61af66fc99e Initial load
duke
parents:
diff changeset
258 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
259 return (CountedLoopEndNode*)le;
a61af66fc99e Initial load
duke
parents:
diff changeset
260 }
a61af66fc99e Initial load
duke
parents:
diff changeset
261 inline Node *CountedLoopNode::init_trip() const { return loopexit() ? loopexit()->init_trip() : NULL; }
a61af66fc99e Initial load
duke
parents:
diff changeset
262 inline Node *CountedLoopNode::stride() const { return loopexit() ? loopexit()->stride() : NULL; }
a61af66fc99e Initial load
duke
parents:
diff changeset
263 inline int CountedLoopNode::stride_con() const { return loopexit() ? loopexit()->stride_con() : 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
264 inline bool CountedLoopNode::stride_is_con() const { return loopexit() && loopexit()->stride_is_con(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
265 inline Node *CountedLoopNode::limit() const { return loopexit() ? loopexit()->limit() : NULL; }
a61af66fc99e Initial load
duke
parents:
diff changeset
266 inline Node *CountedLoopNode::incr() const { return loopexit() ? loopexit()->incr() : NULL; }
a61af66fc99e Initial load
duke
parents:
diff changeset
267 inline Node *CountedLoopNode::phi() const { return loopexit() ? loopexit()->phi() : NULL; }
a61af66fc99e Initial load
duke
parents:
diff changeset
268
a61af66fc99e Initial load
duke
parents:
diff changeset
269
a61af66fc99e Initial load
duke
parents:
diff changeset
270 // -----------------------------IdealLoopTree----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
271 class IdealLoopTree : public ResourceObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
272 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
273 IdealLoopTree *_parent; // Parent in loop tree
a61af66fc99e Initial load
duke
parents:
diff changeset
274 IdealLoopTree *_next; // Next sibling in loop tree
a61af66fc99e Initial load
duke
parents:
diff changeset
275 IdealLoopTree *_child; // First child in loop tree
a61af66fc99e Initial load
duke
parents:
diff changeset
276
a61af66fc99e Initial load
duke
parents:
diff changeset
277 // The head-tail backedge defines the loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
278 // If tail is NULL then this loop has multiple backedges as part of the
a61af66fc99e Initial load
duke
parents:
diff changeset
279 // same loop. During cleanup I'll peel off the multiple backedges; merge
a61af66fc99e Initial load
duke
parents:
diff changeset
280 // them at the loop bottom and flow 1 real backedge into the loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
281 Node *_head; // Head of loop
a61af66fc99e Initial load
duke
parents:
diff changeset
282 Node *_tail; // Tail of loop
a61af66fc99e Initial load
duke
parents:
diff changeset
283 inline Node *tail(); // Handle lazy update of _tail field
a61af66fc99e Initial load
duke
parents:
diff changeset
284 PhaseIdealLoop* _phase;
a61af66fc99e Initial load
duke
parents:
diff changeset
285
a61af66fc99e Initial load
duke
parents:
diff changeset
286 Node_List _body; // Loop body for inner loops
a61af66fc99e Initial load
duke
parents:
diff changeset
287
a61af66fc99e Initial load
duke
parents:
diff changeset
288 uint8 _nest; // Nesting depth
a61af66fc99e Initial load
duke
parents:
diff changeset
289 uint8 _irreducible:1, // True if irreducible
a61af66fc99e Initial load
duke
parents:
diff changeset
290 _has_call:1, // True if has call safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
291 _has_sfpt:1, // True if has non-call safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
292 _rce_candidate:1; // True if candidate for range check elimination
a61af66fc99e Initial load
duke
parents:
diff changeset
293
39
76256d272075 6667612: (Escape Analysis) disable loop cloning if it has a scalar replaceable allocation
kvn
parents: 17
diff changeset
294 Node_List* _required_safept; // A inner loop cannot delete these safepts;
76256d272075 6667612: (Escape Analysis) disable loop cloning if it has a scalar replaceable allocation
kvn
parents: 17
diff changeset
295 bool _allow_optimizations; // Allow loop optimizations
0
a61af66fc99e Initial load
duke
parents:
diff changeset
296
a61af66fc99e Initial load
duke
parents:
diff changeset
297 IdealLoopTree( PhaseIdealLoop* phase, Node *head, Node *tail )
a61af66fc99e Initial load
duke
parents:
diff changeset
298 : _parent(0), _next(0), _child(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
299 _head(head), _tail(tail),
a61af66fc99e Initial load
duke
parents:
diff changeset
300 _phase(phase),
a61af66fc99e Initial load
duke
parents:
diff changeset
301 _required_safept(NULL),
39
76256d272075 6667612: (Escape Analysis) disable loop cloning if it has a scalar replaceable allocation
kvn
parents: 17
diff changeset
302 _allow_optimizations(true),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
303 _nest(0), _irreducible(0), _has_call(0), _has_sfpt(0), _rce_candidate(0)
a61af66fc99e Initial load
duke
parents:
diff changeset
304 { }
a61af66fc99e Initial load
duke
parents:
diff changeset
305
a61af66fc99e Initial load
duke
parents:
diff changeset
306 // Is 'l' a member of 'this'?
a61af66fc99e Initial load
duke
parents:
diff changeset
307 int is_member( const IdealLoopTree *l ) const; // Test for nested membership
a61af66fc99e Initial load
duke
parents:
diff changeset
308
a61af66fc99e Initial load
duke
parents:
diff changeset
309 // Set loop nesting depth. Accumulate has_call bits.
a61af66fc99e Initial load
duke
parents:
diff changeset
310 int set_nest( uint depth );
a61af66fc99e Initial load
duke
parents:
diff changeset
311
a61af66fc99e Initial load
duke
parents:
diff changeset
312 // Split out multiple fall-in edges from the loop header. Move them to a
a61af66fc99e Initial load
duke
parents:
diff changeset
313 // private RegionNode before the loop. This becomes the loop landing pad.
a61af66fc99e Initial load
duke
parents:
diff changeset
314 void split_fall_in( PhaseIdealLoop *phase, int fall_in_cnt );
a61af66fc99e Initial load
duke
parents:
diff changeset
315
a61af66fc99e Initial load
duke
parents:
diff changeset
316 // Split out the outermost loop from this shared header.
a61af66fc99e Initial load
duke
parents:
diff changeset
317 void split_outer_loop( PhaseIdealLoop *phase );
a61af66fc99e Initial load
duke
parents:
diff changeset
318
a61af66fc99e Initial load
duke
parents:
diff changeset
319 // Merge all the backedges from the shared header into a private Region.
a61af66fc99e Initial load
duke
parents:
diff changeset
320 // Feed that region as the one backedge to this loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
321 void merge_many_backedges( PhaseIdealLoop *phase );
a61af66fc99e Initial load
duke
parents:
diff changeset
322
a61af66fc99e Initial load
duke
parents:
diff changeset
323 // Split shared headers and insert loop landing pads.
a61af66fc99e Initial load
duke
parents:
diff changeset
324 // Insert a LoopNode to replace the RegionNode.
a61af66fc99e Initial load
duke
parents:
diff changeset
325 // Returns TRUE if loop tree is structurally changed.
a61af66fc99e Initial load
duke
parents:
diff changeset
326 bool beautify_loops( PhaseIdealLoop *phase );
a61af66fc99e Initial load
duke
parents:
diff changeset
327
401
ee8f06bfb27c 6743188: incomplete fix for 6700047 C2 failed in idom_no_update
never
parents: 367
diff changeset
328 // Perform iteration-splitting on inner loops. Split iterations to
ee8f06bfb27c 6743188: incomplete fix for 6700047 C2 failed in idom_no_update
never
parents: 367
diff changeset
329 // avoid range checks or one-shot null checks. Returns false if the
ee8f06bfb27c 6743188: incomplete fix for 6700047 C2 failed in idom_no_update
never
parents: 367
diff changeset
330 // current round of loop opts should stop.
ee8f06bfb27c 6743188: incomplete fix for 6700047 C2 failed in idom_no_update
never
parents: 367
diff changeset
331 bool iteration_split( PhaseIdealLoop *phase, Node_List &old_new );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
332
401
ee8f06bfb27c 6743188: incomplete fix for 6700047 C2 failed in idom_no_update
never
parents: 367
diff changeset
333 // Driver for various flavors of iteration splitting. Returns false
ee8f06bfb27c 6743188: incomplete fix for 6700047 C2 failed in idom_no_update
never
parents: 367
diff changeset
334 // if the current round of loop opts should stop.
ee8f06bfb27c 6743188: incomplete fix for 6700047 C2 failed in idom_no_update
never
parents: 367
diff changeset
335 bool iteration_split_impl( PhaseIdealLoop *phase, Node_List &old_new );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
336
a61af66fc99e Initial load
duke
parents:
diff changeset
337 // Given dominators, try to find loops with calls that must always be
a61af66fc99e Initial load
duke
parents:
diff changeset
338 // executed (call dominates loop tail). These loops do not need non-call
a61af66fc99e Initial load
duke
parents:
diff changeset
339 // safepoints (ncsfpt).
a61af66fc99e Initial load
duke
parents:
diff changeset
340 void check_safepts(VectorSet &visited, Node_List &stack);
a61af66fc99e Initial load
duke
parents:
diff changeset
341
a61af66fc99e Initial load
duke
parents:
diff changeset
342 // Allpaths backwards scan from loop tail, terminating each path at first safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
343 // encountered.
a61af66fc99e Initial load
duke
parents:
diff changeset
344 void allpaths_check_safepts(VectorSet &visited, Node_List &stack);
a61af66fc99e Initial load
duke
parents:
diff changeset
345
a61af66fc99e Initial load
duke
parents:
diff changeset
346 // Convert to counted loops where possible
a61af66fc99e Initial load
duke
parents:
diff changeset
347 void counted_loop( PhaseIdealLoop *phase );
a61af66fc99e Initial load
duke
parents:
diff changeset
348
a61af66fc99e Initial load
duke
parents:
diff changeset
349 // Check for Node being a loop-breaking test
a61af66fc99e Initial load
duke
parents:
diff changeset
350 Node *is_loop_exit(Node *iff) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
351
a61af66fc99e Initial load
duke
parents:
diff changeset
352 // Returns true if ctrl is executed on every complete iteration
a61af66fc99e Initial load
duke
parents:
diff changeset
353 bool dominates_backedge(Node* ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
354
a61af66fc99e Initial load
duke
parents:
diff changeset
355 // Remove simplistic dead code from loop body
a61af66fc99e Initial load
duke
parents:
diff changeset
356 void DCE_loop_body();
a61af66fc99e Initial load
duke
parents:
diff changeset
357
a61af66fc99e Initial load
duke
parents:
diff changeset
358 // Look for loop-exit tests with my 50/50 guesses from the Parsing stage.
a61af66fc99e Initial load
duke
parents:
diff changeset
359 // Replace with a 1-in-10 exit guess.
a61af66fc99e Initial load
duke
parents:
diff changeset
360 void adjust_loop_exit_prob( PhaseIdealLoop *phase );
a61af66fc99e Initial load
duke
parents:
diff changeset
361
a61af66fc99e Initial load
duke
parents:
diff changeset
362 // Return TRUE or FALSE if the loop should never be RCE'd or aligned.
a61af66fc99e Initial load
duke
parents:
diff changeset
363 // Useful for unrolling loops with NO array accesses.
a61af66fc99e Initial load
duke
parents:
diff changeset
364 bool policy_peel_only( PhaseIdealLoop *phase ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
365
a61af66fc99e Initial load
duke
parents:
diff changeset
366 // Return TRUE or FALSE if the loop should be unswitched -- clone
a61af66fc99e Initial load
duke
parents:
diff changeset
367 // loop with an invariant test
a61af66fc99e Initial load
duke
parents:
diff changeset
368 bool policy_unswitching( PhaseIdealLoop *phase ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
369
a61af66fc99e Initial load
duke
parents:
diff changeset
370 // Micro-benchmark spamming. Remove empty loops.
a61af66fc99e Initial load
duke
parents:
diff changeset
371 bool policy_do_remove_empty_loop( PhaseIdealLoop *phase );
a61af66fc99e Initial load
duke
parents:
diff changeset
372
a61af66fc99e Initial load
duke
parents:
diff changeset
373 // Return TRUE or FALSE if the loop should be peeled or not. Peel if we can
a61af66fc99e Initial load
duke
parents:
diff changeset
374 // make some loop-invariant test (usually a null-check) happen before the
a61af66fc99e Initial load
duke
parents:
diff changeset
375 // loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
376 bool policy_peeling( PhaseIdealLoop *phase ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
377
a61af66fc99e Initial load
duke
parents:
diff changeset
378 // Return TRUE or FALSE if the loop should be maximally unrolled. Stash any
a61af66fc99e Initial load
duke
parents:
diff changeset
379 // known trip count in the counted loop node.
a61af66fc99e Initial load
duke
parents:
diff changeset
380 bool policy_maximally_unroll( PhaseIdealLoop *phase ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
381
a61af66fc99e Initial load
duke
parents:
diff changeset
382 // Return TRUE or FALSE if the loop should be unrolled or not. Unroll if
a61af66fc99e Initial load
duke
parents:
diff changeset
383 // the loop is a CountedLoop and the body is small enough.
a61af66fc99e Initial load
duke
parents:
diff changeset
384 bool policy_unroll( PhaseIdealLoop *phase ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
385
a61af66fc99e Initial load
duke
parents:
diff changeset
386 // Return TRUE or FALSE if the loop should be range-check-eliminated.
a61af66fc99e Initial load
duke
parents:
diff changeset
387 // Gather a list of IF tests that are dominated by iteration splitting;
a61af66fc99e Initial load
duke
parents:
diff changeset
388 // also gather the end of the first split and the start of the 2nd split.
a61af66fc99e Initial load
duke
parents:
diff changeset
389 bool policy_range_check( PhaseIdealLoop *phase ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
390
a61af66fc99e Initial load
duke
parents:
diff changeset
391 // Return TRUE or FALSE if the loop should be cache-line aligned.
a61af66fc99e Initial load
duke
parents:
diff changeset
392 // Gather the expression that does the alignment. Note that only
605
98cb887364d3 6810672: Comment typos
twisti
parents: 401
diff changeset
393 // one array base can be aligned in a loop (unless the VM guarantees
0
a61af66fc99e Initial load
duke
parents:
diff changeset
394 // mutual alignment). Note that if we vectorize short memory ops
a61af66fc99e Initial load
duke
parents:
diff changeset
395 // into longer memory ops, we may want to increase alignment.
a61af66fc99e Initial load
duke
parents:
diff changeset
396 bool policy_align( PhaseIdealLoop *phase ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
397
a61af66fc99e Initial load
duke
parents:
diff changeset
398 // Compute loop trip count from profile data
a61af66fc99e Initial load
duke
parents:
diff changeset
399 void compute_profile_trip_cnt( PhaseIdealLoop *phase );
a61af66fc99e Initial load
duke
parents:
diff changeset
400
a61af66fc99e Initial load
duke
parents:
diff changeset
401 // Reassociate invariant expressions.
a61af66fc99e Initial load
duke
parents:
diff changeset
402 void reassociate_invariants(PhaseIdealLoop *phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
403 // Reassociate invariant add and subtract expressions.
a61af66fc99e Initial load
duke
parents:
diff changeset
404 Node* reassociate_add_sub(Node* n1, PhaseIdealLoop *phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
405 // Return nonzero index of invariant operand if invariant and variant
605
98cb887364d3 6810672: Comment typos
twisti
parents: 401
diff changeset
406 // are combined with an Add or Sub. Helper for reassociate_invariants.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
407 int is_invariant_addition(Node* n, PhaseIdealLoop *phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
408
a61af66fc99e Initial load
duke
parents:
diff changeset
409 // Return true if n is invariant
a61af66fc99e Initial load
duke
parents:
diff changeset
410 bool is_invariant(Node* n) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
411
a61af66fc99e Initial load
duke
parents:
diff changeset
412 // Put loop body on igvn work list
a61af66fc99e Initial load
duke
parents:
diff changeset
413 void record_for_igvn();
a61af66fc99e Initial load
duke
parents:
diff changeset
414
a61af66fc99e Initial load
duke
parents:
diff changeset
415 bool is_loop() { return !_irreducible && _tail && !_tail->is_top(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
416 bool is_inner() { return is_loop() && _child == NULL; }
a61af66fc99e Initial load
duke
parents:
diff changeset
417 bool is_counted() { return is_loop() && _head != NULL && _head->is_CountedLoop(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
418
a61af66fc99e Initial load
duke
parents:
diff changeset
419 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
420 void dump_head( ) const; // Dump loop head only
a61af66fc99e Initial load
duke
parents:
diff changeset
421 void dump() const; // Dump this loop recursively
a61af66fc99e Initial load
duke
parents:
diff changeset
422 void verify_tree(IdealLoopTree *loop, const IdealLoopTree *parent) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
423 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
424
a61af66fc99e Initial load
duke
parents:
diff changeset
425 };
a61af66fc99e Initial load
duke
parents:
diff changeset
426
a61af66fc99e Initial load
duke
parents:
diff changeset
427 // -----------------------------PhaseIdealLoop---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
428 // Computes the mapping from Nodes to IdealLoopTrees. Organizes IdealLoopTrees into a
a61af66fc99e Initial load
duke
parents:
diff changeset
429 // loop tree. Drives the loop-based transformations on the ideal graph.
a61af66fc99e Initial load
duke
parents:
diff changeset
430 class PhaseIdealLoop : public PhaseTransform {
a61af66fc99e Initial load
duke
parents:
diff changeset
431 friend class IdealLoopTree;
a61af66fc99e Initial load
duke
parents:
diff changeset
432 friend class SuperWord;
a61af66fc99e Initial load
duke
parents:
diff changeset
433 // Pre-computed def-use info
a61af66fc99e Initial load
duke
parents:
diff changeset
434 PhaseIterGVN &_igvn;
a61af66fc99e Initial load
duke
parents:
diff changeset
435
a61af66fc99e Initial load
duke
parents:
diff changeset
436 // Head of loop tree
a61af66fc99e Initial load
duke
parents:
diff changeset
437 IdealLoopTree *_ltree_root;
a61af66fc99e Initial load
duke
parents:
diff changeset
438
a61af66fc99e Initial load
duke
parents:
diff changeset
439 // Array of pre-order numbers, plus post-visited bit.
a61af66fc99e Initial load
duke
parents:
diff changeset
440 // ZERO for not pre-visited. EVEN for pre-visited but not post-visited.
a61af66fc99e Initial load
duke
parents:
diff changeset
441 // ODD for post-visited. Other bits are the pre-order number.
a61af66fc99e Initial load
duke
parents:
diff changeset
442 uint *_preorders;
a61af66fc99e Initial load
duke
parents:
diff changeset
443 uint _max_preorder;
a61af66fc99e Initial load
duke
parents:
diff changeset
444
921
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
445 const PhaseIdealLoop* _verify_me;
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
446 bool _verify_only;
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
447
0
a61af66fc99e Initial load
duke
parents:
diff changeset
448 // Allocate _preorders[] array
a61af66fc99e Initial load
duke
parents:
diff changeset
449 void allocate_preorders() {
a61af66fc99e Initial load
duke
parents:
diff changeset
450 _max_preorder = C->unique()+8;
a61af66fc99e Initial load
duke
parents:
diff changeset
451 _preorders = NEW_RESOURCE_ARRAY(uint, _max_preorder);
a61af66fc99e Initial load
duke
parents:
diff changeset
452 memset(_preorders, 0, sizeof(uint) * _max_preorder);
a61af66fc99e Initial load
duke
parents:
diff changeset
453 }
a61af66fc99e Initial load
duke
parents:
diff changeset
454
a61af66fc99e Initial load
duke
parents:
diff changeset
455 // Allocate _preorders[] array
a61af66fc99e Initial load
duke
parents:
diff changeset
456 void reallocate_preorders() {
a61af66fc99e Initial load
duke
parents:
diff changeset
457 if ( _max_preorder < C->unique() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
458 _preorders = REALLOC_RESOURCE_ARRAY(uint, _preorders, _max_preorder, C->unique());
a61af66fc99e Initial load
duke
parents:
diff changeset
459 _max_preorder = C->unique();
a61af66fc99e Initial load
duke
parents:
diff changeset
460 }
a61af66fc99e Initial load
duke
parents:
diff changeset
461 memset(_preorders, 0, sizeof(uint) * _max_preorder);
a61af66fc99e Initial load
duke
parents:
diff changeset
462 }
a61af66fc99e Initial load
duke
parents:
diff changeset
463
a61af66fc99e Initial load
duke
parents:
diff changeset
464 // Check to grow _preorders[] array for the case when build_loop_tree_impl()
a61af66fc99e Initial load
duke
parents:
diff changeset
465 // adds new nodes.
a61af66fc99e Initial load
duke
parents:
diff changeset
466 void check_grow_preorders( ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
467 if ( _max_preorder < C->unique() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
468 uint newsize = _max_preorder<<1; // double size of array
a61af66fc99e Initial load
duke
parents:
diff changeset
469 _preorders = REALLOC_RESOURCE_ARRAY(uint, _preorders, _max_preorder, newsize);
a61af66fc99e Initial load
duke
parents:
diff changeset
470 memset(&_preorders[_max_preorder],0,sizeof(uint)*(newsize-_max_preorder));
a61af66fc99e Initial load
duke
parents:
diff changeset
471 _max_preorder = newsize;
a61af66fc99e Initial load
duke
parents:
diff changeset
472 }
a61af66fc99e Initial load
duke
parents:
diff changeset
473 }
a61af66fc99e Initial load
duke
parents:
diff changeset
474 // Check for pre-visited. Zero for NOT visited; non-zero for visited.
a61af66fc99e Initial load
duke
parents:
diff changeset
475 int is_visited( Node *n ) const { return _preorders[n->_idx]; }
a61af66fc99e Initial load
duke
parents:
diff changeset
476 // Pre-order numbers are written to the Nodes array as low-bit-set values.
a61af66fc99e Initial load
duke
parents:
diff changeset
477 void set_preorder_visited( Node *n, int pre_order ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
478 assert( !is_visited( n ), "already set" );
a61af66fc99e Initial load
duke
parents:
diff changeset
479 _preorders[n->_idx] = (pre_order<<1);
a61af66fc99e Initial load
duke
parents:
diff changeset
480 };
a61af66fc99e Initial load
duke
parents:
diff changeset
481 // Return pre-order number.
a61af66fc99e Initial load
duke
parents:
diff changeset
482 int get_preorder( Node *n ) const { assert( is_visited(n), "" ); return _preorders[n->_idx]>>1; }
a61af66fc99e Initial load
duke
parents:
diff changeset
483
a61af66fc99e Initial load
duke
parents:
diff changeset
484 // Check for being post-visited.
a61af66fc99e Initial load
duke
parents:
diff changeset
485 // Should be previsited already (checked with assert(is_visited(n))).
a61af66fc99e Initial load
duke
parents:
diff changeset
486 int is_postvisited( Node *n ) const { assert( is_visited(n), "" ); return _preorders[n->_idx]&1; }
a61af66fc99e Initial load
duke
parents:
diff changeset
487
a61af66fc99e Initial load
duke
parents:
diff changeset
488 // Mark as post visited
a61af66fc99e Initial load
duke
parents:
diff changeset
489 void set_postvisited( Node *n ) { assert( !is_postvisited( n ), "" ); _preorders[n->_idx] |= 1; }
a61af66fc99e Initial load
duke
parents:
diff changeset
490
a61af66fc99e Initial load
duke
parents:
diff changeset
491 // Set/get control node out. Set lower bit to distinguish from IdealLoopTree
a61af66fc99e Initial load
duke
parents:
diff changeset
492 // Returns true if "n" is a data node, false if it's a control node.
a61af66fc99e Initial load
duke
parents:
diff changeset
493 bool has_ctrl( Node *n ) const { return ((intptr_t)_nodes[n->_idx]) & 1; }
a61af66fc99e Initial load
duke
parents:
diff changeset
494
a61af66fc99e Initial load
duke
parents:
diff changeset
495 // clear out dead code after build_loop_late
a61af66fc99e Initial load
duke
parents:
diff changeset
496 Node_List _deadlist;
a61af66fc99e Initial load
duke
parents:
diff changeset
497
a61af66fc99e Initial load
duke
parents:
diff changeset
498 // Support for faster execution of get_late_ctrl()/dom_lca()
a61af66fc99e Initial load
duke
parents:
diff changeset
499 // when a node has many uses and dominator depth is deep.
a61af66fc99e Initial load
duke
parents:
diff changeset
500 Node_Array _dom_lca_tags;
a61af66fc99e Initial load
duke
parents:
diff changeset
501 void init_dom_lca_tags();
a61af66fc99e Initial load
duke
parents:
diff changeset
502 void clear_dom_lca_tags();
921
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
503
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
504 // Helper for debugging bad dominance relationships
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
505 bool verify_dominance(Node* n, Node* use, Node* LCA, Node* early);
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
506
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
507 Node* compute_lca_of_uses(Node* n, Node* early, bool verify = false);
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
508
0
a61af66fc99e Initial load
duke
parents:
diff changeset
509 // Inline wrapper for frequent cases:
a61af66fc99e Initial load
duke
parents:
diff changeset
510 // 1) only one use
a61af66fc99e Initial load
duke
parents:
diff changeset
511 // 2) a use is the same as the current LCA passed as 'n1'
a61af66fc99e Initial load
duke
parents:
diff changeset
512 Node *dom_lca_for_get_late_ctrl( Node *lca, Node *n, Node *tag ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
513 assert( n->is_CFG(), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
514 // Fast-path NULL lca
a61af66fc99e Initial load
duke
parents:
diff changeset
515 if( lca != NULL && lca != n ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
516 assert( lca->is_CFG(), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
517 // find LCA of all uses
a61af66fc99e Initial load
duke
parents:
diff changeset
518 n = dom_lca_for_get_late_ctrl_internal( lca, n, tag );
a61af66fc99e Initial load
duke
parents:
diff changeset
519 }
a61af66fc99e Initial load
duke
parents:
diff changeset
520 return find_non_split_ctrl(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
521 }
a61af66fc99e Initial load
duke
parents:
diff changeset
522 Node *dom_lca_for_get_late_ctrl_internal( Node *lca, Node *n, Node *tag );
921
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
523
0
a61af66fc99e Initial load
duke
parents:
diff changeset
524 // true if CFG node d dominates CFG node n
a61af66fc99e Initial load
duke
parents:
diff changeset
525 bool is_dominator(Node *d, Node *n);
a61af66fc99e Initial load
duke
parents:
diff changeset
526
a61af66fc99e Initial load
duke
parents:
diff changeset
527 // Helper function for directing control inputs away from CFG split
a61af66fc99e Initial load
duke
parents:
diff changeset
528 // points.
a61af66fc99e Initial load
duke
parents:
diff changeset
529 Node *find_non_split_ctrl( Node *ctrl ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
530 if (ctrl != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
531 if (ctrl->is_MultiBranch()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
532 ctrl = ctrl->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
533 }
a61af66fc99e Initial load
duke
parents:
diff changeset
534 assert(ctrl->is_CFG(), "CFG");
a61af66fc99e Initial load
duke
parents:
diff changeset
535 }
a61af66fc99e Initial load
duke
parents:
diff changeset
536 return ctrl;
a61af66fc99e Initial load
duke
parents:
diff changeset
537 }
a61af66fc99e Initial load
duke
parents:
diff changeset
538
a61af66fc99e Initial load
duke
parents:
diff changeset
539 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
540 bool has_node( Node* n ) const { return _nodes[n->_idx] != NULL; }
a61af66fc99e Initial load
duke
parents:
diff changeset
541 // check if transform created new nodes that need _ctrl recorded
a61af66fc99e Initial load
duke
parents:
diff changeset
542 Node *get_late_ctrl( Node *n, Node *early );
a61af66fc99e Initial load
duke
parents:
diff changeset
543 Node *get_early_ctrl( Node *n );
a61af66fc99e Initial load
duke
parents:
diff changeset
544 void set_early_ctrl( Node *n );
a61af66fc99e Initial load
duke
parents:
diff changeset
545 void set_subtree_ctrl( Node *root );
a61af66fc99e Initial load
duke
parents:
diff changeset
546 void set_ctrl( Node *n, Node *ctrl ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
547 assert( !has_node(n) || has_ctrl(n), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
548 assert( ctrl->in(0), "cannot set dead control node" );
a61af66fc99e Initial load
duke
parents:
diff changeset
549 assert( ctrl == find_non_split_ctrl(ctrl), "must set legal crtl" );
a61af66fc99e Initial load
duke
parents:
diff changeset
550 _nodes.map( n->_idx, (Node*)((intptr_t)ctrl + 1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
551 }
a61af66fc99e Initial load
duke
parents:
diff changeset
552 // Set control and update loop membership
a61af66fc99e Initial load
duke
parents:
diff changeset
553 void set_ctrl_and_loop(Node* n, Node* ctrl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
554 IdealLoopTree* old_loop = get_loop(get_ctrl(n));
a61af66fc99e Initial load
duke
parents:
diff changeset
555 IdealLoopTree* new_loop = get_loop(ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
556 if (old_loop != new_loop) {
a61af66fc99e Initial load
duke
parents:
diff changeset
557 if (old_loop->_child == NULL) old_loop->_body.yank(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
558 if (new_loop->_child == NULL) new_loop->_body.push(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
559 }
a61af66fc99e Initial load
duke
parents:
diff changeset
560 set_ctrl(n, ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
561 }
a61af66fc99e Initial load
duke
parents:
diff changeset
562 // Control nodes can be replaced or subsumed. During this pass they
a61af66fc99e Initial load
duke
parents:
diff changeset
563 // get their replacement Node in slot 1. Instead of updating the block
a61af66fc99e Initial load
duke
parents:
diff changeset
564 // location of all Nodes in the subsumed block, we lazily do it. As we
a61af66fc99e Initial load
duke
parents:
diff changeset
565 // pull such a subsumed block out of the array, we write back the final
a61af66fc99e Initial load
duke
parents:
diff changeset
566 // correct block.
a61af66fc99e Initial load
duke
parents:
diff changeset
567 Node *get_ctrl( Node *i ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
568 assert(has_node(i), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
569 Node *n = get_ctrl_no_update(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
570 _nodes.map( i->_idx, (Node*)((intptr_t)n + 1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
571 assert(has_node(i) && has_ctrl(i), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
572 assert(n == find_non_split_ctrl(n), "must return legal ctrl" );
a61af66fc99e Initial load
duke
parents:
diff changeset
573 return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
574 }
a61af66fc99e Initial load
duke
parents:
diff changeset
575
a61af66fc99e Initial load
duke
parents:
diff changeset
576 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
577 Node *get_ctrl_no_update( Node *i ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
578 assert( has_ctrl(i), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
579 Node *n = (Node*)(((intptr_t)_nodes[i->_idx]) & ~1);
a61af66fc99e Initial load
duke
parents:
diff changeset
580 if (!n->in(0)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
581 // Skip dead CFG nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
582 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
583 n = (Node*)(((intptr_t)_nodes[n->_idx]) & ~1);
a61af66fc99e Initial load
duke
parents:
diff changeset
584 } while (!n->in(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
585 n = find_non_split_ctrl(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
586 }
a61af66fc99e Initial load
duke
parents:
diff changeset
587 return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
588 }
a61af66fc99e Initial load
duke
parents:
diff changeset
589
a61af66fc99e Initial load
duke
parents:
diff changeset
590 // Check for loop being set
a61af66fc99e Initial load
duke
parents:
diff changeset
591 // "n" must be a control node. Returns true if "n" is known to be in a loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
592 bool has_loop( Node *n ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
593 assert(!has_node(n) || !has_ctrl(n), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
594 return has_node(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
595 }
a61af66fc99e Initial load
duke
parents:
diff changeset
596 // Set loop
a61af66fc99e Initial load
duke
parents:
diff changeset
597 void set_loop( Node *n, IdealLoopTree *loop ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
598 _nodes.map(n->_idx, (Node*)loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
599 }
a61af66fc99e Initial load
duke
parents:
diff changeset
600 // Lazy-dazy update of 'get_ctrl' and 'idom_at' mechanisms. Replace
a61af66fc99e Initial load
duke
parents:
diff changeset
601 // the 'old_node' with 'new_node'. Kill old-node. Add a reference
a61af66fc99e Initial load
duke
parents:
diff changeset
602 // from old_node to new_node to support the lazy update. Reference
a61af66fc99e Initial load
duke
parents:
diff changeset
603 // replaces loop reference, since that is not neede for dead node.
a61af66fc99e Initial load
duke
parents:
diff changeset
604 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
605 void lazy_update( Node *old_node, Node *new_node ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
606 assert( old_node != new_node, "no cycles please" );
a61af66fc99e Initial load
duke
parents:
diff changeset
607 //old_node->set_req( 1, new_node /*NO DU INFO*/ );
a61af66fc99e Initial load
duke
parents:
diff changeset
608 // Nodes always have DU info now, so re-use the side array slot
a61af66fc99e Initial load
duke
parents:
diff changeset
609 // for this node to provide the forwarding pointer.
a61af66fc99e Initial load
duke
parents:
diff changeset
610 _nodes.map( old_node->_idx, (Node*)((intptr_t)new_node + 1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
611 }
a61af66fc99e Initial load
duke
parents:
diff changeset
612 void lazy_replace( Node *old_node, Node *new_node ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
613 _igvn.hash_delete(old_node);
a61af66fc99e Initial load
duke
parents:
diff changeset
614 _igvn.subsume_node( old_node, new_node );
a61af66fc99e Initial load
duke
parents:
diff changeset
615 lazy_update( old_node, new_node );
a61af66fc99e Initial load
duke
parents:
diff changeset
616 }
a61af66fc99e Initial load
duke
parents:
diff changeset
617 void lazy_replace_proj( Node *old_node, Node *new_node ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
618 assert( old_node->req() == 1, "use this for Projs" );
a61af66fc99e Initial load
duke
parents:
diff changeset
619 _igvn.hash_delete(old_node); // Must hash-delete before hacking edges
a61af66fc99e Initial load
duke
parents:
diff changeset
620 old_node->add_req( NULL );
a61af66fc99e Initial load
duke
parents:
diff changeset
621 lazy_replace( old_node, new_node );
a61af66fc99e Initial load
duke
parents:
diff changeset
622 }
a61af66fc99e Initial load
duke
parents:
diff changeset
623
a61af66fc99e Initial load
duke
parents:
diff changeset
624 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
625
a61af66fc99e Initial load
duke
parents:
diff changeset
626 // Place 'n' in some loop nest, where 'n' is a CFG node
a61af66fc99e Initial load
duke
parents:
diff changeset
627 void build_loop_tree();
a61af66fc99e Initial load
duke
parents:
diff changeset
628 int build_loop_tree_impl( Node *n, int pre_order );
a61af66fc99e Initial load
duke
parents:
diff changeset
629 // Insert loop into the existing loop tree. 'innermost' is a leaf of the
a61af66fc99e Initial load
duke
parents:
diff changeset
630 // loop tree, not the root.
a61af66fc99e Initial load
duke
parents:
diff changeset
631 IdealLoopTree *sort( IdealLoopTree *loop, IdealLoopTree *innermost );
a61af66fc99e Initial load
duke
parents:
diff changeset
632
a61af66fc99e Initial load
duke
parents:
diff changeset
633 // Place Data nodes in some loop nest
921
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
634 void build_loop_early( VectorSet &visited, Node_List &worklist, Node_Stack &nstack );
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
635 void build_loop_late ( VectorSet &visited, Node_List &worklist, Node_Stack &nstack );
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
636 void build_loop_late_post ( Node* n );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
637
a61af66fc99e Initial load
duke
parents:
diff changeset
638 // Array of immediate dominance info for each CFG node indexed by node idx
a61af66fc99e Initial load
duke
parents:
diff changeset
639 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
640 uint _idom_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
641 Node **_idom; // Array of immediate dominators
a61af66fc99e Initial load
duke
parents:
diff changeset
642 uint *_dom_depth; // Used for fast LCA test
a61af66fc99e Initial load
duke
parents:
diff changeset
643 GrowableArray<uint>* _dom_stk; // For recomputation of dom depth
a61af66fc99e Initial load
duke
parents:
diff changeset
644
a61af66fc99e Initial load
duke
parents:
diff changeset
645 Node* idom_no_update(Node* d) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
646 assert(d->_idx < _idom_size, "oob");
a61af66fc99e Initial load
duke
parents:
diff changeset
647 Node* n = _idom[d->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
648 assert(n != NULL,"Bad immediate dominator info.");
a61af66fc99e Initial load
duke
parents:
diff changeset
649 while (n->in(0) == NULL) { // Skip dead CFG nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
650 //n = n->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
651 n = (Node*)(((intptr_t)_nodes[n->_idx]) & ~1);
a61af66fc99e Initial load
duke
parents:
diff changeset
652 assert(n != NULL,"Bad immediate dominator info.");
a61af66fc99e Initial load
duke
parents:
diff changeset
653 }
a61af66fc99e Initial load
duke
parents:
diff changeset
654 return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
655 }
a61af66fc99e Initial load
duke
parents:
diff changeset
656 Node *idom(Node* d) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
657 uint didx = d->_idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
658 Node *n = idom_no_update(d);
a61af66fc99e Initial load
duke
parents:
diff changeset
659 _idom[didx] = n; // Lazily remove dead CFG nodes from table.
a61af66fc99e Initial load
duke
parents:
diff changeset
660 return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
661 }
a61af66fc99e Initial load
duke
parents:
diff changeset
662 uint dom_depth(Node* d) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
663 assert(d->_idx < _idom_size, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
664 return _dom_depth[d->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
665 }
a61af66fc99e Initial load
duke
parents:
diff changeset
666 void set_idom(Node* d, Node* n, uint dom_depth);
a61af66fc99e Initial load
duke
parents:
diff changeset
667 // Locally compute IDOM using dom_lca call
a61af66fc99e Initial load
duke
parents:
diff changeset
668 Node *compute_idom( Node *region ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
669 // Recompute dom_depth
a61af66fc99e Initial load
duke
parents:
diff changeset
670 void recompute_dom_depth();
a61af66fc99e Initial load
duke
parents:
diff changeset
671
a61af66fc99e Initial load
duke
parents:
diff changeset
672 // Is safept not required by an outer loop?
a61af66fc99e Initial load
duke
parents:
diff changeset
673 bool is_deleteable_safept(Node* sfpt);
a61af66fc99e Initial load
duke
parents:
diff changeset
674
921
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
675 // Perform verification that the graph is valid.
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
676 PhaseIdealLoop( PhaseIterGVN &igvn) :
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
677 PhaseTransform(Ideal_Loop),
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
678 _igvn(igvn),
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
679 _dom_lca_tags(C->comp_arena()),
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
680 _verify_me(NULL),
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
681 _verify_only(true) {
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
682 build_and_optimize(false);
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
683 }
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
684
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
685 // build the loop tree and perform any requested optimizations
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
686 void build_and_optimize(bool do_split_if);
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
687
0
a61af66fc99e Initial load
duke
parents:
diff changeset
688 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
689 // Dominators for the sea of nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
690 void Dominators();
a61af66fc99e Initial load
duke
parents:
diff changeset
691 Node *dom_lca( Node *n1, Node *n2 ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
692 return find_non_split_ctrl(dom_lca_internal(n1, n2));
a61af66fc99e Initial load
duke
parents:
diff changeset
693 }
a61af66fc99e Initial load
duke
parents:
diff changeset
694 Node *dom_lca_internal( Node *n1, Node *n2 ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
695
a61af66fc99e Initial load
duke
parents:
diff changeset
696 // Compute the Ideal Node to Loop mapping
921
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
697 PhaseIdealLoop( PhaseIterGVN &igvn, bool do_split_ifs) :
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
698 PhaseTransform(Ideal_Loop),
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
699 _igvn(igvn),
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
700 _dom_lca_tags(C->comp_arena()),
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
701 _verify_me(NULL),
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
702 _verify_only(false) {
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
703 build_and_optimize(do_split_ifs);
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
704 }
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
705
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
706 // Verify that verify_me made the same decisions as a fresh run.
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
707 PhaseIdealLoop( PhaseIterGVN &igvn, const PhaseIdealLoop *verify_me) :
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
708 PhaseTransform(Ideal_Loop),
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
709 _igvn(igvn),
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
710 _dom_lca_tags(C->comp_arena()),
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
711 _verify_me(verify_me),
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
712 _verify_only(false) {
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
713 build_and_optimize(false);
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
714 }
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
715
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
716 // Build and verify the loop tree without modifying the graph. This
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
717 // is useful to verify that all inputs properly dominate their uses.
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
718 static void verify(PhaseIterGVN& igvn) {
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
719 #ifdef ASSERT
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
720 PhaseIdealLoop v(igvn);
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
721 #endif
046932b72aa2 6862956: PhaseIdealLoop should have a CFG verification mode
never
parents: 605
diff changeset
722 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
723
a61af66fc99e Initial load
duke
parents:
diff changeset
724 // True if the method has at least 1 irreducible loop
a61af66fc99e Initial load
duke
parents:
diff changeset
725 bool _has_irreducible_loops;
a61af66fc99e Initial load
duke
parents:
diff changeset
726
a61af66fc99e Initial load
duke
parents:
diff changeset
727 // Per-Node transform
a61af66fc99e Initial load
duke
parents:
diff changeset
728 virtual Node *transform( Node *a_node ) { return 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
729
a61af66fc99e Initial load
duke
parents:
diff changeset
730 Node *is_counted_loop( Node *x, IdealLoopTree *loop );
a61af66fc99e Initial load
duke
parents:
diff changeset
731
a61af66fc99e Initial load
duke
parents:
diff changeset
732 // Return a post-walked LoopNode
a61af66fc99e Initial load
duke
parents:
diff changeset
733 IdealLoopTree *get_loop( Node *n ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
734 // Dead nodes have no loop, so return the top level loop instead
a61af66fc99e Initial load
duke
parents:
diff changeset
735 if (!has_node(n)) return _ltree_root;
a61af66fc99e Initial load
duke
parents:
diff changeset
736 assert(!has_ctrl(n), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
737 return (IdealLoopTree*)_nodes[n->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
738 }
a61af66fc99e Initial load
duke
parents:
diff changeset
739
a61af66fc99e Initial load
duke
parents:
diff changeset
740 // Is 'n' a (nested) member of 'loop'?
a61af66fc99e Initial load
duke
parents:
diff changeset
741 int is_member( const IdealLoopTree *loop, Node *n ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
742 return loop->is_member(get_loop(n)); }
a61af66fc99e Initial load
duke
parents:
diff changeset
743
a61af66fc99e Initial load
duke
parents:
diff changeset
744 // This is the basic building block of the loop optimizations. It clones an
a61af66fc99e Initial load
duke
parents:
diff changeset
745 // entire loop body. It makes an old_new loop body mapping; with this
a61af66fc99e Initial load
duke
parents:
diff changeset
746 // mapping you can find the new-loop equivalent to an old-loop node. All
a61af66fc99e Initial load
duke
parents:
diff changeset
747 // new-loop nodes are exactly equal to their old-loop counterparts, all
a61af66fc99e Initial load
duke
parents:
diff changeset
748 // edges are the same. All exits from the old-loop now have a RegionNode
a61af66fc99e Initial load
duke
parents:
diff changeset
749 // that merges the equivalent new-loop path. This is true even for the
a61af66fc99e Initial load
duke
parents:
diff changeset
750 // normal "loop-exit" condition. All uses of loop-invariant old-loop values
a61af66fc99e Initial load
duke
parents:
diff changeset
751 // now come from (one or more) Phis that merge their new-loop equivalents.
a61af66fc99e Initial load
duke
parents:
diff changeset
752 // Parameter side_by_side_idom:
a61af66fc99e Initial load
duke
parents:
diff changeset
753 // When side_by_size_idom is NULL, the dominator tree is constructed for
a61af66fc99e Initial load
duke
parents:
diff changeset
754 // the clone loop to dominate the original. Used in construction of
a61af66fc99e Initial load
duke
parents:
diff changeset
755 // pre-main-post loop sequence.
a61af66fc99e Initial load
duke
parents:
diff changeset
756 // When nonnull, the clone and original are side-by-side, both are
a61af66fc99e Initial load
duke
parents:
diff changeset
757 // dominated by the passed in side_by_side_idom node. Used in
a61af66fc99e Initial load
duke
parents:
diff changeset
758 // construction of unswitched loops.
a61af66fc99e Initial load
duke
parents:
diff changeset
759 void clone_loop( IdealLoopTree *loop, Node_List &old_new, int dom_depth,
a61af66fc99e Initial load
duke
parents:
diff changeset
760 Node* side_by_side_idom = NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
761
a61af66fc99e Initial load
duke
parents:
diff changeset
762 // If we got the effect of peeling, either by actually peeling or by
a61af66fc99e Initial load
duke
parents:
diff changeset
763 // making a pre-loop which must execute at least once, we can remove
a61af66fc99e Initial load
duke
parents:
diff changeset
764 // all loop-invariant dominated tests in the main body.
a61af66fc99e Initial load
duke
parents:
diff changeset
765 void peeled_dom_test_elim( IdealLoopTree *loop, Node_List &old_new );
a61af66fc99e Initial load
duke
parents:
diff changeset
766
a61af66fc99e Initial load
duke
parents:
diff changeset
767 // Generate code to do a loop peel for the given loop (and body).
a61af66fc99e Initial load
duke
parents:
diff changeset
768 // old_new is a temp array.
a61af66fc99e Initial load
duke
parents:
diff changeset
769 void do_peeling( IdealLoopTree *loop, Node_List &old_new );
a61af66fc99e Initial load
duke
parents:
diff changeset
770
a61af66fc99e Initial load
duke
parents:
diff changeset
771 // Add pre and post loops around the given loop. These loops are used
a61af66fc99e Initial load
duke
parents:
diff changeset
772 // during RCE, unrolling and aligning loops.
a61af66fc99e Initial load
duke
parents:
diff changeset
773 void insert_pre_post_loops( IdealLoopTree *loop, Node_List &old_new, bool peel_only );
a61af66fc99e Initial load
duke
parents:
diff changeset
774 // If Node n lives in the back_ctrl block, we clone a private version of n
a61af66fc99e Initial load
duke
parents:
diff changeset
775 // in preheader_ctrl block and return that, otherwise return n.
a61af66fc99e Initial load
duke
parents:
diff changeset
776 Node *clone_up_backedge_goo( Node *back_ctrl, Node *preheader_ctrl, Node *n );
a61af66fc99e Initial load
duke
parents:
diff changeset
777
a61af66fc99e Initial load
duke
parents:
diff changeset
778 // Take steps to maximally unroll the loop. Peel any odd iterations, then
a61af66fc99e Initial load
duke
parents:
diff changeset
779 // unroll to do double iterations. The next round of major loop transforms
a61af66fc99e Initial load
duke
parents:
diff changeset
780 // will repeat till the doubled loop body does all remaining iterations in 1
a61af66fc99e Initial load
duke
parents:
diff changeset
781 // pass.
a61af66fc99e Initial load
duke
parents:
diff changeset
782 void do_maximally_unroll( IdealLoopTree *loop, Node_List &old_new );
a61af66fc99e Initial load
duke
parents:
diff changeset
783
a61af66fc99e Initial load
duke
parents:
diff changeset
784 // Unroll the loop body one step - make each trip do 2 iterations.
a61af66fc99e Initial load
duke
parents:
diff changeset
785 void do_unroll( IdealLoopTree *loop, Node_List &old_new, bool adjust_min_trip );
a61af66fc99e Initial load
duke
parents:
diff changeset
786
a61af66fc99e Initial load
duke
parents:
diff changeset
787 // Return true if exp is a constant times an induction var
a61af66fc99e Initial load
duke
parents:
diff changeset
788 bool is_scaled_iv(Node* exp, Node* iv, int* p_scale);
a61af66fc99e Initial load
duke
parents:
diff changeset
789
a61af66fc99e Initial load
duke
parents:
diff changeset
790 // Return true if exp is a scaled induction var plus (or minus) constant
a61af66fc99e Initial load
duke
parents:
diff changeset
791 bool is_scaled_iv_plus_offset(Node* exp, Node* iv, int* p_scale, Node** p_offset, int depth = 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
792
a61af66fc99e Initial load
duke
parents:
diff changeset
793 // Eliminate range-checks and other trip-counter vs loop-invariant tests.
a61af66fc99e Initial load
duke
parents:
diff changeset
794 void do_range_check( IdealLoopTree *loop, Node_List &old_new );
a61af66fc99e Initial load
duke
parents:
diff changeset
795
a61af66fc99e Initial load
duke
parents:
diff changeset
796 // Create a slow version of the loop by cloning the loop
a61af66fc99e Initial load
duke
parents:
diff changeset
797 // and inserting an if to select fast-slow versions.
a61af66fc99e Initial load
duke
parents:
diff changeset
798 ProjNode* create_slow_version_of_loop(IdealLoopTree *loop,
a61af66fc99e Initial load
duke
parents:
diff changeset
799 Node_List &old_new);
a61af66fc99e Initial load
duke
parents:
diff changeset
800
a61af66fc99e Initial load
duke
parents:
diff changeset
801 // Clone loop with an invariant test (that does not exit) and
a61af66fc99e Initial load
duke
parents:
diff changeset
802 // insert a clone of the test that selects which version to
a61af66fc99e Initial load
duke
parents:
diff changeset
803 // execute.
a61af66fc99e Initial load
duke
parents:
diff changeset
804 void do_unswitching (IdealLoopTree *loop, Node_List &old_new);
a61af66fc99e Initial load
duke
parents:
diff changeset
805
a61af66fc99e Initial load
duke
parents:
diff changeset
806 // Find candidate "if" for unswitching
a61af66fc99e Initial load
duke
parents:
diff changeset
807 IfNode* find_unswitching_candidate(const IdealLoopTree *loop) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
808
a61af66fc99e Initial load
duke
parents:
diff changeset
809 // Range Check Elimination uses this function!
a61af66fc99e Initial load
duke
parents:
diff changeset
810 // Constrain the main loop iterations so the affine function:
a61af66fc99e Initial load
duke
parents:
diff changeset
811 // scale_con * I + offset < limit
a61af66fc99e Initial load
duke
parents:
diff changeset
812 // always holds true. That is, either increase the number of iterations in
a61af66fc99e Initial load
duke
parents:
diff changeset
813 // the pre-loop or the post-loop until the condition holds true in the main
a61af66fc99e Initial load
duke
parents:
diff changeset
814 // loop. Scale_con, offset and limit are all loop invariant.
a61af66fc99e Initial load
duke
parents:
diff changeset
815 void add_constraint( int stride_con, int scale_con, Node *offset, Node *limit, Node *pre_ctrl, Node **pre_limit, Node **main_limit );
a61af66fc99e Initial load
duke
parents:
diff changeset
816
a61af66fc99e Initial load
duke
parents:
diff changeset
817 // Partially peel loop up through last_peel node.
a61af66fc99e Initial load
duke
parents:
diff changeset
818 bool partial_peel( IdealLoopTree *loop, Node_List &old_new );
a61af66fc99e Initial load
duke
parents:
diff changeset
819
a61af66fc99e Initial load
duke
parents:
diff changeset
820 // Create a scheduled list of nodes control dependent on ctrl set.
a61af66fc99e Initial load
duke
parents:
diff changeset
821 void scheduled_nodelist( IdealLoopTree *loop, VectorSet& ctrl, Node_List &sched );
a61af66fc99e Initial load
duke
parents:
diff changeset
822 // Has a use in the vector set
a61af66fc99e Initial load
duke
parents:
diff changeset
823 bool has_use_in_set( Node* n, VectorSet& vset );
a61af66fc99e Initial load
duke
parents:
diff changeset
824 // Has use internal to the vector set (ie. not in a phi at the loop head)
a61af66fc99e Initial load
duke
parents:
diff changeset
825 bool has_use_internal_to_set( Node* n, VectorSet& vset, IdealLoopTree *loop );
a61af66fc99e Initial load
duke
parents:
diff changeset
826 // clone "n" for uses that are outside of loop
a61af66fc99e Initial load
duke
parents:
diff changeset
827 void clone_for_use_outside_loop( IdealLoopTree *loop, Node* n, Node_List& worklist );
a61af66fc99e Initial load
duke
parents:
diff changeset
828 // clone "n" for special uses that are in the not_peeled region
a61af66fc99e Initial load
duke
parents:
diff changeset
829 void clone_for_special_use_inside_loop( IdealLoopTree *loop, Node* n,
a61af66fc99e Initial load
duke
parents:
diff changeset
830 VectorSet& not_peel, Node_List& sink_list, Node_List& worklist );
a61af66fc99e Initial load
duke
parents:
diff changeset
831 // Insert phi(lp_entry_val, back_edge_val) at use->in(idx) for loop lp if phi does not already exist
a61af66fc99e Initial load
duke
parents:
diff changeset
832 void insert_phi_for_loop( Node* use, uint idx, Node* lp_entry_val, Node* back_edge_val, LoopNode* lp );
a61af66fc99e Initial load
duke
parents:
diff changeset
833 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
834 // Validate the loop partition sets: peel and not_peel
a61af66fc99e Initial load
duke
parents:
diff changeset
835 bool is_valid_loop_partition( IdealLoopTree *loop, VectorSet& peel, Node_List& peel_list, VectorSet& not_peel );
a61af66fc99e Initial load
duke
parents:
diff changeset
836 // Ensure that uses outside of loop are of the right form
a61af66fc99e Initial load
duke
parents:
diff changeset
837 bool is_valid_clone_loop_form( IdealLoopTree *loop, Node_List& peel_list,
a61af66fc99e Initial load
duke
parents:
diff changeset
838 uint orig_exit_idx, uint clone_exit_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
839 bool is_valid_clone_loop_exit_use( IdealLoopTree *loop, Node* use, uint exit_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
840 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
841
a61af66fc99e Initial load
duke
parents:
diff changeset
842 // Returns nonzero constant stride if-node is a possible iv test (otherwise returns zero.)
a61af66fc99e Initial load
duke
parents:
diff changeset
843 int stride_of_possible_iv( Node* iff );
a61af66fc99e Initial load
duke
parents:
diff changeset
844 bool is_possible_iv_test( Node* iff ) { return stride_of_possible_iv(iff) != 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
845 // Return the (unique) control output node that's in the loop (if it exists.)
a61af66fc99e Initial load
duke
parents:
diff changeset
846 Node* stay_in_loop( Node* n, IdealLoopTree *loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
847 // Insert a signed compare loop exit cloned from an unsigned compare.
a61af66fc99e Initial load
duke
parents:
diff changeset
848 IfNode* insert_cmpi_loop_exit(IfNode* if_cmpu, IdealLoopTree *loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
849 void remove_cmpi_loop_exit(IfNode* if_cmp, IdealLoopTree *loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
850 // Utility to register node "n" with PhaseIdealLoop
a61af66fc99e Initial load
duke
parents:
diff changeset
851 void register_node(Node* n, IdealLoopTree *loop, Node* pred, int ddepth);
a61af66fc99e Initial load
duke
parents:
diff changeset
852 // Utility to create an if-projection
a61af66fc99e Initial load
duke
parents:
diff changeset
853 ProjNode* proj_clone(ProjNode* p, IfNode* iff);
a61af66fc99e Initial load
duke
parents:
diff changeset
854 // Force the iff control output to be the live_proj
a61af66fc99e Initial load
duke
parents:
diff changeset
855 Node* short_circuit_if(IfNode* iff, ProjNode* live_proj);
a61af66fc99e Initial load
duke
parents:
diff changeset
856 // Insert a region before an if projection
a61af66fc99e Initial load
duke
parents:
diff changeset
857 RegionNode* insert_region_before_proj(ProjNode* proj);
a61af66fc99e Initial load
duke
parents:
diff changeset
858 // Insert a new if before an if projection
a61af66fc99e Initial load
duke
parents:
diff changeset
859 ProjNode* insert_if_before_proj(Node* left, bool Signed, BoolTest::mask relop, Node* right, ProjNode* proj);
a61af66fc99e Initial load
duke
parents:
diff changeset
860
a61af66fc99e Initial load
duke
parents:
diff changeset
861 // Passed in a Phi merging (recursively) some nearly equivalent Bool/Cmps.
a61af66fc99e Initial load
duke
parents:
diff changeset
862 // "Nearly" because all Nodes have been cloned from the original in the loop,
a61af66fc99e Initial load
duke
parents:
diff changeset
863 // but the fall-in edges to the Cmp are different. Clone bool/Cmp pairs
a61af66fc99e Initial load
duke
parents:
diff changeset
864 // through the Phi recursively, and return a Bool.
a61af66fc99e Initial load
duke
parents:
diff changeset
865 BoolNode *clone_iff( PhiNode *phi, IdealLoopTree *loop );
a61af66fc99e Initial load
duke
parents:
diff changeset
866 CmpNode *clone_bool( PhiNode *phi, IdealLoopTree *loop );
a61af66fc99e Initial load
duke
parents:
diff changeset
867
a61af66fc99e Initial load
duke
parents:
diff changeset
868
a61af66fc99e Initial load
duke
parents:
diff changeset
869 // Rework addressing expressions to get the most loop-invariant stuff
a61af66fc99e Initial load
duke
parents:
diff changeset
870 // moved out. We'd like to do all associative operators, but it's especially
a61af66fc99e Initial load
duke
parents:
diff changeset
871 // important (common) to do address expressions.
a61af66fc99e Initial load
duke
parents:
diff changeset
872 Node *remix_address_expressions( Node *n );
a61af66fc99e Initial load
duke
parents:
diff changeset
873
a61af66fc99e Initial load
duke
parents:
diff changeset
874 // Attempt to use a conditional move instead of a phi/branch
a61af66fc99e Initial load
duke
parents:
diff changeset
875 Node *conditional_move( Node *n );
a61af66fc99e Initial load
duke
parents:
diff changeset
876
a61af66fc99e Initial load
duke
parents:
diff changeset
877 // Reorganize offset computations to lower register pressure.
a61af66fc99e Initial load
duke
parents:
diff changeset
878 // Mostly prevent loop-fallout uses of the pre-incremented trip counter
a61af66fc99e Initial load
duke
parents:
diff changeset
879 // (which are then alive with the post-incremented trip counter
a61af66fc99e Initial load
duke
parents:
diff changeset
880 // forcing an extra register move)
a61af66fc99e Initial load
duke
parents:
diff changeset
881 void reorg_offsets( IdealLoopTree *loop );
a61af66fc99e Initial load
duke
parents:
diff changeset
882
a61af66fc99e Initial load
duke
parents:
diff changeset
883 // Check for aggressive application of 'split-if' optimization,
a61af66fc99e Initial load
duke
parents:
diff changeset
884 // using basic block level info.
a61af66fc99e Initial load
duke
parents:
diff changeset
885 void split_if_with_blocks ( VectorSet &visited, Node_Stack &nstack );
a61af66fc99e Initial load
duke
parents:
diff changeset
886 Node *split_if_with_blocks_pre ( Node *n );
a61af66fc99e Initial load
duke
parents:
diff changeset
887 void split_if_with_blocks_post( Node *n );
a61af66fc99e Initial load
duke
parents:
diff changeset
888 Node *has_local_phi_input( Node *n );
a61af66fc99e Initial load
duke
parents:
diff changeset
889 // Mark an IfNode as being dominated by a prior test,
a61af66fc99e Initial load
duke
parents:
diff changeset
890 // without actually altering the CFG (and hence IDOM info).
a61af66fc99e Initial load
duke
parents:
diff changeset
891 void dominated_by( Node *prevdom, Node *iff );
a61af66fc99e Initial load
duke
parents:
diff changeset
892
a61af66fc99e Initial load
duke
parents:
diff changeset
893 // Split Node 'n' through merge point
a61af66fc99e Initial load
duke
parents:
diff changeset
894 Node *split_thru_region( Node *n, Node *region );
a61af66fc99e Initial load
duke
parents:
diff changeset
895 // Split Node 'n' through merge point if there is enough win.
a61af66fc99e Initial load
duke
parents:
diff changeset
896 Node *split_thru_phi( Node *n, Node *region, int policy );
a61af66fc99e Initial load
duke
parents:
diff changeset
897 // Found an If getting its condition-code input from a Phi in the
a61af66fc99e Initial load
duke
parents:
diff changeset
898 // same block. Split thru the Region.
a61af66fc99e Initial load
duke
parents:
diff changeset
899 void do_split_if( Node *iff );
a61af66fc99e Initial load
duke
parents:
diff changeset
900
a61af66fc99e Initial load
duke
parents:
diff changeset
901 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
902 // Return a type based on condition control flow
a61af66fc99e Initial load
duke
parents:
diff changeset
903 const TypeInt* filtered_type( Node *n, Node* n_ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
904 const TypeInt* filtered_type( Node *n ) { return filtered_type(n, NULL); }
a61af66fc99e Initial load
duke
parents:
diff changeset
905 // Helpers for filtered type
a61af66fc99e Initial load
duke
parents:
diff changeset
906 const TypeInt* filtered_type_from_dominators( Node* val, Node *val_ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
907
a61af66fc99e Initial load
duke
parents:
diff changeset
908 // Helper functions
a61af66fc99e Initial load
duke
parents:
diff changeset
909 void register_new_node( Node *n, Node *blk );
a61af66fc99e Initial load
duke
parents:
diff changeset
910 Node *spinup( Node *iff, Node *new_false, Node *new_true, Node *region, Node *phi, small_cache *cache );
a61af66fc99e Initial load
duke
parents:
diff changeset
911 Node *find_use_block( Node *use, Node *def, Node *old_false, Node *new_false, Node *old_true, Node *new_true );
a61af66fc99e Initial load
duke
parents:
diff changeset
912 void handle_use( Node *use, Node *def, small_cache *cache, Node *region_dom, Node *new_false, Node *new_true, Node *old_false, Node *old_true );
a61af66fc99e Initial load
duke
parents:
diff changeset
913 bool split_up( Node *n, Node *blk1, Node *blk2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
914 void sink_use( Node *use, Node *post_loop );
a61af66fc99e Initial load
duke
parents:
diff changeset
915 Node *place_near_use( Node *useblock ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
916
a61af66fc99e Initial load
duke
parents:
diff changeset
917 bool _created_loop_node;
a61af66fc99e Initial load
duke
parents:
diff changeset
918 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
919 void set_created_loop_node() { _created_loop_node = true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
920 bool created_loop_node() { return _created_loop_node; }
a61af66fc99e Initial load
duke
parents:
diff changeset
921
a61af66fc99e Initial load
duke
parents:
diff changeset
922 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
923 void dump( ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
924 void dump( IdealLoopTree *loop, uint rpo_idx, Node_List &rpo_list ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
925 void rpo( Node *start, Node_Stack &stk, VectorSet &visited, Node_List &rpo_list ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
926 void verify() const; // Major slow :-)
a61af66fc99e Initial load
duke
parents:
diff changeset
927 void verify_compare( Node *n, const PhaseIdealLoop *loop_verify, VectorSet &visited ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
928 IdealLoopTree *get_loop_idx(Node* n) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
929 // Dead nodes have no loop, so return the top level loop instead
a61af66fc99e Initial load
duke
parents:
diff changeset
930 return _nodes[n->_idx] ? (IdealLoopTree*)_nodes[n->_idx] : _ltree_root;
a61af66fc99e Initial load
duke
parents:
diff changeset
931 }
a61af66fc99e Initial load
duke
parents:
diff changeset
932 // Print some stats
a61af66fc99e Initial load
duke
parents:
diff changeset
933 static void print_statistics();
a61af66fc99e Initial load
duke
parents:
diff changeset
934 static int _loop_invokes; // Count of PhaseIdealLoop invokes
a61af66fc99e Initial load
duke
parents:
diff changeset
935 static int _loop_work; // Sum of PhaseIdealLoop x _unique
a61af66fc99e Initial load
duke
parents:
diff changeset
936 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
937 };
a61af66fc99e Initial load
duke
parents:
diff changeset
938
a61af66fc99e Initial load
duke
parents:
diff changeset
939 inline Node* IdealLoopTree::tail() {
a61af66fc99e Initial load
duke
parents:
diff changeset
940 // Handle lazy update of _tail field
a61af66fc99e Initial load
duke
parents:
diff changeset
941 Node *n = _tail;
a61af66fc99e Initial load
duke
parents:
diff changeset
942 //while( !n->in(0) ) // Skip dead CFG nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
943 //n = n->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
944 if (n->in(0) == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
945 n = _phase->get_ctrl(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
946 _tail = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
947 return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
948 }
a61af66fc99e Initial load
duke
parents:
diff changeset
949
a61af66fc99e Initial load
duke
parents:
diff changeset
950
a61af66fc99e Initial load
duke
parents:
diff changeset
951 // Iterate over the loop tree using a preorder, left-to-right traversal.
a61af66fc99e Initial load
duke
parents:
diff changeset
952 //
a61af66fc99e Initial load
duke
parents:
diff changeset
953 // Example that visits all counted loops from within PhaseIdealLoop
a61af66fc99e Initial load
duke
parents:
diff changeset
954 //
a61af66fc99e Initial load
duke
parents:
diff changeset
955 // for (LoopTreeIterator iter(_ltree_root); !iter.done(); iter.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
956 // IdealLoopTree* lpt = iter.current();
a61af66fc99e Initial load
duke
parents:
diff changeset
957 // if (!lpt->is_counted()) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
958 // ...
a61af66fc99e Initial load
duke
parents:
diff changeset
959 class LoopTreeIterator : public StackObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
960 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
961 IdealLoopTree* _root;
a61af66fc99e Initial load
duke
parents:
diff changeset
962 IdealLoopTree* _curnt;
a61af66fc99e Initial load
duke
parents:
diff changeset
963
a61af66fc99e Initial load
duke
parents:
diff changeset
964 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
965 LoopTreeIterator(IdealLoopTree* root) : _root(root), _curnt(root) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
966
a61af66fc99e Initial load
duke
parents:
diff changeset
967 bool done() { return _curnt == NULL; } // Finished iterating?
a61af66fc99e Initial load
duke
parents:
diff changeset
968
a61af66fc99e Initial load
duke
parents:
diff changeset
969 void next(); // Advance to next loop tree
a61af66fc99e Initial load
duke
parents:
diff changeset
970
a61af66fc99e Initial load
duke
parents:
diff changeset
971 IdealLoopTree* current() { return _curnt; } // Return current value of iterator.
a61af66fc99e Initial load
duke
parents:
diff changeset
972 };