hotspot/src/share/vm/opto/convertnode.cpp
author thartmann
Mon, 02 Jun 2014 08:07:29 +0200
changeset 24923 9631f7d691dc
parent 23528 8f1a7f5e8066
child 29081 c61eb4914428
permissions -rw-r--r--
8034812: remove IDX_INIT macro hack in Node class Summary: The IDX_INIT macro used by Node::Node(...) to retrieve the Compile object is removed and replaced by a call to Compile::current(). The Node constructor, new operator and all calls to it are adapted accordingly. Reviewed-by: kvn, jrose, iveresov, goetz
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
23528
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
     1
/*
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
     2
 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
     4
 *
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
     7
 * published by the Free Software Foundation.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
     8
 *
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    13
 * accompanied this code).
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    14
 *
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    18
 *
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    21
 * questions.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    22
 *
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    23
 */
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    24
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    25
#include "precompiled.hpp"
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    26
#include "opto/addnode.hpp"
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    27
#include "opto/convertnode.hpp"
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    28
#include "opto/matcher.hpp"
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    29
#include "opto/phaseX.hpp"
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    30
#include "opto/subnode.hpp"
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    31
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    32
//=============================================================================
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    33
//------------------------------Identity---------------------------------------
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    34
Node *Conv2BNode::Identity( PhaseTransform *phase ) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    35
  const Type *t = phase->type( in(1) );
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    36
  if( t == Type::TOP ) return in(1);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    37
  if( t == TypeInt::ZERO ) return in(1);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    38
  if( t == TypeInt::ONE ) return in(1);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    39
  if( t == TypeInt::BOOL ) return in(1);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    40
  return this;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    41
}
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    42
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    43
//------------------------------Value------------------------------------------
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    44
const Type *Conv2BNode::Value( PhaseTransform *phase ) const {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    45
  const Type *t = phase->type( in(1) );
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    46
  if( t == Type::TOP ) return Type::TOP;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    47
  if( t == TypeInt::ZERO ) return TypeInt::ZERO;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    48
  if( t == TypePtr::NULL_PTR ) return TypeInt::ZERO;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    49
  const TypePtr *tp = t->isa_ptr();
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    50
  if( tp != NULL ) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    51
    if( tp->ptr() == TypePtr::AnyNull ) return Type::TOP;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    52
    if( tp->ptr() == TypePtr::Constant) return TypeInt::ONE;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    53
    if (tp->ptr() == TypePtr::NotNull)  return TypeInt::ONE;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    54
    return TypeInt::BOOL;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    55
  }
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    56
  if (t->base() != Type::Int) return TypeInt::BOOL;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    57
  const TypeInt *ti = t->is_int();
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    58
  if( ti->_hi < 0 || ti->_lo > 0 ) return TypeInt::ONE;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    59
  return TypeInt::BOOL;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    60
}
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    61
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    62
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    63
// The conversions operations are all Alpha sorted.  Please keep it that way!
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    64
//=============================================================================
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    65
//------------------------------Value------------------------------------------
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    66
const Type *ConvD2FNode::Value( PhaseTransform *phase ) const {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    67
  const Type *t = phase->type( in(1) );
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    68
  if( t == Type::TOP ) return Type::TOP;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    69
  if( t == Type::DOUBLE ) return Type::FLOAT;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    70
  const TypeD *td = t->is_double_constant();
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    71
  return TypeF::make( (float)td->getd() );
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    72
}
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    73
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    74
//------------------------------Identity---------------------------------------
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    75
// Float's can be converted to doubles with no loss of bits.  Hence
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    76
// converting a float to a double and back to a float is a NOP.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    77
Node *ConvD2FNode::Identity(PhaseTransform *phase) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    78
  return (in(1)->Opcode() == Op_ConvF2D) ? in(1)->in(1) : this;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    79
}
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    80
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    81
//=============================================================================
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    82
//------------------------------Value------------------------------------------
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    83
const Type *ConvD2INode::Value( PhaseTransform *phase ) const {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    84
  const Type *t = phase->type( in(1) );
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    85
  if( t == Type::TOP ) return Type::TOP;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    86
  if( t == Type::DOUBLE ) return TypeInt::INT;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    87
  const TypeD *td = t->is_double_constant();
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    88
  return TypeInt::make( SharedRuntime::d2i( td->getd() ) );
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    89
}
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    90
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    91
//------------------------------Ideal------------------------------------------
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    92
// If converting to an int type, skip any rounding nodes
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    93
Node *ConvD2INode::Ideal(PhaseGVN *phase, bool can_reshape) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    94
  if( in(1)->Opcode() == Op_RoundDouble )
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    95
  set_req(1,in(1)->in(1));
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    96
  return NULL;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    97
}
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    98
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
    99
//------------------------------Identity---------------------------------------
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   100
// Int's can be converted to doubles with no loss of bits.  Hence
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   101
// converting an integer to a double and back to an integer is a NOP.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   102
Node *ConvD2INode::Identity(PhaseTransform *phase) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   103
  return (in(1)->Opcode() == Op_ConvI2D) ? in(1)->in(1) : this;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   104
}
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   105
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   106
//=============================================================================
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   107
//------------------------------Value------------------------------------------
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   108
const Type *ConvD2LNode::Value( PhaseTransform *phase ) const {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   109
  const Type *t = phase->type( in(1) );
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   110
  if( t == Type::TOP ) return Type::TOP;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   111
  if( t == Type::DOUBLE ) return TypeLong::LONG;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   112
  const TypeD *td = t->is_double_constant();
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   113
  return TypeLong::make( SharedRuntime::d2l( td->getd() ) );
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   114
}
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   115
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   116
//------------------------------Identity---------------------------------------
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   117
Node *ConvD2LNode::Identity(PhaseTransform *phase) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   118
  // Remove ConvD2L->ConvL2D->ConvD2L sequences.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   119
  if( in(1)       ->Opcode() == Op_ConvL2D &&
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   120
     in(1)->in(1)->Opcode() == Op_ConvD2L )
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   121
  return in(1)->in(1);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   122
  return this;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   123
}
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   124
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   125
//------------------------------Ideal------------------------------------------
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   126
// If converting to an int type, skip any rounding nodes
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   127
Node *ConvD2LNode::Ideal(PhaseGVN *phase, bool can_reshape) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   128
  if( in(1)->Opcode() == Op_RoundDouble )
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   129
  set_req(1,in(1)->in(1));
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   130
  return NULL;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   131
}
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   132
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   133
//=============================================================================
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   134
//------------------------------Value------------------------------------------
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   135
const Type *ConvF2DNode::Value( PhaseTransform *phase ) const {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   136
  const Type *t = phase->type( in(1) );
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   137
  if( t == Type::TOP ) return Type::TOP;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   138
  if( t == Type::FLOAT ) return Type::DOUBLE;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   139
  const TypeF *tf = t->is_float_constant();
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   140
  return TypeD::make( (double)tf->getf() );
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   141
}
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   142
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   143
//=============================================================================
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   144
//------------------------------Value------------------------------------------
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   145
const Type *ConvF2INode::Value( PhaseTransform *phase ) const {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   146
  const Type *t = phase->type( in(1) );
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   147
  if( t == Type::TOP )       return Type::TOP;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   148
  if( t == Type::FLOAT ) return TypeInt::INT;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   149
  const TypeF *tf = t->is_float_constant();
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   150
  return TypeInt::make( SharedRuntime::f2i( tf->getf() ) );
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   151
}
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   152
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   153
//------------------------------Identity---------------------------------------
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   154
Node *ConvF2INode::Identity(PhaseTransform *phase) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   155
  // Remove ConvF2I->ConvI2F->ConvF2I sequences.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   156
  if( in(1)       ->Opcode() == Op_ConvI2F &&
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   157
     in(1)->in(1)->Opcode() == Op_ConvF2I )
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   158
  return in(1)->in(1);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   159
  return this;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   160
}
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   161
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   162
//------------------------------Ideal------------------------------------------
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   163
// If converting to an int type, skip any rounding nodes
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   164
Node *ConvF2INode::Ideal(PhaseGVN *phase, bool can_reshape) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   165
  if( in(1)->Opcode() == Op_RoundFloat )
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   166
  set_req(1,in(1)->in(1));
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   167
  return NULL;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   168
}
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   169
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   170
//=============================================================================
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   171
//------------------------------Value------------------------------------------
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   172
const Type *ConvF2LNode::Value( PhaseTransform *phase ) const {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   173
  const Type *t = phase->type( in(1) );
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   174
  if( t == Type::TOP )       return Type::TOP;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   175
  if( t == Type::FLOAT ) return TypeLong::LONG;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   176
  const TypeF *tf = t->is_float_constant();
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   177
  return TypeLong::make( SharedRuntime::f2l( tf->getf() ) );
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   178
}
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   179
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   180
//------------------------------Identity---------------------------------------
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   181
Node *ConvF2LNode::Identity(PhaseTransform *phase) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   182
  // Remove ConvF2L->ConvL2F->ConvF2L sequences.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   183
  if( in(1)       ->Opcode() == Op_ConvL2F &&
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   184
     in(1)->in(1)->Opcode() == Op_ConvF2L )
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   185
  return in(1)->in(1);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   186
  return this;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   187
}
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   188
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   189
//------------------------------Ideal------------------------------------------
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   190
// If converting to an int type, skip any rounding nodes
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   191
Node *ConvF2LNode::Ideal(PhaseGVN *phase, bool can_reshape) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   192
  if( in(1)->Opcode() == Op_RoundFloat )
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   193
  set_req(1,in(1)->in(1));
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   194
  return NULL;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   195
}
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   196
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   197
//=============================================================================
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   198
//------------------------------Value------------------------------------------
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   199
const Type *ConvI2DNode::Value( PhaseTransform *phase ) const {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   200
  const Type *t = phase->type( in(1) );
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   201
  if( t == Type::TOP ) return Type::TOP;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   202
  const TypeInt *ti = t->is_int();
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   203
  if( ti->is_con() ) return TypeD::make( (double)ti->get_con() );
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   204
  return bottom_type();
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   205
}
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   206
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   207
//=============================================================================
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   208
//------------------------------Value------------------------------------------
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   209
const Type *ConvI2FNode::Value( PhaseTransform *phase ) const {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   210
  const Type *t = phase->type( in(1) );
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   211
  if( t == Type::TOP ) return Type::TOP;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   212
  const TypeInt *ti = t->is_int();
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   213
  if( ti->is_con() ) return TypeF::make( (float)ti->get_con() );
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   214
  return bottom_type();
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   215
}
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   216
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   217
//------------------------------Identity---------------------------------------
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   218
Node *ConvI2FNode::Identity(PhaseTransform *phase) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   219
  // Remove ConvI2F->ConvF2I->ConvI2F sequences.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   220
  if( in(1)       ->Opcode() == Op_ConvF2I &&
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   221
     in(1)->in(1)->Opcode() == Op_ConvI2F )
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   222
  return in(1)->in(1);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   223
  return this;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   224
}
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   225
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   226
//=============================================================================
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   227
//------------------------------Value------------------------------------------
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   228
const Type *ConvI2LNode::Value( PhaseTransform *phase ) const {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   229
  const Type *t = phase->type( in(1) );
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   230
  if( t == Type::TOP ) return Type::TOP;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   231
  const TypeInt *ti = t->is_int();
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   232
  const Type* tl = TypeLong::make(ti->_lo, ti->_hi, ti->_widen);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   233
  // Join my declared type against my incoming type.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   234
  tl = tl->filter(_type);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   235
  return tl;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   236
}
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   237
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   238
#ifdef _LP64
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   239
static inline bool long_ranges_overlap(jlong lo1, jlong hi1,
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   240
                                       jlong lo2, jlong hi2) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   241
  // Two ranges overlap iff one range's low point falls in the other range.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   242
  return (lo2 <= lo1 && lo1 <= hi2) || (lo1 <= lo2 && lo2 <= hi1);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   243
}
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   244
#endif
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   245
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   246
//------------------------------Ideal------------------------------------------
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   247
Node *ConvI2LNode::Ideal(PhaseGVN *phase, bool can_reshape) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   248
  const TypeLong* this_type = this->type()->is_long();
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   249
  Node* this_changed = NULL;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   250
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   251
  // If _major_progress, then more loop optimizations follow.  Do NOT
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   252
  // remove this node's type assertion until no more loop ops can happen.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   253
  // The progress bit is set in the major loop optimizations THEN comes the
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   254
  // call to IterGVN and any chance of hitting this code.  Cf. Opaque1Node.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   255
  if (can_reshape && !phase->C->major_progress()) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   256
    const TypeInt* in_type = phase->type(in(1))->isa_int();
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   257
    if (in_type != NULL && this_type != NULL &&
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   258
        (in_type->_lo != this_type->_lo ||
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   259
         in_type->_hi != this_type->_hi)) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   260
          // Although this WORSENS the type, it increases GVN opportunities,
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   261
          // because I2L nodes with the same input will common up, regardless
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   262
          // of slightly differing type assertions.  Such slight differences
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   263
          // arise routinely as a result of loop unrolling, so this is a
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   264
          // post-unrolling graph cleanup.  Choose a type which depends only
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   265
          // on my input.  (Exception:  Keep a range assertion of >=0 or <0.)
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   266
          jlong lo1 = this_type->_lo;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   267
          jlong hi1 = this_type->_hi;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   268
          int   w1  = this_type->_widen;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   269
          if (lo1 != (jint)lo1 ||
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   270
              hi1 != (jint)hi1 ||
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   271
              lo1 > hi1) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   272
            // Overflow leads to wraparound, wraparound leads to range saturation.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   273
            lo1 = min_jint; hi1 = max_jint;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   274
          } else if (lo1 >= 0) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   275
            // Keep a range assertion of >=0.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   276
            lo1 = 0;        hi1 = max_jint;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   277
          } else if (hi1 < 0) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   278
            // Keep a range assertion of <0.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   279
            lo1 = min_jint; hi1 = -1;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   280
          } else {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   281
            lo1 = min_jint; hi1 = max_jint;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   282
          }
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   283
          const TypeLong* wtype = TypeLong::make(MAX2((jlong)in_type->_lo, lo1),
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   284
                                                 MIN2((jlong)in_type->_hi, hi1),
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   285
                                                 MAX2((int)in_type->_widen, w1));
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   286
          if (wtype != type()) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   287
            set_type(wtype);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   288
            // Note: this_type still has old type value, for the logic below.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   289
            this_changed = this;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   290
          }
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   291
        }
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   292
  }
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   293
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   294
#ifdef _LP64
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   295
  // Convert ConvI2L(AddI(x, y)) to AddL(ConvI2L(x), ConvI2L(y)) ,
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   296
  // but only if x and y have subranges that cannot cause 32-bit overflow,
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   297
  // under the assumption that x+y is in my own subrange this->type().
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   298
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   299
  // This assumption is based on a constraint (i.e., type assertion)
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   300
  // established in Parse::array_addressing or perhaps elsewhere.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   301
  // This constraint has been adjoined to the "natural" type of
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   302
  // the incoming argument in(0).  We know (because of runtime
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   303
  // checks) - that the result value I2L(x+y) is in the joined range.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   304
  // Hence we can restrict the incoming terms (x, y) to values such
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   305
  // that their sum also lands in that range.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   306
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   307
  // This optimization is useful only on 64-bit systems, where we hope
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   308
  // the addition will end up subsumed in an addressing mode.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   309
  // It is necessary to do this when optimizing an unrolled array
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   310
  // copy loop such as x[i++] = y[i++].
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   311
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   312
  // On 32-bit systems, it's better to perform as much 32-bit math as
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   313
  // possible before the I2L conversion, because 32-bit math is cheaper.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   314
  // There's no common reason to "leak" a constant offset through the I2L.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   315
  // Addressing arithmetic will not absorb it as part of a 64-bit AddL.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   316
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   317
  Node* z = in(1);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   318
  int op = z->Opcode();
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   319
  if (op == Op_AddI || op == Op_SubI) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   320
    Node* x = z->in(1);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   321
    Node* y = z->in(2);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   322
    assert (x != z && y != z, "dead loop in ConvI2LNode::Ideal");
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   323
    if (phase->type(x) == Type::TOP)  return this_changed;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   324
    if (phase->type(y) == Type::TOP)  return this_changed;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   325
    const TypeInt*  tx = phase->type(x)->is_int();
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   326
    const TypeInt*  ty = phase->type(y)->is_int();
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   327
    const TypeLong* tz = this_type;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   328
    jlong xlo = tx->_lo;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   329
    jlong xhi = tx->_hi;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   330
    jlong ylo = ty->_lo;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   331
    jlong yhi = ty->_hi;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   332
    jlong zlo = tz->_lo;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   333
    jlong zhi = tz->_hi;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   334
    jlong vbit = CONST64(1) << BitsPerInt;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   335
    int widen =  MAX2(tx->_widen, ty->_widen);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   336
    if (op == Op_SubI) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   337
      jlong ylo0 = ylo;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   338
      ylo = -yhi;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   339
      yhi = -ylo0;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   340
    }
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   341
    // See if x+y can cause positive overflow into z+2**32
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   342
    if (long_ranges_overlap(xlo+ylo, xhi+yhi, zlo+vbit, zhi+vbit)) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   343
      return this_changed;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   344
    }
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   345
    // See if x+y can cause negative overflow into z-2**32
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   346
    if (long_ranges_overlap(xlo+ylo, xhi+yhi, zlo-vbit, zhi-vbit)) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   347
      return this_changed;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   348
    }
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   349
    // Now it's always safe to assume x+y does not overflow.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   350
    // This is true even if some pairs x,y might cause overflow, as long
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   351
    // as that overflow value cannot fall into [zlo,zhi].
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   352
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   353
    // Confident that the arithmetic is "as if infinite precision",
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   354
    // we can now use z's range to put constraints on those of x and y.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   355
    // The "natural" range of x [xlo,xhi] can perhaps be narrowed to a
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   356
    // more "restricted" range by intersecting [xlo,xhi] with the
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   357
    // range obtained by subtracting y's range from the asserted range
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   358
    // of the I2L conversion.  Here's the interval arithmetic algebra:
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   359
    //    x == z-y == [zlo,zhi]-[ylo,yhi] == [zlo,zhi]+[-yhi,-ylo]
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   360
    //    => x in [zlo-yhi, zhi-ylo]
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   361
    //    => x in [zlo-yhi, zhi-ylo] INTERSECT [xlo,xhi]
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   362
    //    => x in [xlo MAX zlo-yhi, xhi MIN zhi-ylo]
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   363
    jlong rxlo = MAX2(xlo, zlo - yhi);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   364
    jlong rxhi = MIN2(xhi, zhi - ylo);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   365
    // And similarly, x changing place with y:
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   366
    jlong rylo = MAX2(ylo, zlo - xhi);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   367
    jlong ryhi = MIN2(yhi, zhi - xlo);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   368
    if (rxlo > rxhi || rylo > ryhi) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   369
      return this_changed;  // x or y is dying; don't mess w/ it
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   370
    }
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   371
    if (op == Op_SubI) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   372
      jlong rylo0 = rylo;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   373
      rylo = -ryhi;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   374
      ryhi = -rylo0;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   375
    }
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   376
24923
9631f7d691dc 8034812: remove IDX_INIT macro hack in Node class
thartmann
parents: 23528
diff changeset
   377
    Node* cx = phase->transform( new ConvI2LNode(x, TypeLong::make(rxlo, rxhi, widen)) );
9631f7d691dc 8034812: remove IDX_INIT macro hack in Node class
thartmann
parents: 23528
diff changeset
   378
    Node* cy = phase->transform( new ConvI2LNode(y, TypeLong::make(rylo, ryhi, widen)) );
23528
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   379
    switch (op) {
24923
9631f7d691dc 8034812: remove IDX_INIT macro hack in Node class
thartmann
parents: 23528
diff changeset
   380
      case Op_AddI:  return new AddLNode(cx, cy);
9631f7d691dc 8034812: remove IDX_INIT macro hack in Node class
thartmann
parents: 23528
diff changeset
   381
      case Op_SubI:  return new SubLNode(cx, cy);
23528
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   382
      default:       ShouldNotReachHere();
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   383
    }
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   384
  }
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   385
#endif //_LP64
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   386
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   387
  return this_changed;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   388
}
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   389
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   390
//=============================================================================
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   391
//------------------------------Value------------------------------------------
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   392
const Type *ConvL2DNode::Value( PhaseTransform *phase ) const {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   393
  const Type *t = phase->type( in(1) );
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   394
  if( t == Type::TOP ) return Type::TOP;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   395
  const TypeLong *tl = t->is_long();
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   396
  if( tl->is_con() ) return TypeD::make( (double)tl->get_con() );
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   397
  return bottom_type();
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   398
}
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   399
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   400
//=============================================================================
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   401
//------------------------------Value------------------------------------------
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   402
const Type *ConvL2FNode::Value( PhaseTransform *phase ) const {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   403
  const Type *t = phase->type( in(1) );
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   404
  if( t == Type::TOP ) return Type::TOP;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   405
  const TypeLong *tl = t->is_long();
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   406
  if( tl->is_con() ) return TypeF::make( (float)tl->get_con() );
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   407
  return bottom_type();
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   408
}
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   409
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   410
//=============================================================================
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   411
//----------------------------Identity-----------------------------------------
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   412
Node *ConvL2INode::Identity( PhaseTransform *phase ) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   413
  // Convert L2I(I2L(x)) => x
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   414
  if (in(1)->Opcode() == Op_ConvI2L)  return in(1)->in(1);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   415
  return this;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   416
}
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   417
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   418
//------------------------------Value------------------------------------------
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   419
const Type *ConvL2INode::Value( PhaseTransform *phase ) const {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   420
  const Type *t = phase->type( in(1) );
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   421
  if( t == Type::TOP ) return Type::TOP;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   422
  const TypeLong *tl = t->is_long();
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   423
  if (tl->is_con())
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   424
  // Easy case.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   425
  return TypeInt::make((jint)tl->get_con());
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   426
  return bottom_type();
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   427
}
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   428
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   429
//------------------------------Ideal------------------------------------------
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   430
// Return a node which is more "ideal" than the current node.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   431
// Blow off prior masking to int
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   432
Node *ConvL2INode::Ideal(PhaseGVN *phase, bool can_reshape) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   433
  Node *andl = in(1);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   434
  uint andl_op = andl->Opcode();
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   435
  if( andl_op == Op_AndL ) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   436
    // Blow off prior masking to int
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   437
    if( phase->type(andl->in(2)) == TypeLong::make( 0xFFFFFFFF ) ) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   438
      set_req(1,andl->in(1));
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   439
      return this;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   440
    }
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   441
  }
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   442
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   443
  // Swap with a prior add: convL2I(addL(x,y)) ==> addI(convL2I(x),convL2I(y))
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   444
  // This replaces an 'AddL' with an 'AddI'.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   445
  if( andl_op == Op_AddL ) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   446
    // Don't do this for nodes which have more than one user since
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   447
    // we'll end up computing the long add anyway.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   448
    if (andl->outcnt() > 1) return NULL;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   449
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   450
    Node* x = andl->in(1);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   451
    Node* y = andl->in(2);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   452
    assert( x != andl && y != andl, "dead loop in ConvL2INode::Ideal" );
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   453
    if (phase->type(x) == Type::TOP)  return NULL;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   454
    if (phase->type(y) == Type::TOP)  return NULL;
24923
9631f7d691dc 8034812: remove IDX_INIT macro hack in Node class
thartmann
parents: 23528
diff changeset
   455
    Node *add1 = phase->transform(new ConvL2INode(x));
9631f7d691dc 8034812: remove IDX_INIT macro hack in Node class
thartmann
parents: 23528
diff changeset
   456
    Node *add2 = phase->transform(new ConvL2INode(y));
9631f7d691dc 8034812: remove IDX_INIT macro hack in Node class
thartmann
parents: 23528
diff changeset
   457
    return new AddINode(add1,add2);
23528
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   458
  }
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   459
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   460
  // Disable optimization: LoadL->ConvL2I ==> LoadI.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   461
  // It causes problems (sizes of Load and Store nodes do not match)
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   462
  // in objects initialization code and Escape Analysis.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   463
  return NULL;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   464
}
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   465
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   466
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   467
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   468
//=============================================================================
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   469
//------------------------------Identity---------------------------------------
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   470
// Remove redundant roundings
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   471
Node *RoundFloatNode::Identity( PhaseTransform *phase ) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   472
  assert(Matcher::strict_fp_requires_explicit_rounding, "should only generate for Intel");
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   473
  // Do not round constants
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   474
  if (phase->type(in(1))->base() == Type::FloatCon)  return in(1);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   475
  int op = in(1)->Opcode();
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   476
  // Redundant rounding
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   477
  if( op == Op_RoundFloat ) return in(1);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   478
  // Already rounded
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   479
  if( op == Op_Parm ) return in(1);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   480
  if( op == Op_LoadF ) return in(1);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   481
  return this;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   482
}
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   483
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   484
//------------------------------Value------------------------------------------
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   485
const Type *RoundFloatNode::Value( PhaseTransform *phase ) const {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   486
  return phase->type( in(1) );
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   487
}
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   488
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   489
//=============================================================================
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   490
//------------------------------Identity---------------------------------------
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   491
// Remove redundant roundings.  Incoming arguments are already rounded.
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   492
Node *RoundDoubleNode::Identity( PhaseTransform *phase ) {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   493
  assert(Matcher::strict_fp_requires_explicit_rounding, "should only generate for Intel");
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   494
  // Do not round constants
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   495
  if (phase->type(in(1))->base() == Type::DoubleCon)  return in(1);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   496
  int op = in(1)->Opcode();
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   497
  // Redundant rounding
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   498
  if( op == Op_RoundDouble ) return in(1);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   499
  // Already rounded
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   500
  if( op == Op_Parm ) return in(1);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   501
  if( op == Op_LoadD ) return in(1);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   502
  if( op == Op_ConvF2D ) return in(1);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   503
  if( op == Op_ConvI2D ) return in(1);
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   504
  return this;
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   505
}
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   506
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   507
//------------------------------Value------------------------------------------
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   508
const Type *RoundDoubleNode::Value( PhaseTransform *phase ) const {
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   509
  return phase->type( in(1) );
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   510
}
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   511
8f1a7f5e8066 8001532: C2 node files refactoring
morris
parents:
diff changeset
   512