multnode.cpp revision 8168:f5fae6f265e2
112032Speter/*
212032Speter * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
312032Speter * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
412032Speter *
512032Speter * This code is free software; you can redistribute it and/or modify it
612032Speter * under the terms of the GNU General Public License version 2 only, as
712032Speter * published by the Free Software Foundation.
812032Speter *
912032Speter * This code is distributed in the hope that it will be useful, but WITHOUT
1012032Speter * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1112032Speter * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1212032Speter * version 2 for more details (a copy is included in the LICENSE file that
1312032Speter * accompanied this code).
1412032Speter *
1512032Speter * You should have received a copy of the GNU General Public License version
1612032Speter * 2 along with this work; if not, write to the Free Software Foundation,
1712032Speter * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1812032Speter *
1912032Speter * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2012032Speter * or visit www.oracle.com if you need additional information or have any
2112032Speter * questions.
2212032Speter *
2312032Speter */
2412032Speter
2512032Speter#include "precompiled.hpp"
2612032Speter#include "opto/callnode.hpp"
2712032Speter#include "opto/cfgnode.hpp"
2812032Speter#include "opto/matcher.hpp"
2912032Speter#include "opto/mathexactnode.hpp"
3012032Speter#include "opto/multnode.hpp"
3112032Speter#include "opto/opcodes.hpp"
3212032Speter#include "opto/phaseX.hpp"
3330262Scharnier#include "opto/regmask.hpp"
3450479Speter#include "opto/type.hpp"
3512032Speter
3612032Speter//=============================================================================
3712032Speter//------------------------------MultiNode--------------------------------------
3812032Speterconst RegMask &MultiNode::out_RegMask() const {
3912032Speter  return RegMask::Empty;
4012032Speter}
4112032Speter
4212032SpeterNode *MultiNode::match( const ProjNode *proj, const Matcher *m ) { return proj->clone(); }
4312032Speter
4430262Scharnier//------------------------------proj_out---------------------------------------
4530262Scharnier// Get a named projection
4674071SpsProjNode* MultiNode::proj_out(uint which_proj) const {
4730262Scharnier  assert(Opcode() != Op_If || which_proj == (uint)true || which_proj == (uint)false, "must be 1 or 0");
4869793Sobrien  assert(Opcode() != Op_If || outcnt() == 2, "bad if #1");
4930262Scharnier  for( DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++ ) {
5012032Speter    Node *p = fast_out(i);
5112032Speter    if (p->is_Proj()) {
5212032Speter      ProjNode *proj = p->as_Proj();
5330262Scharnier      if (proj->_con == which_proj) {
5412032Speter        assert(Opcode() != Op_If || proj->Opcode() == (which_proj?Op_IfTrue:Op_IfFalse), "bad if #2");
5512032Speter        return proj;
5612032Speter      }
5712032Speter    } else {
5812032Speter      assert(p == this && this->is_Start(), "else must be proj");
5930262Scharnier      continue;
6012032Speter    }
6112032Speter  }
6212032Speter  return NULL;
6312032Speter}
6412032Speter
6512032Speter//=============================================================================
6612032Speter//------------------------------ProjNode---------------------------------------
6712032Speteruint ProjNode::hash() const {
6812032Speter  // only one input
6912032Speter  return (uintptr_t)in(TypeFunc::Control) + (_con << 1) + (_is_io_use ? 1 : 0);
7012032Speter}
7141727Sdillonuint ProjNode::cmp( const Node &n ) const { return _con == ((ProjNode&)n)._con && ((ProjNode&)n)._is_io_use == _is_io_use; }
7241727Sdillonuint ProjNode::size_of() const { return sizeof(ProjNode); }
7341727Sdillon
7412032Speter// Test if we propagate interesting control along this projection
7512032Speterbool ProjNode::is_CFG() const {
7612032Speter  Node *def = in(0);
7712032Speter  return (_con == TypeFunc::Control && def->is_CFG());
7841727Sdillon}
7912032Speter
8012032Speterconst Type* ProjNode::proj_type(const Type* t) const {
8112032Speter  if (t == Type::TOP) {
8212032Speter    return Type::TOP;
8312032Speter  }
8430262Scharnier  if (t == Type::BOTTOM) {
8530262Scharnier    return Type::BOTTOM;
8612032Speter  }
8712032Speter  t = t->is_tuple()->field_at(_con);
8812032Speter  Node* n = in(0);
8912032Speter  if ((_con == TypeFunc::Parms) &&
9012032Speter      n->is_CallStaticJava() && n->as_CallStaticJava()->is_boxing_method()) {
9112032Speter    // The result of autoboxing is always non-null on normal path.
9212032Speter    t = t->join_speculative(TypePtr::NOTNULL);
9312032Speter  }
9412032Speter  return t;
9512032Speter}
9612032Speter
9712032Speterconst Type *ProjNode::bottom_type() const {
9812032Speter  if (in(0) == NULL) return Type::TOP;
9912032Speter  return proj_type(in(0)->bottom_type());
10012032Speter}
10112032Speter
10230262Scharnierconst TypePtr *ProjNode::adr_type() const {
10330262Scharnier  if (bottom_type() == Type::MEMORY) {
10412032Speter    // in(0) might be a narrow MemBar; otherwise we will report TypePtr::BOTTOM
10528160Sjkh    Node* ctrl = in(0);
10630262Scharnier    if (ctrl == NULL)  return NULL; // node is dead
10730262Scharnier    const TypePtr* adr_type = ctrl->adr_type();
10812032Speter    #ifdef ASSERT
10912032Speter    if (!is_error_reported() && !Node::in_dump())
11012032Speter      assert(adr_type != NULL, "source must have adr_type");
11112032Speter    #endif
11212032Speter    return adr_type;
11312032Speter  }
11412032Speter  assert(bottom_type()->base() != Type::Memory, "no other memories?");
11512032Speter  return NULL;
11612032Speter}
11712032Speter
11812032Speterbool ProjNode::pinned() const { return in(0)->pinned(); }
11930262Scharnier#ifndef PRODUCT
12012032Spetervoid ProjNode::dump_spec(outputStream *st) const { st->print("#%d",_con); if(_is_io_use) st->print(" (i_o_use)");}
12112032Speter#endif
12212032Speter
12312032Speter//----------------------------check_con----------------------------------------
12412032Spetervoid ProjNode::check_con() const {
12512032Speter  Node* n = in(0);
12612032Speter  if (n == NULL)       return;  // should be assert, but NodeHash makes bogons
12712032Speter  if (n->is_Mach())    return;  // mach. projs. are not type-safe
12812032Speter  if (n->is_Start())   return;  // alas, starts can have mach. projs. also
12912032Speter  if (_con == SCMemProjNode::SCMEMPROJCON ) return;
13012032Speter  const Type* t = n->bottom_type();
13112032Speter  if (t == Type::TOP)  return;  // multi is dead
13212032Speter  assert(_con < t->is_tuple()->cnt(), "ProjNode::_con must be in range");
13312032Speter}
13412032Speter
13512032Speter//------------------------------Value------------------------------------------
13612032Speterconst Type *ProjNode::Value( PhaseTransform *phase ) const {
13712032Speter  if (in(0) == NULL) return Type::TOP;
13812032Speter  return proj_type(phase->type(in(0)));
13912032Speter}
14012032Speter
14112032Speter//------------------------------out_RegMask------------------------------------
14212032Speter// Pass the buck uphill
14312032Speterconst RegMask &ProjNode::out_RegMask() const {
14412032Speter  return RegMask::Empty;
14512032Speter}
14612032Speter
14712032Speter//------------------------------ideal_reg--------------------------------------
14812032Speteruint ProjNode::ideal_reg() const {
14912032Speter  return bottom_type()->ideal_reg();
15012032Speter}
15112032Speter
15212032Speter//-------------------------------is_uncommon_trap_proj----------------------------
15330262Scharnier// Return uncommon trap call node if proj is for "proj->[region->..]call_uct"
15430262Scharnier// NULL otherwise
15512032SpeterCallStaticJavaNode* ProjNode::is_uncommon_trap_proj(Deoptimization::DeoptReason reason) {
15612032Speter  int path_limit = 10;
15712032Speter  Node* out = this;
15812032Speter  for (int ct = 0; ct < path_limit; ct++) {
15912032Speter    out = out->unique_ctrl_out();
16012032Speter    if (out == NULL)
16112032Speter      return NULL;
16212032Speter    if (out->is_CallStaticJava()) {
16312032Speter      CallStaticJavaNode* call = out->as_CallStaticJava();
16412032Speter      int req = call->uncommon_trap_request();
16512032Speter      if (req != 0) {
16612032Speter        Deoptimization::DeoptReason trap_reason = Deoptimization::trap_request_reason(req);
16712032Speter        if (trap_reason == reason || reason == Deoptimization::Reason_none) {
16812032Speter          return call;
16912032Speter        }
17012032Speter      }
17112032Speter      return NULL; // don't do further after call
17212032Speter    }
17312032Speter    if (out->Opcode() != Op_Region)
17412032Speter      return NULL;
17512032Speter  }
17612032Speter  return NULL;
17712032Speter}
17812032Speter
17912032Speter//-------------------------------is_uncommon_trap_if_pattern-------------------------
18012032Speter// Return uncommon trap call node for    "if(test)-> proj -> ...
18112032Speter//                                                 |
18212032Speter//                                                 V
18312032Speter//                                             other_proj->[region->..]call_uct"
18430262Scharnier// NULL otherwise
18530262Scharnier// "must_reason_predicate" means the uct reason must be Reason_predicate
18612032SpeterCallStaticJavaNode* ProjNode::is_uncommon_trap_if_pattern(Deoptimization::DeoptReason reason) {
18712032Speter  Node *in0 = in(0);
18812032Speter  if (!in0->is_If()) return NULL;
18912032Speter  // Variation of a dead If node.
19012032Speter  if (in0->outcnt() < 2)  return NULL;
19112032Speter  IfNode* iff = in0->as_If();
19212032Speter
19330262Scharnier  // we need "If(Conv2B(Opaque1(...)))" pattern for reason_predicate
19430262Scharnier  if (reason != Deoptimization::Reason_none) {
19512032Speter    if (iff->in(1)->Opcode() != Op_Conv2B ||
19612032Speter       iff->in(1)->in(1)->Opcode() != Op_Opaque1) {
19712032Speter      return NULL;
19812032Speter    }
19912032Speter  }
20012032Speter
20112032Speter  ProjNode* other_proj = iff->proj_out(1-_con);
20212032Speter  if (other_proj == NULL) // Should never happen, but make Parfait happy.
20330262Scharnier      return NULL;
20430262Scharnier  CallStaticJavaNode* call = other_proj->is_uncommon_trap_proj(reason);
20512032Speter  if (call != NULL) {
20612032Speter    assert(reason == Deoptimization::Reason_none ||
20712032Speter           Compile::current()->is_predicate_opaq(iff->in(1)->in(1)), "should be on the list");
20812032Speter    return call;
20912032Speter  }
21012032Speter  return NULL;
21112032Speter}
21230262Scharnier
21330262ScharnierProjNode* ProjNode::other_if_proj() const {
21412032Speter  assert(_con == 0 || _con == 1, "not an if?");
21512032Speter  return in(0)->as_If()->proj_out(1-_con);
21612032Speter}
21712032Speter