6791572: assert("duplicating node that's already been matched")

Mon, 23 Feb 2009 16:03:19 -0800

author
kvn
date
Mon, 23 Feb 2009 16:03:19 -0800
changeset 1021
6bea93606c11
parent 1020
22e09c0f4b47
child 1022
e57b6f22d1f3

6791572: assert("duplicating node that's already been matched")
Summary: Mark inputs for an address expression as shared if there are other uses besides address expressions.
Reviewed-by: never

src/share/vm/opto/matcher.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/opto/matcher.cpp	Mon Feb 23 12:02:30 2009 -0800
     1.2 +++ b/src/share/vm/opto/matcher.cpp	Mon Feb 23 16:03:19 2009 -0800
     1.3 @@ -1707,11 +1707,18 @@
     1.4  void Matcher::find_shared( Node *n ) {
     1.5    // Allocate stack of size C->unique() * 2 to avoid frequent realloc
     1.6    MStack mstack(C->unique() * 2);
     1.7 +  // Mark nodes as address_visited if they are inputs to an address expression
     1.8 +  VectorSet address_visited(Thread::current()->resource_area());
     1.9    mstack.push(n, Visit);     // Don't need to pre-visit root node
    1.10    while (mstack.is_nonempty()) {
    1.11      n = mstack.node();       // Leave node on stack
    1.12      Node_State nstate = mstack.state();
    1.13 +    uint nop = n->Opcode();
    1.14      if (nstate == Pre_Visit) {
    1.15 +      if (address_visited.test(n->_idx)) { // Visited in address already?
    1.16 +        // Flag as visited and shared now.
    1.17 +        set_visited(n);
    1.18 +      }
    1.19        if (is_visited(n)) {   // Visited already?
    1.20          // Node is shared and has no reason to clone.  Flag it as shared.
    1.21          // This causes it to match into a register for the sharing.
    1.22 @@ -1726,7 +1733,7 @@
    1.23        set_visited(n);   // Flag as visited now
    1.24        bool mem_op = false;
    1.25  
    1.26 -      switch( n->Opcode() ) {  // Handle some opcodes special
    1.27 +      switch( nop ) {  // Handle some opcodes special
    1.28        case Op_Phi:             // Treat Phis as shared roots
    1.29        case Op_Parm:
    1.30        case Op_Proj:            // All handled specially during matching
    1.31 @@ -1887,34 +1894,51 @@
    1.32              // to have a single use so force sharing here.
    1.33              set_shared(m->in(AddPNode::Base)->in(1));
    1.34            }
    1.35 +
    1.36 +          // Some inputs for address expression are not put on stack
    1.37 +          // to avoid marking them as shared and forcing them into register
    1.38 +          // if they are used only in address expressions.
    1.39 +          // But they should be marked as shared if there are other uses
    1.40 +          // besides address expressions.
    1.41 +
    1.42            Node *off = m->in(AddPNode::Offset);
    1.43 -          if( off->is_Con() ) {
    1.44 -            set_visited(m);  // Flag as visited now
    1.45 +          if( off->is_Con() &&
    1.46 +              // When there are other uses besides address expressions
    1.47 +              // put it on stack and mark as shared.
    1.48 +              !is_visited(m) ) {
    1.49 +            address_visited.test_set(m->_idx); // Flag as address_visited
    1.50              Node *adr = m->in(AddPNode::Address);
    1.51  
    1.52              // Intel, ARM and friends can handle 2 adds in addressing mode
    1.53              if( clone_shift_expressions && adr->is_AddP() &&
    1.54                  // AtomicAdd is not an addressing expression.
    1.55                  // Cheap to find it by looking for screwy base.
    1.56 -                !adr->in(AddPNode::Base)->is_top() ) {
    1.57 -              set_visited(adr);  // Flag as visited now
    1.58 +                !adr->in(AddPNode::Base)->is_top() &&
    1.59 +                // Are there other uses besides address expressions?
    1.60 +                !is_visited(adr) ) {
    1.61 +              address_visited.set(adr->_idx); // Flag as address_visited
    1.62                Node *shift = adr->in(AddPNode::Offset);
    1.63                // Check for shift by small constant as well
    1.64                if( shift->Opcode() == Op_LShiftX && shift->in(2)->is_Con() &&
    1.65 -                  shift->in(2)->get_int() <= 3 ) {
    1.66 -                set_visited(shift);  // Flag as visited now
    1.67 +                  shift->in(2)->get_int() <= 3 &&
    1.68 +                  // Are there other uses besides address expressions?
    1.69 +                  !is_visited(shift) ) {
    1.70 +                address_visited.set(shift->_idx); // Flag as address_visited
    1.71                  mstack.push(shift->in(2), Visit);
    1.72 +                Node *conv = shift->in(1);
    1.73  #ifdef _LP64
    1.74                  // Allow Matcher to match the rule which bypass
    1.75                  // ConvI2L operation for an array index on LP64
    1.76                  // if the index value is positive.
    1.77 -                if( shift->in(1)->Opcode() == Op_ConvI2L &&
    1.78 -                    shift->in(1)->as_Type()->type()->is_long()->_lo >= 0 ) {
    1.79 -                  set_visited(shift->in(1));  // Flag as visited now
    1.80 -                  mstack.push(shift->in(1)->in(1), Pre_Visit);
    1.81 +                if( conv->Opcode() == Op_ConvI2L &&
    1.82 +                    conv->as_Type()->type()->is_long()->_lo >= 0 &&
    1.83 +                    // Are there other uses besides address expressions?
    1.84 +                    !is_visited(conv) ) {
    1.85 +                  address_visited.set(conv->_idx); // Flag as address_visited
    1.86 +                  mstack.push(conv->in(1), Pre_Visit);
    1.87                  } else
    1.88  #endif
    1.89 -                mstack.push(shift->in(1), Pre_Visit);
    1.90 +                mstack.push(conv, Pre_Visit);
    1.91                } else {
    1.92                  mstack.push(shift, Pre_Visit);
    1.93                }

mercurial