Wed, 28 Aug 2013 11:22:43 +0200
8023597: Optimize G1 barriers code for unsafe load_store
Summary: Avoid loading old values in G1 pre-barriers for inlined unsafe load_store nodes.
Reviewed-by: kvn, tonyp
Contributed-by: Martin Doerr <martin.doerr@sap.com>
duke@435 | 1 | /* |
mikael@4153 | 2 | * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. |
duke@435 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
duke@435 | 4 | * |
duke@435 | 5 | * This code is free software; you can redistribute it and/or modify it |
duke@435 | 6 | * under the terms of the GNU General Public License version 2 only, as |
duke@435 | 7 | * published by the Free Software Foundation. |
duke@435 | 8 | * |
duke@435 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
duke@435 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
duke@435 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
duke@435 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
duke@435 | 13 | * accompanied this code). |
duke@435 | 14 | * |
duke@435 | 15 | * You should have received a copy of the GNU General Public License version |
duke@435 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
duke@435 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
duke@435 | 18 | * |
trims@1907 | 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
trims@1907 | 20 | * or visit www.oracle.com if you need additional information or have any |
trims@1907 | 21 | * questions. |
duke@435 | 22 | * |
duke@435 | 23 | */ |
duke@435 | 24 | |
stefank@2314 | 25 | #include "precompiled.hpp" |
stefank@2314 | 26 | #include "memory/allocation.inline.hpp" |
stefank@2314 | 27 | #include "opto/addnode.hpp" |
stefank@2314 | 28 | #include "opto/cfgnode.hpp" |
stefank@2314 | 29 | #include "opto/connode.hpp" |
kvn@2727 | 30 | #include "opto/loopnode.hpp" |
stefank@2314 | 31 | #include "opto/phaseX.hpp" |
stefank@2314 | 32 | #include "opto/runtime.hpp" |
stefank@2314 | 33 | #include "opto/subnode.hpp" |
stefank@2314 | 34 | |
duke@435 | 35 | // Portions of code courtesy of Clifford Click |
duke@435 | 36 | |
duke@435 | 37 | // Optimization - Graph Style |
duke@435 | 38 | |
duke@435 | 39 | |
duke@435 | 40 | extern int explicit_null_checks_elided; |
duke@435 | 41 | |
duke@435 | 42 | //============================================================================= |
duke@435 | 43 | //------------------------------Value------------------------------------------ |
duke@435 | 44 | // Return a tuple for whichever arm of the IF is reachable |
duke@435 | 45 | const Type *IfNode::Value( PhaseTransform *phase ) const { |
duke@435 | 46 | if( !in(0) ) return Type::TOP; |
duke@435 | 47 | if( phase->type(in(0)) == Type::TOP ) |
duke@435 | 48 | return Type::TOP; |
duke@435 | 49 | const Type *t = phase->type(in(1)); |
duke@435 | 50 | if( t == Type::TOP ) // data is undefined |
duke@435 | 51 | return TypeTuple::IFNEITHER; // unreachable altogether |
duke@435 | 52 | if( t == TypeInt::ZERO ) // zero, or false |
duke@435 | 53 | return TypeTuple::IFFALSE; // only false branch is reachable |
duke@435 | 54 | if( t == TypeInt::ONE ) // 1, or true |
duke@435 | 55 | return TypeTuple::IFTRUE; // only true branch is reachable |
duke@435 | 56 | assert( t == TypeInt::BOOL, "expected boolean type" ); |
duke@435 | 57 | |
duke@435 | 58 | return TypeTuple::IFBOTH; // No progress |
duke@435 | 59 | } |
duke@435 | 60 | |
duke@435 | 61 | const RegMask &IfNode::out_RegMask() const { |
duke@435 | 62 | return RegMask::Empty; |
duke@435 | 63 | } |
duke@435 | 64 | |
duke@435 | 65 | //------------------------------split_if--------------------------------------- |
duke@435 | 66 | // Look for places where we merge constants, then test on the merged value. |
duke@435 | 67 | // If the IF test will be constant folded on the path with the constant, we |
duke@435 | 68 | // win by splitting the IF to before the merge point. |
duke@435 | 69 | static Node* split_if(IfNode *iff, PhaseIterGVN *igvn) { |
duke@435 | 70 | // I could be a lot more general here, but I'm trying to squeeze this |
duke@435 | 71 | // in before the Christmas '98 break so I'm gonna be kinda restrictive |
duke@435 | 72 | // on the patterns I accept. CNC |
duke@435 | 73 | |
duke@435 | 74 | // Look for a compare of a constant and a merged value |
duke@435 | 75 | Node *i1 = iff->in(1); |
duke@435 | 76 | if( !i1->is_Bool() ) return NULL; |
duke@435 | 77 | BoolNode *b = i1->as_Bool(); |
duke@435 | 78 | Node *cmp = b->in(1); |
duke@435 | 79 | if( !cmp->is_Cmp() ) return NULL; |
duke@435 | 80 | i1 = cmp->in(1); |
duke@435 | 81 | if( i1 == NULL || !i1->is_Phi() ) return NULL; |
duke@435 | 82 | PhiNode *phi = i1->as_Phi(); |
duke@435 | 83 | if( phi->is_copy() ) return NULL; |
duke@435 | 84 | Node *con2 = cmp->in(2); |
duke@435 | 85 | if( !con2->is_Con() ) return NULL; |
duke@435 | 86 | // See that the merge point contains some constants |
duke@435 | 87 | Node *con1=NULL; |
duke@435 | 88 | uint i4; |
duke@435 | 89 | for( i4 = 1; i4 < phi->req(); i4++ ) { |
duke@435 | 90 | con1 = phi->in(i4); |
twisti@1040 | 91 | if( !con1 ) return NULL; // Do not optimize partially collapsed merges |
duke@435 | 92 | if( con1->is_Con() ) break; // Found a constant |
duke@435 | 93 | // Also allow null-vs-not-null checks |
duke@435 | 94 | const TypePtr *tp = igvn->type(con1)->isa_ptr(); |
duke@435 | 95 | if( tp && tp->_ptr == TypePtr::NotNull ) |
duke@435 | 96 | break; |
duke@435 | 97 | } |
duke@435 | 98 | if( i4 >= phi->req() ) return NULL; // Found no constants |
duke@435 | 99 | |
duke@435 | 100 | igvn->C->set_has_split_ifs(true); // Has chance for split-if |
duke@435 | 101 | |
duke@435 | 102 | // Make sure that the compare can be constant folded away |
duke@435 | 103 | Node *cmp2 = cmp->clone(); |
duke@435 | 104 | cmp2->set_req(1,con1); |
duke@435 | 105 | cmp2->set_req(2,con2); |
duke@435 | 106 | const Type *t = cmp2->Value(igvn); |
duke@435 | 107 | // This compare is dead, so whack it! |
duke@435 | 108 | igvn->remove_dead_node(cmp2); |
duke@435 | 109 | if( !t->singleton() ) return NULL; |
duke@435 | 110 | |
duke@435 | 111 | // No intervening control, like a simple Call |
duke@435 | 112 | Node *r = iff->in(0); |
duke@435 | 113 | if( !r->is_Region() ) return NULL; |
duke@435 | 114 | if( phi->region() != r ) return NULL; |
duke@435 | 115 | // No other users of the cmp/bool |
duke@435 | 116 | if (b->outcnt() != 1 || cmp->outcnt() != 1) { |
duke@435 | 117 | //tty->print_cr("many users of cmp/bool"); |
duke@435 | 118 | return NULL; |
duke@435 | 119 | } |
duke@435 | 120 | |
duke@435 | 121 | // Make sure we can determine where all the uses of merged values go |
duke@435 | 122 | for (DUIterator_Fast jmax, j = r->fast_outs(jmax); j < jmax; j++) { |
duke@435 | 123 | Node* u = r->fast_out(j); |
duke@435 | 124 | if( u == r ) continue; |
duke@435 | 125 | if( u == iff ) continue; |
duke@435 | 126 | if( u->outcnt() == 0 ) continue; // use is dead & ignorable |
duke@435 | 127 | if( !u->is_Phi() ) { |
duke@435 | 128 | /* |
duke@435 | 129 | if( u->is_Start() ) { |
duke@435 | 130 | tty->print_cr("Region has inlined start use"); |
duke@435 | 131 | } else { |
duke@435 | 132 | tty->print_cr("Region has odd use"); |
duke@435 | 133 | u->dump(2); |
duke@435 | 134 | }*/ |
duke@435 | 135 | return NULL; |
duke@435 | 136 | } |
duke@435 | 137 | if( u != phi ) { |
duke@435 | 138 | // CNC - do not allow any other merged value |
duke@435 | 139 | //tty->print_cr("Merging another value"); |
duke@435 | 140 | //u->dump(2); |
duke@435 | 141 | return NULL; |
duke@435 | 142 | } |
duke@435 | 143 | // Make sure we can account for all Phi uses |
duke@435 | 144 | for (DUIterator_Fast kmax, k = u->fast_outs(kmax); k < kmax; k++) { |
duke@435 | 145 | Node* v = u->fast_out(k); // User of the phi |
duke@435 | 146 | // CNC - Allow only really simple patterns. |
duke@435 | 147 | // In particular I disallow AddP of the Phi, a fairly common pattern |
duke@435 | 148 | if( v == cmp ) continue; // The compare is OK |
duke@435 | 149 | if( (v->is_ConstraintCast()) && |
duke@435 | 150 | v->in(0)->in(0) == iff ) |
duke@435 | 151 | continue; // CastPP/II of the IfNode is OK |
duke@435 | 152 | // Disabled following code because I cannot tell if exactly one |
duke@435 | 153 | // path dominates without a real dominator check. CNC 9/9/1999 |
duke@435 | 154 | //uint vop = v->Opcode(); |
duke@435 | 155 | //if( vop == Op_Phi ) { // Phi from another merge point might be OK |
duke@435 | 156 | // Node *r = v->in(0); // Get controlling point |
duke@435 | 157 | // if( !r ) return NULL; // Degraded to a copy |
duke@435 | 158 | // // Find exactly one path in (either True or False doms, but not IFF) |
duke@435 | 159 | // int cnt = 0; |
duke@435 | 160 | // for( uint i = 1; i < r->req(); i++ ) |
duke@435 | 161 | // if( r->in(i) && r->in(i)->in(0) == iff ) |
duke@435 | 162 | // cnt++; |
duke@435 | 163 | // if( cnt == 1 ) continue; // Exactly one of True or False guards Phi |
duke@435 | 164 | //} |
duke@435 | 165 | if( !v->is_Call() ) { |
duke@435 | 166 | /* |
duke@435 | 167 | if( v->Opcode() == Op_AddP ) { |
duke@435 | 168 | tty->print_cr("Phi has AddP use"); |
duke@435 | 169 | } else if( v->Opcode() == Op_CastPP ) { |
duke@435 | 170 | tty->print_cr("Phi has CastPP use"); |
duke@435 | 171 | } else if( v->Opcode() == Op_CastII ) { |
duke@435 | 172 | tty->print_cr("Phi has CastII use"); |
duke@435 | 173 | } else { |
duke@435 | 174 | tty->print_cr("Phi has use I cant be bothered with"); |
duke@435 | 175 | } |
duke@435 | 176 | */ |
duke@435 | 177 | } |
duke@435 | 178 | return NULL; |
duke@435 | 179 | |
duke@435 | 180 | /* CNC - Cut out all the fancy acceptance tests |
duke@435 | 181 | // Can we clone this use when doing the transformation? |
duke@435 | 182 | // If all uses are from Phis at this merge or constants, then YES. |
duke@435 | 183 | if( !v->in(0) && v != cmp ) { |
duke@435 | 184 | tty->print_cr("Phi has free-floating use"); |
duke@435 | 185 | v->dump(2); |
duke@435 | 186 | return NULL; |
duke@435 | 187 | } |
duke@435 | 188 | for( uint l = 1; l < v->req(); l++ ) { |
duke@435 | 189 | if( (!v->in(l)->is_Phi() || v->in(l)->in(0) != r) && |
duke@435 | 190 | !v->in(l)->is_Con() ) { |
duke@435 | 191 | tty->print_cr("Phi has use"); |
duke@435 | 192 | v->dump(2); |
duke@435 | 193 | return NULL; |
duke@435 | 194 | } // End of if Phi-use input is neither Phi nor Constant |
duke@435 | 195 | } // End of for all inputs to Phi-use |
duke@435 | 196 | */ |
duke@435 | 197 | } // End of for all uses of Phi |
duke@435 | 198 | } // End of for all uses of Region |
duke@435 | 199 | |
duke@435 | 200 | // Only do this if the IF node is in a sane state |
duke@435 | 201 | if (iff->outcnt() != 2) |
duke@435 | 202 | return NULL; |
duke@435 | 203 | |
duke@435 | 204 | // Got a hit! Do the Mondo Hack! |
duke@435 | 205 | // |
duke@435 | 206 | //ABC a1c def ghi B 1 e h A C a c d f g i |
duke@435 | 207 | // R - Phi - Phi - Phi Rc - Phi - Phi - Phi Rx - Phi - Phi - Phi |
duke@435 | 208 | // cmp - 2 cmp - 2 cmp - 2 |
duke@435 | 209 | // bool bool_c bool_x |
duke@435 | 210 | // if if_c if_x |
duke@435 | 211 | // T F T F T F |
duke@435 | 212 | // ..s.. ..t .. ..s.. ..t.. ..s.. ..t.. |
duke@435 | 213 | // |
twisti@1040 | 214 | // Split the paths coming into the merge point into 2 separate groups of |
duke@435 | 215 | // merges. On the left will be all the paths feeding constants into the |
duke@435 | 216 | // Cmp's Phi. On the right will be the remaining paths. The Cmp's Phi |
duke@435 | 217 | // will fold up into a constant; this will let the Cmp fold up as well as |
duke@435 | 218 | // all the control flow. Below the original IF we have 2 control |
duke@435 | 219 | // dependent regions, 's' and 't'. Now we will merge the two paths |
duke@435 | 220 | // just prior to 's' and 't' from the two IFs. At least 1 path (and quite |
duke@435 | 221 | // likely 2 or more) will promptly constant fold away. |
duke@435 | 222 | PhaseGVN *phase = igvn; |
duke@435 | 223 | |
duke@435 | 224 | // Make a region merging constants and a region merging the rest |
duke@435 | 225 | uint req_c = 0; |
kvn@2727 | 226 | Node* predicate_proj = NULL; |
duke@435 | 227 | for (uint ii = 1; ii < r->req(); ii++) { |
kvn@2727 | 228 | if (phi->in(ii) == con1) { |
duke@435 | 229 | req_c++; |
duke@435 | 230 | } |
kvn@2727 | 231 | Node* proj = PhaseIdealLoop::find_predicate(r->in(ii)); |
kvn@2727 | 232 | if (proj != NULL) { |
kvn@2727 | 233 | assert(predicate_proj == NULL, "only one predicate entry expected"); |
kvn@2727 | 234 | predicate_proj = proj; |
kvn@2727 | 235 | } |
duke@435 | 236 | } |
kvn@2727 | 237 | Node* predicate_c = NULL; |
kvn@2727 | 238 | Node* predicate_x = NULL; |
kvn@2877 | 239 | bool counted_loop = r->is_CountedLoop(); |
kvn@2727 | 240 | |
kvn@4115 | 241 | Node *region_c = new (igvn->C) RegionNode(req_c + 1); |
duke@435 | 242 | Node *phi_c = con1; |
duke@435 | 243 | uint len = r->req(); |
kvn@4115 | 244 | Node *region_x = new (igvn->C) RegionNode(len - req_c); |
duke@435 | 245 | Node *phi_x = PhiNode::make_blank(region_x, phi); |
duke@435 | 246 | for (uint i = 1, i_c = 1, i_x = 1; i < len; i++) { |
kvn@2727 | 247 | if (phi->in(i) == con1) { |
duke@435 | 248 | region_c->init_req( i_c++, r ->in(i) ); |
kvn@2727 | 249 | if (r->in(i) == predicate_proj) |
kvn@2727 | 250 | predicate_c = predicate_proj; |
duke@435 | 251 | } else { |
duke@435 | 252 | region_x->init_req( i_x, r ->in(i) ); |
duke@435 | 253 | phi_x ->init_req( i_x++, phi->in(i) ); |
kvn@2727 | 254 | if (r->in(i) == predicate_proj) |
kvn@2727 | 255 | predicate_x = predicate_proj; |
duke@435 | 256 | } |
duke@435 | 257 | } |
kvn@3043 | 258 | if (predicate_c != NULL && (req_c > 1)) { |
kvn@3043 | 259 | assert(predicate_x == NULL, "only one predicate entry expected"); |
kvn@3043 | 260 | predicate_c = NULL; // Do not clone predicate below merge point |
kvn@3043 | 261 | } |
kvn@3043 | 262 | if (predicate_x != NULL && ((len - req_c) > 2)) { |
kvn@3043 | 263 | assert(predicate_c == NULL, "only one predicate entry expected"); |
kvn@3043 | 264 | predicate_x = NULL; // Do not clone predicate below merge point |
kvn@3043 | 265 | } |
duke@435 | 266 | |
duke@435 | 267 | // Register the new RegionNodes but do not transform them. Cannot |
twisti@1040 | 268 | // transform until the entire Region/Phi conglomerate has been hacked |
duke@435 | 269 | // as a single huge transform. |
duke@435 | 270 | igvn->register_new_node_with_optimizer( region_c ); |
duke@435 | 271 | igvn->register_new_node_with_optimizer( region_x ); |
duke@435 | 272 | // Prevent the untimely death of phi_x. Currently he has no uses. He is |
duke@435 | 273 | // about to get one. If this only use goes away, then phi_x will look dead. |
duke@435 | 274 | // However, he will be picking up some more uses down below. |
kvn@4115 | 275 | Node *hook = new (igvn->C) Node(4); |
duke@435 | 276 | hook->init_req(0, phi_x); |
duke@435 | 277 | hook->init_req(1, phi_c); |
kvn@1448 | 278 | phi_x = phase->transform( phi_x ); |
duke@435 | 279 | |
duke@435 | 280 | // Make the compare |
duke@435 | 281 | Node *cmp_c = phase->makecon(t); |
duke@435 | 282 | Node *cmp_x = cmp->clone(); |
duke@435 | 283 | cmp_x->set_req(1,phi_x); |
duke@435 | 284 | cmp_x->set_req(2,con2); |
duke@435 | 285 | cmp_x = phase->transform(cmp_x); |
duke@435 | 286 | // Make the bool |
kvn@4115 | 287 | Node *b_c = phase->transform(new (igvn->C) BoolNode(cmp_c,b->_test._test)); |
kvn@4115 | 288 | Node *b_x = phase->transform(new (igvn->C) BoolNode(cmp_x,b->_test._test)); |
duke@435 | 289 | // Make the IfNode |
kvn@4115 | 290 | IfNode *iff_c = new (igvn->C) IfNode(region_c,b_c,iff->_prob,iff->_fcnt); |
duke@435 | 291 | igvn->set_type_bottom(iff_c); |
duke@435 | 292 | igvn->_worklist.push(iff_c); |
duke@435 | 293 | hook->init_req(2, iff_c); |
duke@435 | 294 | |
kvn@4115 | 295 | IfNode *iff_x = new (igvn->C) IfNode(region_x,b_x,iff->_prob, iff->_fcnt); |
duke@435 | 296 | igvn->set_type_bottom(iff_x); |
duke@435 | 297 | igvn->_worklist.push(iff_x); |
duke@435 | 298 | hook->init_req(3, iff_x); |
duke@435 | 299 | |
duke@435 | 300 | // Make the true/false arms |
kvn@4115 | 301 | Node *iff_c_t = phase->transform(new (igvn->C) IfTrueNode (iff_c)); |
kvn@4115 | 302 | Node *iff_c_f = phase->transform(new (igvn->C) IfFalseNode(iff_c)); |
kvn@2727 | 303 | if (predicate_c != NULL) { |
kvn@2727 | 304 | assert(predicate_x == NULL, "only one predicate entry expected"); |
kvn@2727 | 305 | // Clone loop predicates to each path |
kvn@2877 | 306 | iff_c_t = igvn->clone_loop_predicates(predicate_c, iff_c_t, !counted_loop); |
kvn@2877 | 307 | iff_c_f = igvn->clone_loop_predicates(predicate_c, iff_c_f, !counted_loop); |
kvn@2727 | 308 | } |
kvn@4115 | 309 | Node *iff_x_t = phase->transform(new (igvn->C) IfTrueNode (iff_x)); |
kvn@4115 | 310 | Node *iff_x_f = phase->transform(new (igvn->C) IfFalseNode(iff_x)); |
kvn@2727 | 311 | if (predicate_x != NULL) { |
kvn@2727 | 312 | assert(predicate_c == NULL, "only one predicate entry expected"); |
kvn@2727 | 313 | // Clone loop predicates to each path |
kvn@2877 | 314 | iff_x_t = igvn->clone_loop_predicates(predicate_x, iff_x_t, !counted_loop); |
kvn@2877 | 315 | iff_x_f = igvn->clone_loop_predicates(predicate_x, iff_x_f, !counted_loop); |
kvn@2727 | 316 | } |
duke@435 | 317 | |
duke@435 | 318 | // Merge the TRUE paths |
kvn@4115 | 319 | Node *region_s = new (igvn->C) RegionNode(3); |
duke@435 | 320 | igvn->_worklist.push(region_s); |
duke@435 | 321 | region_s->init_req(1, iff_c_t); |
duke@435 | 322 | region_s->init_req(2, iff_x_t); |
duke@435 | 323 | igvn->register_new_node_with_optimizer( region_s ); |
duke@435 | 324 | |
duke@435 | 325 | // Merge the FALSE paths |
kvn@4115 | 326 | Node *region_f = new (igvn->C) RegionNode(3); |
duke@435 | 327 | igvn->_worklist.push(region_f); |
duke@435 | 328 | region_f->init_req(1, iff_c_f); |
duke@435 | 329 | region_f->init_req(2, iff_x_f); |
duke@435 | 330 | igvn->register_new_node_with_optimizer( region_f ); |
duke@435 | 331 | |
duke@435 | 332 | igvn->hash_delete(cmp);// Remove soon-to-be-dead node from hash table. |
duke@435 | 333 | cmp->set_req(1,NULL); // Whack the inputs to cmp because it will be dead |
duke@435 | 334 | cmp->set_req(2,NULL); |
duke@435 | 335 | // Check for all uses of the Phi and give them a new home. |
duke@435 | 336 | // The 'cmp' got cloned, but CastPP/IIs need to be moved. |
duke@435 | 337 | Node *phi_s = NULL; // do not construct unless needed |
duke@435 | 338 | Node *phi_f = NULL; // do not construct unless needed |
duke@435 | 339 | for (DUIterator_Last i2min, i2 = phi->last_outs(i2min); i2 >= i2min; --i2) { |
duke@435 | 340 | Node* v = phi->last_out(i2);// User of the phi |
kvn@3847 | 341 | igvn->rehash_node_delayed(v); // Have to fixup other Phi users |
duke@435 | 342 | uint vop = v->Opcode(); |
duke@435 | 343 | Node *proj = NULL; |
duke@435 | 344 | if( vop == Op_Phi ) { // Remote merge point |
duke@435 | 345 | Node *r = v->in(0); |
duke@435 | 346 | for (uint i3 = 1; i3 < r->req(); i3++) |
duke@435 | 347 | if (r->in(i3) && r->in(i3)->in(0) == iff) { |
duke@435 | 348 | proj = r->in(i3); |
duke@435 | 349 | break; |
duke@435 | 350 | } |
duke@435 | 351 | } else if( v->is_ConstraintCast() ) { |
duke@435 | 352 | proj = v->in(0); // Controlling projection |
duke@435 | 353 | } else { |
duke@435 | 354 | assert( 0, "do not know how to handle this guy" ); |
duke@435 | 355 | } |
duke@435 | 356 | |
duke@435 | 357 | Node *proj_path_data, *proj_path_ctrl; |
duke@435 | 358 | if( proj->Opcode() == Op_IfTrue ) { |
duke@435 | 359 | if( phi_s == NULL ) { |
duke@435 | 360 | // Only construct phi_s if needed, otherwise provides |
duke@435 | 361 | // interfering use. |
duke@435 | 362 | phi_s = PhiNode::make_blank(region_s,phi); |
duke@435 | 363 | phi_s->init_req( 1, phi_c ); |
duke@435 | 364 | phi_s->init_req( 2, phi_x ); |
kvn@1448 | 365 | hook->add_req(phi_s); |
duke@435 | 366 | phi_s = phase->transform(phi_s); |
duke@435 | 367 | } |
duke@435 | 368 | proj_path_data = phi_s; |
duke@435 | 369 | proj_path_ctrl = region_s; |
duke@435 | 370 | } else { |
duke@435 | 371 | if( phi_f == NULL ) { |
duke@435 | 372 | // Only construct phi_f if needed, otherwise provides |
duke@435 | 373 | // interfering use. |
duke@435 | 374 | phi_f = PhiNode::make_blank(region_f,phi); |
duke@435 | 375 | phi_f->init_req( 1, phi_c ); |
duke@435 | 376 | phi_f->init_req( 2, phi_x ); |
kvn@1448 | 377 | hook->add_req(phi_f); |
duke@435 | 378 | phi_f = phase->transform(phi_f); |
duke@435 | 379 | } |
duke@435 | 380 | proj_path_data = phi_f; |
duke@435 | 381 | proj_path_ctrl = region_f; |
duke@435 | 382 | } |
duke@435 | 383 | |
duke@435 | 384 | // Fixup 'v' for for the split |
duke@435 | 385 | if( vop == Op_Phi ) { // Remote merge point |
duke@435 | 386 | uint i; |
duke@435 | 387 | for( i = 1; i < v->req(); i++ ) |
duke@435 | 388 | if( v->in(i) == phi ) |
duke@435 | 389 | break; |
duke@435 | 390 | v->set_req(i, proj_path_data ); |
duke@435 | 391 | } else if( v->is_ConstraintCast() ) { |
duke@435 | 392 | v->set_req(0, proj_path_ctrl ); |
duke@435 | 393 | v->set_req(1, proj_path_data ); |
duke@435 | 394 | } else |
duke@435 | 395 | ShouldNotReachHere(); |
duke@435 | 396 | } |
duke@435 | 397 | |
duke@435 | 398 | // Now replace the original iff's True/False with region_s/region_t. |
duke@435 | 399 | // This makes the original iff go dead. |
duke@435 | 400 | for (DUIterator_Last i3min, i3 = iff->last_outs(i3min); i3 >= i3min; --i3) { |
duke@435 | 401 | Node* p = iff->last_out(i3); |
duke@435 | 402 | assert( p->Opcode() == Op_IfTrue || p->Opcode() == Op_IfFalse, "" ); |
duke@435 | 403 | Node *u = (p->Opcode() == Op_IfTrue) ? region_s : region_f; |
duke@435 | 404 | // Replace p with u |
duke@435 | 405 | igvn->add_users_to_worklist(p); |
duke@435 | 406 | for (DUIterator_Last lmin, l = p->last_outs(lmin); l >= lmin;) { |
duke@435 | 407 | Node* x = p->last_out(l); |
duke@435 | 408 | igvn->hash_delete(x); |
duke@435 | 409 | uint uses_found = 0; |
duke@435 | 410 | for( uint j = 0; j < x->req(); j++ ) { |
duke@435 | 411 | if( x->in(j) == p ) { |
duke@435 | 412 | x->set_req(j, u); |
duke@435 | 413 | uses_found++; |
duke@435 | 414 | } |
duke@435 | 415 | } |
duke@435 | 416 | l -= uses_found; // we deleted 1 or more copies of this edge |
duke@435 | 417 | } |
duke@435 | 418 | igvn->remove_dead_node(p); |
duke@435 | 419 | } |
duke@435 | 420 | |
duke@435 | 421 | // Force the original merge dead |
duke@435 | 422 | igvn->hash_delete(r); |
kvn@1286 | 423 | // First, remove region's dead users. |
kvn@1286 | 424 | for (DUIterator_Last lmin, l = r->last_outs(lmin); l >= lmin;) { |
kvn@1286 | 425 | Node* u = r->last_out(l); |
kvn@1286 | 426 | if( u == r ) { |
kvn@1286 | 427 | r->set_req(0, NULL); |
kvn@1286 | 428 | } else { |
kvn@1286 | 429 | assert(u->outcnt() == 0, "only dead users"); |
kvn@1286 | 430 | igvn->remove_dead_node(u); |
kvn@1286 | 431 | } |
kvn@1286 | 432 | l -= 1; |
kvn@1286 | 433 | } |
kvn@1286 | 434 | igvn->remove_dead_node(r); |
duke@435 | 435 | |
duke@435 | 436 | // Now remove the bogus extra edges used to keep things alive |
duke@435 | 437 | igvn->remove_dead_node( hook ); |
duke@435 | 438 | |
duke@435 | 439 | // Must return either the original node (now dead) or a new node |
duke@435 | 440 | // (Do not return a top here, since that would break the uniqueness of top.) |
kvn@4115 | 441 | return new (igvn->C) ConINode(TypeInt::ZERO); |
duke@435 | 442 | } |
duke@435 | 443 | |
duke@435 | 444 | //------------------------------is_range_check--------------------------------- |
duke@435 | 445 | // Return 0 if not a range check. Return 1 if a range check and set index and |
duke@435 | 446 | // offset. Return 2 if we had to negate the test. Index is NULL if the check |
duke@435 | 447 | // is versus a constant. |
duke@435 | 448 | int IfNode::is_range_check(Node* &range, Node* &index, jint &offset) { |
duke@435 | 449 | Node* b = in(1); |
duke@435 | 450 | if (b == NULL || !b->is_Bool()) return 0; |
duke@435 | 451 | BoolNode* bn = b->as_Bool(); |
duke@435 | 452 | Node* cmp = bn->in(1); |
duke@435 | 453 | if (cmp == NULL) return 0; |
duke@435 | 454 | if (cmp->Opcode() != Op_CmpU) return 0; |
duke@435 | 455 | |
duke@435 | 456 | Node* l = cmp->in(1); |
duke@435 | 457 | Node* r = cmp->in(2); |
duke@435 | 458 | int flip_test = 1; |
duke@435 | 459 | if (bn->_test._test == BoolTest::le) { |
duke@435 | 460 | l = cmp->in(2); |
duke@435 | 461 | r = cmp->in(1); |
duke@435 | 462 | flip_test = 2; |
duke@435 | 463 | } else if (bn->_test._test != BoolTest::lt) { |
duke@435 | 464 | return 0; |
duke@435 | 465 | } |
duke@435 | 466 | if (l->is_top()) return 0; // Top input means dead test |
duke@435 | 467 | if (r->Opcode() != Op_LoadRange) return 0; |
duke@435 | 468 | |
duke@435 | 469 | // We have recognized one of these forms: |
duke@435 | 470 | // Flip 1: If (Bool[<] CmpU(l, LoadRange)) ... |
duke@435 | 471 | // Flip 2: If (Bool[<=] CmpU(LoadRange, l)) ... |
duke@435 | 472 | |
duke@435 | 473 | // Make sure it's a real range check by requiring an uncommon trap |
duke@435 | 474 | // along the OOB path. Otherwise, it's possible that the user wrote |
duke@435 | 475 | // something which optimized to look like a range check but behaves |
duke@435 | 476 | // in some other way. |
duke@435 | 477 | Node* iftrap = proj_out(flip_test == 2 ? true : false); |
duke@435 | 478 | bool found_trap = false; |
duke@435 | 479 | if (iftrap != NULL) { |
duke@435 | 480 | Node* u = iftrap->unique_ctrl_out(); |
duke@435 | 481 | if (u != NULL) { |
duke@435 | 482 | // It could be a merge point (Region) for uncommon trap. |
duke@435 | 483 | if (u->is_Region()) { |
duke@435 | 484 | Node* c = u->unique_ctrl_out(); |
duke@435 | 485 | if (c != NULL) { |
duke@435 | 486 | iftrap = u; |
duke@435 | 487 | u = c; |
duke@435 | 488 | } |
duke@435 | 489 | } |
duke@435 | 490 | if (u->in(0) == iftrap && u->is_CallStaticJava()) { |
duke@435 | 491 | int req = u->as_CallStaticJava()->uncommon_trap_request(); |
duke@435 | 492 | if (Deoptimization::trap_request_reason(req) == |
duke@435 | 493 | Deoptimization::Reason_range_check) { |
duke@435 | 494 | found_trap = true; |
duke@435 | 495 | } |
duke@435 | 496 | } |
duke@435 | 497 | } |
duke@435 | 498 | } |
duke@435 | 499 | if (!found_trap) return 0; // sorry, no cigar |
duke@435 | 500 | |
duke@435 | 501 | // Look for index+offset form |
duke@435 | 502 | Node* ind = l; |
duke@435 | 503 | jint off = 0; |
duke@435 | 504 | if (l->is_top()) { |
duke@435 | 505 | return 0; |
duke@435 | 506 | } else if (l->is_Add()) { |
duke@435 | 507 | if ((off = l->in(1)->find_int_con(0)) != 0) { |
duke@435 | 508 | ind = l->in(2); |
duke@435 | 509 | } else if ((off = l->in(2)->find_int_con(0)) != 0) { |
duke@435 | 510 | ind = l->in(1); |
duke@435 | 511 | } |
duke@435 | 512 | } else if ((off = l->find_int_con(-1)) >= 0) { |
duke@435 | 513 | // constant offset with no variable index |
duke@435 | 514 | ind = NULL; |
duke@435 | 515 | } else { |
duke@435 | 516 | // variable index with no constant offset (or dead negative index) |
duke@435 | 517 | off = 0; |
duke@435 | 518 | } |
duke@435 | 519 | |
duke@435 | 520 | // Return all the values: |
duke@435 | 521 | index = ind; |
duke@435 | 522 | offset = off; |
duke@435 | 523 | range = r; |
duke@435 | 524 | return flip_test; |
duke@435 | 525 | } |
duke@435 | 526 | |
duke@435 | 527 | //------------------------------adjust_check----------------------------------- |
duke@435 | 528 | // Adjust (widen) a prior range check |
duke@435 | 529 | static void adjust_check(Node* proj, Node* range, Node* index, |
duke@435 | 530 | int flip, jint off_lo, PhaseIterGVN* igvn) { |
duke@435 | 531 | PhaseGVN *gvn = igvn; |
duke@435 | 532 | // Break apart the old check |
duke@435 | 533 | Node *iff = proj->in(0); |
duke@435 | 534 | Node *bol = iff->in(1); |
duke@435 | 535 | if( bol->is_top() ) return; // In case a partially dead range check appears |
duke@435 | 536 | // bail (or bomb[ASSERT/DEBUG]) if NOT projection-->IfNode-->BoolNode |
duke@435 | 537 | DEBUG_ONLY( if( !bol->is_Bool() ) { proj->dump(3); fatal("Expect projection-->IfNode-->BoolNode"); } ) |
duke@435 | 538 | if( !bol->is_Bool() ) return; |
duke@435 | 539 | |
duke@435 | 540 | Node *cmp = bol->in(1); |
duke@435 | 541 | // Compute a new check |
duke@435 | 542 | Node *new_add = gvn->intcon(off_lo); |
duke@435 | 543 | if( index ) { |
kvn@4115 | 544 | new_add = off_lo ? gvn->transform(new (gvn->C) AddINode( index, new_add )) : index; |
duke@435 | 545 | } |
duke@435 | 546 | Node *new_cmp = (flip == 1) |
kvn@4115 | 547 | ? new (gvn->C) CmpUNode( new_add, range ) |
kvn@4115 | 548 | : new (gvn->C) CmpUNode( range, new_add ); |
duke@435 | 549 | new_cmp = gvn->transform(new_cmp); |
duke@435 | 550 | // See if no need to adjust the existing check |
duke@435 | 551 | if( new_cmp == cmp ) return; |
duke@435 | 552 | // Else, adjust existing check |
kvn@4115 | 553 | Node *new_bol = gvn->transform( new (gvn->C) BoolNode( new_cmp, bol->as_Bool()->_test._test ) ); |
kvn@3847 | 554 | igvn->rehash_node_delayed( iff ); |
duke@435 | 555 | iff->set_req_X( 1, new_bol, igvn ); |
duke@435 | 556 | } |
duke@435 | 557 | |
duke@435 | 558 | //------------------------------up_one_dom------------------------------------- |
duke@435 | 559 | // Walk up the dominator tree one step. Return NULL at root or true |
duke@435 | 560 | // complex merges. Skips through small diamonds. |
duke@435 | 561 | Node* IfNode::up_one_dom(Node *curr, bool linear_only) { |
duke@435 | 562 | Node *dom = curr->in(0); |
duke@435 | 563 | if( !dom ) // Found a Region degraded to a copy? |
duke@435 | 564 | return curr->nonnull_req(); // Skip thru it |
duke@435 | 565 | |
duke@435 | 566 | if( curr != dom ) // Normal walk up one step? |
duke@435 | 567 | return dom; |
duke@435 | 568 | |
duke@435 | 569 | // Use linear_only if we are still parsing, since we cannot |
duke@435 | 570 | // trust the regions to be fully filled in. |
duke@435 | 571 | if (linear_only) |
duke@435 | 572 | return NULL; |
duke@435 | 573 | |
kvn@1588 | 574 | if( dom->is_Root() ) |
kvn@1588 | 575 | return NULL; |
kvn@1588 | 576 | |
duke@435 | 577 | // Else hit a Region. Check for a loop header |
duke@435 | 578 | if( dom->is_Loop() ) |
duke@435 | 579 | return dom->in(1); // Skip up thru loops |
duke@435 | 580 | |
duke@435 | 581 | // Check for small diamonds |
duke@435 | 582 | Node *din1, *din2, *din3, *din4; |
duke@435 | 583 | if( dom->req() == 3 && // 2-path merge point |
duke@435 | 584 | (din1 = dom ->in(1)) && // Left path exists |
duke@435 | 585 | (din2 = dom ->in(2)) && // Right path exists |
duke@435 | 586 | (din3 = din1->in(0)) && // Left path up one |
duke@435 | 587 | (din4 = din2->in(0)) ) { // Right path up one |
duke@435 | 588 | if( din3->is_Call() && // Handle a slow-path call on either arm |
duke@435 | 589 | (din3 = din3->in(0)) ) |
duke@435 | 590 | din3 = din3->in(0); |
duke@435 | 591 | if( din4->is_Call() && // Handle a slow-path call on either arm |
duke@435 | 592 | (din4 = din4->in(0)) ) |
duke@435 | 593 | din4 = din4->in(0); |
duke@435 | 594 | if( din3 == din4 && din3->is_If() ) |
duke@435 | 595 | return din3; // Skip around diamonds |
duke@435 | 596 | } |
duke@435 | 597 | |
duke@435 | 598 | // Give up the search at true merges |
duke@435 | 599 | return NULL; // Dead loop? Or hit root? |
duke@435 | 600 | } |
duke@435 | 601 | |
never@452 | 602 | |
never@452 | 603 | //------------------------------filtered_int_type-------------------------------- |
never@452 | 604 | // Return a possibly more restrictive type for val based on condition control flow for an if |
never@452 | 605 | const TypeInt* IfNode::filtered_int_type(PhaseGVN* gvn, Node *val, Node* if_proj) { |
never@452 | 606 | assert(if_proj && |
never@452 | 607 | (if_proj->Opcode() == Op_IfTrue || if_proj->Opcode() == Op_IfFalse), "expecting an if projection"); |
never@452 | 608 | if (if_proj->in(0) && if_proj->in(0)->is_If()) { |
never@452 | 609 | IfNode* iff = if_proj->in(0)->as_If(); |
never@452 | 610 | if (iff->in(1) && iff->in(1)->is_Bool()) { |
never@452 | 611 | BoolNode* bol = iff->in(1)->as_Bool(); |
never@452 | 612 | if (bol->in(1) && bol->in(1)->is_Cmp()) { |
never@452 | 613 | const CmpNode* cmp = bol->in(1)->as_Cmp(); |
never@452 | 614 | if (cmp->in(1) == val) { |
never@452 | 615 | const TypeInt* cmp2_t = gvn->type(cmp->in(2))->isa_int(); |
never@452 | 616 | if (cmp2_t != NULL) { |
never@452 | 617 | jint lo = cmp2_t->_lo; |
never@452 | 618 | jint hi = cmp2_t->_hi; |
never@452 | 619 | BoolTest::mask msk = if_proj->Opcode() == Op_IfTrue ? bol->_test._test : bol->_test.negate(); |
never@452 | 620 | switch (msk) { |
never@452 | 621 | case BoolTest::ne: |
never@452 | 622 | // Can't refine type |
never@452 | 623 | return NULL; |
never@452 | 624 | case BoolTest::eq: |
never@452 | 625 | return cmp2_t; |
never@452 | 626 | case BoolTest::lt: |
never@452 | 627 | lo = TypeInt::INT->_lo; |
never@452 | 628 | if (hi - 1 < hi) { |
never@452 | 629 | hi = hi - 1; |
never@452 | 630 | } |
never@452 | 631 | break; |
never@452 | 632 | case BoolTest::le: |
never@452 | 633 | lo = TypeInt::INT->_lo; |
never@452 | 634 | break; |
never@452 | 635 | case BoolTest::gt: |
never@452 | 636 | if (lo + 1 > lo) { |
never@452 | 637 | lo = lo + 1; |
never@452 | 638 | } |
never@452 | 639 | hi = TypeInt::INT->_hi; |
never@452 | 640 | break; |
never@452 | 641 | case BoolTest::ge: |
never@452 | 642 | // lo unchanged |
never@452 | 643 | hi = TypeInt::INT->_hi; |
never@452 | 644 | break; |
never@452 | 645 | } |
never@452 | 646 | const TypeInt* rtn_t = TypeInt::make(lo, hi, cmp2_t->_widen); |
never@452 | 647 | return rtn_t; |
never@452 | 648 | } |
never@452 | 649 | } |
never@452 | 650 | } |
never@452 | 651 | } |
never@452 | 652 | } |
never@452 | 653 | return NULL; |
never@452 | 654 | } |
never@452 | 655 | |
never@452 | 656 | //------------------------------fold_compares---------------------------- |
never@452 | 657 | // See if a pair of CmpIs can be converted into a CmpU. In some cases |
twisti@1040 | 658 | // the direction of this if is determined by the preceding if so it |
never@452 | 659 | // can be eliminate entirely. Given an if testing (CmpI n c) check |
never@452 | 660 | // for an immediately control dependent if that is testing (CmpI n c2) |
never@452 | 661 | // and has one projection leading to this if and the other projection |
never@452 | 662 | // leading to a region that merges one of this ifs control |
never@452 | 663 | // projections. |
never@452 | 664 | // |
never@452 | 665 | // If |
never@452 | 666 | // / | |
never@452 | 667 | // / | |
never@452 | 668 | // / | |
never@452 | 669 | // If | |
never@452 | 670 | // /\ | |
never@452 | 671 | // / \ | |
never@452 | 672 | // / \ | |
never@452 | 673 | // / Region |
never@452 | 674 | // |
never@452 | 675 | Node* IfNode::fold_compares(PhaseGVN* phase) { |
kvn@5110 | 676 | if (!phase->C->eliminate_boxing() || Opcode() != Op_If) return NULL; |
never@452 | 677 | |
never@452 | 678 | Node* this_cmp = in(1)->in(1); |
never@452 | 679 | if (this_cmp != NULL && this_cmp->Opcode() == Op_CmpI && |
never@452 | 680 | this_cmp->in(2)->is_Con() && this_cmp->in(2) != phase->C->top()) { |
never@452 | 681 | Node* ctrl = in(0); |
never@452 | 682 | BoolNode* this_bool = in(1)->as_Bool(); |
never@452 | 683 | Node* n = this_cmp->in(1); |
never@452 | 684 | int hi = this_cmp->in(2)->get_int(); |
never@452 | 685 | if (ctrl != NULL && ctrl->is_Proj() && ctrl->outcnt() == 1 && |
never@452 | 686 | ctrl->in(0)->is_If() && |
never@452 | 687 | ctrl->in(0)->outcnt() == 2 && |
never@452 | 688 | ctrl->in(0)->in(1)->is_Bool() && |
never@452 | 689 | ctrl->in(0)->in(1)->in(1)->Opcode() == Op_CmpI && |
never@452 | 690 | ctrl->in(0)->in(1)->in(1)->in(2)->is_Con() && |
never@452 | 691 | ctrl->in(0)->in(1)->in(1)->in(1) == n) { |
never@452 | 692 | IfNode* dom_iff = ctrl->in(0)->as_If(); |
never@452 | 693 | Node* otherproj = dom_iff->proj_out(!ctrl->as_Proj()->_con); |
never@452 | 694 | if (otherproj->outcnt() == 1 && otherproj->unique_out()->is_Region() && |
never@452 | 695 | this_bool->_test._test != BoolTest::ne && this_bool->_test._test != BoolTest::eq) { |
never@452 | 696 | // Identify which proj goes to the region and which continues on |
never@452 | 697 | RegionNode* region = otherproj->unique_out()->as_Region(); |
never@452 | 698 | Node* success = NULL; |
never@452 | 699 | Node* fail = NULL; |
never@452 | 700 | for (int i = 0; i < 2; i++) { |
never@452 | 701 | Node* proj = proj_out(i); |
never@452 | 702 | if (success == NULL && proj->outcnt() == 1 && proj->unique_out() == region) { |
never@452 | 703 | success = proj; |
never@452 | 704 | } else if (fail == NULL) { |
never@452 | 705 | fail = proj; |
never@452 | 706 | } else { |
never@452 | 707 | success = fail = NULL; |
never@452 | 708 | } |
never@452 | 709 | } |
never@452 | 710 | if (success != NULL && fail != NULL && !region->has_phi()) { |
never@452 | 711 | int lo = dom_iff->in(1)->in(1)->in(2)->get_int(); |
never@452 | 712 | BoolNode* dom_bool = dom_iff->in(1)->as_Bool(); |
never@452 | 713 | Node* dom_cmp = dom_bool->in(1); |
never@452 | 714 | const TypeInt* failtype = filtered_int_type(phase, n, ctrl); |
never@452 | 715 | if (failtype != NULL) { |
never@452 | 716 | const TypeInt* type2 = filtered_int_type(phase, n, fail); |
never@452 | 717 | if (type2 != NULL) { |
never@452 | 718 | failtype = failtype->join(type2)->is_int(); |
never@452 | 719 | } else { |
never@452 | 720 | failtype = NULL; |
never@452 | 721 | } |
never@452 | 722 | } |
never@452 | 723 | |
never@452 | 724 | if (failtype != NULL && |
never@452 | 725 | dom_bool->_test._test != BoolTest::ne && dom_bool->_test._test != BoolTest::eq) { |
never@452 | 726 | int bound = failtype->_hi - failtype->_lo + 1; |
never@452 | 727 | if (failtype->_hi != max_jint && failtype->_lo != min_jint && bound > 1) { |
never@452 | 728 | // Merge the two compares into a single unsigned compare by building (CmpU (n - lo) hi) |
never@452 | 729 | BoolTest::mask cond = fail->as_Proj()->_con ? BoolTest::lt : BoolTest::ge; |
kvn@4115 | 730 | Node* adjusted = phase->transform(new (phase->C) SubINode(n, phase->intcon(failtype->_lo))); |
kvn@4115 | 731 | Node* newcmp = phase->transform(new (phase->C) CmpUNode(adjusted, phase->intcon(bound))); |
kvn@4115 | 732 | Node* newbool = phase->transform(new (phase->C) BoolNode(newcmp, cond)); |
kvn@3847 | 733 | phase->is_IterGVN()->replace_input_of(dom_iff, 1, phase->intcon(ctrl->as_Proj()->_con)); |
never@452 | 734 | phase->hash_delete(this); |
never@452 | 735 | set_req(1, newbool); |
never@452 | 736 | return this; |
never@452 | 737 | } |
never@452 | 738 | if (failtype->_lo > failtype->_hi) { |
never@452 | 739 | // previous if determines the result of this if so |
never@452 | 740 | // replace Bool with constant |
never@452 | 741 | phase->hash_delete(this); |
never@452 | 742 | set_req(1, phase->intcon(success->as_Proj()->_con)); |
never@452 | 743 | return this; |
never@452 | 744 | } |
never@452 | 745 | } |
never@452 | 746 | } |
never@452 | 747 | } |
never@452 | 748 | } |
never@452 | 749 | } |
never@452 | 750 | return NULL; |
never@452 | 751 | } |
never@452 | 752 | |
duke@435 | 753 | //------------------------------remove_useless_bool---------------------------- |
duke@435 | 754 | // Check for people making a useless boolean: things like |
duke@435 | 755 | // if( (x < y ? true : false) ) { ... } |
duke@435 | 756 | // Replace with if( x < y ) { ... } |
duke@435 | 757 | static Node *remove_useless_bool(IfNode *iff, PhaseGVN *phase) { |
duke@435 | 758 | Node *i1 = iff->in(1); |
duke@435 | 759 | if( !i1->is_Bool() ) return NULL; |
duke@435 | 760 | BoolNode *bol = i1->as_Bool(); |
duke@435 | 761 | |
duke@435 | 762 | Node *cmp = bol->in(1); |
duke@435 | 763 | if( cmp->Opcode() != Op_CmpI ) return NULL; |
duke@435 | 764 | |
duke@435 | 765 | // Must be comparing against a bool |
duke@435 | 766 | const Type *cmp2_t = phase->type( cmp->in(2) ); |
duke@435 | 767 | if( cmp2_t != TypeInt::ZERO && |
duke@435 | 768 | cmp2_t != TypeInt::ONE ) |
duke@435 | 769 | return NULL; |
duke@435 | 770 | |
duke@435 | 771 | // Find a prior merge point merging the boolean |
duke@435 | 772 | i1 = cmp->in(1); |
duke@435 | 773 | if( !i1->is_Phi() ) return NULL; |
duke@435 | 774 | PhiNode *phi = i1->as_Phi(); |
duke@435 | 775 | if( phase->type( phi ) != TypeInt::BOOL ) |
duke@435 | 776 | return NULL; |
duke@435 | 777 | |
duke@435 | 778 | // Check for diamond pattern |
duke@435 | 779 | int true_path = phi->is_diamond_phi(); |
duke@435 | 780 | if( true_path == 0 ) return NULL; |
duke@435 | 781 | |
never@685 | 782 | // Make sure that iff and the control of the phi are different. This |
never@685 | 783 | // should really only happen for dead control flow since it requires |
never@685 | 784 | // an illegal cycle. |
never@685 | 785 | if (phi->in(0)->in(1)->in(0) == iff) return NULL; |
never@685 | 786 | |
duke@435 | 787 | // phi->region->if_proj->ifnode->bool->cmp |
duke@435 | 788 | BoolNode *bol2 = phi->in(0)->in(1)->in(0)->in(1)->as_Bool(); |
duke@435 | 789 | |
duke@435 | 790 | // Now get the 'sense' of the test correct so we can plug in |
duke@435 | 791 | // either iff2->in(1) or its complement. |
duke@435 | 792 | int flip = 0; |
duke@435 | 793 | if( bol->_test._test == BoolTest::ne ) flip = 1-flip; |
duke@435 | 794 | else if( bol->_test._test != BoolTest::eq ) return NULL; |
duke@435 | 795 | if( cmp2_t == TypeInt::ZERO ) flip = 1-flip; |
duke@435 | 796 | |
duke@435 | 797 | const Type *phi1_t = phase->type( phi->in(1) ); |
duke@435 | 798 | const Type *phi2_t = phase->type( phi->in(2) ); |
duke@435 | 799 | // Check for Phi(0,1) and flip |
duke@435 | 800 | if( phi1_t == TypeInt::ZERO ) { |
duke@435 | 801 | if( phi2_t != TypeInt::ONE ) return NULL; |
duke@435 | 802 | flip = 1-flip; |
duke@435 | 803 | } else { |
duke@435 | 804 | // Check for Phi(1,0) |
duke@435 | 805 | if( phi1_t != TypeInt::ONE ) return NULL; |
duke@435 | 806 | if( phi2_t != TypeInt::ZERO ) return NULL; |
duke@435 | 807 | } |
duke@435 | 808 | if( true_path == 2 ) { |
duke@435 | 809 | flip = 1-flip; |
duke@435 | 810 | } |
duke@435 | 811 | |
duke@435 | 812 | Node* new_bol = (flip ? phase->transform( bol2->negate(phase) ) : bol2); |
never@685 | 813 | assert(new_bol != iff->in(1), "must make progress"); |
duke@435 | 814 | iff->set_req(1, new_bol); |
duke@435 | 815 | // Intervening diamond probably goes dead |
duke@435 | 816 | phase->C->set_major_progress(); |
duke@435 | 817 | return iff; |
duke@435 | 818 | } |
duke@435 | 819 | |
duke@435 | 820 | static IfNode* idealize_test(PhaseGVN* phase, IfNode* iff); |
duke@435 | 821 | |
duke@435 | 822 | //------------------------------Ideal------------------------------------------ |
duke@435 | 823 | // Return a node which is more "ideal" than the current node. Strip out |
duke@435 | 824 | // control copies |
duke@435 | 825 | Node *IfNode::Ideal(PhaseGVN *phase, bool can_reshape) { |
duke@435 | 826 | if (remove_dead_region(phase, can_reshape)) return this; |
duke@435 | 827 | // No Def-Use info? |
duke@435 | 828 | if (!can_reshape) return NULL; |
duke@435 | 829 | PhaseIterGVN *igvn = phase->is_IterGVN(); |
duke@435 | 830 | |
duke@435 | 831 | // Don't bother trying to transform a dead if |
duke@435 | 832 | if (in(0)->is_top()) return NULL; |
duke@435 | 833 | // Don't bother trying to transform an if with a dead test |
duke@435 | 834 | if (in(1)->is_top()) return NULL; |
duke@435 | 835 | // Another variation of a dead test |
duke@435 | 836 | if (in(1)->is_Con()) return NULL; |
duke@435 | 837 | // Another variation of a dead if |
duke@435 | 838 | if (outcnt() < 2) return NULL; |
duke@435 | 839 | |
duke@435 | 840 | // Canonicalize the test. |
duke@435 | 841 | Node* idt_if = idealize_test(phase, this); |
duke@435 | 842 | if (idt_if != NULL) return idt_if; |
duke@435 | 843 | |
duke@435 | 844 | // Try to split the IF |
duke@435 | 845 | Node *s = split_if(this, igvn); |
duke@435 | 846 | if (s != NULL) return s; |
duke@435 | 847 | |
duke@435 | 848 | // Check for people making a useless boolean: things like |
duke@435 | 849 | // if( (x < y ? true : false) ) { ... } |
duke@435 | 850 | // Replace with if( x < y ) { ... } |
duke@435 | 851 | Node *bol2 = remove_useless_bool(this, phase); |
duke@435 | 852 | if( bol2 ) return bol2; |
duke@435 | 853 | |
duke@435 | 854 | // Setup to scan up the CFG looking for a dominating test |
duke@435 | 855 | Node *dom = in(0); |
duke@435 | 856 | Node *prev_dom = this; |
duke@435 | 857 | |
duke@435 | 858 | // Check for range-check vs other kinds of tests |
duke@435 | 859 | Node *index1, *range1; |
duke@435 | 860 | jint offset1; |
duke@435 | 861 | int flip1 = is_range_check(range1, index1, offset1); |
duke@435 | 862 | if( flip1 ) { |
duke@435 | 863 | Node *first_prev_dom = NULL; |
duke@435 | 864 | |
duke@435 | 865 | // Try to remove extra range checks. All 'up_one_dom' gives up at merges |
duke@435 | 866 | // so all checks we inspect post-dominate the top-most check we find. |
duke@435 | 867 | // If we are going to fail the current check and we reach the top check |
twisti@1040 | 868 | // then we are guaranteed to fail, so just start interpreting there. |
duke@435 | 869 | // We 'expand' the top 2 range checks to include all post-dominating |
duke@435 | 870 | // checks. |
duke@435 | 871 | |
duke@435 | 872 | // The top 2 range checks seen |
duke@435 | 873 | Node *prev_chk1 = NULL; |
duke@435 | 874 | Node *prev_chk2 = NULL; |
duke@435 | 875 | // Low and high offsets seen so far |
duke@435 | 876 | jint off_lo = offset1; |
duke@435 | 877 | jint off_hi = offset1; |
duke@435 | 878 | |
duke@435 | 879 | // Scan for the top 2 checks and collect range of offsets |
duke@435 | 880 | for( int dist = 0; dist < 999; dist++ ) { // Range-Check scan limit |
duke@435 | 881 | if( dom->Opcode() == Op_If && // Not same opcode? |
duke@435 | 882 | prev_dom->in(0) == dom ) { // One path of test does dominate? |
duke@435 | 883 | if( dom == this ) return NULL; // dead loop |
duke@435 | 884 | // See if this is a range check |
duke@435 | 885 | Node *index2, *range2; |
duke@435 | 886 | jint offset2; |
duke@435 | 887 | int flip2 = dom->as_If()->is_range_check(range2, index2, offset2); |
duke@435 | 888 | // See if this is a _matching_ range check, checking against |
duke@435 | 889 | // the same array bounds. |
duke@435 | 890 | if( flip2 == flip1 && range2 == range1 && index2 == index1 && |
duke@435 | 891 | dom->outcnt() == 2 ) { |
duke@435 | 892 | // Gather expanded bounds |
duke@435 | 893 | off_lo = MIN2(off_lo,offset2); |
duke@435 | 894 | off_hi = MAX2(off_hi,offset2); |
duke@435 | 895 | // Record top 2 range checks |
duke@435 | 896 | prev_chk2 = prev_chk1; |
duke@435 | 897 | prev_chk1 = prev_dom; |
duke@435 | 898 | // If we match the test exactly, then the top test covers |
duke@435 | 899 | // both our lower and upper bounds. |
duke@435 | 900 | if( dom->in(1) == in(1) ) |
duke@435 | 901 | prev_chk2 = prev_chk1; |
duke@435 | 902 | } |
duke@435 | 903 | } |
duke@435 | 904 | prev_dom = dom; |
duke@435 | 905 | dom = up_one_dom( dom ); |
duke@435 | 906 | if( !dom ) break; |
duke@435 | 907 | } |
duke@435 | 908 | |
duke@435 | 909 | |
duke@435 | 910 | // Attempt to widen the dominating range check to cover some later |
duke@435 | 911 | // ones. Since range checks "fail" by uncommon-trapping to the |
duke@435 | 912 | // interpreter, widening a check can make us speculative enter the |
duke@435 | 913 | // interpreter. If we see range-check deopt's, do not widen! |
duke@435 | 914 | if (!phase->C->allow_range_check_smearing()) return NULL; |
duke@435 | 915 | |
duke@435 | 916 | // Constant indices only need to check the upper bound. |
duke@435 | 917 | // Non-constance indices must check both low and high. |
duke@435 | 918 | if( index1 ) { |
duke@435 | 919 | // Didn't find 2 prior covering checks, so cannot remove anything. |
duke@435 | 920 | if( !prev_chk2 ) return NULL; |
duke@435 | 921 | // 'Widen' the offsets of the 1st and 2nd covering check |
duke@435 | 922 | adjust_check( prev_chk1, range1, index1, flip1, off_lo, igvn ); |
duke@435 | 923 | // Do not call adjust_check twice on the same projection |
duke@435 | 924 | // as the first call may have transformed the BoolNode to a ConI |
duke@435 | 925 | if( prev_chk1 != prev_chk2 ) { |
duke@435 | 926 | adjust_check( prev_chk2, range1, index1, flip1, off_hi, igvn ); |
duke@435 | 927 | } |
duke@435 | 928 | // Test is now covered by prior checks, dominate it out |
duke@435 | 929 | prev_dom = prev_chk2; |
duke@435 | 930 | } else { |
duke@435 | 931 | // Didn't find prior covering check, so cannot remove anything. |
duke@435 | 932 | if( !prev_chk1 ) return NULL; |
duke@435 | 933 | // 'Widen' the offset of the 1st and only covering check |
duke@435 | 934 | adjust_check( prev_chk1, range1, index1, flip1, off_hi, igvn ); |
duke@435 | 935 | // Test is now covered by prior checks, dominate it out |
duke@435 | 936 | prev_dom = prev_chk1; |
duke@435 | 937 | } |
duke@435 | 938 | |
duke@435 | 939 | |
duke@435 | 940 | } else { // Scan for an equivalent test |
duke@435 | 941 | |
duke@435 | 942 | Node *cmp; |
duke@435 | 943 | int dist = 0; // Cutoff limit for search |
duke@435 | 944 | int op = Opcode(); |
duke@435 | 945 | if( op == Op_If && |
duke@435 | 946 | (cmp=in(1)->in(1))->Opcode() == Op_CmpP ) { |
duke@435 | 947 | if( cmp->in(2) != NULL && // make sure cmp is not already dead |
duke@435 | 948 | cmp->in(2)->bottom_type() == TypePtr::NULL_PTR ) { |
duke@435 | 949 | dist = 64; // Limit for null-pointer scans |
duke@435 | 950 | } else { |
duke@435 | 951 | dist = 4; // Do not bother for random pointer tests |
duke@435 | 952 | } |
duke@435 | 953 | } else { |
duke@435 | 954 | dist = 4; // Limit for random junky scans |
duke@435 | 955 | } |
duke@435 | 956 | |
duke@435 | 957 | // Normal equivalent-test check. |
duke@435 | 958 | if( !dom ) return NULL; // Dead loop? |
duke@435 | 959 | |
never@452 | 960 | Node* result = fold_compares(phase); |
never@452 | 961 | if (result != NULL) { |
never@452 | 962 | return result; |
never@452 | 963 | } |
never@452 | 964 | |
duke@435 | 965 | // Search up the dominator tree for an If with an identical test |
duke@435 | 966 | while( dom->Opcode() != op || // Not same opcode? |
duke@435 | 967 | dom->in(1) != in(1) || // Not same input 1? |
duke@435 | 968 | (req() == 3 && dom->in(2) != in(2)) || // Not same input 2? |
duke@435 | 969 | prev_dom->in(0) != dom ) { // One path of test does not dominate? |
duke@435 | 970 | if( dist < 0 ) return NULL; |
duke@435 | 971 | |
duke@435 | 972 | dist--; |
duke@435 | 973 | prev_dom = dom; |
duke@435 | 974 | dom = up_one_dom( dom ); |
duke@435 | 975 | if( !dom ) return NULL; |
duke@435 | 976 | } |
duke@435 | 977 | |
duke@435 | 978 | // Check that we did not follow a loop back to ourselves |
duke@435 | 979 | if( this == dom ) |
duke@435 | 980 | return NULL; |
duke@435 | 981 | |
duke@435 | 982 | if( dist > 2 ) // Add to count of NULL checks elided |
duke@435 | 983 | explicit_null_checks_elided++; |
duke@435 | 984 | |
duke@435 | 985 | } // End of Else scan for an equivalent test |
duke@435 | 986 | |
duke@435 | 987 | // Hit! Remove this IF |
duke@435 | 988 | #ifndef PRODUCT |
duke@435 | 989 | if( TraceIterativeGVN ) { |
duke@435 | 990 | tty->print(" Removing IfNode: "); this->dump(); |
duke@435 | 991 | } |
duke@435 | 992 | if( VerifyOpto && !phase->allow_progress() ) { |
duke@435 | 993 | // Found an equivalent dominating test, |
duke@435 | 994 | // we can not guarantee reaching a fix-point for these during iterativeGVN |
duke@435 | 995 | // since intervening nodes may not change. |
duke@435 | 996 | return NULL; |
duke@435 | 997 | } |
duke@435 | 998 | #endif |
duke@435 | 999 | |
duke@435 | 1000 | // Replace dominated IfNode |
duke@435 | 1001 | dominated_by( prev_dom, igvn ); |
duke@435 | 1002 | |
duke@435 | 1003 | // Must return either the original node (now dead) or a new node |
duke@435 | 1004 | // (Do not return a top here, since that would break the uniqueness of top.) |
kvn@4115 | 1005 | return new (phase->C) ConINode(TypeInt::ZERO); |
duke@435 | 1006 | } |
duke@435 | 1007 | |
duke@435 | 1008 | //------------------------------dominated_by----------------------------------- |
duke@435 | 1009 | void IfNode::dominated_by( Node *prev_dom, PhaseIterGVN *igvn ) { |
duke@435 | 1010 | igvn->hash_delete(this); // Remove self to prevent spurious V-N |
duke@435 | 1011 | Node *idom = in(0); |
duke@435 | 1012 | // Need opcode to decide which way 'this' test goes |
duke@435 | 1013 | int prev_op = prev_dom->Opcode(); |
duke@435 | 1014 | Node *top = igvn->C->top(); // Shortcut to top |
duke@435 | 1015 | |
kvn@3038 | 1016 | // Loop predicates may have depending checks which should not |
kvn@3038 | 1017 | // be skipped. For example, range check predicate has two checks |
kvn@3038 | 1018 | // for lower and upper bounds. |
kvn@3038 | 1019 | ProjNode* unc_proj = proj_out(1 - prev_dom->as_Proj()->_con)->as_Proj(); |
kvn@3038 | 1020 | if (PhaseIdealLoop::is_uncommon_trap_proj(unc_proj, Deoptimization::Reason_predicate)) |
kvn@3038 | 1021 | prev_dom = idom; |
kvn@3038 | 1022 | |
duke@435 | 1023 | // Now walk the current IfNode's projections. |
duke@435 | 1024 | // Loop ends when 'this' has no more uses. |
duke@435 | 1025 | for (DUIterator_Last imin, i = last_outs(imin); i >= imin; --i) { |
duke@435 | 1026 | Node *ifp = last_out(i); // Get IfTrue/IfFalse |
duke@435 | 1027 | igvn->add_users_to_worklist(ifp); |
duke@435 | 1028 | // Check which projection it is and set target. |
duke@435 | 1029 | // Data-target is either the dominating projection of the same type |
duke@435 | 1030 | // or TOP if the dominating projection is of opposite type. |
duke@435 | 1031 | // Data-target will be used as the new control edge for the non-CFG |
duke@435 | 1032 | // nodes like Casts and Loads. |
kvn@3038 | 1033 | Node *data_target = (ifp->Opcode() == prev_op) ? prev_dom : top; |
duke@435 | 1034 | // Control-target is just the If's immediate dominator or TOP. |
kvn@3038 | 1035 | Node *ctrl_target = (ifp->Opcode() == prev_op) ? idom : top; |
duke@435 | 1036 | |
duke@435 | 1037 | // For each child of an IfTrue/IfFalse projection, reroute. |
duke@435 | 1038 | // Loop ends when projection has no more uses. |
duke@435 | 1039 | for (DUIterator_Last jmin, j = ifp->last_outs(jmin); j >= jmin; --j) { |
duke@435 | 1040 | Node* s = ifp->last_out(j); // Get child of IfTrue/IfFalse |
duke@435 | 1041 | if( !s->depends_only_on_test() ) { |
duke@435 | 1042 | // Find the control input matching this def-use edge. |
duke@435 | 1043 | // For Regions it may not be in slot 0. |
duke@435 | 1044 | uint l; |
duke@435 | 1045 | for( l = 0; s->in(l) != ifp; l++ ) { } |
kvn@3847 | 1046 | igvn->replace_input_of(s, l, ctrl_target); |
duke@435 | 1047 | } else { // Else, for control producers, |
kvn@3847 | 1048 | igvn->replace_input_of(s, 0, data_target); // Move child to data-target |
duke@435 | 1049 | } |
duke@435 | 1050 | } // End for each child of a projection |
duke@435 | 1051 | |
duke@435 | 1052 | igvn->remove_dead_node(ifp); |
duke@435 | 1053 | } // End for each IfTrue/IfFalse child of If |
duke@435 | 1054 | |
duke@435 | 1055 | // Kill the IfNode |
duke@435 | 1056 | igvn->remove_dead_node(this); |
duke@435 | 1057 | } |
duke@435 | 1058 | |
duke@435 | 1059 | //------------------------------Identity--------------------------------------- |
duke@435 | 1060 | // If the test is constant & we match, then we are the input Control |
duke@435 | 1061 | Node *IfTrueNode::Identity( PhaseTransform *phase ) { |
duke@435 | 1062 | // Can only optimize if cannot go the other way |
duke@435 | 1063 | const TypeTuple *t = phase->type(in(0))->is_tuple(); |
duke@435 | 1064 | return ( t == TypeTuple::IFNEITHER || t == TypeTuple::IFTRUE ) |
duke@435 | 1065 | ? in(0)->in(0) // IfNode control |
duke@435 | 1066 | : this; // no progress |
duke@435 | 1067 | } |
duke@435 | 1068 | |
duke@435 | 1069 | //------------------------------dump_spec-------------------------------------- |
duke@435 | 1070 | #ifndef PRODUCT |
duke@435 | 1071 | void IfNode::dump_spec(outputStream *st) const { |
duke@435 | 1072 | st->print("P=%f, C=%f",_prob,_fcnt); |
duke@435 | 1073 | } |
duke@435 | 1074 | #endif |
duke@435 | 1075 | |
duke@435 | 1076 | //------------------------------idealize_test---------------------------------- |
duke@435 | 1077 | // Try to canonicalize tests better. Peek at the Cmp/Bool/If sequence and |
duke@435 | 1078 | // come up with a canonical sequence. Bools getting 'eq', 'gt' and 'ge' forms |
duke@435 | 1079 | // converted to 'ne', 'le' and 'lt' forms. IfTrue/IfFalse get swapped as |
duke@435 | 1080 | // needed. |
duke@435 | 1081 | static IfNode* idealize_test(PhaseGVN* phase, IfNode* iff) { |
duke@435 | 1082 | assert(iff->in(0) != NULL, "If must be live"); |
duke@435 | 1083 | |
duke@435 | 1084 | if (iff->outcnt() != 2) return NULL; // Malformed projections. |
duke@435 | 1085 | Node* old_if_f = iff->proj_out(false); |
duke@435 | 1086 | Node* old_if_t = iff->proj_out(true); |
duke@435 | 1087 | |
duke@435 | 1088 | // CountedLoopEnds want the back-control test to be TRUE, irregardless of |
duke@435 | 1089 | // whether they are testing a 'gt' or 'lt' condition. The 'gt' condition |
duke@435 | 1090 | // happens in count-down loops |
duke@435 | 1091 | if (iff->is_CountedLoopEnd()) return NULL; |
duke@435 | 1092 | if (!iff->in(1)->is_Bool()) return NULL; // Happens for partially optimized IF tests |
duke@435 | 1093 | BoolNode *b = iff->in(1)->as_Bool(); |
duke@435 | 1094 | BoolTest bt = b->_test; |
duke@435 | 1095 | // Test already in good order? |
duke@435 | 1096 | if( bt.is_canonical() ) |
duke@435 | 1097 | return NULL; |
duke@435 | 1098 | |
duke@435 | 1099 | // Flip test to be canonical. Requires flipping the IfFalse/IfTrue and |
duke@435 | 1100 | // cloning the IfNode. |
kvn@4115 | 1101 | Node* new_b = phase->transform( new (phase->C) BoolNode(b->in(1), bt.negate()) ); |
duke@435 | 1102 | if( !new_b->is_Bool() ) return NULL; |
duke@435 | 1103 | b = new_b->as_Bool(); |
duke@435 | 1104 | |
duke@435 | 1105 | PhaseIterGVN *igvn = phase->is_IterGVN(); |
duke@435 | 1106 | assert( igvn, "Test is not canonical in parser?" ); |
duke@435 | 1107 | |
duke@435 | 1108 | // The IF node never really changes, but it needs to be cloned |
kvn@4115 | 1109 | iff = new (phase->C) IfNode( iff->in(0), b, 1.0-iff->_prob, iff->_fcnt); |
duke@435 | 1110 | |
duke@435 | 1111 | Node *prior = igvn->hash_find_insert(iff); |
duke@435 | 1112 | if( prior ) { |
duke@435 | 1113 | igvn->remove_dead_node(iff); |
duke@435 | 1114 | iff = (IfNode*)prior; |
duke@435 | 1115 | } else { |
duke@435 | 1116 | // Cannot call transform on it just yet |
duke@435 | 1117 | igvn->set_type_bottom(iff); |
duke@435 | 1118 | } |
duke@435 | 1119 | igvn->_worklist.push(iff); |
duke@435 | 1120 | |
duke@435 | 1121 | // Now handle projections. Cloning not required. |
kvn@4115 | 1122 | Node* new_if_f = (Node*)(new (phase->C) IfFalseNode( iff )); |
kvn@4115 | 1123 | Node* new_if_t = (Node*)(new (phase->C) IfTrueNode ( iff )); |
duke@435 | 1124 | |
duke@435 | 1125 | igvn->register_new_node_with_optimizer(new_if_f); |
duke@435 | 1126 | igvn->register_new_node_with_optimizer(new_if_t); |
duke@435 | 1127 | // Flip test, so flip trailing control |
kvn@1976 | 1128 | igvn->replace_node(old_if_f, new_if_t); |
kvn@1976 | 1129 | igvn->replace_node(old_if_t, new_if_f); |
duke@435 | 1130 | |
duke@435 | 1131 | // Progress |
duke@435 | 1132 | return iff; |
duke@435 | 1133 | } |
duke@435 | 1134 | |
duke@435 | 1135 | //------------------------------Identity--------------------------------------- |
duke@435 | 1136 | // If the test is constant & we match, then we are the input Control |
duke@435 | 1137 | Node *IfFalseNode::Identity( PhaseTransform *phase ) { |
duke@435 | 1138 | // Can only optimize if cannot go the other way |
duke@435 | 1139 | const TypeTuple *t = phase->type(in(0))->is_tuple(); |
duke@435 | 1140 | return ( t == TypeTuple::IFNEITHER || t == TypeTuple::IFFALSE ) |
duke@435 | 1141 | ? in(0)->in(0) // IfNode control |
duke@435 | 1142 | : this; // no progress |
duke@435 | 1143 | } |