connode.cpp revision 995:ddd6f1182ae3
1218799Snwhitehorn/* 2218799Snwhitehorn * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. 3218799Snwhitehorn * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4218799Snwhitehorn * 5218799Snwhitehorn * This code is free software; you can redistribute it and/or modify it 6218799Snwhitehorn * under the terms of the GNU General Public License version 2 only, as 7218799Snwhitehorn * published by the Free Software Foundation. 8218799Snwhitehorn * 9218799Snwhitehorn * This code is distributed in the hope that it will be useful, but WITHOUT 10218799Snwhitehorn * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11218799Snwhitehorn * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12218799Snwhitehorn * version 2 for more details (a copy is included in the LICENSE file that 13218799Snwhitehorn * accompanied this code). 14218799Snwhitehorn * 15218799Snwhitehorn * You should have received a copy of the GNU General Public License version 16218799Snwhitehorn * 2 along with this work; if not, write to the Free Software Foundation, 17218799Snwhitehorn * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18218799Snwhitehorn * 19218799Snwhitehorn * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 20218799Snwhitehorn * CA 95054 USA or visit www.sun.com if you need additional information or 21218799Snwhitehorn * have any questions. 22218799Snwhitehorn * 23218799Snwhitehorn */ 24218799Snwhitehorn 25218799Snwhitehorn// Optimization - Graph Style 26218799Snwhitehorn 27218799Snwhitehorn#include "incls/_precompiled.incl" 28218799Snwhitehorn#include "incls/_connode.cpp.incl" 29218799Snwhitehorn 30271539Snwhitehorn//============================================================================= 31218799Snwhitehorn//------------------------------hash------------------------------------------- 32218799Snwhitehornuint ConNode::hash() const { 33218799Snwhitehorn return (uintptr_t)in(TypeFunc::Control) + _type->hash(); 34218799Snwhitehorn} 35218799Snwhitehorn 36218799Snwhitehorn//------------------------------make------------------------------------------- 37218799SnwhitehornConNode *ConNode::make( Compile* C, const Type *t ) { 38218799Snwhitehorn switch( t->basic_type() ) { 39218799Snwhitehorn case T_INT: return new (C, 1) ConINode( t->is_int() ); 40218799Snwhitehorn case T_LONG: return new (C, 1) ConLNode( t->is_long() ); 41218799Snwhitehorn case T_FLOAT: return new (C, 1) ConFNode( t->is_float_constant() ); 42218799Snwhitehorn case T_DOUBLE: return new (C, 1) ConDNode( t->is_double_constant() ); 43218799Snwhitehorn case T_VOID: return new (C, 1) ConNode ( Type::TOP ); 44218799Snwhitehorn case T_OBJECT: return new (C, 1) ConPNode( t->is_oopptr() ); 45218799Snwhitehorn case T_ARRAY: return new (C, 1) ConPNode( t->is_aryptr() ); 46218799Snwhitehorn case T_ADDRESS: return new (C, 1) ConPNode( t->is_ptr() ); 47218799Snwhitehorn case T_NARROWOOP: return new (C, 1) ConNNode( t->is_narrowoop() ); 48218799Snwhitehorn // Expected cases: TypePtr::NULL_PTR, any is_rawptr() 49218799Snwhitehorn // Also seen: AnyPtr(TopPTR *+top); from command line: 50218799Snwhitehorn // r -XX:+PrintOpto -XX:CIStart=285 -XX:+CompileTheWorld -XX:CompileTheWorldStartAt=660 51218799Snwhitehorn // %%%% Stop using TypePtr::NULL_PTR to represent nulls: use either TypeRawPtr::NULL_PTR 52218799Snwhitehorn // or else TypeOopPtr::NULL_PTR. Then set Type::_basic_type[AnyPtr] = T_ILLEGAL 53218799Snwhitehorn } 54218799Snwhitehorn ShouldNotReachHere(); 55218799Snwhitehorn return NULL; 56218799Snwhitehorn} 57218799Snwhitehorn 58218799Snwhitehorn//============================================================================= 59218799Snwhitehorn/* 60218799SnwhitehornThe major change is for CMoveP and StrComp. They have related but slightly 61218799Snwhitehorndifferent problems. They both take in TWO oops which are both null-checked 62218799Snwhitehornindependently before the using Node. After CCP removes the CastPP's they need 63218799Snwhitehornto pick up the guarding test edge - in this case TWO control edges. I tried 64218799Snwhitehornvarious solutions, all have problems: 65218799Snwhitehorn 66218799Snwhitehorn(1) Do nothing. This leads to a bug where we hoist a Load from a CMoveP or a 67218799SnwhitehornStrComp above a guarding null check. I've seen both cases in normal -Xcomp 68218799Snwhitehorntesting. 69218853Snwhitehorn 70218853Snwhitehorn(2) Plug the control edge from 1 of the 2 oops in. Apparent problem here is 71218853Snwhitehornto figure out which test post-dominates. The real problem is that it doesn't 72218853Snwhitehornmatter which one you pick. After you pick up, the dominating-test elider in 73218853SnwhitehornIGVN can remove the test and allow you to hoist up to the dominating test on 74218853Snwhitehornthe chosen oop bypassing the test on the not-chosen oop. Seen in testing. 75218853SnwhitehornOops. 76218853Snwhitehorn 77218853Snwhitehorn(3) Leave the CastPP's in. This makes the graph more accurate in some sense; 78218853Snwhitehornwe get to keep around the knowledge that an oop is not-null after some test. 79218853SnwhitehornAlas, the CastPP's interfere with GVN (some values are the regular oop, some 80218853Snwhitehornare the CastPP of the oop, all merge at Phi's which cannot collapse, etc). 81218853SnwhitehornThis cost us 10% on SpecJVM, even when I removed some of the more trivial 82219892Snwhitehorncases in the optimizer. Removing more useless Phi's started allowing Loads to 83219892Snwhitehornillegally float above null checks. I gave up on this approach. 84219892Snwhitehorn 85219892Snwhitehorn(4) Add BOTH control edges to both tests. Alas, too much code knows that 86219892Snwhitehorncontrol edges are in slot-zero ONLY. Many quick asserts fail; no way to do 87219892Snwhitehornthis one. Note that I really want to allow the CMoveP to float and add both 88219892Snwhitehorncontrol edges to the dependent Load op - meaning I can select early but I 89219892Snwhitehorncannot Load until I pass both tests. 90219892Snwhitehorn 91219892Snwhitehorn(5) Do not hoist CMoveP and StrComp. To this end I added the v-call 92219892Snwhitehorndepends_only_on_test(). No obvious performance loss on Spec, but we are 93219892Snwhitehornclearly conservative on CMoveP (also so on StrComp but that's unlikely to 94219892Snwhitehornmatter ever). 95219892Snwhitehorn 96219892Snwhitehorn*/ 97219892Snwhitehorn 98219892Snwhitehorn 99219892Snwhitehorn//------------------------------Ideal------------------------------------------ 100219892Snwhitehorn// Return a node which is more "ideal" than the current node. 101219892Snwhitehorn// Move constants to the right. 102219892SnwhitehornNode *CMoveNode::Ideal(PhaseGVN *phase, bool can_reshape) { 103219892Snwhitehorn if( in(0) && remove_dead_region(phase, can_reshape) ) return this; 104219892Snwhitehorn // Don't bother trying to transform a dead node 105219892Snwhitehorn if( in(0) && in(0)->is_top() ) return NULL; 106219892Snwhitehorn assert( !phase->eqv(in(Condition), this) && 107219892Snwhitehorn !phase->eqv(in(IfFalse), this) && 108219892Snwhitehorn !phase->eqv(in(IfTrue), this), "dead loop in CMoveNode::Ideal" ); 109219892Snwhitehorn if( phase->type(in(Condition)) == Type::TOP ) 110219892Snwhitehorn return NULL; // return NULL when Condition is dead 111219892Snwhitehorn 112219892Snwhitehorn if( in(IfFalse)->is_Con() && !in(IfTrue)->is_Con() ) { 113219892Snwhitehorn if( in(Condition)->is_Bool() ) { 114219892Snwhitehorn BoolNode* b = in(Condition)->as_Bool(); 115219892Snwhitehorn BoolNode* b2 = b->negate(phase); 116219892Snwhitehorn return make( phase->C, in(Control), phase->transform(b2), in(IfTrue), in(IfFalse), _type ); 117219892Snwhitehorn } 118219892Snwhitehorn } 119219892Snwhitehorn return NULL; 120219892Snwhitehorn} 121219892Snwhitehorn 122219892Snwhitehorn//------------------------------is_cmove_id------------------------------------ 123271539Snwhitehorn// Helper function to check for CMOVE identity. Shared with PhiNode::Identity 124271539SnwhitehornNode *CMoveNode::is_cmove_id( PhaseTransform *phase, Node *cmp, Node *t, Node *f, BoolNode *b ) { 125271539Snwhitehorn // Check for Cmp'ing and CMove'ing same values 126271539Snwhitehorn if( (phase->eqv(cmp->in(1),f) && 127271539Snwhitehorn phase->eqv(cmp->in(2),t)) || 128271539Snwhitehorn // Swapped Cmp is OK 129271539Snwhitehorn (phase->eqv(cmp->in(2),f) && 130271539Snwhitehorn phase->eqv(cmp->in(1),t)) ) { 131271539Snwhitehorn // Give up this identity check for floating points because it may choose incorrect 132271539Snwhitehorn // value around 0.0 and -0.0 133271539Snwhitehorn if ( cmp->Opcode()==Op_CmpF || cmp->Opcode()==Op_CmpD ) 134271539Snwhitehorn return NULL; 135271539Snwhitehorn // Check for "(t==f)?t:f;" and replace with "f" 136271539Snwhitehorn if( b->_test._test == BoolTest::eq ) 137271539Snwhitehorn return f; 138271539Snwhitehorn // Allow the inverted case as well 139271539Snwhitehorn // Check for "(t!=f)?t:f;" and replace with "t" 140271539Snwhitehorn if( b->_test._test == BoolTest::ne ) 141271539Snwhitehorn return t; 142271539Snwhitehorn } 143271539Snwhitehorn return NULL; 144271539Snwhitehorn} 145271539Snwhitehorn 146271539Snwhitehorn//------------------------------Identity--------------------------------------- 147271539Snwhitehorn// Conditional-move is an identity if both inputs are the same, or the test 148271539Snwhitehorn// true or false. 149271539SnwhitehornNode *CMoveNode::Identity( PhaseTransform *phase ) { 150271539Snwhitehorn if( phase->eqv(in(IfFalse),in(IfTrue)) ) // C-moving identical inputs? 151271539Snwhitehorn return in(IfFalse); // Then it doesn't matter 152271539Snwhitehorn if( phase->type(in(Condition)) == TypeInt::ZERO ) 153271539Snwhitehorn return in(IfFalse); // Always pick left(false) input 154271539Snwhitehorn if( phase->type(in(Condition)) == TypeInt::ONE ) 155271539Snwhitehorn return in(IfTrue); // Always pick right(true) input 156271539Snwhitehorn 157271539Snwhitehorn // Check for CMove'ing a constant after comparing against the constant. 158271539Snwhitehorn // Happens all the time now, since if we compare equality vs a constant in 159271539Snwhitehorn // the parser, we "know" the variable is constant on one path and we force 160271539Snwhitehorn // it. Thus code like "if( x==0 ) {/*EMPTY*/}" ends up inserting a 161271539Snwhitehorn // conditional move: "x = (x==0)?0:x;". Yucko. This fix is slightly more 162271539Snwhitehorn // general in that we don't need constants. 163271539Snwhitehorn if( in(Condition)->is_Bool() ) { 164271539Snwhitehorn BoolNode *b = in(Condition)->as_Bool(); 165271539Snwhitehorn Node *cmp = b->in(1); 166271539Snwhitehorn if( cmp->is_Cmp() ) { 167271539Snwhitehorn Node *id = is_cmove_id( phase, cmp, in(IfTrue), in(IfFalse), b ); 168271539Snwhitehorn if( id ) return id; 169271539Snwhitehorn } 170219892Snwhitehorn } 171219892Snwhitehorn 172219892Snwhitehorn return this; 173219892Snwhitehorn} 174219892Snwhitehorn 175219892Snwhitehorn//------------------------------Value------------------------------------------ 176219892Snwhitehorn// Result is the meet of inputs 177219892Snwhitehornconst Type *CMoveNode::Value( PhaseTransform *phase ) const { 178219892Snwhitehorn if( phase->type(in(Condition)) == Type::TOP ) 179219892Snwhitehorn return Type::TOP; 180219892Snwhitehorn return phase->type(in(IfFalse))->meet(phase->type(in(IfTrue))); 181219892Snwhitehorn} 182219892Snwhitehorn 183219892Snwhitehorn//------------------------------make------------------------------------------- 184219892Snwhitehorn// Make a correctly-flavored CMove. Since _type is directly determined 185219892Snwhitehorn// from the inputs we do not need to specify it here. 186219892SnwhitehornCMoveNode *CMoveNode::make( Compile *C, Node *c, Node *bol, Node *left, Node *right, const Type *t ) { 187219892Snwhitehorn switch( t->basic_type() ) { 188219892Snwhitehorn case T_INT: return new (C, 4) CMoveINode( bol, left, right, t->is_int() ); 189219892Snwhitehorn case T_FLOAT: return new (C, 4) CMoveFNode( bol, left, right, t ); 190219892Snwhitehorn case T_DOUBLE: return new (C, 4) CMoveDNode( bol, left, right, t ); 191219892Snwhitehorn case T_LONG: return new (C, 4) CMoveLNode( bol, left, right, t->is_long() ); 192219892Snwhitehorn case T_OBJECT: return new (C, 4) CMovePNode( c, bol, left, right, t->is_oopptr() ); 193219892Snwhitehorn case T_ADDRESS: return new (C, 4) CMovePNode( c, bol, left, right, t->is_ptr() ); 194219892Snwhitehorn case T_NARROWOOP: return new (C, 4) CMoveNNode( c, bol, left, right, t ); 195219892Snwhitehorn default: 196219892Snwhitehorn ShouldNotReachHere(); 197219892Snwhitehorn return NULL; 198233904Snwhitehorn } 199219892Snwhitehorn} 200219892Snwhitehorn 201219892Snwhitehorn//============================================================================= 202219892Snwhitehorn//------------------------------Ideal------------------------------------------ 203219892Snwhitehorn// Return a node which is more "ideal" than the current node. 204219892Snwhitehorn// Check for conversions to boolean 205219892SnwhitehornNode *CMoveINode::Ideal(PhaseGVN *phase, bool can_reshape) { 206219892Snwhitehorn // Try generic ideal's first 207219892Snwhitehorn Node *x = CMoveNode::Ideal(phase, can_reshape); 208219892Snwhitehorn if( x ) return x; 209285679Sallanjude 210285679Sallanjude // If zero is on the left (false-case, no-move-case) it must mean another 211218799Snwhitehorn // constant is on the right (otherwise the shared CMove::Ideal code would 212218799Snwhitehorn // have moved the constant to the right). This situation is bad for Intel 213285679Sallanjude // and a don't-care for Sparc. It's bad for Intel because the zero has to 214218799Snwhitehorn // be manifested in a register with a XOR which kills flags, which are live 215218799Snwhitehorn // on input to the CMoveI, leading to a situation which causes excessive 216218799Snwhitehorn // spilling on Intel. For Sparc, if the zero in on the left the Sparc will 217218799Snwhitehorn // zero a register via G0 and conditionally-move the other constant. If the 218218799Snwhitehorn // zero is on the right, the Sparc will load the first constant with a 219218799Snwhitehorn // 13-bit set-lo and conditionally move G0. See bug 4677505. 220218799Snwhitehorn if( phase->type(in(IfFalse)) == TypeInt::ZERO && !(phase->type(in(IfTrue)) == TypeInt::ZERO) ) { 221302025Swma if( in(Condition)->is_Bool() ) { 222218799Snwhitehorn BoolNode* b = in(Condition)->as_Bool(); 223218799Snwhitehorn BoolNode* b2 = b->negate(phase); 224218799Snwhitehorn return make( phase->C, in(Control), phase->transform(b2), in(IfTrue), in(IfFalse), _type ); 225218799Snwhitehorn } 226218799Snwhitehorn } 227218799Snwhitehorn 228218799Snwhitehorn // Now check for booleans 229218799Snwhitehorn int flip = 0; 230285679Sallanjude 231285679Sallanjude // Check for picking from zero/one 232285679Sallanjude if( phase->type(in(IfFalse)) == TypeInt::ZERO && phase->type(in(IfTrue)) == TypeInt::ONE ) { 233285679Sallanjude flip = 1 - flip; 234285679Sallanjude } else if( phase->type(in(IfFalse)) == TypeInt::ONE && phase->type(in(IfTrue)) == TypeInt::ZERO ) { 235285679Sallanjude } else return NULL; 236285679Sallanjude 237285679Sallanjude // Check for eq/ne test 238285679Sallanjude if( !in(1)->is_Bool() ) return NULL; 239285679Sallanjude BoolNode *bol = in(1)->as_Bool(); 240285679Sallanjude if( bol->_test._test == BoolTest::eq ) { 241285679Sallanjude } else if( bol->_test._test == BoolTest::ne ) { 242285679Sallanjude flip = 1-flip; 243285679Sallanjude } else return NULL; 244285679Sallanjude 245285679Sallanjude // Check for vs 0 or 1 246285679Sallanjude if( !bol->in(1)->is_Cmp() ) return NULL; 247285679Sallanjude const CmpNode *cmp = bol->in(1)->as_Cmp(); 248285679Sallanjude if( phase->type(cmp->in(2)) == TypeInt::ZERO ) { 249285679Sallanjude } else if( phase->type(cmp->in(2)) == TypeInt::ONE ) { 250285679Sallanjude // Allow cmp-vs-1 if the other input is bounded by 0-1 251285679Sallanjude if( phase->type(cmp->in(1)) != TypeInt::BOOL ) 252285679Sallanjude return NULL; 253285679Sallanjude flip = 1 - flip; 254285679Sallanjude } else return NULL; 255285679Sallanjude 256285679Sallanjude // Convert to a bool (flipped) 257285679Sallanjude // Build int->bool conversion 258285679Sallanjude#ifndef PRODUCT 259285679Sallanjude if( PrintOpto ) tty->print_cr("CMOV to I2B"); 260285679Sallanjude#endif 261285679Sallanjude Node *n = new (phase->C, 2) Conv2BNode( cmp->in(1) ); 262285679Sallanjude if( flip ) 263285679Sallanjude n = new (phase->C, 3) XorINode( phase->transform(n), phase->intcon(1) ); 264218799Snwhitehorn 265218799Snwhitehorn return n; 266285679Sallanjude} 267218799Snwhitehorn 268285679Sallanjude//============================================================================= 269218799Snwhitehorn//------------------------------Ideal------------------------------------------ 270218799Snwhitehorn// Return a node which is more "ideal" than the current node. 271285679Sallanjude// Check for absolute value 272218799SnwhitehornNode *CMoveFNode::Ideal(PhaseGVN *phase, bool can_reshape) { 273218799Snwhitehorn // Try generic ideal's first 274218799Snwhitehorn Node *x = CMoveNode::Ideal(phase, can_reshape); 275285679Sallanjude if( x ) return x; 276218799Snwhitehorn 277218799Snwhitehorn int cmp_zero_idx = 0; // Index of compare input where to look for zero 278218799Snwhitehorn int phi_x_idx = 0; // Index of phi input where to find naked x 279285679Sallanjude 280285679Sallanjude // Find the Bool 281285679Sallanjude if( !in(1)->is_Bool() ) return NULL; 282218799Snwhitehorn BoolNode *bol = in(1)->as_Bool(); 283285679Sallanjude // Check bool sense 284218799Snwhitehorn switch( bol->_test._test ) { 285218799Snwhitehorn case BoolTest::lt: cmp_zero_idx = 1; phi_x_idx = IfTrue; break; 286218799Snwhitehorn case BoolTest::le: cmp_zero_idx = 2; phi_x_idx = IfFalse; break; 287218799Snwhitehorn case BoolTest::gt: cmp_zero_idx = 2; phi_x_idx = IfTrue; break; 288218799Snwhitehorn case BoolTest::ge: cmp_zero_idx = 1; phi_x_idx = IfFalse; break; 289218799Snwhitehorn default: return NULL; break; 290218799Snwhitehorn } 291218799Snwhitehorn 292218799Snwhitehorn // Find zero input of CmpF; the other input is being abs'd 293218799Snwhitehorn Node *cmpf = bol->in(1); 294218799Snwhitehorn if( cmpf->Opcode() != Op_CmpF ) return NULL; 295218799Snwhitehorn Node *X = NULL; 296218799Snwhitehorn bool flip = false; 297218799Snwhitehorn if( phase->type(cmpf->in(cmp_zero_idx)) == TypeF::ZERO ) { 298218799Snwhitehorn X = cmpf->in(3 - cmp_zero_idx); 299218799Snwhitehorn } else if (phase->type(cmpf->in(3 - cmp_zero_idx)) == TypeF::ZERO) { 300218799Snwhitehorn // The test is inverted, we should invert the result... 301218799Snwhitehorn X = cmpf->in(cmp_zero_idx); 302218799Snwhitehorn flip = true; 303218799Snwhitehorn } else { 304218799Snwhitehorn return NULL; 305218799Snwhitehorn } 306218799Snwhitehorn 307218799Snwhitehorn // If X is found on the appropriate phi input, find the subtract on the other 308218799Snwhitehorn if( X != in(phi_x_idx) ) return NULL; 309218799Snwhitehorn int phi_sub_idx = phi_x_idx == IfTrue ? IfFalse : IfTrue; 310218799Snwhitehorn Node *sub = in(phi_sub_idx); 311218799Snwhitehorn 312218799Snwhitehorn // Allow only SubF(0,X) and fail out for all others; NegF is not OK 313218799Snwhitehorn if( sub->Opcode() != Op_SubF || 314218799Snwhitehorn sub->in(2) != X || 315218799Snwhitehorn phase->type(sub->in(1)) != TypeF::ZERO ) return NULL; 316218799Snwhitehorn 317218799Snwhitehorn Node *abs = new (phase->C, 2) AbsFNode( X ); 318218799Snwhitehorn if( flip ) 319218799Snwhitehorn abs = new (phase->C, 3) SubFNode(sub->in(1), phase->transform(abs)); 320218799Snwhitehorn 321218799Snwhitehorn return abs; 322218799Snwhitehorn} 323218799Snwhitehorn 324218799Snwhitehorn//============================================================================= 325218799Snwhitehorn//------------------------------Ideal------------------------------------------ 326218799Snwhitehorn// Return a node which is more "ideal" than the current node. 327218799Snwhitehorn// Check for absolute value 328218799SnwhitehornNode *CMoveDNode::Ideal(PhaseGVN *phase, bool can_reshape) { 329218799Snwhitehorn // Try generic ideal's first 330218799Snwhitehorn Node *x = CMoveNode::Ideal(phase, can_reshape); 331218799Snwhitehorn if( x ) return x; 332218799Snwhitehorn 333218799Snwhitehorn int cmp_zero_idx = 0; // Index of compare input where to look for zero 334218799Snwhitehorn int phi_x_idx = 0; // Index of phi input where to find naked x 335218799Snwhitehorn 336218799Snwhitehorn // Find the Bool 337218799Snwhitehorn if( !in(1)->is_Bool() ) return NULL; 338218799Snwhitehorn BoolNode *bol = in(1)->as_Bool(); 339218799Snwhitehorn // Check bool sense 340218799Snwhitehorn switch( bol->_test._test ) { 341218799Snwhitehorn case BoolTest::lt: cmp_zero_idx = 1; phi_x_idx = IfTrue; break; 342218799Snwhitehorn case BoolTest::le: cmp_zero_idx = 2; phi_x_idx = IfFalse; break; 343218799Snwhitehorn case BoolTest::gt: cmp_zero_idx = 2; phi_x_idx = IfTrue; break; 344218799Snwhitehorn case BoolTest::ge: cmp_zero_idx = 1; phi_x_idx = IfFalse; break; 345218799Snwhitehorn default: return NULL; break; 346218799Snwhitehorn } 347218799Snwhitehorn 348218799Snwhitehorn // Find zero input of CmpD; the other input is being abs'd 349218799Snwhitehorn Node *cmpd = bol->in(1); 350218799Snwhitehorn if( cmpd->Opcode() != Op_CmpD ) return NULL; 351218799Snwhitehorn Node *X = NULL; 352218799Snwhitehorn bool flip = false; 353218799Snwhitehorn if( phase->type(cmpd->in(cmp_zero_idx)) == TypeD::ZERO ) { 354218799Snwhitehorn X = cmpd->in(3 - cmp_zero_idx); 355285679Sallanjude } else if (phase->type(cmpd->in(3 - cmp_zero_idx)) == TypeD::ZERO) { 356285679Sallanjude // The test is inverted, we should invert the result... 357285679Sallanjude X = cmpd->in(cmp_zero_idx); 358285679Sallanjude flip = true; 359285679Sallanjude } else { 360285679Sallanjude return NULL; 361285679Sallanjude } 362285679Sallanjude 363285679Sallanjude // If X is found on the appropriate phi input, find the subtract on the other 364285679Sallanjude if( X != in(phi_x_idx) ) return NULL; 365285679Sallanjude int phi_sub_idx = phi_x_idx == IfTrue ? IfFalse : IfTrue; 366285679Sallanjude Node *sub = in(phi_sub_idx); 367285679Sallanjude 368285679Sallanjude // Allow only SubD(0,X) and fail out for all others; NegD is not OK 369285679Sallanjude if( sub->Opcode() != Op_SubD || 370285679Sallanjude sub->in(2) != X || 371285679Sallanjude phase->type(sub->in(1)) != TypeD::ZERO ) return NULL; 372285679Sallanjude 373285679Sallanjude Node *abs = new (phase->C, 2) AbsDNode( X ); 374285679Sallanjude if( flip ) 375218799Snwhitehorn abs = new (phase->C, 3) SubDNode(sub->in(1), phase->transform(abs)); 376218799Snwhitehorn 377218799Snwhitehorn return abs; 378218799Snwhitehorn} 379218799Snwhitehorn 380218799Snwhitehorn 381218799Snwhitehorn//============================================================================= 382218799Snwhitehorn// If input is already higher or equal to cast type, then this is an identity. 383218799SnwhitehornNode *ConstraintCastNode::Identity( PhaseTransform *phase ) { 384218799Snwhitehorn return phase->type(in(1))->higher_equal(_type) ? in(1) : this; 385218799Snwhitehorn} 386218799Snwhitehorn 387218799Snwhitehorn//------------------------------Value------------------------------------------ 388218799Snwhitehorn// Take 'join' of input and cast-up type 389218799Snwhitehornconst Type *ConstraintCastNode::Value( PhaseTransform *phase ) const { 390218799Snwhitehorn if( in(0) && phase->type(in(0)) == Type::TOP ) return Type::TOP; 391218799Snwhitehorn const Type* ft = phase->type(in(1))->filter(_type); 392218799Snwhitehorn 393218799Snwhitehorn#ifdef ASSERT 394218799Snwhitehorn // Previous versions of this function had some special case logic, 395218799Snwhitehorn // which is no longer necessary. Make sure of the required effects. 396218799Snwhitehorn switch (Opcode()) { 397218799Snwhitehorn case Op_CastII: 398218799Snwhitehorn { 399218799Snwhitehorn const Type* t1 = phase->type(in(1)); 400218799Snwhitehorn if( t1 == Type::TOP ) assert(ft == Type::TOP, "special case #1"); 401218799Snwhitehorn const Type* rt = t1->join(_type); 402228048Skevlo if (rt->empty()) assert(ft == Type::TOP, "special case #2"); 403218799Snwhitehorn break; 404218799Snwhitehorn } 405218799Snwhitehorn case Op_CastPP: 406218799Snwhitehorn if (phase->type(in(1)) == TypePtr::NULL_PTR && 407218799Snwhitehorn _type->isa_ptr() && _type->is_ptr()->_ptr == TypePtr::NotNull) 408218799Snwhitehorn assert(ft == Type::TOP, "special case #3"); 409218799Snwhitehorn break; 410218799Snwhitehorn } 411218799Snwhitehorn#endif //ASSERT 412218799Snwhitehorn 413218799Snwhitehorn return ft; 414218799Snwhitehorn} 415218799Snwhitehorn 416218799Snwhitehorn//------------------------------Ideal------------------------------------------ 417218799Snwhitehorn// Return a node which is more "ideal" than the current node. Strip out 418218799Snwhitehorn// control copies 419218799SnwhitehornNode *ConstraintCastNode::Ideal(PhaseGVN *phase, bool can_reshape){ 420218799Snwhitehorn return (in(0) && remove_dead_region(phase, can_reshape)) ? this : NULL; 421218799Snwhitehorn} 422218799Snwhitehorn 423218799Snwhitehorn//------------------------------Ideal_DU_postCCP------------------------------- 424218799Snwhitehorn// Throw away cast after constant propagation 425218799SnwhitehornNode *ConstraintCastNode::Ideal_DU_postCCP( PhaseCCP *ccp ) { 426218799Snwhitehorn const Type *t = ccp->type(in(1)); 427218799Snwhitehorn ccp->hash_delete(this); 428218799Snwhitehorn set_type(t); // Turn into ID function 429218799Snwhitehorn ccp->hash_insert(this); 430271539Snwhitehorn return this; 431218799Snwhitehorn} 432218799Snwhitehorn 433218799Snwhitehorn 434218799Snwhitehorn//============================================================================= 435218799Snwhitehorn 436218799Snwhitehorn//------------------------------Ideal_DU_postCCP------------------------------- 437218799Snwhitehorn// If not converting int->oop, throw away cast after constant propagation 438218799SnwhitehornNode *CastPPNode::Ideal_DU_postCCP( PhaseCCP *ccp ) { 439218799Snwhitehorn const Type *t = ccp->type(in(1)); 440218799Snwhitehorn if (!t->isa_oop_ptr() || (in(1)->is_DecodeN() && Universe::narrow_oop_use_implicit_null_checks())) { 441218799Snwhitehorn return NULL; // do not transform raw pointers or narrow oops 442218799Snwhitehorn } 443218799Snwhitehorn return ConstraintCastNode::Ideal_DU_postCCP(ccp); 444218799Snwhitehorn} 445271539Snwhitehorn 446218799Snwhitehorn 447218799Snwhitehorn 448218799Snwhitehorn//============================================================================= 449218799Snwhitehorn//------------------------------Identity--------------------------------------- 450218799Snwhitehorn// If input is already higher or equal to cast type, then this is an identity. 451218799SnwhitehornNode *CheckCastPPNode::Identity( PhaseTransform *phase ) { 452218799Snwhitehorn // Toned down to rescue meeting at a Phi 3 different oops all implementing 453218799Snwhitehorn // the same interface. CompileTheWorld starting at 502, kd12rc1.zip. 454218799Snwhitehorn return (phase->type(in(1)) == phase->type(this)) ? in(1) : this; 455218799Snwhitehorn} 456218799Snwhitehorn 457271539Snwhitehorn// Determine whether "n" is a node which can cause an alias of one of its inputs. Node types 458218799Snwhitehorn// which can create aliases are: CheckCastPP, Phi, and any store (if there is also a load from 459218799Snwhitehorn// the location.) 460218799Snwhitehorn// Note: this checks for aliases created in this compilation, not ones which may 461218799Snwhitehorn// be potentially created at call sites. 462218799Snwhitehornstatic bool can_cause_alias(Node *n, PhaseTransform *phase) { 463218799Snwhitehorn bool possible_alias = false; 464218799Snwhitehorn 465218799Snwhitehorn if (n->is_Store()) { 466226083Snwhitehorn possible_alias = !n->as_Store()->value_never_loaded(phase); 467218799Snwhitehorn } else { 468226083Snwhitehorn int opc = n->Opcode(); 469218799Snwhitehorn possible_alias = n->is_Phi() || 470218799Snwhitehorn opc == Op_CheckCastPP || 471226083Snwhitehorn opc == Op_StorePConditional || 472218799Snwhitehorn opc == Op_CompareAndSwapP || 473226083Snwhitehorn opc == Op_CompareAndSwapN; 474218799Snwhitehorn } 475218799Snwhitehorn return possible_alias; 476218799Snwhitehorn} 477226083Snwhitehorn 478226083Snwhitehorn//------------------------------Value------------------------------------------ 479226083Snwhitehorn// Take 'join' of input and cast-up type, unless working with an Interface 480226083Snwhitehornconst Type *CheckCastPPNode::Value( PhaseTransform *phase ) const { 481226083Snwhitehorn if( in(0) && phase->type(in(0)) == Type::TOP ) return Type::TOP; 482226083Snwhitehorn 483226083Snwhitehorn const Type *inn = phase->type(in(1)); 484226083Snwhitehorn if( inn == Type::TOP ) return Type::TOP; // No information yet 485218799Snwhitehorn 486218799Snwhitehorn const TypePtr *in_type = inn->isa_ptr(); 487218799Snwhitehorn const TypePtr *my_type = _type->isa_ptr(); 488218799Snwhitehorn const Type *result = _type; 489218799Snwhitehorn if( in_type != NULL && my_type != NULL ) { 490226083Snwhitehorn TypePtr::PTR in_ptr = in_type->ptr(); 491218799Snwhitehorn if( in_ptr == TypePtr::Null ) { 492218799Snwhitehorn result = in_type; 493226666Snwhitehorn } else if( in_ptr == TypePtr::Constant ) { 494226666Snwhitehorn // Casting a constant oop to an interface? 495226666Snwhitehorn // (i.e., a String to a Comparable?) 496226666Snwhitehorn // Then return the interface. 497226666Snwhitehorn const TypeOopPtr *jptr = my_type->isa_oopptr(); 498226666Snwhitehorn assert( jptr, "" ); 499226666Snwhitehorn result = (jptr->klass()->is_interface() || !in_type->higher_equal(_type)) 500226666Snwhitehorn ? my_type->cast_to_ptr_type( TypePtr::NotNull ) 501218799Snwhitehorn : in_type; 502218799Snwhitehorn } else { 503218799Snwhitehorn result = my_type->cast_to_ptr_type( my_type->join_ptr(in_ptr) ); 504218799Snwhitehorn } 505218799Snwhitehorn } 506218799Snwhitehorn return result; 507218799Snwhitehorn 508218799Snwhitehorn // JOIN NOT DONE HERE BECAUSE OF INTERFACE ISSUES. 509218799Snwhitehorn // FIX THIS (DO THE JOIN) WHEN UNION TYPES APPEAR! 510218799Snwhitehorn 511218799Snwhitehorn // 512218799Snwhitehorn // Remove this code after overnight run indicates no performance 513218799Snwhitehorn // loss from not performing JOIN at CheckCastPPNode 514218799Snwhitehorn // 515218799Snwhitehorn // const TypeInstPtr *in_oop = in->isa_instptr(); 516218799Snwhitehorn // const TypeInstPtr *my_oop = _type->isa_instptr(); 517271539Snwhitehorn // // If either input is an 'interface', return destination type 518218799Snwhitehorn // assert (in_oop == NULL || in_oop->klass() != NULL, ""); 519218799Snwhitehorn // assert (my_oop == NULL || my_oop->klass() != NULL, ""); 520218799Snwhitehorn // if( (in_oop && in_oop->klass()->klass_part()->is_interface()) 521218799Snwhitehorn // ||(my_oop && my_oop->klass()->klass_part()->is_interface()) ) { 522218799Snwhitehorn // TypePtr::PTR in_ptr = in->isa_ptr() ? in->is_ptr()->_ptr : TypePtr::BotPTR; 523218799Snwhitehorn // // Preserve cast away nullness for interfaces 524271539Snwhitehorn // if( in_ptr == TypePtr::NotNull && my_oop && my_oop->_ptr == TypePtr::BotPTR ) { 525271539Snwhitehorn // return my_oop->cast_to_ptr_type(TypePtr::NotNull); 526218799Snwhitehorn // } 527218799Snwhitehorn // return _type; 528218799Snwhitehorn // } 529218799Snwhitehorn // 530218799Snwhitehorn // // Neither the input nor the destination type is an interface, 531218799Snwhitehorn // 532218799Snwhitehorn // // history: JOIN used to cause weird corner case bugs 533218799Snwhitehorn // // return (in == TypeOopPtr::NULL_PTR) ? in : _type; 534218799Snwhitehorn // // JOIN picks up NotNull in common instance-of/check-cast idioms, both oops. 535218799Snwhitehorn // // JOIN does not preserve NotNull in other cases, e.g. RawPtr vs InstPtr 536218799Snwhitehorn // const Type *join = in->join(_type); 537218799Snwhitehorn // // Check if join preserved NotNull'ness for pointers 538218799Snwhitehorn // if( join->isa_ptr() && _type->isa_ptr() ) { 539218799Snwhitehorn // TypePtr::PTR join_ptr = join->is_ptr()->_ptr; 540218799Snwhitehorn // TypePtr::PTR type_ptr = _type->is_ptr()->_ptr; 541218799Snwhitehorn // // If there isn't any NotNull'ness to preserve 542218799Snwhitehorn // // OR if join preserved NotNull'ness then return it 543218799Snwhitehorn // if( type_ptr == TypePtr::BotPTR || type_ptr == TypePtr::Null || 544226083Snwhitehorn // join_ptr == TypePtr::NotNull || join_ptr == TypePtr::Constant ) { 545226083Snwhitehorn // return join; 546226083Snwhitehorn // } 547226083Snwhitehorn // // ELSE return same old type as before 548226083Snwhitehorn // return _type; 549226083Snwhitehorn // } 550226083Snwhitehorn // // Not joining two pointers 551226083Snwhitehorn // return join; 552226083Snwhitehorn} 553226083Snwhitehorn 554218799Snwhitehorn//------------------------------Ideal------------------------------------------ 555226083Snwhitehorn// Return a node which is more "ideal" than the current node. Strip out 556218799Snwhitehorn// control copies 557226666SnwhitehornNode *CheckCastPPNode::Ideal(PhaseGVN *phase, bool can_reshape){ 558226666Snwhitehorn return (in(0) && remove_dead_region(phase, can_reshape)) ? this : NULL; 559226666Snwhitehorn} 560226666Snwhitehorn 561218799Snwhitehorn 562226083SnwhitehornNode* DecodeNNode::Identity(PhaseTransform* phase) { 563218799Snwhitehorn const Type *t = phase->type( in(1) ); 564218799Snwhitehorn if( t == Type::TOP ) return in(1); 565218799Snwhitehorn 566218799Snwhitehorn if (in(1)->is_EncodeP()) { 567218799Snwhitehorn // (DecodeN (EncodeP p)) -> p 568218799Snwhitehorn return in(1)->in(1); 569218799Snwhitehorn } 570218799Snwhitehorn return this; 571218799Snwhitehorn} 572218799Snwhitehorn 573218799Snwhitehornconst Type *DecodeNNode::Value( PhaseTransform *phase ) const { 574225066Snwhitehorn const Type *t = phase->type( in(1) ); 575218799Snwhitehorn if (t == Type::TOP) return Type::TOP; 576218799Snwhitehorn if (t == TypeNarrowOop::NULL_PTR) return TypePtr::NULL_PTR; 577218799Snwhitehorn 578218799Snwhitehorn assert(t->isa_narrowoop(), "only narrowoop here"); 579218799Snwhitehorn return t->make_ptr(); 580218799Snwhitehorn} 581218799Snwhitehorn 582218799SnwhitehornNode* EncodePNode::Identity(PhaseTransform* phase) { 583218799Snwhitehorn const Type *t = phase->type( in(1) ); 584218799Snwhitehorn if( t == Type::TOP ) return in(1); 585218853Snwhitehorn 586218799Snwhitehorn if (in(1)->is_DecodeN()) { 587218799Snwhitehorn // (EncodeP (DecodeN p)) -> p 588218799Snwhitehorn return in(1)->in(1); 589218799Snwhitehorn } 590218799Snwhitehorn return this; 591218799Snwhitehorn} 592218799Snwhitehorn 593218799Snwhitehornconst Type *EncodePNode::Value( PhaseTransform *phase ) const { 594218799Snwhitehorn const Type *t = phase->type( in(1) ); 595218799Snwhitehorn if (t == Type::TOP) return Type::TOP; 596218799Snwhitehorn if (t == TypePtr::NULL_PTR) return TypeNarrowOop::NULL_PTR; 597218799Snwhitehorn 598218799Snwhitehorn assert(t->isa_oopptr(), "only oopptr here"); 599218799Snwhitehorn return t->make_narrowoop(); 600218799Snwhitehorn} 601218799Snwhitehorn 602218799Snwhitehorn 603218799SnwhitehornNode *EncodePNode::Ideal_DU_postCCP( PhaseCCP *ccp ) { 604218799Snwhitehorn return MemNode::Ideal_common_DU_postCCP(ccp, this, in(1)); 605218799Snwhitehorn} 606218799Snwhitehorn 607218799Snwhitehorn//============================================================================= 608218799Snwhitehorn//------------------------------Identity--------------------------------------- 609218799SnwhitehornNode *Conv2BNode::Identity( PhaseTransform *phase ) { 610218799Snwhitehorn const Type *t = phase->type( in(1) ); 611218799Snwhitehorn if( t == Type::TOP ) return in(1); 612218799Snwhitehorn if( t == TypeInt::ZERO ) return in(1); 613218799Snwhitehorn if( t == TypeInt::ONE ) return in(1); 614218799Snwhitehorn if( t == TypeInt::BOOL ) return in(1); 615218799Snwhitehorn return this; 616218799Snwhitehorn} 617218799Snwhitehorn 618226666Snwhitehorn//------------------------------Value------------------------------------------ 619218799Snwhitehornconst Type *Conv2BNode::Value( PhaseTransform *phase ) const { 620218799Snwhitehorn const Type *t = phase->type( in(1) ); 621218799Snwhitehorn if( t == Type::TOP ) return Type::TOP; 622218799Snwhitehorn if( t == TypeInt::ZERO ) return TypeInt::ZERO; 623218799Snwhitehorn if( t == TypePtr::NULL_PTR ) return TypeInt::ZERO; 624218799Snwhitehorn const TypePtr *tp = t->isa_ptr(); 625218799Snwhitehorn if( tp != NULL ) { 626218799Snwhitehorn if( tp->ptr() == TypePtr::AnyNull ) return Type::TOP; 627218799Snwhitehorn if( tp->ptr() == TypePtr::Constant) return TypeInt::ONE; 628218799Snwhitehorn if (tp->ptr() == TypePtr::NotNull) return TypeInt::ONE; 629218799Snwhitehorn return TypeInt::BOOL; 630218799Snwhitehorn } 631218799Snwhitehorn if (t->base() != Type::Int) return TypeInt::BOOL; 632218799Snwhitehorn const TypeInt *ti = t->is_int(); 633218799Snwhitehorn if( ti->_hi < 0 || ti->_lo > 0 ) return TypeInt::ONE; 634218799Snwhitehorn return TypeInt::BOOL; 635218799Snwhitehorn} 636218799Snwhitehorn 637218799Snwhitehorn 638218799Snwhitehorn// The conversions operations are all Alpha sorted. Please keep it that way! 639218799Snwhitehorn//============================================================================= 640218799Snwhitehorn//------------------------------Value------------------------------------------ 641218799Snwhitehornconst Type *ConvD2FNode::Value( PhaseTransform *phase ) const { 642218799Snwhitehorn const Type *t = phase->type( in(1) ); 643218799Snwhitehorn if( t == Type::TOP ) return Type::TOP; 644219892Snwhitehorn if( t == Type::DOUBLE ) return Type::FLOAT; 645218799Snwhitehorn const TypeD *td = t->is_double_constant(); 646219892Snwhitehorn return TypeF::make( (float)td->getd() ); 647219892Snwhitehorn} 648218799Snwhitehorn 649226666Snwhitehorn//------------------------------Identity--------------------------------------- 650226666Snwhitehorn// Float's can be converted to doubles with no loss of bits. Hence 651226666Snwhitehorn// converting a float to a double and back to a float is a NOP. 652226666SnwhitehornNode *ConvD2FNode::Identity(PhaseTransform *phase) { 653226666Snwhitehorn return (in(1)->Opcode() == Op_ConvF2D) ? in(1)->in(1) : this; 654226666Snwhitehorn} 655226666Snwhitehorn 656218799Snwhitehorn//============================================================================= 657218799Snwhitehorn//------------------------------Value------------------------------------------ 658218799Snwhitehornconst Type *ConvD2INode::Value( PhaseTransform *phase ) const { 659218799Snwhitehorn const Type *t = phase->type( in(1) ); 660218799Snwhitehorn if( t == Type::TOP ) return Type::TOP; 661218799Snwhitehorn if( t == Type::DOUBLE ) return TypeInt::INT; 662218799Snwhitehorn const TypeD *td = t->is_double_constant(); 663219892Snwhitehorn return TypeInt::make( SharedRuntime::d2i( td->getd() ) ); 664218799Snwhitehorn} 665218799Snwhitehorn 666271539Snwhitehorn//------------------------------Ideal------------------------------------------ 667271539Snwhitehorn// If converting to an int type, skip any rounding nodes 668218799SnwhitehornNode *ConvD2INode::Ideal(PhaseGVN *phase, bool can_reshape) { 669218799Snwhitehorn if( in(1)->Opcode() == Op_RoundDouble ) 670218799Snwhitehorn set_req(1,in(1)->in(1)); 671218799Snwhitehorn return NULL; 672218799Snwhitehorn} 673218799Snwhitehorn 674218799Snwhitehorn//------------------------------Identity--------------------------------------- 675218799Snwhitehorn// Int's can be converted to doubles with no loss of bits. Hence 676218799Snwhitehorn// converting an integer to a double and back to an integer is a NOP. 677218799SnwhitehornNode *ConvD2INode::Identity(PhaseTransform *phase) { 678219892Snwhitehorn return (in(1)->Opcode() == Op_ConvI2D) ? in(1)->in(1) : this; 679219892Snwhitehorn} 680271539Snwhitehorn 681271539Snwhitehorn//============================================================================= 682271539Snwhitehorn//------------------------------Value------------------------------------------ 683271539Snwhitehornconst Type *ConvD2LNode::Value( PhaseTransform *phase ) const { 684271539Snwhitehorn const Type *t = phase->type( in(1) ); 685271539Snwhitehorn if( t == Type::TOP ) return Type::TOP; 686271539Snwhitehorn if( t == Type::DOUBLE ) return TypeLong::LONG; 687271539Snwhitehorn const TypeD *td = t->is_double_constant(); 688271539Snwhitehorn return TypeLong::make( SharedRuntime::d2l( td->getd() ) ); 689271539Snwhitehorn} 690271539Snwhitehorn 691271539Snwhitehorn//------------------------------Identity--------------------------------------- 692218799SnwhitehornNode *ConvD2LNode::Identity(PhaseTransform *phase) { 693218799Snwhitehorn // Remove ConvD2L->ConvL2D->ConvD2L sequences. 694218799Snwhitehorn if( in(1) ->Opcode() == Op_ConvL2D && 695218799Snwhitehorn in(1)->in(1)->Opcode() == Op_ConvD2L ) 696218799Snwhitehorn return in(1)->in(1); 697264978Snwhitehorn return this; 698218799Snwhitehorn} 699218799Snwhitehorn 700271539Snwhitehorn//------------------------------Ideal------------------------------------------ 701271539Snwhitehorn// If converting to an int type, skip any rounding nodes 702271539SnwhitehornNode *ConvD2LNode::Ideal(PhaseGVN *phase, bool can_reshape) { 703218799Snwhitehorn if( in(1)->Opcode() == Op_RoundDouble ) 704218799Snwhitehorn set_req(1,in(1)->in(1)); 705218799Snwhitehorn return NULL; 706218799Snwhitehorn} 707218799Snwhitehorn 708218799Snwhitehorn//============================================================================= 709218799Snwhitehorn//------------------------------Value------------------------------------------ 710218799Snwhitehornconst Type *ConvF2DNode::Value( PhaseTransform *phase ) const { 711218799Snwhitehorn const Type *t = phase->type( in(1) ); 712218799Snwhitehorn if( t == Type::TOP ) return Type::TOP; 713218799Snwhitehorn if( t == Type::FLOAT ) return Type::DOUBLE; 714218799Snwhitehorn const TypeF *tf = t->is_float_constant(); 715218799Snwhitehorn#ifndef IA64 716218799Snwhitehorn return TypeD::make( (double)tf->getf() ); 717218799Snwhitehorn#else 718218799Snwhitehorn float x = tf->getf(); 719218799Snwhitehorn return TypeD::make( (x == 0.0f) ? (double)x : (double)x + ia64_double_zero ); 720218799Snwhitehorn#endif 721218799Snwhitehorn} 722218799Snwhitehorn 723218799Snwhitehorn//============================================================================= 724218799Snwhitehorn//------------------------------Value------------------------------------------ 725271539Snwhitehornconst Type *ConvF2INode::Value( PhaseTransform *phase ) const { 726271539Snwhitehorn const Type *t = phase->type( in(1) ); 727271539Snwhitehorn if( t == Type::TOP ) return Type::TOP; 728271539Snwhitehorn if( t == Type::FLOAT ) return TypeInt::INT; 729271539Snwhitehorn const TypeF *tf = t->is_float_constant(); 730271539Snwhitehorn return TypeInt::make( SharedRuntime::f2i( tf->getf() ) ); 731271539Snwhitehorn} 732218799Snwhitehorn 733218799Snwhitehorn//------------------------------Identity--------------------------------------- 734219892SnwhitehornNode *ConvF2INode::Identity(PhaseTransform *phase) { 735218799Snwhitehorn // Remove ConvF2I->ConvI2F->ConvF2I sequences. 736219892Snwhitehorn if( in(1) ->Opcode() == Op_ConvI2F && 737219892Snwhitehorn in(1)->in(1)->Opcode() == Op_ConvF2I ) 738218799Snwhitehorn return in(1)->in(1); 739218799Snwhitehorn return this; 740218799Snwhitehorn} 741218799Snwhitehorn 742218799Snwhitehorn//------------------------------Ideal------------------------------------------ 743218799Snwhitehorn// If converting to an int type, skip any rounding nodes 744271539SnwhitehornNode *ConvF2INode::Ideal(PhaseGVN *phase, bool can_reshape) { 745271539Snwhitehorn if( in(1)->Opcode() == Op_RoundFloat ) 746271539Snwhitehorn set_req(1,in(1)->in(1)); 747271539Snwhitehorn return NULL; 748218799Snwhitehorn} 749218799Snwhitehorn 750218799Snwhitehorn//============================================================================= 751218799Snwhitehorn//------------------------------Value------------------------------------------ 752218799Snwhitehornconst Type *ConvF2LNode::Value( PhaseTransform *phase ) const { 753218799Snwhitehorn const Type *t = phase->type( in(1) ); 754218799Snwhitehorn if( t == Type::TOP ) return Type::TOP; 755218799Snwhitehorn if( t == Type::FLOAT ) return TypeLong::LONG; 756218799Snwhitehorn const TypeF *tf = t->is_float_constant(); 757218799Snwhitehorn return TypeLong::make( SharedRuntime::f2l( tf->getf() ) ); 758218799Snwhitehorn} 759218799Snwhitehorn 760271539Snwhitehorn//------------------------------Identity--------------------------------------- 761271539SnwhitehornNode *ConvF2LNode::Identity(PhaseTransform *phase) { 762271539Snwhitehorn // Remove ConvF2L->ConvL2F->ConvF2L sequences. 763218799Snwhitehorn if( in(1) ->Opcode() == Op_ConvL2F && 764218799Snwhitehorn in(1)->in(1)->Opcode() == Op_ConvF2L ) 765218799Snwhitehorn return in(1)->in(1); 766218799Snwhitehorn return this; 767218799Snwhitehorn} 768218799Snwhitehorn 769218799Snwhitehorn//------------------------------Ideal------------------------------------------ 770218799Snwhitehorn// If converting to an int type, skip any rounding nodes 771218799SnwhitehornNode *ConvF2LNode::Ideal(PhaseGVN *phase, bool can_reshape) { 772218799Snwhitehorn if( in(1)->Opcode() == Op_RoundFloat ) 773218799Snwhitehorn set_req(1,in(1)->in(1)); 774218799Snwhitehorn return NULL; 775218799Snwhitehorn} 776218799Snwhitehorn 777218799Snwhitehorn//============================================================================= 778218799Snwhitehorn//------------------------------Value------------------------------------------ 779218799Snwhitehornconst Type *ConvI2DNode::Value( PhaseTransform *phase ) const { 780218799Snwhitehorn const Type *t = phase->type( in(1) ); 781218799Snwhitehorn if( t == Type::TOP ) return Type::TOP; 782218799Snwhitehorn const TypeInt *ti = t->is_int(); 783218799Snwhitehorn if( ti->is_con() ) return TypeD::make( (double)ti->get_con() ); 784218799Snwhitehorn return bottom_type(); 785218799Snwhitehorn} 786218799Snwhitehorn 787218799Snwhitehorn//============================================================================= 788218799Snwhitehorn//------------------------------Value------------------------------------------ 789218799Snwhitehornconst Type *ConvI2FNode::Value( PhaseTransform *phase ) const { 790218799Snwhitehorn const Type *t = phase->type( in(1) ); 791218799Snwhitehorn if( t == Type::TOP ) return Type::TOP; 792218799Snwhitehorn const TypeInt *ti = t->is_int(); 793218799Snwhitehorn if( ti->is_con() ) return TypeF::make( (float)ti->get_con() ); 794218799Snwhitehorn return bottom_type(); 795218799Snwhitehorn} 796218799Snwhitehorn 797218799Snwhitehorn//------------------------------Identity--------------------------------------- 798304457SdesNode *ConvI2FNode::Identity(PhaseTransform *phase) { 799218799Snwhitehorn // Remove ConvI2F->ConvF2I->ConvI2F sequences. 800218799Snwhitehorn if( in(1) ->Opcode() == Op_ConvF2I && 801218799Snwhitehorn in(1)->in(1)->Opcode() == Op_ConvI2F ) 802218799Snwhitehorn return in(1)->in(1); 803218799Snwhitehorn return this; 804218799Snwhitehorn} 805218799Snwhitehorn 806218799Snwhitehorn//============================================================================= 807218799Snwhitehorn//------------------------------Value------------------------------------------ 808218799Snwhitehornconst Type *ConvI2LNode::Value( PhaseTransform *phase ) const { 809218799Snwhitehorn const Type *t = phase->type( in(1) ); 810218799Snwhitehorn if( t == Type::TOP ) return Type::TOP; 811218799Snwhitehorn const TypeInt *ti = t->is_int(); 812218799Snwhitehorn const Type* tl = TypeLong::make(ti->_lo, ti->_hi, ti->_widen); 813218799Snwhitehorn // Join my declared type against my incoming type. 814218799Snwhitehorn tl = tl->filter(_type); 815218799Snwhitehorn return tl; 816218799Snwhitehorn} 817218799Snwhitehorn 818218799Snwhitehorn#ifdef _LP64 819218799Snwhitehornstatic inline bool long_ranges_overlap(jlong lo1, jlong hi1, 820218799Snwhitehorn jlong lo2, jlong hi2) { 821218799Snwhitehorn // Two ranges overlap iff one range's low point falls in the other range. 822218799Snwhitehorn return (lo2 <= lo1 && lo1 <= hi2) || (lo1 <= lo2 && lo2 <= hi1); 823218799Snwhitehorn} 824218799Snwhitehorn#endif 825218799Snwhitehorn 826218799Snwhitehorn//------------------------------Ideal------------------------------------------ 827218799SnwhitehornNode *ConvI2LNode::Ideal(PhaseGVN *phase, bool can_reshape) { 828218799Snwhitehorn const TypeLong* this_type = this->type()->is_long(); 829218799Snwhitehorn Node* this_changed = NULL; 830218799Snwhitehorn 831218799Snwhitehorn // If _major_progress, then more loop optimizations follow. Do NOT 832218799Snwhitehorn // remove this node's type assertion until no more loop ops can happen. 833218799Snwhitehorn // The progress bit is set in the major loop optimizations THEN comes the 834218799Snwhitehorn // call to IterGVN and any chance of hitting this code. Cf. Opaque1Node. 835218799Snwhitehorn if (can_reshape && !phase->C->major_progress()) { 836218799Snwhitehorn const TypeInt* in_type = phase->type(in(1))->isa_int(); 837218799Snwhitehorn if (in_type != NULL && this_type != NULL && 838218799Snwhitehorn (in_type->_lo != this_type->_lo || 839218799Snwhitehorn in_type->_hi != this_type->_hi)) { 840218799Snwhitehorn // Although this WORSENS the type, it increases GVN opportunities, 841218799Snwhitehorn // because I2L nodes with the same input will common up, regardless 842218799Snwhitehorn // of slightly differing type assertions. Such slight differences 843218799Snwhitehorn // arise routinely as a result of loop unrolling, so this is a 844218799Snwhitehorn // post-unrolling graph cleanup. Choose a type which depends only 845218799Snwhitehorn // on my input. (Exception: Keep a range assertion of >=0 or <0.) 846218799Snwhitehorn jlong lo1 = this_type->_lo; 847218799Snwhitehorn jlong hi1 = this_type->_hi; 848218799Snwhitehorn int w1 = this_type->_widen; 849304457Sdes if (lo1 != (jint)lo1 || 850304457Sdes hi1 != (jint)hi1 || 851304457Sdes lo1 > hi1) { 852304457Sdes // Overflow leads to wraparound, wraparound leads to range saturation. 853304457Sdes lo1 = min_jint; hi1 = max_jint; 854304457Sdes } else if (lo1 >= 0) { 855304457Sdes // Keep a range assertion of >=0. 856304457Sdes lo1 = 0; hi1 = max_jint; 857304457Sdes } else if (hi1 < 0) { 858304457Sdes // Keep a range assertion of <0. 859304457Sdes lo1 = min_jint; hi1 = -1; 860304457Sdes } else { 861304457Sdes lo1 = min_jint; hi1 = max_jint; 862304457Sdes } 863304457Sdes const TypeLong* wtype = TypeLong::make(MAX2((jlong)in_type->_lo, lo1), 864304457Sdes MIN2((jlong)in_type->_hi, hi1), 865304457Sdes MAX2((int)in_type->_widen, w1)); 866304457Sdes if (wtype != type()) { 867304457Sdes set_type(wtype); 868218799Snwhitehorn // Note: this_type still has old type value, for the logic below. 869218799Snwhitehorn this_changed = this; 870218799Snwhitehorn } 871218799Snwhitehorn } 872218799Snwhitehorn } 873218799Snwhitehorn 874218799Snwhitehorn#ifdef _LP64 875218799Snwhitehorn // Convert ConvI2L(AddI(x, y)) to AddL(ConvI2L(x), ConvI2L(y)) , 876218799Snwhitehorn // but only if x and y have subranges that cannot cause 32-bit overflow, 877218799Snwhitehorn // under the assumption that x+y is in my own subrange this->type(). 878218799Snwhitehorn 879218799Snwhitehorn // This assumption is based on a constraint (i.e., type assertion) 880218799Snwhitehorn // established in Parse::array_addressing or perhaps elsewhere. 881218799Snwhitehorn // This constraint has been adjoined to the "natural" type of 882218799Snwhitehorn // the incoming argument in(0). We know (because of runtime 883218799Snwhitehorn // checks) - that the result value I2L(x+y) is in the joined range. 884218799Snwhitehorn // Hence we can restrict the incoming terms (x, y) to values such 885218799Snwhitehorn // that their sum also lands in that range. 886218799Snwhitehorn 887226161Snwhitehorn // This optimization is useful only on 64-bit systems, where we hope 888271539Snwhitehorn // the addition will end up subsumed in an addressing mode. 889218799Snwhitehorn // It is necessary to do this when optimizing an unrolled array 890218799Snwhitehorn // copy loop such as x[i++] = y[i++]. 891218799Snwhitehorn 892218799Snwhitehorn // On 32-bit systems, it's better to perform as much 32-bit math as 893218799Snwhitehorn // possible before the I2L conversion, because 32-bit math is cheaper. 894218799Snwhitehorn // There's no common reason to "leak" a constant offset through the I2L. 895218799Snwhitehorn // Addressing arithmetic will not absorb it as part of a 64-bit AddL. 896271539Snwhitehorn 897271539Snwhitehorn Node* z = in(1); 898218799Snwhitehorn int op = z->Opcode(); 899218799Snwhitehorn if (op == Op_AddI || op == Op_SubI) { 900218799Snwhitehorn Node* x = z->in(1); 901218799Snwhitehorn Node* y = z->in(2); 902218799Snwhitehorn assert (x != z && y != z, "dead loop in ConvI2LNode::Ideal"); 903218799Snwhitehorn if (phase->type(x) == Type::TOP) return this_changed; 904218799Snwhitehorn if (phase->type(y) == Type::TOP) return this_changed; 905218799Snwhitehorn const TypeInt* tx = phase->type(x)->is_int(); 906218799Snwhitehorn const TypeInt* ty = phase->type(y)->is_int(); 907218799Snwhitehorn const TypeLong* tz = this_type; 908218799Snwhitehorn jlong xlo = tx->_lo; 909218799Snwhitehorn jlong xhi = tx->_hi; 910218799Snwhitehorn jlong ylo = ty->_lo; 911218799Snwhitehorn jlong yhi = ty->_hi; 912218799Snwhitehorn jlong zlo = tz->_lo; 913218799Snwhitehorn jlong zhi = tz->_hi; 914218799Snwhitehorn jlong vbit = CONST64(1) << BitsPerInt; 915218799Snwhitehorn int widen = MAX2(tx->_widen, ty->_widen); 916218799Snwhitehorn if (op == Op_SubI) { 917218799Snwhitehorn jlong ylo0 = ylo; 918218799Snwhitehorn ylo = -yhi; 919218799Snwhitehorn yhi = -ylo0; 920218799Snwhitehorn } 921218799Snwhitehorn // See if x+y can cause positive overflow into z+2**32 922218799Snwhitehorn if (long_ranges_overlap(xlo+ylo, xhi+yhi, zlo+vbit, zhi+vbit)) { 923218799Snwhitehorn return this_changed; 924218799Snwhitehorn } 925218799Snwhitehorn // See if x+y can cause negative overflow into z-2**32 926218799Snwhitehorn if (long_ranges_overlap(xlo+ylo, xhi+yhi, zlo-vbit, zhi-vbit)) { 927218799Snwhitehorn return this_changed; 928218799Snwhitehorn } 929218799Snwhitehorn // Now it's always safe to assume x+y does not overflow. 930218799Snwhitehorn // This is true even if some pairs x,y might cause overflow, as long 931218799Snwhitehorn // as that overflow value cannot fall into [zlo,zhi]. 932218799Snwhitehorn 933218799Snwhitehorn // Confident that the arithmetic is "as if infinite precision", 934218799Snwhitehorn // we can now use z's range to put constraints on those of x and y. 935218799Snwhitehorn // The "natural" range of x [xlo,xhi] can perhaps be narrowed to a 936218799Snwhitehorn // more "restricted" range by intersecting [xlo,xhi] with the 937218799Snwhitehorn // range obtained by subtracting y's range from the asserted range 938218799Snwhitehorn // of the I2L conversion. Here's the interval arithmetic algebra: 939225066Snwhitehorn // x == z-y == [zlo,zhi]-[ylo,yhi] == [zlo,zhi]+[-yhi,-ylo] 940218799Snwhitehorn // => x in [zlo-yhi, zhi-ylo] 941218799Snwhitehorn // => x in [zlo-yhi, zhi-ylo] INTERSECT [xlo,xhi] 942218799Snwhitehorn // => x in [xlo MAX zlo-yhi, xhi MIN zhi-ylo] 943218799Snwhitehorn jlong rxlo = MAX2(xlo, zlo - yhi); 944218799Snwhitehorn jlong rxhi = MIN2(xhi, zhi - ylo); 945218799Snwhitehorn // And similarly, x changing place with y: 946218799Snwhitehorn jlong rylo = MAX2(ylo, zlo - xhi); 947218799Snwhitehorn jlong ryhi = MIN2(yhi, zhi - xlo); 948218799Snwhitehorn if (rxlo > rxhi || rylo > ryhi) { 949218799Snwhitehorn return this_changed; // x or y is dying; don't mess w/ it 950218799Snwhitehorn } 951218799Snwhitehorn if (op == Op_SubI) { 952218799Snwhitehorn jlong rylo0 = rylo; 953218799Snwhitehorn rylo = -ryhi; 954218799Snwhitehorn ryhi = -rylo0; 955218799Snwhitehorn } 956218799Snwhitehorn 957218799Snwhitehorn Node* cx = phase->transform( new (phase->C, 2) ConvI2LNode(x, TypeLong::make(rxlo, rxhi, widen)) ); 958218799Snwhitehorn Node* cy = phase->transform( new (phase->C, 2) ConvI2LNode(y, TypeLong::make(rylo, ryhi, widen)) ); 959218799Snwhitehorn switch (op) { 960218799Snwhitehorn case Op_AddI: return new (phase->C, 3) AddLNode(cx, cy); 961218799Snwhitehorn case Op_SubI: return new (phase->C, 3) SubLNode(cx, cy); 962218799Snwhitehorn default: ShouldNotReachHere(); 963218799Snwhitehorn } 964218799Snwhitehorn } 965218799Snwhitehorn#endif //_LP64 966218799Snwhitehorn 967218799Snwhitehorn return this_changed; 968225066Snwhitehorn} 969218799Snwhitehorn 970225066Snwhitehorn//============================================================================= 971225066Snwhitehorn//------------------------------Value------------------------------------------ 972218799Snwhitehornconst Type *ConvL2DNode::Value( PhaseTransform *phase ) const { 973218853Snwhitehorn const Type *t = phase->type( in(1) ); 974218799Snwhitehorn if( t == Type::TOP ) return Type::TOP; 975218799Snwhitehorn const TypeLong *tl = t->is_long(); 976218799Snwhitehorn if( tl->is_con() ) return TypeD::make( (double)tl->get_con() ); 977218799Snwhitehorn return bottom_type(); 978218799Snwhitehorn} 979218799Snwhitehorn 980218799Snwhitehorn//============================================================================= 981218799Snwhitehorn//------------------------------Value------------------------------------------ 982219892Snwhitehornconst Type *ConvL2FNode::Value( PhaseTransform *phase ) const { 983219892Snwhitehorn const Type *t = phase->type( in(1) ); 984219892Snwhitehorn if( t == Type::TOP ) return Type::TOP; 985219892Snwhitehorn const TypeLong *tl = t->is_long(); 986218799Snwhitehorn if( tl->is_con() ) return TypeF::make( (float)tl->get_con() ); 987218799Snwhitehorn return bottom_type(); 988219892Snwhitehorn} 989219892Snwhitehorn 990218799Snwhitehorn//============================================================================= 991218799Snwhitehorn//----------------------------Identity----------------------------------------- 992219892SnwhitehornNode *ConvL2INode::Identity( PhaseTransform *phase ) { 993219892Snwhitehorn // Convert L2I(I2L(x)) => x 994219892Snwhitehorn if (in(1)->Opcode() == Op_ConvI2L) return in(1)->in(1); 995219892Snwhitehorn return this; 996219892Snwhitehorn} 997218799Snwhitehorn 998219892Snwhitehorn//------------------------------Value------------------------------------------ 999219892Snwhitehornconst Type *ConvL2INode::Value( PhaseTransform *phase ) const { 1000219892Snwhitehorn const Type *t = phase->type( in(1) ); 1001219892Snwhitehorn if( t == Type::TOP ) return Type::TOP; 1002219892Snwhitehorn const TypeLong *tl = t->is_long(); 1003219892Snwhitehorn if (tl->is_con()) 1004218799Snwhitehorn // Easy case. 1005218799Snwhitehorn return TypeInt::make((jint)tl->get_con()); 1006219892Snwhitehorn return bottom_type(); 1007219892Snwhitehorn} 1008219892Snwhitehorn 1009219892Snwhitehorn//------------------------------Ideal------------------------------------------ 1010225613Snwhitehorn// Return a node which is more "ideal" than the current node. 1011219892Snwhitehorn// Blow off prior masking to int 1012219892SnwhitehornNode *ConvL2INode::Ideal(PhaseGVN *phase, bool can_reshape) { 1013219892Snwhitehorn Node *andl = in(1); 1014219892Snwhitehorn uint andl_op = andl->Opcode(); 1015218799Snwhitehorn if( andl_op == Op_AndL ) { 1016218799Snwhitehorn // Blow off prior masking to int 1017218799Snwhitehorn if( phase->type(andl->in(2)) == TypeLong::make( 0xFFFFFFFF ) ) { 1018218799Snwhitehorn set_req(1,andl->in(1)); 1019218799Snwhitehorn return this; 1020218799Snwhitehorn } 1021218799Snwhitehorn } 1022218799Snwhitehorn 1023218799Snwhitehorn // Swap with a prior add: convL2I(addL(x,y)) ==> addI(convL2I(x),convL2I(y)) 1024218799Snwhitehorn // This replaces an 'AddL' with an 'AddI'. 1025218799Snwhitehorn if( andl_op == Op_AddL ) { 1026218799Snwhitehorn // Don't do this for nodes which have more than one user since 1027218799Snwhitehorn // we'll end up computing the long add anyway. 1028218799Snwhitehorn if (andl->outcnt() > 1) return NULL; 1029218799Snwhitehorn 1030218799Snwhitehorn Node* x = andl->in(1); 1031218799Snwhitehorn Node* y = andl->in(2); 1032218799Snwhitehorn assert( x != andl && y != andl, "dead loop in ConvL2INode::Ideal" ); 1033218799Snwhitehorn if (phase->type(x) == Type::TOP) return NULL; 1034218799Snwhitehorn if (phase->type(y) == Type::TOP) return NULL; 1035218799Snwhitehorn Node *add1 = phase->transform(new (phase->C, 2) ConvL2INode(x)); 1036218799Snwhitehorn Node *add2 = phase->transform(new (phase->C, 2) ConvL2INode(y)); 1037218799Snwhitehorn return new (phase->C, 3) AddINode(add1,add2); 1038218799Snwhitehorn } 1039218799Snwhitehorn 1040218799Snwhitehorn // Disable optimization: LoadL->ConvL2I ==> LoadI. 1041218799Snwhitehorn // It causes problems (sizes of Load and Store nodes do not match) 1042218799Snwhitehorn // in objects initialization code and Escape Analysis. 1043218799Snwhitehorn return NULL; 1044218799Snwhitehorn} 1045218799Snwhitehorn 1046218799Snwhitehorn//============================================================================= 1047218799Snwhitehorn//------------------------------Value------------------------------------------ 1048218799Snwhitehornconst Type *CastX2PNode::Value( PhaseTransform *phase ) const { 1049226160Snwhitehorn const Type* t = phase->type(in(1)); 1050226160Snwhitehorn if (t->base() == Type_X && t->singleton()) { 1051226160Snwhitehorn uintptr_t bits = (uintptr_t) t->is_intptr_t()->get_con(); 1052226160Snwhitehorn if (bits == 0) return TypePtr::NULL_PTR; 1053226160Snwhitehorn return TypeRawPtr::make((address) bits); 1054226160Snwhitehorn } 1055226160Snwhitehorn return CastX2PNode::bottom_type(); 1056226160Snwhitehorn} 1057226160Snwhitehorn 1058226160Snwhitehorn//------------------------------Idealize--------------------------------------- 1059226160Snwhitehornstatic inline bool fits_in_int(const Type* t, bool but_not_min_int = false) { 1060226160Snwhitehorn if (t == Type::TOP) return false; 1061226160Snwhitehorn const TypeX* tl = t->is_intptr_t(); 1062218799Snwhitehorn jint lo = min_jint; 1063218799Snwhitehorn jint hi = max_jint; 1064218799Snwhitehorn if (but_not_min_int) ++lo; // caller wants to negate the value w/o overflow 1065218799Snwhitehorn return (tl->_lo >= lo) && (tl->_hi <= hi); 1066218799Snwhitehorn} 1067218799Snwhitehorn 1068218799Snwhitehornstatic inline Node* addP_of_X2P(PhaseGVN *phase, 1069218799Snwhitehorn Node* base, 1070218799Snwhitehorn Node* dispX, 1071218799Snwhitehorn bool negate = false) { 1072218799Snwhitehorn if (negate) { 1073218799Snwhitehorn dispX = new (phase->C, 3) SubXNode(phase->MakeConX(0), phase->transform(dispX)); 1074218799Snwhitehorn } 1075271539Snwhitehorn return new (phase->C, 4) AddPNode(phase->C->top(), 1076271539Snwhitehorn phase->transform(new (phase->C, 2) CastX2PNode(base)), 1077271539Snwhitehorn phase->transform(dispX)); 1078271539Snwhitehorn} 1079271539Snwhitehorn 1080271539SnwhitehornNode *CastX2PNode::Ideal(PhaseGVN *phase, bool can_reshape) { 1081271539Snwhitehorn // convert CastX2P(AddX(x, y)) to AddP(CastX2P(x), y) if y fits in an int 1082271539Snwhitehorn int op = in(1)->Opcode(); 1083271539Snwhitehorn Node* x; 1084271539Snwhitehorn Node* y; 1085271539Snwhitehorn switch (op) { 1086271539Snwhitehorn case Op_SubX: 1087271539Snwhitehorn x = in(1)->in(1); 1088271539Snwhitehorn // Avoid ideal transformations ping-pong between this and AddP for raw pointers. 1089218799Snwhitehorn if (phase->find_intptr_t_con(x, -1) == 0) 1090218799Snwhitehorn break; 1091218799Snwhitehorn y = in(1)->in(2); 1092218799Snwhitehorn if (fits_in_int(phase->type(y), true)) { 1093226160Snwhitehorn return addP_of_X2P(phase, x, y, true); 1094226160Snwhitehorn } 1095226160Snwhitehorn break; 1096226160Snwhitehorn case Op_AddX: 1097226160Snwhitehorn x = in(1)->in(1); 1098226160Snwhitehorn y = in(1)->in(2); 1099226160Snwhitehorn if (fits_in_int(phase->type(y))) { 1100226160Snwhitehorn return addP_of_X2P(phase, x, y); 1101226160Snwhitehorn } 1102226160Snwhitehorn if (fits_in_int(phase->type(x))) { 1103264978Snwhitehorn return addP_of_X2P(phase, y, x); 1104264978Snwhitehorn } 1105226160Snwhitehorn break; 1106226160Snwhitehorn } 1107226160Snwhitehorn return NULL; 1108226160Snwhitehorn} 1109255817Snwhitehorn 1110255817Snwhitehorn//------------------------------Identity--------------------------------------- 1111226160SnwhitehornNode *CastX2PNode::Identity( PhaseTransform *phase ) { 1112218799Snwhitehorn if (in(1)->Opcode() == Op_CastP2X) return in(1)->in(1); 1113218799Snwhitehorn return this; 1114218799Snwhitehorn} 1115218799Snwhitehorn 1116218799Snwhitehorn//============================================================================= 1117218799Snwhitehorn//------------------------------Value------------------------------------------ 1118218799Snwhitehornconst Type *CastP2XNode::Value( PhaseTransform *phase ) const { 1119218799Snwhitehorn const Type* t = phase->type(in(1)); 1120218799Snwhitehorn if (t->base() == Type::RawPtr && t->singleton()) { 1121218799Snwhitehorn uintptr_t bits = (uintptr_t) t->is_rawptr()->get_con(); 1122218799Snwhitehorn return TypeX::make(bits); 1123218799Snwhitehorn } 1124218799Snwhitehorn return CastP2XNode::bottom_type(); 1125218799Snwhitehorn} 1126264978Snwhitehorn 1127218799SnwhitehornNode *CastP2XNode::Ideal(PhaseGVN *phase, bool can_reshape) { 1128218799Snwhitehorn return (in(0) && remove_dead_region(phase, can_reshape)) ? this : NULL; 1129218799Snwhitehorn} 1130218799Snwhitehorn 1131218799Snwhitehorn//------------------------------Identity--------------------------------------- 1132218799SnwhitehornNode *CastP2XNode::Identity( PhaseTransform *phase ) { 1133218799Snwhitehorn if (in(1)->Opcode() == Op_CastX2P) return in(1)->in(1); 1134218799Snwhitehorn return this; 1135218799Snwhitehorn} 1136218799Snwhitehorn 1137218799Snwhitehorn 1138218799Snwhitehorn//============================================================================= 1139218799Snwhitehorn//------------------------------Identity--------------------------------------- 1140218799Snwhitehorn// Remove redundant roundings 1141218799SnwhitehornNode *RoundFloatNode::Identity( PhaseTransform *phase ) { 1142218799Snwhitehorn assert(Matcher::strict_fp_requires_explicit_rounding, "should only generate for Intel"); 1143218799Snwhitehorn // Do not round constants 1144218799Snwhitehorn if (phase->type(in(1))->base() == Type::FloatCon) return in(1); 1145218799Snwhitehorn int op = in(1)->Opcode(); 1146218799Snwhitehorn // Redundant rounding 1147218799Snwhitehorn if( op == Op_RoundFloat ) return in(1); 1148218799Snwhitehorn // Already rounded 1149218799Snwhitehorn if( op == Op_Parm ) return in(1); 1150218799Snwhitehorn if( op == Op_LoadF ) return in(1); 1151218799Snwhitehorn return this; 1152218799Snwhitehorn} 1153218799Snwhitehorn 1154218799Snwhitehorn//------------------------------Value------------------------------------------ 1155218799Snwhitehornconst Type *RoundFloatNode::Value( PhaseTransform *phase ) const { 1156218799Snwhitehorn return phase->type( in(1) ); 1157218799Snwhitehorn} 1158218799Snwhitehorn 1159218799Snwhitehorn//============================================================================= 1160218799Snwhitehorn//------------------------------Identity--------------------------------------- 1161218799Snwhitehorn// Remove redundant roundings. Incoming arguments are already rounded. 1162218799SnwhitehornNode *RoundDoubleNode::Identity( PhaseTransform *phase ) { 1163218799Snwhitehorn assert(Matcher::strict_fp_requires_explicit_rounding, "should only generate for Intel"); 1164218799Snwhitehorn // Do not round constants 1165218799Snwhitehorn if (phase->type(in(1))->base() == Type::DoubleCon) return in(1); 1166218799Snwhitehorn int op = in(1)->Opcode(); 1167218799Snwhitehorn // Redundant rounding 1168218799Snwhitehorn if( op == Op_RoundDouble ) return in(1); 1169226161Snwhitehorn // Already rounded 1170226161Snwhitehorn if( op == Op_Parm ) return in(1); 1171218799Snwhitehorn if( op == Op_LoadD ) return in(1); 1172226161Snwhitehorn if( op == Op_ConvF2D ) return in(1); 1173226161Snwhitehorn if( op == Op_ConvI2D ) return in(1); 1174226161Snwhitehorn return this; 1175226161Snwhitehorn} 1176226161Snwhitehorn 1177226161Snwhitehorn//------------------------------Value------------------------------------------ 1178226161Snwhitehornconst Type *RoundDoubleNode::Value( PhaseTransform *phase ) const { 1179226161Snwhitehorn return phase->type( in(1) ); 1180226161Snwhitehorn} 1181226161Snwhitehorn 1182226161Snwhitehorn 1183226161Snwhitehorn//============================================================================= 1184226161Snwhitehorn// Do not allow value-numbering 1185226161Snwhitehornuint Opaque1Node::hash() const { return NO_HASH; } 1186264978Snwhitehornuint Opaque1Node::cmp( const Node &n ) const { 1187226161Snwhitehorn return (&n == this); // Always fail except on self 1188218799Snwhitehorn} 1189226161Snwhitehorn 1190218799Snwhitehorn//------------------------------Identity--------------------------------------- 1191226161Snwhitehorn// If _major_progress, then more loop optimizations follow. Do NOT remove 1192219892Snwhitehorn// the opaque Node until no more loop ops can happen. Note the timing of 1193218799Snwhitehorn// _major_progress; it's set in the major loop optimizations THEN comes the 1194218799Snwhitehorn// call to IterGVN and any chance of hitting this code. Hence there's no 1195218799Snwhitehorn// phase-ordering problem with stripping Opaque1 in IGVN followed by some 1196218799Snwhitehorn// more loop optimizations that require it. 1197218799SnwhitehornNode *Opaque1Node::Identity( PhaseTransform *phase ) { 1198218799Snwhitehorn return phase->C->major_progress() ? this : in(1); 1199226161Snwhitehorn} 1200218799Snwhitehorn 1201218799Snwhitehorn//============================================================================= 1202218799Snwhitehorn// A node to prevent unwanted optimizations. Allows constant folding. Stops 1203218799Snwhitehorn// value-numbering, most Ideal calls or Identity functions. This Node is 1204218799Snwhitehorn// specifically designed to prevent the pre-increment value of a loop trip 1205218799Snwhitehorn// counter from being live out of the bottom of the loop (hence causing the 1206218799Snwhitehorn// pre- and post-increment values both being live and thus requiring an extra 1207218799Snwhitehorn// temp register and an extra move). If we "accidentally" optimize through 1208218799Snwhitehorn// this kind of a Node, we'll get slightly pessimal, but correct, code. Thus 1209218799Snwhitehorn// it's OK to be slightly sloppy on optimizations here. 1210218799Snwhitehorn 1211226083Snwhitehorn// Do not allow value-numbering 1212218799Snwhitehornuint Opaque2Node::hash() const { return NO_HASH; } 1213218799Snwhitehornuint Opaque2Node::cmp( const Node &n ) const { 1214218799Snwhitehorn return (&n == this); // Always fail except on self 1215218799Snwhitehorn} 1216218799Snwhitehorn 1217218799Snwhitehorn 1218218799Snwhitehorn//------------------------------Value------------------------------------------ 1219218799Snwhitehornconst Type *MoveL2DNode::Value( PhaseTransform *phase ) const { 1220218799Snwhitehorn const Type *t = phase->type( in(1) ); 1221218799Snwhitehorn if( t == Type::TOP ) return Type::TOP; 1222218799Snwhitehorn const TypeLong *tl = t->is_long(); 1223218799Snwhitehorn if( !tl->is_con() ) return bottom_type(); 1224226083Snwhitehorn JavaValue v; 1225218799Snwhitehorn v.set_jlong(tl->get_con()); 1226226083Snwhitehorn return TypeD::make( v.get_jdouble() ); 1227226083Snwhitehorn} 1228226083Snwhitehorn 1229218799Snwhitehorn//------------------------------Value------------------------------------------ 1230226083Snwhitehornconst Type *MoveI2FNode::Value( PhaseTransform *phase ) const { 1231226083Snwhitehorn const Type *t = phase->type( in(1) ); 1232226083Snwhitehorn if( t == Type::TOP ) return Type::TOP; 1233226083Snwhitehorn const TypeInt *ti = t->is_int(); 1234226083Snwhitehorn if( !ti->is_con() ) return bottom_type(); 1235226083Snwhitehorn JavaValue v; 1236218799Snwhitehorn v.set_jint(ti->get_con()); 1237226083Snwhitehorn return TypeF::make( v.get_jfloat() ); 1238218799Snwhitehorn} 1239218799Snwhitehorn 1240218799Snwhitehorn//------------------------------Value------------------------------------------ 1241218799Snwhitehornconst Type *MoveF2INode::Value( PhaseTransform *phase ) const { 1242218799Snwhitehorn const Type *t = phase->type( in(1) ); 1243218799Snwhitehorn if( t == Type::TOP ) return Type::TOP; 1244218799Snwhitehorn if( t == Type::FLOAT ) return TypeInt::INT; 1245218799Snwhitehorn const TypeF *tf = t->is_float_constant(); 1246218799Snwhitehorn JavaValue v; 1247218799Snwhitehorn v.set_jfloat(tf->getf()); 1248218799Snwhitehorn return TypeInt::make( v.get_jint() ); 1249218799Snwhitehorn} 1250218799Snwhitehorn 1251218799Snwhitehorn//------------------------------Value------------------------------------------ 1252218799Snwhitehornconst Type *MoveD2LNode::Value( PhaseTransform *phase ) const { 1253218799Snwhitehorn const Type *t = phase->type( in(1) ); 1254218799Snwhitehorn if( t == Type::TOP ) return Type::TOP; 1255218799Snwhitehorn if( t == Type::DOUBLE ) return TypeLong::LONG; 1256218799Snwhitehorn const TypeD *td = t->is_double_constant(); 1257218799Snwhitehorn JavaValue v; 1258218799Snwhitehorn v.set_jdouble(td->getd()); 1259218799Snwhitehorn return TypeLong::make( v.get_jlong() ); 1260218799Snwhitehorn} 1261218799Snwhitehorn 1262218799Snwhitehorn//------------------------------Value------------------------------------------ 1263218799Snwhitehornconst Type* CountLeadingZerosINode::Value(PhaseTransform* phase) const { 1264218799Snwhitehorn const Type* t = phase->type(in(1)); 1265218799Snwhitehorn if (t == Type::TOP) return Type::TOP; 1266218799Snwhitehorn const TypeInt* ti = t->isa_int(); 1267218799Snwhitehorn if (ti && ti->is_con()) { 1268218799Snwhitehorn jint i = ti->get_con(); 1269218799Snwhitehorn // HD, Figure 5-6 1270218799Snwhitehorn if (i == 0) 1271218799Snwhitehorn return TypeInt::make(BitsPerInt); 1272218799Snwhitehorn int n = 1; 1273218799Snwhitehorn unsigned int x = i; 1274218799Snwhitehorn if (x >> 16 == 0) { n += 16; x <<= 16; } 1275218799Snwhitehorn if (x >> 24 == 0) { n += 8; x <<= 8; } 1276218799Snwhitehorn if (x >> 28 == 0) { n += 4; x <<= 4; } 1277218799Snwhitehorn if (x >> 30 == 0) { n += 2; x <<= 2; } 1278218799Snwhitehorn n -= x >> 31; 1279218799Snwhitehorn return TypeInt::make(n); 1280218799Snwhitehorn } 1281218799Snwhitehorn return TypeInt::INT; 1282218799Snwhitehorn} 1283218799Snwhitehorn 1284218799Snwhitehorn//------------------------------Value------------------------------------------ 1285218799Snwhitehornconst Type* CountLeadingZerosLNode::Value(PhaseTransform* phase) const { 1286218799Snwhitehorn const Type* t = phase->type(in(1)); 1287218799Snwhitehorn if (t == Type::TOP) return Type::TOP; 1288218799Snwhitehorn const TypeLong* tl = t->isa_long(); 1289218799Snwhitehorn if (tl && tl->is_con()) { 1290218799Snwhitehorn jlong l = tl->get_con(); 1291218799Snwhitehorn // HD, Figure 5-6 1292218799Snwhitehorn if (l == 0) 1293218799Snwhitehorn return TypeInt::make(BitsPerLong); 1294218799Snwhitehorn int n = 1; 1295218799Snwhitehorn unsigned int x = (((julong) l) >> 32); 1296218799Snwhitehorn if (x == 0) { n += 32; x = (int) l; } 1297218799Snwhitehorn if (x >> 16 == 0) { n += 16; x <<= 16; } 1298218799Snwhitehorn if (x >> 24 == 0) { n += 8; x <<= 8; } 1299218799Snwhitehorn if (x >> 28 == 0) { n += 4; x <<= 4; } 1300218799Snwhitehorn if (x >> 30 == 0) { n += 2; x <<= 2; } 1301218799Snwhitehorn n -= x >> 31; 1302218799Snwhitehorn return TypeInt::make(n); 1303218799Snwhitehorn } 1304218799Snwhitehorn return TypeInt::INT; 1305218799Snwhitehorn} 1306218799Snwhitehorn 1307218799Snwhitehorn//------------------------------Value------------------------------------------ 1308218799Snwhitehornconst Type* CountTrailingZerosINode::Value(PhaseTransform* phase) const { 1309218799Snwhitehorn const Type* t = phase->type(in(1)); 1310218799Snwhitehorn if (t == Type::TOP) return Type::TOP; 1311218799Snwhitehorn const TypeInt* ti = t->isa_int(); 1312218799Snwhitehorn if (ti && ti->is_con()) { 1313218799Snwhitehorn jint i = ti->get_con(); 1314226161Snwhitehorn // HD, Figure 5-14 1315218799Snwhitehorn int y; 1316218799Snwhitehorn if (i == 0) 1317218799Snwhitehorn return TypeInt::make(BitsPerInt); 1318218799Snwhitehorn int n = 31; 1319218799Snwhitehorn y = i << 16; if (y != 0) { n = n - 16; i = y; } 1320218799Snwhitehorn y = i << 8; if (y != 0) { n = n - 8; i = y; } 1321218799Snwhitehorn y = i << 4; if (y != 0) { n = n - 4; i = y; } 1322218799Snwhitehorn y = i << 2; if (y != 0) { n = n - 2; i = y; } 1323218799Snwhitehorn y = i << 1; if (y != 0) { n = n - 1; } 1324218799Snwhitehorn return TypeInt::make(n); 1325218799Snwhitehorn } 1326218799Snwhitehorn return TypeInt::INT; 1327218799Snwhitehorn} 1328218799Snwhitehorn 1329218799Snwhitehorn//------------------------------Value------------------------------------------ 1330218799Snwhitehornconst Type* CountTrailingZerosLNode::Value(PhaseTransform* phase) const { 1331271539Snwhitehorn const Type* t = phase->type(in(1)); 1332218799Snwhitehorn if (t == Type::TOP) return Type::TOP; 1333218799Snwhitehorn const TypeLong* tl = t->isa_long(); 1334218799Snwhitehorn if (tl && tl->is_con()) { 1335218799Snwhitehorn jlong l = tl->get_con(); 1336218799Snwhitehorn // HD, Figure 5-14 1337218799Snwhitehorn int x, y; 1338271539Snwhitehorn if (l == 0) 1339271539Snwhitehorn return TypeInt::make(BitsPerLong); 1340271539Snwhitehorn int n = 63; 1341271539Snwhitehorn y = (int) l; if (y != 0) { n = n - 32; x = y; } else x = (((julong) l) >> 32); 1342271539Snwhitehorn y = x << 16; if (y != 0) { n = n - 16; x = y; } 1343271539Snwhitehorn y = x << 8; if (y != 0) { n = n - 8; x = y; } 1344271539Snwhitehorn y = x << 4; if (y != 0) { n = n - 4; x = y; } 1345271539Snwhitehorn y = x << 2; if (y != 0) { n = n - 2; x = y; } 1346271539Snwhitehorn y = x << 1; if (y != 0) { n = n - 1; } 1347218799Snwhitehorn return TypeInt::make(n); 1348218799Snwhitehorn } 1349218799Snwhitehorn return TypeInt::INT; 1350218799Snwhitehorn} 1351218799Snwhitehorn