hotspot/src/share/vm/opto/subnode.cpp
author coleenp
Mon, 14 Jan 2013 11:01:39 -0500
changeset 15194 a35093d73168
parent 13969 d2a189b83b87
child 16670 4af09aff4237
permissions -rw-r--r--
8006005: Fix constant pool index validation and alignment trap for method parameter reflection Summary: This patch addresses an alignment trap due to the storage format of method parameters data in constMethod. It also adds code to validate constant pool indexes for method parameters data. Reviewed-by: jrose, dholmes Contributed-by: eric.mccorkle@oracle.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13205
diff changeset
     2
 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 4645
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 4645
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 4645
diff changeset
    21
 * questions.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    25
#include "precompiled.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    26
#include "compiler/compileLog.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    27
#include "memory/allocation.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    28
#include "opto/addnode.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    29
#include "opto/callnode.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    30
#include "opto/cfgnode.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    31
#include "opto/connode.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    32
#include "opto/loopnode.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    33
#include "opto/matcher.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    34
#include "opto/mulnode.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    35
#include "opto/opcodes.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    36
#include "opto/phaseX.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    37
#include "opto/subnode.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    38
#include "runtime/sharedRuntime.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    39
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
// Portions of code courtesy of Clifford Click
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
// Optimization - Graph Style
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
#include "math.h"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
//=============================================================================
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
//------------------------------Identity---------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
// If right input is a constant 0, return the left input.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
Node *SubNode::Identity( PhaseTransform *phase ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
  assert(in(1) != this, "Must already have called Value");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
  assert(in(2) != this, "Must already have called Value");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
  // Remove double negation
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
  const Type *zero = add_id();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
  if( phase->type( in(1) )->higher_equal( zero ) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
      in(2)->Opcode() == Opcode() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
      phase->type( in(2)->in(1) )->higher_equal( zero ) ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
    return in(2)->in(2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
758
38c168fb8c79 6697236: missing Identity for "(X+Y) - X" into Y
never
parents: 360
diff changeset
    61
  // Convert "(X+Y) - Y" into X and "(X+Y) - X" into Y
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
  if( in(1)->Opcode() == Op_AddI ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
    if( phase->eqv(in(1)->in(2),in(2)) )
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
      return in(1)->in(1);
758
38c168fb8c79 6697236: missing Identity for "(X+Y) - X" into Y
never
parents: 360
diff changeset
    65
    if (phase->eqv(in(1)->in(1),in(2)))
38c168fb8c79 6697236: missing Identity for "(X+Y) - X" into Y
never
parents: 360
diff changeset
    66
      return in(1)->in(2);
38c168fb8c79 6697236: missing Identity for "(X+Y) - X" into Y
never
parents: 360
diff changeset
    67
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
    // Also catch: "(X + Opaque2(Y)) - Y".  In this case, 'Y' is a loop-varying
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
    // trip counter and X is likely to be loop-invariant (that's how O2 Nodes
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
    // are originally used, although the optimizer sometimes jiggers things).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
    // This folding through an O2 removes a loop-exit use of a loop-varying
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
    // value and generally lowers register pressure in and around the loop.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
    if( in(1)->in(2)->Opcode() == Op_Opaque2 &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
        phase->eqv(in(1)->in(2)->in(1),in(2)) )
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
      return in(1)->in(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
  return ( phase->type( in(2) )->higher_equal( zero ) ) ? in(1) : this;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
//------------------------------Value------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
// A subtract node differences it's two inputs.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
const Type *SubNode::Value( PhaseTransform *phase ) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
  const Node* in1 = in(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
  const Node* in2 = in(2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
  // Either input is TOP ==> the result is TOP
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
  const Type* t1 = (in1 == this) ? Type::TOP : phase->type(in1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
  if( t1 == Type::TOP ) return Type::TOP;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
  const Type* t2 = (in2 == this) ? Type::TOP : phase->type(in2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
  if( t2 == Type::TOP ) return Type::TOP;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
  // Not correct for SubFnode and AddFNode (must check for infinity)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
  // Equal?  Subtract is zero
11446
fd87432a895b 7128352: assert(obj_node == obj) failed
kvn
parents: 9966
diff changeset
    94
  if (in1->eqv_uncast(in2))  return add_id();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
  // Either input is BOTTOM ==> the result is the local BOTTOM
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
  if( t1 == Type::BOTTOM || t2 == Type::BOTTOM )
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
    return bottom_type();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
  return sub(t1,t2);            // Local flavor of type subtraction
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
//=============================================================================
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
//------------------------------Helper function--------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
static bool ok_to_convert(Node* inc, Node* iv) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
    // Do not collapse (x+c0)-y if "+" is a loop increment, because the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
    // "-" is loop invariant and collapsing extends the live-range of "x"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
    // to overlap with the "+", forcing another register to be used in
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
    // the loop.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
    // This test will be clearer with '&&' (apply DeMorgan's rule)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
    // but I like the early cutouts that happen here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
    const PhiNode *phi;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
    if( ( !inc->in(1)->is_Phi() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
          !(phi=inc->in(1)->as_Phi()) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
          phi->is_copy() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
          !phi->region()->is_CountedLoop() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
          inc != phi->region()->as_CountedLoop()->incr() )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
       &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
        // Do not collapse (x+c0)-iv if "iv" is a loop induction variable,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
        // because "x" maybe invariant.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
        ( !iv->is_loop_iv() )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
      ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
      return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
//------------------------------Ideal------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
Node *SubINode::Ideal(PhaseGVN *phase, bool can_reshape){
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
  Node *in1 = in(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
  Node *in2 = in(2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
  uint op1 = in1->Opcode();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
  uint op2 = in2->Opcode();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
  // Check for dead loop
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
  if( phase->eqv( in1, this ) || phase->eqv( in2, this ) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
      ( op1 == Op_AddI || op1 == Op_SubI ) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
      ( phase->eqv( in1->in(1), this ) || phase->eqv( in1->in(2), this ) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
        phase->eqv( in1->in(1), in1  ) || phase->eqv( in1->in(2), in1 ) ) )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
    assert(false, "dead loop in SubINode::Ideal");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
  const Type *t2 = phase->type( in2 );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
  if( t2 == Type::TOP ) return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
  // Convert "x-c0" into "x+ -c0".
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
  if( t2->base() == Type::Int ){        // Might be bottom or top...
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
    const TypeInt *i = t2->is_int();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
    if( i->is_con() )
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   152
      return new (phase->C) AddINode(in1, phase->intcon(-i->get_con()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
  // Convert "(x+c0) - y" into (x-y) + c0"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
  // Do not collapse (x+c0)-y if "+" is a loop increment or
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
  // if "y" is a loop induction variable.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
  if( op1 == Op_AddI && ok_to_convert(in1, in2) ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
    const Type *tadd = phase->type( in1->in(2) );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
    if( tadd->singleton() && tadd != Type::TOP ) {
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   161
      Node *sub2 = phase->transform( new (phase->C) SubINode( in1->in(1), in2 ));
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   162
      return new (phase->C) AddINode( sub2, in1->in(2) );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
  // Convert "x - (y+c0)" into "(x-y) - c0"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
  // Need the same check as in above optimization but reversed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
  if (op2 == Op_AddI && ok_to_convert(in2, in1)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
    Node* in21 = in2->in(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
    Node* in22 = in2->in(2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
    const TypeInt* tcon = phase->type(in22)->isa_int();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
    if (tcon != NULL && tcon->is_con()) {
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   174
      Node* sub2 = phase->transform( new (phase->C) SubINode(in1, in21) );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
      Node* neg_c0 = phase->intcon(- tcon->get_con());
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   176
      return new (phase->C) AddINode(sub2, neg_c0);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
  const Type *t1 = phase->type( in1 );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
  if( t1 == Type::TOP ) return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
  // Check for dead loop
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
  if( ( op2 == Op_AddI || op2 == Op_SubI ) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
      ( phase->eqv( in2->in(1), this ) || phase->eqv( in2->in(2), this ) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
        phase->eqv( in2->in(1), in2  ) || phase->eqv( in2->in(2), in2  ) ) )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
    assert(false, "dead loop in SubINode::Ideal");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
  // Convert "x - (x+y)" into "-y"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
  if( op2 == Op_AddI &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
      phase->eqv( in1, in2->in(1) ) )
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   194
    return new (phase->C) SubINode( phase->intcon(0),in2->in(2));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
  // Convert "(x-y) - x" into "-y"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
  if( op1 == Op_SubI &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
      phase->eqv( in1->in(1), in2 ) )
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   198
    return new (phase->C) SubINode( phase->intcon(0),in1->in(2));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
  // Convert "x - (y+x)" into "-y"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
  if( op2 == Op_AddI &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
      phase->eqv( in1, in2->in(2) ) )
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   202
    return new (phase->C) SubINode( phase->intcon(0),in2->in(1));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
  // Convert "0 - (x-y)" into "y-x"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
  if( t1 == TypeInt::ZERO && op2 == Op_SubI )
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   206
    return new (phase->C) SubINode( in2->in(2), in2->in(1) );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
  // Convert "0 - (x+con)" into "-con-x"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
  jint con;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
  if( t1 == TypeInt::ZERO && op2 == Op_AddI &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
      (con = in2->in(2)->find_int_con(0)) != 0 )
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   212
    return new (phase->C) SubINode( phase->intcon(-con), in2->in(1) );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
  // Convert "(X+A) - (X+B)" into "A - B"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
  if( op1 == Op_AddI && op2 == Op_AddI && in1->in(1) == in2->in(1) )
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   216
    return new (phase->C) SubINode( in1->in(2), in2->in(2) );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
  // Convert "(A+X) - (B+X)" into "A - B"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
  if( op1 == Op_AddI && op2 == Op_AddI && in1->in(2) == in2->in(2) )
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   220
    return new (phase->C) SubINode( in1->in(1), in2->in(1) );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
1432
44f076e3d2a4 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 1058
diff changeset
   222
  // Convert "(A+X) - (X+B)" into "A - B"
44f076e3d2a4 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 1058
diff changeset
   223
  if( op1 == Op_AddI && op2 == Op_AddI && in1->in(2) == in2->in(1) )
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   224
    return new (phase->C) SubINode( in1->in(1), in2->in(2) );
1432
44f076e3d2a4 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 1058
diff changeset
   225
44f076e3d2a4 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 1058
diff changeset
   226
  // Convert "(X+A) - (B+X)" into "A - B"
44f076e3d2a4 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 1058
diff changeset
   227
  if( op1 == Op_AddI && op2 == Op_AddI && in1->in(1) == in2->in(2) )
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   228
    return new (phase->C) SubINode( in1->in(2), in2->in(1) );
1432
44f076e3d2a4 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 1058
diff changeset
   229
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
  // Convert "A-(B-C)" into (A+C)-B", since add is commutative and generally
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
  // nicer to optimize than subtract.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
  if( op2 == Op_SubI && in2->outcnt() == 1) {
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   233
    Node *add1 = phase->transform( new (phase->C) AddINode( in1, in2->in(2) ) );
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   234
    return new (phase->C) SubINode( add1, in2->in(1) );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
//------------------------------sub--------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
// A subtract node differences it's two inputs.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
const Type *SubINode::sub( const Type *t1, const Type *t2 ) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
  const TypeInt *r0 = t1->is_int(); // Handy access
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
  const TypeInt *r1 = t2->is_int();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
  int32 lo = r0->_lo - r1->_hi;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
  int32 hi = r0->_hi - r1->_lo;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
  // We next check for 32-bit overflow.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
  // If that happens, we just assume all integers are possible.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
  if( (((r0->_lo ^ r1->_hi) >= 0) ||    // lo ends have same signs OR
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
       ((r0->_lo ^      lo) >= 0)) &&   // lo results have same signs AND
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
      (((r0->_hi ^ r1->_lo) >= 0) ||    // hi ends have same signs OR
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
       ((r0->_hi ^      hi) >= 0)) )    // hi results have same signs
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
    return TypeInt::make(lo,hi,MAX2(r0->_widen,r1->_widen));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
  else                          // Overflow; assume all integers
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
    return TypeInt::INT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
//=============================================================================
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
//------------------------------Ideal------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
Node *SubLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
  Node *in1 = in(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
  Node *in2 = in(2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
  uint op1 = in1->Opcode();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
  uint op2 = in2->Opcode();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
  // Check for dead loop
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
  if( phase->eqv( in1, this ) || phase->eqv( in2, this ) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
      ( op1 == Op_AddL || op1 == Op_SubL ) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
      ( phase->eqv( in1->in(1), this ) || phase->eqv( in1->in(2), this ) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
        phase->eqv( in1->in(1), in1  ) || phase->eqv( in1->in(2), in1  ) ) )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
    assert(false, "dead loop in SubLNode::Ideal");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
  if( phase->type( in2 ) == Type::TOP ) return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
  const TypeLong *i = phase->type( in2 )->isa_long();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
  // Convert "x-c0" into "x+ -c0".
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
  if( i &&                      // Might be bottom or top...
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
      i->is_con() )
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   281
    return new (phase->C) AddLNode(in1, phase->longcon(-i->get_con()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
  // Convert "(x+c0) - y" into (x-y) + c0"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
  // Do not collapse (x+c0)-y if "+" is a loop increment or
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
  // if "y" is a loop induction variable.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
  if( op1 == Op_AddL && ok_to_convert(in1, in2) ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
    Node *in11 = in1->in(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
    const Type *tadd = phase->type( in1->in(2) );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
    if( tadd->singleton() && tadd != Type::TOP ) {
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   290
      Node *sub2 = phase->transform( new (phase->C) SubLNode( in11, in2 ));
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   291
      return new (phase->C) AddLNode( sub2, in1->in(2) );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
  // Convert "x - (y+c0)" into "(x-y) - c0"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
  // Need the same check as in above optimization but reversed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
  if (op2 == Op_AddL && ok_to_convert(in2, in1)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
    Node* in21 = in2->in(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
    Node* in22 = in2->in(2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
    const TypeLong* tcon = phase->type(in22)->isa_long();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
    if (tcon != NULL && tcon->is_con()) {
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   302
      Node* sub2 = phase->transform( new (phase->C) SubLNode(in1, in21) );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
      Node* neg_c0 = phase->longcon(- tcon->get_con());
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   304
      return new (phase->C) AddLNode(sub2, neg_c0);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
  const Type *t1 = phase->type( in1 );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
  if( t1 == Type::TOP ) return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
  // Check for dead loop
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
  if( ( op2 == Op_AddL || op2 == Op_SubL ) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
      ( phase->eqv( in2->in(1), this ) || phase->eqv( in2->in(2), this ) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
        phase->eqv( in2->in(1), in2  ) || phase->eqv( in2->in(2), in2  ) ) )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
    assert(false, "dead loop in SubLNode::Ideal");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
  // Convert "x - (x+y)" into "-y"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
  if( op2 == Op_AddL &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
      phase->eqv( in1, in2->in(1) ) )
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   322
    return new (phase->C) SubLNode( phase->makecon(TypeLong::ZERO), in2->in(2));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
  // Convert "x - (y+x)" into "-y"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
  if( op2 == Op_AddL &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
      phase->eqv( in1, in2->in(2) ) )
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   326
    return new (phase->C) SubLNode( phase->makecon(TypeLong::ZERO),in2->in(1));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
  // Convert "0 - (x-y)" into "y-x"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
  if( phase->type( in1 ) == TypeLong::ZERO && op2 == Op_SubL )
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   330
    return new (phase->C) SubLNode( in2->in(2), in2->in(1) );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
  // Convert "(X+A) - (X+B)" into "A - B"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
  if( op1 == Op_AddL && op2 == Op_AddL && in1->in(1) == in2->in(1) )
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   334
    return new (phase->C) SubLNode( in1->in(2), in2->in(2) );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
  // Convert "(A+X) - (B+X)" into "A - B"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
  if( op1 == Op_AddL && op2 == Op_AddL && in1->in(2) == in2->in(2) )
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   338
    return new (phase->C) SubLNode( in1->in(1), in2->in(1) );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
  // Convert "A-(B-C)" into (A+C)-B"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
  if( op2 == Op_SubL && in2->outcnt() == 1) {
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   342
    Node *add1 = phase->transform( new (phase->C) AddLNode( in1, in2->in(2) ) );
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   343
    return new (phase->C) SubLNode( add1, in2->in(1) );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
//------------------------------sub--------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
// A subtract node differences it's two inputs.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
const Type *SubLNode::sub( const Type *t1, const Type *t2 ) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
  const TypeLong *r0 = t1->is_long(); // Handy access
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
  const TypeLong *r1 = t2->is_long();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
  jlong lo = r0->_lo - r1->_hi;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
  jlong hi = r0->_hi - r1->_lo;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
  // We next check for 32-bit overflow.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
  // If that happens, we just assume all integers are possible.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
  if( (((r0->_lo ^ r1->_hi) >= 0) ||    // lo ends have same signs OR
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
       ((r0->_lo ^      lo) >= 0)) &&   // lo results have same signs AND
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
      (((r0->_hi ^ r1->_lo) >= 0) ||    // hi ends have same signs OR
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
       ((r0->_hi ^      hi) >= 0)) )    // hi results have same signs
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
    return TypeLong::make(lo,hi,MAX2(r0->_widen,r1->_widen));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
  else                          // Overflow; assume all integers
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
    return TypeLong::LONG;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
//=============================================================================
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
//------------------------------Value------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
// A subtract node differences its two inputs.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
const Type *SubFPNode::Value( PhaseTransform *phase ) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
  const Node* in1 = in(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
  const Node* in2 = in(2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
  // Either input is TOP ==> the result is TOP
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
  const Type* t1 = (in1 == this) ? Type::TOP : phase->type(in1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
  if( t1 == Type::TOP ) return Type::TOP;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
  const Type* t2 = (in2 == this) ? Type::TOP : phase->type(in2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
  if( t2 == Type::TOP ) return Type::TOP;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
  // if both operands are infinity of same sign, the result is NaN; do
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
  // not replace with zero
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
  if( (t1->is_finite() && t2->is_finite()) ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
    if( phase->eqv(in1, in2) ) return add_id();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
  // Either input is BOTTOM ==> the result is the local BOTTOM
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
  const Type *bot = bottom_type();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
  if( (t1 == bot) || (t2 == bot) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
      (t1 == Type::BOTTOM) || (t2 == Type::BOTTOM) )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
    return bot;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
  return sub(t1,t2);            // Local flavor of type subtraction
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
//=============================================================================
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
//------------------------------Ideal------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
Node *SubFNode::Ideal(PhaseGVN *phase, bool can_reshape) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
  const Type *t2 = phase->type( in(2) );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
  // Convert "x-c0" into "x+ -c0".
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
  if( t2->base() == Type::FloatCon ) {  // Might be bottom or top...
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
    // return new (phase->C, 3) AddFNode(in(1), phase->makecon( TypeF::make(-t2->getf()) ) );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
  // Not associative because of boundary conditions (infinity)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
  if( IdealizedNumerics && !phase->C->method()->is_strict() ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
    // Convert "x - (x+y)" into "-y"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
    if( in(2)->is_Add() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
        phase->eqv(in(1),in(2)->in(1) ) )
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   410
      return new (phase->C) SubFNode( phase->makecon(TypeF::ZERO),in(2)->in(2));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
  // Cannot replace 0.0-X with -X because a 'fsub' bytecode computes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
  // 0.0-0.0 as +0.0, while a 'fneg' bytecode computes -0.0.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
  //if( phase->type(in(1)) == TypeF::ZERO )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
  //return new (phase->C, 2) NegFNode(in(2));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
//------------------------------sub--------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
// A subtract node differences its two inputs.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
const Type *SubFNode::sub( const Type *t1, const Type *t2 ) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
  // no folding if one of operands is infinity or NaN, do not do constant folding
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
  if( g_isfinite(t1->getf()) && g_isfinite(t2->getf()) ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
    return TypeF::make( t1->getf() - t2->getf() );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
  else if( g_isnan(t1->getf()) ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
    return t1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
  else if( g_isnan(t2->getf()) ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
    return t2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
  else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
    return Type::FLOAT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
//=============================================================================
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
//------------------------------Ideal------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
Node *SubDNode::Ideal(PhaseGVN *phase, bool can_reshape){
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
  const Type *t2 = phase->type( in(2) );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
  // Convert "x-c0" into "x+ -c0".
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
  if( t2->base() == Type::DoubleCon ) { // Might be bottom or top...
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
    // return new (phase->C, 3) AddDNode(in(1), phase->makecon( TypeD::make(-t2->getd()) ) );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
  // Not associative because of boundary conditions (infinity)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
  if( IdealizedNumerics && !phase->C->method()->is_strict() ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
    // Convert "x - (x+y)" into "-y"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
    if( in(2)->is_Add() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
        phase->eqv(in(1),in(2)->in(1) ) )
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   453
      return new (phase->C) SubDNode( phase->makecon(TypeD::ZERO),in(2)->in(2));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
  // Cannot replace 0.0-X with -X because a 'dsub' bytecode computes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
  // 0.0-0.0 as +0.0, while a 'dneg' bytecode computes -0.0.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
  //if( phase->type(in(1)) == TypeD::ZERO )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
  //return new (phase->C, 2) NegDNode(in(2));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
//------------------------------sub--------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
// A subtract node differences its two inputs.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
const Type *SubDNode::sub( const Type *t1, const Type *t2 ) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
  // no folding if one of operands is infinity or NaN, do not do constant folding
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
  if( g_isfinite(t1->getd()) && g_isfinite(t2->getd()) ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
    return TypeD::make( t1->getd() - t2->getd() );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
  else if( g_isnan(t1->getd()) ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
    return t1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
  else if( g_isnan(t2->getd()) ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
    return t2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
  else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
    return Type::DOUBLE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
//=============================================================================
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
//------------------------------Idealize---------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
// Unlike SubNodes, compare must still flatten return value to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
// range -1, 0, 1.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
// And optimizations like those for (X + Y) - X fail if overflow happens.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
Node *CmpNode::Identity( PhaseTransform *phase ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
  return this;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
//=============================================================================
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
//------------------------------cmp--------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
// Simplify a CmpI (compare 2 integers) node, based on local information.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
// If both inputs are constants, compare them.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
const Type *CmpINode::sub( const Type *t1, const Type *t2 ) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
  const TypeInt *r0 = t1->is_int(); // Handy access
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
  const TypeInt *r1 = t2->is_int();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
  if( r0->_hi < r1->_lo )       // Range is always low?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
    return TypeInt::CC_LT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
  else if( r0->_lo > r1->_hi )  // Range is always high?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
    return TypeInt::CC_GT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
  else if( r0->is_con() && r1->is_con() ) { // comparing constants?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
    assert(r0->get_con() == r1->get_con(), "must be equal");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
    return TypeInt::CC_EQ;      // Equal results.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
  } else if( r0->_hi == r1->_lo ) // Range is never high?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
    return TypeInt::CC_LE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
  else if( r0->_lo == r1->_hi ) // Range is never low?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
    return TypeInt::CC_GE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
  return TypeInt::CC;           // else use worst case results
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
// Simplify a CmpU (compare 2 integers) node, based on local information.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
// If both inputs are constants, compare them.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
const Type *CmpUNode::sub( const Type *t1, const Type *t2 ) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
  assert(!t1->isa_ptr(), "obsolete usage of CmpU");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
  // comparing two unsigned ints
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
  const TypeInt *r0 = t1->is_int();   // Handy access
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
  const TypeInt *r1 = t2->is_int();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
  // Current installed version
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
  // Compare ranges for non-overlap
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
  juint lo0 = r0->_lo;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
  juint hi0 = r0->_hi;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
  juint lo1 = r1->_lo;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
  juint hi1 = r1->_hi;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
  // If either one has both negative and positive values,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
  // it therefore contains both 0 and -1, and since [0..-1] is the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
  // full unsigned range, the type must act as an unsigned bottom.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
  bool bot0 = ((jint)(lo0 ^ hi0) < 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
  bool bot1 = ((jint)(lo1 ^ hi1) < 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
  if (bot0 || bot1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
    // All unsigned values are LE -1 and GE 0.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
    if (lo0 == 0 && hi0 == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
      return TypeInt::CC_LE;            //   0 <= bot
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
    } else if (lo1 == 0 && hi1 == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
      return TypeInt::CC_GE;            // bot >= 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
    // We can use ranges of the form [lo..hi] if signs are the same.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
    assert(lo0 <= hi0 && lo1 <= hi1, "unsigned ranges are valid");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
    // results are reversed, '-' > '+' for unsigned compare
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
    if (hi0 < lo1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
      return TypeInt::CC_LT;            // smaller
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
    } else if (lo0 > hi1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
      return TypeInt::CC_GT;            // greater
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
    } else if (hi0 == lo1 && lo0 == hi1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
      return TypeInt::CC_EQ;            // Equal results
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
    } else if (lo0 >= hi1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
      return TypeInt::CC_GE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
    } else if (hi0 <= lo1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
      // Check for special case in Hashtable::get.  (See below.)
13205
5495b63764bf 7181658: CTW: assert(t->meet(t0) == t) failed: Not monotonic
kvn
parents: 12945
diff changeset
   557
      if ((jint)lo0 >= 0 && (jint)lo1 >= 0 && is_index_range_check())
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
        return TypeInt::CC_LT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
      return TypeInt::CC_LE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
  // Check for special case in Hashtable::get - the hash index is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
  // mod'ed to the table size so the following range check is useless.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
  // Check for: (X Mod Y) CmpU Y, where the mod result and Y both have
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
  // to be positive.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
  // (This is a gross hack, since the sub method never
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
  // looks at the structure of the node in any other case.)
13205
5495b63764bf 7181658: CTW: assert(t->meet(t0) == t) failed: Not monotonic
kvn
parents: 12945
diff changeset
   568
  if ((jint)lo0 >= 0 && (jint)lo1 >= 0 && is_index_range_check())
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
    return TypeInt::CC_LT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
  return TypeInt::CC;                   // else use worst case results
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
13205
5495b63764bf 7181658: CTW: assert(t->meet(t0) == t) failed: Not monotonic
kvn
parents: 12945
diff changeset
   573
bool CmpUNode::is_index_range_check() const {
5495b63764bf 7181658: CTW: assert(t->meet(t0) == t) failed: Not monotonic
kvn
parents: 12945
diff changeset
   574
  // Check for the "(X ModI Y) CmpU Y" shape
5495b63764bf 7181658: CTW: assert(t->meet(t0) == t) failed: Not monotonic
kvn
parents: 12945
diff changeset
   575
  return (in(1)->Opcode() == Op_ModI &&
5495b63764bf 7181658: CTW: assert(t->meet(t0) == t) failed: Not monotonic
kvn
parents: 12945
diff changeset
   576
          in(1)->in(2)->eqv_uncast(in(2)));
5495b63764bf 7181658: CTW: assert(t->meet(t0) == t) failed: Not monotonic
kvn
parents: 12945
diff changeset
   577
}
5495b63764bf 7181658: CTW: assert(t->meet(t0) == t) failed: Not monotonic
kvn
parents: 12945
diff changeset
   578
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
//------------------------------Idealize---------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
Node *CmpINode::Ideal( PhaseGVN *phase, bool can_reshape ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
  if (phase->type(in(2))->higher_equal(TypeInt::ZERO)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
    switch (in(1)->Opcode()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
    case Op_CmpL3:              // Collapse a CmpL3/CmpI into a CmpL
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   584
      return new (phase->C) CmpLNode(in(1)->in(1),in(1)->in(2));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
    case Op_CmpF3:              // Collapse a CmpF3/CmpI into a CmpF
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   586
      return new (phase->C) CmpFNode(in(1)->in(1),in(1)->in(2));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
    case Op_CmpD3:              // Collapse a CmpD3/CmpI into a CmpD
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
   588
      return new (phase->C) CmpDNode(in(1)->in(1),in(1)->in(2));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
    //case Op_SubI:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
      // If (x - y) cannot overflow, then ((x - y) <?> 0)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
      // can be turned into (x <?> y).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
      // This is handled (with more general cases) by Ideal_sub_algebra.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
  return NULL;                  // No change
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
//=============================================================================
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
// Simplify a CmpL (compare 2 longs ) node, based on local information.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
// If both inputs are constants, compare them.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
const Type *CmpLNode::sub( const Type *t1, const Type *t2 ) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
  const TypeLong *r0 = t1->is_long(); // Handy access
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
  const TypeLong *r1 = t2->is_long();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
  if( r0->_hi < r1->_lo )       // Range is always low?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
    return TypeInt::CC_LT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
  else if( r0->_lo > r1->_hi )  // Range is always high?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
    return TypeInt::CC_GT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
  else if( r0->is_con() && r1->is_con() ) { // comparing constants?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
    assert(r0->get_con() == r1->get_con(), "must be equal");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
    return TypeInt::CC_EQ;      // Equal results.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
  } else if( r0->_hi == r1->_lo ) // Range is never high?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   615
    return TypeInt::CC_LE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
  else if( r0->_lo == r1->_hi ) // Range is never low?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
    return TypeInt::CC_GE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
  return TypeInt::CC;           // else use worst case results
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
//=============================================================================
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
//------------------------------sub--------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
// Simplify an CmpP (compare 2 pointers) node, based on local information.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
// If both inputs are constants, compare them.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
const Type *CmpPNode::sub( const Type *t1, const Type *t2 ) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
  const TypePtr *r0 = t1->is_ptr(); // Handy access
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
  const TypePtr *r1 = t2->is_ptr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
  // Undefined inputs makes for an undefined result
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
  if( TypePtr::above_centerline(r0->_ptr) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
      TypePtr::above_centerline(r1->_ptr) )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
    return Type::TOP;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   633
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
  if (r0 == r1 && r0->singleton()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   635
    // Equal pointer constants (klasses, nulls, etc.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
    return TypeInt::CC_EQ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
  // See if it is 2 unrelated classes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
  const TypeOopPtr* p0 = r0->isa_oopptr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   641
  const TypeOopPtr* p1 = r1->isa_oopptr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   642
  if (p0 && p1) {
206
d61cf247afd5 6667580: Optimize CmpP for allocations
kvn
parents: 1
diff changeset
   643
    Node* in1 = in(1)->uncast();
d61cf247afd5 6667580: Optimize CmpP for allocations
kvn
parents: 1
diff changeset
   644
    Node* in2 = in(2)->uncast();
d61cf247afd5 6667580: Optimize CmpP for allocations
kvn
parents: 1
diff changeset
   645
    AllocateNode* alloc1 = AllocateNode::Ideal_allocation(in1, NULL);
d61cf247afd5 6667580: Optimize CmpP for allocations
kvn
parents: 1
diff changeset
   646
    AllocateNode* alloc2 = AllocateNode::Ideal_allocation(in2, NULL);
d61cf247afd5 6667580: Optimize CmpP for allocations
kvn
parents: 1
diff changeset
   647
    if (MemNode::detect_ptr_independence(in1, alloc1, in2, alloc2, NULL)) {
d61cf247afd5 6667580: Optimize CmpP for allocations
kvn
parents: 1
diff changeset
   648
      return TypeInt::CC_GT;  // different pointers
d61cf247afd5 6667580: Optimize CmpP for allocations
kvn
parents: 1
diff changeset
   649
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   650
    ciKlass* klass0 = p0->klass();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   651
    bool    xklass0 = p0->klass_is_exact();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   652
    ciKlass* klass1 = p1->klass();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   653
    bool    xklass1 = p1->klass_is_exact();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
    int kps = (p0->isa_klassptr()?1:0) + (p1->isa_klassptr()?1:0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
    if (klass0 && klass1 &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
        kps != 1 &&             // both or neither are klass pointers
2335
e1965d139bb7 6820510: assertion failure with unloaded class in subnode.cpp
never
parents: 1432
diff changeset
   657
        klass0->is_loaded() && !klass0->is_interface() && // do not trust interfaces
2870
52b70541d4d3 6832293: JIT compiler got wrong result in type checking with -server
kvn
parents: 2335
diff changeset
   658
        klass1->is_loaded() && !klass1->is_interface() &&
52b70541d4d3 6832293: JIT compiler got wrong result in type checking with -server
kvn
parents: 2335
diff changeset
   659
        (!klass0->is_obj_array_klass() ||
52b70541d4d3 6832293: JIT compiler got wrong result in type checking with -server
kvn
parents: 2335
diff changeset
   660
         !klass0->as_obj_array_klass()->base_element_klass()->is_interface()) &&
52b70541d4d3 6832293: JIT compiler got wrong result in type checking with -server
kvn
parents: 2335
diff changeset
   661
        (!klass1->is_obj_array_klass() ||
52b70541d4d3 6832293: JIT compiler got wrong result in type checking with -server
kvn
parents: 2335
diff changeset
   662
         !klass1->as_obj_array_klass()->base_element_klass()->is_interface())) {
1058
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   663
      bool unrelated_classes = false;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
      // See if neither subclasses the other, or if the class on top
1058
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   665
      // is precise.  In either of these cases, the compare is known
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   666
      // to fail if at least one of the pointers is provably not null.
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13205
diff changeset
   667
      if (klass0->equals(klass1)) {  // if types are unequal but klasses are equal
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   668
        // Do nothing; we know nothing for imprecise types
489c9b5090e2 Initial load
duke
parents:
diff changeset
   669
      } else if (klass0->is_subtype_of(klass1)) {
1058
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   670
        // If klass1's type is PRECISE, then classes are unrelated.
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   671
        unrelated_classes = xklass1;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   672
      } else if (klass1->is_subtype_of(klass0)) {
1058
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   673
        // If klass0's type is PRECISE, then classes are unrelated.
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   674
        unrelated_classes = xklass0;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
      } else {                  // Neither subtypes the other
1058
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   676
        unrelated_classes = true;
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   677
      }
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   678
      if (unrelated_classes) {
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   679
        // The oops classes are known to be unrelated. If the joined PTRs of
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   680
        // two oops is not Null and not Bottom, then we are sure that one
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   681
        // of the two oops is non-null, and the comparison will always fail.
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   682
        TypePtr::PTR jp = r0->join_ptr(r1->_ptr);
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   683
        if (jp != TypePtr::Null && jp != TypePtr::BotPTR) {
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   684
          return TypeInt::CC_GT;
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   685
        }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   687
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   688
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   689
489c9b5090e2 Initial load
duke
parents:
diff changeset
   690
  // Known constants can be compared exactly
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
  // Null can be distinguished from any NotNull pointers
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
  // Unknown inputs makes an unknown result
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
  if( r0->singleton() ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
    intptr_t bits0 = r0->get_con();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   695
    if( r1->singleton() )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   696
      return bits0 == r1->get_con() ? TypeInt::CC_EQ : TypeInt::CC_GT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   697
    return ( r1->_ptr == TypePtr::NotNull && bits0==0 ) ? TypeInt::CC_GT : TypeInt::CC;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   698
  } else if( r1->singleton() ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   699
    intptr_t bits1 = r1->get_con();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   700
    return ( r0->_ptr == TypePtr::NotNull && bits1==0 ) ? TypeInt::CC_GT : TypeInt::CC;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   701
  } else
489c9b5090e2 Initial load
duke
parents:
diff changeset
   702
    return TypeInt::CC;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   703
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   704
12945
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   705
static inline Node* isa_java_mirror_load(PhaseGVN* phase, Node* n) {
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   706
  // Return the klass node for
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   707
  //   LoadP(AddP(foo:Klass, #java_mirror))
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   708
  //   or NULL if not matching.
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   709
  if (n->Opcode() != Op_LoadP) return NULL;
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   710
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   711
  const TypeInstPtr* tp = phase->type(n)->isa_instptr();
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   712
  if (!tp || tp->klass() != phase->C->env()->Class_klass()) return NULL;
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   713
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   714
  Node* adr = n->in(MemNode::Address);
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   715
  intptr_t off = 0;
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   716
  Node* k = AddPNode::Ideal_base_and_offset(adr, phase, off);
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   717
  if (k == NULL)  return NULL;
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   718
  const TypeKlassPtr* tkp = phase->type(k)->isa_klassptr();
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   719
  if (!tkp || off != in_bytes(Klass::java_mirror_offset())) return NULL;
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   720
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   721
  // We've found the klass node of a Java mirror load.
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   722
  return k;
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   723
}
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   724
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   725
static inline Node* isa_const_java_mirror(PhaseGVN* phase, Node* n) {
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   726
  // for ConP(Foo.class) return ConP(Foo.klass)
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   727
  // otherwise return NULL
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   728
  if (!n->is_Con()) return NULL;
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   729
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   730
  const TypeInstPtr* tp = phase->type(n)->isa_instptr();
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   731
  if (!tp) return NULL;
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   732
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   733
  ciType* mirror_type = tp->java_mirror_type();
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   734
  // TypeInstPtr::java_mirror_type() returns non-NULL for compile-
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   735
  // time Class constants only.
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   736
  if (!mirror_type) return NULL;
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   737
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   738
  // x.getClass() == int.class can never be true (for all primitive types)
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   739
  // Return a ConP(NULL) node for this case.
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   740
  if (mirror_type->is_classless()) {
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   741
    return phase->makecon(TypePtr::NULL_PTR);
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   742
  }
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   743
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   744
  // return the ConP(Foo.klass)
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13205
diff changeset
   745
  assert(mirror_type->is_klass(), "mirror_type should represent a Klass*");
12945
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   746
  return phase->makecon(TypeKlassPtr::make(mirror_type->as_klass()));
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   747
}
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   748
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   749
//------------------------------Ideal------------------------------------------
12945
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   750
// Normalize comparisons between Java mirror loads to compare the klass instead.
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   751
//
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   752
// Also check for the case of comparing an unknown klass loaded from the primary
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   753
// super-type array vs a known klass with no subtypes.  This amounts to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   754
// checking to see an unknown klass subtypes a known klass with no subtypes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   755
// this only happens on an exact match.  We can shorten this test by 1 load.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   756
Node *CmpPNode::Ideal( PhaseGVN *phase, bool can_reshape ) {
12945
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   757
  // Normalize comparisons between Java mirrors into comparisons of the low-
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   758
  // level klass, where a dependent load could be shortened.
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   759
  //
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   760
  // The new pattern has a nice effect of matching the same pattern used in the
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   761
  // fast path of instanceof/checkcast/Class.isInstance(), which allows
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   762
  // redundant exact type check be optimized away by GVN.
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   763
  // For example, in
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   764
  //   if (x.getClass() == Foo.class) {
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   765
  //     Foo foo = (Foo) x;
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   766
  //     // ... use a ...
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   767
  //   }
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   768
  // a CmpPNode could be shared between if_acmpne and checkcast
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   769
  {
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   770
    Node* k1 = isa_java_mirror_load(phase, in(1));
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   771
    Node* k2 = isa_java_mirror_load(phase, in(2));
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   772
    Node* conk2 = isa_const_java_mirror(phase, in(2));
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   773
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   774
    if (k1 && (k2 || conk2)) {
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   775
      Node* lhs = k1;
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   776
      Node* rhs = (k2 != NULL) ? k2 : conk2;
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   777
      this->set_req(1, lhs);
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   778
      this->set_req(2, rhs);
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   779
      return this;
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   780
    }
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   781
  }
e63d6176cbd1 7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents: 12739
diff changeset
   782
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   783
  // Constant pointer on right?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   784
  const TypeKlassPtr* t2 = phase->type(in(2))->isa_klassptr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   785
  if (t2 == NULL || !t2->klass_is_exact())
489c9b5090e2 Initial load
duke
parents:
diff changeset
   786
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   787
  // Get the constant klass we are comparing to.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   788
  ciKlass* superklass = t2->klass();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   789
489c9b5090e2 Initial load
duke
parents:
diff changeset
   790
  // Now check for LoadKlass on left.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   791
  Node* ldk1 = in(1);
13969
d2a189b83b87 7054512: Compress class pointers after perm gen removal
roland
parents: 13895
diff changeset
   792
  if (ldk1->is_DecodeNKlass()) {
1055
f4fb9fb08038 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 781
diff changeset
   793
    ldk1 = ldk1->in(1);
f4fb9fb08038 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 781
diff changeset
   794
    if (ldk1->Opcode() != Op_LoadNKlass )
f4fb9fb08038 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 781
diff changeset
   795
      return NULL;
f4fb9fb08038 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 781
diff changeset
   796
  } else if (ldk1->Opcode() != Op_LoadKlass )
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   797
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   798
  // Take apart the address of the LoadKlass:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   799
  Node* adr1 = ldk1->in(MemNode::Address);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   800
  intptr_t con2 = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   801
  Node* ldk2 = AddPNode::Ideal_base_and_offset(adr1, phase, con2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   802
  if (ldk2 == NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   803
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   804
  if (con2 == oopDesc::klass_offset_in_bytes()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   805
    // We are inspecting an object's concrete class.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   806
    // Short-circuit the check if the query is abstract.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   807
    if (superklass->is_interface() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   808
        superklass->is_abstract()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   809
      // Make it come out always false:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   810
      this->set_req(2, phase->makecon(TypePtr::NULL_PTR));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   811
      return this;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   812
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   813
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   814
489c9b5090e2 Initial load
duke
parents:
diff changeset
   815
  // Check for a LoadKlass from primary supertype array.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   816
  // Any nested loadklass from loadklass+con must be from the p.s. array.
13969
d2a189b83b87 7054512: Compress class pointers after perm gen removal
roland
parents: 13895
diff changeset
   817
  if (ldk2->is_DecodeNKlass()) {
1055
f4fb9fb08038 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 781
diff changeset
   818
    // Keep ldk2 as DecodeN since it could be used in CmpP below.
f4fb9fb08038 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 781
diff changeset
   819
    if (ldk2->in(1)->Opcode() != Op_LoadNKlass )
f4fb9fb08038 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 781
diff changeset
   820
      return NULL;
f4fb9fb08038 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 781
diff changeset
   821
  } else if (ldk2->Opcode() != Op_LoadKlass)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   822
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   823
489c9b5090e2 Initial load
duke
parents:
diff changeset
   824
  // Verify that we understand the situation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   825
  if (con2 != (intptr_t) superklass->super_check_offset())
489c9b5090e2 Initial load
duke
parents:
diff changeset
   826
    return NULL;                // Might be element-klass loading from array klass
489c9b5090e2 Initial load
duke
parents:
diff changeset
   827
489c9b5090e2 Initial load
duke
parents:
diff changeset
   828
  // If 'superklass' has no subklasses and is not an interface, then we are
489c9b5090e2 Initial load
duke
parents:
diff changeset
   829
  // assured that the only input which will pass the type check is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   830
  // 'superklass' itself.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   831
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   832
  // We could be more liberal here, and allow the optimization on interfaces
489c9b5090e2 Initial load
duke
parents:
diff changeset
   833
  // which have a single implementor.  This would require us to increase the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   834
  // expressiveness of the add_dependency() mechanism.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   835
  // %%% Do this after we fix TypeOopPtr:  Deps are expressive enough now.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   836
489c9b5090e2 Initial load
duke
parents:
diff changeset
   837
  // Object arrays must have their base element have no subtypes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   838
  while (superklass->is_obj_array_klass()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   839
    ciType* elem = superklass->as_obj_array_klass()->element_type();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   840
    superklass = elem->as_klass();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   841
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   842
  if (superklass->is_instance_klass()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   843
    ciInstanceKlass* ik = superklass->as_instance_klass();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   844
    if (ik->has_subklass() || ik->is_interface())  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   845
    // Add a dependency if there is a chance that a subclass will be added later.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   846
    if (!ik->is_final()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   847
      phase->C->dependencies()->assert_leaf_type(ik);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   848
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   849
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   850
489c9b5090e2 Initial load
duke
parents:
diff changeset
   851
  // Bypass the dependent load, and compare directly
489c9b5090e2 Initial load
duke
parents:
diff changeset
   852
  this->set_req(1,ldk2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   853
489c9b5090e2 Initial load
duke
parents:
diff changeset
   854
  return this;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   855
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   856
489c9b5090e2 Initial load
duke
parents:
diff changeset
   857
//=============================================================================
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   858
//------------------------------sub--------------------------------------------
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   859
// Simplify an CmpN (compare 2 pointers) node, based on local information.
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   860
// If both inputs are constants, compare them.
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   861
const Type *CmpNNode::sub( const Type *t1, const Type *t2 ) const {
767
64fb1fd7186d 6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents: 758
diff changeset
   862
  const TypePtr *r0 = t1->make_ptr(); // Handy access
64fb1fd7186d 6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents: 758
diff changeset
   863
  const TypePtr *r1 = t2->make_ptr();
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   864
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   865
  // Undefined inputs makes for an undefined result
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   866
  if( TypePtr::above_centerline(r0->_ptr) ||
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   867
      TypePtr::above_centerline(r1->_ptr) )
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   868
    return Type::TOP;
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   869
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   870
  if (r0 == r1 && r0->singleton()) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   871
    // Equal pointer constants (klasses, nulls, etc.)
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   872
    return TypeInt::CC_EQ;
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   873
  }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   874
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   875
  // See if it is 2 unrelated classes.
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   876
  const TypeOopPtr* p0 = r0->isa_oopptr();
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   877
  const TypeOopPtr* p1 = r1->isa_oopptr();
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   878
  if (p0 && p1) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   879
    ciKlass* klass0 = p0->klass();
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   880
    bool    xklass0 = p0->klass_is_exact();
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   881
    ciKlass* klass1 = p1->klass();
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   882
    bool    xklass1 = p1->klass_is_exact();
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   883
    int kps = (p0->isa_klassptr()?1:0) + (p1->isa_klassptr()?1:0);
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   884
    if (klass0 && klass1 &&
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   885
        kps != 1 &&             // both or neither are klass pointers
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   886
        !klass0->is_interface() && // do not trust interfaces
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   887
        !klass1->is_interface()) {
1058
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   888
      bool unrelated_classes = false;
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   889
      // See if neither subclasses the other, or if the class on top
1058
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   890
      // is precise.  In either of these cases, the compare is known
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   891
      // to fail if at least one of the pointers is provably not null.
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13205
diff changeset
   892
      if (klass0->equals(klass1)) { // if types are unequal but klasses are equal
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   893
        // Do nothing; we know nothing for imprecise types
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   894
      } else if (klass0->is_subtype_of(klass1)) {
1058
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   895
        // If klass1's type is PRECISE, then classes are unrelated.
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   896
        unrelated_classes = xklass1;
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   897
      } else if (klass1->is_subtype_of(klass0)) {
1058
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   898
        // If klass0's type is PRECISE, then classes are unrelated.
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   899
        unrelated_classes = xklass0;
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   900
      } else {                  // Neither subtypes the other
1058
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   901
        unrelated_classes = true;
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   902
      }
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   903
      if (unrelated_classes) {
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   904
        // The oops classes are known to be unrelated. If the joined PTRs of
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   905
        // two oops is not Null and not Bottom, then we are sure that one
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   906
        // of the two oops is non-null, and the comparison will always fail.
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   907
        TypePtr::PTR jp = r0->join_ptr(r1->_ptr);
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   908
        if (jp != TypePtr::Null && jp != TypePtr::BotPTR) {
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   909
          return TypeInt::CC_GT;
52be2dbbdc79 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 1055
diff changeset
   910
        }
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   911
      }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   912
    }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   913
  }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   914
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   915
  // Known constants can be compared exactly
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   916
  // Null can be distinguished from any NotNull pointers
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   917
  // Unknown inputs makes an unknown result
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   918
  if( r0->singleton() ) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   919
    intptr_t bits0 = r0->get_con();
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   920
    if( r1->singleton() )
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   921
      return bits0 == r1->get_con() ? TypeInt::CC_EQ : TypeInt::CC_GT;
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   922
    return ( r1->_ptr == TypePtr::NotNull && bits0==0 ) ? TypeInt::CC_GT : TypeInt::CC;
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   923
  } else if( r1->singleton() ) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   924
    intptr_t bits1 = r1->get_con();
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   925
    return ( r0->_ptr == TypePtr::NotNull && bits1==0 ) ? TypeInt::CC_GT : TypeInt::CC;
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   926
  } else
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   927
    return TypeInt::CC;
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   928
}
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   929
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   930
//------------------------------Ideal------------------------------------------
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   931
Node *CmpNNode::Ideal( PhaseGVN *phase, bool can_reshape ) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   932
  return NULL;
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   933
}
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   934
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 206
diff changeset
   935
//=============================================================================
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   936
//------------------------------Value------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   937
// Simplify an CmpF (compare 2 floats ) node, based on local information.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   938
// If both inputs are constants, compare them.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   939
const Type *CmpFNode::Value( PhaseTransform *phase ) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   940
  const Node* in1 = in(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   941
  const Node* in2 = in(2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   942
  // Either input is TOP ==> the result is TOP
489c9b5090e2 Initial load
duke
parents:
diff changeset
   943
  const Type* t1 = (in1 == this) ? Type::TOP : phase->type(in1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   944
  if( t1 == Type::TOP ) return Type::TOP;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   945
  const Type* t2 = (in2 == this) ? Type::TOP : phase->type(in2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   946
  if( t2 == Type::TOP ) return Type::TOP;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   947
489c9b5090e2 Initial load
duke
parents:
diff changeset
   948
  // Not constants?  Don't know squat - even if they are the same
489c9b5090e2 Initial load
duke
parents:
diff changeset
   949
  // value!  If they are NaN's they compare to LT instead of EQ.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   950
  const TypeF *tf1 = t1->isa_float_constant();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   951
  const TypeF *tf2 = t2->isa_float_constant();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   952
  if( !tf1 || !tf2 ) return TypeInt::CC;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   953
489c9b5090e2 Initial load
duke
parents:
diff changeset
   954
  // This implements the Java bytecode fcmpl, so unordered returns -1.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   955
  if( tf1->is_nan() || tf2->is_nan() )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   956
    return TypeInt::CC_LT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   957
489c9b5090e2 Initial load
duke
parents:
diff changeset
   958
  if( tf1->_f < tf2->_f ) return TypeInt::CC_LT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   959
  if( tf1->_f > tf2->_f ) return TypeInt::CC_GT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   960
  assert( tf1->_f == tf2->_f, "do not understand FP behavior" );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   961
  return TypeInt::CC_EQ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   962
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   963
489c9b5090e2 Initial load
duke
parents:
diff changeset
   964
489c9b5090e2 Initial load
duke
parents:
diff changeset
   965
//=============================================================================
489c9b5090e2 Initial load
duke
parents:
diff changeset
   966
//------------------------------Value------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   967
// Simplify an CmpD (compare 2 doubles ) node, based on local information.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   968
// If both inputs are constants, compare them.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   969
const Type *CmpDNode::Value( PhaseTransform *phase ) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   970
  const Node* in1 = in(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   971
  const Node* in2 = in(2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   972
  // Either input is TOP ==> the result is TOP
489c9b5090e2 Initial load
duke
parents:
diff changeset
   973
  const Type* t1 = (in1 == this) ? Type::TOP : phase->type(in1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   974
  if( t1 == Type::TOP ) return Type::TOP;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   975
  const Type* t2 = (in2 == this) ? Type::TOP : phase->type(in2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   976
  if( t2 == Type::TOP ) return Type::TOP;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   977
489c9b5090e2 Initial load
duke
parents:
diff changeset
   978
  // Not constants?  Don't know squat - even if they are the same
489c9b5090e2 Initial load
duke
parents:
diff changeset
   979
  // value!  If they are NaN's they compare to LT instead of EQ.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   980
  const TypeD *td1 = t1->isa_double_constant();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   981
  const TypeD *td2 = t2->isa_double_constant();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   982
  if( !td1 || !td2 ) return TypeInt::CC;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   983
489c9b5090e2 Initial load
duke
parents:
diff changeset
   984
  // This implements the Java bytecode dcmpl, so unordered returns -1.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   985
  if( td1->is_nan() || td2->is_nan() )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   986
    return TypeInt::CC_LT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   987
489c9b5090e2 Initial load
duke
parents:
diff changeset
   988
  if( td1->_d < td2->_d ) return TypeInt::CC_LT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   989
  if( td1->_d > td2->_d ) return TypeInt::CC_GT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   990
  assert( td1->_d == td2->_d, "do not understand FP behavior" );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   991
  return TypeInt::CC_EQ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   992
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   993
489c9b5090e2 Initial load
duke
parents:
diff changeset
   994
//------------------------------Ideal------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   995
Node *CmpDNode::Ideal(PhaseGVN *phase, bool can_reshape){
489c9b5090e2 Initial load
duke
parents:
diff changeset
   996
  // Check if we can change this to a CmpF and remove a ConvD2F operation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   997
  // Change  (CMPD (F2D (float)) (ConD value))
489c9b5090e2 Initial load
duke
parents:
diff changeset
   998
  // To      (CMPF      (float)  (ConF value))
489c9b5090e2 Initial load
duke
parents:
diff changeset
   999
  // Valid when 'value' does not lose precision as a float.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1000
  // Benefits: eliminates conversion, does not require 24-bit mode
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1001
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1002
  // NaNs prevent commuting operands.  This transform works regardless of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1003
  // order of ConD and ConvF2D inputs by preserving the original order.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1004
  int idx_f2d = 1;              // ConvF2D on left side?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1005
  if( in(idx_f2d)->Opcode() != Op_ConvF2D )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1006
    idx_f2d = 2;                // No, swap to check for reversed args
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1007
  int idx_con = 3-idx_f2d;      // Check for the constant on other input
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1008
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1009
  if( ConvertCmpD2CmpF &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1010
      in(idx_f2d)->Opcode() == Op_ConvF2D &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1011
      in(idx_con)->Opcode() == Op_ConD ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1012
    const TypeD *t2 = in(idx_con)->bottom_type()->is_double_constant();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1013
    double t2_value_as_double = t2->_d;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1014
    float  t2_value_as_float  = (float)t2_value_as_double;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1015
    if( t2_value_as_double == (double)t2_value_as_float ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1016
      // Test value can be represented as a float
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1017
      // Eliminate the conversion to double and create new comparison
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1018
      Node *new_in1 = in(idx_f2d)->in(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1019
      Node *new_in2 = phase->makecon( TypeF::make(t2_value_as_float) );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1020
      if( idx_f2d != 1 ) {      // Must flip args to match original order
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1021
        Node *tmp = new_in1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1022
        new_in1 = new_in2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1023
        new_in2 = tmp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1024
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1025
      CmpFNode *new_cmp = (Opcode() == Op_CmpD3)
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
  1026
        ? new (phase->C) CmpF3Node( new_in1, new_in2 )
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
  1027
        : new (phase->C) CmpFNode ( new_in1, new_in2 ) ;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1028
      return new_cmp;           // Changed to CmpFNode
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1029
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1030
    // Testing value required the precision of a double
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1031
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1032
  return NULL;                  // No change
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1033
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1034
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1035
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1036
//=============================================================================
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1037
//------------------------------cc2logical-------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1038
// Convert a condition code type to a logical type
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1039
const Type *BoolTest::cc2logical( const Type *CC ) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1040
  if( CC == Type::TOP ) return Type::TOP;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1041
  if( CC->base() != Type::Int ) return TypeInt::BOOL; // Bottom or worse
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1042
  const TypeInt *ti = CC->is_int();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1043
  if( ti->is_con() ) {          // Only 1 kind of condition codes set?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1044
    // Match low order 2 bits
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1045
    int tmp = ((ti->get_con()&3) == (_test&3)) ? 1 : 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1046
    if( _test & 4 ) tmp = 1-tmp;     // Optionally complement result
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1047
    return TypeInt::make(tmp);       // Boolean result
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1048
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1049
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1050
  if( CC == TypeInt::CC_GE ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1051
    if( _test == ge ) return TypeInt::ONE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1052
    if( _test == lt ) return TypeInt::ZERO;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1053
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1054
  if( CC == TypeInt::CC_LE ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1055
    if( _test == le ) return TypeInt::ONE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1056
    if( _test == gt ) return TypeInt::ZERO;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1057
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1058
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1059
  return TypeInt::BOOL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1060
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1061
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1062
//------------------------------dump_spec-------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1063
// Print special per-node info
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1064
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1065
void BoolTest::dump_on(outputStream *st) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1066
  const char *msg[] = {"eq","gt","??","lt","ne","le","??","ge"};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1067
  st->print(msg[_test]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1068
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1069
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1070
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1071
//=============================================================================
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1072
uint BoolNode::hash() const { return (Node::hash() << 3)|(_test._test+1); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1073
uint BoolNode::size_of() const { return sizeof(BoolNode); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1074
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1075
//------------------------------operator==-------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1076
uint BoolNode::cmp( const Node &n ) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1077
  const BoolNode *b = (const BoolNode *)&n; // Cast up
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1078
  return (_test._test == b->_test._test);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1079
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1080
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1081
//------------------------------clone_cmp--------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1082
// Clone a compare/bool tree
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1083
static Node *clone_cmp( Node *cmp, Node *cmp1, Node *cmp2, PhaseGVN *gvn, BoolTest::mask test ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1084
  Node *ncmp = cmp->clone();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1085
  ncmp->set_req(1,cmp1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1086
  ncmp->set_req(2,cmp2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1087
  ncmp = gvn->transform( ncmp );
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
  1088
  return new (gvn->C) BoolNode( ncmp, test );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1089
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1090
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1091
//-------------------------------make_predicate--------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1092
Node* BoolNode::make_predicate(Node* test_value, PhaseGVN* phase) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1093
  if (test_value->is_Con())   return test_value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1094
  if (test_value->is_Bool())  return test_value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1095
  Compile* C = phase->C;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1096
  if (test_value->is_CMove() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1097
      test_value->in(CMoveNode::Condition)->is_Bool()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1098
    BoolNode*   bol   = test_value->in(CMoveNode::Condition)->as_Bool();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1099
    const Type* ftype = phase->type(test_value->in(CMoveNode::IfFalse));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1100
    const Type* ttype = phase->type(test_value->in(CMoveNode::IfTrue));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1101
    if (ftype == TypeInt::ZERO && !TypeInt::ZERO->higher_equal(ttype)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1102
      return bol;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1103
    } else if (ttype == TypeInt::ZERO && !TypeInt::ZERO->higher_equal(ftype)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1104
      return phase->transform( bol->negate(phase) );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1105
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1106
    // Else fall through.  The CMove gets in the way of the test.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1107
    // It should be the case that make_predicate(bol->as_int_value()) == bol.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1108
  }
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
  1109
  Node* cmp = new (C) CmpINode(test_value, phase->intcon(0));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1110
  cmp = phase->transform(cmp);
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
  1111
  Node* bol = new (C) BoolNode(cmp, BoolTest::ne);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1112
  return phase->transform(bol);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1113
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1114
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1115
//--------------------------------as_int_value---------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1116
Node* BoolNode::as_int_value(PhaseGVN* phase) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1117
  // Inverse to make_predicate.  The CMove probably boils down to a Conv2B.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1118
  Node* cmov = CMoveNode::make(phase->C, NULL, this,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1119
                               phase->intcon(0), phase->intcon(1),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1120
                               TypeInt::BOOL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1121
  return phase->transform(cmov);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1122
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1123
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1124
//----------------------------------negate-------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1125
BoolNode* BoolNode::negate(PhaseGVN* phase) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1126
  Compile* C = phase->C;
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
  1127
  return new (C) BoolNode(in(1), _test.negate());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1128
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1129
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1130
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1131
//------------------------------Ideal------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1132
Node *BoolNode::Ideal(PhaseGVN *phase, bool can_reshape) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1133
  // Change "bool tst (cmp con x)" into "bool ~tst (cmp x con)".
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1134
  // This moves the constant to the right.  Helps value-numbering.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1135
  Node *cmp = in(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1136
  if( !cmp->is_Sub() ) return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1137
  int cop = cmp->Opcode();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1138
  if( cop == Op_FastLock || cop == Op_FastUnlock ) return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1139
  Node *cmp1 = cmp->in(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1140
  Node *cmp2 = cmp->in(2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1141
  if( !cmp1 ) return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1142
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1143
  // Constant on left?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1144
  Node *con = cmp1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1145
  uint op2 = cmp2->Opcode();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1146
  // Move constants to the right of compare's to canonicalize.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1147
  // Do not muck with Opaque1 nodes, as this indicates a loop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1148
  // guard that cannot change shape.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1149
  if( con->is_Con() && !cmp2->is_Con() && op2 != Op_Opaque1 &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1150
      // Because of NaN's, CmpD and CmpF are not commutative
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1151
      cop != Op_CmpD && cop != Op_CmpF &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1152
      // Protect against swapping inputs to a compare when it is used by a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1153
      // counted loop exit, which requires maintaining the loop-limit as in(2)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1154
      !is_counted_loop_exit_test() ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1155
    // Ok, commute the constant to the right of the cmp node.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1156
    // Clone the Node, getting a new Node of the same class
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1157
    cmp = cmp->clone();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1158
    // Swap inputs to the clone
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1159
    cmp->swap_edges(1, 2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1160
    cmp = phase->transform( cmp );
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
  1161
    return new (phase->C) BoolNode( cmp, _test.commute() );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1162
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1163
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1164
  // Change "bool eq/ne (cmp (xor X 1) 0)" into "bool ne/eq (cmp X 0)".
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1165
  // The XOR-1 is an idiom used to flip the sense of a bool.  We flip the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1166
  // test instead.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1167
  int cmp1_op = cmp1->Opcode();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1168
  const TypeInt* cmp2_type = phase->type(cmp2)->isa_int();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1169
  if (cmp2_type == NULL)  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1170
  Node* j_xor = cmp1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1171
  if( cmp2_type == TypeInt::ZERO &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1172
      cmp1_op == Op_XorI &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1173
      j_xor->in(1) != j_xor &&          // An xor of itself is dead
9966
b30a5eb9bcff 6956668: misbehavior of XOR operator (^) with int
kvn
parents: 9439
diff changeset
  1174
      phase->type( j_xor->in(1) ) == TypeInt::BOOL &&
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1175
      phase->type( j_xor->in(2) ) == TypeInt::ONE &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1176
      (_test._test == BoolTest::eq ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1177
       _test._test == BoolTest::ne) ) {
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
  1178
    Node *ncmp = phase->transform(new (phase->C) CmpINode(j_xor->in(1),cmp2));
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
  1179
    return new (phase->C) BoolNode( ncmp, _test.negate() );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1180
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1181
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1182
  // Change "bool eq/ne (cmp (Conv2B X) 0)" into "bool eq/ne (cmp X 0)".
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1183
  // This is a standard idiom for branching on a boolean value.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1184
  Node *c2b = cmp1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1185
  if( cmp2_type == TypeInt::ZERO &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1186
      cmp1_op == Op_Conv2B &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1187
      (_test._test == BoolTest::eq ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1188
       _test._test == BoolTest::ne) ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1189
    Node *ncmp = phase->transform(phase->type(c2b->in(1))->isa_int()
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
  1190
       ? (Node*)new (phase->C) CmpINode(c2b->in(1),cmp2)
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
  1191
       : (Node*)new (phase->C) CmpPNode(c2b->in(1),phase->makecon(TypePtr::NULL_PTR))
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1192
    );
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
  1193
    return new (phase->C) BoolNode( ncmp, _test._test );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1194
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1195
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1196
  // Comparing a SubI against a zero is equal to comparing the SubI
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1197
  // arguments directly.  This only works for eq and ne comparisons
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1198
  // due to possible integer overflow.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1199
  if ((_test._test == BoolTest::eq || _test._test == BoolTest::ne) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1200
        (cop == Op_CmpI) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1201
        (cmp1->Opcode() == Op_SubI) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1202
        ( cmp2_type == TypeInt::ZERO ) ) {
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
  1203
    Node *ncmp = phase->transform( new (phase->C) CmpINode(cmp1->in(1),cmp1->in(2)));
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
  1204
    return new (phase->C) BoolNode( ncmp, _test._test );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1205
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1206
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1207
  // Change (-A vs 0) into (A vs 0) by commuting the test.  Disallow in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1208
  // most general case because negating 0x80000000 does nothing.  Needed for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1209
  // the CmpF3/SubI/CmpI idiom.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1210
  if( cop == Op_CmpI &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1211
      cmp1->Opcode() == Op_SubI &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1212
      cmp2_type == TypeInt::ZERO &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1213
      phase->type( cmp1->in(1) ) == TypeInt::ZERO &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1214
      phase->type( cmp1->in(2) )->higher_equal(TypeInt::SYMINT) ) {
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
  1215
    Node *ncmp = phase->transform( new (phase->C) CmpINode(cmp1->in(2),cmp2));
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13728
diff changeset
  1216
    return new (phase->C) BoolNode( ncmp, _test.commute() );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1217
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1218
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1219
  //  The transformation below is not valid for either signed or unsigned
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1220
  //  comparisons due to wraparound concerns at MAX_VALUE and MIN_VALUE.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1221
  //  This transformation can be resurrected when we are able to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1222
  //  make inferences about the range of values being subtracted from
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1223
  //  (or added to) relative to the wraparound point.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1224
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1225
  //    // Remove +/-1's if possible.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1226
  //    // "X <= Y-1" becomes "X <  Y"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1227
  //    // "X+1 <= Y" becomes "X <  Y"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1228
  //    // "X <  Y+1" becomes "X <= Y"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1229
  //    // "X-1 <  Y" becomes "X <= Y"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1230
  //    // Do not this to compares off of the counted-loop-end.  These guys are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1231
  //    // checking the trip counter and they want to use the post-incremented
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1232
  //    // counter.  If they use the PRE-incremented counter, then the counter has
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1233
  //    // to be incremented in a private block on a loop backedge.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1234
  //    if( du && du->cnt(this) && du->out(this)[0]->Opcode() == Op_CountedLoopEnd )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1235
  //      return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1236
  //  #ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1237
  //    // Do not do this in a wash GVN pass during verification.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1238
  //    // Gets triggered by too many simple optimizations to be bothered with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1239
  //    // re-trying it again and again.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1240
  //    if( !phase->allow_progress() ) return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1241
  //  #endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1242
  //    // Not valid for unsigned compare because of corner cases in involving zero.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1243
  //    // For example, replacing "X-1 <u Y" with "X <=u Y" fails to throw an
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1244
  //    // exception in case X is 0 (because 0-1 turns into 4billion unsigned but
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1245
  //    // "0 <=u Y" is always true).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1246
  //    if( cmp->Opcode() == Op_CmpU ) return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1247
  //    int cmp2_op = cmp2->Opcode();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1248
  //    if( _test._test == BoolTest::le ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1249
  //      if( cmp1_op == Op_AddI &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1250
  //          phase->type( cmp1->in(2) ) == TypeInt::ONE )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1251
  //        return clone_cmp( cmp, cmp1->in(1), cmp2, phase, BoolTest::lt );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1252
  //      else if( cmp2_op == Op_AddI &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1253
  //         phase->type( cmp2->in(2) ) == TypeInt::MINUS_1 )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1254
  //        return clone_cmp( cmp, cmp1, cmp2->in(1), phase, BoolTest::lt );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1255
  //    } else if( _test._test == BoolTest::lt ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1256
  //      if( cmp1_op == Op_AddI &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1257
  //          phase->type( cmp1->in(2) ) == TypeInt::MINUS_1 )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1258
  //        return clone_cmp( cmp, cmp1->in(1), cmp2, phase, BoolTest::le );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1259
  //      else if( cmp2_op == Op_AddI &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1260
  //         phase->type( cmp2->in(2) ) == TypeInt::ONE )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1261
  //        return clone_cmp( cmp, cmp1, cmp2->in(1), phase, BoolTest::le );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1262
  //    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1263
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1264
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1265
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1266
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1267
//------------------------------Value------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1268
// Simplify a Bool (convert condition codes to boolean (1 or 0)) node,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1269
// based on local information.   If the input is constant, do it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1270
const Type *BoolNode::Value( PhaseTransform *phase ) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1271
  return _test.cc2logical( phase->type( in(1) ) );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1272
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1273
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1274
//------------------------------dump_spec--------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1275
// Dump special per-node info
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1276
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1277
void BoolNode::dump_spec(outputStream *st) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1278
  st->print("[");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1279
  _test.dump_on(st);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1280
  st->print("]");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1281
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1282
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1283
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1284
//------------------------------is_counted_loop_exit_test--------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1285
// Returns true if node is used by a counted loop node.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1286
bool BoolNode::is_counted_loop_exit_test() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1287
  for( DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++ ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1288
    Node* use = fast_out(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1289
    if (use->is_CountedLoopEnd()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1290
      return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1291
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1292
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1293
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1294
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1295
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1296
//=============================================================================
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1297
//------------------------------Value------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1298
// Compute sqrt
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1299
const Type *SqrtDNode::Value( PhaseTransform *phase ) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1300
  const Type *t1 = phase->type( in(1) );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1301
  if( t1 == Type::TOP ) return Type::TOP;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1302
  if( t1->base() != Type::DoubleCon ) return Type::DOUBLE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1303
  double d = t1->getd();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1304
  if( d < 0.0 ) return Type::DOUBLE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1305
  return TypeD::make( sqrt( d ) );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1306
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1307
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1308
//=============================================================================
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1309
//------------------------------Value------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1310
// Compute cos
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1311
const Type *CosDNode::Value( PhaseTransform *phase ) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1312
  const Type *t1 = phase->type( in(1) );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1313
  if( t1 == Type::TOP ) return Type::TOP;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1314
  if( t1->base() != Type::DoubleCon ) return Type::DOUBLE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1315
  double d = t1->getd();
4645
0c5f5b94e93a 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 3261
diff changeset
  1316
  return TypeD::make( StubRoutines::intrinsic_cos( d ) );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1317
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1318
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1319
//=============================================================================
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1320
//------------------------------Value------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1321
// Compute sin
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1322
const Type *SinDNode::Value( PhaseTransform *phase ) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1323
  const Type *t1 = phase->type( in(1) );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1324
  if( t1 == Type::TOP ) return Type::TOP;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1325
  if( t1->base() != Type::DoubleCon ) return Type::DOUBLE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1326
  double d = t1->getd();
4645
0c5f5b94e93a 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 3261
diff changeset
  1327
  return TypeD::make( StubRoutines::intrinsic_sin( d ) );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1328
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1329
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1330
//=============================================================================
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1331
//------------------------------Value------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1332
// Compute tan
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1333
const Type *TanDNode::Value( PhaseTransform *phase ) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1334
  const Type *t1 = phase->type( in(1) );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1335
  if( t1 == Type::TOP ) return Type::TOP;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1336
  if( t1->base() != Type::DoubleCon ) return Type::DOUBLE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1337
  double d = t1->getd();
4645
0c5f5b94e93a 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 3261
diff changeset
  1338
  return TypeD::make( StubRoutines::intrinsic_tan( d ) );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1339
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1340
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1341
//=============================================================================
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1342
//------------------------------Value------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1343
// Compute log
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1344
const Type *LogDNode::Value( PhaseTransform *phase ) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1345
  const Type *t1 = phase->type( in(1) );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1346
  if( t1 == Type::TOP ) return Type::TOP;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1347
  if( t1->base() != Type::DoubleCon ) return Type::DOUBLE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1348
  double d = t1->getd();
4645
0c5f5b94e93a 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 3261
diff changeset
  1349
  return TypeD::make( StubRoutines::intrinsic_log( d ) );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1350
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1351
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1352
//=============================================================================
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1353
//------------------------------Value------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1354
// Compute log10
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1355
const Type *Log10DNode::Value( PhaseTransform *phase ) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1356
  const Type *t1 = phase->type( in(1) );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1357
  if( t1 == Type::TOP ) return Type::TOP;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1358
  if( t1->base() != Type::DoubleCon ) return Type::DOUBLE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1359
  double d = t1->getd();
4645
0c5f5b94e93a 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 3261
diff changeset
  1360
  return TypeD::make( StubRoutines::intrinsic_log10( d ) );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1361
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1362
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1363
//=============================================================================
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1364
//------------------------------Value------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1365
// Compute exp
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1366
const Type *ExpDNode::Value( PhaseTransform *phase ) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1367
  const Type *t1 = phase->type( in(1) );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1368
  if( t1 == Type::TOP ) return Type::TOP;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1369
  if( t1->base() != Type::DoubleCon ) return Type::DOUBLE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1370
  double d = t1->getd();
4645
0c5f5b94e93a 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 3261
diff changeset
  1371
  return TypeD::make( StubRoutines::intrinsic_exp( d ) );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1372
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1373
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1374
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1375
//=============================================================================
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1376
//------------------------------Value------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1377
// Compute pow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1378
const Type *PowDNode::Value( PhaseTransform *phase ) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1379
  const Type *t1 = phase->type( in(1) );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1380
  if( t1 == Type::TOP ) return Type::TOP;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1381
  if( t1->base() != Type::DoubleCon ) return Type::DOUBLE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1382
  const Type *t2 = phase->type( in(2) );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1383
  if( t2 == Type::TOP ) return Type::TOP;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1384
  if( t2->base() != Type::DoubleCon ) return Type::DOUBLE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1385
  double d1 = t1->getd();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1386
  double d2 = t2->getd();
4645
0c5f5b94e93a 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 3261
diff changeset
  1387
  return TypeD::make( StubRoutines::intrinsic_pow( d1, d2 ) );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1388
}