node.cpp revision 4022
1472N/A * Copyright (c) 1997, 2012, Oracle and/or its affiliates. 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. 1472N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1879N/A// Arena we are currently building Nodes in 1879N/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 1703N/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 // Allocate memory for the necessary number of edges. 0N/A // Allocate space for _in array to have double alignment. 0N/A _in[
req-
1] =
this;
// magic cookie for assertion check 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 710N/A // Free just the input array 1208N/A // We will not actually delete the storage, but we'll make the node unusable. 1206N/A//------------------------------grow------------------------------------------- 1206N/A// Grow the input array, making space for more edges 1703N/A // Trimming to limit allows a uint8 to handle up to 255 edges. 1703N/A // Previously I was using only powers-of-2 which peaked at 128 edges. 1703N/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 1202N/A // Insert multiple out edges on the node. 1202N/A//------------------------------del_req---------------------------------------- 1202N/A// Delete the required edge and compact the edge array 0N/A "remove node from hash table before modifying it");
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--------------------------------------- 1612N/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;
48N/A // Node::destruct requires all out edges be deleted first 48N/A // debug_only(destruct();) // no reuse benefit expected 48N/A//-----------------------------uncast--------------------------------------- 48N/A// %%% Temporary, until we sort out CheckCastPP vs. CastPP. 48N/A// Strip away casting. (It is depth-limited.) 48N/A // Should be inline: 48N/A //return is_ConstraintCast() ? uncast_helper(this) : (Node*) this; 48N/A//---------------------------uncast_helper------------------------------------- 710N/A//------------------------------add_prec--------------------------------------- 710N/A// Add a new precedence input. Precedence inputs are unordered, with 710N/A// duplicates removed and NULLs packed down at the end. 710N/A // Check for NULL at end 710N/A // Find a precedence edge to move 710N/A _in[i] = n;
// Stuff prec edge over NULL 1152N/A//------------------------------rm_prec---------------------------------------- 1152N/A// Remove a precedence input. Precedence inputs are unordered, with 1427N/A// duplicates removed and NULLs packed down at the end. 1582N/A // Find end of precedence list to pack NULLs 1582N/A if( !
_in[i] )
// Find the NULL at end of prec edge list 710N/A//------------------------------size_of---------------------------------------- 710N/A//------------------------------ideal_reg-------------------------------------- 710N/A//------------------------------jvms------------------------------------------- 710N/A//------------------------------jvms------------------------------------------- 710N/A//------------------------------init_NodeProperty------------------------------ 710N/A//------------------------------format----------------------------------------- 710N/A//------------------------------emit------------------------------------------- 710N/A// Emit bytes starting at parameter 'ptr'. 710N/A//------------------------------size------------------------------------------- 710N/A// Size of instruction in bytes 710N/A//------------------------------CFG Construction------------------------------- 710N/A// Minimum guaranteed type 710N/A//------------------------------raise_bottom_type------------------------------ 710N/A// Get the worst-case Type output for this Node. 710N/A//------------------------------Identity--------------------------------------- 710N/A// Return a node that the given node is equivalent to. 1039N/A return this;
// Default to no identities 710N/A//------------------------------Value------------------------------------------ 710N/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 518N/A// hacking an Ideal call, be sure to test with +VerifyIterativeGVN! 518N/A// The Ideal call almost arbitrarily reshape the graph rooted at the 'this' 518N/A// pointer. If ANY change is made, it must return the root of the reshaped 518N/A// graph - even if the root is the same Node. Example: swapping the inputs 518N/A// to an AddINode gives the same answer and same root, but you still have to 518N/A// return the 'this' pointer instead of NULL. 518N/A// You cannot return an OLD Node, except for the 'this' pointer. Use the 518N/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 518N/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 518N/A// "X+3" unchanged in case it is shared. 518N/A// If you modify the 'this' pointer's inputs, you should use 518N/A// 'set_req'. If you are making a new Node (either as the new root or 518N/A// some new internal piece) you may use 'init_req' to set the initial 518N/A// value. You can make a new Node with either 'new' or 'clone'. In 518N/A// either case, def-use info is correctly maintained. 0N/A// Example: reshape "(X+3)+4" into "X+7": 518N/A// set_req(1, in(1)->in(1)); 0N/A// set_req(2, phase->intcon(7)); 0N/A// Example: reshape "X*4" into "X<<2" 0N/A// return new (C) LShiftINode(in(1), phase->intcon(2)); 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)-X". 0N/A// Node *shift=phase->transform(new(C)LShiftINode(in(1),phase->intcon(5))); 0N/A// return new (C) AddINode(shift, in(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) 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. 518N/A // Condition for back-to-back stores folding. 518N/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) 0N/A//--------------------------find_exact_control--------------------------------- 0N/A// Skip Proj and CatchProj nodes chains. Check for Null and Top. 0N/A//--------------------------dominates------------------------------------------ 1713N/A// Helper function for MemNode::all_controls_dominate(). 1713N/A// Check if 'this' control node dominates or equal to 'sub' control node. 0N/A// We already know that if any path back to Root or Start reaches 'this', 0N/A// then all paths so, so this is a simple search for one example, 856N/A// not an exhaustive search for a counterexample. 856N/A // detect dead cycle without regions 0N/A // Walk 'sub' backward up the chain to 'dom', watching for regions. 0N/A // After seeing 'dom', continue up to Root or Start. 0N/A // If we hit a region (backward split point), it may be a loop head. 856N/A // Keep going through one of the region's inputs. If we reach the 0N/A // same region again, go through a different input. Eventually we 0N/A // will either exit through the loop head, or give up. 1427N/A // (If we get confused, break out and return a conservative 'false'.) 1427N/A // No Region nodes except loops were visited before and the EntryControl 1427N/A // path was taken for loops: it did not walk in a cycle. 1713N/A break;
// already met before: walk in a cycle 1713N/A // Region nodes were visited. Continue walk up to Start or Root 1713N/A // to make sure that it did not walk in a cycle. 1427N/A // Success if we met 'dom' along a path to Start or Root. 1427N/A // We assume there are no alternative paths that avoid 'dom'. 1427N/A // (This assumption is up to the caller to ensure!) 856N/A // Normalize simple pass-through regions and projections: 856N/A // If sub == up, we found a self-loop. Try to push past it. 0N/A // Take loop entry path on the way up to 'dom'. 0N/A // Always take in(1) path on the way up to 'dom' for clone regions 0N/A // (with only one input) or regions which merge > 2 paths 0N/A // Try both paths for Regions with 2 input paths (it may be a loop head). 0N/A // It could give conservative 'false' answer without information 0N/A // which region's input is the entry path. 104N/A // Was this Region node visited before? 104N/A // If so, we have reached it because we accidentally took a 0N/A // loop-back edge from 'sub' back into the body of the loop, 1142N/A // and worked our way up again to the loop header 'sub'. 1142N/A // So, take the first unexplored path on the way up to 'dom'. 0N/A // Visited 2 paths, but still stuck in loop body. Give up. 0N/A // The Region node was visited before only once. 0N/A // (We will repush with the low bit set, below.) 0N/A // We will find a new edge and re-insert. 0N/A // Find an incoming edge which has not been seen yet; walk through it. 0N/A --
skip;
// skip this nontrivial input 0N/A // Set 0 bit to indicate that both paths were taken. 0N/A break;
// some kind of tight cycle 0N/A // returned back after visiting 'dom' 0N/A break;
// some kind of cycle 0N/A break;
// dead cycle 0N/A // Did not meet Root or Start node in pred. chain. 0N/A // Conservative answer for dead code. 0N/A//------------------------------remove_dead_region----------------------------- 1418N/A// This control node is dead. Follow the subgraph below it making everything 1418N/A// using it dead as well. This will happen normally via the usual IterGVN 1418N/A// worklist but this call is more efficient. Do not update use-def info 1418N/A// inside the dead region, just at the borders. 1418N/A // Con's are a popular node to re-hit in the hash table again. 1418N/A // Can't put ResourceMark here since igvn->_worklist uses the same arena 1418N/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 return false;
// Node is dead. 0N/A//------------------------------Ideal_DU_postCCP------------------------------- 0N/A// Idealize graph, using DU info. Must clone result into new-space 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 0N/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? Check old_arena first since it's mostly empty. 0N/A // Search along forward edges also: 0N/A // Search along debug_orig edges last, checking for cycles 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------------------------------------------- 1703N/A // Step fast twice for each single step of orig: 1703N/A tty->
print_cr(
"BreakAtNode: _idx=%d _debug_idx=%d orig._idx=%d orig._debug_idx=%d",
1703N/A//------------------------------dump------------------------------------------ 1703N/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 // Dump MachSpillcopy vector type. //------------------------------dump_req-------------------------------------- // Dump the required input edges for (
uint i = 0; i <
req(); i++) {
// For all required inputs tty->
print(
"NotANode ");
// uninitialized, sentinel, garbage, etc. //------------------------------dump_prec------------------------------------- // Dump the precedence edges for (
uint i =
req(); i <
len(); i++) {
// For all precedence inputs //------------------------------dump_out-------------------------------------- // Delimit the output edges for (
uint i = 0; i <
_outcnt; i++) {
// For all outputs //------------------------------dump_nodes------------------------------------- // do not recurse through top or the root (would reach unrelated stuff) for(
int j =
end-
1; j >= 0; j--) {
for(
int j = 0; j <
end; j++) {
//------------------------------dump------------------------------------------- //------------------------------dump_ctrl-------------------------------------- // Dump a Node's control history to depth // For each input edge to a node (ie - for each Use-Def edge), verify that // there is a corresponding Def-Use edge. //------------------------------verify_edges----------------------------------- // Recursive termination test // Walk over all input edges, checking for correspondence for( i = 0; i <
len(); i++ ) {
// Count instances of (Node *)this assert(
cnt > 0,
"Failed to find Def-Use edge." );
// Check for duplicate edges // walk the input array downcounting the input edges to n for( j = 0; j <
len(); j++ ) {
// Recursive walk over all input edges for( i = 0; i <
len(); i++ ) {
//------------------------------verify_recur----------------------------------- // Contained in new_space or old_space? // Check for visited in the proper space. Numberings are not unique // across spaces so we need a separate VectorSet for each space. for(
uint i = 0; i < n->
len(); i++ ) {
if (!x || x->
is_top())
continue;
// Verify my input has a def-use edge to me if (
true /*VerifyDefUse*/) {
// Count use-def edges from n to x for(
uint j = 0; j < n->
len(); j++ )
// Count def-use edges from x to n assert(
cnt == 0,
"mismatched def-use edge counts" );
//------------------------------verify----------------------------------------- // Check Def-Use info for my subgraph //------------------------------walk------------------------------------------- // Graph walk, with both pre-order and post-order functions pre(*
this,
env);
// Call the pre-order walk function if(
in(i) )
// Input exists and is not walked? post(*
this,
env);
// Call the post-order walk function //------------------------------Registers-------------------------------------- // Do we Match on this edge index or not? Generally false for Control // and true for everything else. Weird for calls & returns. return idx;
// True for other than index 0 (control) // Register classes are defined for specific machines //============================================================================= //----------------------------------------------------------------------------- //------------------------------clear------------------------------------------ // Clear all entries in _nodes to NULL but keep storage //----------------------------------------------------------------------------- while( i >=
_max )
_max <<=
1;
// Double to fit //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- //--------------------------is_iteratively_computed------------------------------ // Operation appears to be iteratively computed (such as an induction variable) // It is possible for this operation to return false for a loop-varying // value, if it appears (by local graph inspection) to be computed by a simple conditional. if (
ideal_reg()) {
// does operation have a result register? for (
uint j =
1; j < n->
req(); j++) {
//--------------------------find_similar------------------------------ // Return a node with opcode "opc" and same inputs as "this" if one can // be found; Otherwise return NULL; for (j = 0; j <
use->
req(); j++) {
//--------------------------unique_ctrl_out------------------------------ // Return the unique control out if only one. Null if none or more than one. //============================================================================= //------------------------------yank------------------------------------------- for( i = 0; i <
_cnt; i++ )
//------------------------------dump------------------------------------------- //============================================================================= //------------------------------remove----------------------------------------- //-----------------------remove_useless_nodes---------------------------------- // Remove useless nodes from worklist assert( n !=
NULL,
"Did not expect null entries in worklist");
// Node *replacement = Node_List::pop(); // if( i != size() ) { // Check if removing last entry // _nodes[i] = replacement; --i;
// Visit popped node // If it was last entry, loop terminates since size() was also reduced //============================================================================= // Node_Stack is used to map nodes. //============================================================================= // standard dump does this in Verbose and WizardMode //------------------------------ideal_reg--------------------------------------