hotspot/src/share/vm/opto/postaloc.cpp
author kvn
Fri, 15 Jun 2012 01:25:19 -0700
changeset 13104 657b387034fb
parent 11444 8a2619fd3fca
child 13110 f84319c2aca0
permissions -rw-r--r--
7119644: Increase superword's vector size up to 256 bits Summary: Increase vector size up to 256-bits for YMM AVX registers on x86. Reviewed-by: never, twisti, roland
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
13104
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
     2
 * Copyright (c) 1998, 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: 3795
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 3795
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: 3795
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/chaitin.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    28
#include "opto/machnode.hpp"
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
13104
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
    30
// See if this register (or pairs, or vector) already contains the value.
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
    31
static bool register_contains_value(Node* val, OptoReg::Name reg, int n_regs,
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
    32
                                    Node_List& value) {
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
    33
  for (int i = 0; i < n_regs; i++) {
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
    34
    OptoReg::Name nreg = OptoReg::add(reg,-i);
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
    35
    if (value[nreg] != val)
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
    36
      return false;
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
    37
  }
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
    38
  return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
1432
44f076e3d2a4 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 670
diff changeset
    41
//---------------------------may_be_copy_of_callee-----------------------------
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
// Check to see if we can possibly be a copy of a callee-save value.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
bool PhaseChaitin::may_be_copy_of_callee( Node *def ) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
  // Short circuit if there are no callee save registers
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
  if (_matcher.number_of_saved_registers() == 0) return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
  // Expect only a spill-down and reload on exit for callee-save spills.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
  // Chains of copies cannot be deep.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
  // 5008997 - This is wishful thinking. Register allocator seems to
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
  // be splitting live ranges for callee save registers to such
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
  // an extent that in large methods the chains can be very long
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
  // (50+). The conservative answer is to return true if we don't
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 1432
diff changeset
    53
  // know as this prevents optimizations from occurring.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
  const int limit = 60;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
  int i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
  for( i=0; i < limit; i++ ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
    if( def->is_Proj() && def->in(0)->is_Start() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
        _matcher.is_save_on_entry(lrgs(n2lidx(def)).reg()) )
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
      return true;              // Direct use of callee-save proj
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
    if( def->is_Copy() )        // Copies carry value through
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
      def = def->in(def->is_Copy());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
    else if( def->is_Phi() )    // Phis can merge it from any direction
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
      def = def->in(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
    else
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
    guarantee(def != NULL, "must not resurrect dead copy");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
  // If we reached the end and didn't find a callee save proj
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
  // then this may be a callee save proj so we return true
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
  // as the conservative answer. If we didn't reach then end
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
  // we must have discovered that it was not a callee save
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
  // else we would have returned.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
  return i == limit;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
10542
93e6f995c75c 7087453: PhaseChaitin::yank_if_dead() should handle MachTemp inputs
roland
parents: 7433
diff changeset
    77
//------------------------------yank-----------------------------------
93e6f995c75c 7087453: PhaseChaitin::yank_if_dead() should handle MachTemp inputs
roland
parents: 7433
diff changeset
    78
// Helper function for yank_if_dead
93e6f995c75c 7087453: PhaseChaitin::yank_if_dead() should handle MachTemp inputs
roland
parents: 7433
diff changeset
    79
int PhaseChaitin::yank( Node *old, Block *current_block, Node_List *value, Node_List *regnd ) {
93e6f995c75c 7087453: PhaseChaitin::yank_if_dead() should handle MachTemp inputs
roland
parents: 7433
diff changeset
    80
  int blk_adjust=0;
93e6f995c75c 7087453: PhaseChaitin::yank_if_dead() should handle MachTemp inputs
roland
parents: 7433
diff changeset
    81
  Block *oldb = _cfg._bbs[old->_idx];
93e6f995c75c 7087453: PhaseChaitin::yank_if_dead() should handle MachTemp inputs
roland
parents: 7433
diff changeset
    82
  oldb->find_remove(old);
93e6f995c75c 7087453: PhaseChaitin::yank_if_dead() should handle MachTemp inputs
roland
parents: 7433
diff changeset
    83
  // Count 1 if deleting an instruction from the current block
93e6f995c75c 7087453: PhaseChaitin::yank_if_dead() should handle MachTemp inputs
roland
parents: 7433
diff changeset
    84
  if( oldb == current_block ) blk_adjust++;
93e6f995c75c 7087453: PhaseChaitin::yank_if_dead() should handle MachTemp inputs
roland
parents: 7433
diff changeset
    85
  _cfg._bbs.map(old->_idx,NULL);
93e6f995c75c 7087453: PhaseChaitin::yank_if_dead() should handle MachTemp inputs
roland
parents: 7433
diff changeset
    86
  OptoReg::Name old_reg = lrgs(n2lidx(old)).reg();
93e6f995c75c 7087453: PhaseChaitin::yank_if_dead() should handle MachTemp inputs
roland
parents: 7433
diff changeset
    87
  if( regnd && (*regnd)[old_reg]==old ) { // Instruction is currently available?
93e6f995c75c 7087453: PhaseChaitin::yank_if_dead() should handle MachTemp inputs
roland
parents: 7433
diff changeset
    88
    value->map(old_reg,NULL);  // Yank from value/regnd maps
93e6f995c75c 7087453: PhaseChaitin::yank_if_dead() should handle MachTemp inputs
roland
parents: 7433
diff changeset
    89
    regnd->map(old_reg,NULL);  // This register's value is now unknown
93e6f995c75c 7087453: PhaseChaitin::yank_if_dead() should handle MachTemp inputs
roland
parents: 7433
diff changeset
    90
  }
93e6f995c75c 7087453: PhaseChaitin::yank_if_dead() should handle MachTemp inputs
roland
parents: 7433
diff changeset
    91
  return blk_adjust;
93e6f995c75c 7087453: PhaseChaitin::yank_if_dead() should handle MachTemp inputs
roland
parents: 7433
diff changeset
    92
}
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
11444
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
    94
#ifdef ASSERT
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
    95
static bool expected_yanked_node(Node *old, Node *orig_old) {
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
    96
  // This code is expected only next original nodes:
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
    97
  // - load from constant table node which may have next data input nodes:
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
    98
  //     MachConstantBase, Phi, MachTemp, MachSpillCopy
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
    99
  // - load constant node which may have next data input nodes:
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   100
  //     MachTemp, MachSpillCopy
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   101
  // - MachSpillCopy
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   102
  // - MachProj and Copy dead nodes
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   103
  if (old->is_MachSpillCopy()) {
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   104
    return true;
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   105
  } else if (old->is_Con()) {
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   106
    return true;
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   107
  } else if (old->is_MachProj()) { // Dead kills projection of Con node
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   108
    return (old == orig_old);
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   109
  } else if (old->is_Copy()) {     // Dead copy of a callee-save value
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   110
    return (old == orig_old);
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   111
  } else if (old->is_MachTemp()) {
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   112
    return orig_old->is_Con();
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   113
  } else if (old->is_Phi() || old->is_MachConstantBase()) {
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   114
    return (orig_old->is_Con() && orig_old->is_MachConstant());
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   115
  }
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   116
  return false;
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   117
}
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   118
#endif
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   119
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
//------------------------------yank_if_dead-----------------------------------
11444
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   121
// Removed edges from 'old'.  Yank if dead.  Return adjustment counts to
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
// iterators in the current block.
11444
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   123
int PhaseChaitin::yank_if_dead_recurse(Node *old, Node *orig_old, Block *current_block,
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   124
                                       Node_List *value, Node_List *regnd) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
  int blk_adjust=0;
11444
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   126
  if (old->outcnt() == 0 && old != C->top()) {
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   127
#ifdef ASSERT
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   128
    if (!expected_yanked_node(old, orig_old)) {
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   129
      tty->print_cr("==============================================");
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   130
      tty->print_cr("orig_old:");
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   131
      orig_old->dump();
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   132
      tty->print_cr("old:");
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   133
      old->dump();
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   134
      assert(false, "unexpected yanked node");
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   135
    }
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   136
    if (old->is_Con())
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   137
      orig_old = old; // Reset to satisfy expected nodes checks.
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   138
#endif
10542
93e6f995c75c 7087453: PhaseChaitin::yank_if_dead() should handle MachTemp inputs
roland
parents: 7433
diff changeset
   139
    blk_adjust += yank(old, current_block, value, regnd);
93e6f995c75c 7087453: PhaseChaitin::yank_if_dead() should handle MachTemp inputs
roland
parents: 7433
diff changeset
   140
93e6f995c75c 7087453: PhaseChaitin::yank_if_dead() should handle MachTemp inputs
roland
parents: 7433
diff changeset
   141
    for (uint i = 1; i < old->req(); i++) {
11444
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   142
      Node* n = old->in(i);
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   143
      if (n != NULL) {
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   144
        old->set_req(i, NULL);
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   145
        blk_adjust += yank_if_dead_recurse(n, orig_old, current_block, value, regnd);
10542
93e6f995c75c 7087453: PhaseChaitin::yank_if_dead() should handle MachTemp inputs
roland
parents: 7433
diff changeset
   146
      }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
    }
11444
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10549
diff changeset
   148
    // Disconnect control and remove precedence edges if any exist
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
    old->disconnect_inputs(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
  return blk_adjust;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
//------------------------------use_prior_register-----------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
// Use the prior value instead of the current value, in an effort to make
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
// the current value go dead.  Return block iterator adjustment, in case
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
// we yank some instructions from this block.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
int PhaseChaitin::use_prior_register( Node *n, uint idx, Node *def, Block *current_block, Node_List &value, Node_List &regnd ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
  // No effect?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
  if( def == n->in(idx) ) return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
  // Def is currently dead and can be removed?  Do not resurrect
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
  if( def->outcnt() == 0 ) return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
  // Not every pair of physical registers are assignment compatible,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
  // e.g. on sparc floating point registers are not assignable to integer
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
  // registers.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
  const LRG &def_lrg = lrgs(n2lidx(def));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
  OptoReg::Name def_reg = def_lrg.reg();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
  const RegMask &use_mask = n->in_RegMask(idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
  bool can_use = ( RegMask::can_represent(def_reg) ? (use_mask.Member(def_reg) != 0)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
                                                   : (use_mask.is_AllStack() != 0));
13104
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   172
  if (!RegMask::is_vector(def->ideal_reg())) {
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   173
    // Check for a copy to or from a misaligned pair.
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   174
    // It is workaround for a sparc with misaligned pairs.
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   175
    can_use = can_use && !use_mask.is_misaligned_pair() && !def_lrg.mask().is_misaligned_pair();
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   176
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
  if (!can_use)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
    return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
  // Capture the old def in case it goes dead...
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
  Node *old = n->in(idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
  // Save-on-call copies can only be elided if the entire copy chain can go
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
  // away, lest we get the same callee-save value alive in 2 locations at
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
  // once.  We check for the obvious trivial case here.  Although it can
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
  // sometimes be elided with cooperation outside our scope, here we will just
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
  // miss the opportunity.  :-(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
  if( may_be_copy_of_callee(def) ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
    if( old->outcnt() > 1 ) return 0; // We're the not last user
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
    int idx = old->is_Copy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
    assert( idx, "chain of copies being removed" );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
    Node *old2 = old->in(idx);  // Chain of copies
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
    if( old2->outcnt() > 1 ) return 0; // old is not the last user
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
    int idx2 = old2->is_Copy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
    if( !idx2 ) return 0;       // Not a chain of 2 copies
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
    if( def != old2->in(idx2) ) return 0; // Chain of exactly 2 copies
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
  // Use the new def
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
  n->set_req(idx,def);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
  _post_alloc++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
  // Is old def now dead?  We successfully yanked a copy?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
  return yank_if_dead(old,current_block,&value,&regnd);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
//------------------------------skip_copies------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
// Skip through any number of copies (that don't mod oop-i-ness)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
Node *PhaseChaitin::skip_copies( Node *c ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
  int idx = c->is_Copy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
  uint is_oop = lrgs(n2lidx(c))._is_oop;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
  while (idx != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
    guarantee(c->in(idx) != NULL, "must not resurrect dead copy");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
    if (lrgs(n2lidx(c->in(idx)))._is_oop != is_oop)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
      break;  // casting copy, not the same value
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
    c = c->in(idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
    idx = c->is_Copy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
  return c;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
//------------------------------elide_copy-------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
// Remove (bypass) copies along Node n, edge k.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
int PhaseChaitin::elide_copy( Node *n, int k, Block *current_block, Node_List &value, Node_List &regnd, bool can_change_regs ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
  int blk_adjust = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
  uint nk_idx = n2lidx(n->in(k));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
  OptoReg::Name nk_reg = lrgs(nk_idx ).reg();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
  // Remove obvious same-register copies
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
  Node *x = n->in(k);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
  int idx;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
  while( (idx=x->is_Copy()) != 0 ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
    Node *copy = x->in(idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
    guarantee(copy != NULL, "must not resurrect dead copy");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
    if( lrgs(n2lidx(copy)).reg() != nk_reg ) break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
    blk_adjust += use_prior_register(n,k,copy,current_block,value,regnd);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
    if( n->in(k) != copy ) break; // Failed for some cutout?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
    x = copy;                   // Progress, try again
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
  // Phis and 2-address instructions cannot change registers so easily - their
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
  // outputs must match their input.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
  if( !can_change_regs )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
    return blk_adjust;          // Only check stupid copies!
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
  // Loop backedges won't have a value-mapping yet
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
  if( &value == NULL ) return blk_adjust;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
  // Skip through all copies to the _value_ being used.  Do not change from
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
  // int to pointer.  This attempts to jump through a chain of copies, where
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
  // intermediate copies might be illegal, i.e., value is stored down to stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
  // then reloaded BUT survives in a register the whole way.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
  Node *val = skip_copies(n->in(k));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
7433
b418028612ad 6961690: load oops from constant table on SPARC
twisti
parents: 7397
diff changeset
   257
  if (val == x && nk_idx != 0 &&
b418028612ad 6961690: load oops from constant table on SPARC
twisti
parents: 7397
diff changeset
   258
      regnd[nk_reg] != NULL && regnd[nk_reg] != x &&
b418028612ad 6961690: load oops from constant table on SPARC
twisti
parents: 7397
diff changeset
   259
      n2lidx(x) == n2lidx(regnd[nk_reg])) {
b418028612ad 6961690: load oops from constant table on SPARC
twisti
parents: 7397
diff changeset
   260
    // When rematerialzing nodes and stretching lifetimes, the
b418028612ad 6961690: load oops from constant table on SPARC
twisti
parents: 7397
diff changeset
   261
    // allocator will reuse the original def for multidef LRG instead
b418028612ad 6961690: load oops from constant table on SPARC
twisti
parents: 7397
diff changeset
   262
    // of the current reaching def because it can't know it's safe to
b418028612ad 6961690: load oops from constant table on SPARC
twisti
parents: 7397
diff changeset
   263
    // do so.  After allocation completes if they are in the same LRG
b418028612ad 6961690: load oops from constant table on SPARC
twisti
parents: 7397
diff changeset
   264
    // then it should use the current reaching def instead.
b418028612ad 6961690: load oops from constant table on SPARC
twisti
parents: 7397
diff changeset
   265
    n->set_req(k, regnd[nk_reg]);
b418028612ad 6961690: load oops from constant table on SPARC
twisti
parents: 7397
diff changeset
   266
    blk_adjust += yank_if_dead(val, current_block, &value, &regnd);
b418028612ad 6961690: load oops from constant table on SPARC
twisti
parents: 7397
diff changeset
   267
    val = skip_copies(n->in(k));
b418028612ad 6961690: load oops from constant table on SPARC
twisti
parents: 7397
diff changeset
   268
  }
b418028612ad 6961690: load oops from constant table on SPARC
twisti
parents: 7397
diff changeset
   269
13104
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   270
  if (val == x) return blk_adjust; // No progress?
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
13104
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   272
  int n_regs = RegMask::num_registers(val->ideal_reg());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
  uint val_idx = n2lidx(val);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
  OptoReg::Name val_reg = lrgs(val_idx).reg();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
  // See if it happens to already be in the correct register!
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
  // (either Phi's direct register, or the common case of the name
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
  // never-clobbered original-def register)
13104
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   279
  if (register_contains_value(val, val_reg, n_regs, value)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
    blk_adjust += use_prior_register(n,k,regnd[val_reg],current_block,value,regnd);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
    if( n->in(k) == regnd[val_reg] ) // Success!  Quit trying
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
      return blk_adjust;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
  // See if we can skip the copy by changing registers.  Don't change from
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
  // using a register to using the stack unless we know we can remove a
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
  // copy-load.  Otherwise we might end up making a pile of Intel cisc-spill
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
  // ops reading from memory instead of just loading once and using the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
  // register.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
  // Also handle duplicate copies here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
  const Type *t = val->is_Con() ? val->bottom_type() : NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
  // Scan all registers to see if this value is around already
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
  for( uint reg = 0; reg < (uint)_max_reg; reg++ ) {
1432
44f076e3d2a4 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 670
diff changeset
   296
    if (reg == (uint)nk_reg) {
44f076e3d2a4 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 670
diff changeset
   297
      // Found ourselves so check if there is only one user of this
44f076e3d2a4 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 670
diff changeset
   298
      // copy and keep on searching for a better copy if so.
44f076e3d2a4 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 670
diff changeset
   299
      bool ignore_self = true;
44f076e3d2a4 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 670
diff changeset
   300
      x = n->in(k);
44f076e3d2a4 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 670
diff changeset
   301
      DUIterator_Fast imax, i = x->fast_outs(imax);
44f076e3d2a4 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 670
diff changeset
   302
      Node* first = x->fast_out(i); i++;
44f076e3d2a4 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 670
diff changeset
   303
      while (i < imax && ignore_self) {
44f076e3d2a4 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 670
diff changeset
   304
        Node* use = x->fast_out(i); i++;
44f076e3d2a4 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 670
diff changeset
   305
        if (use != first) ignore_self = false;
44f076e3d2a4 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 670
diff changeset
   306
      }
44f076e3d2a4 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 670
diff changeset
   307
      if (ignore_self) continue;
44f076e3d2a4 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 670
diff changeset
   308
    }
44f076e3d2a4 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 670
diff changeset
   309
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
    Node *vv = value[reg];
13104
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   311
    if (n_regs > 1) {             // Doubles check for aligned-adjacent pair
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
      if( (reg&1)==0 ) continue;  // Wrong half of a pair
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
      if( vv != value[reg-1] ) continue; // Not a complete pair
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
    if( vv == val ||            // Got a direct hit?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
        (t && vv && vv->bottom_type() == t && vv->is_Mach() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
         vv->as_Mach()->rule() == val->as_Mach()->rule()) ) { // Or same constant?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
      assert( !n->is_Phi(), "cannot change registers at a Phi so easily" );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
      if( OptoReg::is_stack(nk_reg) || // CISC-loading from stack OR
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
          OptoReg::is_reg(reg) || // turning into a register use OR
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
          regnd[reg]->outcnt()==1 ) { // last use of a spill-load turns into a CISC use
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
        blk_adjust += use_prior_register(n,k,regnd[reg],current_block,value,regnd);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
        if( n->in(k) == regnd[reg] ) // Success!  Quit trying
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
          return blk_adjust;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
      } // End of if not degrading to a stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
    } // End of if found value in another register
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
  } // End of scan all machine registers
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
  return blk_adjust;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
// Check if nreg already contains the constant value val.  Normal copy
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
// elimination doesn't doesn't work on constants because multiple
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
// nodes can represent the same constant so the type and rule of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
// MachNode must be checked to ensure equivalence.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
//
243
79b67a7a584a 6661247: Internal bug in 32-bit HotSpot optimizer while bit manipulations
never
parents: 1
diff changeset
   338
bool PhaseChaitin::eliminate_copy_of_constant(Node* val, Node* n,
79b67a7a584a 6661247: Internal bug in 32-bit HotSpot optimizer while bit manipulations
never
parents: 1
diff changeset
   339
                                              Block *current_block,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
                                              Node_List& value, Node_List& regnd,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
                                              OptoReg::Name nreg, OptoReg::Name nreg2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
  if (value[nreg] != val && val->is_Con() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
      value[nreg] != NULL && value[nreg]->is_Con() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
      (nreg2 == OptoReg::Bad || value[nreg] == value[nreg2]) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
      value[nreg]->bottom_type() == val->bottom_type() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
      value[nreg]->as_Mach()->rule() == val->as_Mach()->rule()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
    // This code assumes that two MachNodes representing constants
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
    // which have the same rule and the same bottom type will produce
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
    // identical effects into a register.  This seems like it must be
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
    // objectively true unless there are hidden inputs to the nodes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
    // but if that were to change this code would need to updated.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
    // Since they are equivalent the second one if redundant and can
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
    // be removed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
    //
243
79b67a7a584a 6661247: Internal bug in 32-bit HotSpot optimizer while bit manipulations
never
parents: 1
diff changeset
   355
    // n will be replaced with the old value but n might have
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
    // kills projections associated with it so remove them now so that
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 1432
diff changeset
   357
    // yank_if_dead will be able to eliminate the copy once the uses
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
    // have been transferred to the old[value].
243
79b67a7a584a 6661247: Internal bug in 32-bit HotSpot optimizer while bit manipulations
never
parents: 1
diff changeset
   359
    for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
79b67a7a584a 6661247: Internal bug in 32-bit HotSpot optimizer while bit manipulations
never
parents: 1
diff changeset
   360
      Node* use = n->fast_out(i);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
      if (use->is_Proj() && use->outcnt() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
        // Kill projections have no users and one input
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
        use->set_req(0, C->top());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
        yank_if_dead(use, current_block, &value, &regnd);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
        --i; --imax;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
    _post_alloc++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
//------------------------------post_allocate_copy_removal---------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
// Post-Allocation peephole copy removal.  We do this in 1 pass over the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
// basic blocks.  We maintain a mapping of registers to Nodes (an  array of
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
// Nodes indexed by machine register or stack slot number).  NULL means that a
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
// register is not mapped to any Node.  We can (want to have!) have several
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
// registers map to the same Node.  We walk forward over the instructions
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
// updating the mapping as we go.  At merge points we force a NULL if we have
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
// to merge 2 different Nodes into the same register.  Phi functions will give
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
// us a new Node if there is a proper value merging.  Since the blocks are
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
// arranged in some RPO, we will visit all parent blocks before visiting any
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
// successor blocks (except at loops).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
// If we find a Copy we look to see if the Copy's source register is a stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
// slot and that value has already been loaded into some machine register; if
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
// so we use machine register directly.  This turns a Load into a reg-reg
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
// Move.  We also look for reloads of identical constants.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
// When we see a use from a reg-reg Copy, we will attempt to use the copy's
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
// source directly and make the copy go dead.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
void PhaseChaitin::post_allocate_copy_removal() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
  NOT_PRODUCT( Compile::TracePhase t3("postAllocCopyRemoval", &_t_postAllocCopyRemoval, TimeCompiler); )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
  // Need a mapping from basic block Node_Lists.  We need a Node_List to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
  // map from register number to value-producing Node.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
  Node_List **blk2value = NEW_RESOURCE_ARRAY( Node_List *, _cfg._num_blocks+1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
  memset( blk2value, 0, sizeof(Node_List*)*(_cfg._num_blocks+1) );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
  // Need a mapping from basic block Node_Lists.  We need a Node_List to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
  // map from register number to register-defining Node.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
  Node_List **blk2regnd = NEW_RESOURCE_ARRAY( Node_List *, _cfg._num_blocks+1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
  memset( blk2regnd, 0, sizeof(Node_List*)*(_cfg._num_blocks+1) );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
  // We keep unused Node_Lists on a free_list to avoid wasting
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
  // memory.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
  GrowableArray<Node_List*> free_list = GrowableArray<Node_List*>(16);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
  // For all blocks
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
  for( uint i = 0; i < _cfg._num_blocks; i++ ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
    uint j;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
    Block *b = _cfg._blocks[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
    // Count of Phis in block
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
    uint phi_dex;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
    for( phi_dex = 1; phi_dex < b->_nodes.size(); phi_dex++ ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
      Node *phi = b->_nodes[phi_dex];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
      if( !phi->is_Phi() )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
    // If any predecessor has not been visited, we do not know the state
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
    // of registers at the start.  Check for this, while updating copies
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
    // along Phi input edges
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
    bool missing_some_inputs = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
    Block *freed = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
    for( j = 1; j < b->num_preds(); j++ ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
      Block *pb = _cfg._bbs[b->pred(j)->_idx];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
      // Remove copies along phi edges
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
      for( uint k=1; k<phi_dex; k++ )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
        elide_copy( b->_nodes[k], j, b, *blk2value[pb->_pre_order], *blk2regnd[pb->_pre_order], false );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
      if( blk2value[pb->_pre_order] ) { // Have a mapping on this edge?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
        // See if this predecessor's mappings have been used by everybody
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
        // who wants them.  If so, free 'em.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
        uint k;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
        for( k=0; k<pb->_num_succs; k++ ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
          Block *pbsucc = pb->_succs[k];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
          if( !blk2value[pbsucc->_pre_order] && pbsucc != b )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
            break;              // Found a future user
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
        if( k >= pb->_num_succs ) { // No more uses, free!
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
          freed = pb;           // Record last block freed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
          free_list.push(blk2value[pb->_pre_order]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
          free_list.push(blk2regnd[pb->_pre_order]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
      } else {                  // This block has unvisited (loopback) inputs
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
        missing_some_inputs = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
    // Extract Node_List mappings.  If 'freed' is non-zero, we just popped
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
    // 'freed's blocks off the list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
    Node_List &regnd = *(free_list.is_empty() ? new Node_List() : free_list.pop());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
    Node_List &value = *(free_list.is_empty() ? new Node_List() : free_list.pop());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
    assert( !freed || blk2value[freed->_pre_order] == &value, "" );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
    value.map(_max_reg,NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
    regnd.map(_max_reg,NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
    // Set mappings as OUR mappings
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
    blk2value[b->_pre_order] = &value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
    blk2regnd[b->_pre_order] = &regnd;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
    // Initialize value & regnd for this block
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
    if( missing_some_inputs ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
      // Some predecessor has not yet been visited; zap map to empty
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
      for( uint k = 0; k < (uint)_max_reg; k++ ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
        value.map(k,NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
        regnd.map(k,NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
      if( !freed ) {            // Didn't get a freebie prior block
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
        // Must clone some data
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
        freed = _cfg._bbs[b->pred(1)->_idx];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
        Node_List &f_value = *blk2value[freed->_pre_order];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
        Node_List &f_regnd = *blk2regnd[freed->_pre_order];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
        for( uint k = 0; k < (uint)_max_reg; k++ ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
          value.map(k,f_value[k]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
          regnd.map(k,f_regnd[k]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
      // Merge all inputs together, setting to NULL any conflicts.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
      for( j = 1; j < b->num_preds(); j++ ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
        Block *pb = _cfg._bbs[b->pred(j)->_idx];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
        if( pb == freed ) continue; // Did self already via freelist
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
        Node_List &p_regnd = *blk2regnd[pb->_pre_order];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
        for( uint k = 0; k < (uint)_max_reg; k++ ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
          if( regnd[k] != p_regnd[k] ) { // Conflict on reaching defs?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
            value.map(k,NULL); // Then no value handy
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
            regnd.map(k,NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
    // For all Phi's
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
    for( j = 1; j < phi_dex; j++ ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
      uint k;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
      Node *phi = b->_nodes[j];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
      uint pidx = n2lidx(phi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
      OptoReg::Name preg = lrgs(n2lidx(phi)).reg();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
      // Remove copies remaining on edges.  Check for junk phi.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
      Node *u = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
      for( k=1; k<phi->req(); k++ ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
        Node *x = phi->in(k);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
        if( phi != x && u != x ) // Found a different input
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
          u = u ? NodeSentinel : x; // Capture unique input, or NodeSentinel for 2nd input
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
      if( u != NodeSentinel ) {    // Junk Phi.  Remove
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
        b->_nodes.remove(j--); phi_dex--;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
        _cfg._bbs.map(phi->_idx,NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
        phi->replace_by(u);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
        phi->disconnect_inputs(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
        continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
      // Note that if value[pidx] exists, then we merged no new values here
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
      // and the phi is useless.  This can happen even with the above phi
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
      // removal for complex flows.  I cannot keep the better known value here
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
      // because locally the phi appears to define a new merged value.  If I
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
      // keep the better value then a copy of the phi, being unable to use the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
      // global flow analysis, can't "peek through" the phi to the original
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
      // reaching value and so will act like it's defining a new value.  This
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
      // can lead to situations where some uses are from the old and some from
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
      // the new values.  Not illegal by itself but throws the over-strong
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
      // assert in scheduling.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
      if( pidx ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
        value.map(preg,phi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
        regnd.map(preg,phi);
13104
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   531
        int n_regs = RegMask::num_registers(phi->ideal_reg());
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   532
        for (int l = 1; l < n_regs; l++) {
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   533
          OptoReg::Name preg_lo = OptoReg::add(preg,-l);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
          value.map(preg_lo,phi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
          regnd.map(preg_lo,phi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
    // For all remaining instructions
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
    for( j = phi_dex; j < b->_nodes.size(); j++ ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
      Node *n = b->_nodes[j];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
      if( n->outcnt() == 0 &&   // Dead?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
          n != C->top() &&      // (ignore TOP, it has no du info)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
          !n->is_Proj() ) {     // fat-proj kills
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
        j -= yank_if_dead(n,b,&value,&regnd);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
        continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
      // Improve reaching-def info.  Occasionally post-alloc's liveness gives
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
      // up (at loop backedges, because we aren't doing a full flow pass).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
      // The presence of a live use essentially asserts that the use's def is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
      // alive and well at the use (or else the allocator fubar'd).  Take
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
      // advantage of this info to set a reaching def for the use-reg.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
      uint k;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
      for( k = 1; k < n->req(); k++ ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
        Node *def = n->in(k);   // n->in(k) is a USE; def is the DEF for this USE
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
        guarantee(def != NULL, "no disconnected nodes at this point");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
        uint useidx = n2lidx(def); // useidx is the live range index for this USE
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
        if( useidx ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
          OptoReg::Name ureg = lrgs(useidx).reg();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
          if( !value[ureg] ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
            int idx;            // Skip occasional useless copy
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
            while( (idx=def->is_Copy()) != 0 &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
                   def->in(idx) != NULL &&  // NULL should not happen
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
                   ureg == lrgs(n2lidx(def->in(idx))).reg() )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
              def = def->in(idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
            Node *valdef = skip_copies(def); // tighten up val through non-useless copies
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
            value.map(ureg,valdef); // record improved reaching-def info
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
            regnd.map(ureg,   def);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   573
            // Record other half of doubles
13104
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   574
            uint def_ideal_reg = def->ideal_reg();
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   575
            int n_regs = RegMask::num_registers(def_ideal_reg);
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   576
            bool is_vec = RegMask::is_vector(def_ideal_reg);
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   577
            for (int l = 1; l < n_regs; l++) {
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   578
              OptoReg::Name ureg_lo = OptoReg::add(ureg,-l);
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   579
              if (!value[ureg_lo] &&
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   580
                  (!RegMask::can_represent(ureg_lo) ||
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   581
                   lrgs(useidx).mask().Member(ureg_lo))) { // Nearly always adjacent
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   582
                value.map(ureg_lo,valdef); // record improved reaching-def info
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   583
                regnd.map(ureg_lo,   def);
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   584
              }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
      const uint two_adr = n->is_Mach() ? n->as_Mach()->two_adr() : 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
      // Remove copies along input edges
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
      for( k = 1; k < n->req(); k++ )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
        j -= elide_copy( n, k, b, value, regnd, two_adr!=k );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
      // Unallocated Nodes define no registers
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
      uint lidx = n2lidx(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
      if( !lidx ) continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
      // Update the register defined by this instruction
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
      OptoReg::Name nreg = lrgs(lidx).reg();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
      // Skip through all copies to the _value_ being defined.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
      // Do not change from int to pointer
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
      Node *val = skip_copies(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
3678
d797d97552e4 6862863: C2 compiler fails in elide_copy()
never
parents: 2131
diff changeset
   606
      // Clear out a dead definition before starting so that the
d797d97552e4 6862863: C2 compiler fails in elide_copy()
never
parents: 2131
diff changeset
   607
      // elimination code doesn't have to guard against it.  The
d797d97552e4 6862863: C2 compiler fails in elide_copy()
never
parents: 2131
diff changeset
   608
      // definition could in fact be a kill projection with a count of
d797d97552e4 6862863: C2 compiler fails in elide_copy()
never
parents: 2131
diff changeset
   609
      // 0 which is safe but since those are uninteresting for copy
d797d97552e4 6862863: C2 compiler fails in elide_copy()
never
parents: 2131
diff changeset
   610
      // elimination just delete them as well.
d797d97552e4 6862863: C2 compiler fails in elide_copy()
never
parents: 2131
diff changeset
   611
      if (regnd[nreg] != NULL && regnd[nreg]->outcnt() == 0) {
d797d97552e4 6862863: C2 compiler fails in elide_copy()
never
parents: 2131
diff changeset
   612
        regnd.map(nreg, NULL);
d797d97552e4 6862863: C2 compiler fails in elide_copy()
never
parents: 2131
diff changeset
   613
        value.map(nreg, NULL);
d797d97552e4 6862863: C2 compiler fails in elide_copy()
never
parents: 2131
diff changeset
   614
      }
d797d97552e4 6862863: C2 compiler fails in elide_copy()
never
parents: 2131
diff changeset
   615
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
      uint n_ideal_reg = n->ideal_reg();
13104
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   617
      int n_regs = RegMask::num_registers(n_ideal_reg);
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   618
      if (n_regs == 1) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
        // If Node 'n' does not change the value mapped by the register,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
        // then 'n' is a useless copy.  Do not update the register->node
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
        // mapping so 'n' will go dead.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
        if( value[nreg] != val ) {
243
79b67a7a584a 6661247: Internal bug in 32-bit HotSpot optimizer while bit manipulations
never
parents: 1
diff changeset
   623
          if (eliminate_copy_of_constant(val, n, b, value, regnd, nreg, OptoReg::Bad)) {
3678
d797d97552e4 6862863: C2 compiler fails in elide_copy()
never
parents: 2131
diff changeset
   624
            j -= replace_and_yank_if_dead(n, nreg, b, value, regnd);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
          } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
            // Update the mapping: record new Node defined by the register
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
            regnd.map(nreg,n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
            // Update mapping for defined *value*, which is the defined
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
            // Node after skipping all copies.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
            value.map(nreg,val);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
          }
3678
d797d97552e4 6862863: C2 compiler fails in elide_copy()
never
parents: 2131
diff changeset
   632
        } else if( !may_be_copy_of_callee(n) ) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   633
          assert( n->is_Copy(), "" );
3678
d797d97552e4 6862863: C2 compiler fails in elide_copy()
never
parents: 2131
diff changeset
   634
          j -= replace_and_yank_if_dead(n, nreg, b, value, regnd);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   635
        }
13104
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   636
      } else if (RegMask::is_vector(n_ideal_reg)) {
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   637
        // If Node 'n' does not change the value mapped by the register,
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   638
        // then 'n' is a useless copy.  Do not update the register->node
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   639
        // mapping so 'n' will go dead.
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   640
        if (!register_contains_value(val, nreg, n_regs, value)) {
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   641
          // Update the mapping: record new Node defined by the register
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   642
          regnd.map(nreg,n);
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   643
          // Update mapping for defined *value*, which is the defined
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   644
          // Node after skipping all copies.
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   645
          value.map(nreg,val);
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   646
          for (int l = 1; l < n_regs; l++) {
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   647
            OptoReg::Name nreg_lo = OptoReg::add(nreg,-l);
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   648
            regnd.map(nreg_lo, n );
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   649
            value.map(nreg_lo,val);
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   650
          }
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   651
        } else if (n->is_Copy()) {
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   652
          // Note: vector can't be constant and can't be copy of calee.
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   653
          j -= replace_and_yank_if_dead(n, nreg, b, value, regnd);
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   654
        }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
        // If the value occupies a register pair, record same info
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
        // in both registers.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
        OptoReg::Name nreg_lo = OptoReg::add(nreg,-1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
        if( RegMask::can_represent(nreg_lo) &&     // Either a spill slot, or
489c9b5090e2 Initial load
duke
parents:
diff changeset
   660
            !lrgs(lidx).mask().Member(nreg_lo) ) { // Nearly always adjacent
489c9b5090e2 Initial load
duke
parents:
diff changeset
   661
          // Sparc occasionally has non-adjacent pairs.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   662
          // Find the actual other value
489c9b5090e2 Initial load
duke
parents:
diff changeset
   663
          RegMask tmp = lrgs(lidx).mask();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
          tmp.Remove(nreg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
          nreg_lo = tmp.find_first_elem();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   666
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   667
        if( value[nreg] != val || value[nreg_lo] != val ) {
243
79b67a7a584a 6661247: Internal bug in 32-bit HotSpot optimizer while bit manipulations
never
parents: 1
diff changeset
   668
          if (eliminate_copy_of_constant(val, n, b, value, regnd, nreg, nreg_lo)) {
3678
d797d97552e4 6862863: C2 compiler fails in elide_copy()
never
parents: 2131
diff changeset
   669
            j -= replace_and_yank_if_dead(n, nreg, b, value, regnd);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   670
          } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   671
            regnd.map(nreg   , n );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   672
            regnd.map(nreg_lo, n );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   673
            value.map(nreg   ,val);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   674
            value.map(nreg_lo,val);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
          }
3678
d797d97552e4 6862863: C2 compiler fails in elide_copy()
never
parents: 2131
diff changeset
   676
        } else if( !may_be_copy_of_callee(n) ) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   677
          assert( n->is_Copy(), "" );
3678
d797d97552e4 6862863: C2 compiler fails in elide_copy()
never
parents: 2131
diff changeset
   678
          j -= replace_and_yank_if_dead(n, nreg, b, value, regnd);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
      // Fat projections kill many registers
489c9b5090e2 Initial load
duke
parents:
diff changeset
   683
      if( n_ideal_reg == MachProjNode::fat_proj ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   684
        RegMask rm = n->out_RegMask();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   685
        // wow, what an expensive iterator...
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
        nreg = rm.find_first_elem();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   687
        while( OptoReg::is_valid(nreg)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   688
          rm.Remove(nreg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   689
          value.map(nreg,n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   690
          regnd.map(nreg,n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
          nreg = rm.find_first_elem();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
489c9b5090e2 Initial load
duke
parents:
diff changeset
   695
    } // End of for all instructions in the block
489c9b5090e2 Initial load
duke
parents:
diff changeset
   696
489c9b5090e2 Initial load
duke
parents:
diff changeset
   697
  } // End for all blocks
489c9b5090e2 Initial load
duke
parents:
diff changeset
   698
}