src/share/vm/opto/loopPredicate.cpp

Wed, 27 Apr 2016 01:25:04 +0800

author
aoqi
date
Wed, 27 Apr 2016 01:25:04 +0800
changeset 0
f90c822e73f8
child 6876
710a3c8b516e
permissions
-rw-r--r--

Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/
changeset: 6782:28b50d07f6f8
tag: jdk8u25-b17

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation.
aoqi@0 8 *
aoqi@0 9 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 12 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 13 * accompanied this code).
aoqi@0 14 *
aoqi@0 15 * You should have received a copy of the GNU General Public License version
aoqi@0 16 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 18 *
aoqi@0 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 20 * or visit www.oracle.com if you need additional information or have any
aoqi@0 21 * questions.
aoqi@0 22 *
aoqi@0 23 */
aoqi@0 24
aoqi@0 25 #include "precompiled.hpp"
aoqi@0 26 #include "opto/loopnode.hpp"
aoqi@0 27 #include "opto/addnode.hpp"
aoqi@0 28 #include "opto/callnode.hpp"
aoqi@0 29 #include "opto/connode.hpp"
aoqi@0 30 #include "opto/loopnode.hpp"
aoqi@0 31 #include "opto/mulnode.hpp"
aoqi@0 32 #include "opto/rootnode.hpp"
aoqi@0 33 #include "opto/subnode.hpp"
aoqi@0 34
aoqi@0 35 /*
aoqi@0 36 * The general idea of Loop Predication is to insert a predicate on the entry
aoqi@0 37 * path to a loop, and raise a uncommon trap if the check of the condition fails.
aoqi@0 38 * The condition checks are promoted from inside the loop body, and thus
aoqi@0 39 * the checks inside the loop could be eliminated. Currently, loop predication
aoqi@0 40 * optimization has been applied to remove array range check and loop invariant
aoqi@0 41 * checks (such as null checks).
aoqi@0 42 */
aoqi@0 43
aoqi@0 44 //-------------------------------register_control-------------------------
aoqi@0 45 void PhaseIdealLoop::register_control(Node* n, IdealLoopTree *loop, Node* pred) {
aoqi@0 46 assert(n->is_CFG(), "must be control node");
aoqi@0 47 _igvn.register_new_node_with_optimizer(n);
aoqi@0 48 loop->_body.push(n);
aoqi@0 49 set_loop(n, loop);
aoqi@0 50 // When called from beautify_loops() idom is not constructed yet.
aoqi@0 51 if (_idom != NULL) {
aoqi@0 52 set_idom(n, pred, dom_depth(pred));
aoqi@0 53 }
aoqi@0 54 }
aoqi@0 55
aoqi@0 56 //------------------------------create_new_if_for_predicate------------------------
aoqi@0 57 // create a new if above the uct_if_pattern for the predicate to be promoted.
aoqi@0 58 //
aoqi@0 59 // before after
aoqi@0 60 // ---------- ----------
aoqi@0 61 // ctrl ctrl
aoqi@0 62 // | |
aoqi@0 63 // | |
aoqi@0 64 // v v
aoqi@0 65 // iff new_iff
aoqi@0 66 // / \ / \
aoqi@0 67 // / \ / \
aoqi@0 68 // v v v v
aoqi@0 69 // uncommon_proj cont_proj if_uct if_cont
aoqi@0 70 // \ | | | |
aoqi@0 71 // \ | | | |
aoqi@0 72 // v v v | v
aoqi@0 73 // rgn loop | iff
aoqi@0 74 // | | / \
aoqi@0 75 // | | / \
aoqi@0 76 // v | v v
aoqi@0 77 // uncommon_trap | uncommon_proj cont_proj
aoqi@0 78 // \ \ | |
aoqi@0 79 // \ \ | |
aoqi@0 80 // v v v v
aoqi@0 81 // rgn loop
aoqi@0 82 // |
aoqi@0 83 // |
aoqi@0 84 // v
aoqi@0 85 // uncommon_trap
aoqi@0 86 //
aoqi@0 87 //
aoqi@0 88 // We will create a region to guard the uct call if there is no one there.
aoqi@0 89 // The true projecttion (if_cont) of the new_iff is returned.
aoqi@0 90 // This code is also used to clone predicates to clonned loops.
aoqi@0 91 ProjNode* PhaseIdealLoop::create_new_if_for_predicate(ProjNode* cont_proj, Node* new_entry,
aoqi@0 92 Deoptimization::DeoptReason reason) {
aoqi@0 93 assert(cont_proj->is_uncommon_trap_if_pattern(reason), "must be a uct if pattern!");
aoqi@0 94 IfNode* iff = cont_proj->in(0)->as_If();
aoqi@0 95
aoqi@0 96 ProjNode *uncommon_proj = iff->proj_out(1 - cont_proj->_con);
aoqi@0 97 Node *rgn = uncommon_proj->unique_ctrl_out();
aoqi@0 98 assert(rgn->is_Region() || rgn->is_Call(), "must be a region or call uct");
aoqi@0 99
aoqi@0 100 uint proj_index = 1; // region's edge corresponding to uncommon_proj
aoqi@0 101 if (!rgn->is_Region()) { // create a region to guard the call
aoqi@0 102 assert(rgn->is_Call(), "must be call uct");
aoqi@0 103 CallNode* call = rgn->as_Call();
aoqi@0 104 IdealLoopTree* loop = get_loop(call);
aoqi@0 105 rgn = new (C) RegionNode(1);
aoqi@0 106 rgn->add_req(uncommon_proj);
aoqi@0 107 register_control(rgn, loop, uncommon_proj);
aoqi@0 108 _igvn.hash_delete(call);
aoqi@0 109 call->set_req(0, rgn);
aoqi@0 110 // When called from beautify_loops() idom is not constructed yet.
aoqi@0 111 if (_idom != NULL) {
aoqi@0 112 set_idom(call, rgn, dom_depth(rgn));
aoqi@0 113 }
aoqi@0 114 } else {
aoqi@0 115 // Find region's edge corresponding to uncommon_proj
aoqi@0 116 for (; proj_index < rgn->req(); proj_index++)
aoqi@0 117 if (rgn->in(proj_index) == uncommon_proj) break;
aoqi@0 118 assert(proj_index < rgn->req(), "sanity");
aoqi@0 119 }
aoqi@0 120
aoqi@0 121 Node* entry = iff->in(0);
aoqi@0 122 if (new_entry != NULL) {
aoqi@0 123 // Clonning the predicate to new location.
aoqi@0 124 entry = new_entry;
aoqi@0 125 }
aoqi@0 126 // Create new_iff
aoqi@0 127 IdealLoopTree* lp = get_loop(entry);
aoqi@0 128 IfNode *new_iff = iff->clone()->as_If();
aoqi@0 129 new_iff->set_req(0, entry);
aoqi@0 130 register_control(new_iff, lp, entry);
aoqi@0 131 Node *if_cont = new (C) IfTrueNode(new_iff);
aoqi@0 132 Node *if_uct = new (C) IfFalseNode(new_iff);
aoqi@0 133 if (cont_proj->is_IfFalse()) {
aoqi@0 134 // Swap
aoqi@0 135 Node* tmp = if_uct; if_uct = if_cont; if_cont = tmp;
aoqi@0 136 }
aoqi@0 137 register_control(if_cont, lp, new_iff);
aoqi@0 138 register_control(if_uct, get_loop(rgn), new_iff);
aoqi@0 139
aoqi@0 140 // if_uct to rgn
aoqi@0 141 _igvn.hash_delete(rgn);
aoqi@0 142 rgn->add_req(if_uct);
aoqi@0 143 // When called from beautify_loops() idom is not constructed yet.
aoqi@0 144 if (_idom != NULL) {
aoqi@0 145 Node* ridom = idom(rgn);
aoqi@0 146 Node* nrdom = dom_lca(ridom, new_iff);
aoqi@0 147 set_idom(rgn, nrdom, dom_depth(rgn));
aoqi@0 148 }
aoqi@0 149
aoqi@0 150 // If rgn has phis add new edges which has the same
aoqi@0 151 // value as on original uncommon_proj pass.
aoqi@0 152 assert(rgn->in(rgn->req() -1) == if_uct, "new edge should be last");
aoqi@0 153 bool has_phi = false;
aoqi@0 154 for (DUIterator_Fast imax, i = rgn->fast_outs(imax); i < imax; i++) {
aoqi@0 155 Node* use = rgn->fast_out(i);
aoqi@0 156 if (use->is_Phi() && use->outcnt() > 0) {
aoqi@0 157 assert(use->in(0) == rgn, "");
aoqi@0 158 _igvn.rehash_node_delayed(use);
aoqi@0 159 use->add_req(use->in(proj_index));
aoqi@0 160 has_phi = true;
aoqi@0 161 }
aoqi@0 162 }
aoqi@0 163 assert(!has_phi || rgn->req() > 3, "no phis when region is created");
aoqi@0 164
aoqi@0 165 if (new_entry == NULL) {
aoqi@0 166 // Attach if_cont to iff
aoqi@0 167 _igvn.hash_delete(iff);
aoqi@0 168 iff->set_req(0, if_cont);
aoqi@0 169 if (_idom != NULL) {
aoqi@0 170 set_idom(iff, if_cont, dom_depth(iff));
aoqi@0 171 }
aoqi@0 172 }
aoqi@0 173 return if_cont->as_Proj();
aoqi@0 174 }
aoqi@0 175
aoqi@0 176 //------------------------------create_new_if_for_predicate------------------------
aoqi@0 177 // Create a new if below new_entry for the predicate to be cloned (IGVN optimization)
aoqi@0 178 ProjNode* PhaseIterGVN::create_new_if_for_predicate(ProjNode* cont_proj, Node* new_entry,
aoqi@0 179 Deoptimization::DeoptReason reason) {
aoqi@0 180 assert(new_entry != 0, "only used for clone predicate");
aoqi@0 181 assert(cont_proj->is_uncommon_trap_if_pattern(reason), "must be a uct if pattern!");
aoqi@0 182 IfNode* iff = cont_proj->in(0)->as_If();
aoqi@0 183
aoqi@0 184 ProjNode *uncommon_proj = iff->proj_out(1 - cont_proj->_con);
aoqi@0 185 Node *rgn = uncommon_proj->unique_ctrl_out();
aoqi@0 186 assert(rgn->is_Region() || rgn->is_Call(), "must be a region or call uct");
aoqi@0 187
aoqi@0 188 uint proj_index = 1; // region's edge corresponding to uncommon_proj
aoqi@0 189 if (!rgn->is_Region()) { // create a region to guard the call
aoqi@0 190 assert(rgn->is_Call(), "must be call uct");
aoqi@0 191 CallNode* call = rgn->as_Call();
aoqi@0 192 rgn = new (C) RegionNode(1);
aoqi@0 193 register_new_node_with_optimizer(rgn);
aoqi@0 194 rgn->add_req(uncommon_proj);
aoqi@0 195 hash_delete(call);
aoqi@0 196 call->set_req(0, rgn);
aoqi@0 197 } else {
aoqi@0 198 // Find region's edge corresponding to uncommon_proj
aoqi@0 199 for (; proj_index < rgn->req(); proj_index++)
aoqi@0 200 if (rgn->in(proj_index) == uncommon_proj) break;
aoqi@0 201 assert(proj_index < rgn->req(), "sanity");
aoqi@0 202 }
aoqi@0 203
aoqi@0 204 // Create new_iff in new location.
aoqi@0 205 IfNode *new_iff = iff->clone()->as_If();
aoqi@0 206 new_iff->set_req(0, new_entry);
aoqi@0 207
aoqi@0 208 register_new_node_with_optimizer(new_iff);
aoqi@0 209 Node *if_cont = new (C) IfTrueNode(new_iff);
aoqi@0 210 Node *if_uct = new (C) IfFalseNode(new_iff);
aoqi@0 211 if (cont_proj->is_IfFalse()) {
aoqi@0 212 // Swap
aoqi@0 213 Node* tmp = if_uct; if_uct = if_cont; if_cont = tmp;
aoqi@0 214 }
aoqi@0 215 register_new_node_with_optimizer(if_cont);
aoqi@0 216 register_new_node_with_optimizer(if_uct);
aoqi@0 217
aoqi@0 218 // if_uct to rgn
aoqi@0 219 hash_delete(rgn);
aoqi@0 220 rgn->add_req(if_uct);
aoqi@0 221
aoqi@0 222 // If rgn has phis add corresponding new edges which has the same
aoqi@0 223 // value as on original uncommon_proj pass.
aoqi@0 224 assert(rgn->in(rgn->req() -1) == if_uct, "new edge should be last");
aoqi@0 225 bool has_phi = false;
aoqi@0 226 for (DUIterator_Fast imax, i = rgn->fast_outs(imax); i < imax; i++) {
aoqi@0 227 Node* use = rgn->fast_out(i);
aoqi@0 228 if (use->is_Phi() && use->outcnt() > 0) {
aoqi@0 229 rehash_node_delayed(use);
aoqi@0 230 use->add_req(use->in(proj_index));
aoqi@0 231 has_phi = true;
aoqi@0 232 }
aoqi@0 233 }
aoqi@0 234 assert(!has_phi || rgn->req() > 3, "no phis when region is created");
aoqi@0 235
aoqi@0 236 return if_cont->as_Proj();
aoqi@0 237 }
aoqi@0 238
aoqi@0 239 //--------------------------clone_predicate-----------------------
aoqi@0 240 ProjNode* PhaseIdealLoop::clone_predicate(ProjNode* predicate_proj, Node* new_entry,
aoqi@0 241 Deoptimization::DeoptReason reason,
aoqi@0 242 PhaseIdealLoop* loop_phase,
aoqi@0 243 PhaseIterGVN* igvn) {
aoqi@0 244 ProjNode* new_predicate_proj;
aoqi@0 245 if (loop_phase != NULL) {
aoqi@0 246 new_predicate_proj = loop_phase->create_new_if_for_predicate(predicate_proj, new_entry, reason);
aoqi@0 247 } else {
aoqi@0 248 new_predicate_proj = igvn->create_new_if_for_predicate(predicate_proj, new_entry, reason);
aoqi@0 249 }
aoqi@0 250 IfNode* iff = new_predicate_proj->in(0)->as_If();
aoqi@0 251 Node* ctrl = iff->in(0);
aoqi@0 252
aoqi@0 253 // Match original condition since predicate's projections could be swapped.
aoqi@0 254 assert(predicate_proj->in(0)->in(1)->in(1)->Opcode()==Op_Opaque1, "must be");
aoqi@0 255 Node* opq = new (igvn->C) Opaque1Node(igvn->C, predicate_proj->in(0)->in(1)->in(1)->in(1));
aoqi@0 256 igvn->C->add_predicate_opaq(opq);
aoqi@0 257
aoqi@0 258 Node* bol = new (igvn->C) Conv2BNode(opq);
aoqi@0 259 if (loop_phase != NULL) {
aoqi@0 260 loop_phase->register_new_node(opq, ctrl);
aoqi@0 261 loop_phase->register_new_node(bol, ctrl);
aoqi@0 262 } else {
aoqi@0 263 igvn->register_new_node_with_optimizer(opq);
aoqi@0 264 igvn->register_new_node_with_optimizer(bol);
aoqi@0 265 }
aoqi@0 266 igvn->hash_delete(iff);
aoqi@0 267 iff->set_req(1, bol);
aoqi@0 268 return new_predicate_proj;
aoqi@0 269 }
aoqi@0 270
aoqi@0 271
aoqi@0 272 //--------------------------clone_loop_predicates-----------------------
aoqi@0 273 // Interface from IGVN
aoqi@0 274 Node* PhaseIterGVN::clone_loop_predicates(Node* old_entry, Node* new_entry, bool clone_limit_check) {
aoqi@0 275 return PhaseIdealLoop::clone_loop_predicates(old_entry, new_entry, clone_limit_check, NULL, this);
aoqi@0 276 }
aoqi@0 277
aoqi@0 278 // Interface from PhaseIdealLoop
aoqi@0 279 Node* PhaseIdealLoop::clone_loop_predicates(Node* old_entry, Node* new_entry, bool clone_limit_check) {
aoqi@0 280 return clone_loop_predicates(old_entry, new_entry, clone_limit_check, this, &this->_igvn);
aoqi@0 281 }
aoqi@0 282
aoqi@0 283 // Clone loop predicates to cloned loops (peeled, unswitched, split_if).
aoqi@0 284 Node* PhaseIdealLoop::clone_loop_predicates(Node* old_entry, Node* new_entry,
aoqi@0 285 bool clone_limit_check,
aoqi@0 286 PhaseIdealLoop* loop_phase,
aoqi@0 287 PhaseIterGVN* igvn) {
aoqi@0 288 #ifdef ASSERT
aoqi@0 289 if (new_entry == NULL || !(new_entry->is_Proj() || new_entry->is_Region() || new_entry->is_SafePoint())) {
aoqi@0 290 if (new_entry != NULL)
aoqi@0 291 new_entry->dump();
aoqi@0 292 assert(false, "not IfTrue, IfFalse, Region or SafePoint");
aoqi@0 293 }
aoqi@0 294 #endif
aoqi@0 295 // Search original predicates
aoqi@0 296 Node* entry = old_entry;
aoqi@0 297 ProjNode* limit_check_proj = NULL;
aoqi@0 298 if (LoopLimitCheck) {
aoqi@0 299 limit_check_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check);
aoqi@0 300 if (limit_check_proj != NULL) {
aoqi@0 301 entry = entry->in(0)->in(0);
aoqi@0 302 }
aoqi@0 303 }
aoqi@0 304 if (UseLoopPredicate) {
aoqi@0 305 ProjNode* predicate_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
aoqi@0 306 if (predicate_proj != NULL) { // right pattern that can be used by loop predication
aoqi@0 307 // clone predicate
aoqi@0 308 new_entry = clone_predicate(predicate_proj, new_entry,
aoqi@0 309 Deoptimization::Reason_predicate,
aoqi@0 310 loop_phase, igvn);
aoqi@0 311 assert(new_entry != NULL && new_entry->is_Proj(), "IfTrue or IfFalse after clone predicate");
aoqi@0 312 if (TraceLoopPredicate) {
aoqi@0 313 tty->print("Loop Predicate cloned: ");
aoqi@0 314 debug_only( new_entry->in(0)->dump(); )
aoqi@0 315 }
aoqi@0 316 }
aoqi@0 317 }
aoqi@0 318 if (limit_check_proj != NULL && clone_limit_check) {
aoqi@0 319 // Clone loop limit check last to insert it before loop.
aoqi@0 320 // Don't clone a limit check which was already finalized
aoqi@0 321 // for this counted loop (only one limit check is needed).
aoqi@0 322 new_entry = clone_predicate(limit_check_proj, new_entry,
aoqi@0 323 Deoptimization::Reason_loop_limit_check,
aoqi@0 324 loop_phase, igvn);
aoqi@0 325 assert(new_entry != NULL && new_entry->is_Proj(), "IfTrue or IfFalse after clone limit check");
aoqi@0 326 if (TraceLoopLimitCheck) {
aoqi@0 327 tty->print("Loop Limit Check cloned: ");
aoqi@0 328 debug_only( new_entry->in(0)->dump(); )
aoqi@0 329 }
aoqi@0 330 }
aoqi@0 331 return new_entry;
aoqi@0 332 }
aoqi@0 333
aoqi@0 334 //--------------------------skip_loop_predicates------------------------------
aoqi@0 335 // Skip related predicates.
aoqi@0 336 Node* PhaseIdealLoop::skip_loop_predicates(Node* entry) {
aoqi@0 337 Node* predicate = NULL;
aoqi@0 338 if (LoopLimitCheck) {
aoqi@0 339 predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check);
aoqi@0 340 if (predicate != NULL) {
aoqi@0 341 entry = entry->in(0)->in(0);
aoqi@0 342 }
aoqi@0 343 }
aoqi@0 344 if (UseLoopPredicate) {
aoqi@0 345 predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
aoqi@0 346 if (predicate != NULL) { // right pattern that can be used by loop predication
aoqi@0 347 IfNode* iff = entry->in(0)->as_If();
aoqi@0 348 ProjNode* uncommon_proj = iff->proj_out(1 - entry->as_Proj()->_con);
aoqi@0 349 Node* rgn = uncommon_proj->unique_ctrl_out();
aoqi@0 350 assert(rgn->is_Region() || rgn->is_Call(), "must be a region or call uct");
aoqi@0 351 entry = entry->in(0)->in(0);
aoqi@0 352 while (entry != NULL && entry->is_Proj() && entry->in(0)->is_If()) {
aoqi@0 353 uncommon_proj = entry->in(0)->as_If()->proj_out(1 - entry->as_Proj()->_con);
aoqi@0 354 if (uncommon_proj->unique_ctrl_out() != rgn)
aoqi@0 355 break;
aoqi@0 356 entry = entry->in(0)->in(0);
aoqi@0 357 }
aoqi@0 358 }
aoqi@0 359 }
aoqi@0 360 return entry;
aoqi@0 361 }
aoqi@0 362
aoqi@0 363 //--------------------------find_predicate_insertion_point-------------------
aoqi@0 364 // Find a good location to insert a predicate
aoqi@0 365 ProjNode* PhaseIdealLoop::find_predicate_insertion_point(Node* start_c, Deoptimization::DeoptReason reason) {
aoqi@0 366 if (start_c == NULL || !start_c->is_Proj())
aoqi@0 367 return NULL;
aoqi@0 368 if (start_c->as_Proj()->is_uncommon_trap_if_pattern(reason)) {
aoqi@0 369 return start_c->as_Proj();
aoqi@0 370 }
aoqi@0 371 return NULL;
aoqi@0 372 }
aoqi@0 373
aoqi@0 374 //--------------------------find_predicate------------------------------------
aoqi@0 375 // Find a predicate
aoqi@0 376 Node* PhaseIdealLoop::find_predicate(Node* entry) {
aoqi@0 377 Node* predicate = NULL;
aoqi@0 378 if (LoopLimitCheck) {
aoqi@0 379 predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check);
aoqi@0 380 if (predicate != NULL) { // right pattern that can be used by loop predication
aoqi@0 381 return entry;
aoqi@0 382 }
aoqi@0 383 }
aoqi@0 384 if (UseLoopPredicate) {
aoqi@0 385 predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
aoqi@0 386 if (predicate != NULL) { // right pattern that can be used by loop predication
aoqi@0 387 return entry;
aoqi@0 388 }
aoqi@0 389 }
aoqi@0 390 return NULL;
aoqi@0 391 }
aoqi@0 392
aoqi@0 393 //------------------------------Invariance-----------------------------------
aoqi@0 394 // Helper class for loop_predication_impl to compute invariance on the fly and
aoqi@0 395 // clone invariants.
aoqi@0 396 class Invariance : public StackObj {
aoqi@0 397 VectorSet _visited, _invariant;
aoqi@0 398 Node_Stack _stack;
aoqi@0 399 VectorSet _clone_visited;
aoqi@0 400 Node_List _old_new; // map of old to new (clone)
aoqi@0 401 IdealLoopTree* _lpt;
aoqi@0 402 PhaseIdealLoop* _phase;
aoqi@0 403
aoqi@0 404 // Helper function to set up the invariance for invariance computation
aoqi@0 405 // If n is a known invariant, set up directly. Otherwise, look up the
aoqi@0 406 // the possibility to push n onto the stack for further processing.
aoqi@0 407 void visit(Node* use, Node* n) {
aoqi@0 408 if (_lpt->is_invariant(n)) { // known invariant
aoqi@0 409 _invariant.set(n->_idx);
aoqi@0 410 } else if (!n->is_CFG()) {
aoqi@0 411 Node *n_ctrl = _phase->ctrl_or_self(n);
aoqi@0 412 Node *u_ctrl = _phase->ctrl_or_self(use); // self if use is a CFG
aoqi@0 413 if (_phase->is_dominator(n_ctrl, u_ctrl)) {
aoqi@0 414 _stack.push(n, n->in(0) == NULL ? 1 : 0);
aoqi@0 415 }
aoqi@0 416 }
aoqi@0 417 }
aoqi@0 418
aoqi@0 419 // Compute invariance for "the_node" and (possibly) all its inputs recursively
aoqi@0 420 // on the fly
aoqi@0 421 void compute_invariance(Node* n) {
aoqi@0 422 assert(_visited.test(n->_idx), "must be");
aoqi@0 423 visit(n, n);
aoqi@0 424 while (_stack.is_nonempty()) {
aoqi@0 425 Node* n = _stack.node();
aoqi@0 426 uint idx = _stack.index();
aoqi@0 427 if (idx == n->req()) { // all inputs are processed
aoqi@0 428 _stack.pop();
aoqi@0 429 // n is invariant if it's inputs are all invariant
aoqi@0 430 bool all_inputs_invariant = true;
aoqi@0 431 for (uint i = 0; i < n->req(); i++) {
aoqi@0 432 Node* in = n->in(i);
aoqi@0 433 if (in == NULL) continue;
aoqi@0 434 assert(_visited.test(in->_idx), "must have visited input");
aoqi@0 435 if (!_invariant.test(in->_idx)) { // bad guy
aoqi@0 436 all_inputs_invariant = false;
aoqi@0 437 break;
aoqi@0 438 }
aoqi@0 439 }
aoqi@0 440 if (all_inputs_invariant) {
aoqi@0 441 _invariant.set(n->_idx); // I am a invariant too
aoqi@0 442 }
aoqi@0 443 } else { // process next input
aoqi@0 444 _stack.set_index(idx + 1);
aoqi@0 445 Node* m = n->in(idx);
aoqi@0 446 if (m != NULL && !_visited.test_set(m->_idx)) {
aoqi@0 447 visit(n, m);
aoqi@0 448 }
aoqi@0 449 }
aoqi@0 450 }
aoqi@0 451 }
aoqi@0 452
aoqi@0 453 // Helper function to set up _old_new map for clone_nodes.
aoqi@0 454 // If n is a known invariant, set up directly ("clone" of n == n).
aoqi@0 455 // Otherwise, push n onto the stack for real cloning.
aoqi@0 456 void clone_visit(Node* n) {
aoqi@0 457 assert(_invariant.test(n->_idx), "must be invariant");
aoqi@0 458 if (_lpt->is_invariant(n)) { // known invariant
aoqi@0 459 _old_new.map(n->_idx, n);
aoqi@0 460 } else { // to be cloned
aoqi@0 461 assert(!n->is_CFG(), "should not see CFG here");
aoqi@0 462 _stack.push(n, n->in(0) == NULL ? 1 : 0);
aoqi@0 463 }
aoqi@0 464 }
aoqi@0 465
aoqi@0 466 // Clone "n" and (possibly) all its inputs recursively
aoqi@0 467 void clone_nodes(Node* n, Node* ctrl) {
aoqi@0 468 clone_visit(n);
aoqi@0 469 while (_stack.is_nonempty()) {
aoqi@0 470 Node* n = _stack.node();
aoqi@0 471 uint idx = _stack.index();
aoqi@0 472 if (idx == n->req()) { // all inputs processed, clone n!
aoqi@0 473 _stack.pop();
aoqi@0 474 // clone invariant node
aoqi@0 475 Node* n_cl = n->clone();
aoqi@0 476 _old_new.map(n->_idx, n_cl);
aoqi@0 477 _phase->register_new_node(n_cl, ctrl);
aoqi@0 478 for (uint i = 0; i < n->req(); i++) {
aoqi@0 479 Node* in = n_cl->in(i);
aoqi@0 480 if (in == NULL) continue;
aoqi@0 481 n_cl->set_req(i, _old_new[in->_idx]);
aoqi@0 482 }
aoqi@0 483 } else { // process next input
aoqi@0 484 _stack.set_index(idx + 1);
aoqi@0 485 Node* m = n->in(idx);
aoqi@0 486 if (m != NULL && !_clone_visited.test_set(m->_idx)) {
aoqi@0 487 clone_visit(m); // visit the input
aoqi@0 488 }
aoqi@0 489 }
aoqi@0 490 }
aoqi@0 491 }
aoqi@0 492
aoqi@0 493 public:
aoqi@0 494 Invariance(Arena* area, IdealLoopTree* lpt) :
aoqi@0 495 _lpt(lpt), _phase(lpt->_phase),
aoqi@0 496 _visited(area), _invariant(area), _stack(area, 10 /* guess */),
aoqi@0 497 _clone_visited(area), _old_new(area)
aoqi@0 498 {}
aoqi@0 499
aoqi@0 500 // Map old to n for invariance computation and clone
aoqi@0 501 void map_ctrl(Node* old, Node* n) {
aoqi@0 502 assert(old->is_CFG() && n->is_CFG(), "must be");
aoqi@0 503 _old_new.map(old->_idx, n); // "clone" of old is n
aoqi@0 504 _invariant.set(old->_idx); // old is invariant
aoqi@0 505 _clone_visited.set(old->_idx);
aoqi@0 506 }
aoqi@0 507
aoqi@0 508 // Driver function to compute invariance
aoqi@0 509 bool is_invariant(Node* n) {
aoqi@0 510 if (!_visited.test_set(n->_idx))
aoqi@0 511 compute_invariance(n);
aoqi@0 512 return (_invariant.test(n->_idx) != 0);
aoqi@0 513 }
aoqi@0 514
aoqi@0 515 // Driver function to clone invariant
aoqi@0 516 Node* clone(Node* n, Node* ctrl) {
aoqi@0 517 assert(ctrl->is_CFG(), "must be");
aoqi@0 518 assert(_invariant.test(n->_idx), "must be an invariant");
aoqi@0 519 if (!_clone_visited.test(n->_idx))
aoqi@0 520 clone_nodes(n, ctrl);
aoqi@0 521 return _old_new[n->_idx];
aoqi@0 522 }
aoqi@0 523 };
aoqi@0 524
aoqi@0 525 //------------------------------is_range_check_if -----------------------------------
aoqi@0 526 // Returns true if the predicate of iff is in "scale*iv + offset u< load_range(ptr)" format
aoqi@0 527 // Note: this function is particularly designed for loop predication. We require load_range
aoqi@0 528 // and offset to be loop invariant computed on the fly by "invar"
aoqi@0 529 bool IdealLoopTree::is_range_check_if(IfNode *iff, PhaseIdealLoop *phase, Invariance& invar) const {
aoqi@0 530 if (!is_loop_exit(iff)) {
aoqi@0 531 return false;
aoqi@0 532 }
aoqi@0 533 if (!iff->in(1)->is_Bool()) {
aoqi@0 534 return false;
aoqi@0 535 }
aoqi@0 536 const BoolNode *bol = iff->in(1)->as_Bool();
aoqi@0 537 if (bol->_test._test != BoolTest::lt) {
aoqi@0 538 return false;
aoqi@0 539 }
aoqi@0 540 if (!bol->in(1)->is_Cmp()) {
aoqi@0 541 return false;
aoqi@0 542 }
aoqi@0 543 const CmpNode *cmp = bol->in(1)->as_Cmp();
aoqi@0 544 if (cmp->Opcode() != Op_CmpU) {
aoqi@0 545 return false;
aoqi@0 546 }
aoqi@0 547 Node* range = cmp->in(2);
aoqi@0 548 if (range->Opcode() != Op_LoadRange) {
aoqi@0 549 const TypeInt* tint = phase->_igvn.type(range)->isa_int();
aoqi@0 550 if (tint == NULL || tint->empty() || tint->_lo < 0) {
aoqi@0 551 // Allow predication on positive values that aren't LoadRanges.
aoqi@0 552 // This allows optimization of loops where the length of the
aoqi@0 553 // array is a known value and doesn't need to be loaded back
aoqi@0 554 // from the array.
aoqi@0 555 return false;
aoqi@0 556 }
aoqi@0 557 }
aoqi@0 558 if (!invar.is_invariant(range)) {
aoqi@0 559 return false;
aoqi@0 560 }
aoqi@0 561 Node *iv = _head->as_CountedLoop()->phi();
aoqi@0 562 int scale = 0;
aoqi@0 563 Node *offset = NULL;
aoqi@0 564 if (!phase->is_scaled_iv_plus_offset(cmp->in(1), iv, &scale, &offset)) {
aoqi@0 565 return false;
aoqi@0 566 }
aoqi@0 567 if (offset && !invar.is_invariant(offset)) { // offset must be invariant
aoqi@0 568 return false;
aoqi@0 569 }
aoqi@0 570 return true;
aoqi@0 571 }
aoqi@0 572
aoqi@0 573 //------------------------------rc_predicate-----------------------------------
aoqi@0 574 // Create a range check predicate
aoqi@0 575 //
aoqi@0 576 // for (i = init; i < limit; i += stride) {
aoqi@0 577 // a[scale*i+offset]
aoqi@0 578 // }
aoqi@0 579 //
aoqi@0 580 // Compute max(scale*i + offset) for init <= i < limit and build the predicate
aoqi@0 581 // as "max(scale*i + offset) u< a.length".
aoqi@0 582 //
aoqi@0 583 // There are two cases for max(scale*i + offset):
aoqi@0 584 // (1) stride*scale > 0
aoqi@0 585 // max(scale*i + offset) = scale*(limit-stride) + offset
aoqi@0 586 // (2) stride*scale < 0
aoqi@0 587 // max(scale*i + offset) = scale*init + offset
aoqi@0 588 BoolNode* PhaseIdealLoop::rc_predicate(IdealLoopTree *loop, Node* ctrl,
aoqi@0 589 int scale, Node* offset,
aoqi@0 590 Node* init, Node* limit, Node* stride,
aoqi@0 591 Node* range, bool upper) {
aoqi@0 592 stringStream* predString = NULL;
aoqi@0 593 if (TraceLoopPredicate) {
aoqi@0 594 predString = new stringStream();
aoqi@0 595 predString->print("rc_predicate ");
aoqi@0 596 }
aoqi@0 597
aoqi@0 598 Node* max_idx_expr = init;
aoqi@0 599 int stride_con = stride->get_int();
aoqi@0 600 if ((stride_con > 0) == (scale > 0) == upper) {
aoqi@0 601 if (LoopLimitCheck) {
aoqi@0 602 // With LoopLimitCheck limit is not exact.
aoqi@0 603 // Calculate exact limit here.
aoqi@0 604 // Note, counted loop's test is '<' or '>'.
aoqi@0 605 limit = exact_limit(loop);
aoqi@0 606 max_idx_expr = new (C) SubINode(limit, stride);
aoqi@0 607 register_new_node(max_idx_expr, ctrl);
aoqi@0 608 if (TraceLoopPredicate) predString->print("(limit - stride) ");
aoqi@0 609 } else {
aoqi@0 610 max_idx_expr = new (C) SubINode(limit, stride);
aoqi@0 611 register_new_node(max_idx_expr, ctrl);
aoqi@0 612 if (TraceLoopPredicate) predString->print("(limit - stride) ");
aoqi@0 613 }
aoqi@0 614 } else {
aoqi@0 615 if (TraceLoopPredicate) predString->print("init ");
aoqi@0 616 }
aoqi@0 617
aoqi@0 618 if (scale != 1) {
aoqi@0 619 ConNode* con_scale = _igvn.intcon(scale);
aoqi@0 620 max_idx_expr = new (C) MulINode(max_idx_expr, con_scale);
aoqi@0 621 register_new_node(max_idx_expr, ctrl);
aoqi@0 622 if (TraceLoopPredicate) predString->print("* %d ", scale);
aoqi@0 623 }
aoqi@0 624
aoqi@0 625 if (offset && (!offset->is_Con() || offset->get_int() != 0)){
aoqi@0 626 max_idx_expr = new (C) AddINode(max_idx_expr, offset);
aoqi@0 627 register_new_node(max_idx_expr, ctrl);
aoqi@0 628 if (TraceLoopPredicate)
aoqi@0 629 if (offset->is_Con()) predString->print("+ %d ", offset->get_int());
aoqi@0 630 else predString->print("+ offset ");
aoqi@0 631 }
aoqi@0 632
aoqi@0 633 CmpUNode* cmp = new (C) CmpUNode(max_idx_expr, range);
aoqi@0 634 register_new_node(cmp, ctrl);
aoqi@0 635 BoolNode* bol = new (C) BoolNode(cmp, BoolTest::lt);
aoqi@0 636 register_new_node(bol, ctrl);
aoqi@0 637
aoqi@0 638 if (TraceLoopPredicate) {
aoqi@0 639 predString->print_cr("<u range");
aoqi@0 640 tty->print("%s", predString->as_string());
aoqi@0 641 }
aoqi@0 642 return bol;
aoqi@0 643 }
aoqi@0 644
aoqi@0 645 //------------------------------ loop_predication_impl--------------------------
aoqi@0 646 // Insert loop predicates for null checks and range checks
aoqi@0 647 bool PhaseIdealLoop::loop_predication_impl(IdealLoopTree *loop) {
aoqi@0 648 if (!UseLoopPredicate) return false;
aoqi@0 649
aoqi@0 650 if (!loop->_head->is_Loop()) {
aoqi@0 651 // Could be a simple region when irreducible loops are present.
aoqi@0 652 return false;
aoqi@0 653 }
aoqi@0 654 LoopNode* head = loop->_head->as_Loop();
aoqi@0 655
aoqi@0 656 if (head->unique_ctrl_out()->Opcode() == Op_NeverBranch) {
aoqi@0 657 // do nothing for infinite loops
aoqi@0 658 return false;
aoqi@0 659 }
aoqi@0 660
aoqi@0 661 CountedLoopNode *cl = NULL;
aoqi@0 662 if (head->is_valid_counted_loop()) {
aoqi@0 663 cl = head->as_CountedLoop();
aoqi@0 664 // do nothing for iteration-splitted loops
aoqi@0 665 if (!cl->is_normal_loop()) return false;
aoqi@0 666 // Avoid RCE if Counted loop's test is '!='.
aoqi@0 667 BoolTest::mask bt = cl->loopexit()->test_trip();
aoqi@0 668 if (bt != BoolTest::lt && bt != BoolTest::gt)
aoqi@0 669 cl = NULL;
aoqi@0 670 }
aoqi@0 671
aoqi@0 672 Node* entry = head->in(LoopNode::EntryControl);
aoqi@0 673 ProjNode *predicate_proj = NULL;
aoqi@0 674 // Loop limit check predicate should be near the loop.
aoqi@0 675 if (LoopLimitCheck) {
aoqi@0 676 predicate_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check);
aoqi@0 677 if (predicate_proj != NULL)
aoqi@0 678 entry = predicate_proj->in(0)->in(0);
aoqi@0 679 }
aoqi@0 680
aoqi@0 681 predicate_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
aoqi@0 682 if (!predicate_proj) {
aoqi@0 683 #ifndef PRODUCT
aoqi@0 684 if (TraceLoopPredicate) {
aoqi@0 685 tty->print("missing predicate:");
aoqi@0 686 loop->dump_head();
aoqi@0 687 head->dump(1);
aoqi@0 688 }
aoqi@0 689 #endif
aoqi@0 690 return false;
aoqi@0 691 }
aoqi@0 692 ConNode* zero = _igvn.intcon(0);
aoqi@0 693 set_ctrl(zero, C->root());
aoqi@0 694
aoqi@0 695 ResourceArea *area = Thread::current()->resource_area();
aoqi@0 696 Invariance invar(area, loop);
aoqi@0 697
aoqi@0 698 // Create list of if-projs such that a newer proj dominates all older
aoqi@0 699 // projs in the list, and they all dominate loop->tail()
aoqi@0 700 Node_List if_proj_list(area);
aoqi@0 701 Node *current_proj = loop->tail(); //start from tail
aoqi@0 702 while (current_proj != head) {
aoqi@0 703 if (loop == get_loop(current_proj) && // still in the loop ?
aoqi@0 704 current_proj->is_Proj() && // is a projection ?
aoqi@0 705 current_proj->in(0)->Opcode() == Op_If) { // is a if projection ?
aoqi@0 706 if_proj_list.push(current_proj);
aoqi@0 707 }
aoqi@0 708 current_proj = idom(current_proj);
aoqi@0 709 }
aoqi@0 710
aoqi@0 711 bool hoisted = false; // true if at least one proj is promoted
aoqi@0 712 while (if_proj_list.size() > 0) {
aoqi@0 713 // Following are changed to nonnull when a predicate can be hoisted
aoqi@0 714 ProjNode* new_predicate_proj = NULL;
aoqi@0 715
aoqi@0 716 ProjNode* proj = if_proj_list.pop()->as_Proj();
aoqi@0 717 IfNode* iff = proj->in(0)->as_If();
aoqi@0 718
aoqi@0 719 if (!proj->is_uncommon_trap_if_pattern(Deoptimization::Reason_none)) {
aoqi@0 720 if (loop->is_loop_exit(iff)) {
aoqi@0 721 // stop processing the remaining projs in the list because the execution of them
aoqi@0 722 // depends on the condition of "iff" (iff->in(1)).
aoqi@0 723 break;
aoqi@0 724 } else {
aoqi@0 725 // Both arms are inside the loop. There are two cases:
aoqi@0 726 // (1) there is one backward branch. In this case, any remaining proj
aoqi@0 727 // in the if_proj list post-dominates "iff". So, the condition of "iff"
aoqi@0 728 // does not determine the execution the remining projs directly, and we
aoqi@0 729 // can safely continue.
aoqi@0 730 // (2) both arms are forwarded, i.e. a diamond shape. In this case, "proj"
aoqi@0 731 // does not dominate loop->tail(), so it can not be in the if_proj list.
aoqi@0 732 continue;
aoqi@0 733 }
aoqi@0 734 }
aoqi@0 735
aoqi@0 736 Node* test = iff->in(1);
aoqi@0 737 if (!test->is_Bool()){ //Conv2B, ...
aoqi@0 738 continue;
aoqi@0 739 }
aoqi@0 740 BoolNode* bol = test->as_Bool();
aoqi@0 741 if (invar.is_invariant(bol)) {
aoqi@0 742 // Invariant test
aoqi@0 743 new_predicate_proj = create_new_if_for_predicate(predicate_proj, NULL,
aoqi@0 744 Deoptimization::Reason_predicate);
aoqi@0 745 Node* ctrl = new_predicate_proj->in(0)->as_If()->in(0);
aoqi@0 746 BoolNode* new_predicate_bol = invar.clone(bol, ctrl)->as_Bool();
aoqi@0 747
aoqi@0 748 // Negate test if necessary
aoqi@0 749 bool negated = false;
aoqi@0 750 if (proj->_con != predicate_proj->_con) {
aoqi@0 751 new_predicate_bol = new (C) BoolNode(new_predicate_bol->in(1), new_predicate_bol->_test.negate());
aoqi@0 752 register_new_node(new_predicate_bol, ctrl);
aoqi@0 753 negated = true;
aoqi@0 754 }
aoqi@0 755 IfNode* new_predicate_iff = new_predicate_proj->in(0)->as_If();
aoqi@0 756 _igvn.hash_delete(new_predicate_iff);
aoqi@0 757 new_predicate_iff->set_req(1, new_predicate_bol);
aoqi@0 758 #ifndef PRODUCT
aoqi@0 759 if (TraceLoopPredicate) {
aoqi@0 760 tty->print("Predicate invariant if%s: %d ", negated ? " negated" : "", new_predicate_iff->_idx);
aoqi@0 761 loop->dump_head();
aoqi@0 762 } else if (TraceLoopOpts) {
aoqi@0 763 tty->print("Predicate IC ");
aoqi@0 764 loop->dump_head();
aoqi@0 765 }
aoqi@0 766 #endif
aoqi@0 767 } else if ((cl != NULL) && (proj->_con == predicate_proj->_con) &&
aoqi@0 768 loop->is_range_check_if(iff, this, invar)) {
aoqi@0 769
aoqi@0 770 // Range check for counted loops
aoqi@0 771 const Node* cmp = bol->in(1)->as_Cmp();
aoqi@0 772 Node* idx = cmp->in(1);
aoqi@0 773 assert(!invar.is_invariant(idx), "index is variant");
aoqi@0 774 Node* rng = cmp->in(2);
aoqi@0 775 assert(rng->Opcode() == Op_LoadRange || _igvn.type(rng)->is_int() >= 0, "must be");
aoqi@0 776 assert(invar.is_invariant(rng), "range must be invariant");
aoqi@0 777 int scale = 1;
aoqi@0 778 Node* offset = zero;
aoqi@0 779 bool ok = is_scaled_iv_plus_offset(idx, cl->phi(), &scale, &offset);
aoqi@0 780 assert(ok, "must be index expression");
aoqi@0 781
aoqi@0 782 Node* init = cl->init_trip();
aoqi@0 783 Node* limit = cl->limit();
aoqi@0 784 Node* stride = cl->stride();
aoqi@0 785
aoqi@0 786 // Build if's for the upper and lower bound tests. The
aoqi@0 787 // lower_bound test will dominate the upper bound test and all
aoqi@0 788 // cloned or created nodes will use the lower bound test as
aoqi@0 789 // their declared control.
aoqi@0 790 ProjNode* lower_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate);
aoqi@0 791 ProjNode* upper_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate);
aoqi@0 792 assert(upper_bound_proj->in(0)->as_If()->in(0) == lower_bound_proj, "should dominate");
aoqi@0 793 Node *ctrl = lower_bound_proj->in(0)->as_If()->in(0);
aoqi@0 794
aoqi@0 795 // Perform cloning to keep Invariance state correct since the
aoqi@0 796 // late schedule will place invariant things in the loop.
aoqi@0 797 rng = invar.clone(rng, ctrl);
aoqi@0 798 if (offset && offset != zero) {
aoqi@0 799 assert(invar.is_invariant(offset), "offset must be loop invariant");
aoqi@0 800 offset = invar.clone(offset, ctrl);
aoqi@0 801 }
aoqi@0 802
aoqi@0 803 // Test the lower bound
aoqi@0 804 Node* lower_bound_bol = rc_predicate(loop, ctrl, scale, offset, init, limit, stride, rng, false);
aoqi@0 805 IfNode* lower_bound_iff = lower_bound_proj->in(0)->as_If();
aoqi@0 806 _igvn.hash_delete(lower_bound_iff);
aoqi@0 807 lower_bound_iff->set_req(1, lower_bound_bol);
aoqi@0 808 if (TraceLoopPredicate) tty->print_cr("lower bound check if: %d", lower_bound_iff->_idx);
aoqi@0 809
aoqi@0 810 // Test the upper bound
aoqi@0 811 Node* upper_bound_bol = rc_predicate(loop, lower_bound_proj, scale, offset, init, limit, stride, rng, true);
aoqi@0 812 IfNode* upper_bound_iff = upper_bound_proj->in(0)->as_If();
aoqi@0 813 _igvn.hash_delete(upper_bound_iff);
aoqi@0 814 upper_bound_iff->set_req(1, upper_bound_bol);
aoqi@0 815 if (TraceLoopPredicate) tty->print_cr("upper bound check if: %d", lower_bound_iff->_idx);
aoqi@0 816
aoqi@0 817 // Fall through into rest of the clean up code which will move
aoqi@0 818 // any dependent nodes onto the upper bound test.
aoqi@0 819 new_predicate_proj = upper_bound_proj;
aoqi@0 820
aoqi@0 821 #ifndef PRODUCT
aoqi@0 822 if (TraceLoopOpts && !TraceLoopPredicate) {
aoqi@0 823 tty->print("Predicate RC ");
aoqi@0 824 loop->dump_head();
aoqi@0 825 }
aoqi@0 826 #endif
aoqi@0 827 } else {
aoqi@0 828 // Loop variant check (for example, range check in non-counted loop)
aoqi@0 829 // with uncommon trap.
aoqi@0 830 continue;
aoqi@0 831 }
aoqi@0 832 assert(new_predicate_proj != NULL, "sanity");
aoqi@0 833 // Success - attach condition (new_predicate_bol) to predicate if
aoqi@0 834 invar.map_ctrl(proj, new_predicate_proj); // so that invariance test can be appropriate
aoqi@0 835
aoqi@0 836 // Eliminate the old If in the loop body
aoqi@0 837 dominated_by( new_predicate_proj, iff, proj->_con != new_predicate_proj->_con );
aoqi@0 838
aoqi@0 839 hoisted = true;
aoqi@0 840 C->set_major_progress();
aoqi@0 841 } // end while
aoqi@0 842
aoqi@0 843 #ifndef PRODUCT
aoqi@0 844 // report that the loop predication has been actually performed
aoqi@0 845 // for this loop
aoqi@0 846 if (TraceLoopPredicate && hoisted) {
aoqi@0 847 tty->print("Loop Predication Performed:");
aoqi@0 848 loop->dump_head();
aoqi@0 849 }
aoqi@0 850 #endif
aoqi@0 851
aoqi@0 852 return hoisted;
aoqi@0 853 }
aoqi@0 854
aoqi@0 855 //------------------------------loop_predication--------------------------------
aoqi@0 856 // driver routine for loop predication optimization
aoqi@0 857 bool IdealLoopTree::loop_predication( PhaseIdealLoop *phase) {
aoqi@0 858 bool hoisted = false;
aoqi@0 859 // Recursively promote predicates
aoqi@0 860 if (_child) {
aoqi@0 861 hoisted = _child->loop_predication( phase);
aoqi@0 862 }
aoqi@0 863
aoqi@0 864 // self
aoqi@0 865 if (!_irreducible && !tail()->is_top()) {
aoqi@0 866 hoisted |= phase->loop_predication_impl(this);
aoqi@0 867 }
aoqi@0 868
aoqi@0 869 if (_next) { //sibling
aoqi@0 870 hoisted |= _next->loop_predication( phase);
aoqi@0 871 }
aoqi@0 872
aoqi@0 873 return hoisted;
aoqi@0 874 }

mercurial