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