src/share/vm/opto/opaquenode.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Cdiff src/share/vm/opto/opaquenode.cpp

src/share/vm/opto/opaquenode.cpp

Print this page
rev 7063 : 8054478: C2: Incorrectly compiled char[] array access crashes JVM
Summary: propagate node replacements along control flow edges to callers
Reviewed-by: dead backbranch in main loop results in erroneous array access

*** 21,51 **** * questions. * */ #include "precompiled.hpp" #include "opto/opaquenode.hpp" #include "opto/phaseX.hpp" //============================================================================= // Do not allow value-numbering uint Opaque1Node::hash() const { return NO_HASH; } ! uint Opaque1Node::cmp( const Node &n ) const { return (&n == this); // Always fail except on self } //------------------------------Identity--------------------------------------- // If _major_progress, then more loop optimizations follow. Do NOT remove // the opaque Node until no more loop ops can happen. Note the timing of // _major_progress; it's set in the major loop optimizations THEN comes the // call to IterGVN and any chance of hitting this code. Hence there's no // phase-ordering problem with stripping Opaque1 in IGVN followed by some // more loop optimizations that require it. ! Node *Opaque1Node::Identity( PhaseTransform *phase ) { return phase->C->major_progress() ? this : in(1); } //============================================================================= // A node to prevent unwanted optimizations. Allows constant folding. Stops // value-numbering, most Ideal calls or Identity functions. This Node is // specifically designed to prevent the pre-increment value of a loop trip // counter from being live out of the bottom of the loop (hence causing the --- 21,93 ---- * questions. * */ #include "precompiled.hpp" + #include "opto/loopnode.hpp" #include "opto/opaquenode.hpp" #include "opto/phaseX.hpp" //============================================================================= // Do not allow value-numbering uint Opaque1Node::hash() const { return NO_HASH; } ! uint Opaque1Node::cmp(const Node &n) const { return (&n == this); // Always fail except on self } //------------------------------Identity--------------------------------------- // If _major_progress, then more loop optimizations follow. Do NOT remove // the opaque Node until no more loop ops can happen. Note the timing of // _major_progress; it's set in the major loop optimizations THEN comes the // call to IterGVN and any chance of hitting this code. Hence there's no // phase-ordering problem with stripping Opaque1 in IGVN followed by some // more loop optimizations that require it. ! Node *Opaque1Node::Identity(PhaseTransform *phase) { return phase->C->major_progress() ? this : in(1); } + Node *Opaque1Node::Ideal(PhaseGVN *phase, bool can_reshape) { + if (!phase->C->major_progress() && outcnt() > 0) { + assert(can_reshape, "loop opts over but not IGVN?"); + if (raw_out(0)->Opcode() == Op_CmpI) { + Node* cmp = raw_out(0); + if (cmp->in(1)->Opcode() == Op_AddI) { + Node *add = cmp->in(1); + if (add->in(1)->is_Phi()) { + Node* phi = add->in(1); + if (phi->in(0)->is_CountedLoop()) { + CountedLoopNode* cl = phi->in(0)->as_CountedLoop(); + if (cl->phi() == phi) { + // If this opaque node feeds into the limit condition of + // a CountedLoop, we need to process the Phi node for + // the induction variable: the range of values taken by + // the Phi is known now and so its type is also known. + phase->is_IterGVN()->_worklist.push(phi); + } + } + } + } + Node* in1 = cmp->in(1); + for (uint i = 0; i < in1->outcnt(); i++) { + if (in1->raw_out(i)->Opcode() == Op_CastII) { + Node* castii = in1->raw_out(i); + if (castii->in(0) != NULL && castii->in(0)->in(0) != NULL && castii->in(0)->in(0)->is_If()) { + Node* ifnode = castii->in(0)->in(0); + if (ifnode->in(1) != NULL && ifnode->in(1)->in(1) == cmp) { + // Reprocess a CastII node that may depend on this + // opaque node value in case it's inexact and we can do + // a better job of setting its type. + phase->is_IterGVN()->_worklist.push(castii); + } + } + } + } + } + } + return NULL; + } + //============================================================================= // A node to prevent unwanted optimizations. Allows constant folding. Stops // value-numbering, most Ideal calls or Identity functions. This Node is // specifically designed to prevent the pre-increment value of a loop trip // counter from being live out of the bottom of the loop (hence causing the
src/share/vm/opto/opaquenode.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File