multnode.cpp revision 1472:c18cbe5936b8
14910Swollman/*
24910Swollman * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
34910Swollman * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44910Swollman *
54910Swollman * This code is free software; you can redistribute it and/or modify it
625944Sjoerg * under the terms of the GNU General Public License version 2 only, as
74910Swollman * published by the Free Software Foundation.
825944Sjoerg *
925944Sjoerg * This code is distributed in the hope that it will be useful, but WITHOUT
1025944Sjoerg * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
114910Swollman * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
124910Swollman * version 2 for more details (a copy is included in the LICENSE file that
134910Swollman * accompanied this code).
144910Swollman *
154910Swollman * You should have received a copy of the GNU General Public License version
164910Swollman * 2 along with this work; if not, write to the Free Software Foundation,
174910Swollman * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1825944Sjoerg *
1916288Sgpalmer * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2025944Sjoerg * or visit www.oracle.com if you need additional information or have any
214910Swollman * questions.
224910Swollman *
234910Swollman */
244952Sbde
254952Sbde#include "incls/_precompiled.incl"
2624204Sbde#include "incls/_multnode.cpp.incl"
274910Swollman
2825706Sjoerg//=============================================================================
294910Swollman//------------------------------MultiNode--------------------------------------
304910Swollmanconst RegMask &MultiNode::out_RegMask() const {
314910Swollman  return RegMask::Empty;
324910Swollman}
334910Swollman
344910SwollmanNode *MultiNode::match( const ProjNode *proj, const Matcher *m ) { return proj->clone(); }
354910Swollman
364910Swollman//------------------------------proj_out---------------------------------------
374910Swollman// Get a named projection
384910SwollmanProjNode* MultiNode::proj_out(uint which_proj) const {
394910Swollman  assert(Opcode() != Op_If || which_proj == (uint)true || which_proj == (uint)false, "must be 1 or 0");
404910Swollman  assert(Opcode() != Op_If || outcnt() == 2, "bad if #1");
414910Swollman  for( DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++ ) {
424910Swollman    Node *p = fast_out(i);
434910Swollman    if( !p->is_Proj() ) {
4411819Sjulian      assert(p == this && this->is_Start(), "else must be proj");
4511819Sjulian      continue;
4611819Sjulian    }
4711819Sjulian    ProjNode *proj = p->as_Proj();
4811819Sjulian    if( proj->_con == which_proj ) {
494910Swollman      assert(Opcode() != Op_If || proj->Opcode() == (which_proj?Op_IfTrue:Op_IfFalse), "bad if #2");
504910Swollman      return proj;
514910Swollman    }
524910Swollman  }
534910Swollman  return NULL;
544910Swollman}
554910Swollman
564910Swollman//=============================================================================
574910Swollman//------------------------------ProjNode---------------------------------------
584910Swollmanuint ProjNode::hash() const {
594910Swollman  // only one input
604910Swollman  return (uintptr_t)in(TypeFunc::Control) + (_con << 1) + (_is_io_use ? 1 : 0);
614910Swollman}
624910Swollmanuint ProjNode::cmp( const Node &n ) const { return _con == ((ProjNode&)n)._con && ((ProjNode&)n)._is_io_use == _is_io_use; }
634910Swollmanuint ProjNode::size_of() const { return sizeof(ProjNode); }
644910Swollman
6525944Sjoerg// Test if we propagate interesting control along this projection
6625944Sjoergbool ProjNode::is_CFG() const {
6725944Sjoerg  Node *def = in(0);
6825944Sjoerg  return (_con == TypeFunc::Control && def->is_CFG());
6925944Sjoerg}
7025944Sjoerg
7125944Sjoergconst Type *ProjNode::bottom_type() const {
7225944Sjoerg  if (in(0) == NULL)  return Type::TOP;
7325944Sjoerg  const Type *tb = in(0)->bottom_type();
7425944Sjoerg  if( tb == Type::TOP ) return Type::TOP;
7525944Sjoerg  if( tb == Type::BOTTOM ) return Type::BOTTOM;
7625944Sjoerg  const TypeTuple *t = tb->is_tuple();
7725944Sjoerg  return t->field_at(_con);
7825944Sjoerg}
7925944Sjoerg
804910Swollmanconst TypePtr *ProjNode::adr_type() const {
814910Swollman  if (bottom_type() == Type::MEMORY) {
824910Swollman    // in(0) might be a narrow MemBar; otherwise we will report TypePtr::BOTTOM
834910Swollman    const TypePtr* adr_type = in(0)->adr_type();
844910Swollman    #ifdef ASSERT
8512495Speter    if (!is_error_reported() && !Node::in_dump())
864910Swollman      assert(adr_type != NULL, "source must have adr_type");
874910Swollman    #endif
884910Swollman    return adr_type;
8925944Sjoerg  }
9025944Sjoerg  assert(bottom_type()->base() != Type::Memory, "no other memories?");
9125944Sjoerg  return NULL;
9225944Sjoerg}
9325944Sjoerg
9425944Sjoergbool ProjNode::pinned() const { return in(0)->pinned(); }
9525944Sjoerg#ifndef PRODUCT
9625944Sjoergvoid ProjNode::dump_spec(outputStream *st) const { st->print("#%d",_con); if(_is_io_use) st->print(" (i_o_use)");}
9725944Sjoerg#endif
9825944Sjoerg
9925944Sjoerg//----------------------------check_con----------------------------------------
1004910Swollmanvoid ProjNode::check_con() const {
1014910Swollman  Node* n = in(0);
1024910Swollman  if (n == NULL)       return;  // should be assert, but NodeHash makes bogons
1034910Swollman  if (n->is_Mach())    return;  // mach. projs. are not type-safe
1044910Swollman  if (n->is_Start())   return;  // alas, starts can have mach. projs. also
1054910Swollman  if (_con == SCMemProjNode::SCMEMPROJCON ) return;
1064910Swollman  const Type* t = n->bottom_type();
1074910Swollman  if (t == Type::TOP)  return;  // multi is dead
1084910Swollman  assert(_con < t->is_tuple()->cnt(), "ProjNode::_con must be in range");
1094910Swollman}
11025944Sjoerg
11125944Sjoerg//------------------------------Value------------------------------------------
11225944Sjoergconst Type *ProjNode::Value( PhaseTransform *phase ) const {
1134910Swollman  if( !in(0) ) return Type::TOP;
1144910Swollman  const Type *t = phase->type(in(0));
1154910Swollman  if( t == Type::TOP ) return t;
1164910Swollman  if( t == Type::BOTTOM ) return t;
1174910Swollman  return t->is_tuple()->field_at(_con);
1184910Swollman}
1194910Swollman
1204910Swollman//------------------------------out_RegMask------------------------------------
12125944Sjoerg// Pass the buck uphill
12225944Sjoergconst RegMask &ProjNode::out_RegMask() const {
12325944Sjoerg  return RegMask::Empty;
12425944Sjoerg}
12525944Sjoerg
12625944Sjoerg//------------------------------ideal_reg--------------------------------------
12725944Sjoerguint ProjNode::ideal_reg() const {
12825944Sjoerg  return Matcher::base2reg[bottom_type()->base()];
12925944Sjoerg}
13025944Sjoerg