annotate src/share/vm/opto/loopnode.hpp @ 1994:6cd6d394f280

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