duke@435: /* duke@435: * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * duke@435: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, duke@435: * CA 95054 USA or visit www.sun.com if you need additional information or duke@435: * have any questions. duke@435: * duke@435: */ duke@435: duke@435: #include "incls/_precompiled.incl" duke@435: #include "incls/_rootnode.cpp.incl" duke@435: duke@435: //------------------------------Ideal------------------------------------------ duke@435: // Remove dead inputs duke@435: Node *RootNode::Ideal(PhaseGVN *phase, bool can_reshape) { duke@435: for( uint i = 1; i < req(); i++ ) { // For all inputs duke@435: // Check for and remove dead inputs duke@435: if( phase->type(in(i)) == Type::TOP ) { duke@435: del_req(i--); // Delete TOP inputs duke@435: } duke@435: } duke@435: duke@435: // I used to do tail-splitting in the Ideal graph here, but it does not duke@435: // work. The tail-splitting forces values live into the Return to be duke@435: // ready at a point which dominates the split returns. This forces Stores duke@435: // to be hoisted high. The "proper" fix would be to split Stores down duke@435: // each path, but this makes the split unprofitable. If we want to do this duke@435: // optimization, it needs to be done after allocation so we can count all duke@435: // the instructions needing to be cloned in the cost metric. duke@435: duke@435: // There used to be a spoof here for caffeine marks which completely duke@435: // eliminated very simple self-recursion recursions, but it's not worth it. duke@435: // Deep inlining of self-calls gets nearly all of the same benefits. duke@435: // If we want to get the rest of the win later, we should pattern match duke@435: // simple recursive call trees to closed-form solutions. duke@435: duke@435: return NULL; // No further opportunities exposed duke@435: } duke@435: duke@435: //============================================================================= duke@435: HaltNode::HaltNode( Node *ctrl, Node *frameptr ) : Node(TypeFunc::Parms) { duke@435: Node* top = Compile::current()->top(); duke@435: init_req(TypeFunc::Control, ctrl ); duke@435: init_req(TypeFunc::I_O, top); duke@435: init_req(TypeFunc::Memory, top); duke@435: init_req(TypeFunc::FramePtr, frameptr ); duke@435: init_req(TypeFunc::ReturnAdr,top); duke@435: } duke@435: duke@435: const Type *HaltNode::bottom_type() const { return Type::BOTTOM; } duke@435: duke@435: //------------------------------Ideal------------------------------------------ duke@435: Node *HaltNode::Ideal(PhaseGVN *phase, bool can_reshape) { duke@435: return remove_dead_region(phase, can_reshape) ? this : NULL; duke@435: } duke@435: duke@435: //------------------------------Value------------------------------------------ duke@435: const Type *HaltNode::Value( PhaseTransform *phase ) const { duke@435: return ( phase->type(in(TypeFunc::Control)) == Type::TOP) duke@435: ? Type::TOP duke@435: : Type::BOTTOM; duke@435: } duke@435: duke@435: const RegMask &HaltNode::out_RegMask() const { duke@435: return RegMask::Empty; duke@435: }