hotspot/src/share/vm/opto/replacednodes.cpp
author roland
Wed, 15 Feb 2017 17:26:37 -0800
changeset 43963 6845bb645be5
parent 37248 11a660dbbb8e
permissions -rw-r--r--
8174164: SafePointNode::_replaced_nodes breaks with irreducible loops Reviewed-by: kvn
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
24946
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
     1
/*
37248
11a660dbbb8e 8132524: Missing includes to resourceArea.hpp
jprovino
parents: 25645
diff changeset
     2
 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
24946
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
     4
 *
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
     7
 * published by the Free Software Foundation.
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
     8
 *
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    13
 * accompanied this code).
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    14
 *
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    18
 *
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    21
 * questions.
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    22
 *
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    23
 */
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    24
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    25
#include "precompiled.hpp"
37248
11a660dbbb8e 8132524: Missing includes to resourceArea.hpp
jprovino
parents: 25645
diff changeset
    26
#include "memory/resourceArea.hpp"
24946
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    27
#include "opto/cfgnode.hpp"
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    28
#include "opto/phaseX.hpp"
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    29
#include "opto/replacednodes.hpp"
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    30
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    31
void ReplacedNodes::allocate_if_necessary() {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    32
  if (_replaced_nodes == NULL) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    33
    _replaced_nodes = new GrowableArray<ReplacedNode>();
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    34
  }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    35
}
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    36
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    37
bool ReplacedNodes::is_empty() const {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    38
  return _replaced_nodes == NULL || _replaced_nodes->length() == 0;
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    39
}
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    40
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    41
bool ReplacedNodes::has_node(const ReplacedNode& r) const {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    42
  return _replaced_nodes->find(r) != -1;
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    43
}
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    44
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    45
bool ReplacedNodes::has_target_node(Node* n) const {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    46
  for (int i = 0; i < _replaced_nodes->length(); i++) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    47
    if (_replaced_nodes->at(i).improved() == n) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    48
      return true;
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    49
    }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    50
  }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    51
  return false;
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    52
}
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    53
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    54
// Record replaced node if not seen before
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    55
void ReplacedNodes::record(Node* initial, Node* improved) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    56
  allocate_if_necessary();
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    57
  ReplacedNode r(initial, improved);
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    58
  if (!has_node(r)) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    59
    _replaced_nodes->push(r);
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    60
  }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    61
}
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    62
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    63
// Copy replaced nodes from one map to another. idx is used to
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    64
// identify nodes that are too new to be of interest in the target
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    65
// node list.
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    66
void ReplacedNodes::transfer_from(const ReplacedNodes& other, uint idx) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    67
  if (other.is_empty()) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    68
    return;
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    69
  }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    70
  allocate_if_necessary();
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    71
  for (int i = 0; i < other._replaced_nodes->length(); i++) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    72
    ReplacedNode replaced = other._replaced_nodes->at(i);
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    73
    // Only transfer the nodes that can actually be useful
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    74
    if (!has_node(replaced) && (replaced.initial()->_idx < idx || has_target_node(replaced.initial()))) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    75
      _replaced_nodes->push(replaced);
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    76
    }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    77
  }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    78
}
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    79
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    80
void ReplacedNodes::clone() {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    81
  if (_replaced_nodes != NULL) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    82
    GrowableArray<ReplacedNode>* replaced_nodes_clone = new GrowableArray<ReplacedNode>();
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    83
    replaced_nodes_clone->appendAll(_replaced_nodes);
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    84
    _replaced_nodes = replaced_nodes_clone;
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    85
  }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    86
}
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    87
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    88
void ReplacedNodes::reset() {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    89
  if (_replaced_nodes != NULL) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    90
    _replaced_nodes->clear();
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    91
  }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    92
}
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    93
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    94
// Perfom node replacement (used when returning to caller)
43963
6845bb645be5 8174164: SafePointNode::_replaced_nodes breaks with irreducible loops
roland
parents: 37248
diff changeset
    95
void ReplacedNodes::apply(Node* n, uint idx) {
24946
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    96
  if (is_empty()) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    97
    return;
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    98
  }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
    99
  for (int i = 0; i < _replaced_nodes->length(); i++) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   100
    ReplacedNode replaced = _replaced_nodes->at(i);
43963
6845bb645be5 8174164: SafePointNode::_replaced_nodes breaks with irreducible loops
roland
parents: 37248
diff changeset
   101
    // Only apply if improved node was created in a callee to avoid
6845bb645be5 8174164: SafePointNode::_replaced_nodes breaks with irreducible loops
roland
parents: 37248
diff changeset
   102
    // issues with irreducible loops in the caller
6845bb645be5 8174164: SafePointNode::_replaced_nodes breaks with irreducible loops
roland
parents: 37248
diff changeset
   103
    if (replaced.improved()->_idx >= idx) {
6845bb645be5 8174164: SafePointNode::_replaced_nodes breaks with irreducible loops
roland
parents: 37248
diff changeset
   104
      n->replace_edge(replaced.initial(), replaced.improved());
6845bb645be5 8174164: SafePointNode::_replaced_nodes breaks with irreducible loops
roland
parents: 37248
diff changeset
   105
    }
24946
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   106
  }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   107
}
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   108
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   109
static void enqueue_use(Node* n, Node* use, Unique_Node_List& work) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   110
  if (use->is_Phi()) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   111
    Node* r = use->in(0);
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   112
    assert(r->is_Region(), "Phi should have Region");
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   113
    for (uint i = 1; i < use->req(); i++) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   114
      if (use->in(i) == n) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   115
        work.push(r->in(i));
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   116
      }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   117
    }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   118
  } else {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   119
    work.push(use);
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   120
  }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   121
}
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   122
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   123
// Perfom node replacement following late inlining
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   124
void ReplacedNodes::apply(Compile* C, Node* ctl) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   125
  // ctl is the control on exit of the method that was late inlined
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   126
  if (is_empty()) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   127
    return;
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   128
  }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   129
  for (int i = 0; i < _replaced_nodes->length(); i++) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   130
    ReplacedNode replaced = _replaced_nodes->at(i);
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   131
    Node* initial = replaced.initial();
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   132
    Node* improved = replaced.improved();
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   133
    assert (ctl != NULL && !ctl->is_top(), "replaced node should have actual control");
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   134
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   135
    ResourceMark rm;
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   136
    Unique_Node_List work;
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   137
    // Go over all the uses of the node that is considered for replacement...
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   138
    for (DUIterator j = initial->outs(); initial->has_out(j); j++) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   139
      Node* use = initial->out(j);
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   140
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   141
      if (use == improved || use->outcnt() == 0) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   142
        continue;
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   143
      }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   144
      work.clear();
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   145
      enqueue_use(initial, use, work);
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   146
      bool replace = true;
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   147
      // Check that this use is dominated by ctl. Go ahead with the
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   148
      // replacement if it is.
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   149
      while (work.size() != 0 && replace) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   150
        Node* n = work.pop();
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   151
        if (use->outcnt() == 0) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   152
          continue;
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   153
        }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   154
        if (n->is_CFG() || (n->in(0) != NULL && !n->in(0)->is_top())) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   155
          int depth = 0;
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   156
          Node *m = n;
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   157
          if (!n->is_CFG()) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   158
            n = n->in(0);
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   159
          }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   160
          assert(n->is_CFG(), "should be CFG now");
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   161
          while(n != ctl) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   162
            n = IfNode::up_one_dom(n);
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   163
            depth++;
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   164
            // limit search depth
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   165
            if (depth >= 100 || n == NULL) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   166
              replace = false;
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   167
              break;
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   168
            }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   169
          }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   170
        } else {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   171
          for (DUIterator k = n->outs(); n->has_out(k); k++) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   172
            enqueue_use(n, n->out(k), work);
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   173
          }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   174
        }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   175
      }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   176
      if (replace) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   177
        bool is_in_table = C->initial_gvn()->hash_delete(use);
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   178
        int replaced = use->replace_edge(initial, improved);
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   179
        if (is_in_table) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   180
          C->initial_gvn()->hash_find_insert(use);
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   181
        }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   182
        C->record_for_igvn(use);
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   183
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   184
        assert(replaced > 0, "inconsistent");
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   185
        --j;
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   186
      }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   187
    }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   188
  }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   189
}
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   190
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   191
void ReplacedNodes::dump(outputStream *st) const {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   192
  if (!is_empty()) {
25645
0bcfdc697031 8048703: ReplacedNodes dumps it's content to tty
vlivanov
parents: 24946
diff changeset
   193
    st->print("replaced nodes: ");
24946
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   194
    for (int i = 0; i < _replaced_nodes->length(); i++) {
25645
0bcfdc697031 8048703: ReplacedNodes dumps it's content to tty
vlivanov
parents: 24946
diff changeset
   195
      st->print("%d->%d", _replaced_nodes->at(i).initial()->_idx, _replaced_nodes->at(i).improved()->_idx);
24946
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   196
      if (i < _replaced_nodes->length()-1) {
25645
0bcfdc697031 8048703: ReplacedNodes dumps it's content to tty
vlivanov
parents: 24946
diff changeset
   197
        st->print(",");
24946
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   198
      }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   199
    }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   200
  }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   201
}
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   202
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   203
// Merge 2 list of replaced node at a point where control flow paths merge
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   204
void ReplacedNodes::merge_with(const ReplacedNodes& other) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   205
  if (is_empty()) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   206
    return;
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   207
  }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   208
  if (other.is_empty()) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   209
    reset();
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   210
    return;
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   211
  }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   212
  int shift = 0;
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   213
  int len = _replaced_nodes->length();
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   214
  for (int i = 0; i < len; i++) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   215
    if (!other.has_node(_replaced_nodes->at(i))) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   216
      shift++;
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   217
    } else if (shift > 0) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   218
      _replaced_nodes->at_put(i-shift, _replaced_nodes->at(i));
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   219
    }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   220
  }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   221
  if (shift > 0) {
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   222
    _replaced_nodes->trunc_to(len - shift);
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   223
  }
24b68ccf3fc4 8026796: Make replace_in_map() on parent maps generic
roland
parents:
diff changeset
   224
}