annotate src/share/vm/opto/loopnode.hpp @ 6972:bd7a7ce2e264

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