annotate src/share/vm/opto/loopnode.hpp @ 14649:f6301b007a16

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