annotate src/share/vm/opto/loopopts.cpp @ 1721:413ad0331a0c

6977924: Changes for 6975078 produce build error with certain gcc versions Summary: The changes introduced for 6975078 assign badHeapOopVal to the _allocation field in the ResourceObj class. In 32 bit linux builds with certain versions of gcc this assignment will be flagged as an error while compiling allocation.cpp. In 32 bit builds the constant value badHeapOopVal (which is cast to an intptr_t) is negative. The _allocation field is typed as an unsigned intptr_t and gcc catches this as an error. Reviewed-by: jcoomes, ysr, phh
author johnc
date Wed, 18 Aug 2010 10:59:06 -0700
parents 6027dddc26c6
children f95d63e2154a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1254
diff changeset
2 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1254
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1254
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: 1254
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 #include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
26 #include "incls/_loopopts.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
29 //------------------------------split_thru_phi---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
30 // Split Node 'n' through merge point if there is enough win.
a61af66fc99e Initial load
duke
parents:
diff changeset
31 Node *PhaseIdealLoop::split_thru_phi( Node *n, Node *region, int policy ) {
69
8bb88f9877e5 6659207: access violation in CompilerThread0
never
parents: 64
diff changeset
32 if (n->Opcode() == Op_ConvI2L && n->bottom_type() != TypeLong::LONG) {
8bb88f9877e5 6659207: access violation in CompilerThread0
never
parents: 64
diff changeset
33 // ConvI2L may have type information on it which is unsafe to push up
8bb88f9877e5 6659207: access violation in CompilerThread0
never
parents: 64
diff changeset
34 // so disable this for now
8bb88f9877e5 6659207: access violation in CompilerThread0
never
parents: 64
diff changeset
35 return NULL;
8bb88f9877e5 6659207: access violation in CompilerThread0
never
parents: 64
diff changeset
36 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
37 int wins = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
38 assert( !n->is_CFG(), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
39 assert( region->is_Region(), "" );
64
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 35
diff changeset
40
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 35
diff changeset
41 const Type* type = n->bottom_type();
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 35
diff changeset
42 const TypeOopPtr *t_oop = _igvn.type(n)->isa_oopptr();
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 35
diff changeset
43 Node *phi;
223
1dd146f17531 6716441: error in meet with +DoEscapeAnalysis
kvn
parents: 216
diff changeset
44 if( t_oop != NULL && t_oop->is_known_instance_field() ) {
64
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 35
diff changeset
45 int iid = t_oop->instance_id();
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 35
diff changeset
46 int index = C->get_alias_index(t_oop);
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 35
diff changeset
47 int offset = t_oop->offset();
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 35
diff changeset
48 phi = new (C,region->req()) PhiNode(region, type, NULL, iid, index, offset);
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 35
diff changeset
49 } else {
1254
4ee1c645110e 6924097: assert((_type == Type::MEMORY) == (_adr_type != 0),"adr_type for memory phis only")
kvn
parents: 866
diff changeset
50 phi = PhiNode::make_blank(region, n);
64
b8f5ba577b02 6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents: 35
diff changeset
51 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
52 uint old_unique = C->unique();
a61af66fc99e Initial load
duke
parents:
diff changeset
53 for( uint i = 1; i < region->req(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
54 Node *x;
a61af66fc99e Initial load
duke
parents:
diff changeset
55 Node* the_clone = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
56 if( region->in(i) == C->top() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
57 x = C->top(); // Dead path? Use a dead data op
a61af66fc99e Initial load
duke
parents:
diff changeset
58 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
59 x = n->clone(); // Else clone up the data op
a61af66fc99e Initial load
duke
parents:
diff changeset
60 the_clone = x; // Remember for possible deletion.
a61af66fc99e Initial load
duke
parents:
diff changeset
61 // Alter data node to use pre-phi inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
62 if( n->in(0) == region )
a61af66fc99e Initial load
duke
parents:
diff changeset
63 x->set_req( 0, region->in(i) );
a61af66fc99e Initial load
duke
parents:
diff changeset
64 for( uint j = 1; j < n->req(); j++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
65 Node *in = n->in(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
66 if( in->is_Phi() && in->in(0) == region )
a61af66fc99e Initial load
duke
parents:
diff changeset
67 x->set_req( j, in->in(i) ); // Use pre-Phi input for the clone
a61af66fc99e Initial load
duke
parents:
diff changeset
68 }
a61af66fc99e Initial load
duke
parents:
diff changeset
69 }
a61af66fc99e Initial load
duke
parents:
diff changeset
70 // Check for a 'win' on some paths
a61af66fc99e Initial load
duke
parents:
diff changeset
71 const Type *t = x->Value(&_igvn);
a61af66fc99e Initial load
duke
parents:
diff changeset
72
a61af66fc99e Initial load
duke
parents:
diff changeset
73 bool singleton = t->singleton();
a61af66fc99e Initial load
duke
parents:
diff changeset
74
a61af66fc99e Initial load
duke
parents:
diff changeset
75 // A TOP singleton indicates that there are no possible values incoming
a61af66fc99e Initial load
duke
parents:
diff changeset
76 // along a particular edge. In most cases, this is OK, and the Phi will
a61af66fc99e Initial load
duke
parents:
diff changeset
77 // be eliminated later in an Ideal call. However, we can't allow this to
a61af66fc99e Initial load
duke
parents:
diff changeset
78 // happen if the singleton occurs on loop entry, as the elimination of
a61af66fc99e Initial load
duke
parents:
diff changeset
79 // the PhiNode may cause the resulting node to migrate back to a previous
a61af66fc99e Initial load
duke
parents:
diff changeset
80 // loop iteration.
a61af66fc99e Initial load
duke
parents:
diff changeset
81 if( singleton && t == Type::TOP ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
82 // Is_Loop() == false does not confirm the absence of a loop (e.g., an
a61af66fc99e Initial load
duke
parents:
diff changeset
83 // irreducible loop may not be indicated by an affirmative is_Loop());
a61af66fc99e Initial load
duke
parents:
diff changeset
84 // therefore, the only top we can split thru a phi is on a backedge of
a61af66fc99e Initial load
duke
parents:
diff changeset
85 // a loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
86 singleton &= region->is_Loop() && (i != LoopNode::EntryControl);
a61af66fc99e Initial load
duke
parents:
diff changeset
87 }
a61af66fc99e Initial load
duke
parents:
diff changeset
88
a61af66fc99e Initial load
duke
parents:
diff changeset
89 if( singleton ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
90 wins++;
a61af66fc99e Initial load
duke
parents:
diff changeset
91 x = ((PhaseGVN&)_igvn).makecon(t);
a61af66fc99e Initial load
duke
parents:
diff changeset
92 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
93 // We now call Identity to try to simplify the cloned node.
a61af66fc99e Initial load
duke
parents:
diff changeset
94 // Note that some Identity methods call phase->type(this).
a61af66fc99e Initial load
duke
parents:
diff changeset
95 // Make sure that the type array is big enough for
a61af66fc99e Initial load
duke
parents:
diff changeset
96 // our new node, even though we may throw the node away.
a61af66fc99e Initial load
duke
parents:
diff changeset
97 // (Note: This tweaking with igvn only works because x is a new node.)
a61af66fc99e Initial load
duke
parents:
diff changeset
98 _igvn.set_type(x, t);
293
c3e045194476 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 253
diff changeset
99 // If x is a TypeNode, capture any more-precise type permanently into Node
605
98cb887364d3 6810672: Comment typos
twisti
parents: 401
diff changeset
100 // otherwise it will be not updated during igvn->transform since
293
c3e045194476 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 253
diff changeset
101 // igvn->type(x) is set to x->Value() already.
c3e045194476 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 253
diff changeset
102 x->raise_bottom_type(t);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
103 Node *y = x->Identity(&_igvn);
a61af66fc99e Initial load
duke
parents:
diff changeset
104 if( y != x ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
105 wins++;
a61af66fc99e Initial load
duke
parents:
diff changeset
106 x = y;
a61af66fc99e Initial load
duke
parents:
diff changeset
107 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
108 y = _igvn.hash_find(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
109 if( y ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
110 wins++;
a61af66fc99e Initial load
duke
parents:
diff changeset
111 x = y;
a61af66fc99e Initial load
duke
parents:
diff changeset
112 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
113 // Else x is a new node we are keeping
a61af66fc99e Initial load
duke
parents:
diff changeset
114 // We do not need register_new_node_with_optimizer
a61af66fc99e Initial load
duke
parents:
diff changeset
115 // because set_type has already been called.
a61af66fc99e Initial load
duke
parents:
diff changeset
116 _igvn._worklist.push(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
117 }
a61af66fc99e Initial load
duke
parents:
diff changeset
118 }
a61af66fc99e Initial load
duke
parents:
diff changeset
119 }
a61af66fc99e Initial load
duke
parents:
diff changeset
120 if (x != the_clone && the_clone != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
121 _igvn.remove_dead_node(the_clone);
a61af66fc99e Initial load
duke
parents:
diff changeset
122 phi->set_req( i, x );
a61af66fc99e Initial load
duke
parents:
diff changeset
123 }
a61af66fc99e Initial load
duke
parents:
diff changeset
124 // Too few wins?
a61af66fc99e Initial load
duke
parents:
diff changeset
125 if( wins <= policy ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
126 _igvn.remove_dead_node(phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
127 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
128 }
a61af66fc99e Initial load
duke
parents:
diff changeset
129
a61af66fc99e Initial load
duke
parents:
diff changeset
130 // Record Phi
a61af66fc99e Initial load
duke
parents:
diff changeset
131 register_new_node( phi, region );
a61af66fc99e Initial load
duke
parents:
diff changeset
132
a61af66fc99e Initial load
duke
parents:
diff changeset
133 for( uint i2 = 1; i2 < phi->req(); i2++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
134 Node *x = phi->in(i2);
a61af66fc99e Initial load
duke
parents:
diff changeset
135 // If we commoned up the cloned 'x' with another existing Node,
a61af66fc99e Initial load
duke
parents:
diff changeset
136 // the existing Node picks up a new use. We need to make the
a61af66fc99e Initial load
duke
parents:
diff changeset
137 // existing Node occur higher up so it dominates its uses.
a61af66fc99e Initial load
duke
parents:
diff changeset
138 Node *old_ctrl;
a61af66fc99e Initial load
duke
parents:
diff changeset
139 IdealLoopTree *old_loop;
a61af66fc99e Initial load
duke
parents:
diff changeset
140
a61af66fc99e Initial load
duke
parents:
diff changeset
141 // The occasional new node
a61af66fc99e Initial load
duke
parents:
diff changeset
142 if( x->_idx >= old_unique ) { // Found a new, unplaced node?
a61af66fc99e Initial load
duke
parents:
diff changeset
143 old_ctrl = x->is_Con() ? C->root() : NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
144 old_loop = NULL; // Not in any prior loop
a61af66fc99e Initial load
duke
parents:
diff changeset
145 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
146 old_ctrl = x->is_Con() ? C->root() : get_ctrl(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
147 old_loop = get_loop(old_ctrl); // Get prior loop
a61af66fc99e Initial load
duke
parents:
diff changeset
148 }
a61af66fc99e Initial load
duke
parents:
diff changeset
149 // New late point must dominate new use
a61af66fc99e Initial load
duke
parents:
diff changeset
150 Node *new_ctrl = dom_lca( old_ctrl, region->in(i2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
151 // Set new location
a61af66fc99e Initial load
duke
parents:
diff changeset
152 set_ctrl(x, new_ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
153 IdealLoopTree *new_loop = get_loop( new_ctrl );
a61af66fc99e Initial load
duke
parents:
diff changeset
154 // If changing loop bodies, see if we need to collect into new body
a61af66fc99e Initial load
duke
parents:
diff changeset
155 if( old_loop != new_loop ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
156 if( old_loop && !old_loop->_child )
a61af66fc99e Initial load
duke
parents:
diff changeset
157 old_loop->_body.yank(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
158 if( !new_loop->_child )
a61af66fc99e Initial load
duke
parents:
diff changeset
159 new_loop->_body.push(x); // Collect body info
a61af66fc99e Initial load
duke
parents:
diff changeset
160 }
a61af66fc99e Initial load
duke
parents:
diff changeset
161 }
a61af66fc99e Initial load
duke
parents:
diff changeset
162
a61af66fc99e Initial load
duke
parents:
diff changeset
163 return phi;
a61af66fc99e Initial load
duke
parents:
diff changeset
164 }
a61af66fc99e Initial load
duke
parents:
diff changeset
165
a61af66fc99e Initial load
duke
parents:
diff changeset
166 //------------------------------dominated_by------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
167 // Replace the dominated test with an obvious true or false. Place it on the
a61af66fc99e Initial load
duke
parents:
diff changeset
168 // IGVN worklist for later cleanup. Move control-dependent data Nodes on the
a61af66fc99e Initial load
duke
parents:
diff changeset
169 // live path up to the dominating control.
a61af66fc99e Initial load
duke
parents:
diff changeset
170 void PhaseIdealLoop::dominated_by( Node *prevdom, Node *iff ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
171 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
172 if( VerifyLoopOptimizations && PrintOpto ) tty->print_cr("dominating test");
a61af66fc99e Initial load
duke
parents:
diff changeset
173 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
174
a61af66fc99e Initial load
duke
parents:
diff changeset
175
a61af66fc99e Initial load
duke
parents:
diff changeset
176 // prevdom is the dominating projection of the dominating test.
a61af66fc99e Initial load
duke
parents:
diff changeset
177 assert( iff->is_If(), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
178 assert( iff->Opcode() == Op_If || iff->Opcode() == Op_CountedLoopEnd, "Check this code when new subtype is added");
a61af66fc99e Initial load
duke
parents:
diff changeset
179 int pop = prevdom->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
180 assert( pop == Op_IfFalse || pop == Op_IfTrue, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
181 // 'con' is set to true or false to kill the dominated test.
a61af66fc99e Initial load
duke
parents:
diff changeset
182 Node *con = _igvn.makecon(pop == Op_IfTrue ? TypeInt::ONE : TypeInt::ZERO);
a61af66fc99e Initial load
duke
parents:
diff changeset
183 set_ctrl(con, C->root()); // Constant gets a new use
a61af66fc99e Initial load
duke
parents:
diff changeset
184 // Hack the dominated test
a61af66fc99e Initial load
duke
parents:
diff changeset
185 _igvn.hash_delete(iff);
a61af66fc99e Initial load
duke
parents:
diff changeset
186 iff->set_req(1, con);
a61af66fc99e Initial load
duke
parents:
diff changeset
187 _igvn._worklist.push(iff);
a61af66fc99e Initial load
duke
parents:
diff changeset
188
a61af66fc99e Initial load
duke
parents:
diff changeset
189 // If I dont have a reachable TRUE and FALSE path following the IfNode then
a61af66fc99e Initial load
duke
parents:
diff changeset
190 // I can assume this path reaches an infinite loop. In this case it's not
a61af66fc99e Initial load
duke
parents:
diff changeset
191 // important to optimize the data Nodes - either the whole compilation will
a61af66fc99e Initial load
duke
parents:
diff changeset
192 // be tossed or this path (and all data Nodes) will go dead.
a61af66fc99e Initial load
duke
parents:
diff changeset
193 if( iff->outcnt() != 2 ) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
194
a61af66fc99e Initial load
duke
parents:
diff changeset
195 // Make control-dependent data Nodes on the live path (path that will remain
a61af66fc99e Initial load
duke
parents:
diff changeset
196 // once the dominated IF is removed) become control-dependent on the
a61af66fc99e Initial load
duke
parents:
diff changeset
197 // dominating projection.
a61af66fc99e Initial load
duke
parents:
diff changeset
198 Node* dp = ((IfNode*)iff)->proj_out(pop == Op_IfTrue);
a61af66fc99e Initial load
duke
parents:
diff changeset
199 IdealLoopTree *old_loop = get_loop(dp);
a61af66fc99e Initial load
duke
parents:
diff changeset
200
a61af66fc99e Initial load
duke
parents:
diff changeset
201 for (DUIterator_Fast imax, i = dp->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
202 Node* cd = dp->fast_out(i); // Control-dependent node
a61af66fc99e Initial load
duke
parents:
diff changeset
203 if( cd->depends_only_on_test() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
204 assert( cd->in(0) == dp, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
205 _igvn.hash_delete( cd );
a61af66fc99e Initial load
duke
parents:
diff changeset
206 cd->set_req(0, prevdom);
a61af66fc99e Initial load
duke
parents:
diff changeset
207 set_early_ctrl( cd );
a61af66fc99e Initial load
duke
parents:
diff changeset
208 _igvn._worklist.push(cd);
a61af66fc99e Initial load
duke
parents:
diff changeset
209 IdealLoopTree *new_loop = get_loop(get_ctrl(cd));
a61af66fc99e Initial load
duke
parents:
diff changeset
210 if( old_loop != new_loop ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
211 if( !old_loop->_child ) old_loop->_body.yank(cd);
a61af66fc99e Initial load
duke
parents:
diff changeset
212 if( !new_loop->_child ) new_loop->_body.push(cd);
a61af66fc99e Initial load
duke
parents:
diff changeset
213 }
a61af66fc99e Initial load
duke
parents:
diff changeset
214 --i;
a61af66fc99e Initial load
duke
parents:
diff changeset
215 --imax;
a61af66fc99e Initial load
duke
parents:
diff changeset
216 }
a61af66fc99e Initial load
duke
parents:
diff changeset
217 }
a61af66fc99e Initial load
duke
parents:
diff changeset
218 }
a61af66fc99e Initial load
duke
parents:
diff changeset
219
a61af66fc99e Initial load
duke
parents:
diff changeset
220 //------------------------------has_local_phi_input----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
221 // Return TRUE if 'n' has Phi inputs from its local block and no other
a61af66fc99e Initial load
duke
parents:
diff changeset
222 // block-local inputs (all non-local-phi inputs come from earlier blocks)
a61af66fc99e Initial load
duke
parents:
diff changeset
223 Node *PhaseIdealLoop::has_local_phi_input( Node *n ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
224 Node *n_ctrl = get_ctrl(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
225 // See if some inputs come from a Phi in this block, or from before
a61af66fc99e Initial load
duke
parents:
diff changeset
226 // this block.
a61af66fc99e Initial load
duke
parents:
diff changeset
227 uint i;
a61af66fc99e Initial load
duke
parents:
diff changeset
228 for( i = 1; i < n->req(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
229 Node *phi = n->in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
230 if( phi->is_Phi() && phi->in(0) == n_ctrl )
a61af66fc99e Initial load
duke
parents:
diff changeset
231 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
232 }
a61af66fc99e Initial load
duke
parents:
diff changeset
233 if( i >= n->req() )
a61af66fc99e Initial load
duke
parents:
diff changeset
234 return NULL; // No Phi inputs; nowhere to clone thru
a61af66fc99e Initial load
duke
parents:
diff changeset
235
a61af66fc99e Initial load
duke
parents:
diff changeset
236 // Check for inputs created between 'n' and the Phi input. These
a61af66fc99e Initial load
duke
parents:
diff changeset
237 // must split as well; they have already been given the chance
a61af66fc99e Initial load
duke
parents:
diff changeset
238 // (courtesy of a post-order visit) and since they did not we must
a61af66fc99e Initial load
duke
parents:
diff changeset
239 // recover the 'cost' of splitting them by being very profitable
a61af66fc99e Initial load
duke
parents:
diff changeset
240 // when splitting 'n'. Since this is unlikely we simply give up.
a61af66fc99e Initial load
duke
parents:
diff changeset
241 for( i = 1; i < n->req(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
242 Node *m = n->in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
243 if( get_ctrl(m) == n_ctrl && !m->is_Phi() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
244 // We allow the special case of AddP's with no local inputs.
a61af66fc99e Initial load
duke
parents:
diff changeset
245 // This allows us to split-up address expressions.
a61af66fc99e Initial load
duke
parents:
diff changeset
246 if (m->is_AddP() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
247 get_ctrl(m->in(2)) != n_ctrl &&
a61af66fc99e Initial load
duke
parents:
diff changeset
248 get_ctrl(m->in(3)) != n_ctrl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
249 // Move the AddP up to dominating point
a61af66fc99e Initial load
duke
parents:
diff changeset
250 set_ctrl_and_loop(m, find_non_split_ctrl(idom(n_ctrl)));
a61af66fc99e Initial load
duke
parents:
diff changeset
251 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
252 }
a61af66fc99e Initial load
duke
parents:
diff changeset
253 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
254 }
a61af66fc99e Initial load
duke
parents:
diff changeset
255 }
a61af66fc99e Initial load
duke
parents:
diff changeset
256
a61af66fc99e Initial load
duke
parents:
diff changeset
257 return n_ctrl;
a61af66fc99e Initial load
duke
parents:
diff changeset
258 }
a61af66fc99e Initial load
duke
parents:
diff changeset
259
a61af66fc99e Initial load
duke
parents:
diff changeset
260 //------------------------------remix_address_expressions----------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
261 // Rework addressing expressions to get the most loop-invariant stuff
a61af66fc99e Initial load
duke
parents:
diff changeset
262 // moved out. We'd like to do all associative operators, but it's especially
a61af66fc99e Initial load
duke
parents:
diff changeset
263 // important (common) to do address expressions.
a61af66fc99e Initial load
duke
parents:
diff changeset
264 Node *PhaseIdealLoop::remix_address_expressions( Node *n ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
265 if (!has_ctrl(n)) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
266 Node *n_ctrl = get_ctrl(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
267 IdealLoopTree *n_loop = get_loop(n_ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
268
a61af66fc99e Initial load
duke
parents:
diff changeset
269 // See if 'n' mixes loop-varying and loop-invariant inputs and
a61af66fc99e Initial load
duke
parents:
diff changeset
270 // itself is loop-varying.
a61af66fc99e Initial load
duke
parents:
diff changeset
271
a61af66fc99e Initial load
duke
parents:
diff changeset
272 // Only interested in binary ops (and AddP)
a61af66fc99e Initial load
duke
parents:
diff changeset
273 if( n->req() < 3 || n->req() > 4 ) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
274
a61af66fc99e Initial load
duke
parents:
diff changeset
275 Node *n1_ctrl = get_ctrl(n->in( 1));
a61af66fc99e Initial load
duke
parents:
diff changeset
276 Node *n2_ctrl = get_ctrl(n->in( 2));
a61af66fc99e Initial load
duke
parents:
diff changeset
277 Node *n3_ctrl = get_ctrl(n->in(n->req() == 3 ? 2 : 3));
a61af66fc99e Initial load
duke
parents:
diff changeset
278 IdealLoopTree *n1_loop = get_loop( n1_ctrl );
a61af66fc99e Initial load
duke
parents:
diff changeset
279 IdealLoopTree *n2_loop = get_loop( n2_ctrl );
a61af66fc99e Initial load
duke
parents:
diff changeset
280 IdealLoopTree *n3_loop = get_loop( n3_ctrl );
a61af66fc99e Initial load
duke
parents:
diff changeset
281
a61af66fc99e Initial load
duke
parents:
diff changeset
282 // Does one of my inputs spin in a tighter loop than self?
a61af66fc99e Initial load
duke
parents:
diff changeset
283 if( (n_loop->is_member( n1_loop ) && n_loop != n1_loop) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
284 (n_loop->is_member( n2_loop ) && n_loop != n2_loop) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
285 (n_loop->is_member( n3_loop ) && n_loop != n3_loop) )
a61af66fc99e Initial load
duke
parents:
diff changeset
286 return NULL; // Leave well enough alone
a61af66fc99e Initial load
duke
parents:
diff changeset
287
a61af66fc99e Initial load
duke
parents:
diff changeset
288 // Is at least one of my inputs loop-invariant?
a61af66fc99e Initial load
duke
parents:
diff changeset
289 if( n1_loop == n_loop &&
a61af66fc99e Initial load
duke
parents:
diff changeset
290 n2_loop == n_loop &&
a61af66fc99e Initial load
duke
parents:
diff changeset
291 n3_loop == n_loop )
a61af66fc99e Initial load
duke
parents:
diff changeset
292 return NULL; // No loop-invariant inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
293
a61af66fc99e Initial load
duke
parents:
diff changeset
294
a61af66fc99e Initial load
duke
parents:
diff changeset
295 int n_op = n->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
296
a61af66fc99e Initial load
duke
parents:
diff changeset
297 // Replace expressions like ((V+I) << 2) with (V<<2 + I<<2).
a61af66fc99e Initial load
duke
parents:
diff changeset
298 if( n_op == Op_LShiftI ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
299 // Scale is loop invariant
a61af66fc99e Initial load
duke
parents:
diff changeset
300 Node *scale = n->in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
301 Node *scale_ctrl = get_ctrl(scale);
a61af66fc99e Initial load
duke
parents:
diff changeset
302 IdealLoopTree *scale_loop = get_loop(scale_ctrl );
a61af66fc99e Initial load
duke
parents:
diff changeset
303 if( n_loop == scale_loop || !scale_loop->is_member( n_loop ) )
a61af66fc99e Initial load
duke
parents:
diff changeset
304 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
305 const TypeInt *scale_t = scale->bottom_type()->isa_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
306 if( scale_t && scale_t->is_con() && scale_t->get_con() >= 16 )
a61af66fc99e Initial load
duke
parents:
diff changeset
307 return NULL; // Dont bother with byte/short masking
a61af66fc99e Initial load
duke
parents:
diff changeset
308 // Add must vary with loop (else shift would be loop-invariant)
a61af66fc99e Initial load
duke
parents:
diff changeset
309 Node *add = n->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
310 Node *add_ctrl = get_ctrl(add);
a61af66fc99e Initial load
duke
parents:
diff changeset
311 IdealLoopTree *add_loop = get_loop(add_ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
312 //assert( n_loop == add_loop, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
313 if( n_loop != add_loop ) return NULL; // happens w/ evil ZKM loops
a61af66fc99e Initial load
duke
parents:
diff changeset
314
a61af66fc99e Initial load
duke
parents:
diff changeset
315 // Convert I-V into I+ (0-V); same for V-I
a61af66fc99e Initial load
duke
parents:
diff changeset
316 if( add->Opcode() == Op_SubI &&
a61af66fc99e Initial load
duke
parents:
diff changeset
317 _igvn.type( add->in(1) ) != TypeInt::ZERO ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
318 Node *zero = _igvn.intcon(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
319 set_ctrl(zero, C->root());
a61af66fc99e Initial load
duke
parents:
diff changeset
320 Node *neg = new (C, 3) SubINode( _igvn.intcon(0), add->in(2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
321 register_new_node( neg, get_ctrl(add->in(2) ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
322 add = new (C, 3) AddINode( add->in(1), neg );
a61af66fc99e Initial load
duke
parents:
diff changeset
323 register_new_node( add, add_ctrl );
a61af66fc99e Initial load
duke
parents:
diff changeset
324 }
a61af66fc99e Initial load
duke
parents:
diff changeset
325 if( add->Opcode() != Op_AddI ) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
326 // See if one add input is loop invariant
a61af66fc99e Initial load
duke
parents:
diff changeset
327 Node *add_var = add->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
328 Node *add_var_ctrl = get_ctrl(add_var);
a61af66fc99e Initial load
duke
parents:
diff changeset
329 IdealLoopTree *add_var_loop = get_loop(add_var_ctrl );
a61af66fc99e Initial load
duke
parents:
diff changeset
330 Node *add_invar = add->in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
331 Node *add_invar_ctrl = get_ctrl(add_invar);
a61af66fc99e Initial load
duke
parents:
diff changeset
332 IdealLoopTree *add_invar_loop = get_loop(add_invar_ctrl );
a61af66fc99e Initial load
duke
parents:
diff changeset
333 if( add_var_loop == n_loop ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
334 } else if( add_invar_loop == n_loop ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
335 // Swap to find the invariant part
a61af66fc99e Initial load
duke
parents:
diff changeset
336 add_invar = add_var;
a61af66fc99e Initial load
duke
parents:
diff changeset
337 add_invar_ctrl = add_var_ctrl;
a61af66fc99e Initial load
duke
parents:
diff changeset
338 add_invar_loop = add_var_loop;
a61af66fc99e Initial load
duke
parents:
diff changeset
339 add_var = add->in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
340 Node *add_var_ctrl = get_ctrl(add_var);
a61af66fc99e Initial load
duke
parents:
diff changeset
341 IdealLoopTree *add_var_loop = get_loop(add_var_ctrl );
a61af66fc99e Initial load
duke
parents:
diff changeset
342 } else // Else neither input is loop invariant
a61af66fc99e Initial load
duke
parents:
diff changeset
343 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
344 if( n_loop == add_invar_loop || !add_invar_loop->is_member( n_loop ) )
a61af66fc99e Initial load
duke
parents:
diff changeset
345 return NULL; // No invariant part of the add?
a61af66fc99e Initial load
duke
parents:
diff changeset
346
a61af66fc99e Initial load
duke
parents:
diff changeset
347 // Yes! Reshape address expression!
a61af66fc99e Initial load
duke
parents:
diff changeset
348 Node *inv_scale = new (C, 3) LShiftINode( add_invar, scale );
850
fd50a67f97d1 6860469: remix_address_expressions sets incorrect control causing crash in split_if_with_block_post
never
parents: 834
diff changeset
349 Node *inv_scale_ctrl =
fd50a67f97d1 6860469: remix_address_expressions sets incorrect control causing crash in split_if_with_block_post
never
parents: 834
diff changeset
350 dom_depth(add_invar_ctrl) > dom_depth(scale_ctrl) ?
fd50a67f97d1 6860469: remix_address_expressions sets incorrect control causing crash in split_if_with_block_post
never
parents: 834
diff changeset
351 add_invar_ctrl : scale_ctrl;
fd50a67f97d1 6860469: remix_address_expressions sets incorrect control causing crash in split_if_with_block_post
never
parents: 834
diff changeset
352 register_new_node( inv_scale, inv_scale_ctrl );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
353 Node *var_scale = new (C, 3) LShiftINode( add_var, scale );
a61af66fc99e Initial load
duke
parents:
diff changeset
354 register_new_node( var_scale, n_ctrl );
a61af66fc99e Initial load
duke
parents:
diff changeset
355 Node *var_add = new (C, 3) AddINode( var_scale, inv_scale );
a61af66fc99e Initial load
duke
parents:
diff changeset
356 register_new_node( var_add, n_ctrl );
1621
6027dddc26c6 6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents: 1552
diff changeset
357 _igvn.replace_node( n, var_add );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
358 return var_add;
a61af66fc99e Initial load
duke
parents:
diff changeset
359 }
a61af66fc99e Initial load
duke
parents:
diff changeset
360
a61af66fc99e Initial load
duke
parents:
diff changeset
361 // Replace (I+V) with (V+I)
a61af66fc99e Initial load
duke
parents:
diff changeset
362 if( n_op == Op_AddI ||
a61af66fc99e Initial load
duke
parents:
diff changeset
363 n_op == Op_AddL ||
a61af66fc99e Initial load
duke
parents:
diff changeset
364 n_op == Op_AddF ||
a61af66fc99e Initial load
duke
parents:
diff changeset
365 n_op == Op_AddD ||
a61af66fc99e Initial load
duke
parents:
diff changeset
366 n_op == Op_MulI ||
a61af66fc99e Initial load
duke
parents:
diff changeset
367 n_op == Op_MulL ||
a61af66fc99e Initial load
duke
parents:
diff changeset
368 n_op == Op_MulF ||
a61af66fc99e Initial load
duke
parents:
diff changeset
369 n_op == Op_MulD ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
370 if( n2_loop == n_loop ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
371 assert( n1_loop != n_loop, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
372 n->swap_edges(1, 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
373 }
a61af66fc99e Initial load
duke
parents:
diff changeset
374 }
a61af66fc99e Initial load
duke
parents:
diff changeset
375
a61af66fc99e Initial load
duke
parents:
diff changeset
376 // Replace ((I1 +p V) +p I2) with ((I1 +p I2) +p V),
a61af66fc99e Initial load
duke
parents:
diff changeset
377 // but not if I2 is a constant.
a61af66fc99e Initial load
duke
parents:
diff changeset
378 if( n_op == Op_AddP ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
379 if( n2_loop == n_loop && n3_loop != n_loop ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
380 if( n->in(2)->Opcode() == Op_AddP && !n->in(3)->is_Con() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
381 Node *n22_ctrl = get_ctrl(n->in(2)->in(2));
a61af66fc99e Initial load
duke
parents:
diff changeset
382 Node *n23_ctrl = get_ctrl(n->in(2)->in(3));
a61af66fc99e Initial load
duke
parents:
diff changeset
383 IdealLoopTree *n22loop = get_loop( n22_ctrl );
a61af66fc99e Initial load
duke
parents:
diff changeset
384 IdealLoopTree *n23_loop = get_loop( n23_ctrl );
a61af66fc99e Initial load
duke
parents:
diff changeset
385 if( n22loop != n_loop && n22loop->is_member(n_loop) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
386 n23_loop == n_loop ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
387 Node *add1 = new (C, 4) AddPNode( n->in(1), n->in(2)->in(2), n->in(3) );
a61af66fc99e Initial load
duke
parents:
diff changeset
388 // Stuff new AddP in the loop preheader
a61af66fc99e Initial load
duke
parents:
diff changeset
389 register_new_node( add1, n_loop->_head->in(LoopNode::EntryControl) );
a61af66fc99e Initial load
duke
parents:
diff changeset
390 Node *add2 = new (C, 4) AddPNode( n->in(1), add1, n->in(2)->in(3) );
a61af66fc99e Initial load
duke
parents:
diff changeset
391 register_new_node( add2, n_ctrl );
1621
6027dddc26c6 6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents: 1552
diff changeset
392 _igvn.replace_node( n, add2 );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
393 return add2;
a61af66fc99e Initial load
duke
parents:
diff changeset
394 }
a61af66fc99e Initial load
duke
parents:
diff changeset
395 }
a61af66fc99e Initial load
duke
parents:
diff changeset
396 }
a61af66fc99e Initial load
duke
parents:
diff changeset
397
a61af66fc99e Initial load
duke
parents:
diff changeset
398 // Replace (I1 +p (I2 + V)) with ((I1 +p I2) +p V)
a61af66fc99e Initial load
duke
parents:
diff changeset
399 if( n2_loop != n_loop && n3_loop == n_loop ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
400 if( n->in(3)->Opcode() == Op_AddI ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
401 Node *V = n->in(3)->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
402 Node *I = n->in(3)->in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
403 if( is_member(n_loop,get_ctrl(V)) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
404 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
405 Node *tmp = V; V = I; I = tmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
406 }
a61af66fc99e Initial load
duke
parents:
diff changeset
407 if( !is_member(n_loop,get_ctrl(I)) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
408 Node *add1 = new (C, 4) AddPNode( n->in(1), n->in(2), I );
a61af66fc99e Initial load
duke
parents:
diff changeset
409 // Stuff new AddP in the loop preheader
a61af66fc99e Initial load
duke
parents:
diff changeset
410 register_new_node( add1, n_loop->_head->in(LoopNode::EntryControl) );
a61af66fc99e Initial load
duke
parents:
diff changeset
411 Node *add2 = new (C, 4) AddPNode( n->in(1), add1, V );
a61af66fc99e Initial load
duke
parents:
diff changeset
412 register_new_node( add2, n_ctrl );
1621
6027dddc26c6 6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents: 1552
diff changeset
413 _igvn.replace_node( n, add2 );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
414 return add2;
a61af66fc99e Initial load
duke
parents:
diff changeset
415 }
a61af66fc99e Initial load
duke
parents:
diff changeset
416 }
a61af66fc99e Initial load
duke
parents:
diff changeset
417 }
a61af66fc99e Initial load
duke
parents:
diff changeset
418 }
a61af66fc99e Initial load
duke
parents:
diff changeset
419
a61af66fc99e Initial load
duke
parents:
diff changeset
420 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
421 }
a61af66fc99e Initial load
duke
parents:
diff changeset
422
a61af66fc99e Initial load
duke
parents:
diff changeset
423 //------------------------------conditional_move-------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
424 // Attempt to replace a Phi with a conditional move. We have some pretty
a61af66fc99e Initial load
duke
parents:
diff changeset
425 // strict profitability requirements. All Phis at the merge point must
a61af66fc99e Initial load
duke
parents:
diff changeset
426 // be converted, so we can remove the control flow. We need to limit the
a61af66fc99e Initial load
duke
parents:
diff changeset
427 // number of c-moves to a small handful. All code that was in the side-arms
a61af66fc99e Initial load
duke
parents:
diff changeset
428 // of the CFG diamond is now speculatively executed. This code has to be
a61af66fc99e Initial load
duke
parents:
diff changeset
429 // "cheap enough". We are pretty much limited to CFG diamonds that merge
a61af66fc99e Initial load
duke
parents:
diff changeset
430 // 1 or 2 items with a total of 1 or 2 ops executed speculatively.
a61af66fc99e Initial load
duke
parents:
diff changeset
431 Node *PhaseIdealLoop::conditional_move( Node *region ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
432
a61af66fc99e Initial load
duke
parents:
diff changeset
433 assert( region->is_Region(), "sanity check" );
a61af66fc99e Initial load
duke
parents:
diff changeset
434 if( region->req() != 3 ) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
435
a61af66fc99e Initial load
duke
parents:
diff changeset
436 // Check for CFG diamond
a61af66fc99e Initial load
duke
parents:
diff changeset
437 Node *lp = region->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
438 Node *rp = region->in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
439 if( !lp || !rp ) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
440 Node *lp_c = lp->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
441 if( lp_c == NULL || lp_c != rp->in(0) || !lp_c->is_If() ) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
442 IfNode *iff = lp_c->as_If();
a61af66fc99e Initial load
duke
parents:
diff changeset
443
a61af66fc99e Initial load
duke
parents:
diff changeset
444 // Check for highly predictable branch. No point in CMOV'ing if
a61af66fc99e Initial load
duke
parents:
diff changeset
445 // we are going to predict accurately all the time.
a61af66fc99e Initial load
duke
parents:
diff changeset
446 // %%% This hides patterns produced by utility methods like Math.min.
a61af66fc99e Initial load
duke
parents:
diff changeset
447 if( iff->_prob < PROB_UNLIKELY_MAG(3) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
448 iff->_prob > PROB_LIKELY_MAG(3) )
a61af66fc99e Initial load
duke
parents:
diff changeset
449 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
450
a61af66fc99e Initial load
duke
parents:
diff changeset
451 // Check for ops pinned in an arm of the diamond.
a61af66fc99e Initial load
duke
parents:
diff changeset
452 // Can't remove the control flow in this case
a61af66fc99e Initial load
duke
parents:
diff changeset
453 if( lp->outcnt() > 1 ) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
454 if( rp->outcnt() > 1 ) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
455
a61af66fc99e Initial load
duke
parents:
diff changeset
456 // Check profitability
a61af66fc99e Initial load
duke
parents:
diff changeset
457 int cost = 0;
35
e2ae28d2ce91 6667588: Don't generate duplicated CMP for float/double values
kvn
parents: 0
diff changeset
458 int phis = 0;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
459 for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
460 Node *out = region->fast_out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
461 if( !out->is_Phi() ) continue; // Ignore other control edges, etc
35
e2ae28d2ce91 6667588: Don't generate duplicated CMP for float/double values
kvn
parents: 0
diff changeset
462 phis++;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
463 PhiNode* phi = out->as_Phi();
a61af66fc99e Initial load
duke
parents:
diff changeset
464 switch (phi->type()->basic_type()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
465 case T_LONG:
a61af66fc99e Initial load
duke
parents:
diff changeset
466 cost++; // Probably encodes as 2 CMOV's
a61af66fc99e Initial load
duke
parents:
diff changeset
467 case T_INT: // These all CMOV fine
a61af66fc99e Initial load
duke
parents:
diff changeset
468 case T_FLOAT:
a61af66fc99e Initial load
duke
parents:
diff changeset
469 case T_DOUBLE:
a61af66fc99e Initial load
duke
parents:
diff changeset
470 case T_ADDRESS: // (RawPtr)
a61af66fc99e Initial load
duke
parents:
diff changeset
471 cost++;
a61af66fc99e Initial load
duke
parents:
diff changeset
472 break;
293
c3e045194476 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 253
diff changeset
473 case T_NARROWOOP: // Fall through
0
a61af66fc99e Initial load
duke
parents:
diff changeset
474 case T_OBJECT: { // Base oops are OK, but not derived oops
293
c3e045194476 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 253
diff changeset
475 const TypeOopPtr *tp = phi->type()->make_ptr()->isa_oopptr();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
476 // Derived pointers are Bad (tm): what's the Base (for GC purposes) of a
a61af66fc99e Initial load
duke
parents:
diff changeset
477 // CMOVE'd derived pointer? It's a CMOVE'd derived base. Thus
a61af66fc99e Initial load
duke
parents:
diff changeset
478 // CMOVE'ing a derived pointer requires we also CMOVE the base. If we
a61af66fc99e Initial load
duke
parents:
diff changeset
479 // have a Phi for the base here that we convert to a CMOVE all is well
a61af66fc99e Initial load
duke
parents:
diff changeset
480 // and good. But if the base is dead, we'll not make a CMOVE. Later
a61af66fc99e Initial load
duke
parents:
diff changeset
481 // the allocator will have to produce a base by creating a CMOVE of the
a61af66fc99e Initial load
duke
parents:
diff changeset
482 // relevant bases. This puts the allocator in the business of
a61af66fc99e Initial load
duke
parents:
diff changeset
483 // manufacturing expensive instructions, generally a bad plan.
a61af66fc99e Initial load
duke
parents:
diff changeset
484 // Just Say No to Conditionally-Moved Derived Pointers.
a61af66fc99e Initial load
duke
parents:
diff changeset
485 if( tp && tp->offset() != 0 )
a61af66fc99e Initial load
duke
parents:
diff changeset
486 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
487 cost++;
a61af66fc99e Initial load
duke
parents:
diff changeset
488 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
489 }
a61af66fc99e Initial load
duke
parents:
diff changeset
490 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
491 return NULL; // In particular, can't do memory or I/O
a61af66fc99e Initial load
duke
parents:
diff changeset
492 }
a61af66fc99e Initial load
duke
parents:
diff changeset
493 // Add in cost any speculative ops
a61af66fc99e Initial load
duke
parents:
diff changeset
494 for( uint j = 1; j < region->req(); j++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
495 Node *proj = region->in(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
496 Node *inp = phi->in(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
497 if (get_ctrl(inp) == proj) { // Found local op
a61af66fc99e Initial load
duke
parents:
diff changeset
498 cost++;
a61af66fc99e Initial load
duke
parents:
diff changeset
499 // Check for a chain of dependent ops; these will all become
a61af66fc99e Initial load
duke
parents:
diff changeset
500 // speculative in a CMOV.
a61af66fc99e Initial load
duke
parents:
diff changeset
501 for( uint k = 1; k < inp->req(); k++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
502 if (get_ctrl(inp->in(k)) == proj)
a61af66fc99e Initial load
duke
parents:
diff changeset
503 return NULL; // Too much speculative goo
a61af66fc99e Initial load
duke
parents:
diff changeset
504 }
a61af66fc99e Initial load
duke
parents:
diff changeset
505 }
293
c3e045194476 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 253
diff changeset
506 // See if the Phi is used by a Cmp or Narrow oop Decode/Encode.
c3e045194476 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 253
diff changeset
507 // This will likely Split-If, a higher-payoff operation.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
508 for (DUIterator_Fast kmax, k = phi->fast_outs(kmax); k < kmax; k++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
509 Node* use = phi->fast_out(k);
293
c3e045194476 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 253
diff changeset
510 if( use->is_Cmp() || use->is_DecodeN() || use->is_EncodeP() )
0
a61af66fc99e Initial load
duke
parents:
diff changeset
511 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
512 }
a61af66fc99e Initial load
duke
parents:
diff changeset
513 }
a61af66fc99e Initial load
duke
parents:
diff changeset
514 if( cost >= ConditionalMoveLimit ) return NULL; // Too much goo
35
e2ae28d2ce91 6667588: Don't generate duplicated CMP for float/double values
kvn
parents: 0
diff changeset
515 Node* bol = iff->in(1);
e2ae28d2ce91 6667588: Don't generate duplicated CMP for float/double values
kvn
parents: 0
diff changeset
516 assert( bol->Opcode() == Op_Bool, "" );
e2ae28d2ce91 6667588: Don't generate duplicated CMP for float/double values
kvn
parents: 0
diff changeset
517 int cmp_op = bol->in(1)->Opcode();
e2ae28d2ce91 6667588: Don't generate duplicated CMP for float/double values
kvn
parents: 0
diff changeset
518 // It is expensive to generate flags from a float compare.
e2ae28d2ce91 6667588: Don't generate duplicated CMP for float/double values
kvn
parents: 0
diff changeset
519 // Avoid duplicated float compare.
e2ae28d2ce91 6667588: Don't generate duplicated CMP for float/double values
kvn
parents: 0
diff changeset
520 if( phis > 1 && (cmp_op == Op_CmpF || cmp_op == Op_CmpD)) return NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
521
a61af66fc99e Initial load
duke
parents:
diff changeset
522 // --------------
a61af66fc99e Initial load
duke
parents:
diff changeset
523 // Now replace all Phis with CMOV's
a61af66fc99e Initial load
duke
parents:
diff changeset
524 Node *cmov_ctrl = iff->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
525 uint flip = (lp->Opcode() == Op_IfTrue);
a61af66fc99e Initial load
duke
parents:
diff changeset
526 while( 1 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
527 PhiNode* phi = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
528 for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
529 Node *out = region->fast_out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
530 if (out->is_Phi()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
531 phi = out->as_Phi();
a61af66fc99e Initial load
duke
parents:
diff changeset
532 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
533 }
a61af66fc99e Initial load
duke
parents:
diff changeset
534 }
a61af66fc99e Initial load
duke
parents:
diff changeset
535 if (phi == NULL) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
536 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
537 if( PrintOpto && VerifyLoopOptimizations ) tty->print_cr("CMOV");
a61af66fc99e Initial load
duke
parents:
diff changeset
538 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
539 // Move speculative ops
a61af66fc99e Initial load
duke
parents:
diff changeset
540 for( uint j = 1; j < region->req(); j++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
541 Node *proj = region->in(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
542 Node *inp = phi->in(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
543 if (get_ctrl(inp) == proj) { // Found local op
a61af66fc99e Initial load
duke
parents:
diff changeset
544 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
545 if( PrintOpto && VerifyLoopOptimizations ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
546 tty->print(" speculate: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
547 inp->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
548 }
a61af66fc99e Initial load
duke
parents:
diff changeset
549 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
550 set_ctrl(inp, cmov_ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
551 }
a61af66fc99e Initial load
duke
parents:
diff changeset
552 }
a61af66fc99e Initial load
duke
parents:
diff changeset
553 Node *cmov = CMoveNode::make( C, cmov_ctrl, iff->in(1), phi->in(1+flip), phi->in(2-flip), _igvn.type(phi) );
a61af66fc99e Initial load
duke
parents:
diff changeset
554 register_new_node( cmov, cmov_ctrl );
1621
6027dddc26c6 6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents: 1552
diff changeset
555 _igvn.replace_node( phi, cmov );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
556 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
557 if( VerifyLoopOptimizations ) verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
558 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
559 }
a61af66fc99e Initial load
duke
parents:
diff changeset
560
a61af66fc99e Initial load
duke
parents:
diff changeset
561 // The useless CFG diamond will fold up later; see the optimization in
a61af66fc99e Initial load
duke
parents:
diff changeset
562 // RegionNode::Ideal.
a61af66fc99e Initial load
duke
parents:
diff changeset
563 _igvn._worklist.push(region);
a61af66fc99e Initial load
duke
parents:
diff changeset
564
a61af66fc99e Initial load
duke
parents:
diff changeset
565 return iff->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
566 }
a61af66fc99e Initial load
duke
parents:
diff changeset
567
a61af66fc99e Initial load
duke
parents:
diff changeset
568 //------------------------------split_if_with_blocks_pre-----------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
569 // Do the real work in a non-recursive function. Data nodes want to be
a61af66fc99e Initial load
duke
parents:
diff changeset
570 // cloned in the pre-order so they can feed each other nicely.
a61af66fc99e Initial load
duke
parents:
diff changeset
571 Node *PhaseIdealLoop::split_if_with_blocks_pre( Node *n ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
572 // Cloning these guys is unlikely to win
a61af66fc99e Initial load
duke
parents:
diff changeset
573 int n_op = n->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
574 if( n_op == Op_MergeMem ) return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
575 if( n->is_Proj() ) return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
576 // Do not clone-up CmpFXXX variations, as these are always
a61af66fc99e Initial load
duke
parents:
diff changeset
577 // followed by a CmpI
a61af66fc99e Initial load
duke
parents:
diff changeset
578 if( n->is_Cmp() ) return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
579 // Attempt to use a conditional move instead of a phi/branch
a61af66fc99e Initial load
duke
parents:
diff changeset
580 if( ConditionalMoveLimit > 0 && n_op == Op_Region ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
581 Node *cmov = conditional_move( n );
a61af66fc99e Initial load
duke
parents:
diff changeset
582 if( cmov ) return cmov;
a61af66fc99e Initial load
duke
parents:
diff changeset
583 }
253
b0fe4deeb9fb 6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents: 251
diff changeset
584 if( n->is_CFG() || n->is_LoadStore() )
b0fe4deeb9fb 6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents: 251
diff changeset
585 return n;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
586 if( n_op == Op_Opaque1 || // Opaque nodes cannot be mod'd
a61af66fc99e Initial load
duke
parents:
diff changeset
587 n_op == Op_Opaque2 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
588 if( !C->major_progress() ) // If chance of no more loop opts...
a61af66fc99e Initial load
duke
parents:
diff changeset
589 _igvn._worklist.push(n); // maybe we'll remove them
a61af66fc99e Initial load
duke
parents:
diff changeset
590 return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
591 }
a61af66fc99e Initial load
duke
parents:
diff changeset
592
a61af66fc99e Initial load
duke
parents:
diff changeset
593 if( n->is_Con() ) return n; // No cloning for Con nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
594
a61af66fc99e Initial load
duke
parents:
diff changeset
595 Node *n_ctrl = get_ctrl(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
596 if( !n_ctrl ) return n; // Dead node
a61af66fc99e Initial load
duke
parents:
diff changeset
597
a61af66fc99e Initial load
duke
parents:
diff changeset
598 // Attempt to remix address expressions for loop invariants
a61af66fc99e Initial load
duke
parents:
diff changeset
599 Node *m = remix_address_expressions( n );
a61af66fc99e Initial load
duke
parents:
diff changeset
600 if( m ) return m;
a61af66fc99e Initial load
duke
parents:
diff changeset
601
a61af66fc99e Initial load
duke
parents:
diff changeset
602 // Determine if the Node has inputs from some local Phi.
a61af66fc99e Initial load
duke
parents:
diff changeset
603 // Returns the block to clone thru.
a61af66fc99e Initial load
duke
parents:
diff changeset
604 Node *n_blk = has_local_phi_input( n );
a61af66fc99e Initial load
duke
parents:
diff changeset
605 if( !n_blk ) return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
606 // Do not clone the trip counter through on a CountedLoop
a61af66fc99e Initial load
duke
parents:
diff changeset
607 // (messes up the canonical shape).
a61af66fc99e Initial load
duke
parents:
diff changeset
608 if( n_blk->is_CountedLoop() && n->Opcode() == Op_AddI ) return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
609
a61af66fc99e Initial load
duke
parents:
diff changeset
610 // Check for having no control input; not pinned. Allow
a61af66fc99e Initial load
duke
parents:
diff changeset
611 // dominating control.
a61af66fc99e Initial load
duke
parents:
diff changeset
612 if( n->in(0) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
613 Node *dom = idom(n_blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
614 if( dom_lca( n->in(0), dom ) != n->in(0) )
a61af66fc99e Initial load
duke
parents:
diff changeset
615 return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
616 }
a61af66fc99e Initial load
duke
parents:
diff changeset
617 // Policy: when is it profitable. You must get more wins than
a61af66fc99e Initial load
duke
parents:
diff changeset
618 // policy before it is considered profitable. Policy is usually 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
619 // so 1 win is considered profitable. Big merges will require big
a61af66fc99e Initial load
duke
parents:
diff changeset
620 // cloning, so get a larger policy.
a61af66fc99e Initial load
duke
parents:
diff changeset
621 int policy = n_blk->req() >> 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
622
a61af66fc99e Initial load
duke
parents:
diff changeset
623 // If the loop is a candidate for range check elimination,
a61af66fc99e Initial load
duke
parents:
diff changeset
624 // delay splitting through it's phi until a later loop optimization
a61af66fc99e Initial load
duke
parents:
diff changeset
625 if (n_blk->is_CountedLoop()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
626 IdealLoopTree *lp = get_loop(n_blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
627 if (lp && lp->_rce_candidate) {
a61af66fc99e Initial load
duke
parents:
diff changeset
628 return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
629 }
a61af66fc99e Initial load
duke
parents:
diff changeset
630 }
a61af66fc99e Initial load
duke
parents:
diff changeset
631
a61af66fc99e Initial load
duke
parents:
diff changeset
632 // Use same limit as split_if_with_blocks_post
a61af66fc99e Initial load
duke
parents:
diff changeset
633 if( C->unique() > 35000 ) return n; // Method too big
a61af66fc99e Initial load
duke
parents:
diff changeset
634
a61af66fc99e Initial load
duke
parents:
diff changeset
635 // Split 'n' through the merge point if it is profitable
a61af66fc99e Initial load
duke
parents:
diff changeset
636 Node *phi = split_thru_phi( n, n_blk, policy );
a61af66fc99e Initial load
duke
parents:
diff changeset
637 if( !phi ) return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
638
a61af66fc99e Initial load
duke
parents:
diff changeset
639 // Found a Phi to split thru!
a61af66fc99e Initial load
duke
parents:
diff changeset
640 // Replace 'n' with the new phi
1621
6027dddc26c6 6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents: 1552
diff changeset
641 _igvn.replace_node( n, phi );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
642 // Moved a load around the loop, 'en-registering' something.
a61af66fc99e Initial load
duke
parents:
diff changeset
643 if( n_blk->Opcode() == Op_Loop && n->is_Load() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
644 !phi->in(LoopNode::LoopBackControl)->is_Load() )
a61af66fc99e Initial load
duke
parents:
diff changeset
645 C->set_major_progress();
a61af66fc99e Initial load
duke
parents:
diff changeset
646
a61af66fc99e Initial load
duke
parents:
diff changeset
647 return phi;
a61af66fc99e Initial load
duke
parents:
diff changeset
648 }
a61af66fc99e Initial load
duke
parents:
diff changeset
649
a61af66fc99e Initial load
duke
parents:
diff changeset
650 static bool merge_point_too_heavy(Compile* C, Node* region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
651 // Bail out if the region and its phis have too many users.
a61af66fc99e Initial load
duke
parents:
diff changeset
652 int weight = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
653 for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
654 weight += region->fast_out(i)->outcnt();
a61af66fc99e Initial load
duke
parents:
diff changeset
655 }
a61af66fc99e Initial load
duke
parents:
diff changeset
656 int nodes_left = MaxNodeLimit - C->unique();
a61af66fc99e Initial load
duke
parents:
diff changeset
657 if (weight * 8 > nodes_left) {
a61af66fc99e Initial load
duke
parents:
diff changeset
658 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
659 if (PrintOpto)
a61af66fc99e Initial load
duke
parents:
diff changeset
660 tty->print_cr("*** Split-if bails out: %d nodes, region weight %d", C->unique(), weight);
a61af66fc99e Initial load
duke
parents:
diff changeset
661 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
662 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
663 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
664 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
665 }
a61af66fc99e Initial load
duke
parents:
diff changeset
666 }
a61af66fc99e Initial load
duke
parents:
diff changeset
667
a61af66fc99e Initial load
duke
parents:
diff changeset
668 static bool merge_point_safe(Node* region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
669 // 4799512: Stop split_if_with_blocks from splitting a block with a ConvI2LNode
a61af66fc99e Initial load
duke
parents:
diff changeset
670 // having a PhiNode input. This sidesteps the dangerous case where the split
a61af66fc99e Initial load
duke
parents:
diff changeset
671 // ConvI2LNode may become TOP if the input Value() does not
a61af66fc99e Initial load
duke
parents:
diff changeset
672 // overlap the ConvI2L range, leaving a node which may not dominate its
a61af66fc99e Initial load
duke
parents:
diff changeset
673 // uses.
a61af66fc99e Initial load
duke
parents:
diff changeset
674 // A better fix for this problem can be found in the BugTraq entry, but
a61af66fc99e Initial load
duke
parents:
diff changeset
675 // expediency for Mantis demands this hack.
834
0f2d888530e7 6855164: SIGSEGV during compilation of method involving loop over CharSequence.
cfang
parents: 605
diff changeset
676 // 6855164: If the merge point has a FastLockNode with a PhiNode input, we stop
0f2d888530e7 6855164: SIGSEGV during compilation of method involving loop over CharSequence.
cfang
parents: 605
diff changeset
677 // split_if_with_blocks from splitting a block because we could not move around
0f2d888530e7 6855164: SIGSEGV during compilation of method involving loop over CharSequence.
cfang
parents: 605
diff changeset
678 // the FastLockNode.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
679 for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
680 Node* n = region->fast_out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
681 if (n->is_Phi()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
682 for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
683 Node* m = n->fast_out(j);
834
0f2d888530e7 6855164: SIGSEGV during compilation of method involving loop over CharSequence.
cfang
parents: 605
diff changeset
684 if (m->is_FastLock())
0
a61af66fc99e Initial load
duke
parents:
diff changeset
685 return false;
834
0f2d888530e7 6855164: SIGSEGV during compilation of method involving loop over CharSequence.
cfang
parents: 605
diff changeset
686 #ifdef _LP64
0f2d888530e7 6855164: SIGSEGV during compilation of method involving loop over CharSequence.
cfang
parents: 605
diff changeset
687 if (m->Opcode() == Op_ConvI2L)
0f2d888530e7 6855164: SIGSEGV during compilation of method involving loop over CharSequence.
cfang
parents: 605
diff changeset
688 return false;
0f2d888530e7 6855164: SIGSEGV during compilation of method involving loop over CharSequence.
cfang
parents: 605
diff changeset
689 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
690 }
a61af66fc99e Initial load
duke
parents:
diff changeset
691 }
a61af66fc99e Initial load
duke
parents:
diff changeset
692 }
a61af66fc99e Initial load
duke
parents:
diff changeset
693 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
694 }
a61af66fc99e Initial load
duke
parents:
diff changeset
695
a61af66fc99e Initial load
duke
parents:
diff changeset
696
a61af66fc99e Initial load
duke
parents:
diff changeset
697 //------------------------------place_near_use---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
698 // Place some computation next to use but not inside inner loops.
a61af66fc99e Initial load
duke
parents:
diff changeset
699 // For inner loop uses move it to the preheader area.
a61af66fc99e Initial load
duke
parents:
diff changeset
700 Node *PhaseIdealLoop::place_near_use( Node *useblock ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
701 IdealLoopTree *u_loop = get_loop( useblock );
a61af66fc99e Initial load
duke
parents:
diff changeset
702 return (u_loop->_irreducible || u_loop->_child)
a61af66fc99e Initial load
duke
parents:
diff changeset
703 ? useblock
a61af66fc99e Initial load
duke
parents:
diff changeset
704 : u_loop->_head->in(LoopNode::EntryControl);
a61af66fc99e Initial load
duke
parents:
diff changeset
705 }
a61af66fc99e Initial load
duke
parents:
diff changeset
706
a61af66fc99e Initial load
duke
parents:
diff changeset
707
a61af66fc99e Initial load
duke
parents:
diff changeset
708 //------------------------------split_if_with_blocks_post----------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
709 // Do the real work in a non-recursive function. CFG hackery wants to be
a61af66fc99e Initial load
duke
parents:
diff changeset
710 // in the post-order, so it can dirty the I-DOM info and not use the dirtied
a61af66fc99e Initial load
duke
parents:
diff changeset
711 // info.
a61af66fc99e Initial load
duke
parents:
diff changeset
712 void PhaseIdealLoop::split_if_with_blocks_post( Node *n ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
713
a61af66fc99e Initial load
duke
parents:
diff changeset
714 // Cloning Cmp through Phi's involves the split-if transform.
a61af66fc99e Initial load
duke
parents:
diff changeset
715 // FastLock is not used by an If
a61af66fc99e Initial load
duke
parents:
diff changeset
716 if( n->is_Cmp() && !n->is_FastLock() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
717 if( C->unique() > 35000 ) return; // Method too big
a61af66fc99e Initial load
duke
parents:
diff changeset
718
a61af66fc99e Initial load
duke
parents:
diff changeset
719 // Do not do 'split-if' if irreducible loops are present.
a61af66fc99e Initial load
duke
parents:
diff changeset
720 if( _has_irreducible_loops )
a61af66fc99e Initial load
duke
parents:
diff changeset
721 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
722
a61af66fc99e Initial load
duke
parents:
diff changeset
723 Node *n_ctrl = get_ctrl(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
724 // Determine if the Node has inputs from some local Phi.
a61af66fc99e Initial load
duke
parents:
diff changeset
725 // Returns the block to clone thru.
a61af66fc99e Initial load
duke
parents:
diff changeset
726 Node *n_blk = has_local_phi_input( n );
a61af66fc99e Initial load
duke
parents:
diff changeset
727 if( n_blk != n_ctrl ) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
728
a61af66fc99e Initial load
duke
parents:
diff changeset
729 if( merge_point_too_heavy(C, n_ctrl) )
a61af66fc99e Initial load
duke
parents:
diff changeset
730 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
731
a61af66fc99e Initial load
duke
parents:
diff changeset
732 if( n->outcnt() != 1 ) return; // Multiple bool's from 1 compare?
a61af66fc99e Initial load
duke
parents:
diff changeset
733 Node *bol = n->unique_out();
a61af66fc99e Initial load
duke
parents:
diff changeset
734 assert( bol->is_Bool(), "expect a bool here" );
a61af66fc99e Initial load
duke
parents:
diff changeset
735 if( bol->outcnt() != 1 ) return;// Multiple branches from 1 compare?
a61af66fc99e Initial load
duke
parents:
diff changeset
736 Node *iff = bol->unique_out();
a61af66fc99e Initial load
duke
parents:
diff changeset
737
a61af66fc99e Initial load
duke
parents:
diff changeset
738 // Check some safety conditions
a61af66fc99e Initial load
duke
parents:
diff changeset
739 if( iff->is_If() ) { // Classic split-if?
a61af66fc99e Initial load
duke
parents:
diff changeset
740 if( iff->in(0) != n_ctrl ) return; // Compare must be in same blk as if
a61af66fc99e Initial load
duke
parents:
diff changeset
741 } else if (iff->is_CMove()) { // Trying to split-up a CMOVE
a61af66fc99e Initial load
duke
parents:
diff changeset
742 if( get_ctrl(iff->in(2)) == n_ctrl ||
a61af66fc99e Initial load
duke
parents:
diff changeset
743 get_ctrl(iff->in(3)) == n_ctrl )
a61af66fc99e Initial load
duke
parents:
diff changeset
744 return; // Inputs not yet split-up
a61af66fc99e Initial load
duke
parents:
diff changeset
745 if ( get_loop(n_ctrl) != get_loop(get_ctrl(iff)) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
746 return; // Loop-invar test gates loop-varying CMOVE
a61af66fc99e Initial load
duke
parents:
diff changeset
747 }
a61af66fc99e Initial load
duke
parents:
diff changeset
748 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
749 return; // some other kind of node, such as an Allocate
a61af66fc99e Initial load
duke
parents:
diff changeset
750 }
a61af66fc99e Initial load
duke
parents:
diff changeset
751
a61af66fc99e Initial load
duke
parents:
diff changeset
752 // Do not do 'split-if' if some paths are dead. First do dead code
a61af66fc99e Initial load
duke
parents:
diff changeset
753 // elimination and then see if its still profitable.
a61af66fc99e Initial load
duke
parents:
diff changeset
754 for( uint i = 1; i < n_ctrl->req(); i++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
755 if( n_ctrl->in(i) == C->top() )
a61af66fc99e Initial load
duke
parents:
diff changeset
756 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
757
a61af66fc99e Initial load
duke
parents:
diff changeset
758 // When is split-if profitable? Every 'win' on means some control flow
a61af66fc99e Initial load
duke
parents:
diff changeset
759 // goes dead, so it's almost always a win.
a61af66fc99e Initial load
duke
parents:
diff changeset
760 int policy = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
761 // If trying to do a 'Split-If' at the loop head, it is only
a61af66fc99e Initial load
duke
parents:
diff changeset
762 // profitable if the cmp folds up on BOTH paths. Otherwise we
a61af66fc99e Initial load
duke
parents:
diff changeset
763 // risk peeling a loop forever.
a61af66fc99e Initial load
duke
parents:
diff changeset
764
a61af66fc99e Initial load
duke
parents:
diff changeset
765 // CNC - Disabled for now. Requires careful handling of loop
a61af66fc99e Initial load
duke
parents:
diff changeset
766 // body selection for the cloned code. Also, make sure we check
a61af66fc99e Initial load
duke
parents:
diff changeset
767 // for any input path not being in the same loop as n_ctrl. For
a61af66fc99e Initial load
duke
parents:
diff changeset
768 // irreducible loops we cannot check for 'n_ctrl->is_Loop()'
a61af66fc99e Initial load
duke
parents:
diff changeset
769 // because the alternative loop entry points won't be converted
a61af66fc99e Initial load
duke
parents:
diff changeset
770 // into LoopNodes.
a61af66fc99e Initial load
duke
parents:
diff changeset
771 IdealLoopTree *n_loop = get_loop(n_ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
772 for( uint j = 1; j < n_ctrl->req(); j++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
773 if( get_loop(n_ctrl->in(j)) != n_loop )
a61af66fc99e Initial load
duke
parents:
diff changeset
774 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
775
a61af66fc99e Initial load
duke
parents:
diff changeset
776 // Check for safety of the merge point.
a61af66fc99e Initial load
duke
parents:
diff changeset
777 if( !merge_point_safe(n_ctrl) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
778 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
779 }
a61af66fc99e Initial load
duke
parents:
diff changeset
780
a61af66fc99e Initial load
duke
parents:
diff changeset
781 // Split compare 'n' through the merge point if it is profitable
a61af66fc99e Initial load
duke
parents:
diff changeset
782 Node *phi = split_thru_phi( n, n_ctrl, policy );
a61af66fc99e Initial load
duke
parents:
diff changeset
783 if( !phi ) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
784
a61af66fc99e Initial load
duke
parents:
diff changeset
785 // Found a Phi to split thru!
a61af66fc99e Initial load
duke
parents:
diff changeset
786 // Replace 'n' with the new phi
1621
6027dddc26c6 6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents: 1552
diff changeset
787 _igvn.replace_node( n, phi );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
788
a61af66fc99e Initial load
duke
parents:
diff changeset
789 // Now split the bool up thru the phi
a61af66fc99e Initial load
duke
parents:
diff changeset
790 Node *bolphi = split_thru_phi( bol, n_ctrl, -1 );
1621
6027dddc26c6 6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents: 1552
diff changeset
791 _igvn.replace_node( bol, bolphi );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
792 assert( iff->in(1) == bolphi, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
793 if( bolphi->Value(&_igvn)->singleton() )
a61af66fc99e Initial load
duke
parents:
diff changeset
794 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
795
a61af66fc99e Initial load
duke
parents:
diff changeset
796 // Conditional-move? Must split up now
a61af66fc99e Initial load
duke
parents:
diff changeset
797 if( !iff->is_If() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
798 Node *cmovphi = split_thru_phi( iff, n_ctrl, -1 );
1621
6027dddc26c6 6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents: 1552
diff changeset
799 _igvn.replace_node( iff, cmovphi );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
800 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
801 }
a61af66fc99e Initial load
duke
parents:
diff changeset
802
a61af66fc99e Initial load
duke
parents:
diff changeset
803 // Now split the IF
a61af66fc99e Initial load
duke
parents:
diff changeset
804 do_split_if( iff );
a61af66fc99e Initial load
duke
parents:
diff changeset
805 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
806 }
a61af66fc99e Initial load
duke
parents:
diff changeset
807
a61af66fc99e Initial load
duke
parents:
diff changeset
808 // Check for an IF ready to split; one that has its
a61af66fc99e Initial load
duke
parents:
diff changeset
809 // condition codes input coming from a Phi at the block start.
a61af66fc99e Initial load
duke
parents:
diff changeset
810 int n_op = n->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
811
a61af66fc99e Initial load
duke
parents:
diff changeset
812 // Check for an IF being dominated by another IF same test
a61af66fc99e Initial load
duke
parents:
diff changeset
813 if( n_op == Op_If ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
814 Node *bol = n->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
815 uint max = bol->outcnt();
a61af66fc99e Initial load
duke
parents:
diff changeset
816 // Check for same test used more than once?
a61af66fc99e Initial load
duke
parents:
diff changeset
817 if( n_op == Op_If && max > 1 && bol->is_Bool() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
818 // Search up IDOMs to see if this IF is dominated.
a61af66fc99e Initial load
duke
parents:
diff changeset
819 Node *cutoff = get_ctrl(bol);
a61af66fc99e Initial load
duke
parents:
diff changeset
820
a61af66fc99e Initial load
duke
parents:
diff changeset
821 // Now search up IDOMs till cutoff, looking for a dominating test
a61af66fc99e Initial load
duke
parents:
diff changeset
822 Node *prevdom = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
823 Node *dom = idom(prevdom);
a61af66fc99e Initial load
duke
parents:
diff changeset
824 while( dom != cutoff ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
825 if( dom->req() > 1 && dom->in(1) == bol && prevdom->in(0) == dom ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
826 // Replace the dominated test with an obvious true or false.
a61af66fc99e Initial load
duke
parents:
diff changeset
827 // Place it on the IGVN worklist for later cleanup.
a61af66fc99e Initial load
duke
parents:
diff changeset
828 C->set_major_progress();
a61af66fc99e Initial load
duke
parents:
diff changeset
829 dominated_by( prevdom, n );
a61af66fc99e Initial load
duke
parents:
diff changeset
830 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
831 if( VerifyLoopOptimizations ) verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
832 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
833 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
834 }
a61af66fc99e Initial load
duke
parents:
diff changeset
835 prevdom = dom;
a61af66fc99e Initial load
duke
parents:
diff changeset
836 dom = idom(prevdom);
a61af66fc99e Initial load
duke
parents:
diff changeset
837 }
a61af66fc99e Initial load
duke
parents:
diff changeset
838 }
a61af66fc99e Initial load
duke
parents:
diff changeset
839 }
a61af66fc99e Initial load
duke
parents:
diff changeset
840
a61af66fc99e Initial load
duke
parents:
diff changeset
841 // See if a shared loop-varying computation has no loop-varying uses.
a61af66fc99e Initial load
duke
parents:
diff changeset
842 // Happens if something is only used for JVM state in uncommon trap exits,
a61af66fc99e Initial load
duke
parents:
diff changeset
843 // like various versions of induction variable+offset. Clone the
a61af66fc99e Initial load
duke
parents:
diff changeset
844 // computation per usage to allow it to sink out of the loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
845 if (has_ctrl(n) && !n->in(0)) {// n not dead and has no control edge (can float about)
a61af66fc99e Initial load
duke
parents:
diff changeset
846 Node *n_ctrl = get_ctrl(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
847 IdealLoopTree *n_loop = get_loop(n_ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
848 if( n_loop != _ltree_root ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
849 DUIterator_Fast imax, i = n->fast_outs(imax);
a61af66fc99e Initial load
duke
parents:
diff changeset
850 for (; i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
851 Node* u = n->fast_out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
852 if( !has_ctrl(u) ) break; // Found control user
a61af66fc99e Initial load
duke
parents:
diff changeset
853 IdealLoopTree *u_loop = get_loop(get_ctrl(u));
a61af66fc99e Initial load
duke
parents:
diff changeset
854 if( u_loop == n_loop ) break; // Found loop-varying use
a61af66fc99e Initial load
duke
parents:
diff changeset
855 if( n_loop->is_member( u_loop ) ) break; // Found use in inner loop
a61af66fc99e Initial load
duke
parents:
diff changeset
856 if( u->Opcode() == Op_Opaque1 ) break; // Found loop limit, bugfix for 4677003
a61af66fc99e Initial load
duke
parents:
diff changeset
857 }
a61af66fc99e Initial load
duke
parents:
diff changeset
858 bool did_break = (i < imax); // Did we break out of the previous loop?
a61af66fc99e Initial load
duke
parents:
diff changeset
859 if (!did_break && n->outcnt() > 1) { // All uses in outer loops!
a61af66fc99e Initial load
duke
parents:
diff changeset
860 Node *late_load_ctrl;
a61af66fc99e Initial load
duke
parents:
diff changeset
861 if (n->is_Load()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
862 // If n is a load, get and save the result from get_late_ctrl(),
a61af66fc99e Initial load
duke
parents:
diff changeset
863 // to be later used in calculating the control for n's clones.
a61af66fc99e Initial load
duke
parents:
diff changeset
864 clear_dom_lca_tags();
a61af66fc99e Initial load
duke
parents:
diff changeset
865 late_load_ctrl = get_late_ctrl(n, n_ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
866 }
a61af66fc99e Initial load
duke
parents:
diff changeset
867 // If n is a load, and the late control is the same as the current
a61af66fc99e Initial load
duke
parents:
diff changeset
868 // control, then the cloning of n is a pointless exercise, because
a61af66fc99e Initial load
duke
parents:
diff changeset
869 // GVN will ensure that we end up where we started.
a61af66fc99e Initial load
duke
parents:
diff changeset
870 if (!n->is_Load() || late_load_ctrl != n_ctrl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
871 for (DUIterator_Last jmin, j = n->last_outs(jmin); j >= jmin; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
872 Node *u = n->last_out(j); // Clone private computation per use
a61af66fc99e Initial load
duke
parents:
diff changeset
873 _igvn.hash_delete(u);
a61af66fc99e Initial load
duke
parents:
diff changeset
874 _igvn._worklist.push(u);
a61af66fc99e Initial load
duke
parents:
diff changeset
875 Node *x = n->clone(); // Clone computation
a61af66fc99e Initial load
duke
parents:
diff changeset
876 Node *x_ctrl = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
877 if( u->is_Phi() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
878 // Replace all uses of normal nodes. Replace Phi uses
605
98cb887364d3 6810672: Comment typos
twisti
parents: 401
diff changeset
879 // individually, so the separate Nodes can sink down
0
a61af66fc99e Initial load
duke
parents:
diff changeset
880 // different paths.
a61af66fc99e Initial load
duke
parents:
diff changeset
881 uint k = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
882 while( u->in(k) != n ) k++;
a61af66fc99e Initial load
duke
parents:
diff changeset
883 u->set_req( k, x );
a61af66fc99e Initial load
duke
parents:
diff changeset
884 // x goes next to Phi input path
a61af66fc99e Initial load
duke
parents:
diff changeset
885 x_ctrl = u->in(0)->in(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
886 --j;
a61af66fc99e Initial load
duke
parents:
diff changeset
887 } else { // Normal use
a61af66fc99e Initial load
duke
parents:
diff changeset
888 // Replace all uses
a61af66fc99e Initial load
duke
parents:
diff changeset
889 for( uint k = 0; k < u->req(); k++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
890 if( u->in(k) == n ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
891 u->set_req( k, x );
a61af66fc99e Initial load
duke
parents:
diff changeset
892 --j;
a61af66fc99e Initial load
duke
parents:
diff changeset
893 }
a61af66fc99e Initial load
duke
parents:
diff changeset
894 }
a61af66fc99e Initial load
duke
parents:
diff changeset
895 x_ctrl = get_ctrl(u);
a61af66fc99e Initial load
duke
parents:
diff changeset
896 }
a61af66fc99e Initial load
duke
parents:
diff changeset
897
a61af66fc99e Initial load
duke
parents:
diff changeset
898 // Find control for 'x' next to use but not inside inner loops.
a61af66fc99e Initial load
duke
parents:
diff changeset
899 // For inner loop uses get the preheader area.
a61af66fc99e Initial load
duke
parents:
diff changeset
900 x_ctrl = place_near_use(x_ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
901
a61af66fc99e Initial load
duke
parents:
diff changeset
902 if (n->is_Load()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
903 // For loads, add a control edge to a CFG node outside of the loop
a61af66fc99e Initial load
duke
parents:
diff changeset
904 // to force them to not combine and return back inside the loop
a61af66fc99e Initial load
duke
parents:
diff changeset
905 // during GVN optimization (4641526).
a61af66fc99e Initial load
duke
parents:
diff changeset
906 //
a61af66fc99e Initial load
duke
parents:
diff changeset
907 // Because we are setting the actual control input, factor in
a61af66fc99e Initial load
duke
parents:
diff changeset
908 // the result from get_late_ctrl() so we respect any
a61af66fc99e Initial load
duke
parents:
diff changeset
909 // anti-dependences. (6233005).
a61af66fc99e Initial load
duke
parents:
diff changeset
910 x_ctrl = dom_lca(late_load_ctrl, x_ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
911
a61af66fc99e Initial load
duke
parents:
diff changeset
912 // Don't allow the control input to be a CFG splitting node.
a61af66fc99e Initial load
duke
parents:
diff changeset
913 // Such nodes should only have ProjNodes as outs, e.g. IfNode
a61af66fc99e Initial load
duke
parents:
diff changeset
914 // should only have IfTrueNode and IfFalseNode (4985384).
a61af66fc99e Initial load
duke
parents:
diff changeset
915 x_ctrl = find_non_split_ctrl(x_ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
916 assert(dom_depth(n_ctrl) <= dom_depth(x_ctrl), "n is later than its clone");
a61af66fc99e Initial load
duke
parents:
diff changeset
917
a61af66fc99e Initial load
duke
parents:
diff changeset
918 x->set_req(0, x_ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
919 }
a61af66fc99e Initial load
duke
parents:
diff changeset
920 register_new_node(x, x_ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
921
a61af66fc99e Initial load
duke
parents:
diff changeset
922 // Some institutional knowledge is needed here: 'x' is
a61af66fc99e Initial load
duke
parents:
diff changeset
923 // yanked because if the optimizer runs GVN on it all the
a61af66fc99e Initial load
duke
parents:
diff changeset
924 // cloned x's will common up and undo this optimization and
a61af66fc99e Initial load
duke
parents:
diff changeset
925 // be forced back in the loop. This is annoying because it
a61af66fc99e Initial load
duke
parents:
diff changeset
926 // makes +VerifyOpto report false-positives on progress. I
a61af66fc99e Initial load
duke
parents:
diff changeset
927 // tried setting control edges on the x's to force them to
a61af66fc99e Initial load
duke
parents:
diff changeset
928 // not combine, but the matching gets worried when it tries
a61af66fc99e Initial load
duke
parents:
diff changeset
929 // to fold a StoreP and an AddP together (as part of an
a61af66fc99e Initial load
duke
parents:
diff changeset
930 // address expression) and the AddP and StoreP have
a61af66fc99e Initial load
duke
parents:
diff changeset
931 // different controls.
318
60bc5071073f 6738933: assert with base pointers must match with compressed oops enabled
never
parents: 293
diff changeset
932 if( !x->is_Load() && !x->is_DecodeN() ) _igvn._worklist.yank(x);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
933 }
a61af66fc99e Initial load
duke
parents:
diff changeset
934 _igvn.remove_dead_node(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
935 }
a61af66fc99e Initial load
duke
parents:
diff changeset
936 }
a61af66fc99e Initial load
duke
parents:
diff changeset
937 }
a61af66fc99e Initial load
duke
parents:
diff changeset
938 }
a61af66fc99e Initial load
duke
parents:
diff changeset
939
a61af66fc99e Initial load
duke
parents:
diff changeset
940 // Check for Opaque2's who's loop has disappeared - who's input is in the
a61af66fc99e Initial load
duke
parents:
diff changeset
941 // same loop nest as their output. Remove 'em, they are no longer useful.
a61af66fc99e Initial load
duke
parents:
diff changeset
942 if( n_op == Op_Opaque2 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
943 n->in(1) != NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
944 get_loop(get_ctrl(n)) == get_loop(get_ctrl(n->in(1))) ) {
1621
6027dddc26c6 6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents: 1552
diff changeset
945 _igvn.replace_node( n, n->in(1) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
946 }
a61af66fc99e Initial load
duke
parents:
diff changeset
947 }
a61af66fc99e Initial load
duke
parents:
diff changeset
948
a61af66fc99e Initial load
duke
parents:
diff changeset
949 //------------------------------split_if_with_blocks---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
950 // Check for aggressive application of 'split-if' optimization,
a61af66fc99e Initial load
duke
parents:
diff changeset
951 // using basic block level info.
a61af66fc99e Initial load
duke
parents:
diff changeset
952 void PhaseIdealLoop::split_if_with_blocks( VectorSet &visited, Node_Stack &nstack ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
953 Node *n = C->root();
a61af66fc99e Initial load
duke
parents:
diff changeset
954 visited.set(n->_idx); // first, mark node as visited
a61af66fc99e Initial load
duke
parents:
diff changeset
955 // Do pre-visit work for root
a61af66fc99e Initial load
duke
parents:
diff changeset
956 n = split_if_with_blocks_pre( n );
a61af66fc99e Initial load
duke
parents:
diff changeset
957 uint cnt = n->outcnt();
a61af66fc99e Initial load
duke
parents:
diff changeset
958 uint i = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
959 while (true) {
a61af66fc99e Initial load
duke
parents:
diff changeset
960 // Visit all children
a61af66fc99e Initial load
duke
parents:
diff changeset
961 if (i < cnt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
962 Node* use = n->raw_out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
963 ++i;
a61af66fc99e Initial load
duke
parents:
diff changeset
964 if (use->outcnt() != 0 && !visited.test_set(use->_idx)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
965 // Now do pre-visit work for this use
a61af66fc99e Initial load
duke
parents:
diff changeset
966 use = split_if_with_blocks_pre( use );
a61af66fc99e Initial load
duke
parents:
diff changeset
967 nstack.push(n, i); // Save parent and next use's index.
a61af66fc99e Initial load
duke
parents:
diff changeset
968 n = use; // Process all children of current use.
a61af66fc99e Initial load
duke
parents:
diff changeset
969 cnt = use->outcnt();
a61af66fc99e Initial load
duke
parents:
diff changeset
970 i = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
971 }
a61af66fc99e Initial load
duke
parents:
diff changeset
972 }
a61af66fc99e Initial load
duke
parents:
diff changeset
973 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
974 // All of n's children have been processed, complete post-processing.
a61af66fc99e Initial load
duke
parents:
diff changeset
975 if (cnt != 0 && !n->is_Con()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
976 assert(has_node(n), "no dead nodes");
a61af66fc99e Initial load
duke
parents:
diff changeset
977 split_if_with_blocks_post( n );
a61af66fc99e Initial load
duke
parents:
diff changeset
978 }
a61af66fc99e Initial load
duke
parents:
diff changeset
979 if (nstack.is_empty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
980 // Finished all nodes on stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
981 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
982 }
a61af66fc99e Initial load
duke
parents:
diff changeset
983 // Get saved parent node and next use's index. Visit the rest of uses.
a61af66fc99e Initial load
duke
parents:
diff changeset
984 n = nstack.node();
a61af66fc99e Initial load
duke
parents:
diff changeset
985 cnt = n->outcnt();
a61af66fc99e Initial load
duke
parents:
diff changeset
986 i = nstack.index();
a61af66fc99e Initial load
duke
parents:
diff changeset
987 nstack.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
988 }
a61af66fc99e Initial load
duke
parents:
diff changeset
989 }
a61af66fc99e Initial load
duke
parents:
diff changeset
990 }
a61af66fc99e Initial load
duke
parents:
diff changeset
991
a61af66fc99e Initial load
duke
parents:
diff changeset
992
a61af66fc99e Initial load
duke
parents:
diff changeset
993 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
994 //
a61af66fc99e Initial load
duke
parents:
diff changeset
995 // C L O N E A L O O P B O D Y
a61af66fc99e Initial load
duke
parents:
diff changeset
996 //
a61af66fc99e Initial load
duke
parents:
diff changeset
997
a61af66fc99e Initial load
duke
parents:
diff changeset
998 //------------------------------clone_iff--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
999 // Passed in a Phi merging (recursively) some nearly equivalent Bool/Cmps.
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 // "Nearly" because all Nodes have been cloned from the original in the loop,
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 // but the fall-in edges to the Cmp are different. Clone bool/Cmp pairs
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 // through the Phi recursively, and return a Bool.
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 BoolNode *PhaseIdealLoop::clone_iff( PhiNode *phi, IdealLoopTree *loop ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1004
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 // Convert this Phi into a Phi merging Bools
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 uint i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 for( i = 1; i < phi->req(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 Node *b = phi->in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 if( b->is_Phi() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 _igvn.hash_delete(phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 _igvn._worklist.push(phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 phi->set_req(i, clone_iff( b->as_Phi(), loop ));
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 assert( b->is_Bool(), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1017
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 Node *sample_bool = phi->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 Node *sample_cmp = sample_bool->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1020
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 // Make Phis to merge the Cmp's inputs.
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 int size = phi->in(0)->req();
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 PhiNode *phi1 = new (C, size) PhiNode( phi->in(0), Type::TOP );
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 PhiNode *phi2 = new (C, size) PhiNode( phi->in(0), Type::TOP );
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 for( i = 1; i < phi->req(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 Node *n1 = phi->in(i)->in(1)->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 Node *n2 = phi->in(i)->in(1)->in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 phi1->set_req( i, n1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 phi2->set_req( i, n2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 phi1->set_type( phi1->type()->meet(n1->bottom_type()) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 phi2->set_type( phi2->type()->meet(n2->bottom_type()) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 // See if these Phis have been made before.
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 // Register with optimizer
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 Node *hit1 = _igvn.hash_find_insert(phi1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 if( hit1 ) { // Hit, toss just made Phi
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 _igvn.remove_dead_node(phi1); // Remove new phi
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 assert( hit1->is_Phi(), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 phi1 = (PhiNode*)hit1; // Use existing phi
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 } else { // Miss
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 _igvn.register_new_node_with_optimizer(phi1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 Node *hit2 = _igvn.hash_find_insert(phi2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 if( hit2 ) { // Hit, toss just made Phi
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 _igvn.remove_dead_node(phi2); // Remove new phi
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 assert( hit2->is_Phi(), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 phi2 = (PhiNode*)hit2; // Use existing phi
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 } else { // Miss
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 _igvn.register_new_node_with_optimizer(phi2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 // Register Phis with loop/block info
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 set_ctrl(phi1, phi->in(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 set_ctrl(phi2, phi->in(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 // Make a new Cmp
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 Node *cmp = sample_cmp->clone();
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 cmp->set_req( 1, phi1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 cmp->set_req( 2, phi2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 _igvn.register_new_node_with_optimizer(cmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 set_ctrl(cmp, phi->in(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1060
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 // Make a new Bool
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 Node *b = sample_bool->clone();
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 b->set_req(1,cmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 _igvn.register_new_node_with_optimizer(b);
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 set_ctrl(b, phi->in(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1066
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 assert( b->is_Bool(), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 return (BoolNode*)b;
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1070
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 //------------------------------clone_bool-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 // Passed in a Phi merging (recursively) some nearly equivalent Bool/Cmps.
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 // "Nearly" because all Nodes have been cloned from the original in the loop,
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 // but the fall-in edges to the Cmp are different. Clone bool/Cmp pairs
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 // through the Phi recursively, and return a Bool.
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 CmpNode *PhaseIdealLoop::clone_bool( PhiNode *phi, IdealLoopTree *loop ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 uint i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 // Convert this Phi into a Phi merging Bools
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 for( i = 1; i < phi->req(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 Node *b = phi->in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 if( b->is_Phi() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 _igvn.hash_delete(phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 _igvn._worklist.push(phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 phi->set_req(i, clone_bool( b->as_Phi(), loop ));
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 assert( b->is_Cmp() || b->is_top(), "inputs are all Cmp or TOP" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1089
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 Node *sample_cmp = phi->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1091
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 // Make Phis to merge the Cmp's inputs.
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 int size = phi->in(0)->req();
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 PhiNode *phi1 = new (C, size) PhiNode( phi->in(0), Type::TOP );
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 PhiNode *phi2 = new (C, size) PhiNode( phi->in(0), Type::TOP );
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 for( uint j = 1; j < phi->req(); j++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 Node *cmp_top = phi->in(j); // Inputs are all Cmp or TOP
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 Node *n1, *n2;
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 if( cmp_top->is_Cmp() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 n1 = cmp_top->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 n2 = cmp_top->in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 n1 = n2 = cmp_top;
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 phi1->set_req( j, n1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 phi2->set_req( j, n2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 phi1->set_type( phi1->type()->meet(n1->bottom_type()) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 phi2->set_type( phi2->type()->meet(n2->bottom_type()) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1110
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 // See if these Phis have been made before.
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 // Register with optimizer
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 Node *hit1 = _igvn.hash_find_insert(phi1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 if( hit1 ) { // Hit, toss just made Phi
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 _igvn.remove_dead_node(phi1); // Remove new phi
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 assert( hit1->is_Phi(), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 phi1 = (PhiNode*)hit1; // Use existing phi
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 } else { // Miss
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 _igvn.register_new_node_with_optimizer(phi1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 Node *hit2 = _igvn.hash_find_insert(phi2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 if( hit2 ) { // Hit, toss just made Phi
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 _igvn.remove_dead_node(phi2); // Remove new phi
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 assert( hit2->is_Phi(), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 phi2 = (PhiNode*)hit2; // Use existing phi
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 } else { // Miss
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 _igvn.register_new_node_with_optimizer(phi2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 // Register Phis with loop/block info
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 set_ctrl(phi1, phi->in(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 set_ctrl(phi2, phi->in(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 // Make a new Cmp
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 Node *cmp = sample_cmp->clone();
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 cmp->set_req( 1, phi1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 cmp->set_req( 2, phi2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 _igvn.register_new_node_with_optimizer(cmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 set_ctrl(cmp, phi->in(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1138
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 assert( cmp->is_Cmp(), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 return (CmpNode*)cmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1142
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 //------------------------------sink_use---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 // If 'use' was in the loop-exit block, it now needs to be sunk
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 // below the post-loop merge point.
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 void PhaseIdealLoop::sink_use( Node *use, Node *post_loop ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 if (!use->is_CFG() && get_ctrl(use) == post_loop->in(2)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 set_ctrl(use, post_loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 for (DUIterator j = use->outs(); use->has_out(j); j++)
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 sink_use(use->out(j), post_loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1153
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 //------------------------------clone_loop-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 // C L O N E A L O O P B O D Y
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 // This is the basic building block of the loop optimizations. It clones an
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 // entire loop body. It makes an old_new loop body mapping; with this mapping
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 // you can find the new-loop equivalent to an old-loop node. All new-loop
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 // nodes are exactly equal to their old-loop counterparts, all edges are the
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 // same. All exits from the old-loop now have a RegionNode that merges the
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 // equivalent new-loop path. This is true even for the normal "loop-exit"
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 // condition. All uses of loop-invariant old-loop values now come from (one
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 // or more) Phis that merge their new-loop equivalents.
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 // This operation leaves the graph in an illegal state: there are two valid
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 // control edges coming from the loop pre-header to both loop bodies. I'll
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 // definitely have to hack the graph after running this transform.
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 // From this building block I will further edit edges to perform loop peeling
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 // or loop unrolling or iteration splitting (Range-Check-Elimination), etc.
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 // Parameter side_by_size_idom:
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 // When side_by_size_idom is NULL, the dominator tree is constructed for
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 // the clone loop to dominate the original. Used in construction of
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 // pre-main-post loop sequence.
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 // When nonnull, the clone and original are side-by-side, both are
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 // dominated by the side_by_side_idom node. Used in construction of
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 // unswitched loops.
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 void PhaseIdealLoop::clone_loop( IdealLoopTree *loop, Node_List &old_new, int dd,
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 Node* side_by_side_idom) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1183
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 // Step 1: Clone the loop body. Make the old->new mapping.
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 uint i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 for( i = 0; i < loop->_body.size(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 Node *old = loop->_body.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 Node *nnn = old->clone();
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 old_new.map( old->_idx, nnn );
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 _igvn.register_new_node_with_optimizer(nnn);
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1192
a61af66fc99e Initial load
duke
parents:
diff changeset
1193
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 // Step 2: Fix the edges in the new body. If the old input is outside the
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 // loop use it. If the old input is INside the loop, use the corresponding
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 // new node instead.
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 for( i = 0; i < loop->_body.size(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 Node *old = loop->_body.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 Node *nnn = old_new[old->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 // Fix CFG/Loop controlling the new node
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 if (has_ctrl(old)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 set_ctrl(nnn, old_new[get_ctrl(old)->_idx]);
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 set_loop(nnn, loop->_parent);
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 if (old->outcnt() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 set_idom( nnn, old_new[idom(old)->_idx], dd );
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 // Correct edges to the new node
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 for( uint j = 0; j < nnn->req(); j++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 Node *n = nnn->in(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 if( n ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 IdealLoopTree *old_in_loop = get_loop( has_ctrl(n) ? get_ctrl(n) : n );
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 if( loop->is_member( old_in_loop ) )
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 nnn->set_req(j, old_new[n->_idx]);
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 _igvn.hash_find_insert(nnn);
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 Node *newhead = old_new[loop->_head->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 set_idom(newhead, newhead->in(LoopNode::EntryControl), dd);
a61af66fc99e Initial load
duke
parents:
diff changeset
1222
a61af66fc99e Initial load
duke
parents:
diff changeset
1223
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 // Step 3: Now fix control uses. Loop varying control uses have already
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 // been fixed up (as part of all input edges in Step 2). Loop invariant
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 // control uses must be either an IfFalse or an IfTrue. Make a merge
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 // point to merge the old and new IfFalse/IfTrue nodes; make the use
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 // refer to this.
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 ResourceArea *area = Thread::current()->resource_area();
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 Node_List worklist(area);
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 uint new_counter = C->unique();
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 for( i = 0; i < loop->_body.size(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 Node* old = loop->_body.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 if( !old->is_CFG() ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 Node* nnn = old_new[old->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
1236
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 // Copy uses to a worklist, so I can munge the def-use info
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 // with impunity.
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 for (DUIterator_Fast jmax, j = old->fast_outs(jmax); j < jmax; j++)
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 worklist.push(old->fast_out(j));
a61af66fc99e Initial load
duke
parents:
diff changeset
1241
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 while( worklist.size() ) { // Visit all uses
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 Node *use = worklist.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 if (!has_node(use)) continue; // Ignore dead nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 IdealLoopTree *use_loop = get_loop( has_ctrl(use) ? get_ctrl(use) : use );
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 if( !loop->is_member( use_loop ) && use->is_CFG() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 // Both OLD and USE are CFG nodes here.
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 assert( use->is_Proj(), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1249
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 // Clone the loop exit control projection
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 Node *newuse = use->clone();
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 newuse->set_req(0,nnn);
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 _igvn.register_new_node_with_optimizer(newuse);
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 set_loop(newuse, use_loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 set_idom(newuse, nnn, dom_depth(nnn) + 1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1256
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 // We need a Region to merge the exit from the peeled body and the
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 // exit from the old loop body.
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 RegionNode *r = new (C, 3) RegionNode(3);
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 // Map the old use to the new merge point
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 old_new.map( use->_idx, r );
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 uint dd_r = MIN2(dom_depth(newuse),dom_depth(use));
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 assert( dd_r >= dom_depth(dom_lca(newuse,use)), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1264
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 // The original user of 'use' uses 'r' instead.
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 for (DUIterator_Last lmin, l = use->last_outs(lmin); l >= lmin;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 Node* useuse = use->last_out(l);
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 _igvn.hash_delete(useuse);
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 _igvn._worklist.push(useuse);
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 uint uses_found = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 if( useuse->in(0) == use ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 useuse->set_req(0, r);
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 uses_found++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 if( useuse->is_CFG() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 assert( dom_depth(useuse) > dd_r, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 set_idom(useuse, r, dom_depth(useuse));
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 for( uint k = 1; k < useuse->req(); k++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 if( useuse->in(k) == use ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 useuse->set_req(k, r);
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 uses_found++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 l -= uses_found; // we deleted 1 or more copies of this edge
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1287
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 // Now finish up 'r'
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 r->set_req( 1, newuse );
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 r->set_req( 2, use );
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 _igvn.register_new_node_with_optimizer(r);
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 set_loop(r, use_loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 set_idom(r, !side_by_side_idom ? newuse->in(0) : side_by_side_idom, dd_r);
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 } // End of if a loop-exit test
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1297
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 // Step 4: If loop-invariant use is not control, it must be dominated by a
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 // loop exit IfFalse/IfTrue. Find "proper" loop exit. Make a Region
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 // there if needed. Make a Phi there merging old and new used values.
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 Node_List *split_if_set = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 Node_List *split_bool_set = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 Node_List *split_cex_set = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 for( i = 0; i < loop->_body.size(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 Node* old = loop->_body.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 Node* nnn = old_new[old->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 // Copy uses to a worklist, so I can munge the def-use info
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 // with impunity.
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 for (DUIterator_Fast jmax, j = old->fast_outs(jmax); j < jmax; j++)
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 worklist.push(old->fast_out(j));
a61af66fc99e Initial load
duke
parents:
diff changeset
1311
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 while( worklist.size() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 Node *use = worklist.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 if (!has_node(use)) continue; // Ignore dead nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 if (use->in(0) == C->top()) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 IdealLoopTree *use_loop = get_loop( has_ctrl(use) ? get_ctrl(use) : use );
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 // Check for data-use outside of loop - at least one of OLD or USE
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 // must not be a CFG node.
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 if( !loop->is_member( use_loop ) && (!old->is_CFG() || !use->is_CFG())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1320
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 // If the Data use is an IF, that means we have an IF outside of the
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 // loop that is switching on a condition that is set inside of the
a61af66fc99e Initial load
duke
parents:
diff changeset
1323 // loop. Happens if people set a loop-exit flag; then test the flag
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 // in the loop to break the loop, then test is again outside of the
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 // loop to determine which way the loop exited.
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 if( use->is_If() || use->is_CMove() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 // Since this code is highly unlikely, we lazily build the worklist
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 // of such Nodes to go split.
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 if( !split_if_set )
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 split_if_set = new Node_List(area);
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 split_if_set->push(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 if( use->is_Bool() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 if( !split_bool_set )
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 split_bool_set = new Node_List(area);
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 split_bool_set->push(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 if( use->Opcode() == Op_CreateEx ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 if( !split_cex_set )
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 split_cex_set = new Node_List(area);
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 split_cex_set->push(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1343
a61af66fc99e Initial load
duke
parents:
diff changeset
1344
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 // Get "block" use is in
a61af66fc99e Initial load
duke
parents:
diff changeset
1346 uint idx = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 while( use->in(idx) != old ) idx++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 Node *prev = use->is_CFG() ? use : get_ctrl(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 assert( !loop->is_member( get_loop( prev ) ), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 Node *cfg = prev->_idx >= new_counter
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 ? prev->in(2)
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 : idom(prev);
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 if( use->is_Phi() ) // Phi use is in prior block
a61af66fc99e Initial load
duke
parents:
diff changeset
1354 cfg = prev->in(idx); // NOT in block of Phi itself
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 if (cfg->is_top()) { // Use is dead?
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 _igvn.hash_delete(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
1357 _igvn._worklist.push(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 use->set_req(idx, C->top());
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1361
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 while( !loop->is_member( get_loop( cfg ) ) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1363 prev = cfg;
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 cfg = cfg->_idx >= new_counter ? cfg->in(2) : idom(cfg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 // If the use occurs after merging several exits from the loop, then
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 // old value must have dominated all those exits. Since the same old
a61af66fc99e Initial load
duke
parents:
diff changeset
1368 // value was used on all those exits we did not need a Phi at this
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 // merge point. NOW we do need a Phi here. Each loop exit value
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 // is now merged with the peeled body exit; each exit gets its own
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 // private Phi and those Phis need to be merged here.
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 Node *phi;
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 if( prev->is_Region() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 if( idx == 0 ) { // Updating control edge?
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 phi = prev; // Just use existing control
a61af66fc99e Initial load
duke
parents:
diff changeset
1376 } else { // Else need a new Phi
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 phi = PhiNode::make( prev, old );
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 // Now recursively fix up the new uses of old!
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 for( uint i = 1; i < prev->req(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 worklist.push(phi); // Onto worklist once for each 'old' input
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 // Get new RegionNode merging old and new loop exits
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 prev = old_new[prev->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 assert( prev, "just made this in step 7" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1387 if( idx == 0 ) { // Updating control edge?
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 phi = prev; // Just use existing control
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 } else { // Else need a new Phi
a61af66fc99e Initial load
duke
parents:
diff changeset
1390 // Make a new Phi merging data values properly
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 phi = PhiNode::make( prev, old );
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 phi->set_req( 1, nnn );
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1394 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1395 // If inserting a new Phi, check for prior hits
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 if( idx != 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 Node *hit = _igvn.hash_find_insert(phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
1398 if( hit == NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1399 _igvn.register_new_node_with_optimizer(phi); // Register new phi
a61af66fc99e Initial load
duke
parents:
diff changeset
1400 } else { // or
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 // Remove the new phi from the graph and use the hit
a61af66fc99e Initial load
duke
parents:
diff changeset
1402 _igvn.remove_dead_node(phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 phi = hit; // Use existing phi
a61af66fc99e Initial load
duke
parents:
diff changeset
1404 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 set_ctrl(phi, prev);
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 // Make 'use' use the Phi instead of the old loop body exit value
a61af66fc99e Initial load
duke
parents:
diff changeset
1408 _igvn.hash_delete(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 _igvn._worklist.push(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
1410 use->set_req(idx, phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
1411 if( use->_idx >= new_counter ) { // If updating new phis
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 // Not needed for correctness, but prevents a weak assert
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 // in AddPNode from tripping (when we end up with different
a61af66fc99e Initial load
duke
parents:
diff changeset
1414 // base & derived Phis that will become the same after
a61af66fc99e Initial load
duke
parents:
diff changeset
1415 // IGVN does CSE).
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 Node *hit = _igvn.hash_find_insert(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
1417 if( hit ) // Go ahead and re-hash for hits.
1621
6027dddc26c6 6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents: 1552
diff changeset
1418 _igvn.replace_node( use, hit );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1419 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1420
a61af66fc99e Initial load
duke
parents:
diff changeset
1421 // If 'use' was in the loop-exit block, it now needs to be sunk
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 // below the post-loop merge point.
a61af66fc99e Initial load
duke
parents:
diff changeset
1423 sink_use( use, prev );
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1425 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1426 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1427
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 // Check for IFs that need splitting/cloning. Happens if an IF outside of
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 // the loop uses a condition set in the loop. The original IF probably
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 // takes control from one or more OLD Regions (which in turn get from NEW
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 // Regions). In any case, there will be a set of Phis for each merge point
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 // from the IF up to where the original BOOL def exists the loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 if( split_if_set ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 while( split_if_set->size() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 Node *iff = split_if_set->pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 if( iff->in(1)->is_Phi() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 BoolNode *b = clone_iff( iff->in(1)->as_Phi(), loop );
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 _igvn.hash_delete(iff);
a61af66fc99e Initial load
duke
parents:
diff changeset
1439 _igvn._worklist.push(iff);
a61af66fc99e Initial load
duke
parents:
diff changeset
1440 iff->set_req(1, b);
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1442 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1443 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 if( split_bool_set ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 while( split_bool_set->size() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 Node *b = split_bool_set->pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 Node *phi = b->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 assert( phi->is_Phi(), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 CmpNode *cmp = clone_bool( (PhiNode*)phi, loop );
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 _igvn.hash_delete(b);
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 _igvn._worklist.push(b);
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 b->set_req(1, cmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1453 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 if( split_cex_set ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 while( split_cex_set->size() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 Node *b = split_cex_set->pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1458 assert( b->in(0)->is_Region(), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 assert( b->in(1)->is_Phi(), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 assert( b->in(0)->in(0) == b->in(1)->in(0), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 split_up( b, b->in(0), NULL );
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1464
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1466
a61af66fc99e Initial load
duke
parents:
diff changeset
1467
a61af66fc99e Initial load
duke
parents:
diff changeset
1468 //---------------------- stride_of_possible_iv -------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1469 // Looks for an iff/bool/comp with one operand of the compare
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 // being a cycle involving an add and a phi,
a61af66fc99e Initial load
duke
parents:
diff changeset
1471 // with an optional truncation (left-shift followed by a right-shift)
a61af66fc99e Initial load
duke
parents:
diff changeset
1472 // of the add. Returns zero if not an iv.
a61af66fc99e Initial load
duke
parents:
diff changeset
1473 int PhaseIdealLoop::stride_of_possible_iv(Node* iff) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 Node* trunc1 = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1475 Node* trunc2 = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1476 const TypeInt* ttype = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 if (!iff->is_If() || iff->in(1) == NULL || !iff->in(1)->is_Bool()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1478 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 BoolNode* bl = iff->in(1)->as_Bool();
a61af66fc99e Initial load
duke
parents:
diff changeset
1481 Node* cmp = bl->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1482 if (!cmp || cmp->Opcode() != Op_CmpI && cmp->Opcode() != Op_CmpU) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1483 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1484 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 // Must have an invariant operand
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 if (is_member(get_loop(iff), get_ctrl(cmp->in(2)))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1487 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 Node* add2 = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 Node* cmp1 = cmp->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 if (cmp1->is_Phi()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1492 // (If (Bool (CmpX phi:(Phi ...(Optional-trunc(AddI phi add2))) )))
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 Node* phi = cmp1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 for (uint i = 1; i < phi->req(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1495 Node* in = phi->in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1496 Node* add = CountedLoopNode::match_incr_with_optional_truncation(in,
a61af66fc99e Initial load
duke
parents:
diff changeset
1497 &trunc1, &trunc2, &ttype);
a61af66fc99e Initial load
duke
parents:
diff changeset
1498 if (add && add->in(1) == phi) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1499 add2 = add->in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1501 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1502 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1503 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1504 // (If (Bool (CmpX addtrunc:(Optional-trunc((AddI (Phi ...addtrunc...) add2)) )))
a61af66fc99e Initial load
duke
parents:
diff changeset
1505 Node* addtrunc = cmp1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 Node* add = CountedLoopNode::match_incr_with_optional_truncation(addtrunc,
a61af66fc99e Initial load
duke
parents:
diff changeset
1507 &trunc1, &trunc2, &ttype);
a61af66fc99e Initial load
duke
parents:
diff changeset
1508 if (add && add->in(1)->is_Phi()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1509 Node* phi = add->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1510 for (uint i = 1; i < phi->req(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 if (phi->in(i) == addtrunc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1512 add2 = add->in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1513 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1514 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1515 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1516 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 if (add2 != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1519 const TypeInt* add2t = _igvn.type(add2)->is_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
1520 if (add2t->is_con()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1521 return add2t->get_con();
a61af66fc99e Initial load
duke
parents:
diff changeset
1522 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1523 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1525 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1526
a61af66fc99e Initial load
duke
parents:
diff changeset
1527
a61af66fc99e Initial load
duke
parents:
diff changeset
1528 //---------------------- stay_in_loop -------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1529 // Return the (unique) control output node that's in the loop (if it exists.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1530 Node* PhaseIdealLoop::stay_in_loop( Node* n, IdealLoopTree *loop) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1531 Node* unique = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1532 if (!n) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1533 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1534 Node* use = n->fast_out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1535 if (!has_ctrl(use) && loop->is_member(get_loop(use))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1536 if (unique != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1537 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1538 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 unique = use;
a61af66fc99e Initial load
duke
parents:
diff changeset
1540 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1541 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1542 return unique;
a61af66fc99e Initial load
duke
parents:
diff changeset
1543 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1544
a61af66fc99e Initial load
duke
parents:
diff changeset
1545 //------------------------------ register_node -------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1546 // Utility to register node "n" with PhaseIdealLoop
a61af66fc99e Initial load
duke
parents:
diff changeset
1547 void PhaseIdealLoop::register_node(Node* n, IdealLoopTree *loop, Node* pred, int ddepth) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1548 _igvn.register_new_node_with_optimizer(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1549 loop->_body.push(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1550 if (n->is_CFG()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1551 set_loop(n, loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1552 set_idom(n, pred, ddepth);
a61af66fc99e Initial load
duke
parents:
diff changeset
1553 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1554 set_ctrl(n, pred);
a61af66fc99e Initial load
duke
parents:
diff changeset
1555 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1556 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1557
a61af66fc99e Initial load
duke
parents:
diff changeset
1558 //------------------------------ proj_clone -------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1559 // Utility to create an if-projection
a61af66fc99e Initial load
duke
parents:
diff changeset
1560 ProjNode* PhaseIdealLoop::proj_clone(ProjNode* p, IfNode* iff) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1561 ProjNode* c = p->clone()->as_Proj();
a61af66fc99e Initial load
duke
parents:
diff changeset
1562 c->set_req(0, iff);
a61af66fc99e Initial load
duke
parents:
diff changeset
1563 return c;
a61af66fc99e Initial load
duke
parents:
diff changeset
1564 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1565
a61af66fc99e Initial load
duke
parents:
diff changeset
1566 //------------------------------ short_circuit_if -------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1567 // Force the iff control output to be the live_proj
a61af66fc99e Initial load
duke
parents:
diff changeset
1568 Node* PhaseIdealLoop::short_circuit_if(IfNode* iff, ProjNode* live_proj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1569 int proj_con = live_proj->_con;
a61af66fc99e Initial load
duke
parents:
diff changeset
1570 assert(proj_con == 0 || proj_con == 1, "false or true projection");
a61af66fc99e Initial load
duke
parents:
diff changeset
1571 Node *con = _igvn.intcon(proj_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
1572 set_ctrl(con, C->root());
a61af66fc99e Initial load
duke
parents:
diff changeset
1573 if (iff) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1574 iff->set_req(1, con);
a61af66fc99e Initial load
duke
parents:
diff changeset
1575 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1576 return con;
a61af66fc99e Initial load
duke
parents:
diff changeset
1577 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1578
a61af66fc99e Initial load
duke
parents:
diff changeset
1579 //------------------------------ insert_if_before_proj -------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1580 // Insert a new if before an if projection (* - new node)
a61af66fc99e Initial load
duke
parents:
diff changeset
1581 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1582 // before
a61af66fc99e Initial load
duke
parents:
diff changeset
1583 // if(test)
a61af66fc99e Initial load
duke
parents:
diff changeset
1584 // / \
a61af66fc99e Initial load
duke
parents:
diff changeset
1585 // v v
a61af66fc99e Initial load
duke
parents:
diff changeset
1586 // other-proj proj (arg)
a61af66fc99e Initial load
duke
parents:
diff changeset
1587 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1588 // after
a61af66fc99e Initial load
duke
parents:
diff changeset
1589 // if(test)
a61af66fc99e Initial load
duke
parents:
diff changeset
1590 // / \
a61af66fc99e Initial load
duke
parents:
diff changeset
1591 // / v
a61af66fc99e Initial load
duke
parents:
diff changeset
1592 // | * proj-clone
a61af66fc99e Initial load
duke
parents:
diff changeset
1593 // v |
a61af66fc99e Initial load
duke
parents:
diff changeset
1594 // other-proj v
a61af66fc99e Initial load
duke
parents:
diff changeset
1595 // * new_if(relop(cmp[IU](left,right)))
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 // / \
a61af66fc99e Initial load
duke
parents:
diff changeset
1597 // v v
a61af66fc99e Initial load
duke
parents:
diff changeset
1598 // * new-proj proj
a61af66fc99e Initial load
duke
parents:
diff changeset
1599 // (returned)
a61af66fc99e Initial load
duke
parents:
diff changeset
1600 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1601 ProjNode* PhaseIdealLoop::insert_if_before_proj(Node* left, bool Signed, BoolTest::mask relop, Node* right, ProjNode* proj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1602 IfNode* iff = proj->in(0)->as_If();
a61af66fc99e Initial load
duke
parents:
diff changeset
1603 IdealLoopTree *loop = get_loop(proj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1604 ProjNode *other_proj = iff->proj_out(!proj->is_IfTrue())->as_Proj();
a61af66fc99e Initial load
duke
parents:
diff changeset
1605 int ddepth = dom_depth(proj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1606
a61af66fc99e Initial load
duke
parents:
diff changeset
1607 _igvn.hash_delete(iff);
a61af66fc99e Initial load
duke
parents:
diff changeset
1608 _igvn._worklist.push(iff);
a61af66fc99e Initial load
duke
parents:
diff changeset
1609 _igvn.hash_delete(proj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1610 _igvn._worklist.push(proj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1611
a61af66fc99e Initial load
duke
parents:
diff changeset
1612 proj->set_req(0, NULL); // temporary disconnect
a61af66fc99e Initial load
duke
parents:
diff changeset
1613 ProjNode* proj2 = proj_clone(proj, iff);
a61af66fc99e Initial load
duke
parents:
diff changeset
1614 register_node(proj2, loop, iff, ddepth);
a61af66fc99e Initial load
duke
parents:
diff changeset
1615
a61af66fc99e Initial load
duke
parents:
diff changeset
1616 Node* cmp = Signed ? (Node*) new (C,3)CmpINode(left, right) : (Node*) new (C,3)CmpUNode(left, right);
a61af66fc99e Initial load
duke
parents:
diff changeset
1617 register_node(cmp, loop, proj2, ddepth);
a61af66fc99e Initial load
duke
parents:
diff changeset
1618
a61af66fc99e Initial load
duke
parents:
diff changeset
1619 BoolNode* bol = new (C,2)BoolNode(cmp, relop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1620 register_node(bol, loop, proj2, ddepth);
a61af66fc99e Initial load
duke
parents:
diff changeset
1621
a61af66fc99e Initial load
duke
parents:
diff changeset
1622 IfNode* new_if = new (C,2)IfNode(proj2, bol, iff->_prob, iff->_fcnt);
a61af66fc99e Initial load
duke
parents:
diff changeset
1623 register_node(new_if, loop, proj2, ddepth);
a61af66fc99e Initial load
duke
parents:
diff changeset
1624
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 proj->set_req(0, new_if); // reattach
a61af66fc99e Initial load
duke
parents:
diff changeset
1626 set_idom(proj, new_if, ddepth);
a61af66fc99e Initial load
duke
parents:
diff changeset
1627
a61af66fc99e Initial load
duke
parents:
diff changeset
1628 ProjNode* new_exit = proj_clone(other_proj, new_if)->as_Proj();
a61af66fc99e Initial load
duke
parents:
diff changeset
1629 register_node(new_exit, get_loop(other_proj), new_if, ddepth);
a61af66fc99e Initial load
duke
parents:
diff changeset
1630
a61af66fc99e Initial load
duke
parents:
diff changeset
1631 return new_exit;
a61af66fc99e Initial load
duke
parents:
diff changeset
1632 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1633
a61af66fc99e Initial load
duke
parents:
diff changeset
1634 //------------------------------ insert_region_before_proj -------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1635 // Insert a region before an if projection (* - new node)
a61af66fc99e Initial load
duke
parents:
diff changeset
1636 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1637 // before
a61af66fc99e Initial load
duke
parents:
diff changeset
1638 // if(test)
a61af66fc99e Initial load
duke
parents:
diff changeset
1639 // / |
a61af66fc99e Initial load
duke
parents:
diff changeset
1640 // v |
a61af66fc99e Initial load
duke
parents:
diff changeset
1641 // proj v
a61af66fc99e Initial load
duke
parents:
diff changeset
1642 // other-proj
a61af66fc99e Initial load
duke
parents:
diff changeset
1643 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1644 // after
a61af66fc99e Initial load
duke
parents:
diff changeset
1645 // if(test)
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 // / |
a61af66fc99e Initial load
duke
parents:
diff changeset
1647 // v |
a61af66fc99e Initial load
duke
parents:
diff changeset
1648 // * proj-clone v
a61af66fc99e Initial load
duke
parents:
diff changeset
1649 // | other-proj
a61af66fc99e Initial load
duke
parents:
diff changeset
1650 // v
a61af66fc99e Initial load
duke
parents:
diff changeset
1651 // * new-region
a61af66fc99e Initial load
duke
parents:
diff changeset
1652 // |
a61af66fc99e Initial load
duke
parents:
diff changeset
1653 // v
a61af66fc99e Initial load
duke
parents:
diff changeset
1654 // * dum_if
a61af66fc99e Initial load
duke
parents:
diff changeset
1655 // / \
a61af66fc99e Initial load
duke
parents:
diff changeset
1656 // v \
a61af66fc99e Initial load
duke
parents:
diff changeset
1657 // * dum-proj v
a61af66fc99e Initial load
duke
parents:
diff changeset
1658 // proj
a61af66fc99e Initial load
duke
parents:
diff changeset
1659 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1660 RegionNode* PhaseIdealLoop::insert_region_before_proj(ProjNode* proj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1661 IfNode* iff = proj->in(0)->as_If();
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 IdealLoopTree *loop = get_loop(proj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 ProjNode *other_proj = iff->proj_out(!proj->is_IfTrue())->as_Proj();
a61af66fc99e Initial load
duke
parents:
diff changeset
1664 int ddepth = dom_depth(proj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1665
a61af66fc99e Initial load
duke
parents:
diff changeset
1666 _igvn.hash_delete(iff);
a61af66fc99e Initial load
duke
parents:
diff changeset
1667 _igvn._worklist.push(iff);
a61af66fc99e Initial load
duke
parents:
diff changeset
1668 _igvn.hash_delete(proj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1669 _igvn._worklist.push(proj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1670
a61af66fc99e Initial load
duke
parents:
diff changeset
1671 proj->set_req(0, NULL); // temporary disconnect
a61af66fc99e Initial load
duke
parents:
diff changeset
1672 ProjNode* proj2 = proj_clone(proj, iff);
a61af66fc99e Initial load
duke
parents:
diff changeset
1673 register_node(proj2, loop, iff, ddepth);
a61af66fc99e Initial load
duke
parents:
diff changeset
1674
a61af66fc99e Initial load
duke
parents:
diff changeset
1675 RegionNode* reg = new (C,2)RegionNode(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1676 reg->set_req(1, proj2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1677 register_node(reg, loop, iff, ddepth);
a61af66fc99e Initial load
duke
parents:
diff changeset
1678
a61af66fc99e Initial load
duke
parents:
diff changeset
1679 IfNode* dum_if = new (C,2)IfNode(reg, short_circuit_if(NULL, proj), iff->_prob, iff->_fcnt);
a61af66fc99e Initial load
duke
parents:
diff changeset
1680 register_node(dum_if, loop, reg, ddepth);
a61af66fc99e Initial load
duke
parents:
diff changeset
1681
a61af66fc99e Initial load
duke
parents:
diff changeset
1682 proj->set_req(0, dum_if); // reattach
a61af66fc99e Initial load
duke
parents:
diff changeset
1683 set_idom(proj, dum_if, ddepth);
a61af66fc99e Initial load
duke
parents:
diff changeset
1684
a61af66fc99e Initial load
duke
parents:
diff changeset
1685 ProjNode* dum_proj = proj_clone(other_proj, dum_if);
a61af66fc99e Initial load
duke
parents:
diff changeset
1686 register_node(dum_proj, loop, dum_if, ddepth);
a61af66fc99e Initial load
duke
parents:
diff changeset
1687
a61af66fc99e Initial load
duke
parents:
diff changeset
1688 return reg;
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1690
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 //------------------------------ insert_cmpi_loop_exit -------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1692 // Clone a signed compare loop exit from an unsigned compare and
a61af66fc99e Initial load
duke
parents:
diff changeset
1693 // insert it before the unsigned cmp on the stay-in-loop path.
a61af66fc99e Initial load
duke
parents:
diff changeset
1694 // All new nodes inserted in the dominator tree between the original
a61af66fc99e Initial load
duke
parents:
diff changeset
1695 // if and it's projections. The original if test is replaced with
a61af66fc99e Initial load
duke
parents:
diff changeset
1696 // a constant to force the stay-in-loop path.
a61af66fc99e Initial load
duke
parents:
diff changeset
1697 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1698 // This is done to make sure that the original if and it's projections
a61af66fc99e Initial load
duke
parents:
diff changeset
1699 // still dominate the same set of control nodes, that the ctrl() relation
a61af66fc99e Initial load
duke
parents:
diff changeset
1700 // from data nodes to them is preserved, and that their loop nesting is
a61af66fc99e Initial load
duke
parents:
diff changeset
1701 // preserved.
a61af66fc99e Initial load
duke
parents:
diff changeset
1702 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1703 // before
a61af66fc99e Initial load
duke
parents:
diff changeset
1704 // if(i <u limit) unsigned compare loop exit
a61af66fc99e Initial load
duke
parents:
diff changeset
1705 // / |
a61af66fc99e Initial load
duke
parents:
diff changeset
1706 // v v
a61af66fc99e Initial load
duke
parents:
diff changeset
1707 // exit-proj stay-in-loop-proj
a61af66fc99e Initial load
duke
parents:
diff changeset
1708 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1709 // after
a61af66fc99e Initial load
duke
parents:
diff changeset
1710 // if(stay-in-loop-const) original if
a61af66fc99e Initial load
duke
parents:
diff changeset
1711 // / |
a61af66fc99e Initial load
duke
parents:
diff changeset
1712 // / v
a61af66fc99e Initial load
duke
parents:
diff changeset
1713 // / if(i < limit) new signed test
a61af66fc99e Initial load
duke
parents:
diff changeset
1714 // / / |
a61af66fc99e Initial load
duke
parents:
diff changeset
1715 // / / v
a61af66fc99e Initial load
duke
parents:
diff changeset
1716 // / / if(i <u limit) new cloned unsigned test
a61af66fc99e Initial load
duke
parents:
diff changeset
1717 // / / / |
a61af66fc99e Initial load
duke
parents:
diff changeset
1718 // v v v |
a61af66fc99e Initial load
duke
parents:
diff changeset
1719 // region |
a61af66fc99e Initial load
duke
parents:
diff changeset
1720 // | |
a61af66fc99e Initial load
duke
parents:
diff changeset
1721 // dum-if |
a61af66fc99e Initial load
duke
parents:
diff changeset
1722 // / | |
a61af66fc99e Initial load
duke
parents:
diff changeset
1723 // ether | |
a61af66fc99e Initial load
duke
parents:
diff changeset
1724 // v v
a61af66fc99e Initial load
duke
parents:
diff changeset
1725 // exit-proj stay-in-loop-proj
a61af66fc99e Initial load
duke
parents:
diff changeset
1726 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1727 IfNode* PhaseIdealLoop::insert_cmpi_loop_exit(IfNode* if_cmpu, IdealLoopTree *loop) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1728 const bool Signed = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1729 const bool Unsigned = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1730
a61af66fc99e Initial load
duke
parents:
diff changeset
1731 BoolNode* bol = if_cmpu->in(1)->as_Bool();
a61af66fc99e Initial load
duke
parents:
diff changeset
1732 if (bol->_test._test != BoolTest::lt) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1733 CmpNode* cmpu = bol->in(1)->as_Cmp();
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 if (cmpu->Opcode() != Op_CmpU) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1735 int stride = stride_of_possible_iv(if_cmpu);
a61af66fc99e Initial load
duke
parents:
diff changeset
1736 if (stride == 0) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1737
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 ProjNode* lp_continue = stay_in_loop(if_cmpu, loop)->as_Proj();
a61af66fc99e Initial load
duke
parents:
diff changeset
1739 ProjNode* lp_exit = if_cmpu->proj_out(!lp_continue->is_IfTrue())->as_Proj();
a61af66fc99e Initial load
duke
parents:
diff changeset
1740
a61af66fc99e Initial load
duke
parents:
diff changeset
1741 Node* limit = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1742 if (stride > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1743 limit = cmpu->in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1744 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1745 limit = _igvn.makecon(TypeInt::ZERO);
a61af66fc99e Initial load
duke
parents:
diff changeset
1746 set_ctrl(limit, C->root());
a61af66fc99e Initial load
duke
parents:
diff changeset
1747 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1748 // Create a new region on the exit path
a61af66fc99e Initial load
duke
parents:
diff changeset
1749 RegionNode* reg = insert_region_before_proj(lp_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1750
a61af66fc99e Initial load
duke
parents:
diff changeset
1751 // Clone the if-cmpu-true-false using a signed compare
a61af66fc99e Initial load
duke
parents:
diff changeset
1752 BoolTest::mask rel_i = stride > 0 ? bol->_test._test : BoolTest::ge;
a61af66fc99e Initial load
duke
parents:
diff changeset
1753 ProjNode* cmpi_exit = insert_if_before_proj(cmpu->in(1), Signed, rel_i, limit, lp_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1754 reg->add_req(cmpi_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1755
a61af66fc99e Initial load
duke
parents:
diff changeset
1756 // Clone the if-cmpu-true-false
a61af66fc99e Initial load
duke
parents:
diff changeset
1757 BoolTest::mask rel_u = bol->_test._test;
a61af66fc99e Initial load
duke
parents:
diff changeset
1758 ProjNode* cmpu_exit = insert_if_before_proj(cmpu->in(1), Unsigned, rel_u, cmpu->in(2), lp_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1759 reg->add_req(cmpu_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1760
a61af66fc99e Initial load
duke
parents:
diff changeset
1761 // Force original if to stay in loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
1762 short_circuit_if(if_cmpu, lp_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1763
a61af66fc99e Initial load
duke
parents:
diff changeset
1764 return cmpi_exit->in(0)->as_If();
a61af66fc99e Initial load
duke
parents:
diff changeset
1765 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1766
a61af66fc99e Initial load
duke
parents:
diff changeset
1767 //------------------------------ remove_cmpi_loop_exit -------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1768 // Remove a previously inserted signed compare loop exit.
a61af66fc99e Initial load
duke
parents:
diff changeset
1769 void PhaseIdealLoop::remove_cmpi_loop_exit(IfNode* if_cmp, IdealLoopTree *loop) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1770 Node* lp_proj = stay_in_loop(if_cmp, loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1771 assert(if_cmp->in(1)->in(1)->Opcode() == Op_CmpI &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1772 stay_in_loop(lp_proj, loop)->is_If() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1773 stay_in_loop(lp_proj, loop)->in(1)->in(1)->Opcode() == Op_CmpU, "inserted cmpi before cmpu");
a61af66fc99e Initial load
duke
parents:
diff changeset
1774 Node *con = _igvn.makecon(lp_proj->is_IfTrue() ? TypeInt::ONE : TypeInt::ZERO);
a61af66fc99e Initial load
duke
parents:
diff changeset
1775 set_ctrl(con, C->root());
a61af66fc99e Initial load
duke
parents:
diff changeset
1776 if_cmp->set_req(1, con);
a61af66fc99e Initial load
duke
parents:
diff changeset
1777 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1778
a61af66fc99e Initial load
duke
parents:
diff changeset
1779 //------------------------------ scheduled_nodelist -------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1780 // Create a post order schedule of nodes that are in the
a61af66fc99e Initial load
duke
parents:
diff changeset
1781 // "member" set. The list is returned in "sched".
a61af66fc99e Initial load
duke
parents:
diff changeset
1782 // The first node in "sched" is the loop head, followed by
a61af66fc99e Initial load
duke
parents:
diff changeset
1783 // nodes which have no inputs in the "member" set, and then
a61af66fc99e Initial load
duke
parents:
diff changeset
1784 // followed by the nodes that have an immediate input dependence
a61af66fc99e Initial load
duke
parents:
diff changeset
1785 // on a node in "sched".
a61af66fc99e Initial load
duke
parents:
diff changeset
1786 void PhaseIdealLoop::scheduled_nodelist( IdealLoopTree *loop, VectorSet& member, Node_List &sched ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1787
a61af66fc99e Initial load
duke
parents:
diff changeset
1788 assert(member.test(loop->_head->_idx), "loop head must be in member set");
a61af66fc99e Initial load
duke
parents:
diff changeset
1789 Arena *a = Thread::current()->resource_area();
a61af66fc99e Initial load
duke
parents:
diff changeset
1790 VectorSet visited(a);
a61af66fc99e Initial load
duke
parents:
diff changeset
1791 Node_Stack nstack(a, loop->_body.size());
a61af66fc99e Initial load
duke
parents:
diff changeset
1792
a61af66fc99e Initial load
duke
parents:
diff changeset
1793 Node* n = loop->_head; // top of stack is cached in "n"
a61af66fc99e Initial load
duke
parents:
diff changeset
1794 uint idx = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1795 visited.set(n->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1796
a61af66fc99e Initial load
duke
parents:
diff changeset
1797 // Initially push all with no inputs from within member set
a61af66fc99e Initial load
duke
parents:
diff changeset
1798 for(uint i = 0; i < loop->_body.size(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1799 Node *elt = loop->_body.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 if (member.test(elt->_idx)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1801 bool found = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1802 for (uint j = 0; j < elt->req(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1803 Node* def = elt->in(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
1804 if (def && member.test(def->_idx) && def != elt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1805 found = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1806 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1807 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1808 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1809 if (!found && elt != loop->_head) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1810 nstack.push(n, idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1811 n = elt;
a61af66fc99e Initial load
duke
parents:
diff changeset
1812 assert(!visited.test(n->_idx), "not seen yet");
a61af66fc99e Initial load
duke
parents:
diff changeset
1813 visited.set(n->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1814 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1815 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1816 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1817
a61af66fc99e Initial load
duke
parents:
diff changeset
1818 // traverse out's that are in the member set
a61af66fc99e Initial load
duke
parents:
diff changeset
1819 while (true) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1820 if (idx < n->outcnt()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1821 Node* use = n->raw_out(idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1822 idx++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1823 if (!visited.test_set(use->_idx)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1824 if (member.test(use->_idx)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1825 nstack.push(n, idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1826 n = use;
a61af66fc99e Initial load
duke
parents:
diff changeset
1827 idx = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1828 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1829 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1830 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1831 // All outputs processed
a61af66fc99e Initial load
duke
parents:
diff changeset
1832 sched.push(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1833 if (nstack.is_empty()) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1834 n = nstack.node();
a61af66fc99e Initial load
duke
parents:
diff changeset
1835 idx = nstack.index();
a61af66fc99e Initial load
duke
parents:
diff changeset
1836 nstack.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1837 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1838 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1839 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1840
a61af66fc99e Initial load
duke
parents:
diff changeset
1841
a61af66fc99e Initial load
duke
parents:
diff changeset
1842 //------------------------------ has_use_in_set -------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1843 // Has a use in the vector set
a61af66fc99e Initial load
duke
parents:
diff changeset
1844 bool PhaseIdealLoop::has_use_in_set( Node* n, VectorSet& vset ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1845 for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1846 Node* use = n->fast_out(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
1847 if (vset.test(use->_idx)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1848 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1849 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1850 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1851 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1852 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1853
a61af66fc99e Initial load
duke
parents:
diff changeset
1854
a61af66fc99e Initial load
duke
parents:
diff changeset
1855 //------------------------------ has_use_internal_to_set -------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1856 // Has use internal to the vector set (ie. not in a phi at the loop head)
a61af66fc99e Initial load
duke
parents:
diff changeset
1857 bool PhaseIdealLoop::has_use_internal_to_set( Node* n, VectorSet& vset, IdealLoopTree *loop ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1858 Node* head = loop->_head;
a61af66fc99e Initial load
duke
parents:
diff changeset
1859 for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1860 Node* use = n->fast_out(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
1861 if (vset.test(use->_idx) && !(use->is_Phi() && use->in(0) == head)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1862 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1863 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1864 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1865 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1866 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1867
a61af66fc99e Initial load
duke
parents:
diff changeset
1868
a61af66fc99e Initial load
duke
parents:
diff changeset
1869 //------------------------------ clone_for_use_outside_loop -------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1870 // clone "n" for uses that are outside of loop
a61af66fc99e Initial load
duke
parents:
diff changeset
1871 void PhaseIdealLoop::clone_for_use_outside_loop( IdealLoopTree *loop, Node* n, Node_List& worklist ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1872
a61af66fc99e Initial load
duke
parents:
diff changeset
1873 assert(worklist.size() == 0, "should be empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
1874 for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1875 Node* use = n->fast_out(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
1876 if( !loop->is_member(get_loop(has_ctrl(use) ? get_ctrl(use) : use)) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1877 worklist.push(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
1878 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1879 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1880 while( worklist.size() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1881 Node *use = worklist.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1882 if (!has_node(use) || use->in(0) == C->top()) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1883 uint j;
a61af66fc99e Initial load
duke
parents:
diff changeset
1884 for (j = 0; j < use->req(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1885 if (use->in(j) == n) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1886 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1887 assert(j < use->req(), "must be there");
a61af66fc99e Initial load
duke
parents:
diff changeset
1888
a61af66fc99e Initial load
duke
parents:
diff changeset
1889 // clone "n" and insert it between the inputs of "n" and the use outside the loop
a61af66fc99e Initial load
duke
parents:
diff changeset
1890 Node* n_clone = n->clone();
a61af66fc99e Initial load
duke
parents:
diff changeset
1891 _igvn.hash_delete(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
1892 use->set_req(j, n_clone);
a61af66fc99e Initial load
duke
parents:
diff changeset
1893 _igvn._worklist.push(use);
251
020a0b730379 6700047: C2 failed in idom_no_update
never
parents: 235
diff changeset
1894 Node* use_c;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1895 if (!use->is_Phi()) {
251
020a0b730379 6700047: C2 failed in idom_no_update
never
parents: 235
diff changeset
1896 use_c = has_ctrl(use) ? get_ctrl(use) : use->in(0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1897 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1898 // Use in a phi is considered a use in the associated predecessor block
251
020a0b730379 6700047: C2 failed in idom_no_update
never
parents: 235
diff changeset
1899 use_c = use->in(0)->in(j);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1900 }
251
020a0b730379 6700047: C2 failed in idom_no_update
never
parents: 235
diff changeset
1901 set_ctrl(n_clone, use_c);
020a0b730379 6700047: C2 failed in idom_no_update
never
parents: 235
diff changeset
1902 assert(!loop->is_member(get_loop(use_c)), "should be outside loop");
020a0b730379 6700047: C2 failed in idom_no_update
never
parents: 235
diff changeset
1903 get_loop(use_c)->_body.push(n_clone);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1904 _igvn.register_new_node_with_optimizer(n_clone);
a61af66fc99e Initial load
duke
parents:
diff changeset
1905 #if !defined(PRODUCT)
a61af66fc99e Initial load
duke
parents:
diff changeset
1906 if (TracePartialPeeling) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1907 tty->print_cr("loop exit cloning old: %d new: %d newbb: %d", n->_idx, n_clone->_idx, get_ctrl(n_clone)->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1908 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1911 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1912
a61af66fc99e Initial load
duke
parents:
diff changeset
1913
a61af66fc99e Initial load
duke
parents:
diff changeset
1914 //------------------------------ clone_for_special_use_inside_loop -------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1915 // clone "n" for special uses that are in the not_peeled region.
a61af66fc99e Initial load
duke
parents:
diff changeset
1916 // If these def-uses occur in separate blocks, the code generator
a61af66fc99e Initial load
duke
parents:
diff changeset
1917 // marks the method as not compilable. For example, if a "BoolNode"
a61af66fc99e Initial load
duke
parents:
diff changeset
1918 // is in a different basic block than the "IfNode" that uses it, then
a61af66fc99e Initial load
duke
parents:
diff changeset
1919 // the compilation is aborted in the code generator.
a61af66fc99e Initial load
duke
parents:
diff changeset
1920 void PhaseIdealLoop::clone_for_special_use_inside_loop( IdealLoopTree *loop, Node* n,
a61af66fc99e Initial load
duke
parents:
diff changeset
1921 VectorSet& not_peel, Node_List& sink_list, Node_List& worklist ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1922 if (n->is_Phi() || n->is_Load()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1923 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1924 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1925 assert(worklist.size() == 0, "should be empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
1926 for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1927 Node* use = n->fast_out(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
1928 if ( not_peel.test(use->_idx) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1929 (use->is_If() || use->is_CMove() || use->is_Bool()) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1930 use->in(1) == n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1931 worklist.push(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
1932 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1933 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1934 if (worklist.size() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1935 // clone "n" and insert it between inputs of "n" and the use
a61af66fc99e Initial load
duke
parents:
diff changeset
1936 Node* n_clone = n->clone();
a61af66fc99e Initial load
duke
parents:
diff changeset
1937 loop->_body.push(n_clone);
a61af66fc99e Initial load
duke
parents:
diff changeset
1938 _igvn.register_new_node_with_optimizer(n_clone);
a61af66fc99e Initial load
duke
parents:
diff changeset
1939 set_ctrl(n_clone, get_ctrl(n));
a61af66fc99e Initial load
duke
parents:
diff changeset
1940 sink_list.push(n_clone);
a61af66fc99e Initial load
duke
parents:
diff changeset
1941 not_peel <<= n_clone->_idx; // add n_clone to not_peel set.
a61af66fc99e Initial load
duke
parents:
diff changeset
1942 #if !defined(PRODUCT)
a61af66fc99e Initial load
duke
parents:
diff changeset
1943 if (TracePartialPeeling) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1944 tty->print_cr("special not_peeled cloning old: %d new: %d", n->_idx, n_clone->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1945 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1946 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1947 while( worklist.size() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1948 Node *use = worklist.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1949 _igvn.hash_delete(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
1950 _igvn._worklist.push(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
1951 for (uint j = 1; j < use->req(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1952 if (use->in(j) == n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1953 use->set_req(j, n_clone);
a61af66fc99e Initial load
duke
parents:
diff changeset
1954 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1955 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1956 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1957 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1958 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1959
a61af66fc99e Initial load
duke
parents:
diff changeset
1960
a61af66fc99e Initial load
duke
parents:
diff changeset
1961 //------------------------------ insert_phi_for_loop -------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1962 // 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
1963 void PhaseIdealLoop::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
1964 Node *phi = PhiNode::make(lp, back_edge_val);
a61af66fc99e Initial load
duke
parents:
diff changeset
1965 phi->set_req(LoopNode::EntryControl, lp_entry_val);
a61af66fc99e Initial load
duke
parents:
diff changeset
1966 // Use existing phi if it already exists
a61af66fc99e Initial load
duke
parents:
diff changeset
1967 Node *hit = _igvn.hash_find_insert(phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
1968 if( hit == NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1969 _igvn.register_new_node_with_optimizer(phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
1970 set_ctrl(phi, lp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1971 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1972 // Remove the new phi from the graph and use the hit
a61af66fc99e Initial load
duke
parents:
diff changeset
1973 _igvn.remove_dead_node(phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
1974 phi = hit;
a61af66fc99e Initial load
duke
parents:
diff changeset
1975 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1976 _igvn.hash_delete(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
1977 _igvn._worklist.push(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
1978 use->set_req(idx, phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
1979 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1980
a61af66fc99e Initial load
duke
parents:
diff changeset
1981 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1982 //------------------------------ is_valid_loop_partition -------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1983 // Validate the loop partition sets: peel and not_peel
a61af66fc99e Initial load
duke
parents:
diff changeset
1984 bool PhaseIdealLoop::is_valid_loop_partition( IdealLoopTree *loop, VectorSet& peel, Node_List& peel_list,
a61af66fc99e Initial load
duke
parents:
diff changeset
1985 VectorSet& not_peel ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1986 uint i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1987 // Check that peel_list entries are in the peel set
a61af66fc99e Initial load
duke
parents:
diff changeset
1988 for (i = 0; i < peel_list.size(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1989 if (!peel.test(peel_list.at(i)->_idx)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1990 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1991 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1992 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1993 // Check at loop members are in one of peel set or not_peel set
a61af66fc99e Initial load
duke
parents:
diff changeset
1994 for (i = 0; i < loop->_body.size(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1995 Node *def = loop->_body.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1996 uint di = def->_idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
1997 // Check that peel set elements are in peel_list
a61af66fc99e Initial load
duke
parents:
diff changeset
1998 if (peel.test(di)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1999 if (not_peel.test(di)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2000 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2001 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2002 // Must be in peel_list also
a61af66fc99e Initial load
duke
parents:
diff changeset
2003 bool found = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2004 for (uint j = 0; j < peel_list.size(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2005 if (peel_list.at(j)->_idx == di) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2006 found = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2007 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2008 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2009 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2010 if (!found) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2011 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2012 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2013 } else if (not_peel.test(di)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2014 if (peel.test(di)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2015 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2016 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2017 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2018 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2019 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2020 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2021 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2022 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2023
a61af66fc99e Initial load
duke
parents:
diff changeset
2024 //------------------------------ is_valid_clone_loop_exit_use -------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2025 // Ensure a use outside of loop is of the right form
a61af66fc99e Initial load
duke
parents:
diff changeset
2026 bool PhaseIdealLoop::is_valid_clone_loop_exit_use( IdealLoopTree *loop, Node* use, uint exit_idx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2027 Node *use_c = has_ctrl(use) ? get_ctrl(use) : use;
a61af66fc99e Initial load
duke
parents:
diff changeset
2028 return (use->is_Phi() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2029 use_c->is_Region() && use_c->req() == 3 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2030 (use_c->in(exit_idx)->Opcode() == Op_IfTrue ||
a61af66fc99e Initial load
duke
parents:
diff changeset
2031 use_c->in(exit_idx)->Opcode() == Op_IfFalse ||
a61af66fc99e Initial load
duke
parents:
diff changeset
2032 use_c->in(exit_idx)->Opcode() == Op_JumpProj) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2033 loop->is_member( get_loop( use_c->in(exit_idx)->in(0) ) ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
2034 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2035
a61af66fc99e Initial load
duke
parents:
diff changeset
2036 //------------------------------ is_valid_clone_loop_form -------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2037 // Ensure that all uses outside of loop are of the right form
a61af66fc99e Initial load
duke
parents:
diff changeset
2038 bool PhaseIdealLoop::is_valid_clone_loop_form( IdealLoopTree *loop, Node_List& peel_list,
a61af66fc99e Initial load
duke
parents:
diff changeset
2039 uint orig_exit_idx, uint clone_exit_idx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2040 uint len = peel_list.size();
a61af66fc99e Initial load
duke
parents:
diff changeset
2041 for (uint i = 0; i < len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2042 Node *def = peel_list.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2043
a61af66fc99e Initial load
duke
parents:
diff changeset
2044 for (DUIterator_Fast jmax, j = def->fast_outs(jmax); j < jmax; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2045 Node *use = def->fast_out(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
2046 Node *use_c = has_ctrl(use) ? get_ctrl(use) : use;
a61af66fc99e Initial load
duke
parents:
diff changeset
2047 if (!loop->is_member(get_loop(use_c))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2048 // use is not in the loop, check for correct structure
a61af66fc99e Initial load
duke
parents:
diff changeset
2049 if (use->in(0) == def) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2050 // Okay
a61af66fc99e Initial load
duke
parents:
diff changeset
2051 } else if (!is_valid_clone_loop_exit_use(loop, use, orig_exit_idx)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2052 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2053 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2054 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2055 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2056 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2057 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2058 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2059 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2060
a61af66fc99e Initial load
duke
parents:
diff changeset
2061 //------------------------------ partial_peel -------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2062 // Partially peel (aka loop rotation) the top portion of a loop (called
a61af66fc99e Initial load
duke
parents:
diff changeset
2063 // the peel section below) by cloning it and placing one copy just before
a61af66fc99e Initial load
duke
parents:
diff changeset
2064 // the new loop head and the other copy at the bottom of the new loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
2065 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2066 // before after where it came from
a61af66fc99e Initial load
duke
parents:
diff changeset
2067 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2068 // stmt1 stmt1
a61af66fc99e Initial load
duke
parents:
diff changeset
2069 // loop: stmt2 clone
a61af66fc99e Initial load
duke
parents:
diff changeset
2070 // stmt2 if condA goto exitA clone
a61af66fc99e Initial load
duke
parents:
diff changeset
2071 // if condA goto exitA new_loop: new
a61af66fc99e Initial load
duke
parents:
diff changeset
2072 // stmt3 stmt3 clone
a61af66fc99e Initial load
duke
parents:
diff changeset
2073 // if !condB goto loop if condB goto exitB clone
a61af66fc99e Initial load
duke
parents:
diff changeset
2074 // exitB: stmt2 orig
a61af66fc99e Initial load
duke
parents:
diff changeset
2075 // stmt4 if !condA goto new_loop orig
a61af66fc99e Initial load
duke
parents:
diff changeset
2076 // exitA: goto exitA
a61af66fc99e Initial load
duke
parents:
diff changeset
2077 // exitB:
a61af66fc99e Initial load
duke
parents:
diff changeset
2078 // stmt4
a61af66fc99e Initial load
duke
parents:
diff changeset
2079 // exitA:
a61af66fc99e Initial load
duke
parents:
diff changeset
2080 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2081 // Step 1: find the cut point: an exit test on probable
a61af66fc99e Initial load
duke
parents:
diff changeset
2082 // induction variable.
a61af66fc99e Initial load
duke
parents:
diff changeset
2083 // Step 2: schedule (with cloning) operations in the peel
a61af66fc99e Initial load
duke
parents:
diff changeset
2084 // section that can be executed after the cut into
a61af66fc99e Initial load
duke
parents:
diff changeset
2085 // the section that is not peeled. This may need
a61af66fc99e Initial load
duke
parents:
diff changeset
2086 // to clone operations into exit blocks. For
a61af66fc99e Initial load
duke
parents:
diff changeset
2087 // instance, a reference to A[i] in the not-peel
a61af66fc99e Initial load
duke
parents:
diff changeset
2088 // section and a reference to B[i] in an exit block
a61af66fc99e Initial load
duke
parents:
diff changeset
2089 // may cause a left-shift of i by 2 to be placed
a61af66fc99e Initial load
duke
parents:
diff changeset
2090 // in the peel block. This step will clone the left
a61af66fc99e Initial load
duke
parents:
diff changeset
2091 // shift into the exit block and sink the left shift
a61af66fc99e Initial load
duke
parents:
diff changeset
2092 // from the peel to the not-peel section.
a61af66fc99e Initial load
duke
parents:
diff changeset
2093 // Step 3: clone the loop, retarget the control, and insert
a61af66fc99e Initial load
duke
parents:
diff changeset
2094 // phis for values that are live across the new loop
a61af66fc99e Initial load
duke
parents:
diff changeset
2095 // head. This is very dependent on the graph structure
a61af66fc99e Initial load
duke
parents:
diff changeset
2096 // from clone_loop. It creates region nodes for
a61af66fc99e Initial load
duke
parents:
diff changeset
2097 // exit control and associated phi nodes for values
a61af66fc99e Initial load
duke
parents:
diff changeset
2098 // flow out of the loop through that exit. The region
a61af66fc99e Initial load
duke
parents:
diff changeset
2099 // node is dominated by the clone's control projection.
a61af66fc99e Initial load
duke
parents:
diff changeset
2100 // So the clone's peel section is placed before the
a61af66fc99e Initial load
duke
parents:
diff changeset
2101 // new loop head, and the clone's not-peel section is
a61af66fc99e Initial load
duke
parents:
diff changeset
2102 // forms the top part of the new loop. The original
a61af66fc99e Initial load
duke
parents:
diff changeset
2103 // peel section forms the tail of the new loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
2104 // Step 4: update the dominator tree and recompute the
a61af66fc99e Initial load
duke
parents:
diff changeset
2105 // dominator depth.
a61af66fc99e Initial load
duke
parents:
diff changeset
2106 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2107 // orig
a61af66fc99e Initial load
duke
parents:
diff changeset
2108 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2109 // stmt1
a61af66fc99e Initial load
duke
parents:
diff changeset
2110 // |
a61af66fc99e Initial load
duke
parents:
diff changeset
2111 // v
a61af66fc99e Initial load
duke
parents:
diff changeset
2112 // loop<----+
a61af66fc99e Initial load
duke
parents:
diff changeset
2113 // | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2114 // stmt2 |
a61af66fc99e Initial load
duke
parents:
diff changeset
2115 // | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2116 // v |
a61af66fc99e Initial load
duke
parents:
diff changeset
2117 // ifA |
a61af66fc99e Initial load
duke
parents:
diff changeset
2118 // / | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2119 // v v |
a61af66fc99e Initial load
duke
parents:
diff changeset
2120 // false true ^ <-- last_peel
a61af66fc99e Initial load
duke
parents:
diff changeset
2121 // / | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2122 // / ===|==cut |
a61af66fc99e Initial load
duke
parents:
diff changeset
2123 // / stmt3 | <-- first_not_peel
a61af66fc99e Initial load
duke
parents:
diff changeset
2124 // / | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2125 // | v |
a61af66fc99e Initial load
duke
parents:
diff changeset
2126 // v ifB |
a61af66fc99e Initial load
duke
parents:
diff changeset
2127 // exitA: / \ |
a61af66fc99e Initial load
duke
parents:
diff changeset
2128 // / \ |
a61af66fc99e Initial load
duke
parents:
diff changeset
2129 // v v |
a61af66fc99e Initial load
duke
parents:
diff changeset
2130 // false true |
a61af66fc99e Initial load
duke
parents:
diff changeset
2131 // / \ |
a61af66fc99e Initial load
duke
parents:
diff changeset
2132 // / ----+
a61af66fc99e Initial load
duke
parents:
diff changeset
2133 // |
a61af66fc99e Initial load
duke
parents:
diff changeset
2134 // v
a61af66fc99e Initial load
duke
parents:
diff changeset
2135 // exitB:
a61af66fc99e Initial load
duke
parents:
diff changeset
2136 // stmt4
a61af66fc99e Initial load
duke
parents:
diff changeset
2137 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2138 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2139 // after clone loop
a61af66fc99e Initial load
duke
parents:
diff changeset
2140 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2141 // stmt1
a61af66fc99e Initial load
duke
parents:
diff changeset
2142 // / \
a61af66fc99e Initial load
duke
parents:
diff changeset
2143 // clone / \ orig
a61af66fc99e Initial load
duke
parents:
diff changeset
2144 // / \
a61af66fc99e Initial load
duke
parents:
diff changeset
2145 // / \
a61af66fc99e Initial load
duke
parents:
diff changeset
2146 // v v
a61af66fc99e Initial load
duke
parents:
diff changeset
2147 // +---->loop loop<----+
a61af66fc99e Initial load
duke
parents:
diff changeset
2148 // | | | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2149 // | stmt2 stmt2 |
a61af66fc99e Initial load
duke
parents:
diff changeset
2150 // | | | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2151 // | v v |
a61af66fc99e Initial load
duke
parents:
diff changeset
2152 // | ifA ifA |
a61af66fc99e Initial load
duke
parents:
diff changeset
2153 // | | \ / | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2154 // | v v v v |
a61af66fc99e Initial load
duke
parents:
diff changeset
2155 // ^ true false false true ^ <-- last_peel
a61af66fc99e Initial load
duke
parents:
diff changeset
2156 // | | ^ \ / | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2157 // | cut==|== \ \ / ===|==cut |
a61af66fc99e Initial load
duke
parents:
diff changeset
2158 // | stmt3 \ \ / stmt3 | <-- first_not_peel
a61af66fc99e Initial load
duke
parents:
diff changeset
2159 // | | dom | | | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2160 // | v \ 1v v2 v |
a61af66fc99e Initial load
duke
parents:
diff changeset
2161 // | ifB regionA ifB |
a61af66fc99e Initial load
duke
parents:
diff changeset
2162 // | / \ | / \ |
a61af66fc99e Initial load
duke
parents:
diff changeset
2163 // | / \ v / \ |
a61af66fc99e Initial load
duke
parents:
diff changeset
2164 // | v v exitA: v v |
a61af66fc99e Initial load
duke
parents:
diff changeset
2165 // | true false false true |
a61af66fc99e Initial load
duke
parents:
diff changeset
2166 // | / ^ \ / \ |
a61af66fc99e Initial load
duke
parents:
diff changeset
2167 // +---- \ \ / ----+
a61af66fc99e Initial load
duke
parents:
diff changeset
2168 // dom \ /
a61af66fc99e Initial load
duke
parents:
diff changeset
2169 // \ 1v v2
a61af66fc99e Initial load
duke
parents:
diff changeset
2170 // regionB
a61af66fc99e Initial load
duke
parents:
diff changeset
2171 // |
a61af66fc99e Initial load
duke
parents:
diff changeset
2172 // v
a61af66fc99e Initial load
duke
parents:
diff changeset
2173 // exitB:
a61af66fc99e Initial load
duke
parents:
diff changeset
2174 // stmt4
a61af66fc99e Initial load
duke
parents:
diff changeset
2175 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2176 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2177 // after partial peel
a61af66fc99e Initial load
duke
parents:
diff changeset
2178 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2179 // stmt1
a61af66fc99e Initial load
duke
parents:
diff changeset
2180 // /
a61af66fc99e Initial load
duke
parents:
diff changeset
2181 // clone / orig
a61af66fc99e Initial load
duke
parents:
diff changeset
2182 // / TOP
a61af66fc99e Initial load
duke
parents:
diff changeset
2183 // / \
a61af66fc99e Initial load
duke
parents:
diff changeset
2184 // v v
a61af66fc99e Initial load
duke
parents:
diff changeset
2185 // TOP->region region----+
a61af66fc99e Initial load
duke
parents:
diff changeset
2186 // | | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2187 // stmt2 stmt2 |
a61af66fc99e Initial load
duke
parents:
diff changeset
2188 // | | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2189 // v v |
a61af66fc99e Initial load
duke
parents:
diff changeset
2190 // ifA ifA |
a61af66fc99e Initial load
duke
parents:
diff changeset
2191 // | \ / | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2192 // v v v v |
a61af66fc99e Initial load
duke
parents:
diff changeset
2193 // true false false true | <-- last_peel
a61af66fc99e Initial load
duke
parents:
diff changeset
2194 // | ^ \ / +------|---+
a61af66fc99e Initial load
duke
parents:
diff changeset
2195 // +->newloop \ \ / === ==cut | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2196 // | stmt3 \ \ / TOP | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2197 // | | dom | | stmt3 | | <-- first_not_peel
a61af66fc99e Initial load
duke
parents:
diff changeset
2198 // | v \ 1v v2 v | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2199 // | ifB regionA ifB ^ v
a61af66fc99e Initial load
duke
parents:
diff changeset
2200 // | / \ | / \ | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2201 // | / \ v / \ | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2202 // | v v exitA: v v | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2203 // | true false false true | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2204 // | / ^ \ / \ | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2205 // | | \ \ / v | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2206 // | | dom \ / TOP | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2207 // | | \ 1v v2 | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2208 // ^ v regionB | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2209 // | | | | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2210 // | | v ^ v
a61af66fc99e Initial load
duke
parents:
diff changeset
2211 // | | exitB: | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2212 // | | stmt4 | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2213 // | +------------>-----------------+ |
a61af66fc99e Initial load
duke
parents:
diff changeset
2214 // | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2215 // +-----------------<---------------------+
a61af66fc99e Initial load
duke
parents:
diff changeset
2216 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2217 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2218 // final graph
a61af66fc99e Initial load
duke
parents:
diff changeset
2219 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2220 // stmt1
a61af66fc99e Initial load
duke
parents:
diff changeset
2221 // |
a61af66fc99e Initial load
duke
parents:
diff changeset
2222 // v
a61af66fc99e Initial load
duke
parents:
diff changeset
2223 // ........> ifA clone
a61af66fc99e Initial load
duke
parents:
diff changeset
2224 // : / |
a61af66fc99e Initial load
duke
parents:
diff changeset
2225 // dom / |
a61af66fc99e Initial load
duke
parents:
diff changeset
2226 // : v v
a61af66fc99e Initial load
duke
parents:
diff changeset
2227 // : false true
a61af66fc99e Initial load
duke
parents:
diff changeset
2228 // : | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2229 // : | stmt2 clone
a61af66fc99e Initial load
duke
parents:
diff changeset
2230 // : | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2231 // : | v
a61af66fc99e Initial load
duke
parents:
diff changeset
2232 // : | newloop<-----+
a61af66fc99e Initial load
duke
parents:
diff changeset
2233 // : | | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2234 // : | stmt3 clone |
a61af66fc99e Initial load
duke
parents:
diff changeset
2235 // : | | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2236 // : | v |
a61af66fc99e Initial load
duke
parents:
diff changeset
2237 // : | ifB |
a61af66fc99e Initial load
duke
parents:
diff changeset
2238 // : | / \ |
a61af66fc99e Initial load
duke
parents:
diff changeset
2239 // : | v v |
a61af66fc99e Initial load
duke
parents:
diff changeset
2240 // : | false true |
a61af66fc99e Initial load
duke
parents:
diff changeset
2241 // : | | | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2242 // : | v stmt2 |
a61af66fc99e Initial load
duke
parents:
diff changeset
2243 // : | exitB: | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2244 // : | stmt4 v |
a61af66fc99e Initial load
duke
parents:
diff changeset
2245 // : | ifA orig |
a61af66fc99e Initial load
duke
parents:
diff changeset
2246 // : | / \ |
a61af66fc99e Initial load
duke
parents:
diff changeset
2247 // : | / \ |
a61af66fc99e Initial load
duke
parents:
diff changeset
2248 // : | v v |
a61af66fc99e Initial load
duke
parents:
diff changeset
2249 // : | false true |
a61af66fc99e Initial load
duke
parents:
diff changeset
2250 // : | / \ |
a61af66fc99e Initial load
duke
parents:
diff changeset
2251 // : v v -----+
a61af66fc99e Initial load
duke
parents:
diff changeset
2252 // RegionA
a61af66fc99e Initial load
duke
parents:
diff changeset
2253 // |
a61af66fc99e Initial load
duke
parents:
diff changeset
2254 // v
a61af66fc99e Initial load
duke
parents:
diff changeset
2255 // exitA
a61af66fc99e Initial load
duke
parents:
diff changeset
2256 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2257 bool PhaseIdealLoop::partial_peel( IdealLoopTree *loop, Node_List &old_new ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2258
108
a761c2d3b76a 6684385: Loop unswitching crashes without LoopNode
rasbold
parents: 69
diff changeset
2259 if (!loop->_head->is_Loop()) {
a761c2d3b76a 6684385: Loop unswitching crashes without LoopNode
rasbold
parents: 69
diff changeset
2260 return false; }
a761c2d3b76a 6684385: Loop unswitching crashes without LoopNode
rasbold
parents: 69
diff changeset
2261
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2262 LoopNode *head = loop->_head->as_Loop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2263
a61af66fc99e Initial load
duke
parents:
diff changeset
2264 if (head->is_partial_peel_loop() || head->partial_peel_has_failed()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2265 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2266 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2267
a61af66fc99e Initial load
duke
parents:
diff changeset
2268 // Check for complex exit control
a61af66fc99e Initial load
duke
parents:
diff changeset
2269 for(uint ii = 0; ii < loop->_body.size(); ii++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2270 Node *n = loop->_body.at(ii);
a61af66fc99e Initial load
duke
parents:
diff changeset
2271 int opc = n->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
2272 if (n->is_Call() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
2273 opc == Op_Catch ||
a61af66fc99e Initial load
duke
parents:
diff changeset
2274 opc == Op_CatchProj ||
a61af66fc99e Initial load
duke
parents:
diff changeset
2275 opc == Op_Jump ||
a61af66fc99e Initial load
duke
parents:
diff changeset
2276 opc == Op_JumpProj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2277 #if !defined(PRODUCT)
a61af66fc99e Initial load
duke
parents:
diff changeset
2278 if (TracePartialPeeling) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2279 tty->print_cr("\nExit control too complex: lp: %d", head->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
2280 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2281 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2282 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2283 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2284 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2285
a61af66fc99e Initial load
duke
parents:
diff changeset
2286 int dd = dom_depth(head);
a61af66fc99e Initial load
duke
parents:
diff changeset
2287
a61af66fc99e Initial load
duke
parents:
diff changeset
2288 // Step 1: find cut point
a61af66fc99e Initial load
duke
parents:
diff changeset
2289
a61af66fc99e Initial load
duke
parents:
diff changeset
2290 // Walk up dominators to loop head looking for first loop exit
a61af66fc99e Initial load
duke
parents:
diff changeset
2291 // which is executed on every path thru loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
2292 IfNode *peel_if = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2293 IfNode *peel_if_cmpu = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2294
a61af66fc99e Initial load
duke
parents:
diff changeset
2295 Node *iff = loop->tail();
a61af66fc99e Initial load
duke
parents:
diff changeset
2296 while( iff != head ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2297 if( iff->is_If() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2298 Node *ctrl = get_ctrl(iff->in(1));
a61af66fc99e Initial load
duke
parents:
diff changeset
2299 if (ctrl->is_top()) return false; // Dead test on live IF.
a61af66fc99e Initial load
duke
parents:
diff changeset
2300 // If loop-varying exit-test, check for induction variable
a61af66fc99e Initial load
duke
parents:
diff changeset
2301 if( loop->is_member(get_loop(ctrl)) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2302 loop->is_loop_exit(iff) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2303 is_possible_iv_test(iff)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2304 Node* cmp = iff->in(1)->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2305 if (cmp->Opcode() == Op_CmpI) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2306 peel_if = iff->as_If();
a61af66fc99e Initial load
duke
parents:
diff changeset
2307 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2308 assert(cmp->Opcode() == Op_CmpU, "must be CmpI or CmpU");
a61af66fc99e Initial load
duke
parents:
diff changeset
2309 peel_if_cmpu = iff->as_If();
a61af66fc99e Initial load
duke
parents:
diff changeset
2310 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2311 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2312 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2313 iff = idom(iff);
a61af66fc99e Initial load
duke
parents:
diff changeset
2314 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2315 // Prefer signed compare over unsigned compare.
a61af66fc99e Initial load
duke
parents:
diff changeset
2316 IfNode* new_peel_if = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2317 if (peel_if == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2318 if (!PartialPeelAtUnsignedTests || peel_if_cmpu == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2319 return false; // No peel point found
a61af66fc99e Initial load
duke
parents:
diff changeset
2320 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2321 new_peel_if = insert_cmpi_loop_exit(peel_if_cmpu, loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
2322 if (new_peel_if == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2323 return false; // No peel point found
a61af66fc99e Initial load
duke
parents:
diff changeset
2324 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2325 peel_if = new_peel_if;
a61af66fc99e Initial load
duke
parents:
diff changeset
2326 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2327 Node* last_peel = stay_in_loop(peel_if, loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
2328 Node* first_not_peeled = stay_in_loop(last_peel, loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
2329 if (first_not_peeled == NULL || first_not_peeled == head) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2330 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2331 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2332
a61af66fc99e Initial load
duke
parents:
diff changeset
2333 #if !defined(PRODUCT)
a61af66fc99e Initial load
duke
parents:
diff changeset
2334 if (TracePartialPeeling) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2335 tty->print_cr("before partial peel one iteration");
a61af66fc99e Initial load
duke
parents:
diff changeset
2336 Node_List wl;
a61af66fc99e Initial load
duke
parents:
diff changeset
2337 Node* t = head->in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
2338 while (true) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2339 wl.push(t);
a61af66fc99e Initial load
duke
parents:
diff changeset
2340 if (t == head) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2341 t = idom(t);
a61af66fc99e Initial load
duke
parents:
diff changeset
2342 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2343 while (wl.size() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2344 Node* tt = wl.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2345 tt->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
2346 if (tt == last_peel) tty->print_cr("-- cut --");
a61af66fc99e Initial load
duke
parents:
diff changeset
2347 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2348 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2349 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2350 ResourceArea *area = Thread::current()->resource_area();
a61af66fc99e Initial load
duke
parents:
diff changeset
2351 VectorSet peel(area);
a61af66fc99e Initial load
duke
parents:
diff changeset
2352 VectorSet not_peel(area);
a61af66fc99e Initial load
duke
parents:
diff changeset
2353 Node_List peel_list(area);
a61af66fc99e Initial load
duke
parents:
diff changeset
2354 Node_List worklist(area);
a61af66fc99e Initial load
duke
parents:
diff changeset
2355 Node_List sink_list(area);
a61af66fc99e Initial load
duke
parents:
diff changeset
2356
a61af66fc99e Initial load
duke
parents:
diff changeset
2357 // Set of cfg nodes to peel are those that are executable from
a61af66fc99e Initial load
duke
parents:
diff changeset
2358 // the head through last_peel.
a61af66fc99e Initial load
duke
parents:
diff changeset
2359 assert(worklist.size() == 0, "should be empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
2360 worklist.push(head);
a61af66fc99e Initial load
duke
parents:
diff changeset
2361 peel.set(head->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
2362 while (worklist.size() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2363 Node *n = worklist.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2364 if (n != last_peel) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2365 for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2366 Node* use = n->fast_out(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
2367 if (use->is_CFG() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2368 loop->is_member(get_loop(use)) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2369 !peel.test_set(use->_idx)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2370 worklist.push(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
2371 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2372 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2373 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2374 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2375
a61af66fc99e Initial load
duke
parents:
diff changeset
2376 // Set of non-cfg nodes to peel are those that are control
a61af66fc99e Initial load
duke
parents:
diff changeset
2377 // dependent on the cfg nodes.
a61af66fc99e Initial load
duke
parents:
diff changeset
2378 uint i;
a61af66fc99e Initial load
duke
parents:
diff changeset
2379 for(i = 0; i < loop->_body.size(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2380 Node *n = loop->_body.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2381 Node *n_c = has_ctrl(n) ? get_ctrl(n) : n;
a61af66fc99e Initial load
duke
parents:
diff changeset
2382 if (peel.test(n_c->_idx)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2383 peel.set(n->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
2384 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2385 not_peel.set(n->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
2386 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2387 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2388
a61af66fc99e Initial load
duke
parents:
diff changeset
2389 // Step 2: move operations from the peeled section down into the
a61af66fc99e Initial load
duke
parents:
diff changeset
2390 // not-peeled section
a61af66fc99e Initial load
duke
parents:
diff changeset
2391
a61af66fc99e Initial load
duke
parents:
diff changeset
2392 // Get a post order schedule of nodes in the peel region
a61af66fc99e Initial load
duke
parents:
diff changeset
2393 // Result in right-most operand.
a61af66fc99e Initial load
duke
parents:
diff changeset
2394 scheduled_nodelist(loop, peel, peel_list );
a61af66fc99e Initial load
duke
parents:
diff changeset
2395
a61af66fc99e Initial load
duke
parents:
diff changeset
2396 assert(is_valid_loop_partition(loop, peel, peel_list, not_peel), "bad partition");
a61af66fc99e Initial load
duke
parents:
diff changeset
2397
a61af66fc99e Initial load
duke
parents:
diff changeset
2398 // For future check for too many new phis
a61af66fc99e Initial load
duke
parents:
diff changeset
2399 uint old_phi_cnt = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2400 for (DUIterator_Fast jmax, j = head->fast_outs(jmax); j < jmax; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2401 Node* use = head->fast_out(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
2402 if (use->is_Phi()) old_phi_cnt++;
a61af66fc99e Initial load
duke
parents:
diff changeset
2403 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2404
a61af66fc99e Initial load
duke
parents:
diff changeset
2405 #if !defined(PRODUCT)
a61af66fc99e Initial load
duke
parents:
diff changeset
2406 if (TracePartialPeeling) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2407 tty->print_cr("\npeeled list");
a61af66fc99e Initial load
duke
parents:
diff changeset
2408 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2409 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2410
a61af66fc99e Initial load
duke
parents:
diff changeset
2411 // Evacuate nodes in peel region into the not_peeled region if possible
a61af66fc99e Initial load
duke
parents:
diff changeset
2412 uint new_phi_cnt = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2413 for (i = 0; i < peel_list.size();) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2414 Node* n = peel_list.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2415 #if !defined(PRODUCT)
a61af66fc99e Initial load
duke
parents:
diff changeset
2416 if (TracePartialPeeling) n->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
2417 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2418 bool incr = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2419 if ( !n->is_CFG() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2420
a61af66fc99e Initial load
duke
parents:
diff changeset
2421 if ( has_use_in_set(n, not_peel) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2422
a61af66fc99e Initial load
duke
parents:
diff changeset
2423 // If not used internal to the peeled region,
a61af66fc99e Initial load
duke
parents:
diff changeset
2424 // move "n" from peeled to not_peeled region.
a61af66fc99e Initial load
duke
parents:
diff changeset
2425
a61af66fc99e Initial load
duke
parents:
diff changeset
2426 if ( !has_use_internal_to_set(n, peel, loop) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2427
a61af66fc99e Initial load
duke
parents:
diff changeset
2428 // if not pinned and not a load (which maybe anti-dependent on a store)
a61af66fc99e Initial load
duke
parents:
diff changeset
2429 // and not a CMove (Matcher expects only bool->cmove).
a61af66fc99e Initial load
duke
parents:
diff changeset
2430 if ( n->in(0) == NULL && !n->is_Load() && !n->is_CMove() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2431 clone_for_use_outside_loop( loop, n, worklist );
a61af66fc99e Initial load
duke
parents:
diff changeset
2432
a61af66fc99e Initial load
duke
parents:
diff changeset
2433 sink_list.push(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
2434 peel >>= n->_idx; // delete n from peel set.
a61af66fc99e Initial load
duke
parents:
diff changeset
2435 not_peel <<= n->_idx; // add n to not_peel set.
a61af66fc99e Initial load
duke
parents:
diff changeset
2436 peel_list.remove(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2437 incr = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2438 #if !defined(PRODUCT)
a61af66fc99e Initial load
duke
parents:
diff changeset
2439 if (TracePartialPeeling) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2440 tty->print_cr("sink to not_peeled region: %d newbb: %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
2441 n->_idx, get_ctrl(n)->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
2442 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2443 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2444 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2445 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2446 // Otherwise check for special def-use cases that span
a61af66fc99e Initial load
duke
parents:
diff changeset
2447 // the peel/not_peel boundary such as bool->if
a61af66fc99e Initial load
duke
parents:
diff changeset
2448 clone_for_special_use_inside_loop( loop, n, not_peel, sink_list, worklist );
a61af66fc99e Initial load
duke
parents:
diff changeset
2449 new_phi_cnt++;
a61af66fc99e Initial load
duke
parents:
diff changeset
2450 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2451 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2452 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2453 if (incr) i++;
a61af66fc99e Initial load
duke
parents:
diff changeset
2454 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2455
a61af66fc99e Initial load
duke
parents:
diff changeset
2456 if (new_phi_cnt > old_phi_cnt + PartialPeelNewPhiDelta) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2457 #if !defined(PRODUCT)
a61af66fc99e Initial load
duke
parents:
diff changeset
2458 if (TracePartialPeeling) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2459 tty->print_cr("\nToo many new phis: %d old %d new cmpi: %c",
a61af66fc99e Initial load
duke
parents:
diff changeset
2460 new_phi_cnt, old_phi_cnt, new_peel_if != NULL?'T':'F');
a61af66fc99e Initial load
duke
parents:
diff changeset
2461 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2462 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2463 if (new_peel_if != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2464 remove_cmpi_loop_exit(new_peel_if, loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
2465 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2466 // Inhibit more partial peeling on this loop
a61af66fc99e Initial load
duke
parents:
diff changeset
2467 assert(!head->is_partial_peel_loop(), "not partial peeled");
a61af66fc99e Initial load
duke
parents:
diff changeset
2468 head->mark_partial_peel_failed();
a61af66fc99e Initial load
duke
parents:
diff changeset
2469 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2470 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2471
a61af66fc99e Initial load
duke
parents:
diff changeset
2472 // Step 3: clone loop, retarget control, and insert new phis
a61af66fc99e Initial load
duke
parents:
diff changeset
2473
a61af66fc99e Initial load
duke
parents:
diff changeset
2474 // Create new loop head for new phis and to hang
a61af66fc99e Initial load
duke
parents:
diff changeset
2475 // the nodes being moved (sinked) from the peel region.
a61af66fc99e Initial load
duke
parents:
diff changeset
2476 LoopNode* new_head = new (C, 3) LoopNode(last_peel, last_peel);
a61af66fc99e Initial load
duke
parents:
diff changeset
2477 _igvn.register_new_node_with_optimizer(new_head);
a61af66fc99e Initial load
duke
parents:
diff changeset
2478 assert(first_not_peeled->in(0) == last_peel, "last_peel <- first_not_peeled");
a61af66fc99e Initial load
duke
parents:
diff changeset
2479 first_not_peeled->set_req(0, new_head);
a61af66fc99e Initial load
duke
parents:
diff changeset
2480 set_loop(new_head, loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
2481 loop->_body.push(new_head);
a61af66fc99e Initial load
duke
parents:
diff changeset
2482 not_peel.set(new_head->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
2483 set_idom(new_head, last_peel, dom_depth(first_not_peeled));
a61af66fc99e Initial load
duke
parents:
diff changeset
2484 set_idom(first_not_peeled, new_head, dom_depth(first_not_peeled));
a61af66fc99e Initial load
duke
parents:
diff changeset
2485
a61af66fc99e Initial load
duke
parents:
diff changeset
2486 while (sink_list.size() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2487 Node* n = sink_list.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2488 set_ctrl(n, new_head);
a61af66fc99e Initial load
duke
parents:
diff changeset
2489 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2490
a61af66fc99e Initial load
duke
parents:
diff changeset
2491 assert(is_valid_loop_partition(loop, peel, peel_list, not_peel), "bad partition");
a61af66fc99e Initial load
duke
parents:
diff changeset
2492
a61af66fc99e Initial load
duke
parents:
diff changeset
2493 clone_loop( loop, old_new, dd );
a61af66fc99e Initial load
duke
parents:
diff changeset
2494
a61af66fc99e Initial load
duke
parents:
diff changeset
2495 const uint clone_exit_idx = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2496 const uint orig_exit_idx = 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
2497 assert(is_valid_clone_loop_form( loop, peel_list, orig_exit_idx, clone_exit_idx ), "bad clone loop");
a61af66fc99e Initial load
duke
parents:
diff changeset
2498
a61af66fc99e Initial load
duke
parents:
diff changeset
2499 Node* head_clone = old_new[head->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
2500 LoopNode* new_head_clone = old_new[new_head->_idx]->as_Loop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2501 Node* orig_tail_clone = head_clone->in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
2502
a61af66fc99e Initial load
duke
parents:
diff changeset
2503 // Add phi if "def" node is in peel set and "use" is not
a61af66fc99e Initial load
duke
parents:
diff changeset
2504
a61af66fc99e Initial load
duke
parents:
diff changeset
2505 for(i = 0; i < peel_list.size(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2506 Node *def = peel_list.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2507 if (!def->is_CFG()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2508 for (DUIterator_Fast jmax, j = def->fast_outs(jmax); j < jmax; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2509 Node *use = def->fast_out(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
2510 if (has_node(use) && use->in(0) != C->top() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2511 (!peel.test(use->_idx) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
2512 (use->is_Phi() && use->in(0) == head)) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2513 worklist.push(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
2514 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2515 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2516 while( worklist.size() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2517 Node *use = worklist.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2518 for (uint j = 1; j < use->req(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2519 Node* n = use->in(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
2520 if (n == def) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2521
a61af66fc99e Initial load
duke
parents:
diff changeset
2522 // "def" is in peel set, "use" is not in peel set
a61af66fc99e Initial load
duke
parents:
diff changeset
2523 // or "use" is in the entry boundary (a phi) of the peel set
a61af66fc99e Initial load
duke
parents:
diff changeset
2524
a61af66fc99e Initial load
duke
parents:
diff changeset
2525 Node* use_c = has_ctrl(use) ? get_ctrl(use) : use;
a61af66fc99e Initial load
duke
parents:
diff changeset
2526
a61af66fc99e Initial load
duke
parents:
diff changeset
2527 if ( loop->is_member(get_loop( use_c )) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2528 // use is in loop
a61af66fc99e Initial load
duke
parents:
diff changeset
2529 if (old_new[use->_idx] != NULL) { // null for dead code
a61af66fc99e Initial load
duke
parents:
diff changeset
2530 Node* use_clone = old_new[use->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
2531 _igvn.hash_delete(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
2532 use->set_req(j, C->top());
a61af66fc99e Initial load
duke
parents:
diff changeset
2533 _igvn._worklist.push(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
2534 insert_phi_for_loop( use_clone, j, old_new[def->_idx], def, new_head_clone );
a61af66fc99e Initial load
duke
parents:
diff changeset
2535 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2536 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2537 assert(is_valid_clone_loop_exit_use(loop, use, orig_exit_idx), "clone loop format");
a61af66fc99e Initial load
duke
parents:
diff changeset
2538 // use is not in the loop, check if the live range includes the cut
a61af66fc99e Initial load
duke
parents:
diff changeset
2539 Node* lp_if = use_c->in(orig_exit_idx)->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2540 if (not_peel.test(lp_if->_idx)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2541 assert(j == orig_exit_idx, "use from original loop");
a61af66fc99e Initial load
duke
parents:
diff changeset
2542 insert_phi_for_loop( use, clone_exit_idx, old_new[def->_idx], def, new_head_clone );
a61af66fc99e Initial load
duke
parents:
diff changeset
2543 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2544 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2545 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2546 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2547 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2548 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2549 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2550
a61af66fc99e Initial load
duke
parents:
diff changeset
2551 // Step 3b: retarget control
a61af66fc99e Initial load
duke
parents:
diff changeset
2552
a61af66fc99e Initial load
duke
parents:
diff changeset
2553 // Redirect control to the new loop head if a cloned node in
a61af66fc99e Initial load
duke
parents:
diff changeset
2554 // the not_peeled region has control that points into the peeled region.
a61af66fc99e Initial load
duke
parents:
diff changeset
2555 // This necessary because the cloned peeled region will be outside
a61af66fc99e Initial load
duke
parents:
diff changeset
2556 // the loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
2557 // from to
a61af66fc99e Initial load
duke
parents:
diff changeset
2558 // cloned-peeled <---+
a61af66fc99e Initial load
duke
parents:
diff changeset
2559 // new_head_clone: | <--+
a61af66fc99e Initial load
duke
parents:
diff changeset
2560 // cloned-not_peeled in(0) in(0)
a61af66fc99e Initial load
duke
parents:
diff changeset
2561 // orig-peeled
a61af66fc99e Initial load
duke
parents:
diff changeset
2562
a61af66fc99e Initial load
duke
parents:
diff changeset
2563 for(i = 0; i < loop->_body.size(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2564 Node *n = loop->_body.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2565 if (!n->is_CFG() && n->in(0) != NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2566 not_peel.test(n->_idx) && peel.test(n->in(0)->_idx)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2567 Node* n_clone = old_new[n->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
2568 _igvn.hash_delete(n_clone);
a61af66fc99e Initial load
duke
parents:
diff changeset
2569 n_clone->set_req(0, new_head_clone);
a61af66fc99e Initial load
duke
parents:
diff changeset
2570 _igvn._worklist.push(n_clone);
a61af66fc99e Initial load
duke
parents:
diff changeset
2571 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2572 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2573
a61af66fc99e Initial load
duke
parents:
diff changeset
2574 // Backedge of the surviving new_head (the clone) is original last_peel
a61af66fc99e Initial load
duke
parents:
diff changeset
2575 _igvn.hash_delete(new_head_clone);
a61af66fc99e Initial load
duke
parents:
diff changeset
2576 new_head_clone->set_req(LoopNode::LoopBackControl, last_peel);
a61af66fc99e Initial load
duke
parents:
diff changeset
2577 _igvn._worklist.push(new_head_clone);
a61af66fc99e Initial load
duke
parents:
diff changeset
2578
a61af66fc99e Initial load
duke
parents:
diff changeset
2579 // Cut first node in original not_peel set
a61af66fc99e Initial load
duke
parents:
diff changeset
2580 _igvn.hash_delete(new_head);
a61af66fc99e Initial load
duke
parents:
diff changeset
2581 new_head->set_req(LoopNode::EntryControl, C->top());
a61af66fc99e Initial load
duke
parents:
diff changeset
2582 new_head->set_req(LoopNode::LoopBackControl, C->top());
a61af66fc99e Initial load
duke
parents:
diff changeset
2583 _igvn._worklist.push(new_head);
a61af66fc99e Initial load
duke
parents:
diff changeset
2584
a61af66fc99e Initial load
duke
parents:
diff changeset
2585 // Copy head_clone back-branch info to original head
a61af66fc99e Initial load
duke
parents:
diff changeset
2586 // and remove original head's loop entry and
a61af66fc99e Initial load
duke
parents:
diff changeset
2587 // clone head's back-branch
a61af66fc99e Initial load
duke
parents:
diff changeset
2588 _igvn.hash_delete(head);
a61af66fc99e Initial load
duke
parents:
diff changeset
2589 _igvn.hash_delete(head_clone);
a61af66fc99e Initial load
duke
parents:
diff changeset
2590 head->set_req(LoopNode::EntryControl, head_clone->in(LoopNode::LoopBackControl));
a61af66fc99e Initial load
duke
parents:
diff changeset
2591 head->set_req(LoopNode::LoopBackControl, C->top());
a61af66fc99e Initial load
duke
parents:
diff changeset
2592 head_clone->set_req(LoopNode::LoopBackControl, C->top());
a61af66fc99e Initial load
duke
parents:
diff changeset
2593 _igvn._worklist.push(head);
a61af66fc99e Initial load
duke
parents:
diff changeset
2594 _igvn._worklist.push(head_clone);
a61af66fc99e Initial load
duke
parents:
diff changeset
2595
a61af66fc99e Initial load
duke
parents:
diff changeset
2596 // Similarly modify the phis
a61af66fc99e Initial load
duke
parents:
diff changeset
2597 for (DUIterator_Fast kmax, k = head->fast_outs(kmax); k < kmax; k++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2598 Node* use = head->fast_out(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
2599 if (use->is_Phi() && use->outcnt() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2600 Node* use_clone = old_new[use->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
2601 _igvn.hash_delete(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
2602 _igvn.hash_delete(use_clone);
a61af66fc99e Initial load
duke
parents:
diff changeset
2603 use->set_req(LoopNode::EntryControl, use_clone->in(LoopNode::LoopBackControl));
a61af66fc99e Initial load
duke
parents:
diff changeset
2604 use->set_req(LoopNode::LoopBackControl, C->top());
a61af66fc99e Initial load
duke
parents:
diff changeset
2605 use_clone->set_req(LoopNode::LoopBackControl, C->top());
a61af66fc99e Initial load
duke
parents:
diff changeset
2606 _igvn._worklist.push(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
2607 _igvn._worklist.push(use_clone);
a61af66fc99e Initial load
duke
parents:
diff changeset
2608 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2609 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2610
a61af66fc99e Initial load
duke
parents:
diff changeset
2611 // Step 4: update dominator tree and dominator depth
a61af66fc99e Initial load
duke
parents:
diff changeset
2612
a61af66fc99e Initial load
duke
parents:
diff changeset
2613 set_idom(head, orig_tail_clone, dd);
a61af66fc99e Initial load
duke
parents:
diff changeset
2614 recompute_dom_depth();
a61af66fc99e Initial load
duke
parents:
diff changeset
2615
a61af66fc99e Initial load
duke
parents:
diff changeset
2616 // Inhibit more partial peeling on this loop
a61af66fc99e Initial load
duke
parents:
diff changeset
2617 new_head_clone->set_partial_peel_loop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2618 C->set_major_progress();
a61af66fc99e Initial load
duke
parents:
diff changeset
2619
a61af66fc99e Initial load
duke
parents:
diff changeset
2620 #if !defined(PRODUCT)
a61af66fc99e Initial load
duke
parents:
diff changeset
2621 if (TracePartialPeeling) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2622 tty->print_cr("\nafter partial peel one iteration");
a61af66fc99e Initial load
duke
parents:
diff changeset
2623 Node_List wl(area);
a61af66fc99e Initial load
duke
parents:
diff changeset
2624 Node* t = last_peel;
a61af66fc99e Initial load
duke
parents:
diff changeset
2625 while (true) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2626 wl.push(t);
a61af66fc99e Initial load
duke
parents:
diff changeset
2627 if (t == head_clone) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2628 t = idom(t);
a61af66fc99e Initial load
duke
parents:
diff changeset
2629 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2630 while (wl.size() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2631 Node* tt = wl.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2632 if (tt == head) tty->print_cr("orig head");
a61af66fc99e Initial load
duke
parents:
diff changeset
2633 else if (tt == new_head_clone) tty->print_cr("new head");
a61af66fc99e Initial load
duke
parents:
diff changeset
2634 else if (tt == head_clone) tty->print_cr("clone head");
a61af66fc99e Initial load
duke
parents:
diff changeset
2635 tt->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
2636 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2637 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2638 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2639 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2640 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2641
a61af66fc99e Initial load
duke
parents:
diff changeset
2642 //------------------------------reorg_offsets----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2643 // Reorganize offset computations to lower register pressure. Mostly
a61af66fc99e Initial load
duke
parents:
diff changeset
2644 // prevent loop-fallout uses of the pre-incremented trip counter (which are
a61af66fc99e Initial load
duke
parents:
diff changeset
2645 // then alive with the post-incremented trip counter forcing an extra
a61af66fc99e Initial load
duke
parents:
diff changeset
2646 // register move)
a61af66fc99e Initial load
duke
parents:
diff changeset
2647 void PhaseIdealLoop::reorg_offsets( IdealLoopTree *loop ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2648
a61af66fc99e Initial load
duke
parents:
diff changeset
2649 CountedLoopNode *cl = loop->_head->as_CountedLoop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2650 CountedLoopEndNode *cle = cl->loopexit();
a61af66fc99e Initial load
duke
parents:
diff changeset
2651 if( !cle ) return; // The occasional dead loop
a61af66fc99e Initial load
duke
parents:
diff changeset
2652 // Find loop exit control
a61af66fc99e Initial load
duke
parents:
diff changeset
2653 Node *exit = cle->proj_out(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2654 assert( exit->Opcode() == Op_IfFalse, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
2655
a61af66fc99e Initial load
duke
parents:
diff changeset
2656 // Check for the special case of folks using the pre-incremented
a61af66fc99e Initial load
duke
parents:
diff changeset
2657 // trip-counter on the fall-out path (forces the pre-incremented
a61af66fc99e Initial load
duke
parents:
diff changeset
2658 // and post-incremented trip counter to be live at the same time).
a61af66fc99e Initial load
duke
parents:
diff changeset
2659 // Fix this by adjusting to use the post-increment trip counter.
a61af66fc99e Initial load
duke
parents:
diff changeset
2660 Node *phi = cl->phi();
a61af66fc99e Initial load
duke
parents:
diff changeset
2661 if( !phi ) return; // Dead infinite loop
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 318
diff changeset
2662
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 318
diff changeset
2663 // Shape messed up, probably by iteration_split_impl
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 318
diff changeset
2664 if (phi->in(LoopNode::LoopBackControl) != cl->incr()) return;
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 318
diff changeset
2665
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2666 bool progress = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2667 while (progress) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2668 progress = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2669 for (DUIterator_Fast imax, i = phi->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2670 Node* use = phi->fast_out(i); // User of trip-counter
a61af66fc99e Initial load
duke
parents:
diff changeset
2671 if (!has_ctrl(use)) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2672 Node *u_ctrl = get_ctrl(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
2673 if( use->is_Phi() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2674 u_ctrl = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2675 for( uint j = 1; j < use->req(); j++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
2676 if( use->in(j) == phi )
a61af66fc99e Initial load
duke
parents:
diff changeset
2677 u_ctrl = dom_lca( u_ctrl, use->in(0)->in(j) );
a61af66fc99e Initial load
duke
parents:
diff changeset
2678 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2679 IdealLoopTree *u_loop = get_loop(u_ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
2680 // Look for loop-invariant use
a61af66fc99e Initial load
duke
parents:
diff changeset
2681 if( u_loop == loop ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2682 if( loop->is_member( u_loop ) ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2683 // Check that use is live out the bottom. Assuming the trip-counter
a61af66fc99e Initial load
duke
parents:
diff changeset
2684 // update is right at the bottom, uses of of the loop middle are ok.
a61af66fc99e Initial load
duke
parents:
diff changeset
2685 if( dom_lca( exit, u_ctrl ) != exit ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2686 // protect against stride not being a constant
a61af66fc99e Initial load
duke
parents:
diff changeset
2687 if( !cle->stride_is_con() ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2688 // Hit! Refactor use to use the post-incremented tripcounter.
a61af66fc99e Initial load
duke
parents:
diff changeset
2689 // Compute a post-increment tripcounter.
216
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 164
diff changeset
2690 Node *opaq = new (C, 2) Opaque2Node( C, cle->incr() );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2691 register_new_node( opaq, u_ctrl );
a61af66fc99e Initial load
duke
parents:
diff changeset
2692 Node *neg_stride = _igvn.intcon(-cle->stride_con());
a61af66fc99e Initial load
duke
parents:
diff changeset
2693 set_ctrl(neg_stride, C->root());
a61af66fc99e Initial load
duke
parents:
diff changeset
2694 Node *post = new (C, 3) AddINode( opaq, neg_stride);
a61af66fc99e Initial load
duke
parents:
diff changeset
2695 register_new_node( post, u_ctrl );
a61af66fc99e Initial load
duke
parents:
diff changeset
2696 _igvn.hash_delete(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
2697 _igvn._worklist.push(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
2698 for( uint j = 1; j < use->req(); j++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
2699 if( use->in(j) == phi )
a61af66fc99e Initial load
duke
parents:
diff changeset
2700 use->set_req(j, post);
a61af66fc99e Initial load
duke
parents:
diff changeset
2701 // Since DU info changed, rerun loop
a61af66fc99e Initial load
duke
parents:
diff changeset
2702 progress = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2703 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2704 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2705 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2706
a61af66fc99e Initial load
duke
parents:
diff changeset
2707 }