changeset 253:b0fe4deeb9fb

6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.") Summary: Escape Analysis fixes. Reviewed-by: never, rasbold
author kvn
date Mon, 28 Jul 2008 17:12:52 -0700
parents be7facf71163
children 3e333d6f35dd
files src/share/vm/opto/c2_globals.hpp src/share/vm/opto/compile.cpp src/share/vm/opto/escape.cpp src/share/vm/opto/escape.hpp src/share/vm/opto/lcm.cpp src/share/vm/opto/loopopts.cpp src/share/vm/opto/macro.cpp src/share/vm/opto/memnode.cpp src/share/vm/opto/memnode.hpp src/share/vm/opto/superword.cpp src/share/vm/runtime/arguments.cpp test/compiler/6646019/Test.java test/compiler/6689060/Test.java test/compiler/6695810/Test.java test/compiler/6726999/Test.java
diffstat 15 files changed, 1680 insertions(+), 115 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/opto/c2_globals.hpp	Fri Jul 25 16:03:40 2008 -0700
+++ b/src/share/vm/opto/c2_globals.hpp	Mon Jul 28 17:12:52 2008 -0700
@@ -388,6 +388,9 @@
   product(intx, EliminateAllocationArraySizeLimit, 64,                      \
           "Array size (number of elements) limit for scalar replacement")   \
                                                                             \
+  product(intx, ValueSearchLimit, 1000,                                     \
+          "Recursion limit in PhaseMacroExpand::value_from_mem_phi")        \
+                                                                            \
   product(intx, MaxLabelRootDepth, 1100,                                    \
           "Maximum times call Label_Root to prevent stack overflow")        \
                                                                             \
--- a/src/share/vm/opto/compile.cpp	Fri Jul 25 16:03:40 2008 -0700
+++ b/src/share/vm/opto/compile.cpp	Mon Jul 28 17:12:52 2008 -0700
@@ -585,6 +585,10 @@
   // Perform escape analysis
   if (_do_escape_analysis && ConnectionGraph::has_candidates(this)) {
     TracePhase t2("escapeAnalysis", &_t_escapeAnalysis, true);
+    // Add ConP#NULL and ConN#NULL nodes before ConnectionGraph construction.
+    PhaseGVN* igvn = initial_gvn();
+    Node* oop_null = igvn->zerocon(T_OBJECT);
+    Node* noop_null = igvn->zerocon(T_NARROWOOP);
 
     _congraph = new(comp_arena()) ConnectionGraph(this);
     bool has_non_escaping_obj = _congraph->compute_escape();
@@ -594,6 +598,12 @@
       _congraph->dump();
     }
 #endif
+    // Cleanup.
+    if (oop_null->outcnt() == 0)
+      igvn->hash_delete(oop_null);
+    if (noop_null->outcnt() == 0)
+      igvn->hash_delete(noop_null);
+
     if (!has_non_escaping_obj) {
       _congraph = NULL;
     }
--- a/src/share/vm/opto/escape.cpp	Fri Jul 25 16:03:40 2008 -0700
+++ b/src/share/vm/opto/escape.cpp	Mon Jul 28 17:12:52 2008 -0700
@@ -62,10 +62,14 @@
  "F"  // FieldEdge
 };
 
-void PointsToNode::dump() const {
+void PointsToNode::dump(bool print_state) const {
   NodeType nt = node_type();
-  EscapeState es = escape_state();
-  tty->print("%s %s %s [[", node_type_names[(int) nt], esc_names[(int) es], _scalar_replaceable ? "" : "NSR");
+  tty->print("%s ", node_type_names[(int) nt]);
+  if (print_state) {
+    EscapeState es = escape_state();
+    tty->print("%s %s ", esc_names[(int) es], _scalar_replaceable ? "":"NSR");
+  }
+  tty->print("[[");
   for (uint i = 0; i < edge_count(); i++) {
     tty->print(" %d%s", edge_target(i), edge_type_suffix[(int) edge_type(i)]);
   }
@@ -84,11 +88,22 @@
   _compile(C),
   _node_map(C->comp_arena()) {
 
-  _phantom_object = C->top()->_idx;
-  PointsToNode *phn = ptnode_adr(_phantom_object);
-  phn->_node = C->top();
-  phn->set_node_type(PointsToNode::JavaObject);
-  phn->set_escape_state(PointsToNode::GlobalEscape);
+  _phantom_object = C->top()->_idx,
+  add_node(C->top(), PointsToNode::JavaObject, PointsToNode::GlobalEscape,true);
+
+  // Add ConP(#NULL) and ConN(#NULL) nodes.
+  PhaseGVN* igvn = C->initial_gvn();
+  Node* oop_null = igvn->zerocon(T_OBJECT);
+  _oop_null = oop_null->_idx;
+  assert(_oop_null < C->unique(), "should be created already");
+  add_node(oop_null, PointsToNode::JavaObject, PointsToNode::NoEscape, true);
+
+  if (UseCompressedOops) {
+    Node* noop_null = igvn->zerocon(T_NARROWOOP);
+    _noop_null = noop_null->_idx;
+    assert(_noop_null < C->unique(), "should be created already");
+    add_node(noop_null, PointsToNode::JavaObject, PointsToNode::NoEscape, true);
+  }
 }
 
 void ConnectionGraph::add_pointsto_edge(uint from_i, uint to_i) {
@@ -500,29 +515,30 @@
   igvn->set_type(addp, tinst);
   // record the allocation in the node map
   set_map(addp->_idx, get_map(base->_idx));
-  // if the Address input is not the appropriate instance type
-  // (due to intervening casts,) insert a cast
-  Node *adr = addp->in(AddPNode::Address);
-  const TypeOopPtr  *atype = igvn->type(adr)->isa_oopptr();
-  if (atype != NULL && atype->instance_id() != inst_id) {
-    assert(!atype->is_known_instance(), "no conflicting instances");
-    const TypeOopPtr *new_atype = base_t->add_offset(atype->offset())->isa_oopptr();
-    Node *acast = new (_compile, 2) CastPPNode(adr, new_atype);
-    acast->set_req(0, adr->in(0));
-    igvn->set_type(acast, new_atype);
-    record_for_optimizer(acast);
-    Node *bcast = acast;
-    Node *abase = addp->in(AddPNode::Base);
-    if (abase != adr) {
-      bcast = new (_compile, 2) CastPPNode(abase, base_t);
-      bcast->set_req(0, abase->in(0));
-      igvn->set_type(bcast, base_t);
-      record_for_optimizer(bcast);
+
+  // Set addp's Base and Address to 'base'.
+  Node *abase = addp->in(AddPNode::Base);
+  Node *adr   = addp->in(AddPNode::Address);
+  if (adr->is_Proj() && adr->in(0)->is_Allocate() &&
+      adr->in(0)->_idx == (uint)inst_id) {
+    // Skip AddP cases #3 and #5.
+  } else {
+    assert(!abase->is_top(), "sanity"); // AddP case #3
+    if (abase != base) {
+      igvn->hash_delete(addp);
+      addp->set_req(AddPNode::Base, base);
+      if (abase == adr) {
+        addp->set_req(AddPNode::Address, base);
+      } else {
+        // AddP case #4 (adr is array's element offset AddP node)
+#ifdef ASSERT
+        const TypeOopPtr *atype = igvn->type(adr)->isa_oopptr();
+        assert(adr->is_AddP() && atype != NULL &&
+               atype->instance_id() == inst_id, "array's element offset should be processed first");
+#endif
+      }
+      igvn->hash_insert(addp);
     }
-    igvn->hash_delete(addp);
-    addp->set_req(AddPNode::Base, bcast);
-    addp->set_req(AddPNode::Address, acast);
-    igvn->hash_insert(addp);
   }
   // Put on IGVN worklist since at least addp's type was changed above.
   record_for_optimizer(addp);
@@ -660,27 +676,31 @@
   Compile* C = phase->C;
   const TypeOopPtr *tinst = C->get_adr_type(alias_idx)->isa_oopptr();
   bool is_instance = (tinst != NULL) && tinst->is_known_instance();
+  Node *start_mem = C->start()->proj_out(TypeFunc::Memory);
   Node *prev = NULL;
   Node *result = orig_mem;
   while (prev != result) {
     prev = result;
+    if (result == start_mem)
+      break;  // hit one of our sentinals
     if (result->is_Mem()) {
-      MemNode *mem = result->as_Mem();
-      const Type *at = phase->type(mem->in(MemNode::Address));
+      const Type *at = phase->type(result->in(MemNode::Address));
       if (at != Type::TOP) {
         assert (at->isa_ptr() != NULL, "pointer type required.");
         int idx = C->get_alias_index(at->is_ptr());
         if (idx == alias_idx)
           break;
       }
-      result = mem->in(MemNode::Memory);
+      result = result->in(MemNode::Memory);
     }
     if (!is_instance)
       continue;  // don't search further for non-instance types
     // skip over a call which does not affect this memory slice
     if (result->is_Proj() && result->as_Proj()->_con == TypeFunc::Memory) {
       Node *proj_in = result->in(0);
-      if (proj_in->is_Call()) {
+      if (proj_in->is_Allocate() && proj_in->_idx == (uint)tinst->instance_id()) {
+        break;  // hit one of our sentinals
+      } else if (proj_in->is_Call()) {
         CallNode *call = proj_in->as_Call();
         if (!call->may_modify(tinst, phase)) {
           result = call->in(TypeFunc::Memory);
@@ -1006,12 +1026,12 @@
         memnode_worklist.append_if_missing(use);
       } else if (use->is_MergeMem()) {
         mergemem_worklist.append_if_missing(use);
-      } else if (use->is_Call() && tinst != NULL) {
+      } else if (use->is_SafePoint() && tinst != NULL) {
         // Look for MergeMem nodes for calls which reference unique allocation
         // (through CheckCastPP nodes) even for debug info.
         Node* m = use->in(TypeFunc::Memory);
         uint iid = tinst->instance_id();
-        while (m->is_Proj() && m->in(0)->is_Call() &&
+        while (m->is_Proj() && m->in(0)->is_SafePoint() &&
                m->in(0) != use && !m->in(0)->_idx != iid) {
           m = m->in(0)->in(TypeFunc::Memory);
         }
@@ -1348,15 +1368,95 @@
       remove_deferred(ni, &deferred_edges, &visited);
       Node *n = ptn->_node;
       if (n->is_AddP()) {
-        // If this AddP computes an address which may point to more that one
-        // object or more then one field (array's element), nothing the address
-        // points to can be scalar replaceable.
+        // Search for objects which are not scalar replaceable.
+        // Mark their escape state as ArgEscape to propagate the state
+        // to referenced objects.
+        // Note: currently there are no difference in compiler optimizations
+        // for ArgEscape objects and NoEscape objects which are not
+        // scalar replaceable.
+
+        int offset = ptn->offset();
         Node *base = get_addp_base(n);
         ptset.Clear();
         PointsTo(ptset, base, igvn);
-        if (ptset.Size() > 1 ||
-            (ptset.Size() != 0 && ptn->offset() == Type::OffsetBot)) {
+        int ptset_size = ptset.Size();
+
+        // Check if a field's initializing value is recorded and add
+        // a corresponding NULL field's value if it is not recorded.
+        // Connection Graph does not record a default initialization by NULL
+        // captured by Initialize node.
+        //
+        // Note: it will disable scalar replacement in some cases:
+        //
+        //    Point p[] = new Point[1];
+        //    p[0] = new Point(); // Will be not scalar replaced
+        //
+        // but it will save us from incorrect optimizations in next cases:
+        //
+        //    Point p[] = new Point[1];
+        //    if ( x ) p[0] = new Point(); // Will be not scalar replaced
+        //
+        // Without a control flow analysis we can't distinguish above cases.
+        //
+        if (offset != Type::OffsetBot && ptset_size == 1) {
+          uint elem = ptset.getelem(); // Allocation node's index
+          // It does not matter if it is not Allocation node since
+          // only non-escaping allocations are scalar replaced.
+          if (ptnode_adr(elem)->_node->is_Allocate() &&
+              ptnode_adr(elem)->escape_state() == PointsToNode::NoEscape) {
+            AllocateNode* alloc = ptnode_adr(elem)->_node->as_Allocate();
+            InitializeNode* ini = alloc->initialization();
+            Node* value = NULL;
+            if (ini != NULL) {
+              BasicType ft = UseCompressedOops ? T_NARROWOOP : T_OBJECT;
+              Node* store = ini->find_captured_store(offset, type2aelembytes(ft), igvn);
+              if (store != NULL && store->is_Store())
+                value = store->in(MemNode::ValueIn);
+            }
+            if (value == NULL || value != ptnode_adr(value->_idx)->_node) {
+              // A field's initializing value was not recorded. Add NULL.
+              uint null_idx = UseCompressedOops ? _noop_null : _oop_null;
+              add_pointsto_edge(ni, null_idx);
+            }
+          }
+        }
+
+        // An object is not scalar replaceable if the field which may point
+        // to it has unknown offset (unknown element of an array of objects).
+        //
+        if (offset == Type::OffsetBot) {
+          uint e_cnt = ptn->edge_count();
+          for (uint ei = 0; ei < e_cnt; ei++) {
+            uint npi = ptn->edge_target(ei);
+            set_escape_state(npi, PointsToNode::ArgEscape);
+            ptnode_adr(npi)->_scalar_replaceable = false;
+          }
+        }
+
+        // Currently an object is not scalar replaceable if a LoadStore node
+        // access its field since the field value is unknown after it.
+        //
+        bool has_LoadStore = false;
+        for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
+          Node *use = n->fast_out(i);
+          if (use->is_LoadStore()) {
+            has_LoadStore = true;
+            break;
+          }
+        }
+        // An object is not scalar replaceable if the address points
+        // to unknown field (unknown element for arrays, offset is OffsetBot).
+        //
+        // Or the address may point to more then one object. This may produce
+        // the false positive result (set scalar_replaceable to false)
+        // since the flow-insensitive escape analysis can't separate
+        // the case when stores overwrite the field's value from the case
+        // when stores happened on different control branches.
+        //
+        if (ptset_size > 1 || ptset_size != 0 &&
+            (has_LoadStore || offset == Type::OffsetBot)) {
           for( VectorSetI j(&ptset); j.test(); ++j ) {
+            set_escape_state(j.elem, PointsToNode::ArgEscape);
             ptnode_adr(j.elem)->_scalar_replaceable = false;
           }
         }
@@ -1855,7 +1955,7 @@
     case Op_LoadN:
     {
       const Type *t = phase->type(n);
-      if (!t->isa_narrowoop() && t->isa_ptr() == NULL) {
+      if (t->make_ptr() == NULL) {
         _processed.set(n->_idx);
         return;
       }
@@ -1878,8 +1978,9 @@
     }
     case Op_Phi:
     {
-      if (n->as_Phi()->type()->isa_ptr() == NULL) {
-        // nothing to do if not an oop
+      const Type *t = n->as_Phi()->type();
+      if (t->make_ptr() == NULL) {
+        // nothing to do if not an oop or narrow oop
         _processed.set(n->_idx);
         return;
       }
@@ -2067,7 +2168,7 @@
     {
       const Type *t = phase->type(n);
 #ifdef ASSERT
-      if (!t->isa_narrowoop() && t->isa_ptr() == NULL)
+      if (t->make_ptr() == NULL)
         assert(false, "Op_LoadP");
 #endif
 
@@ -2099,7 +2200,8 @@
     case Op_Phi:
     {
 #ifdef ASSERT
-      if (n->as_Phi()->type()->isa_ptr() == NULL)
+      const Type *t = n->as_Phi()->type();
+      if (t->make_ptr() == NULL)
         assert(false, "Op_Phi");
 #endif
       for (uint i = 1; i < n->req() ; i++) {
@@ -2213,16 +2315,14 @@
         PointsToNode::NodeType ptn_loc_type = ptn_loc->node_type();
         if ( ptn_loc_type == PointsToNode::LocalVar && ptn_loc->_node != NULL &&
              ptn_loc->edge_count() == 1 && ptn_loc->edge_target(0) == ni ) {
-          tty->print("%6d  LocalVar [[%d]]", li, ni);
-          ptnode_adr(li)->_node->dump();
+          ptnode_adr(li)->dump(false);
         }
       }
       if (Verbose) {
         // Print all fields which reference this allocation
         for (uint i = 0; i < ptn->edge_count(); i++) {
           uint ei = ptn->edge_target(i);
-          tty->print("%6d  Field [[%d]]", ei, ni);
-          ptnode_adr(ei)->_node->dump();
+          ptnode_adr(ei)->dump(false);
         }
       }
       tty->cr();
--- a/src/share/vm/opto/escape.hpp	Fri Jul 25 16:03:40 2008 -0700
+++ b/src/share/vm/opto/escape.hpp	Mon Jul 28 17:12:52 2008 -0700
@@ -197,7 +197,7 @@
   void remove_edge(uint targIdx, EdgeType et);
 
 #ifndef PRODUCT
-  void dump() const;
+  void dump(bool print_state=true) const;
 #endif
 
 };
@@ -221,6 +221,8 @@
                                        // that pointer values loaded from
                                        // a field which has not been set
                                        // are assumed to point to.
+  uint                      _oop_null; // ConP(#NULL)
+  uint                     _noop_null; // ConN(#NULL)
 
   Compile *                  _compile; // Compile object for current compilation
 
--- a/src/share/vm/opto/lcm.cpp	Fri Jul 25 16:03:40 2008 -0700
+++ b/src/share/vm/opto/lcm.cpp	Mon Jul 28 17:12:52 2008 -0700
@@ -322,7 +322,7 @@
   uint choice  = 0; // Bigger is most important
   uint latency = 0; // Bigger is scheduled first
   uint score   = 0; // Bigger is better
-  uint idx;         // Index in worklist
+  int idx = -1;     // Index in worklist
 
   for( uint i=0; i<cnt; i++ ) { // Inspect entire worklist
     // Order in worklist is used to break ties.
@@ -412,9 +412,10 @@
     }
   } // End of for all ready nodes in worklist
 
-  Node *n = worklist[idx];      // Get the winner
+  assert(idx >= 0, "index should be set");
+  Node *n = worklist[(uint)idx];      // Get the winner
 
-  worklist.map(idx,worklist.pop());     // Compress worklist
+  worklist.map((uint)idx, worklist.pop());     // Compress worklist
   return n;
 }
 
@@ -599,7 +600,14 @@
           assert(cfg->_bbs[oop_store->_idx]->_dom_depth <= this->_dom_depth, "oop_store must dominate card-mark");
         }
       }
-      if( n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_MemBarAcquire ) {
+      if( n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_MemBarAcquire &&
+          n->req() > TypeFunc::Parms ) {
+        // MemBarAcquire could be created without Precedent edge.
+        // del_req() replaces the specified edge with the last input edge
+        // and then removes the last edge. If the specified edge > number of
+        // edges the last edge will be moved outside of the input edges array
+        // and the edge will be lost. This is why this code should be
+        // executed only when Precedent (== TypeFunc::Parms) edge is present.
         Node *x = n->in(TypeFunc::Parms);
         n->del_req(TypeFunc::Parms);
         n->add_prec(x);
--- a/src/share/vm/opto/loopopts.cpp	Fri Jul 25 16:03:40 2008 -0700
+++ b/src/share/vm/opto/loopopts.cpp	Mon Jul 28 17:12:52 2008 -0700
@@ -578,7 +578,8 @@
     Node *cmov = conditional_move( n );
     if( cmov ) return cmov;
   }
-  if( n->is_CFG() || n_op == Op_StorePConditional || n_op == Op_StoreLConditional || n_op == Op_CompareAndSwapI || n_op == Op_CompareAndSwapL ||n_op == Op_CompareAndSwapP)  return n;
+  if( n->is_CFG() || n->is_LoadStore() )
+    return n;
   if( n_op == Op_Opaque1 ||     // Opaque nodes cannot be mod'd
       n_op == Op_Opaque2 ) {
     if( !C->major_progress() )   // If chance of no more loop opts...
--- a/src/share/vm/opto/macro.cpp	Fri Jul 25 16:03:40 2008 -0700
+++ b/src/share/vm/opto/macro.cpp	Mon Jul 28 17:12:52 2008 -0700
@@ -194,9 +194,10 @@
 }
 
 // Search for a memory operation for the specified memory slice.
-static Node *scan_mem_chain(Node *mem, int alias_idx, int offset, Node *start_mem, Node *alloc) {
+static Node *scan_mem_chain(Node *mem, int alias_idx, int offset, Node *start_mem, Node *alloc, PhaseGVN *phase) {
   Node *orig_mem = mem;
   Node *alloc_mem = alloc->in(TypeFunc::Memory);
+  const TypeOopPtr *tinst = phase->C->get_adr_type(alias_idx)->isa_oopptr();
   while (true) {
     if (mem == alloc_mem || mem == start_mem ) {
       return mem;  // hit one of our sentinals
@@ -208,7 +209,13 @@
       // already know that the object is safe to eliminate.
       if (in->is_Initialize() && in->as_Initialize()->allocation() == alloc) {
         return in;
-      } else if (in->is_Call() || in->is_MemBar()) {
+      } else if (in->is_Call()) {
+        CallNode *call = in->as_Call();
+        if (!call->may_modify(tinst, phase)) {
+          mem = call->in(TypeFunc::Memory);
+        }
+        mem = in->in(TypeFunc::Memory);
+      } else if (in->is_MemBar()) {
         mem = in->in(TypeFunc::Memory);
       } else {
         assert(false, "unexpected projection");
@@ -265,7 +272,7 @@
   }
 
   if (level <= 0) {
-    return NULL;
+    return NULL; // Give up: phi tree too deep
   }
   Node *start_mem = C->start()->proj_out(TypeFunc::Memory);
   Node *alloc_mem = alloc->in(TypeFunc::Memory);
@@ -283,7 +290,7 @@
     if (in == NULL || in->is_top()) {
       values.at_put(j, in);
     } else  {
-      Node *val = scan_mem_chain(in, alias_idx, offset, start_mem, alloc);
+      Node *val = scan_mem_chain(in, alias_idx, offset, start_mem, alloc, &_igvn);
       if (val == start_mem || val == alloc_mem) {
         // hit a sentinel, return appropriate 0 value
         values.at_put(j, _igvn.zerocon(ft));
@@ -308,7 +315,8 @@
         }
         values.at_put(j, val);
       } else {
-        return NULL;  // unknown node  on this path
+        assert(false, "unknown node on this path");
+        return NULL;  // unknown node on this path
       }
     }
   }
@@ -344,7 +352,7 @@
     if (visited.test_set(mem->_idx)) {
       return NULL;  // found a loop, give up
     }
-    mem = scan_mem_chain(mem, alias_idx, offset, start_mem, alloc);
+    mem = scan_mem_chain(mem, alias_idx, offset, start_mem, alloc, &_igvn);
     if (mem == start_mem || mem == alloc_mem) {
       done = true;  // hit a sentinel, return appropriate 0 value
     } else if (mem->is_Initialize()) {
@@ -368,7 +376,7 @@
       Node *unique_input = NULL;
       Node *top = C->top();
       for (uint i = 1; i < mem->req(); i++) {
-        Node *n = scan_mem_chain(mem->in(i), alias_idx, offset, start_mem, alloc);
+        Node *n = scan_mem_chain(mem->in(i), alias_idx, offset, start_mem, alloc, &_igvn);
         if (n == NULL || n == top || n == mem) {
           continue;
         } else if (unique_input == NULL) {
@@ -396,7 +404,7 @@
     } else if (mem->is_Phi()) {
       // attempt to produce a Phi reflecting the values on the input paths of the Phi
       Node_Stack value_phis(a, 8);
-      Node * phi = value_from_mem_phi(mem, ft, ftype, adr_t, alloc, &value_phis, 8);
+      Node * phi = value_from_mem_phi(mem, ft, ftype, adr_t, alloc, &value_phis, ValueSearchLimit);
       if (phi != NULL) {
         return phi;
       } else {
@@ -463,7 +471,7 @@
           Node* n = use->fast_out(k);
           if (!n->is_Store() && n->Opcode() != Op_CastP2X) {
             DEBUG_ONLY(disq_node = n;)
-            if (n->is_Load()) {
+            if (n->is_Load() || n->is_LoadStore()) {
               NOT_PRODUCT(fail_eliminate = "Field load";)
             } else {
               NOT_PRODUCT(fail_eliminate = "Not store field referrence";)
--- a/src/share/vm/opto/memnode.cpp	Fri Jul 25 16:03:40 2008 -0700
+++ b/src/share/vm/opto/memnode.cpp	Mon Jul 28 17:12:52 2008 -0700
@@ -94,14 +94,19 @@
   if (tinst == NULL || !tinst->is_known_instance_field())
     return mchain;  // don't try to optimize non-instance types
   uint instance_id = tinst->instance_id();
+  Node *start_mem = phase->C->start()->proj_out(TypeFunc::Memory);
   Node *prev = NULL;
   Node *result = mchain;
   while (prev != result) {
     prev = result;
+    if (result == start_mem)
+      break;  // hit one of our sentinals
     // skip over a call which does not affect this memory slice
     if (result->is_Proj() && result->as_Proj()->_con == TypeFunc::Memory) {
       Node *proj_in = result->in(0);
-      if (proj_in->is_Call()) {
+      if (proj_in->is_Allocate() && proj_in->_idx == instance_id) {
+        break;  // hit one of our sentinals
+      } else if (proj_in->is_Call()) {
         CallNode *call = proj_in->as_Call();
         if (!call->may_modify(t_adr, phase)) {
           result = call->in(TypeFunc::Memory);
@@ -115,6 +120,8 @@
         }
       } else if (proj_in->is_MemBar()) {
         result = proj_in->in(TypeFunc::Memory);
+      } else {
+        assert(false, "unexpected projection");
       }
     } else if (result->is_MergeMem()) {
       result = step_through_mergemem(phase, result->as_MergeMem(), t_adr, NULL, tty);
--- a/src/share/vm/opto/memnode.hpp	Fri Jul 25 16:03:40 2008 -0700
+++ b/src/share/vm/opto/memnode.hpp	Mon Jul 28 17:12:52 2008 -0700
@@ -607,6 +607,7 @@
 };
 
 //------------------------------LoadStoreNode---------------------------
+// Note: is_Mem() method returns 'true' for this class.
 class LoadStoreNode : public Node {
 public:
   enum {
--- a/src/share/vm/opto/superword.cpp	Fri Jul 25 16:03:40 2008 -0700
+++ b/src/share/vm/opto/superword.cpp	Mon Jul 28 17:12:52 2008 -0700
@@ -1196,8 +1196,10 @@
     Node *n = lp()->fast_out(i);
     if (in_bb(n) && (n->is_Phi() && n->bottom_type() == Type::MEMORY)) {
       Node* n_tail  = n->in(LoopNode::LoopBackControl);
-      _mem_slice_head.push(n);
-      _mem_slice_tail.push(n_tail);
+      if (n_tail != n->in(LoopNode::EntryControl)) {
+        _mem_slice_head.push(n);
+        _mem_slice_tail.push(n_tail);
+      }
     }
   }
 
--- a/src/share/vm/runtime/arguments.cpp	Fri Jul 25 16:03:40 2008 -0700
+++ b/src/share/vm/runtime/arguments.cpp	Mon Jul 28 17:12:52 2008 -0700
@@ -2472,6 +2472,9 @@
     if (match_option(option, "-XX:+PrintVMOptions", &tail)) {
       PrintVMOptions = true;
     }
+    if (match_option(option, "-XX:-PrintVMOptions", &tail)) {
+      PrintVMOptions = false;
+    }
   }
 
   // Parse default .hotspotrc settings file
--- a/test/compiler/6646019/Test.java	Fri Jul 25 16:03:40 2008 -0700
+++ b/test/compiler/6646019/Test.java	Mon Jul 28 17:12:52 2008 -0700
@@ -1,23 +1,24 @@
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- *
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
  *
  */
 
--- a/test/compiler/6689060/Test.java	Fri Jul 25 16:03:40 2008 -0700
+++ b/test/compiler/6689060/Test.java	Mon Jul 28 17:12:52 2008 -0700
@@ -1,24 +1,24 @@
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- *
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
  *
  */
 
--- a/test/compiler/6695810/Test.java	Fri Jul 25 16:03:40 2008 -0700
+++ b/test/compiler/6695810/Test.java	Mon Jul 28 17:12:52 2008 -0700
@@ -1,24 +1,24 @@
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- *
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
  *
  */
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/6726999/Test.java	Mon Jul 28 17:12:52 2008 -0700
@@ -0,0 +1,1419 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+/*
+ * @test
+ * @bug 6726999
+ * @summary nsk/stress/jck12a/jck12a010 assert(n != NULL,"Bad immediate dominator info.");
+ * @run main/othervm -Xbatch -XX:CompileCommand=exclude,Test.dummy -XX:+AggressiveOpts Test
+ */
+
+import java.lang.reflect.Array;
+
+class Point {
+  int x;
+  int y;
+}
+
+public class Test {
+
+  void dummy() {
+    // Empty method to verify correctness of DebugInfo.
+    // Use -XX:CompileCommand=exclude,Test.dummy
+  }
+
+  int test0_0_0(int y) {
+    int x = 3;
+    Point p = new Point();
+    dummy();
+    p.x = x;
+    p.y = 3 * x + y;
+    return p.x * p.y;
+  }
+
+  int test0_0_1(int y) {
+    int x = 3;
+    Point p = null;
+    dummy();
+    p = new Point();
+    dummy();
+    p.x = x;
+    p.y = 3 * x + y;
+    return p.x * p.y;
+  }
+
+  int test0_0_2(int y) {
+    int x = 3;
+    Point p = new Point();
+    dummy();
+    p = new Point();
+    dummy();
+    p.x = x;
+    p.y = 3 * x + y;
+    return p.x * p.y;
+  }
+
+  int test0_0_3(int y) {
+    int x = 3;
+    Point p[] = new Point[1];
+    p[0] = new Point();
+    dummy();
+    p[0].x = x;
+    p[0].y = 3 * x + y;
+    return p[0].x * p[0].y;
+  }
+
+  int test0_0_4(int y) {
+    int x = 3;
+    Point p[] = new Point[1];
+    dummy();
+    p[0] = new Point();
+    dummy();
+    p[0].x = x;
+    p[0].y = 3 * x + y;
+    return p[0].x * p[0].y;
+  }
+
+  int test0_0_5(int y) {
+    int x = 3;
+    Point p[] = new Point[1];
+    dummy();
+    p[0] = null;
+    dummy();
+    p[0] = new Point();
+    dummy();
+    p[0].x = x;
+    p[0].y = 3 * x + y;
+    return p[0].x * p[0].y;
+  }
+
+  int test0_0_6(int y) {
+    int x = 3;
+    Point p[] = new Point[1];
+    p[0] = new Point();
+    dummy();
+    p[0] = new Point();
+    dummy();
+    p[0].x = x;
+    p[0].y = 3 * x + y;
+    return p[0].x * p[0].y;
+  }
+
+  int test0_1_3(int y) {
+    int x = 3;
+    Point p1 = new Point();
+    dummy();
+    Point p[] = new Point[1];
+    p[0] = p1;
+    dummy();
+    p[0].x = x;
+    p[0].y = 3 * x + y;
+    return p[0].x * p[0].y;
+  }
+
+  int test0_1_4(int y) {
+    int x = 3;
+    Point p1 = new Point();
+    dummy();
+    Point p[] = new Point[1];
+    dummy();
+    p[0] = p1;
+    dummy();
+    p[0].x = x;
+    p[0].y = 3 * x + y;
+    return p[0].x * p[0].y;
+  }
+
+  int test0_1_5(int y) {
+    int x = 3;
+    Point p1 = new Point();
+    dummy();
+    Point p[] = new Point[1];
+    dummy();
+    p[0] = null;
+    dummy();
+    p[0] = p1;
+    dummy();
+    p[0].x = x;
+    p[0].y = 3 * x + y;
+    return p[0].x * p[0].y;
+  }
+
+  int test0_1_6(int y) {
+    int x = 3;
+    Point p1 = new Point();
+    dummy();
+    Point p2 = new Point();
+    dummy();
+    Point p[] = new Point[1];
+    p[0] = p1;
+    dummy();
+    p[0] = p2;
+    dummy();
+    p[0].x = x;
+    p[0].y = 3 * x + y;
+    return p[0].x * p[0].y;
+  }
+
+  int test1_0_0(int y) {
+    Point p = new Point();
+    if ( (y & 1) == 1 ) {
+      p = new Point();
+    }
+    int x = 3;
+    p.x = x;
+    p.y = 3 * x + y;
+    dummy();
+    return p.x * p.y;
+  }
+
+  int test1_0_1(int y) {
+    Point p = null;
+    if ( (y & 1) == 1 ) {
+      p = new Point();
+    }
+    int x = 3;
+    if ( p == null )
+      return (3 * x + y) * x;
+    p.x = x;
+    p.y = 3 * x + y;
+    dummy();
+    return p.x * p.y;
+  }
+
+  int test1_0_2(int y) {
+    Point p[] = new Point[1];
+    if ( (y & 1) == 1 ) {
+      p[0] = new Point();
+    }
+    int x = 3;
+    if ( p[0] == null )
+      return (3 * x + y) * x;
+    p[0].x = x;
+    p[0].y = 3 * x + y;
+    dummy();
+    return p[0].x * p[0].y;
+  }
+
+  int test1_0_3(int y) {
+    Point p[] = new Point[1];
+    p[0] = null;
+    if ( (y & 1) == 1 ) {
+      p[0] = new Point();
+    }
+    int x = 3;
+    if ( p[0] == null )
+      return (3 * x + y) * x;
+    p[0].x = x;
+    p[0].y = 3 * x + y;
+    dummy();
+    return p[0].x * p[0].y;
+  }
+
+  int test1_0_4(int y) {
+    Point p[] = new Point[1];
+    p[0] = new Point();
+    if ( (y & 1) == 1 ) {
+      p[0] = new Point();
+    }
+    int x = 3;
+    if ( p[0] == null )
+      return (3 * x + y) * x;
+    p[0].x = x;
+    p[0].y = 3 * x + y;
+    dummy();
+    return p[0].x * p[0].y;
+  }
+
+  int test1_0_5(int y) {
+    Point p[] = new Point[1];
+    if ( (y & 1) == 1 ) {
+      p[0] = new Point();
+    } else {
+      p[0] = null;
+    }
+    int x = 3;
+    if ( p[0] == null )
+      return (3 * x + y) * x;
+    p[0].x = x;
+    p[0].y = 3 * x + y;
+    dummy();
+    return p[0].x * p[0].y;
+  }
+
+  int test1_0_6(int y) {
+    Point p[] = new Point[1];
+    if ( (y & 1) == 1 ) {
+      p[0] = new Point();
+    } else {
+      p[0] = new Point();
+    }
+    int x = 3;
+    if ( p[0] == null )
+      return (3 * x + y) * x;
+    p[0].x = x;
+    p[0].y = 3 * x + y;
+    dummy();
+    return p[0].x * p[0].y;
+  }
+
+  int test1_1_0(int y) {
+    Point p = new Point();
+    if ( (y & 1) == 1 ) {
+      dummy();
+      p = new Point();
+      dummy();
+    }
+    int x = 3;
+    p.x = x;
+    p.y = 3 * x + y;
+    dummy();
+    return p.x * p.y;
+  }
+
+  int test1_1_1(int y) {
+    Point p = null;
+    if ( (y & 1) == 1 ) {
+      dummy();
+      p = new Point();
+      dummy();
+    }
+    int x = 3;
+    if ( p == null )
+      return (3 * x + y) * x;
+    p.x = x;
+    p.y = 3 * x + y;
+    dummy();
+    return p.x * p.y;
+  }
+
+  int test1_1_2(int y) {
+    Point p[] = new Point[1];
+    if ( (y & 1) == 1 ) {
+      dummy();
+      p[0] = new Point();
+      dummy();
+    }
+    int x = 3;
+    if ( p[0] == null )
+      return (3 * x + y) * x;
+    p[0].x = x;
+    p[0].y = 3 * x + y;
+    dummy();
+    return p[0].x * p[0].y;
+  }
+
+  int test1_1_3(int y) {
+    Point p[] = new Point[1];
+    dummy();
+    p[0] = null;
+    if ( (y & 1) == 1 ) {
+      dummy();
+      p[0] = new Point();
+      dummy();
+    }
+    int x = 3;
+    if ( p[0] == null )
+      return (3 * x + y) * x;
+    p[0].x = x;
+    p[0].y = 3 * x + y;
+    dummy();
+    return p[0].x * p[0].y;
+  }
+
+  int test1_1_4(int y) {
+    Point p[] = new Point[1];
+    dummy();
+    p[0] = new Point();
+    if ( (y & 1) == 1 ) {
+      dummy();
+      p[0] = new Point();
+      dummy();
+    }
+    int x = 3;
+    if ( p[0] == null )
+      return (3 * x + y) * x;
+    p[0].x = x;
+    p[0].y = 3 * x + y;
+    dummy();
+    return p[0].x * p[0].y;
+  }
+
+  int test1_1_5(int y) {
+    Point p[] = new Point[1];
+    if ( (y & 1) == 1 ) {
+      dummy();
+      p[0] = new Point();
+      dummy();
+    } else {
+      dummy();
+      p[0] = null;
+      dummy();
+    }
+    int x = 3;
+    if ( p[0] == null )
+      return (3 * x + y) * x;
+    p[0].x = x;
+    p[0].y = 3 * x + y;
+    dummy();
+    return p[0].x * p[0].y;
+  }
+
+  int test1_1_6(int y) {
+    Point p[] = new Point[1];
+    if ( (y & 1) == 1 ) {
+      dummy();
+      p[0] = new Point();
+      dummy();
+    } else {
+      dummy();
+      p[0] = new Point();
+      dummy();
+    }
+    int x = 3;
+    if ( p[0] == null )
+      return (3 * x + y) * x;
+    p[0].x = x;
+    p[0].y = 3 * x + y;
+    dummy();
+    return p[0].x * p[0].y;
+  }
+
+  int test1_2_0(int y) {
+    Point p1 = new Point();
+    dummy();
+    Point p = new Point();
+    if ( (y & 1) == 1 ) {
+      dummy();
+      p = p1;
+      dummy();
+    }
+    int x = 3;
+    p.x = x;
+    p.y = 3 * x + y;
+    dummy();
+    return p.x * p.y;
+  }
+
+  int test1_2_1(int y) {
+    Point p1 = new Point();
+    dummy();
+    Point p = null;
+    if ( (y & 1) == 1 ) {
+      dummy();
+      p = p1;
+      dummy();
+    }
+    int x = 3;
+    if ( p == null )
+      return (3 * x + y) * x;
+    p.x = x;
+    p.y = 3 * x + y;
+    dummy();
+    return p.x * p.y;
+  }
+
+  int test1_2_2(int y) {
+    Point p1 = new Point();
+    dummy();
+    Point p[] = new Point[1];
+    if ( (y & 1) == 1 ) {
+      dummy();
+      p[0] = p1;
+      dummy();
+    }
+    int x = 3;
+    if ( p[0] == null )
+      return (3 * x + y) * x;
+    p[0].x = x;
+    p[0].y = 3 * x + y;
+    dummy();
+    return p[0].x * p[0].y;
+  }
+
+  int test1_2_3(int y) {
+    Point p1 = new Point();
+    dummy();
+    Point p[] = new Point[1];
+    dummy();
+    p[0] = null;
+    if ( (y & 1) == 1 ) {
+      dummy();
+      p[0] = p1;
+      dummy();
+    }
+    int x = 3;
+    if ( p[0] == null )
+      return (3 * x + y) * x;
+    p[0].x = x;
+    p[0].y = 3 * x + y;
+    dummy();
+    return p[0].x * p[0].y;
+  }
+
+  int test1_2_4(int y) {
+    Point p1 = new Point();
+    dummy();
+    Point p2 = new Point();
+    dummy();
+    Point p[] = new Point[1];
+    dummy();
+    p[0] = p1;
+    if ( (y & 1) == 1 ) {
+      dummy();
+      p[0] = p2;
+      dummy();
+    }
+    int x = 3;
+    if ( p[0] == null )
+      return (3 * x + y) * x;
+    p[0].x = x;
+    p[0].y = 3 * x + y;
+    dummy();
+    return p[0].x * p[0].y;
+  }
+
+  int test1_2_5(int y) {
+    Point p1 = new Point();
+    dummy();
+    Point p[] = new Point[1];
+    if ( (y & 1) == 1 ) {
+      dummy();
+      p[0] = p1;
+      dummy();
+    } else {
+      dummy();
+      p[0] = null;
+      dummy();
+    }
+    int x = 3;
+    if ( p[0] == null )
+      return (3 * x + y) * x;
+    p[0].x = x;
+    p[0].y = 3 * x + y;
+    dummy();
+    return p[0].x * p[0].y;
+  }
+
+  int test1_2_6(int y) {
+    Point p1 = new Point();
+    dummy();
+    Point p2 = new Point();
+    dummy();
+    Point p[] = new Point[1];
+    if ( (y & 1) == 1 ) {
+      dummy();
+      p[0] = p1;
+      dummy();
+    } else {
+      dummy();
+      p[0] = p2;
+      dummy();
+    }
+    int x = 3;
+    if ( p[0] == null )
+      return (3 * x + y) * x;
+    p[0].x = x;
+    p[0].y = 3 * x + y;
+    dummy();
+    return p[0].x * p[0].y;
+  }
+
+  int test2_0_0(int y) {
+    Point p = new Point();
+    int lim = (y & 3);
+    for (int i = 0; i < lim; i++) {
+      p = new Point();
+    }
+    int x = 3;
+    p.x = x;
+    p.y = 3 * x + y;
+    dummy();
+    return p.x * p.y;
+  }
+
+  int test2_0_1(int y) {
+    Point p = null;
+    int lim = (y & 3);
+    for (int i = 0; i < lim; i++) {
+      p = new Point();
+    }
+    int x = 3;
+    if ( p == null )
+      return (3 * x + y) * x;
+    p.x = x;
+    p.y = 3 * x + y;
+    dummy();
+    return p.x * p.y;
+  }
+
+  int test2_0_2(int y) {
+    Point p[] = new Point[3];
+    int lim = (y & 3);
+    for (int i = 0; i < lim; i++) {
+      p[i] = new Point();
+    }
+    int x = 3;
+    int j = (y & 1);
+    if ( p[j] == null )
+      return (3 * x + y) * x;
+    p[j].x = x;
+    p[j].y = 3 * x + y;
+    dummy();
+    return p[j].x * p[0].y;
+  }
+
+  int test2_0_3(int y) {
+    Point p[] = new Point[3];
+    int j = (y & 1);
+    p[j] = null;
+    int lim = (y & 3);
+    for (int i = 0; i < lim; i++) {
+      p[i] = new Point();
+    }
+    int x = 3;
+    if ( p[j] == null )
+      return (3 * x + y) * x;
+    p[j].x = x;
+    p[j].y = 3 * x + y;
+    dummy();
+    return p[j].x * p[0].y;
+  }
+
+  int test2_0_4(int y) {
+    Point p[] = new Point[3];
+    int j = (y & 1);
+    p[j] = new Point();
+    int lim = (y & 3);
+    for (int i = 0; i < lim; i++) {
+      p[i] = new Point();
+    }
+    int x = 3;
+    if ( p[j] == null )
+      return (3 * x + y) * x;
+    p[j].x = x;
+    p[j].y = 3 * x + y;
+    dummy();
+    return p[j].x * p[0].y;
+  }
+
+  int test2_0_5(int y) {
+    Point p[] = new Point[3];
+    int lim = (y & 3);
+    for (int i = 0; i < lim; i++) {
+      p[i] = new Point();
+    }
+    for (int i = 0; i < lim; i++) {
+      p[i] = null;
+    }
+    int x = 3;
+    int j = (y & 1);
+    if ( p[j] == null )
+      return (3 * x + y) * x;
+    p[j].x = x;
+    p[j].y = 3 * x + y;
+    dummy();
+    return p[j].x * p[0].y;
+  }
+
+  int test2_0_6(int y) {
+    Point p[] = new Point[3];
+    int lim = (y & 3);
+    for (int i = 0; i < lim; i++) {
+      p[i] = new Point();
+    }
+    for (int i = 0; i < lim; i++) {
+      p[i] = new Point();
+    }
+    int x = 3;
+    int j = (y & 1);
+    if ( p[j] == null )
+      return (3 * x + y) * x;
+    p[j].x = x;
+    p[j].y = 3 * x + y;
+    dummy();
+    return p[j].x * p[0].y;
+  }
+
+  int test2_1_0(int y) {
+    Point p = new Point();
+    int lim = (y & 3);
+    for (int i = 0; i < lim; i++) {
+      dummy();
+      p = new Point();
+      dummy();
+    }
+    int x = 3;
+    p.x = x;
+    p.y = 3 * x + y;
+    dummy();
+    return p.x * p.y;
+  }
+
+  int test2_1_1(int y) {
+    Point p = null;
+    int lim = (y & 3);
+    for (int i = 0; i < lim; i++) {
+      dummy();
+      p = new Point();
+      dummy();
+    }
+    int x = 3;
+    if ( p == null )
+      return (3 * x + y) * x;
+    p.x = x;
+    p.y = 3 * x + y;
+    dummy();
+    return p.x * p.y;
+  }
+
+  int test2_1_2(int y) {
+    Point p[] = new Point[3];
+    int lim = (y & 3);
+    for (int i = 0; i < lim; i++) {
+      dummy();
+      p[i] = new Point();
+      dummy();
+    }
+    int x = 3;
+    int j = (y & 1);
+    if ( p[j] == null )
+      return (3 * x + y) * x;
+    p[j].x = x;
+    p[j].y = 3 * x + y;
+    dummy();
+    return p[j].x * p[0].y;
+  }
+
+  int test2_1_3(int y) {
+    Point p[] = new Point[3];
+    dummy();
+    int j = (y & 1);
+    p[j] = null;
+    int lim = (y & 3);
+    for (int i = 0; i < lim; i++) {
+      dummy();
+      p[i] = new Point();
+      dummy();
+    }
+    int x = 3;
+    if ( p[j] == null )
+      return (3 * x + y) * x;
+    p[j].x = x;
+    p[j].y = 3 * x + y;
+    dummy();
+    return p[j].x * p[0].y;
+  }
+
+  int test2_1_4(int y) {
+    Point p[] = new Point[3];
+    dummy();
+    int j = (y & 1);
+    p[j] = new Point();
+    int lim = (y & 3);
+    for (int i = 0; i < lim; i++) {
+      dummy();
+      p[i] = new Point();
+      dummy();
+    }
+    int x = 3;
+    if ( p[j] == null )
+      return (3 * x + y) * x;
+    p[j].x = x;
+    p[j].y = 3 * x + y;
+    dummy();
+    return p[j].x * p[0].y;
+  }
+
+  int test2_1_5(int y) {
+    Point p[] = new Point[3];
+    int lim = (y & 3);
+    for (int i = 0; i < lim; i++) {
+      dummy();
+      p[i] = new Point();
+      dummy();
+    }
+    for (int i = 0; i < lim; i++) {
+      dummy();
+      p[i] = null;
+      dummy();
+    }
+    int x = 3;
+    int j = (y & 1);
+    if ( p[j] == null )
+      return (3 * x + y) * x;
+    p[j].x = x;
+    p[j].y = 3 * x + y;
+    dummy();
+    return p[j].x * p[0].y;
+  }
+
+  int test2_1_6(int y) {
+    Point p[] = new Point[3];
+    int lim = (y & 3);
+    for (int i = 0; i < lim; i++) {
+      dummy();
+      p[i] = new Point();
+      dummy();
+    }
+    for (int i = 0; i < lim; i++) {
+      dummy();
+      p[i] = new Point();
+      dummy();
+    }
+    int x = 3;
+    int j = (y & 1);
+    if ( p[j] == null )
+      return (3 * x + y) * x;
+    p[j].x = x;
+    p[j].y = 3 * x + y;
+    dummy();
+    return p[j].x * p[0].y;
+  }
+
+  int test2_2_0(int y) {
+    Point p1 = new Point();
+    dummy();
+    Point p = new Point();
+    int lim = (y & 3);
+    for (int i = 0; i < lim; i++) {
+      dummy();
+      p = p1;
+      dummy();
+    }
+    int x = 3;
+    p.x = x;
+    p.y = 3 * x + y;
+    dummy();
+    return p.x * p.y;
+  }
+
+  int test2_2_1(int y) {
+    Point p1 = new Point();
+    dummy();
+    Point p = null;
+    int lim = (y & 3);
+    for (int i = 0; i < lim; i++) {
+      dummy();
+      p = p1;
+      dummy();
+    }
+    int x = 3;
+    if ( p == null )
+      return (3 * x + y) * x;
+    p.x = x;
+    p.y = 3 * x + y;
+    dummy();
+    return p.x * p.y;
+  }
+
+  int test2_2_2(int y) {
+    Point p1 = new Point();
+    dummy();
+    Point p[] = new Point[3];
+    int lim = (y & 3);
+    for (int i = 0; i < lim; i++) {
+      dummy();
+      p[i] = p1;
+      dummy();
+    }
+    int x = 3;
+    int j = (y & 1);
+    if ( p[j] == null )
+      return (3 * x + y) * x;
+    p[j].x = x;
+    p[j].y = 3 * x + y;
+    dummy();
+    return p[j].x * p[0].y;
+  }
+
+  int test2_2_3(int y) {
+    Point p1 = new Point();
+    dummy();
+    Point p[] = new Point[3];
+    dummy();
+    int j = (y & 1);
+    p[j] = null;
+    int lim = (y & 3);
+    for (int i = 0; i < lim; i++) {
+      dummy();
+      p[i] = p1;
+      dummy();
+    }
+    int x = 3;
+    if ( p[j] == null )
+      return (3 * x + y) * x;
+    p[j].x = x;
+    p[j].y = 3 * x + y;
+    dummy();
+    return p[j].x * p[0].y;
+  }
+
+  int test2_2_4(int y) {
+    Point p1 = new Point();
+    dummy();
+    Point p2 = new Point();
+    dummy();
+    Point p[] = new Point[3];
+    dummy();
+    int j = (y & 1);
+    p[j] = p1;
+    int lim = (y & 3);
+    for (int i = 0; i < lim; i++) {
+      dummy();
+      p[i] = p2;
+      dummy();
+    }
+    int x = 3;
+    if ( p[j] == null )
+      return (3 * x + y) * x;
+    p[j].x = x;
+    p[j].y = 3 * x + y;
+    dummy();
+    return p[j].x * p[0].y;
+  }
+
+  int test2_2_5(int y) {
+    Point p1 = new Point();
+    dummy();
+    Point p[] = new Point[3];
+    int lim = (y & 3);
+    for (int i = 0; i < lim; i++) {
+      dummy();
+      p[i] = p1;
+      dummy();
+    }
+    for (int i = 0; i < lim; i++) {
+      dummy();
+      p[i] = null;
+      dummy();
+    }
+    int x = 3;
+    int j = (y & 1);
+    if ( p[j] == null )
+      return (3 * x + y) * x;
+    p[j].x = x;
+    p[j].y = 3 * x + y;
+    dummy();
+    return p[j].x * p[0].y;
+  }
+
+  int test2_2_6(int y) {
+    Point p1 = new Point();
+    dummy();
+    Point p2 = new Point();
+    dummy();
+    Point p[] = new Point[3];
+    int lim = (y & 3);
+    for (int i = 0; i < lim; i++) {
+      dummy();
+      p[i] = p1;
+      dummy();
+    }
+    for (int i = 0; i < lim; i++) {
+      dummy();
+      p[i] = p2;
+      dummy();
+    }
+    int x = 3;
+    int j = (y & 1);
+    if ( p[j] == null )
+      return (3 * x + y) * x;
+    p[j].x = x;
+    p[j].y = 3 * x + y;
+    dummy();
+    return p[j].x * p[0].y;
+  }
+
+  public static void main(String args[]) {
+    Test tsr    = new Test();
+    Point p     = new Point();
+    Point ptmp  = p;
+    Class cls   = Point.class;
+    int y = 0;
+    for (int i=0; i<10000; i++) {
+      y = tsr.test0_0_0(y);
+      y = tsr.test0_0_0(y);
+      y = tsr.test0_0_1(y);
+      y = tsr.test0_0_1(y);
+      y = tsr.test0_0_2(y);
+      y = tsr.test0_0_2(y);
+      y = tsr.test0_0_3(y);
+      y = tsr.test0_0_3(y);
+      y = tsr.test0_0_4(y);
+      y = tsr.test0_0_4(y);
+      y = tsr.test0_0_5(y);
+      y = tsr.test0_0_5(y);
+      y = tsr.test0_0_6(y);
+      y = tsr.test0_0_6(y);
+
+      y = tsr.test0_1_3(y);
+      y = tsr.test0_1_3(y);
+      y = tsr.test0_1_4(y);
+      y = tsr.test0_1_4(y);
+      y = tsr.test0_1_5(y);
+      y = tsr.test0_1_5(y);
+      y = tsr.test0_1_6(y);
+      y = tsr.test0_1_6(y);
+
+      y = tsr.test1_0_0(y&~1);
+      y = tsr.test1_0_1(y&~1);
+      y = tsr.test1_0_2(y&~1);
+      y = tsr.test1_0_3(y&~1);
+      y = tsr.test1_0_4(y&~1);
+      y = tsr.test1_0_5(y&~1);
+      y = tsr.test1_0_6(y&~1);
+      y = tsr.test1_0_0((y&~1)+1);
+      y = tsr.test1_0_1((y&~1)+1);
+      y = tsr.test1_0_2((y&~1)+1);
+      y = tsr.test1_0_3((y&~1)+1);
+      y = tsr.test1_0_4((y&~1)+1);
+      y = tsr.test1_0_5((y&~1)+1);
+      y = tsr.test1_0_6((y&~1)+1);
+
+      y = tsr.test1_1_0(y&~1);
+      y = tsr.test1_1_1(y&~1);
+      y = tsr.test1_1_2(y&~1);
+      y = tsr.test1_1_3(y&~1);
+      y = tsr.test1_1_4(y&~1);
+      y = tsr.test1_1_5(y&~1);
+      y = tsr.test1_1_6(y&~1);
+      y = tsr.test1_1_0((y&~1)+1);
+      y = tsr.test1_1_1((y&~1)+1);
+      y = tsr.test1_1_2((y&~1)+1);
+      y = tsr.test1_1_3((y&~1)+1);
+      y = tsr.test1_1_4((y&~1)+1);
+      y = tsr.test1_1_5((y&~1)+1);
+      y = tsr.test1_1_6((y&~1)+1);
+
+      y = tsr.test1_2_0(y&~1);
+      y = tsr.test1_2_1(y&~1);
+      y = tsr.test1_2_2(y&~1);
+      y = tsr.test1_2_3(y&~1);
+      y = tsr.test1_2_4(y&~1);
+      y = tsr.test1_2_5(y&~1);
+      y = tsr.test1_2_6(y&~1);
+      y = tsr.test1_2_0((y&~1)+1);
+      y = tsr.test1_2_1((y&~1)+1);
+      y = tsr.test1_2_2((y&~1)+1);
+      y = tsr.test1_2_3((y&~1)+1);
+      y = tsr.test1_2_4((y&~1)+1);
+      y = tsr.test1_2_5((y&~1)+1);
+      y = tsr.test1_2_6((y&~1)+1);
+
+      y = tsr.test2_0_0(y&~3);
+      y = tsr.test2_0_1(y&~3);
+      y = tsr.test2_0_2(y&~3);
+      y = tsr.test2_0_3(y&~3);
+      y = tsr.test2_0_4(y&~3);
+      y = tsr.test2_0_5(y&~3);
+      y = tsr.test2_0_6(y&~3);
+      y = tsr.test2_0_0((y&~3)+3);
+      y = tsr.test2_0_1((y&~3)+3);
+      y = tsr.test2_0_2((y&~3)+3);
+      y = tsr.test2_0_3((y&~3)+3);
+      y = tsr.test2_0_4((y&~3)+3);
+      y = tsr.test2_0_5((y&~3)+3);
+      y = tsr.test2_0_6((y&~3)+3);
+
+      y = tsr.test2_1_0(y&~3);
+      y = tsr.test2_1_1(y&~3);
+      y = tsr.test2_1_2(y&~3);
+      y = tsr.test2_1_3(y&~3);
+      y = tsr.test2_1_4(y&~3);
+      y = tsr.test2_1_5(y&~3);
+      y = tsr.test2_1_6(y&~3);
+      y = tsr.test2_1_0((y&~3)+3);
+      y = tsr.test2_1_1((y&~3)+3);
+      y = tsr.test2_1_2((y&~3)+3);
+      y = tsr.test2_1_3((y&~3)+3);
+      y = tsr.test2_1_4((y&~3)+3);
+      y = tsr.test2_1_5((y&~3)+3);
+      y = tsr.test2_1_6((y&~3)+3);
+
+      y = tsr.test2_2_0(y&~3);
+      y = tsr.test2_2_1(y&~3);
+      y = tsr.test2_2_2(y&~3);
+      y = tsr.test2_2_3(y&~3);
+      y = tsr.test2_2_4(y&~3);
+      y = tsr.test2_2_5(y&~3);
+      y = tsr.test2_2_6(y&~3);
+      y = tsr.test2_2_0((y&~3)+3);
+      y = tsr.test2_2_1((y&~3)+3);
+      y = tsr.test2_2_2((y&~3)+3);
+      y = tsr.test2_2_3((y&~3)+3);
+      y = tsr.test2_2_4((y&~3)+3);
+      y = tsr.test2_2_5((y&~3)+3);
+      y = tsr.test2_2_6((y&~3)+3);
+
+    }
+    for (int i=0; i<10000; i++) {
+      y = tsr.test0_0_0(y);
+      y = tsr.test0_0_0(y);
+      y = tsr.test0_0_1(y);
+      y = tsr.test0_0_1(y);
+      y = tsr.test0_0_2(y);
+      y = tsr.test0_0_2(y);
+      y = tsr.test0_0_3(y);
+      y = tsr.test0_0_3(y);
+      y = tsr.test0_0_4(y);
+      y = tsr.test0_0_4(y);
+      y = tsr.test0_0_5(y);
+      y = tsr.test0_0_5(y);
+      y = tsr.test0_0_6(y);
+      y = tsr.test0_0_6(y);
+
+      y = tsr.test0_1_3(y);
+      y = tsr.test0_1_3(y);
+      y = tsr.test0_1_4(y);
+      y = tsr.test0_1_4(y);
+      y = tsr.test0_1_5(y);
+      y = tsr.test0_1_5(y);
+      y = tsr.test0_1_6(y);
+      y = tsr.test0_1_6(y);
+
+      y = tsr.test1_0_0(y&~1);
+      y = tsr.test1_0_1(y&~1);
+      y = tsr.test1_0_2(y&~1);
+      y = tsr.test1_0_3(y&~1);
+      y = tsr.test1_0_4(y&~1);
+      y = tsr.test1_0_5(y&~1);
+      y = tsr.test1_0_6(y&~1);
+      y = tsr.test1_0_0((y&~1)+1);
+      y = tsr.test1_0_1((y&~1)+1);
+      y = tsr.test1_0_2((y&~1)+1);
+      y = tsr.test1_0_3((y&~1)+1);
+      y = tsr.test1_0_4((y&~1)+1);
+      y = tsr.test1_0_5((y&~1)+1);
+      y = tsr.test1_0_6((y&~1)+1);
+
+      y = tsr.test1_1_0(y&~1);
+      y = tsr.test1_1_1(y&~1);
+      y = tsr.test1_1_2(y&~1);
+      y = tsr.test1_1_3(y&~1);
+      y = tsr.test1_1_4(y&~1);
+      y = tsr.test1_1_5(y&~1);
+      y = tsr.test1_1_6(y&~1);
+      y = tsr.test1_1_0((y&~1)+1);
+      y = tsr.test1_1_1((y&~1)+1);
+      y = tsr.test1_1_2((y&~1)+1);
+      y = tsr.test1_1_3((y&~1)+1);
+      y = tsr.test1_1_4((y&~1)+1);
+      y = tsr.test1_1_5((y&~1)+1);
+      y = tsr.test1_1_6((y&~1)+1);
+
+      y = tsr.test1_2_0(y&~1);
+      y = tsr.test1_2_1(y&~1);
+      y = tsr.test1_2_2(y&~1);
+      y = tsr.test1_2_3(y&~1);
+      y = tsr.test1_2_4(y&~1);
+      y = tsr.test1_2_5(y&~1);
+      y = tsr.test1_2_6(y&~1);
+      y = tsr.test1_2_0((y&~1)+1);
+      y = tsr.test1_2_1((y&~1)+1);
+      y = tsr.test1_2_2((y&~1)+1);
+      y = tsr.test1_2_3((y&~1)+1);
+      y = tsr.test1_2_4((y&~1)+1);
+      y = tsr.test1_2_5((y&~1)+1);
+      y = tsr.test1_2_6((y&~1)+1);
+
+      y = tsr.test2_0_0(y&~3);
+      y = tsr.test2_0_1(y&~3);
+      y = tsr.test2_0_2(y&~3);
+      y = tsr.test2_0_3(y&~3);
+      y = tsr.test2_0_4(y&~3);
+      y = tsr.test2_0_5(y&~3);
+      y = tsr.test2_0_6(y&~3);
+      y = tsr.test2_0_0((y&~3)+3);
+      y = tsr.test2_0_1((y&~3)+3);
+      y = tsr.test2_0_2((y&~3)+3);
+      y = tsr.test2_0_3((y&~3)+3);
+      y = tsr.test2_0_4((y&~3)+3);
+      y = tsr.test2_0_5((y&~3)+3);
+      y = tsr.test2_0_6((y&~3)+3);
+
+      y = tsr.test2_1_0(y&~3);
+      y = tsr.test2_1_1(y&~3);
+      y = tsr.test2_1_2(y&~3);
+      y = tsr.test2_1_3(y&~3);
+      y = tsr.test2_1_4(y&~3);
+      y = tsr.test2_1_5(y&~3);
+      y = tsr.test2_1_6(y&~3);
+      y = tsr.test2_1_0((y&~3)+3);
+      y = tsr.test2_1_1((y&~3)+3);
+      y = tsr.test2_1_2((y&~3)+3);
+      y = tsr.test2_1_3((y&~3)+3);
+      y = tsr.test2_1_4((y&~3)+3);
+      y = tsr.test2_1_5((y&~3)+3);
+      y = tsr.test2_1_6((y&~3)+3);
+
+      y = tsr.test2_2_0(y&~3);
+      y = tsr.test2_2_1(y&~3);
+      y = tsr.test2_2_2(y&~3);
+      y = tsr.test2_2_3(y&~3);
+      y = tsr.test2_2_4(y&~3);
+      y = tsr.test2_2_5(y&~3);
+      y = tsr.test2_2_6(y&~3);
+      y = tsr.test2_2_0((y&~3)+3);
+      y = tsr.test2_2_1((y&~3)+3);
+      y = tsr.test2_2_2((y&~3)+3);
+      y = tsr.test2_2_3((y&~3)+3);
+      y = tsr.test2_2_4((y&~3)+3);
+      y = tsr.test2_2_5((y&~3)+3);
+      y = tsr.test2_2_6((y&~3)+3);
+
+    }
+    for (int i=0; i<10000; i++) {
+      y = tsr.test0_0_0(y);
+      y = tsr.test0_0_0(y);
+      y = tsr.test0_0_1(y);
+      y = tsr.test0_0_1(y);
+      y = tsr.test0_0_2(y);
+      y = tsr.test0_0_2(y);
+      y = tsr.test0_0_3(y);
+      y = tsr.test0_0_3(y);
+      y = tsr.test0_0_4(y);
+      y = tsr.test0_0_4(y);
+      y = tsr.test0_0_5(y);
+      y = tsr.test0_0_5(y);
+      y = tsr.test0_0_6(y);
+      y = tsr.test0_0_6(y);
+
+      y = tsr.test0_1_3(y);
+      y = tsr.test0_1_3(y);
+      y = tsr.test0_1_4(y);
+      y = tsr.test0_1_4(y);
+      y = tsr.test0_1_5(y);
+      y = tsr.test0_1_5(y);
+      y = tsr.test0_1_6(y);
+      y = tsr.test0_1_6(y);
+
+      y = tsr.test1_0_0(y&~1);
+      y = tsr.test1_0_1(y&~1);
+      y = tsr.test1_0_2(y&~1);
+      y = tsr.test1_0_3(y&~1);
+      y = tsr.test1_0_4(y&~1);
+      y = tsr.test1_0_5(y&~1);
+      y = tsr.test1_0_6(y&~1);
+      y = tsr.test1_0_0((y&~1)+1);
+      y = tsr.test1_0_1((y&~1)+1);
+      y = tsr.test1_0_2((y&~1)+1);
+      y = tsr.test1_0_3((y&~1)+1);
+      y = tsr.test1_0_4((y&~1)+1);
+      y = tsr.test1_0_5((y&~1)+1);
+      y = tsr.test1_0_6((y&~1)+1);
+
+      y = tsr.test1_1_0(y&~1);
+      y = tsr.test1_1_1(y&~1);
+      y = tsr.test1_1_2(y&~1);
+      y = tsr.test1_1_3(y&~1);
+      y = tsr.test1_1_4(y&~1);
+      y = tsr.test1_1_5(y&~1);
+      y = tsr.test1_1_6(y&~1);
+      y = tsr.test1_1_0((y&~1)+1);
+      y = tsr.test1_1_1((y&~1)+1);
+      y = tsr.test1_1_2((y&~1)+1);
+      y = tsr.test1_1_3((y&~1)+1);
+      y = tsr.test1_1_4((y&~1)+1);
+      y = tsr.test1_1_5((y&~1)+1);
+      y = tsr.test1_1_6((y&~1)+1);
+
+      y = tsr.test1_2_0(y&~1);
+      y = tsr.test1_2_1(y&~1);
+      y = tsr.test1_2_2(y&~1);
+      y = tsr.test1_2_3(y&~1);
+      y = tsr.test1_2_4(y&~1);
+      y = tsr.test1_2_5(y&~1);
+      y = tsr.test1_2_6(y&~1);
+      y = tsr.test1_2_0((y&~1)+1);
+      y = tsr.test1_2_1((y&~1)+1);
+      y = tsr.test1_2_2((y&~1)+1);
+      y = tsr.test1_2_3((y&~1)+1);
+      y = tsr.test1_2_4((y&~1)+1);
+      y = tsr.test1_2_5((y&~1)+1);
+      y = tsr.test1_2_6((y&~1)+1);
+
+      y = tsr.test2_0_0(y&~3);
+      y = tsr.test2_0_1(y&~3);
+      y = tsr.test2_0_2(y&~3);
+      y = tsr.test2_0_3(y&~3);
+      y = tsr.test2_0_4(y&~3);
+      y = tsr.test2_0_5(y&~3);
+      y = tsr.test2_0_6(y&~3);
+      y = tsr.test2_0_0((y&~3)+3);
+      y = tsr.test2_0_1((y&~3)+3);
+      y = tsr.test2_0_2((y&~3)+3);
+      y = tsr.test2_0_3((y&~3)+3);
+      y = tsr.test2_0_4((y&~3)+3);
+      y = tsr.test2_0_5((y&~3)+3);
+      y = tsr.test2_0_6((y&~3)+3);
+
+      y = tsr.test2_1_0(y&~3);
+      y = tsr.test2_1_1(y&~3);
+      y = tsr.test2_1_2(y&~3);
+      y = tsr.test2_1_3(y&~3);
+      y = tsr.test2_1_4(y&~3);
+      y = tsr.test2_1_5(y&~3);
+      y = tsr.test2_1_6(y&~3);
+      y = tsr.test2_1_0((y&~3)+3);
+      y = tsr.test2_1_1((y&~3)+3);
+      y = tsr.test2_1_2((y&~3)+3);
+      y = tsr.test2_1_3((y&~3)+3);
+      y = tsr.test2_1_4((y&~3)+3);
+      y = tsr.test2_1_5((y&~3)+3);
+      y = tsr.test2_1_6((y&~3)+3);
+
+      y = tsr.test2_2_0(y&~3);
+      y = tsr.test2_2_1(y&~3);
+      y = tsr.test2_2_2(y&~3);
+      y = tsr.test2_2_3(y&~3);
+      y = tsr.test2_2_4(y&~3);
+      y = tsr.test2_2_5(y&~3);
+      y = tsr.test2_2_6(y&~3);
+      y = tsr.test2_2_0((y&~3)+3);
+      y = tsr.test2_2_1((y&~3)+3);
+      y = tsr.test2_2_2((y&~3)+3);
+      y = tsr.test2_2_3((y&~3)+3);
+      y = tsr.test2_2_4((y&~3)+3);
+      y = tsr.test2_2_5((y&~3)+3);
+      y = tsr.test2_2_6((y&~3)+3);
+
+    }
+
+    int z = 0;
+    y = tsr.test0_0_0(0);
+    System.out.println("After 'test0_0_0' y=" + y);
+    y = tsr.test0_0_1(0);
+    System.out.println("After 'test0_0_1' y=" + y);
+    y = tsr.test0_0_2(0);
+    System.out.println("After 'test0_0_2' y=" + y);
+    y = tsr.test0_0_3(0);
+    System.out.println("After 'test0_0_3' y=" + y);
+    y = tsr.test0_0_4(0);
+    System.out.println("After 'test0_0_4' y=" + y);
+    y = tsr.test0_0_5(0);
+    System.out.println("After 'test0_0_5' y=" + y);
+    y = tsr.test0_0_6(0);
+    System.out.println("After 'test0_0_6' y=" + y);
+    y = tsr.test0_1_3(0);
+    System.out.println("After 'test0_1_3' y=" + y);
+    y = tsr.test0_1_4(0);
+    System.out.println("After 'test0_1_4' y=" + y);
+    y = tsr.test0_1_5(0);
+    System.out.println("After 'test0_1_5' y=" + y);
+    y = tsr.test0_1_6(0);
+    System.out.println("After 'test0_1_6' y=" + y);
+
+    y = tsr.test1_0_0(0);
+    System.out.println("After 'test1_0_0' y=" + y);
+    y = tsr.test1_0_1(0);
+    System.out.println("After 'test1_0_1' y=" + y);
+    y = tsr.test1_0_2(0);
+    System.out.println("After 'test1_0_2' y=" + y);
+    y = tsr.test1_0_3(0);
+    System.out.println("After 'test1_0_3' y=" + y);
+    y = tsr.test1_0_4(0);
+    System.out.println("After 'test1_0_4' y=" + y);
+    y = tsr.test1_0_5(0);
+    System.out.println("After 'test1_0_5' y=" + y);
+    y = tsr.test1_0_6(0);
+    System.out.println("After 'test1_0_6' y=" + y);
+
+    y = tsr.test1_1_0(0);
+    System.out.println("After 'test1_1_0' y=" + y);
+    y = tsr.test1_1_1(0);
+    System.out.println("After 'test1_1_1' y=" + y);
+    y = tsr.test1_1_2(0);
+    System.out.println("After 'test1_1_2' y=" + y);
+    y = tsr.test1_1_3(0);
+    System.out.println("After 'test1_1_3' y=" + y);
+    y = tsr.test1_1_4(0);
+    System.out.println("After 'test1_1_4' y=" + y);
+    y = tsr.test1_1_5(0);
+    System.out.println("After 'test1_1_5' y=" + y);
+    y = tsr.test1_1_6(0);
+    System.out.println("After 'test1_1_6' y=" + y);
+
+    y = tsr.test1_2_0(0);
+    System.out.println("After 'test1_2_0' y=" + y);
+    y = tsr.test1_2_1(0);
+    System.out.println("After 'test1_2_1' y=" + y);
+    y = tsr.test1_2_2(0);
+    System.out.println("After 'test1_2_2' y=" + y);
+    y = tsr.test1_2_3(0);
+    System.out.println("After 'test1_2_3' y=" + y);
+    y = tsr.test1_2_4(0);
+    System.out.println("After 'test1_2_4' y=" + y);
+    y = tsr.test1_2_5(0);
+    System.out.println("After 'test1_2_5' y=" + y);
+    y = tsr.test1_2_6(0);
+    System.out.println("After 'test1_2_6' y=" + y);
+
+    y = tsr.test2_0_0(0);
+    System.out.println("After 'test2_0_0' y=" + y);
+    y = tsr.test2_0_1(0);
+    System.out.println("After 'test2_0_1' y=" + y);
+    y = tsr.test2_0_2(0);
+    System.out.println("After 'test2_0_2' y=" + y);
+    y = tsr.test2_0_3(0);
+    System.out.println("After 'test2_0_3' y=" + y);
+    y = tsr.test2_0_4(0);
+    System.out.println("After 'test2_0_4' y=" + y);
+    y = tsr.test2_0_5(0);
+    System.out.println("After 'test2_0_5' y=" + y);
+    y = tsr.test2_0_6(0);
+    System.out.println("After 'test2_0_6' y=" + y);
+
+    y = tsr.test2_1_0(0);
+    System.out.println("After 'test2_1_0' y=" + y);
+    y = tsr.test2_1_1(0);
+    System.out.println("After 'test2_1_1' y=" + y);
+    y = tsr.test2_1_2(0);
+    System.out.println("After 'test2_1_2' y=" + y);
+    y = tsr.test2_1_3(0);
+    System.out.println("After 'test2_1_3' y=" + y);
+    y = tsr.test2_1_4(0);
+    System.out.println("After 'test2_1_4' y=" + y);
+    y = tsr.test2_1_5(0);
+    System.out.println("After 'test2_1_5' y=" + y);
+    y = tsr.test2_1_6(0);
+    System.out.println("After 'test2_1_6' y=" + y);
+
+    y = tsr.test2_2_0(0);
+    System.out.println("After 'test2_2_0' y=" + y);
+    y = tsr.test2_2_1(0);
+    System.out.println("After 'test2_2_1' y=" + y);
+    y = tsr.test2_2_2(0);
+    System.out.println("After 'test2_2_2' y=" + y);
+    y = tsr.test2_2_3(0);
+    System.out.println("After 'test2_2_3' y=" + y);
+    y = tsr.test2_2_4(0);
+    System.out.println("After 'test2_2_4' y=" + y);
+    y = tsr.test2_2_5(0);
+    System.out.println("After 'test2_2_5' y=" + y);
+    y = tsr.test2_2_6(0);
+    System.out.println("After 'test2_2_6' y=" + y);
+
+  }
+}