8039298: assert(base == NULL || t_adr->isa_rawptr() || !phase->type(base)->higher_equal(TypePtr::NULL_PTR))

Fri, 02 May 2014 16:44:54 -0700

author
kvn
date
Fri, 02 May 2014 16:44:54 -0700
changeset 6657
3636afd5ec1a
parent 6656
1eba0601f0dd
child 6658
e0a77b91da68

8039298: assert(base == NULL || t_adr->isa_rawptr() || !phase->type(base)->higher_equal(TypePtr::NULL_PTR))
Summary: Convert the assert into the runtime check to skip IGVN optimizations for problematic memory nodes. Eliminate dead nodes more aggressively.
Reviewed-by: twisti, iveresov

src/share/vm/opto/compile.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/compile.hpp file | annotate | diff | comparison | revisions
src/share/vm/opto/loopnode.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/memnode.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/node.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/opto/compile.cpp	Tue Apr 29 12:20:53 2014 -0700
     1.2 +++ b/src/share/vm/opto/compile.cpp	Fri May 02 16:44:54 2014 -0700
     1.3 @@ -693,6 +693,7 @@
     1.4  #endif
     1.5    set_print_inlining(PrintInlining || method()->has_option("PrintInlining") NOT_PRODUCT( || PrintOptoInlining));
     1.6    set_print_intrinsics(PrintIntrinsics || method()->has_option("PrintIntrinsics"));
     1.7 +  set_has_irreducible_loop(true); // conservative until build_loop_tree() reset it
     1.8  
     1.9    if (ProfileTraps RTM_OPT_ONLY( || UseRTMLocking )) {
    1.10      // Make sure the method being compiled gets its own MDO,
    1.11 @@ -977,6 +978,8 @@
    1.12    set_print_assembly(PrintFrameConverterAssembly);
    1.13    set_parsed_irreducible_loop(false);
    1.14  #endif
    1.15 +  set_has_irreducible_loop(false); // no loops
    1.16 +
    1.17    CompileWrapper cw(this);
    1.18    Init(/*AliasLevel=*/ 0);
    1.19    init_tf((*generator)());
    1.20 @@ -1147,7 +1150,7 @@
    1.21      if( start->is_Start() )
    1.22        return start->as_Start();
    1.23    }
    1.24 -  ShouldNotReachHere();
    1.25 +  fatal("Did not find Start node!");
    1.26    return NULL;
    1.27  }
    1.28  
     2.1 --- a/src/share/vm/opto/compile.hpp	Tue Apr 29 12:20:53 2014 -0700
     2.2 +++ b/src/share/vm/opto/compile.hpp	Fri May 02 16:44:54 2014 -0700
     2.3 @@ -319,6 +319,7 @@
     2.4    bool                  _trace_opto_output;
     2.5    bool                  _parsed_irreducible_loop; // True if ciTypeFlow detected irreducible loops during parsing
     2.6  #endif
     2.7 +  bool                  _has_irreducible_loop;  // Found irreducible loops
     2.8    // JSR 292
     2.9    bool                  _has_method_handle_invokes; // True if this method has MethodHandle invokes.
    2.10    RTMState              _rtm_state;             // State of Restricted Transactional Memory usage
    2.11 @@ -605,6 +606,8 @@
    2.12    void          set_parsed_irreducible_loop(bool z) { _parsed_irreducible_loop = z; }
    2.13    int _in_dump_cnt;  // Required for dumping ir nodes.
    2.14  #endif
    2.15 +  bool              has_irreducible_loop() const { return _has_irreducible_loop; }
    2.16 +  void          set_has_irreducible_loop(bool z) { _has_irreducible_loop = z; }
    2.17  
    2.18    // JSR 292
    2.19    bool              has_method_handle_invokes() const { return _has_method_handle_invokes;     }
     3.1 --- a/src/share/vm/opto/loopnode.cpp	Tue Apr 29 12:20:53 2014 -0700
     3.2 +++ b/src/share/vm/opto/loopnode.cpp	Fri May 02 16:44:54 2014 -0700
     3.3 @@ -266,9 +266,9 @@
     3.4  
     3.5    // Counted loop head must be a good RegionNode with only 3 not NULL
     3.6    // control input edges: Self, Entry, LoopBack.
     3.7 -  if (x->in(LoopNode::Self) == NULL || x->req() != 3)
     3.8 +  if (x->in(LoopNode::Self) == NULL || x->req() != 3 || loop->_irreducible) {
     3.9      return false;
    3.10 -
    3.11 +  }
    3.12    Node *init_control = x->in(LoopNode::EntryControl);
    3.13    Node *back_control = x->in(LoopNode::LoopBackControl);
    3.14    if (init_control == NULL || back_control == NULL)    // Partially dead
    3.15 @@ -1522,11 +1522,11 @@
    3.16  
    3.17    // If I have one hot backedge, peel off myself loop.
    3.18    // I better be the outermost loop.
    3.19 -  if( _head->req() > 3 ) {
    3.20 +  if (_head->req() > 3 && !_irreducible) {
    3.21      split_outer_loop( phase );
    3.22      result = true;
    3.23  
    3.24 -  } else if( !_head->is_Loop() && !_irreducible ) {
    3.25 +  } else if (!_head->is_Loop() && !_irreducible) {
    3.26      // Make a new LoopNode to replace the old loop head
    3.27      Node *l = new (phase->C) LoopNode( _head->in(1), _head->in(2) );
    3.28      l = igvn.register_new_node_with_optimizer(l, _head);
    3.29 @@ -2938,6 +2938,7 @@
    3.30            return pre_order;
    3.31          }
    3.32        }
    3.33 +      C->set_has_irreducible_loop(_has_irreducible_loops);
    3.34      }
    3.35  
    3.36      // This Node might be a decision point for loops.  It is only if
     4.1 --- a/src/share/vm/opto/memnode.cpp	Tue Apr 29 12:20:53 2014 -0700
     4.2 +++ b/src/share/vm/opto/memnode.cpp	Fri May 02 16:44:54 2014 -0700
     4.3 @@ -306,33 +306,16 @@
     4.4      int alias_idx = phase->C->get_alias_index(t_adr->is_ptr());
     4.5    }
     4.6  
     4.7 -#ifdef ASSERT
     4.8    Node* base = NULL;
     4.9 -  if (address->is_AddP())
    4.10 +  if (address->is_AddP()) {
    4.11      base = address->in(AddPNode::Base);
    4.12 +  }
    4.13    if (base != NULL && phase->type(base)->higher_equal(TypePtr::NULL_PTR) &&
    4.14        !t_adr->isa_rawptr()) {
    4.15      // Note: raw address has TOP base and top->higher_equal(TypePtr::NULL_PTR) is true.
    4.16 -    Compile* C = phase->C;
    4.17 -    tty->cr();
    4.18 -    tty->print_cr("===== NULL+offs not RAW address =====");
    4.19 -    if (C->is_dead_node(this->_idx))    tty->print_cr("'this' is dead");
    4.20 -    if ((ctl != NULL) && C->is_dead_node(ctl->_idx)) tty->print_cr("'ctl' is dead");
    4.21 -    if (C->is_dead_node(mem->_idx))     tty->print_cr("'mem' is dead");
    4.22 -    if (C->is_dead_node(address->_idx)) tty->print_cr("'address' is dead");
    4.23 -    if (C->is_dead_node(base->_idx))    tty->print_cr("'base' is dead");
    4.24 -    tty->cr();
    4.25 -    base->dump(1);
    4.26 -    tty->cr();
    4.27 -    this->dump(2);
    4.28 -    tty->print("this->adr_type():     "); adr_type()->dump(); tty->cr();
    4.29 -    tty->print("phase->type(address): "); t_adr->dump(); tty->cr();
    4.30 -    tty->print("phase->type(base):    "); phase->type(address)->dump(); tty->cr();
    4.31 -    tty->cr();
    4.32 +    // Skip this node optimization if its address has TOP base.
    4.33 +    return NodeSentinel; // caller will return NULL
    4.34    }
    4.35 -  assert(base == NULL || t_adr->isa_rawptr() ||
    4.36 -        !phase->type(base)->higher_equal(TypePtr::NULL_PTR), "NULL+offs not RAW address?");
    4.37 -#endif
    4.38  
    4.39    // Avoid independent memory operations
    4.40    Node* old_mem = mem;
     5.1 --- a/src/share/vm/opto/node.cpp	Tue Apr 29 12:20:53 2014 -0700
     5.2 +++ b/src/share/vm/opto/node.cpp	Fri May 02 16:44:54 2014 -0700
     5.3 @@ -27,6 +27,7 @@
     5.4  #include "memory/allocation.inline.hpp"
     5.5  #include "opto/cfgnode.hpp"
     5.6  #include "opto/connode.hpp"
     5.7 +#include "opto/loopnode.hpp"
     5.8  #include "opto/machnode.hpp"
     5.9  #include "opto/matcher.hpp"
    5.10  #include "opto/node.hpp"
    5.11 @@ -1255,6 +1256,7 @@
    5.12  
    5.13    Node *top = igvn->C->top();
    5.14    nstack.push(dead);
    5.15 +  bool has_irreducible_loop = igvn->C->has_irreducible_loop();
    5.16  
    5.17    while (nstack.size() > 0) {
    5.18      dead = nstack.pop();
    5.19 @@ -1269,13 +1271,31 @@
    5.20            assert (!use->is_Con(), "Control for Con node should be Root node.");
    5.21            use->set_req(0, top);       // Cut dead edge to prevent processing
    5.22            nstack.push(use);           // the dead node again.
    5.23 +        } else if (!has_irreducible_loop && // Backedge could be alive in irreducible loop
    5.24 +                   use->is_Loop() && !use->is_Root() &&       // Don't kill Root (RootNode extends LoopNode)
    5.25 +                   use->in(LoopNode::EntryControl) == dead) { // Dead loop if its entry is dead
    5.26 +          use->set_req(LoopNode::EntryControl, top);          // Cut dead edge to prevent processing
    5.27 +          use->set_req(0, top);       // Cut self edge
    5.28 +          nstack.push(use);
    5.29          } else {                      // Else found a not-dead user
    5.30 +          // Dead if all inputs are top or null
    5.31 +          bool dead_use = !use->is_Root(); // Keep empty graph alive
    5.32            for (uint j = 1; j < use->req(); j++) {
    5.33 -            if (use->in(j) == dead) { // Turn all dead inputs into TOP
    5.34 +            Node* in = use->in(j);
    5.35 +            if (in == dead) {         // Turn all dead inputs into TOP
    5.36                use->set_req(j, top);
    5.37 +            } else if (in != NULL && !in->is_top()) {
    5.38 +              dead_use = false;
    5.39              }
    5.40            }
    5.41 -          igvn->_worklist.push(use);
    5.42 +          if (dead_use) {
    5.43 +            if (use->is_Region()) {
    5.44 +              use->set_req(0, top);   // Cut self edge
    5.45 +            }
    5.46 +            nstack.push(use);
    5.47 +          } else {
    5.48 +            igvn->_worklist.push(use);
    5.49 +          }
    5.50          }
    5.51          // Refresh the iterator, since any number of kills might have happened.
    5.52          k = dead->last_outs(kmin);

mercurial