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