cfgnode.cpp revision 247
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// Portions of code courtesy of Clifford Click 0N/A// Optimization - Graph Style 0N/A#
include "incls/_precompiled.incl" 0N/A//============================================================================= 0N/A//------------------------------Value------------------------------------------ 0N/A// Compute the type of the RegionNode. 0N/A for(
uint i=
1; i<
req(); ++i ) {
// For all paths in 0N/A if( !n )
continue;
// Missing inputs are TOP 0N/A return Type::
TOP;
// All paths dead? Then so are we 0N/A//------------------------------Identity--------------------------------------- 0N/A// Check for Region being Identity. 0N/A // Cannot have Region be an identity, even if it has only 1 input. 0N/A // Phi users cannot have their Region input folded away for them, 0N/A // since they need to select the proper data input 0N/A//------------------------------merge_region----------------------------------- 0N/A// If a Region flows into a Region, merge into one big happy merge. This is 0N/A// hard to do if there is stuff that has to happen 0N/A r->
in(0) == r &&
// Not already collapsed? 0N/A r->
outcnt() ==
2 ) {
// Self user and 'region' user only? 0N/A return NULL;
// Only flatten if no Phi users 0N/A // igvn->hash_delete( phi ); 0N/A // Append inputs to 'r' onto 'region' 0N/A // Move an input from 'r' to 'region' 0N/A // Update phis of 'region' 0N/A //for( uint k = 0; k < max; k++ ) { 0N/A // Node *phi = region->out(k); 0N/A // if( phi->is_Phi() ) { 0N/A // phi->add_req(phi->in(i)); 0N/A rreq++;
// One more input to Region 0N/A }
// Found a region to merge into Region 0N/A // Clobber pointer to the now dead 'r' 0N/A//--------------------------------has_phi-------------------------------------- 0N/A// Helper function: Return any PhiNode that uses this region or NULL 0N/A//-----------------------------has_unique_phi---------------------------------- 0N/A// Helper function: Return the only PhiNode that uses this region or NULL 0N/A // Check that only one use is a Phi 0N/A//------------------------------check_phi_clipping----------------------------- 0N/A// Helper function for RegionNode's identification of FP clipping 0N/A// Check inputs to the Phi 0N/A//------------------------------check_if_clipping------------------------------ 0N/A// Helper function for RegionNode's identification of FP clipping 0N/A// Check that inputs to Region come from two IfNodes, 0N/A // Check control structure above RegionNode for (if ( if ) ) 0N/A // Check that all inputs are projections 0N/A // Check that #1 and #2 are ifTrue and ifFalse from same If 0N/A // Check that control for in10 comes from other branch of IF from in3 0N/A // Control pattern checks 0N/A//------------------------------check_convf2i_clipping------------------------- 0N/A// Helper function for RegionNode's identification of FP clipping 0N/A// Verify that the value input to the phi comes from "ConvF2I; LShift; RShift" 0N/A // Check for the RShiftNode 0N/A // Check for the LShiftNode 0N/A // Check for the ConvF2INode 0N/A // Check that shift amounts are only to get sign bits set after F2I 0N/A // Shifts are necessary but current transformation eliminates them 0N/A // OK to return the result of ConvF2I without shifting 0N/A//------------------------------check_compare_clipping------------------------- 0N/A// Helper function for RegionNode's identification of FP clipping 0N/A // Test that the float value being compared against 0N/A // is equivalent to the int value used as a limit 0N/A//------------------------------is_unreachable_region-------------------------- 0N/A// Find if the Region node is reachable from the root. 0N/A // First, cut the simple case of fallthrough region when NONE of 0N/A // region's phis references itself directly or through a data node. 0N/A continue;
// Safe case - no loops 0N/A // Skip if only one use is an other Phi or Call or Uncommon trap. 0N/A // It is safe to consider this case as fallthrough. 0N/A // Check when phi references itself directly or through an other node. 0N/A break;
// Found possible unsafe data loop. 0N/A return false;
// An unsafe case was NOT found - don't need graph walk. 0N/A // Unsafe case - check if the Region node is reachable from root. 0N/A // Mark all control nodes reachable from root outputs 0N/A return false;
// We reached the Region node - it is not dead. 0N/A return true;
// The Region node is unreachable - it is dead. 0N/A//------------------------------Ideal------------------------------------------ 0N/A// Return a node which is more "ideal" than the current node. Must preserve 0N/A// the CFG, but we can still strip out dead paths. 0N/A // Check for RegionNode with no Phi users and both inputs come from either 0N/A // arm of the same IF. If found, then the control-flow split is useless. 0N/A // Add the IF Projections to the worklist. They (and the IF itself) 0N/A // will be eliminated if dead. 0N/A return this;
// Record progress 0N/A // Remove TOP or NULL input paths. If only 1 input path remains, this Region 0N/A // degrades to a copy. 0N/A int cnt = 0;
// Count of values merging 0N/A int del_it = 0;
// The last input path we delete 0N/A // For all inputs... 0N/A // Remove useless control copy inputs 0N/A cnt++;
// One more value merging 0N/A while(
progress) {
// Need to establish property over all users 0N/A // If it is LoopNopde it had 2 (+1 itself) inputs and 0N/A // one of them was cut. The loop is dead if it was EntryContol. 0N/A // Yes, the region will be removed during the next step below. 0N/A // Cut the backedge input and remove phis since no data paths left. 0N/A // We don't cut outputs to other nodes here since we need to put them 0N/A // Break dead loop data path. 0N/A // Eagerly replace phis with top to avoid phis copies generation. 0N/A if(
cnt <=
1 ) {
// Only 1 path in? 0N/A // No inputs or all inputs are NULL. 0N/A // During IGVN phase such region will be subsumed by TOP node 0N/A // so region's phis will have TOP as control node. 0N/A // Kill phis here to avoid it. PhiNode::is_copy() will be always false. 0N/A // Also set other user's input to top. 0N/A // The fallthrough case since we already checked dead loops above. 0N/A // Eagerly replace phis to avoid copies generation. 0N/A // Remove the RegionNode itself from DefUse info 0N/A return this;
// Record progress 0N/A // If a Region flows into a Region, merge into one big happy merge. 0N/A // Check if this region is the root of a clipping idiom on floats 0N/A // Check that only one use is a Phi and that it simplifies to two constants + 0N/A // Check inputs to the Phi 0N/A // Control pattern checks, now verify compares 0N/A // Only remaining check is that bot_in == top_in == (Phi's val + mods) 0N/A // Check for the ConvF2INode 0N/A // Matched pattern, including LShiftI; RShiftI, replace with integer compares 0N/A // update input edges to region node 0N/A // remove unnecessary 'LShiftI; RShiftI' idiom 0N/A // Return transformed region node 0N/A// Find the one non-null required input. RegionNode only 0N/A//============================================================================= 0N/A// note that these functions assume that the _adr_type field is flattened 0N/A//----------------------------make--------------------------------------------- 0N/A// create a new phi with edges matching r and set (initially) to x 0N/A // Fill in all inputs, except those which the region does not yet have 0N/A//------------------------slice_memory----------------------------------------- 0N/A// create a new phi with narrowed memory type 0N/A // convert self-loops, or else we get a bad graph 74N/A//------------------------split_out_instance----------------------------------- 74N/A// Split out an instance type from a bottom phi. 163N/A "bottom or raw memory required");
74N/A // Check if an appropriate node already exists. 74N/A i = 0;
// will get incremented at top of loop 0N/A//------------------------verify_adr_type-------------------------------------- 0N/A // recheck constructor invariants: 0N/A "adr_type must be consistent across phi nest");
0N/A // ignore top inputs 0N/A "adr_type must be consistent at leaves of phi nest");
0N/A// Verify a whole nest of phis rooted at this one. 0N/A "Phi::adr_type must be pre-normalized");
0N/A//------------------------------Value------------------------------------------ 0N/A// Compute the type of the PhiNode 0N/A if( !r )
// Copy or dead 0N/A // Note: During parsing, phis are often transformed before their regions. 0N/A // This means we have to use type_or_null to defend against untyped regions. 0N/A // Check for trip-counted loop. If so, be smarter. 0N/A ((
const Node*)l->
phi() ==
this) ) {
// Trip counted loop! 0N/A // protect against init_trip() or limit() returning NULL 0N/A if(
lo &&
hi ) {
// Dying loops might have TOP here 0N/A if(
lo->
_hi <
hi->
_lo )
// Reversed endpoints are well defined :-( 0N/A // Until we have harmony between classes and interfaces in the type 0N/A // lattice, we must tread carefully around phis which implicitly 0N/A // convert the one to the other. 0N/A // Default case: merge all inputs 0N/A for (
uint i =
1; i <
req(); ++i) {
// For all paths in 0N/A // Reachable control path? 0N/A // We assume that each input of an interface-valued Phi is a true 0N/A // subtype of that interface. This might not be true of the meet 0N/A // of all the input types. The lattice is not distributive in 0N/A // such cases. Ward off asserts in type.cpp by refusing to do 0N/A // meets between interfaces and proper classes. 0N/A // The worst-case type (from ciTypeFlow) should be consistent with "t". 0N/A // That is, we expect that "t->higher_equal(_type)" holds true. 0N/A // There are various exceptions: 0N/A // - Inputs which are phis might in fact be widened unnecessarily. 0N/A // For example, an input might be a widened int while the phi is a short. 0N/A // - Inputs might be BotPtrs but this phi is dependent on a null check, 0N/A // and postCCP has removed the cast which encodes the result of the check. 0N/A // - The type of this phi is an interface, and the inputs are classes. 0N/A // - Value calls on inputs might produce fuzzy results. 0N/A // (Occurrences of this case suggest improvements to Value methods.) 0N/A // It is not possible to see Type::BOTTOM values as phi inputs, 0N/A // because the ciTypeFlow pre-pass produces verifier-quality types. 0N/A // The following logic has been moved into TypeOopPtr::filter. 0N/A // Check for evil case of 't' being a class and '_type' expecting an 0N/A // interface. This can happen because the bytecodes do not contain 0N/A // enough type info to distinguish a Java-level interface variable 0N/A // from a Java-level object variable. If we meet 2 classes which 0N/A // both implement interface I, but their meet is at 'j/l/O' which 0N/A // doesn't implement I, we have no way to tell if the result should 0N/A // be 'I' or 'j/l/O'. Thus we'll pick 'j/l/O'. If this then flows 0N/A // into a Phi which "knows" it's an Interface type we'll have to 0N/A // Otherwise it's something stupid like non-overlapping int ranges 0N/A // found on dying counted loops. 0N/A // If we have an interface-typed Phi and we narrow to a class type, the join 0N/A // should report back the class. However, if we have a J/L/Object 0N/A // class-typed Phi and an interface flows in, it's possible that the meet & 0N/A // join report an interface back out. This isn't possible but happens 0N/A // because the type system doesn't interact well with interfaces. 0N/A // Happens in a CTW of rt.jar, 320-341, no extra flags 0N/A // Deal with conversion problems found in data loops. 0N/A//------------------------------is_diamond_phi--------------------------------- 0N/A// Does this Phi represent a simple well-shaped diamond merge? Return the 0N/A// index of the true path or 0 otherwise. 0N/A // Check for a 2-path merge 0N/A // Check that both paths come from the same If 0N/A // Check for branching opposite expected 0N/A//----------------------------check_cmove_id----------------------------------- 0N/A// Check for CMove'ing a constant after comparing against the constant. 0N/A// Happens all the time now, since if we compare equality vs a constant in 0N/A// the parser, we "know" the variable is constant on one path and we force 0N/A// it. Thus code like "if( x==0 ) {/*EMPTY*/}" ends up inserting a 0N/A// conditional move: "x = (x==0)?0:x;". Yucko. This fix is slightly more 0N/A// general in that we don't need constants. Since CMove's are only inserted 0N/A// in very special circumstances, we do it here on generic Phi's. 0N/A // is_diamond_phi() has guaranteed the correctness of the nodes sequence: 0N/A // phi->region->if_proj->ifnode->bool->cmp 0N/A // Either value might be a cast that depends on a branch of 'iff'. 0N/A // Since the 'id' value will float free of the diamond, either 0N/A // decast or return failure. 0N/A // Don't know how to disentangle this value. 0N/A//------------------------------Identity--------------------------------------- 0N/A// Check for Region being Identity. 0N/A // Check for no merging going on 0N/A // (There used to be special-case code here when this->region->is_Loop. 0N/A // It would check for a tributary phi on the backedge that the main phi 0N/A // trivially, perhaps with a single cast. The unique_input method 0N/A // does all this and more, by reducing such tributaries to 'this'.) 0N/A return this;
// No identity 0N/A//-----------------------------unique_input------------------------------------ 0N/A// Find the unique value, discounting top, self-loops, and casts. 0N/A// Return top if there are no inputs, and self if there are multiple. 0N/A // 1) One unique direct input, or 0N/A // 2) some of the inputs have an intervening ConstraintCast and 0N/A // the type of input is the same or sharper (more specific) 0N/A // than the phi's type. 0N/A // 3) an input is a self loop 0N/A // 1) input or 2) input or 3) input __ 0N/A // \ / | cast phi cast 0N/A if (r ==
NULL)
return in(
1);
// Already degraded to a Copy 0N/A continue;
// ignore unreachable control path 0N/A continue;
// ignore if top, or in(i) and "this" are in a data cycle 0N/A // Check for a unique uncasted input 0N/A // Check for a unique direct input 0N/A//------------------------------is_x2logic------------------------------------- 0N/A// Check for simple convert-to-boolean pattern 0N/A// If:(C Bool) Region:(IfF IfT) Phi:(Region 0 1) 0N/A// Convert Phi to an ConvIB. 0N/A // Convert the true/false index into an expected 0/1 return. 0N/A // Map 2->0 and 1->1. 0N/A // is_diamond_phi() has guaranteed the correctness of the nodes sequence: 0N/A // phi->region->if_proj->ifnode->bool->cmp 0N/A // Check for compare vs 0 0N/A // Allow cmp-vs-1 if the other input is bounded by 0-1 0N/A // Check for boolean test backwards 0N/A // Build int->bool conversion 0N/A//------------------------------is_cond_add------------------------------------ 0N/A// Check for simple conditional add pattern: "(P < Q) ? X+Y : X;" 0N/A// To be profitable the control flow has to disappear; there can be no other 0N/A// values merging here. We replace the test-and-branch with: 0N/A// "(sgn(P-Q))&Y) + X". Basically, convert "(P < Q)" into 0 or -1 by 0N/A// moving the carry bit from (P-Q) into a register with 'sbb EAX,EAX'. 0N/A// Then convert Y to 0-or-Y and finally add. 0N/A// This is a key transform for SpecJava _201_compress. 0N/A // is_diamond_phi() has guaranteed the correctness of the nodes sequence: 0N/A // phi->region->if_proj->ifnode->bool->cmp 0N/A // Make sure only merging this one phi here 0N/A // Make sure each arm of the diamond has exactly one output, which we assume 0N/A // is the region. Otherwise, the control flow won't disappear. 0N/A // Check for "(P < Q)" of type signed int 0N/A /*&&op != Op_SubI && 0N/A // Not so profitable if compare and add are constants 0N/A//------------------------------is_absolute------------------------------------ 0N/A// Check for absolute value. 0N/A int phi_x_idx = 0;
// Index of phi input where to find naked x 0N/A // ABS ends with the merge of 2 control flow paths. 0N/A // Find the false path from the true path. With only 2 inputs, 3 - x works nicely. 0N/A // is_diamond_phi() has guaranteed the correctness of the nodes sequence: 0N/A // phi->region->if_proj->ifnode->bool->cmp 0N/A // Find zero input of compare; the other input is being abs'd 0N/A // The test is inverted, we should invert the result... 0N/A // Next get the 2 pieces being selected, one is the original value 0N/A // and the other is the negated value. 0N/A // Check other phi input for subtract node 0N/A // Allow only Sub(0,X) and fail out for all others; Neg is not OK 0N/A//------------------------------split_once------------------------------------- 0N/A// Helper for split_flow_path 0N/A // Register the new node but do not transform it. Cannot transform until the 0N/A // entire Region/Phi conglerate has been hacked as a single huge transform. 0N/A // Now I can point to the new node. 0N/A//------------------------------split_flow_path-------------------------------- 0N/A// Check for merging identical values and split flow paths 0N/A return NULL;
// Bail out on funny non-value stuff 0N/A if(
phi->
req() <=
3 )
// Need at least 2 matched inputs and a 0N/A return NULL;
// third unequal input to be worth doing 0N/A // Scan for a constant 0N/A if( i >=
phi->
req() )
// Only split for constants 0N/A for( ; i <
phi->
req(); i++ ){
// Count occurances of constant 0N/A if(
hit <=
1 ||
// Make sure we find 2 or more 0N/A // Now start splitting out the flow paths that merge the same value. 0N/A // Split first the RegionNode. 0N/A // Now split all other Phis than this one 0N/A // Clean up this guy 0N/A//============================================================================= 0N/A//------------------------------simple_data_loop_check------------------------- 0N/A// Try to determing if the phi node in a simple safe/unsafe data loop. 0N/A// enum LoopSafety { Safe = 0, Unsafe, UnsafeLoop }; 0N/A// Safe - safe case when the phi and it's inputs reference only safe data 0N/A// Unsafe - the phi and it's inputs reference unsafe data nodes but there 0N/A// is no reference back to the phi - need a graph walk 0N/A// to determine if it is in a loop; 0N/A// UnsafeLoop - unsafe case when the phi references itself directly or through 0N/A// Note: a safe data node is a node which could/never reference itself during 0N/A// GVN transformations. For now it is Con, Proj, Phi, CastPP, CheckCastPP. 0N/A// I mark Phi nodes as safe node not only because they can reference itself 0N/A// but also to prevent mistaking the fallthrough case inside an outer loop 0N/A// as dead loop when the phi references itselfs through an other phi. 0N/A // It is unsafe loop if the phi node references itself directly. 0N/A // Unsafe loop if the phi node references itself through an unsafe data node. 0N/A // Exclude cases with null inputs or data nodes which could reference 0N/A // itself (safe for dead loops). 0N/A // Check inputs of phi's inputs also. 0N/A // It is much less expensive then full graph walk. 0N/A // Check the most common case (about 30% of all cases): 0N/A continue;
// Safe case 0N/A // The phi references an unsafe node - need full analysis. 0N/A return Safe;
// Safe case - we can optimize the phi node. 0N/A//------------------------------is_unsafe_data_reference----------------------- 0N/A// If phi can be reached through the data input - it is data loop. 0N/A // First, check simple cases when phi references itself directly or 0N/A // through an other node. 0N/A return true;
// phi references itself - unsafe loop 0N/A return false;
// Safe case - phi could be replaced with the unique input. 0N/A // Unsafe case when we should go through data graph to determine 0N/A // if the phi references itself. 0N/A return true;
// Data loop 0N/A return false;
// The phi is not reachable from its inputs 0N/A//------------------------------Ideal------------------------------------------ 0N/A// Return a node which is more "ideal" than the current node. Must preserve 0N/A// the CFG, but we can still strip out dead paths. 0N/A // The next should never happen after 6297035 fix. 0N/A // Note: During parsing, phis are often transformed before their regions. 0N/A // This means we have to use type_or_null to defend against untyped regions. 0N/A // The are 2 situations when only one valid phi's input is left 0N/A // (in addition to Region input). 0N/A // One: region is not loop - replace phi with this input. 0N/A // Two: region is loop - replace phi with top since this data path is dead 0N/A // and we need to break the dead data loop. 0N/A for(
uint j =
1; j <
req(); ++j ){
// For all paths in 0N/A // Check unreachable control paths 0N/A if (n !=
top) {
// Not already top? 0N/A if (
uin ==
top) {
// Simplest case: no alive inputs. 0N/A return NULL;
// Identity will return TOP 0N/A // Only one not-NULL unique input path is left. 0N/A // Determine if this input is backedge of a loop. 0N/A // (Skip new phis which have no uses and dead regions). 0N/A // First, take the short cut when we know it is a loop and 0N/A // the EntryControl data path is dead. 0N/A // Then, check if there is a data loop when phi references itself directly 0N/A // or through other data nodes. 0N/A // Break this data loop to avoid creation of a dead loop. 0N/A // We can't return top if we are in Parse phase - cut inputs only 0N/A // let Identity to handle the case. 0N/A // One unique input. 0N/A // The unique input must eventually be detected by the Identity call. 0N/A // print this output before failing assert 0N/A // Check for CMove'ing identity. If it would be unsafe, 0N/A // handle it here. In the safe case, let Identity handle it. 0N/A // Check for simple convert-to-boolean pattern 0N/A // Check for absolute value 0N/A // Check for conditional add 0N/A // These 4 optimizations could subsume the phi: 0N/A // have to check for a dead data loop creation. 0N/A // We can't return top if we are in Parse phase - cut inputs only 0N/A // to stop further optimizations for this phi. Identity will return TOP. 0N/A // Check for merging identical values and split flow paths 0N/A // This optimization only modifies phi - don't need to check for dead loop. 0N/A // Split phis through memory merges, so that the memory merges will go away. 0N/A // Piggy-back this transformation on the search for a unique input.... 0N/A // It will be as if the merged memory is the unique value of the phi. 0N/A // (Do not attempt this optimization unless parsing is complete. 0N/A // It would make the parser's memory-merge logic sick.) 0N/A // (MergeMemNode is not dead_loop_safe - need to check for dead loop.) 0N/A // see if this phi should be sliced 0N/A for(
uint i=
1; i<
req(); ++i ) {
// For all paths in 0N/A // This restriction is temporarily necessary to ensure termination: 0N/A // found at least one non-empty MergeMem 0N/A // Patch the existing phi to select an input from the merge: 0N/A // Phi:AT1(...MergeMem(m0, m1, m2)...) into 0N/A // Phi:AT1(...m1...) 0N/A // compress paths and change unreachable cycles to TOP 0N/A // If not, we can update the input infinitely along a MergeMem cycle 0N/A // Equivalent code is in MemNode::Ideal_common 0N/A // If tranformed to a MergeMem, get the desired slice 0N/A // Otherwise the returned node represents memory for every slice 0N/A // Update input if it is progress over what we have now 0N/A // We know that at least one MergeMem->base_memory() == this 0N/A // (saw_self == true). If all other inputs also references this phi 0N/A // (directly or through data nodes) - it is dead loop. 0N/A continue;
// skip known cases 0N/A return top;
// all inputs reference back to this phi - dead loop 0N/A // Phi(...MergeMem(m0, m1:AT1, m2:AT2)...) into 0N/A // MergeMem(Phi(...m0...), Phi:AT1(...m1...), Phi:AT2(...m2...)) 0N/A // Must eagerly register phis, since they participate in loops. 0N/A // If we have not seen this slice yet, make a phi for it. 0N/A // Distribute all self-loops. 0N/A {
// (Extra braces to hide mms.) 0N/A // now transform the new nodes, and return the mergemem 0N/A // Replace self with the result. 74N/A // Other optimizations on the memory chain 0N/A//------------------------------out_RegMask------------------------------------ 0N/A//============================================================================= 0N/A // If the input is reachable, then we are executed. 0N/A // If the input is not reachable, then we are not executed. 0N/A return in(0);
// Simple copy of incoming control 0N/A//============================================================================= 0N/A//============================================================================= 0N/A//============================================================================= 0N/A//============================================================================= 0N/A//------------------------------Value------------------------------------------ 0N/A// Compute the type of the PCTableNode. If reachable it is a tuple of 0N/A// Control, otherwise the table targets are not reachable 0N/A return Type::
TOP;
// All paths dead? Then so are we 0N/A//------------------------------Ideal------------------------------------------ 0N/A// Return a node which is more "ideal" than the current node. Strip out 0N/A//============================================================================= 0N/A//============================================================================= 0N/A//------------------------------Value------------------------------------------ 0N/A// Check for being unreachable, or for coming from a Rethrow. Rethrow's cannot 0N/A// have the default "fall_through_index" path. 0N/A // Unreachable? Then so are all paths from here. 0N/A // First assume all paths are reachable 0N/A // Identify cases that will always throw an exception 0N/A // () virtual or interface call with NULL receiver 0N/A // () call is a check cast with incompatible arguments 0N/A // Rethrows always throw exceptions, never return 0N/A // Check for null reciever to virtual or interface calls 0N/A }
// End of if not a runtime stub 0N/A }
// End of if have call above me 0N/A }
// End of slot 1 is not a projection 0N/A//============================================================================= 0N/A//------------------------------Identity--------------------------------------- 0N/A// If only 1 target is possible, choose it if it is the main control 0N/A // If my value is control and no other value is, then treat as ID 0N/A // also remove any exception table entry. Thus we must know the call 0N/A // feeding the Catch will not really throw an exception. This is ok for 0N/A // the main fall-thru control (happens when we know a call can never throw 0N/A // an exception) or for "rethrow", because a further optimnization will 0N/A // yank the rethrow (happens when we inline a function that can throw an 0N/A // exception and the caller has no handler). Not legal, e.g., for passing 0N/A // a NULL receiver to a v-call, or passing bad types to a slow-check-cast. 0N/A // These cases MUST throw an exception via the runtime system, so the VM 0N/A // will be looking for a table entry. 0N/A // Search for any other path being control 0N/A // Only my path is possible; I am identity on control to the jump 0N/A//============================================================================= 0N/A//------------------------------Identity--------------------------------------- 0N/A// Check for CreateEx being Identity. 0N/A // We only come from CatchProj, unless the CatchProj goes away. 0N/A // If the CatchProj is optimized away, then we just carry the 0N/A // exception oop through. 0N/A//============================================================================= 127N/A//------------------------------Value------------------------------------------ 127N/A// Check for being unreachable. 127N/A//------------------------------Ideal------------------------------------------ 127N/A// Check for no longer being part of a loop 127N/A // Dead code elimination can sometimes delete this projection so 127N/A // if it's not there, there's nothing to do.