src/share/vm/opto/opaquenode.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
*** old/src/share/vm/opto/opaquenode.cpp Wed Sep 17 18:42:42 2014
--- new/src/share/vm/opto/opaquenode.cpp Wed Sep 17 18:42:42 2014
*** 21,51 ****
--- 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