108 if( PrintOpto && VerifyLoopOptimizations ) { |
108 if( PrintOpto && VerifyLoopOptimizations ) { |
109 tty->print("Cloning down: "); |
109 tty->print("Cloning down: "); |
110 n->dump(); |
110 n->dump(); |
111 } |
111 } |
112 #endif |
112 #endif |
113 // Clone down any block-local BoolNode uses of this CmpNode |
113 if (!n->is_FastLock()) { |
114 for (DUIterator i = n->outs(); n->has_out(i); i++) { |
114 // Clone down any block-local BoolNode uses of this CmpNode |
115 Node* bol = n->out(i); |
115 for (DUIterator i = n->outs(); n->has_out(i); i++) { |
116 assert( bol->is_Bool(), "" ); |
116 Node* bol = n->out(i); |
117 if (bol->outcnt() == 1) { |
117 assert( bol->is_Bool(), "" ); |
118 Node* use = bol->unique_out(); |
118 if (bol->outcnt() == 1) { |
119 if (use->Opcode() == Op_Opaque4) { |
119 Node* use = bol->unique_out(); |
120 if (use->outcnt() == 1) { |
120 if (use->Opcode() == Op_Opaque4) { |
121 Node* iff = use->unique_out(); |
121 if (use->outcnt() == 1) { |
122 assert(iff->is_If(), "unexpected node type"); |
122 Node* iff = use->unique_out(); |
123 Node *use_c = iff->in(0); |
123 assert(iff->is_If(), "unexpected node type"); |
|
124 Node *use_c = iff->in(0); |
|
125 if (use_c == blk1 || use_c == blk2) { |
|
126 continue; |
|
127 } |
|
128 } |
|
129 } else { |
|
130 // We might see an Opaque1 from a loop limit check here |
|
131 assert(use->is_If() || use->is_CMove() || use->Opcode() == Op_Opaque1, "unexpected node type"); |
|
132 Node *use_c = use->is_If() ? use->in(0) : get_ctrl(use); |
124 if (use_c == blk1 || use_c == blk2) { |
133 if (use_c == blk1 || use_c == blk2) { |
|
134 assert(use->is_CMove(), "unexpected node type"); |
125 continue; |
135 continue; |
126 } |
136 } |
127 } |
137 } |
128 } else { |
138 } |
129 // We might see an Opaque1 from a loop limit check here |
139 if (get_ctrl(bol) == blk1 || get_ctrl(bol) == blk2) { |
130 assert(use->is_If() || use->is_CMove() || use->Opcode() == Op_Opaque1, "unexpected node type"); |
140 // Recursively sink any BoolNode |
131 Node *use_c = use->is_If() ? use->in(0) : get_ctrl(use); |
141 #ifndef PRODUCT |
132 if (use_c == blk1 || use_c == blk2) { |
142 if( PrintOpto && VerifyLoopOptimizations ) { |
133 assert(use->is_CMove(), "unexpected node type"); |
143 tty->print("Cloning down: "); |
134 continue; |
144 bol->dump(); |
135 } |
145 } |
|
146 #endif |
|
147 for (DUIterator j = bol->outs(); bol->has_out(j); j++) { |
|
148 Node* u = bol->out(j); |
|
149 // Uses are either IfNodes, CMoves or Opaque4 |
|
150 if (u->Opcode() == Op_Opaque4) { |
|
151 assert(u->in(1) == bol, "bad input"); |
|
152 for (DUIterator_Last kmin, k = u->last_outs(kmin); k >= kmin; --k) { |
|
153 Node* iff = u->last_out(k); |
|
154 assert(iff->is_If() || iff->is_CMove(), "unexpected node type"); |
|
155 assert( iff->in(1) == u, "" ); |
|
156 // Get control block of either the CMove or the If input |
|
157 Node *iff_ctrl = iff->is_If() ? iff->in(0) : get_ctrl(iff); |
|
158 Node *x1 = bol->clone(); |
|
159 Node *x2 = u->clone(); |
|
160 register_new_node(x1, iff_ctrl); |
|
161 register_new_node(x2, iff_ctrl); |
|
162 _igvn.replace_input_of(x2, 1, x1); |
|
163 _igvn.replace_input_of(iff, 1, x2); |
|
164 } |
|
165 _igvn.remove_dead_node(u); |
|
166 --j; |
|
167 } else { |
|
168 // We might see an Opaque1 from a loop limit check here |
|
169 assert(u->is_If() || u->is_CMove() || u->Opcode() == Op_Opaque1, "unexpected node type"); |
|
170 assert(u->in(1) == bol, ""); |
|
171 // Get control block of either the CMove or the If input |
|
172 Node *u_ctrl = u->is_If() ? u->in(0) : get_ctrl(u); |
|
173 assert((u_ctrl != blk1 && u_ctrl != blk2) || u->is_CMove(), "won't converge"); |
|
174 Node *x = bol->clone(); |
|
175 register_new_node(x, u_ctrl); |
|
176 _igvn.replace_input_of(u, 1, x); |
|
177 --j; |
|
178 } |
|
179 } |
|
180 _igvn.remove_dead_node(bol); |
|
181 --i; |
136 } |
182 } |
137 } |
183 } |
138 if (get_ctrl(bol) == blk1 || get_ctrl(bol) == blk2) { |
|
139 // Recursively sink any BoolNode |
|
140 #ifndef PRODUCT |
|
141 if( PrintOpto && VerifyLoopOptimizations ) { |
|
142 tty->print("Cloning down: "); |
|
143 bol->dump(); |
|
144 } |
|
145 #endif |
|
146 for (DUIterator j = bol->outs(); bol->has_out(j); j++) { |
|
147 Node* u = bol->out(j); |
|
148 // Uses are either IfNodes, CMoves or Opaque4 |
|
149 if (u->Opcode() == Op_Opaque4) { |
|
150 assert(u->in(1) == bol, "bad input"); |
|
151 for (DUIterator_Last kmin, k = u->last_outs(kmin); k >= kmin; --k) { |
|
152 Node* iff = u->last_out(k); |
|
153 assert(iff->is_If() || iff->is_CMove(), "unexpected node type"); |
|
154 assert( iff->in(1) == u, "" ); |
|
155 // Get control block of either the CMove or the If input |
|
156 Node *iff_ctrl = iff->is_If() ? iff->in(0) : get_ctrl(iff); |
|
157 Node *x1 = bol->clone(); |
|
158 Node *x2 = u->clone(); |
|
159 register_new_node(x1, iff_ctrl); |
|
160 register_new_node(x2, iff_ctrl); |
|
161 _igvn.replace_input_of(x2, 1, x1); |
|
162 _igvn.replace_input_of(iff, 1, x2); |
|
163 } |
|
164 _igvn.remove_dead_node(u); |
|
165 --j; |
|
166 } else { |
|
167 // We might see an Opaque1 from a loop limit check here |
|
168 assert(u->is_If() || u->is_CMove() || u->Opcode() == Op_Opaque1, "unexpected node type"); |
|
169 assert(u->in(1) == bol, ""); |
|
170 // Get control block of either the CMove or the If input |
|
171 Node *u_ctrl = u->is_If() ? u->in(0) : get_ctrl(u); |
|
172 assert((u_ctrl != blk1 && u_ctrl != blk2) || u->is_CMove(), "won't converge"); |
|
173 Node *x = bol->clone(); |
|
174 register_new_node(x, u_ctrl); |
|
175 _igvn.replace_input_of(u, 1, x); |
|
176 --j; |
|
177 } |
|
178 } |
|
179 _igvn.remove_dead_node(bol); |
|
180 --i; |
|
181 } |
|
182 } |
184 } |
183 // Clone down this CmpNode |
185 // Clone down this CmpNode |
184 for (DUIterator_Last jmin, j = n->last_outs(jmin); j >= jmin; --j) { |
186 for (DUIterator_Last jmin, j = n->last_outs(jmin); j >= jmin; --j) { |
185 Node* bol = n->last_out(j); |
187 Node* use = n->last_out(j); |
186 assert( bol->in(1) == n, "" ); |
188 uint pos = 1; |
|
189 if (n->is_FastLock()) { |
|
190 pos = TypeFunc::Parms + 2; |
|
191 assert(use->is_Lock(), "FastLock only used by LockNode"); |
|
192 } |
|
193 assert(use->in(pos) == n, "" ); |
187 Node *x = n->clone(); |
194 Node *x = n->clone(); |
188 register_new_node(x, get_ctrl(bol)); |
195 register_new_node(x, ctrl_or_self(use)); |
189 _igvn.replace_input_of(bol, 1, x); |
196 _igvn.replace_input_of(use, pos, x); |
190 } |
197 } |
191 _igvn.remove_dead_node( n ); |
198 _igvn.remove_dead_node( n ); |
192 |
199 |
193 return true; |
200 return true; |
194 } |
201 } |