hotspot/src/share/vm/opto/loopUnswitch.cpp
author coleenp
Mon, 14 Jan 2013 11:01:39 -0500
changeset 15194 a35093d73168
parent 14623 70c4c1be0a14
child 23528 8f1a7f5e8066
permissions -rw-r--r--
8006005: Fix constant pool index validation and alignment trap for method parameter reflection Summary: This patch addresses an alignment trap due to the storage format of method parameters data in constMethod. It also adds code to validate constant pool indexes for method parameters data. Reviewed-by: jrose, dholmes Contributed-by: eric.mccorkle@oracle.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
13963
e5b53c306fb5 7197424: update copyright year to match last edit in jdk8 hotspot repository
mikael
parents: 13895
diff changeset
     2
 * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 2131
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 2131
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 2131
diff changeset
    21
 * questions.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    25
#include "precompiled.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    26
#include "memory/allocation.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    27
#include "opto/connode.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    28
#include "opto/loopnode.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    29
#include "opto/rootnode.hpp"
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
//================= Loop Unswitching =====================
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
// orig:                       transformed:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
//                               if (invariant-test) then
9101
ff58f9a8e31c 7004535: Clone loop predicate during loop unswitch
kvn
parents: 8732
diff changeset
    35
//  predicate                      predicate
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
//  loop                           loop
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
//    stmt1                          stmt1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
//    if (invariant-test) then       stmt2
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
//      stmt2                        stmt4
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
//    else                         endloop
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
//      stmt3                    else
9101
ff58f9a8e31c 7004535: Clone loop predicate during loop unswitch
kvn
parents: 8732
diff changeset
    42
//    endif                        predicate [clone]
ff58f9a8e31c 7004535: Clone loop predicate during loop unswitch
kvn
parents: 8732
diff changeset
    43
//    stmt4                        loop [clone]
ff58f9a8e31c 7004535: Clone loop predicate during loop unswitch
kvn
parents: 8732
diff changeset
    44
//  endloop                          stmt1 [clone]
ff58f9a8e31c 7004535: Clone loop predicate during loop unswitch
kvn
parents: 8732
diff changeset
    45
//                                   stmt3
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
//                                   stmt4 [clone]
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
//                                 endloop
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
//                               endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
// Note: the "else" clause may be empty
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
//------------------------------policy_unswitching-----------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
// Return TRUE or FALSE if the loop should be unswitched
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
// (ie. clone loop with an invariant test that does not exit the loop)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
bool IdealLoopTree::policy_unswitching( PhaseIdealLoop *phase ) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
  if( !LoopUnswitching ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
  }
355
22d39d357cca 6684385: Loop unswitching crashes without LoopNode
rasbold
parents: 1
diff changeset
    59
  if (!_head->is_Loop()) {
22d39d357cca 6684385: Loop unswitching crashes without LoopNode
rasbold
parents: 1
diff changeset
    60
    return false;
22d39d357cca 6684385: Loop unswitching crashes without LoopNode
rasbold
parents: 1
diff changeset
    61
  }
14623
70c4c1be0a14 7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents: 13963
diff changeset
    62
  uint nodes_left = MaxNodeLimit - phase->C->live_nodes();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
  if (2 * _body.size() > nodes_left) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
    return false; // Too speculative if running low on nodes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
  LoopNode* head = _head->as_Loop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
  if (head->unswitch_count() + 1 > head->unswitch_max()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
  return phase->find_unswitching_candidate(this) != NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
//------------------------------find_unswitching_candidate-----------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
// Find candidate "if" for unswitching
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
IfNode* PhaseIdealLoop::find_unswitching_candidate(const IdealLoopTree *loop) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
  // Find first invariant test that doesn't exit the loop
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
  LoopNode *head = loop->_head->as_Loop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
  IfNode* unswitch_iff = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
  Node* n = head->in(LoopNode::LoopBackControl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
  while (n != head) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
    Node* n_dom = idom(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
    if (n->is_Region()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
      if (n_dom->is_If()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
        IfNode* iff = n_dom->as_If();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
        if (iff->in(1)->is_Bool()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
          BoolNode* bol = iff->in(1)->as_Bool();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
          if (bol->in(1)->is_Cmp()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
            // If condition is invariant and not a loop exit,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
            // then found reason to unswitch.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
            if (loop->is_invariant(bol) && !loop->is_loop_exit(iff)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
              unswitch_iff = iff;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
    n = n_dom;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
  return unswitch_iff;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
//------------------------------do_unswitching-----------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
// Clone loop with an invariant test (that does not exit) and
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
// insert a clone of the test that selects which version to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
// execute.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
void PhaseIdealLoop::do_unswitching (IdealLoopTree *loop, Node_List &old_new) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
  // Find first invariant test that doesn't exit the loop
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
  LoopNode *head = loop->_head->as_Loop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
  IfNode* unswitch_iff = find_unswitching_candidate((const IdealLoopTree *)loop);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
  assert(unswitch_iff != NULL, "should be at least one");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
8732
16fc1c68714b 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 7397
diff changeset
   115
#ifndef PRODUCT
16fc1c68714b 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 7397
diff changeset
   116
  if (TraceLoopOpts) {
16fc1c68714b 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 7397
diff changeset
   117
    tty->print("Unswitch   %d ", head->unswitch_count()+1);
16fc1c68714b 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 7397
diff changeset
   118
    loop->dump_head();
16fc1c68714b 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 7397
diff changeset
   119
  }
16fc1c68714b 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 7397
diff changeset
   120
#endif
16fc1c68714b 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 7397
diff changeset
   121
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
  // Need to revert back to normal loop
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
  if (head->is_CountedLoop() && !head->as_CountedLoop()->is_normal_loop()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
    head->as_CountedLoop()->set_normal_loop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
  ProjNode* proj_true = create_slow_version_of_loop(loop, old_new);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
9101
ff58f9a8e31c 7004535: Clone loop predicate during loop unswitch
kvn
parents: 8732
diff changeset
   129
#ifdef ASSERT
ff58f9a8e31c 7004535: Clone loop predicate during loop unswitch
kvn
parents: 8732
diff changeset
   130
  Node* uniqc = proj_true->unique_ctrl_out();
ff58f9a8e31c 7004535: Clone loop predicate during loop unswitch
kvn
parents: 8732
diff changeset
   131
  Node* entry = head->in(LoopNode::EntryControl);
ff58f9a8e31c 7004535: Clone loop predicate during loop unswitch
kvn
parents: 8732
diff changeset
   132
  Node* predicate = find_predicate(entry);
9446
748a37b25d10 5091921: Sign flip issues in loop optimizer
kvn
parents: 9124
diff changeset
   133
  if (predicate != NULL && LoopLimitCheck && UseLoopPredicate) {
748a37b25d10 5091921: Sign flip issues in loop optimizer
kvn
parents: 9124
diff changeset
   134
    // We may have two predicates, find first.
748a37b25d10 5091921: Sign flip issues in loop optimizer
kvn
parents: 9124
diff changeset
   135
    entry = find_predicate(entry->in(0)->in(0));
748a37b25d10 5091921: Sign flip issues in loop optimizer
kvn
parents: 9124
diff changeset
   136
    if (entry != NULL) predicate = entry;
748a37b25d10 5091921: Sign flip issues in loop optimizer
kvn
parents: 9124
diff changeset
   137
  }
9101
ff58f9a8e31c 7004535: Clone loop predicate during loop unswitch
kvn
parents: 8732
diff changeset
   138
  if (predicate != NULL) predicate = predicate->in(0);
ff58f9a8e31c 7004535: Clone loop predicate during loop unswitch
kvn
parents: 8732
diff changeset
   139
  assert(proj_true->is_IfTrue() &&
ff58f9a8e31c 7004535: Clone loop predicate during loop unswitch
kvn
parents: 8732
diff changeset
   140
         (predicate == NULL && uniqc == head ||
ff58f9a8e31c 7004535: Clone loop predicate during loop unswitch
kvn
parents: 8732
diff changeset
   141
          predicate != NULL && uniqc == predicate), "by construction");
ff58f9a8e31c 7004535: Clone loop predicate during loop unswitch
kvn
parents: 8732
diff changeset
   142
#endif
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
  // Increment unswitch count
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
  LoopNode* head_clone = old_new[head->_idx]->as_Loop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
  int nct = head->unswitch_count() + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
  head->set_unswitch_count(nct);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
  head_clone->set_unswitch_count(nct);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
  // Add test to new "if" outside of loop
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
  IfNode* invar_iff   = proj_true->in(0)->as_If();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
  Node* invar_iff_c   = invar_iff->in(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
  BoolNode* bol       = unswitch_iff->in(1)->as_Bool();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
  invar_iff->set_req(1, bol);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
  invar_iff->_prob    = unswitch_iff->_prob;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
  ProjNode* proj_false = invar_iff->proj_out(0)->as_Proj();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 781
diff changeset
   158
  // Hoist invariant casts out of each loop to the appropriate
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
  // control projection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
  Node_List worklist;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
  for (DUIterator_Fast imax, i = unswitch_iff->fast_outs(imax); i < imax; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
    ProjNode* proj= unswitch_iff->fast_out(i)->as_Proj();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
    // Copy to a worklist for easier manipulation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
    for (DUIterator_Fast jmax, j = proj->fast_outs(jmax); j < jmax; j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
      Node* use = proj->fast_out(j);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
      if (use->Opcode() == Op_CheckCastPP && loop->is_invariant(use->in(1))) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
        worklist.push(use);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
    ProjNode* invar_proj = invar_iff->proj_out(proj->_con)->as_Proj();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
    while (worklist.size() > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
      Node* use = worklist.pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
      Node* nuse = use->clone();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
      nuse->set_req(0, invar_proj);
12958
009b6c9586d8 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 10258
diff changeset
   177
      _igvn.replace_input_of(use, 1, nuse);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
      register_new_node(nuse, invar_proj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
      // Same for the clone
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
      Node* use_clone = old_new[use->_idx];
12958
009b6c9586d8 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 10258
diff changeset
   181
      _igvn.replace_input_of(use_clone, 1, nuse);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
  // Hardwire the control paths in the loops into if(true) and if(false)
12958
009b6c9586d8 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 10258
diff changeset
   186
  _igvn.rehash_node_delayed(unswitch_iff);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
  short_circuit_if(unswitch_iff, proj_true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
  IfNode* unswitch_iff_clone = old_new[unswitch_iff->_idx]->as_If();
12958
009b6c9586d8 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 10258
diff changeset
   190
  _igvn.rehash_node_delayed(unswitch_iff_clone);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
  short_circuit_if(unswitch_iff_clone, proj_false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
  // Reoptimize loops
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
  loop->record_for_igvn();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
  for(int i = loop->_body.size() - 1; i >= 0 ; i--) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
    Node *n = loop->_body[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
    Node *n_clone = old_new[n->_idx];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
    _igvn._worklist.push(n_clone);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
  if (TraceLoopUnswitching) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
    tty->print_cr("Loop unswitching orig: %d @ %d  new: %d @ %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
                  head->_idx,                unswitch_iff->_idx,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
                  old_new[head->_idx]->_idx, unswitch_iff_clone->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
  C->set_major_progress();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
//-------------------------create_slow_version_of_loop------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
// Create a slow version of the loop by cloning the loop
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
// and inserting an if to select fast-slow versions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
// Return control projection of the entry to the fast version.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
ProjNode* PhaseIdealLoop::create_slow_version_of_loop(IdealLoopTree *loop,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
                                                      Node_List &old_new) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
  LoopNode* head  = loop->_head->as_Loop();
9446
748a37b25d10 5091921: Sign flip issues in loop optimizer
kvn
parents: 9124
diff changeset
   219
  bool counted_loop = head->is_CountedLoop();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
  Node*     entry = head->in(LoopNode::EntryControl);
12958
009b6c9586d8 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 10258
diff changeset
   221
  _igvn.rehash_node_delayed(entry);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
  IdealLoopTree* outer_loop = loop->_parent;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
  Node *cont      = _igvn.intcon(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
  set_ctrl(cont, C->root());
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 12958
diff changeset
   226
  Node* opq       = new (C) Opaque1Node(C, cont);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
  register_node(opq, outer_loop, entry, dom_depth(entry));
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 12958
diff changeset
   228
  Node *bol       = new (C) Conv2BNode(opq);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
  register_node(bol, outer_loop, entry, dom_depth(entry));
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 12958
diff changeset
   230
  IfNode* iff = new (C) IfNode(entry, bol, PROB_MAX, COUNT_UNKNOWN);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
  register_node(iff, outer_loop, entry, dom_depth(entry));
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 12958
diff changeset
   232
  ProjNode* iffast = new (C) IfTrueNode(iff);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
  register_node(iffast, outer_loop, iff, dom_depth(iff));
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 12958
diff changeset
   234
  ProjNode* ifslow = new (C) IfFalseNode(iff);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
  register_node(ifslow, outer_loop, iff, dom_depth(iff));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
  // Clone the loop body.  The clone becomes the fast loop.  The
9101
ff58f9a8e31c 7004535: Clone loop predicate during loop unswitch
kvn
parents: 8732
diff changeset
   238
  // original pre-header will (illegally) have 3 control users
ff58f9a8e31c 7004535: Clone loop predicate during loop unswitch
kvn
parents: 8732
diff changeset
   239
  // (old & new loops & new if).
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
  clone_loop(loop, old_new, dom_depth(head), iff);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
  assert(old_new[head->_idx]->is_Loop(), "" );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
  // Fast (true) control
9446
748a37b25d10 5091921: Sign flip issues in loop optimizer
kvn
parents: 9124
diff changeset
   244
  Node* iffast_pred = clone_loop_predicates(entry, iffast, !counted_loop);
12958
009b6c9586d8 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 10258
diff changeset
   245
  _igvn.replace_input_of(head, LoopNode::EntryControl, iffast_pred);
9101
ff58f9a8e31c 7004535: Clone loop predicate during loop unswitch
kvn
parents: 8732
diff changeset
   246
  set_idom(head, iffast_pred, dom_depth(head));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
  // Slow (false) control
10258
10c77b8c8d3e 7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents: 9446
diff changeset
   249
  Node* ifslow_pred = clone_loop_predicates(entry, ifslow, !counted_loop);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
  LoopNode* slow_head = old_new[head->_idx]->as_Loop();
12958
009b6c9586d8 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 10258
diff changeset
   251
  _igvn.replace_input_of(slow_head, LoopNode::EntryControl, ifslow_pred);
9101
ff58f9a8e31c 7004535: Clone loop predicate during loop unswitch
kvn
parents: 8732
diff changeset
   252
  set_idom(slow_head, ifslow_pred, dom_depth(slow_head));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
  recompute_dom_depth();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
  return iffast;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
}