node.cpp revision 196
196N/A * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 0N/A * published by the Free Software Foundation. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 0N/A * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 0N/A * CA 95054 USA or visit www.sun.com if you need additional information or 0N/A * have any questions. 0N/A#
include "incls/_precompiled.incl" 0N/A// Arena we are currently building Nodes in 0N/A//-------------------------- construct_node------------------------------------ 0N/A// Set a breakpoint here to identify where a particular node index is built. 0N/A // Arrange that the lowest five decimal digits of _debug_idx 0N/A // will repeat thos of _idx. In case this is somehow pathological, 0N/A // we continue to assign negative numbers (!) consecutively. 0N/A // Ensure that the loop body has just deleted the last guy produced. 0N/A // Ensure that at least one copy of the last-seen edge was deleted. 0N/A // Note: It is OK to delete multiple copies of the last-seen edge. 0N/A // Unfortunately, we have no way to verify that all the deletions delete 0N/A // that same edge. On this point we must use the Honor System. 0N/A // We liked this deletion, so accept the resulting outcnt and tick. 0N/A if (
this == &
that)
return;
// ignore assignment to self 0N/A // We need to initialize everything, overwriting garbage values. 0N/A // Note: It is legal (though odd) for an iterator over some node x 0N/A // to be reassigned to iterate over another node y. Some doubly-nested 0N/A // progress loops depend on being able to do this. 0N/A // Re-initialize everything, except _last. 0N/A // We have refreshed the index during this loop. 0N/A // Fix up _idx to meet asserts. 0N/A // Note: We do not assert on _outcnt, because insertions are OK here. 0N/A // Make sure we are still in sync, possibly with no more out-edges: 0N/A if (
this == &
that)
return;
// self assignment is always a no-op 0N/A // We need to initialize everything, overwriting garbage values. 0N/A // If the loop has killed the node, do not require it to re-run. 0N/A // If this assert triggers, it means that a loop used refresh_out_pos 0N/A // to re-synch an iteration index, but the loop did not correctly 0N/A // re-run itself, using a "while (progress)" construct. 0N/A // This iterator enforces the rule that you must keep trying the loop 0N/A // until it "runs clean" without any need for refreshing. 0N/A // This last check is carefully designed to work for NO_OUT_ARRAY. 0N/A // Note that the limit imax, not the pointer i, gets updated with the 0N/A // exact count of deletions. (For the pointer it's always "--i".) 0N/A // This is a limit pointer, with a name like "imax". 0N/A // Fudge the _last field so that the common assert will be happy. 0N/A // A normal internal pointer. 0N/A // Make sure we are still in sync, possibly with no more out-edges: 0N/A assert((
int)n > 0,
"use imax -= n only with a positive count");
0N/A // This must be a limit pointer, with a name like "imax". 0N/A // The reported number of deletions must match what the node saw. 0N/A // Fudge the _last field so that the common assert will be happy. 0N/A // at_end_ok means the _outp is allowed to underflow by 1 0N/A // Do not require the limit address to be resynched. 0N/A //verify(node, true); 0N/A // Make sure we are still in sync, possibly with no more out-edges: 0N/A#
endif //OPTO_DU_ITERATOR_ASSERT 0N/A// This constant used to initialize _out may be any non-null value. 0N/A// The value NULL is reserved for the top node only. 0N/A// This funny expression handshakes with Node::operator new 0N/A// to pull Compile::current out of the new node's _out field, 0N/A// and then calls a subroutine which manages most field 0N/A// initializations. The only one which is tricky is the 0N/A// _idx field, which is const, and so must be initialized 0N/A// by a return value, not an assignment. 0N/A// (Aren't you thankful that Java finals don't require so many tricks?) 0N/A#
ifdef _MSC_VER // the IDX_INIT hack falls foul of warning C4355 0N/A// Out-of-line code from node constructors. 0N/A// Executed only when extra debug info. is being passed around. 0N/A// Shared initialization code. 0N/A // If there are default notes floating around, capture them: 0N/A // Note: At this point, C is dead, 0N/A // and we begin to initialize the new Node. 0N/A//------------------------------Node------------------------------------------- 0N/A// Create a Node, with a given number of required edges. 0N/A//------------------------------Node------------------------------------------- 0N/A // Assert we allocated space for input array already 0N/A//------------------------------Node------------------------------------------- 0N/A // Assert we allocated space for input array already 0N/A//------------------------------Node------------------------------------------- 0N/A // Assert we allocated space for input array already 0N/A//------------------------------Node------------------------------------------- 0N/A // Assert we allocated space for input array already 0N/A//------------------------------Node------------------------------------------- 0N/A // Assert we allocated space for input array already 0N/A//------------------------------Node------------------------------------------- 0N/A // Assert we allocated space for input array already 0N/A//------------------------------Node------------------------------------------- 0N/A // Assert we allocated space for input array already 0N/A//------------------------------clone------------------------------------------ 0N/A // Set the new input pointer array 0N/A // Cannot share the old output pointer array, so kill it 0N/A // And reset the counters to 0 0N/A // Unlock this guy, since he is not in any hash table. 0N/A // Walk the old node's input list to duplicate its edges 0N/A for( i = 0; i <
len(); i++ ) {
0N/A // Do not patch over the debug_idx of a clone, because it makes it 0N/A // impossible to break on the clone's moment of creation. 0N/A //debug_only( n->set_debug_idx( debug_idx() ) ); 0N/A // Get address of _opnd_array. 0N/A // It should be the same offset since it is the clone of this node. 0N/A // cloning CallNode may need to clone JVMState 0N/A return n;
// Return the clone 0N/A//---------------------------setup_is_top-------------------------------------- 0N/A// Call this when changing the top node, to reassert the invariants 0N/A// required by Node::is_top. See Compile::set_cached_top_node. 0N/A // This node has just become top. Kill its out array. 0N/A//------------------------------~Node------------------------------------------ 0N/A// Fancy destructor; eagerly attempt to reclaim Node numberings and storage 0N/A // Eagerly reclaim unique Node numberings 0N/A // Clear debug info: 0N/A // Walk the input array, freeing the corresponding output edges 0N/A //assert(def->out(def->outcnt()-1) == (Node *)this,"bad def-use hacking in reclaim"); 0N/A // See if the input array was allocated just prior to the object 0N/A // Free the output edge array 0N/A // Free the input edge array and the node itself 0N/A // It was; free the input array and object all in one hit 0N/A // Free just the input array 0N/A // Free just the object 0N/A // We will not actually delete the storage, but we'll make the node unusable. 0N/A//------------------------------grow------------------------------------------- 0N/A// Grow the input array, making space for more edges 0N/A // Trimming to limit allows a uint8 to handle up to 255 edges. 0N/A // Previously I was using only powers-of-2 which peaked at 128 edges. 0N/A //if( new_max >= limit ) new_max = limit-1; 0N/A // This assertion makes sure that Node::_max is wide enough to 0N/A // represent the numerical value of new_max. 0N/A//-----------------------------out_grow---------------------------------------- 0N/A// Grow the input array, making space for more edges 0N/A // Trimming to limit allows a uint8 to handle up to 255 edges. 0N/A // Previously I was using only powers-of-2 which peaked at 128 edges. 0N/A //if( new_max >= limit ) new_max = limit-1; 0N/A //Copy::zero_to_bytes(&_out[_outmax], (new_max-_outmax)*sizeof(Node*)); // NULL all new space 0N/A // This assertion makes sure that Node::_max is wide enough to 0N/A // represent the numerical value of new_max. 0N/A//------------------------------is_dead---------------------------------------- 0N/A // Mach and pinch point nodes may look like dead. 0N/A//------------------------------add_req---------------------------------------- 0N/A// Add a new required input at the end 0N/A // Look to see if I can move precedence down one without reallocating 0N/A // Find a precedence edge to move 0N/A if(
in(i) ==
NULL )
// Find the NULL at end of prec edge list 0N/A break;
// There must be one, since we grew the array 0N/A _in[i] =
in(
_cnt);
// Move prec over, making space for req edge 0N/A//---------------------------add_req_batch------------------------------------- 0N/A// Add a new required input at the end 0N/A // check various edge cases 0N/A // Look to see if I can move precedence down one without reallocating 0N/A // Find a precedence edge to move 0N/A if(
_in[i] ==
NULL )
// Find the NULL at end of prec edge list 0N/A break;
// There must be one, since we grew the array 0N/A // Slide all the precs over by m positions (assume #prec << m). 0N/A // Stuff over the old prec edges 0N/A // Insert multiple out edges on the node. 0N/A//------------------------------del_req---------------------------------------- 0N/A// Delete the required edge and compact the edge array 0N/A // First remove corresponding def-use edge 0N/A//------------------------------ins_req---------------------------------------- 0N/A// Insert a new required input at the end 0N/A _in[
idx] = n;
// Stuff over old required edge 0N/A//-----------------------------find_edge--------------------------------------- 0N/A//----------------------------replace_edge------------------------------------- 0N/A//-------------------------disconnect_inputs----------------------------------- 0N/A// NULL out all inputs to eliminate incoming Def-Use edges. 0N/A// Return the number of edges between 'n' and 'this' 0N/A if(
in(i) == 0 )
continue;
0N/A // Remove precedence edges if any exist 0N/A // Note: Safepoints may have precedence edges, even during parsing 0N/A if(
in(i) == 0 )
continue;
0N/A // Node::destruct requires all out edges be deleted first 0N/A // debug_only(destruct();) // no reuse benefit expected 0N/A//-----------------------------uncast--------------------------------------- 0N/A// %%% Temporary, until we sort out CheckCastPP vs. CastPP. 0N/A// Strip away casting. (It is depth-limited.) 0N/A // Should be inline: 0N/A //return is_ConstraintCast() ? uncast_helper(this) : (Node*) this; 0N/A//---------------------------uncast_helper------------------------------------- 0N/A//------------------------------add_prec--------------------------------------- 0N/A// Add a new precedence input. Precedence inputs are unordered, with 0N/A// duplicates removed and NULLs packed down at the end. 0N/A // Check for NULL at end 0N/A // Find a precedence edge to move 0N/A _in[i] = n;
// Stuff prec edge over NULL 0N/A//------------------------------rm_prec---------------------------------------- 0N/A// Remove a precedence input. Precedence inputs are unordered, with 0N/A// duplicates removed and NULLs packed down at the end. 0N/A // Find end of precedence list to pack NULLs 0N/A if( !
_in[i] )
// Find the NULL at end of prec edge list 0N/A _in[j] =
_in[--i];
// Move last element over removed guy 0N/A//------------------------------size_of---------------------------------------- 0N/A//------------------------------ideal_reg-------------------------------------- 0N/A//------------------------------jvms------------------------------------------- 0N/A//------------------------------jvms------------------------------------------- 0N/A//------------------------------init_NodeProperty------------------------------ 0N/A//------------------------------format----------------------------------------- 0N/A//------------------------------emit------------------------------------------- 0N/A// Emit bytes starting at parameter 'ptr'. 0N/A//------------------------------size------------------------------------------- 0N/A// Size of instruction in bytes 0N/A//------------------------------CFG Construction------------------------------- 0N/A// Minimum guaranteed type 0N/A//------------------------------raise_bottom_type------------------------------ 0N/A// Get the worst-case Type output for this Node. 0N/A//------------------------------Identity--------------------------------------- 0N/A// Return a node that the given node is equivalent to. 0N/A return this;
// Default to no identities 0N/A//------------------------------Value------------------------------------------ 0N/A// Compute a new Type for a node using the Type of the inputs. 0N/A//------------------------------Ideal------------------------------------------ 0N/A// 'Idealize' the graph rooted at this Node. 0N/A// In order to be efficient and flexible there are some subtle invariants 0N/A// these Ideal calls need to hold. Running with '+VerifyIterativeGVN' checks 0N/A// these invariants, although its too slow to have on by default. If you are 0N/A// hacking an Ideal call, be sure to test with +VerifyIterativeGVN! 0N/A// The Ideal call almost arbitrarily reshape the graph rooted at the 'this' 0N/A// pointer. If ANY change is made, it must return the root of the reshaped 0N/A// graph - even if the root is the same Node. Example: swapping the inputs 0N/A// to an AddINode gives the same answer and same root, but you still have to 0N/A// return the 'this' pointer instead of NULL. 0N/A// You cannot return an OLD Node, except for the 'this' pointer. Use the 0N/A// Identity call to return an old Node; basically if Identity can find 0N/A// another Node have the Ideal call make no change and return NULL. 0N/A// Example: AddINode::Ideal must check for add of zero; in this case it 0N/A// returns NULL instead of doing any graph reshaping. 0N/A// You cannot modify any old Nodes except for the 'this' pointer. Due to 0N/A// sharing there may be other users of the old Nodes relying on their current 0N/A// semantics. Modifying them will break the other users. 0N/A// Example: when reshape "(X+3)+4" into "X+7" you must leave the Node for 0N/A// "X+3" unchanged in case it is shared. 0N/A// If you modify the 'this' pointer's inputs, you must use 'set_req' with 0N/A// def-use info. If you are making a new Node (either as the new root or 0N/A// some new internal piece) you must NOT use set_req with def-use info. 0N/A// You can make a new Node with either 'new' or 'clone'. In either case, 0N/A// def-use info is (correctly) not generated. 0N/A// Example: reshape "(X+3)+4" into "X+7": 0N/A// set_req(1,in(1)->in(1) /* grab X */, du /* must use DU on 'this' */); 0N/A// set_req(2,phase->intcon(7),du); 0N/A// Example: reshape "X*4" into "X<<1" 0N/A// return new (C,3) LShiftINode( in(1), phase->intcon(1) ); 0N/A// You must call 'phase->transform(X)' on any new Nodes X you make, except 0N/A// for the returned root node. Example: reshape "X*31" with "(X<<5)-1". 0N/A// Node *shift=phase->transform(new(C,3)LShiftINode(in(1),phase->intcon(5))); 0N/A// return new (C,3) AddINode(shift, phase->intcon(-1)); 0N/A// When making a Node for a constant use 'phase->makecon' or 'phase->intcon'. 0N/A// These forms are faster than 'phase->transform(new (C,1) ConNode())' and Do 0N/A// The Right Thing with def-use info. 0N/A// You cannot bury the 'this' Node inside of a graph reshape. If the reshaped 0N/A// graph uses the 'this' Node it must be the root. If you want a Node with 0N/A// the same Opcode as the 'this' pointer use 'clone'. 0N/A return NULL;
// Default to being Ideal already 0N/A// Some nodes have specific Ideal subgraph transformations only if they are 0N/A// unique users of specific nodes. Such nodes should be put on IGVN worklist 0N/A// for the transformations to happen. 0N/A // Condition for back-to-back stores folding. 0N/A // Condition for convL2I(addL(x,y)) ==> addI(convL2I(x),convL2I(y)) 0N/A // Condition for subI(x,subI(y,z)) ==> subI(addI(x,z),y) 85N/A//--------------------------find_exact_control--------------------------------- 85N/A// Skip Proj and CatchProj nodes chains. Check for Null and Top. 85N/A//--------------------------dominates------------------------------------------ 85N/A// Helper function for MemNode::all_controls_dominate(). 85N/A// Check if 'this' control node dominates or equal to 'sub' control node. 193N/A// We already know that if any path back to Root or Start reaches 'this', 193N/A// then all paths so, so this is a simple search for one example, 193N/A// not an exhaustive search for a counterexample. 155N/A // detect dead cycle without regions 193N/A // Walk 'sub' backward up the chain to 'dom', watching for regions. 193N/A // After seeing 'dom', continue up to Root or Start. 193N/A // If we hit a region (backward split point), it may be a loop head. 193N/A // Keep going through one of the region's inputs. If we reach the 193N/A // same region again, go through a different input. Eventually we 193N/A // will either exit through the loop head, or give up. 193N/A // (If we get confused, break out and return a conservative 'false'.) 85N/A // No Region nodes except loops were visited before and the EntryControl 85N/A // path was taken for loops: it did not walk in a cycle. 193N/A break;
// already met before: walk in a cycle 85N/A // Region nodes were visited. Continue walk up to Start or Root 85N/A // to make sure that it did not walk in a cycle. 193N/A // Success if we met 'dom' along a path to Start or Root. 193N/A // We assume there are no alternative paths that avoid 'dom'. 193N/A // (This assumption is up to the caller to ensure!) 193N/A // Normalize simple pass-through regions and projections: 193N/A // If sub == up, we found a self-loop. Try to push past it. 193N/A // Take loop entry path on the way up to 'dom'. 193N/A // Always take in(1) path on the way up to 'dom' for clone regions 193N/A // (with only one input) or regions which merge > 2 paths 193N/A // Try both paths for Regions with 2 input paths (it may be a loop head). 193N/A // It could give conservative 'false' answer without information 193N/A // which region's input is the entry path. 193N/A // Was this Region node visited before? 193N/A // If so, we have reached it because we accidentally took a 193N/A // loop-back edge from 'sub' back into the body of the loop, 193N/A // and worked our way up again to the loop header 'sub'. 193N/A // So, take the first unexplored path on the way up to 'dom'. 193N/A // Visited 2 paths, but still stuck in loop body. Give up. 193N/A // The Region node was visited before only once. 193N/A // (We will repush with the low bit set, below.) 193N/A // We will find a new edge and re-insert. 193N/A // Find an incoming edge which has not been seen yet; walk through it. 193N/A // Set 0 bit to indicate that both paths were taken. 193N/A break;
// some kind of tight cycle 193N/A // returned back after visiting 'dom' 193N/A break;
// some kind of cycle 193N/A // Did not meet Root or Start node in pred. chain. 193N/A // Conservative answer for dead code. 0N/A//------------------------------remove_dead_region----------------------------- 0N/A// This control node is dead. Follow the subgraph below it making everything 0N/A// using it dead as well. This will happen normally via the usual IterGVN 0N/A// worklist but this call is more efficient. Do not update use-def info 0N/A// inside the dead region, just at the borders. 0N/A // Con's are a popular node to re-hit in the hash table again. 0N/A // Can't put ResourceMark here since igvn->_worklist uses the same arena 0N/A // for verify pass with +VerifyOpto and we add/remove elements in it here. 0N/A // Keep dead node on stack until all uses are processed. 0N/A // For all Users of the Dead... ;-) 0N/A }
else {
// Else found a not-dead user 0N/A // Refresh the iterator, since any number of kills might have happened. 0N/A }
else {
// (dead->outcnt() == 0) 0N/A // Done with outputs. 0N/A // Kill all inputs to the dead guy 0N/A if (n->
outcnt() == 0) {
// Input also goes dead? 0N/A // Push store's uses on worklist to enable folding optimization for 0N/A // The restriction (outcnt() <= 2) is the same as in set_req_X() 0N/A // and remove_globally_dead_node(). 0N/A }
// (dead->outcnt() == 0) 0N/A//------------------------------remove_dead_region----------------------------- 0N/A if( !n )
return false;
0N/A // Lost control into this guy? I.e., it became unreachable? 0N/A // Aggressively kill all unreachable code. 0N/A//------------------------------Ideal_DU_postCCP------------------------------- 0N/A// Idealize graph, using DU info. Must clone result into new-space 0N/A return NULL;
// Default to no change 0N/A//------------------------------hash------------------------------------------- 0N/A// Hash function over Nodes. 0N/A//------------------------------cmp-------------------------------------------- 0N/A// Compare special parts of simple Nodes 0N/A return 1;
// Must be same 0N/A//------------------------------rematerialize----------------------------------- 0N/A// Should we clone rather than spill this instruction? 0N/A//------------------------------needs_anti_dependence_check--------------------- 0N/A// Nodes which use memory without consuming it, hence need antidependences. 0N/A// Get an integer constant from a ConNode (or CastIINode). 0N/A// Return a default value if there is no apparent constant here. 0N/A// Get a pointer constant from a ConstNode. 0N/A// Returns the constant if it is a pointer ConstNode 113N/A// Get a narrow oop constant from a ConNNode. 0N/A// Get a long constant from a ConNode. 0N/A// Return a default value if there is no apparent constant here. 0N/A// Get a double constant from a ConstNode. 0N/A// Returns the constant if it is a double ConstNode 0N/A// Get a float constant from a ConstNode. 0N/A// Returns the constant if it is a float ConstNode 0N/A//----------------------------NotANode---------------------------------------- 0N/A// Used in debugging code to avoid walking across dead or uninitialized edges. 0N/A if (((
intptr_t)n &
1) != 0)
return true;
// uninitialized, etc. 0N/A//------------------------------find------------------------------------------ 0N/A// Find a neighbor of this Node with the given _idx 0N/A// If idx is negative, find its absolute value, following both _in and _out. 0N/A if (
NotANode(n))
return;
// Gracefully handle NULL, -1, 0xabababab, etc. 0N/A // Contained in new_space or old_space? 0N/A // Search along forward edges also: 0N/A // Search along debug_orig edges last: 0N/A// call this from debugger: 0N/A//------------------------------find------------------------------------------- 0N/A//------------------------------find_ctrl-------------------------------------- 0N/A// Find an ancestor to this node in the control history with given _idx 0N/A// -----------------------------Name------------------------------------------- 0N/A // Step fast twice for each single step of orig: 0N/A tty->
print_cr(
"BreakAtNode: _idx=%d _debug_idx=%d orig._idx=%d orig._debug_idx=%d",
0N/A//------------------------------dump------------------------------------------ 0N/A // Dump the required and precedence inputs 0N/A return;
// don't process dead nodes 0N/A // Dump node-specific info 0N/A // Dump the non-reset _debug_idx 0N/A//------------------------------dump_req-------------------------------------- 0N/A // Dump the required input edges 0N/A for (
uint i = 0; i <
req(); i++) {
// For all required inputs 0N/A tty->
print(
"NotANode ");
// uninitialized, sentinel, garbage, etc. 0N/A//------------------------------dump_prec------------------------------------- 0N/A // Dump the precedence edges 0N/A for (
uint i =
req(); i <
len(); i++) {
// For all precedence inputs 0N/A//------------------------------dump_out-------------------------------------- 0N/A // Delimit the output edges 0N/A // Dump the output edges 0N/A//------------------------------dump_nodes------------------------------------- 40N/A // do not recurse through top or the root (would reach unrelated stuff) 0N/A//------------------------------dump------------------------------------------- 0N/A//------------------------------dump_ctrl-------------------------------------- 0N/A// Dump a Node's control history to depth 0N/A// For each input edge to a node (ie - for each Use-Def edge), verify that 0N/A// there is a corresponding Def-Use edge. 0N/A//------------------------------verify_edges----------------------------------- 0N/A // Recursive termination test 0N/A // Walk over all input edges, checking for correspondance 0N/A for( i = 0; i <
len(); i++ ) {
0N/A // Count instances of (Node *)this 0N/A // Check for duplicate edges 0N/A // walk the input array downcounting the input edges to n 0N/A for( j = 0; j <
len(); j++ ) {
0N/A // Nothing to check. 0N/A // Recursive walk over all input edges 0N/A for( i = 0; i <
len(); i++ ) {
0N/A//------------------------------verify_recur----------------------------------- 0N/A // Contained in new_space or old_space? 0N/A // Check for visited in the proper space. Numberings are not unique 0N/A // across spaces so we need a seperate VectorSet for each space. 0N/A // Verify my input has a def-use edge to me 0N/A if (
true /*VerifyDefUse*/) {
0N/A // Count use-def edges from n to x 0N/A // Count def-use edges from x to n 0N/A//------------------------------verify----------------------------------------- 0N/A// Check Def-Use info for my subgraph 0N/A//------------------------------walk------------------------------------------- 0N/A// Graph walk, with both pre-order and post-order functions 0N/A pre(*
this,
env);
// Call the pre-order walk function 0N/A if(
in(i) )
// Input exists and is not walked? 0N/A post(*
this,
env);
// Call the post-order walk function 0N/A//------------------------------Registers-------------------------------------- 0N/A// Do we Match on this edge index or not? Generally false for Control 0N/A// and true for everything else. Weird for calls & returns. 0N/A return idx;
// True for other than index 0 (control) 0N/A// Register classes are defined for specific machines 0N/A//============================================================================= 0N/A//----------------------------------------------------------------------------- 0N/A//------------------------------clear------------------------------------------ 0N/A// Clear all entries in _nodes to NULL but keep storage 0N/A//----------------------------------------------------------------------------- 0N/A//----------------------------------------------------------------------------- 0N/A//----------------------------------------------------------------------------- 0N/A//----------------------------------------------------------------------------- 0N/A//----------------------------------------------------------------------------- 0N/A//--------------------------is_iteratively_computed------------------------------ 0N/A// Operation appears to be iteratively computed (such as an induction variable) 0N/A// It is possible for this operation to return false for a loop-varying 0N/A// value, if it appears (by local graph inspection) to be computed by a simple conditional. 0N/A if (
ideal_reg()) {
// does operation have a result register? 0N/A//--------------------------find_similar------------------------------ 0N/A// Return a node with opcode "opc" and same inputs as "this" if one can 0N/A// be found; Otherwise return NULL; 0N/A//--------------------------unique_ctrl_out------------------------------ 0N/A// Return the unique control out if only one. Null if none or more than one. 0N/A//============================================================================= 0N/A//------------------------------yank------------------------------------------- 0N/A//------------------------------dump------------------------------------------- 0N/A//============================================================================= 0N/A//------------------------------remove----------------------------------------- 0N/A//-----------------------remove_useless_nodes---------------------------------- 0N/A// Remove useless nodes from worklist 0N/A // Node *replacement = Node_List::pop(); 0N/A // if( i != size() ) { // Check if removing last entry 0N/A // _nodes[i] = replacement; 0N/A --i;
// Visit popped node 0N/A // If it was last entry, loop terminates since size() was also reduced 0N/A//============================================================================= 0N/A//============================================================================= 0N/A // standard dump does this in Verbose and WizardMode 0N/A//------------------------------ideal_reg--------------------------------------