src/share/vm/opto/compile.cpp

changeset 8478
c42cb5db3601
parent 8193
70649f10b88c
parent 8476
94ec11846b18
child 8504
a96cf90239c6
     1.1 --- a/src/share/vm/opto/compile.cpp	Mon Feb 22 13:39:47 2016 -0800
     1.2 +++ b/src/share/vm/opto/compile.cpp	Tue Mar 01 15:19:31 2016 -0800
     1.3 @@ -412,6 +412,13 @@
     1.4        remove_macro_node(n);
     1.5      }
     1.6    }
     1.7 +  // Remove useless CastII nodes with range check dependency
     1.8 +  for (int i = range_check_cast_count() - 1; i >= 0; i--) {
     1.9 +    Node* cast = range_check_cast_node(i);
    1.10 +    if (!useful.member(cast)) {
    1.11 +      remove_range_check_cast(cast);
    1.12 +    }
    1.13 +  }
    1.14    // Remove useless expensive node
    1.15    for (int i = C->expensive_count()-1; i >= 0; i--) {
    1.16      Node* n = C->expensive_node(i);
    1.17 @@ -1148,6 +1155,7 @@
    1.18    _macro_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8,  0, NULL);
    1.19    _predicate_opaqs = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8,  0, NULL);
    1.20    _expensive_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8,  0, NULL);
    1.21 +  _range_check_casts = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8,  0, NULL);
    1.22    register_library_intrinsics();
    1.23  }
    1.24  
    1.25 @@ -1876,6 +1884,22 @@
    1.26    assert(predicate_count()==0, "should be clean!");
    1.27  }
    1.28  
    1.29 +void Compile::add_range_check_cast(Node* n) {
    1.30 +  assert(n->isa_CastII()->has_range_check(), "CastII should have range check dependency");
    1.31 +  assert(!_range_check_casts->contains(n), "duplicate entry in range check casts");
    1.32 +  _range_check_casts->append(n);
    1.33 +}
    1.34 +
    1.35 +// Remove all range check dependent CastIINodes.
    1.36 +void Compile::remove_range_check_casts(PhaseIterGVN &igvn) {
    1.37 +  for (int i = range_check_cast_count(); i > 0; i--) {
    1.38 +    Node* cast = range_check_cast_node(i-1);
    1.39 +    assert(cast->isa_CastII()->has_range_check(), "CastII should have range check dependency");
    1.40 +    igvn.replace_node(cast, cast->in(1));
    1.41 +  }
    1.42 +  assert(range_check_cast_count() == 0, "should be empty");
    1.43 +}
    1.44 +
    1.45  // StringOpts and late inlining of string methods
    1.46  void Compile::inline_string_calls(bool parse_time) {
    1.47    {
    1.48 @@ -2218,6 +2242,12 @@
    1.49      PhaseIdealLoop::verify(igvn);
    1.50    }
    1.51  
    1.52 +  if (range_check_cast_count() > 0) {
    1.53 +    // No more loop optimizations. Remove all range check dependent CastIINodes.
    1.54 +    C->remove_range_check_casts(igvn);
    1.55 +    igvn.optimize();
    1.56 +  }
    1.57 +
    1.58    {
    1.59      NOT_PRODUCT( TracePhase t2("macroExpand", &_t_macroExpand, TimeCompiler); )
    1.60      PhaseMacroExpand  mex(igvn);
    1.61 @@ -2987,6 +3017,16 @@
    1.62  
    1.63  #endif
    1.64  
    1.65 +#ifdef ASSERT
    1.66 +  case Op_CastII:
    1.67 +    // Verify that all range check dependent CastII nodes were removed.
    1.68 +    if (n->isa_CastII()->has_range_check()) {
    1.69 +      n->dump(3);
    1.70 +      assert(false, "Range check dependent CastII node was not removed");
    1.71 +    }
    1.72 +    break;
    1.73 +#endif
    1.74 +
    1.75    case Op_ModI:
    1.76      if (UseDivMod) {
    1.77        // Check if a%b and a/b both exist
    1.78 @@ -4024,6 +4064,24 @@
    1.79    }
    1.80  }
    1.81  
    1.82 +// Convert integer value to a narrowed long type dependent on ctrl (for example, a range check)
    1.83 +Node* Compile::constrained_convI2L(PhaseGVN* phase, Node* value, const TypeInt* itype, Node* ctrl) {
    1.84 +  if (ctrl != NULL) {
    1.85 +    // Express control dependency by a CastII node with a narrow type.
    1.86 +    value = new (phase->C) CastIINode(value, itype, false, true /* range check dependency */);
    1.87 +    // Make the CastII node dependent on the control input to prevent the narrowed ConvI2L
    1.88 +    // node from floating above the range check during loop optimizations. Otherwise, the
    1.89 +    // ConvI2L node may be eliminated independently of the range check, causing the data path
    1.90 +    // to become TOP while the control path is still there (although it's unreachable).
    1.91 +    value->set_req(0, ctrl);
    1.92 +    // Save CastII node to remove it after loop optimizations.
    1.93 +    phase->C->add_range_check_cast(value);
    1.94 +    value = phase->transform(value);
    1.95 +  }
    1.96 +  const TypeLong* ltype = TypeLong::make(itype->_lo, itype->_hi, itype->_widen);
    1.97 +  return phase->transform(new (phase->C) ConvI2LNode(value, ltype));
    1.98 +}
    1.99 +
   1.100  // Auxiliary method to support randomized stressing/fuzzing.
   1.101  //
   1.102  // This method can be called the arbitrary number of times, with current count

mercurial