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