src/share/vm/opto/memnode.cpp

changeset 499
b8f5ba577b02
parent 478
d821d920b465
child 503
daf38130e60d
     1.1 --- a/src/share/vm/opto/memnode.cpp	Thu Mar 13 16:06:34 2008 -0700
     1.2 +++ b/src/share/vm/opto/memnode.cpp	Thu Mar 13 16:31:32 2008 -0700
     1.3 @@ -87,6 +87,58 @@
     1.4  
     1.5  #endif
     1.6  
     1.7 +static Node *step_through_mergemem(PhaseGVN *phase, MergeMemNode *mmem,  const TypePtr *tp, const TypePtr *adr_check, outputStream *st) {
     1.8 +  uint alias_idx = phase->C->get_alias_index(tp);
     1.9 +  Node *mem = mmem;
    1.10 +#ifdef ASSERT
    1.11 +  {
    1.12 +    // Check that current type is consistent with the alias index used during graph construction
    1.13 +    assert(alias_idx >= Compile::AliasIdxRaw, "must not be a bad alias_idx");
    1.14 +    bool consistent =  adr_check == NULL || adr_check->empty() ||
    1.15 +                       phase->C->must_alias(adr_check, alias_idx );
    1.16 +    // Sometimes dead array references collapse to a[-1], a[-2], or a[-3]
    1.17 +    if( !consistent && adr_check != NULL && !adr_check->empty() &&
    1.18 +           tp->isa_aryptr() &&    tp->offset() == Type::OffsetBot &&
    1.19 +        adr_check->isa_aryptr() && adr_check->offset() != Type::OffsetBot &&
    1.20 +        ( adr_check->offset() == arrayOopDesc::length_offset_in_bytes() ||
    1.21 +          adr_check->offset() == oopDesc::klass_offset_in_bytes() ||
    1.22 +          adr_check->offset() == oopDesc::mark_offset_in_bytes() ) ) {
    1.23 +      // don't assert if it is dead code.
    1.24 +      consistent = true;
    1.25 +    }
    1.26 +    if( !consistent ) {
    1.27 +      st->print("alias_idx==%d, adr_check==", alias_idx);
    1.28 +      if( adr_check == NULL ) {
    1.29 +        st->print("NULL");
    1.30 +      } else {
    1.31 +        adr_check->dump();
    1.32 +      }
    1.33 +      st->cr();
    1.34 +      print_alias_types();
    1.35 +      assert(consistent, "adr_check must match alias idx");
    1.36 +    }
    1.37 +  }
    1.38 +#endif
    1.39 +  // TypeInstPtr::NOTNULL+any is an OOP with unknown offset - generally
    1.40 +  // means an array I have not precisely typed yet.  Do not do any
    1.41 +  // alias stuff with it any time soon.
    1.42 +  const TypeOopPtr *tinst = tp->isa_oopptr();
    1.43 +  if( tp->base() != Type::AnyPtr &&
    1.44 +      !(tinst &&
    1.45 +        tinst->klass()->is_java_lang_Object() &&
    1.46 +        tinst->offset() == Type::OffsetBot) ) {
    1.47 +    // compress paths and change unreachable cycles to TOP
    1.48 +    // If not, we can update the input infinitely along a MergeMem cycle
    1.49 +    // Equivalent code in PhiNode::Ideal
    1.50 +    Node* m  = phase->transform(mmem);
    1.51 +    // If tranformed to a MergeMem, get the desired slice
    1.52 +    // Otherwise the returned node represents memory for every slice
    1.53 +    mem = (m->is_MergeMem())? m->as_MergeMem()->memory_at(alias_idx) : m;
    1.54 +    // Update input if it is progress over what we have now
    1.55 +  }
    1.56 +  return mem;
    1.57 +}
    1.58 +
    1.59  //--------------------------Ideal_common---------------------------------------
    1.60  // Look for degenerate control and memory inputs.  Bypass MergeMem inputs.
    1.61  // Unhook non-raw memories from complete (macro-expanded) initializations.
    1.62 @@ -119,48 +171,8 @@
    1.63    if (mem->is_MergeMem()) {
    1.64      MergeMemNode* mmem = mem->as_MergeMem();
    1.65      const TypePtr *tp = t_adr->is_ptr();
    1.66 -    uint alias_idx = phase->C->get_alias_index(tp);
    1.67 -#ifdef ASSERT
    1.68 -    {
    1.69 -      // Check that current type is consistent with the alias index used during graph construction
    1.70 -      assert(alias_idx >= Compile::AliasIdxRaw, "must not be a bad alias_idx");
    1.71 -      const TypePtr *adr_t =  adr_type();
    1.72 -      bool consistent =  adr_t == NULL || adr_t->empty() || phase->C->must_alias(adr_t, alias_idx );
    1.73 -      // Sometimes dead array references collapse to a[-1], a[-2], or a[-3]
    1.74 -      if( !consistent && adr_t != NULL && !adr_t->empty() &&
    1.75 -             tp->isa_aryptr() &&    tp->offset() == Type::OffsetBot &&
    1.76 -          adr_t->isa_aryptr() && adr_t->offset() != Type::OffsetBot &&
    1.77 -          ( adr_t->offset() == arrayOopDesc::length_offset_in_bytes() ||
    1.78 -            adr_t->offset() == oopDesc::klass_offset_in_bytes() ||
    1.79 -            adr_t->offset() == oopDesc::mark_offset_in_bytes() ) ) {
    1.80 -        // don't assert if it is dead code.
    1.81 -        consistent = true;
    1.82 -      }
    1.83 -      if( !consistent ) {
    1.84 -        tty->print("alias_idx==%d, adr_type()==", alias_idx); if( adr_t == NULL ) { tty->print("NULL"); } else { adr_t->dump(); }
    1.85 -        tty->cr();
    1.86 -        print_alias_types();
    1.87 -        assert(consistent, "adr_type must match alias idx");
    1.88 -      }
    1.89 -    }
    1.90 -#endif
    1.91 -    // TypeInstPtr::NOTNULL+any is an OOP with unknown offset - generally
    1.92 -    // means an array I have not precisely typed yet.  Do not do any
    1.93 -    // alias stuff with it any time soon.
    1.94 -    const TypeInstPtr *tinst = tp->isa_instptr();
    1.95 -    if( tp->base() != Type::AnyPtr &&
    1.96 -        !(tinst &&
    1.97 -          tinst->klass()->is_java_lang_Object() &&
    1.98 -          tinst->offset() == Type::OffsetBot) ) {
    1.99 -      // compress paths and change unreachable cycles to TOP
   1.100 -      // If not, we can update the input infinitely along a MergeMem cycle
   1.101 -      // Equivalent code in PhiNode::Ideal
   1.102 -      Node* m  = phase->transform(mmem);
   1.103 -      // If tranformed to a MergeMem, get the desired slice
   1.104 -      // Otherwise the returned node represents memory for every slice
   1.105 -      mem = (m->is_MergeMem())? m->as_MergeMem()->memory_at(alias_idx) : m;
   1.106 -      // Update input if it is progress over what we have now
   1.107 -    }
   1.108 +
   1.109 +    mem = step_through_mergemem(phase, mmem, tp, adr_type(), tty);
   1.110    }
   1.111  
   1.112    if (mem != old_mem) {
   1.113 @@ -534,7 +546,10 @@
   1.114            const Node* call = adr->in(0);
   1.115            if (call->is_CallStaticJava()) {
   1.116              const CallStaticJavaNode* call_java = call->as_CallStaticJava();
   1.117 -            assert(call_java && call_java->method() == NULL, "must be runtime call");
   1.118 +            const TypeTuple *r = call_java->tf()->range();
   1.119 +            assert(r->cnt() > TypeFunc::Parms, "must return value");
   1.120 +            const Type* ret_type = r->field_at(TypeFunc::Parms);
   1.121 +            assert(ret_type && ret_type->isa_ptr(), "must return pointer");
   1.122              // We further presume that this is one of
   1.123              // new_instance_Java, new_array_Java, or
   1.124              // the like, but do not assert for this.
   1.125 @@ -732,6 +747,21 @@
   1.126    return NULL;
   1.127  }
   1.128  
   1.129 +//----------------------is_instance_field_load_with_local_phi------------------
   1.130 +bool LoadNode::is_instance_field_load_with_local_phi(Node* ctrl) {
   1.131 +  if( in(MemNode::Memory)->is_Phi() && in(MemNode::Memory)->in(0) == ctrl &&
   1.132 +      in(MemNode::Address)->is_AddP() ) {
   1.133 +    const TypeOopPtr* t_oop = in(MemNode::Address)->bottom_type()->isa_oopptr();
   1.134 +    // Only instances.
   1.135 +    if( t_oop != NULL && t_oop->is_instance_field() &&
   1.136 +        t_oop->offset() != Type::OffsetBot &&
   1.137 +        t_oop->offset() != Type::OffsetTop) {
   1.138 +      return true;
   1.139 +    }
   1.140 +  }
   1.141 +  return false;
   1.142 +}
   1.143 +
   1.144  //------------------------------Identity---------------------------------------
   1.145  // Loads are identity if previous store is to same address
   1.146  Node *LoadNode::Identity( PhaseTransform *phase ) {
   1.147 @@ -754,6 +784,25 @@
   1.148      // usually runs first, producing the singleton type of the Con.)
   1.149      return value;
   1.150    }
   1.151 +
   1.152 +  // Search for an existing data phi which was generated before for the same
   1.153 +  // instance's field to avoid infinite genertion of phis in a loop.
   1.154 +  Node *region = mem->in(0);
   1.155 +  if (is_instance_field_load_with_local_phi(region)) {
   1.156 +    const TypePtr *addr_t = in(MemNode::Address)->bottom_type()->isa_ptr();
   1.157 +    int this_index  = phase->C->get_alias_index(addr_t);
   1.158 +    int this_offset = addr_t->offset();
   1.159 +    int this_id    = addr_t->is_oopptr()->instance_id();
   1.160 +    const Type* this_type = bottom_type();
   1.161 +    for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) {
   1.162 +      Node* phi = region->fast_out(i);
   1.163 +      if (phi->is_Phi() && phi != mem &&
   1.164 +          phi->as_Phi()->is_same_inst_field(this_type, this_id, this_index, this_offset)) {
   1.165 +        return phi;
   1.166 +      }
   1.167 +    }
   1.168 +  }
   1.169 +
   1.170    return this;
   1.171  }
   1.172  
   1.173 @@ -1189,6 +1238,17 @@
   1.174        return value->bottom_type();
   1.175    }
   1.176  
   1.177 +  const TypeOopPtr *tinst = tp->isa_oopptr();
   1.178 +  if (tinst != NULL && tinst->is_instance_field()) {
   1.179 +    // If we have an instance type and our memory input is the
   1.180 +    // programs's initial memory state, there is no matching store,
   1.181 +    // so just return a zero of the appropriate type
   1.182 +    Node *mem = in(MemNode::Memory);
   1.183 +    if (mem->is_Parm() && mem->in(0)->is_Start()) {
   1.184 +      assert(mem->as_Parm()->_con == TypeFunc::Memory, "must be memory Parm");
   1.185 +      return Type::get_zero_type(_type->basic_type());
   1.186 +    }
   1.187 +  }
   1.188    return _type;
   1.189  }
   1.190  
   1.191 @@ -1712,7 +1772,7 @@
   1.192    const TypeOopPtr *adr_oop = phase->type(adr)->isa_oopptr();
   1.193    if (adr_oop == NULL)
   1.194      return false;
   1.195 -  if (!adr_oop->is_instance())
   1.196 +  if (!adr_oop->is_instance_field())
   1.197      return false; // if not a distinct instance, there may be aliases of the address
   1.198    for (DUIterator_Fast imax, i = adr->fast_outs(imax); i < imax; i++) {
   1.199      Node *use = adr->fast_out(i);
   1.200 @@ -3244,7 +3304,7 @@
   1.201      }
   1.202    }
   1.203  
   1.204 -  assert(verify_sparse(), "please, no dups of base");
   1.205 +  assert(progress || verify_sparse(), "please, no dups of base");
   1.206    return progress;
   1.207  }
   1.208  

mercurial