annotate src/share/vm/opto/loopnode.hpp @ 1721:413ad0331a0c

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