src/share/vm/opto/lcm.cpp

changeset 3316
f03a3c8bd5e5
parent 3040
c7b60b601eb4
child 3447
cf407b7d3d78
     1.1 --- a/src/share/vm/opto/lcm.cpp	Mon Nov 21 00:57:43 2011 -0800
     1.2 +++ b/src/share/vm/opto/lcm.cpp	Wed Sep 14 09:22:51 2011 +0200
     1.3 @@ -548,6 +548,22 @@
     1.4    set_next_call(call, next_call, bbs);
     1.5  }
     1.6  
     1.7 +//------------------------------add_call_kills-------------------------------------
     1.8 +void Block::add_call_kills(MachProjNode *proj, RegMask& regs, const char* save_policy, bool exclude_soe) {
     1.9 +  // Fill in the kill mask for the call
    1.10 +  for( OptoReg::Name r = OptoReg::Name(0); r < _last_Mach_Reg; r=OptoReg::add(r,1) ) {
    1.11 +    if( !regs.Member(r) ) {     // Not already defined by the call
    1.12 +      // Save-on-call register?
    1.13 +      if ((save_policy[r] == 'C') ||
    1.14 +          (save_policy[r] == 'A') ||
    1.15 +          ((save_policy[r] == 'E') && exclude_soe)) {
    1.16 +        proj->_rout.Insert(r);
    1.17 +      }
    1.18 +    }
    1.19 +  }
    1.20 +}
    1.21 +
    1.22 +
    1.23  //------------------------------sched_call-------------------------------------
    1.24  uint Block::sched_call( Matcher &matcher, Block_Array &bbs, uint node_cnt, Node_List &worklist, int *ready_cnt, MachCallNode *mcall, VectorSet &next_call ) {
    1.25    RegMask regs;
    1.26 @@ -631,17 +647,7 @@
    1.27        proj->_rout.OR(Matcher::method_handle_invoke_SP_save_mask());
    1.28    }
    1.29  
    1.30 -  // Fill in the kill mask for the call
    1.31 -  for( OptoReg::Name r = OptoReg::Name(0); r < _last_Mach_Reg; r=OptoReg::add(r,1) ) {
    1.32 -    if( !regs.Member(r) ) {     // Not already defined by the call
    1.33 -      // Save-on-call register?
    1.34 -      if ((save_policy[r] == 'C') ||
    1.35 -          (save_policy[r] == 'A') ||
    1.36 -          ((save_policy[r] == 'E') && exclude_soe)) {
    1.37 -        proj->_rout.Insert(r);
    1.38 -      }
    1.39 -    }
    1.40 -  }
    1.41 +  add_call_kills(proj, regs, save_policy, exclude_soe);
    1.42  
    1.43    return node_cnt;
    1.44  }
    1.45 @@ -776,6 +782,7 @@
    1.46      }
    1.47  #endif
    1.48  
    1.49 +  uint max_idx = matcher.C->unique();
    1.50    // Pull from worklist and schedule
    1.51    while( worklist.size() ) {    // Worklist is not ready
    1.52  
    1.53 @@ -815,11 +822,28 @@
    1.54        phi_cnt = sched_call(matcher, cfg->_bbs, phi_cnt, worklist, ready_cnt, mcall, next_call);
    1.55        continue;
    1.56      }
    1.57 +
    1.58 +    if (n->is_Mach() && n->as_Mach()->has_call()) {
    1.59 +      RegMask regs;
    1.60 +      regs.Insert(matcher.c_frame_pointer());
    1.61 +      regs.OR(n->out_RegMask());
    1.62 +
    1.63 +      MachProjNode *proj = new (matcher.C, 1) MachProjNode( n, 1, RegMask::Empty, MachProjNode::fat_proj );
    1.64 +      cfg->_bbs.map(proj->_idx,this);
    1.65 +      _nodes.insert(phi_cnt++, proj);
    1.66 +
    1.67 +      add_call_kills(proj, regs, matcher._c_reg_save_policy, false);
    1.68 +    }
    1.69 +
    1.70      // Children are now all ready
    1.71      for (DUIterator_Fast i5max, i5 = n->fast_outs(i5max); i5 < i5max; i5++) {
    1.72        Node* m = n->fast_out(i5); // Get user
    1.73        if( cfg->_bbs[m->_idx] != this ) continue;
    1.74        if( m->is_Phi() ) continue;
    1.75 +      if (m->_idx > max_idx) { // new node, skip it
    1.76 +        assert(m->is_MachProj() && n->is_Mach() && n->as_Mach()->has_call(), "unexpected node types");
    1.77 +        continue;
    1.78 +      }
    1.79        if( !--ready_cnt[m->_idx] )
    1.80          worklist.push(m);
    1.81      }

mercurial