1.1 --- a/src/share/vm/opto/callGenerator.cpp Tue Aug 05 15:02:10 2014 -0700 1.2 +++ b/src/share/vm/opto/callGenerator.cpp Tue Jun 10 12:28:06 2014 -0700 1.3 @@ -710,7 +710,15 @@ 1.4 Node* iophi = PhiNode::make(region, kit.i_o(), Type::ABIO); 1.5 iophi->set_req(2, slow_map->i_o()); 1.6 kit.set_i_o(gvn.transform(iophi)); 1.7 + // Merge memory 1.8 kit.merge_memory(slow_map->merged_memory(), region, 2); 1.9 + // Transform new memory Phis. 1.10 + for (MergeMemStream mms(kit.merged_memory()); mms.next_non_empty();) { 1.11 + Node* phi = mms.memory(); 1.12 + if (phi->is_Phi() && phi->in(0) == region) { 1.13 + mms.set_memory(gvn.transform(phi)); 1.14 + } 1.15 + } 1.16 uint tos = kit.jvms()->stkoff() + kit.sp(); 1.17 uint limit = slow_map->req(); 1.18 for (uint i = TypeFunc::Parms; i < limit; i++) { 1.19 @@ -864,15 +872,15 @@ 1.20 } 1.21 1.22 1.23 -//------------------------PredictedIntrinsicGenerator------------------------------ 1.24 -// Internal class which handles all predicted Intrinsic calls. 1.25 -class PredictedIntrinsicGenerator : public CallGenerator { 1.26 +//------------------------PredicatedIntrinsicGenerator------------------------------ 1.27 +// Internal class which handles all predicated Intrinsic calls. 1.28 +class PredicatedIntrinsicGenerator : public CallGenerator { 1.29 CallGenerator* _intrinsic; 1.30 CallGenerator* _cg; 1.31 1.32 public: 1.33 - PredictedIntrinsicGenerator(CallGenerator* intrinsic, 1.34 - CallGenerator* cg) 1.35 + PredicatedIntrinsicGenerator(CallGenerator* intrinsic, 1.36 + CallGenerator* cg) 1.37 : CallGenerator(cg->method()) 1.38 { 1.39 _intrinsic = intrinsic; 1.40 @@ -887,103 +895,182 @@ 1.41 }; 1.42 1.43 1.44 -CallGenerator* CallGenerator::for_predicted_intrinsic(CallGenerator* intrinsic, 1.45 - CallGenerator* cg) { 1.46 - return new PredictedIntrinsicGenerator(intrinsic, cg); 1.47 +CallGenerator* CallGenerator::for_predicated_intrinsic(CallGenerator* intrinsic, 1.48 + CallGenerator* cg) { 1.49 + return new PredicatedIntrinsicGenerator(intrinsic, cg); 1.50 } 1.51 1.52 1.53 -JVMState* PredictedIntrinsicGenerator::generate(JVMState* jvms, Parse* parent_parser) { 1.54 +JVMState* PredicatedIntrinsicGenerator::generate(JVMState* jvms, Parse* parent_parser) { 1.55 + // The code we want to generate here is: 1.56 + // if (receiver == NULL) 1.57 + // uncommon_Trap 1.58 + // if (predicate(0)) 1.59 + // do_intrinsic(0) 1.60 + // else 1.61 + // if (predicate(1)) 1.62 + // do_intrinsic(1) 1.63 + // ... 1.64 + // else 1.65 + // do_java_comp 1.66 + 1.67 GraphKit kit(jvms); 1.68 PhaseGVN& gvn = kit.gvn(); 1.69 1.70 CompileLog* log = kit.C->log(); 1.71 if (log != NULL) { 1.72 - log->elem("predicted_intrinsic bci='%d' method='%d'", 1.73 + log->elem("predicated_intrinsic bci='%d' method='%d'", 1.74 jvms->bci(), log->identify(method())); 1.75 } 1.76 1.77 - Node* slow_ctl = _intrinsic->generate_predicate(kit.sync_jvms()); 1.78 - if (kit.failing()) 1.79 - return NULL; // might happen because of NodeCountInliningCutoff 1.80 - 1.81 - SafePointNode* slow_map = NULL; 1.82 - JVMState* slow_jvms; 1.83 - if (slow_ctl != NULL) { 1.84 - PreserveJVMState pjvms(&kit); 1.85 - kit.set_control(slow_ctl); 1.86 - if (!kit.stopped()) { 1.87 - slow_jvms = _cg->generate(kit.sync_jvms(), parent_parser); 1.88 - if (kit.failing()) 1.89 - return NULL; // might happen because of NodeCountInliningCutoff 1.90 - assert(slow_jvms != NULL, "must be"); 1.91 - kit.add_exception_states_from(slow_jvms); 1.92 - kit.set_map(slow_jvms->map()); 1.93 - if (!kit.stopped()) 1.94 - slow_map = kit.stop(); 1.95 + if (!method()->is_static()) { 1.96 + // We need an explicit receiver null_check before checking its type in predicate. 1.97 + // We share a map with the caller, so his JVMS gets adjusted. 1.98 + Node* receiver = kit.null_check_receiver_before_call(method()); 1.99 + if (kit.stopped()) { 1.100 + return kit.transfer_exceptions_into_jvms(); 1.101 } 1.102 } 1.103 1.104 - if (kit.stopped()) { 1.105 - // Predicate is always false. 1.106 - kit.set_jvms(slow_jvms); 1.107 + int n_predicates = _intrinsic->predicates_count(); 1.108 + assert(n_predicates > 0, "sanity"); 1.109 + 1.110 + JVMState** result_jvms = NEW_RESOURCE_ARRAY(JVMState*, (n_predicates+1)); 1.111 + 1.112 + // Region for normal compilation code if intrinsic failed. 1.113 + Node* slow_region = new (kit.C) RegionNode(1); 1.114 + 1.115 + int results = 0; 1.116 + for (int predicate = 0; (predicate < n_predicates) && !kit.stopped(); predicate++) { 1.117 +#ifdef ASSERT 1.118 + JVMState* old_jvms = kit.jvms(); 1.119 + SafePointNode* old_map = kit.map(); 1.120 + Node* old_io = old_map->i_o(); 1.121 + Node* old_mem = old_map->memory(); 1.122 + Node* old_exc = old_map->next_exception(); 1.123 +#endif 1.124 + Node* else_ctrl = _intrinsic->generate_predicate(kit.sync_jvms(), predicate); 1.125 +#ifdef ASSERT 1.126 + // Assert(no_new_memory && no_new_io && no_new_exceptions) after generate_predicate. 1.127 + assert(old_jvms == kit.jvms(), "generate_predicate should not change jvm state"); 1.128 + SafePointNode* new_map = kit.map(); 1.129 + assert(old_io == new_map->i_o(), "generate_predicate should not change i_o"); 1.130 + assert(old_mem == new_map->memory(), "generate_predicate should not change memory"); 1.131 + assert(old_exc == new_map->next_exception(), "generate_predicate should not add exceptions"); 1.132 +#endif 1.133 + if (!kit.stopped()) { 1.134 + PreserveJVMState pjvms(&kit); 1.135 + // Generate intrinsic code: 1.136 + JVMState* new_jvms = _intrinsic->generate(kit.sync_jvms(), parent_parser); 1.137 + if (new_jvms == NULL) { 1.138 + // Intrinsic failed, use normal compilation path for this predicate. 1.139 + slow_region->add_req(kit.control()); 1.140 + } else { 1.141 + kit.add_exception_states_from(new_jvms); 1.142 + kit.set_jvms(new_jvms); 1.143 + if (!kit.stopped()) { 1.144 + result_jvms[results++] = kit.jvms(); 1.145 + } 1.146 + } 1.147 + } 1.148 + if (else_ctrl == NULL) { 1.149 + else_ctrl = kit.C->top(); 1.150 + } 1.151 + kit.set_control(else_ctrl); 1.152 + } 1.153 + if (!kit.stopped()) { 1.154 + // Final 'else' after predicates. 1.155 + slow_region->add_req(kit.control()); 1.156 + } 1.157 + if (slow_region->req() > 1) { 1.158 + PreserveJVMState pjvms(&kit); 1.159 + // Generate normal compilation code: 1.160 + kit.set_control(gvn.transform(slow_region)); 1.161 + JVMState* new_jvms = _cg->generate(kit.sync_jvms(), parent_parser); 1.162 + if (kit.failing()) 1.163 + return NULL; // might happen because of NodeCountInliningCutoff 1.164 + assert(new_jvms != NULL, "must be"); 1.165 + kit.add_exception_states_from(new_jvms); 1.166 + kit.set_jvms(new_jvms); 1.167 + if (!kit.stopped()) { 1.168 + result_jvms[results++] = kit.jvms(); 1.169 + } 1.170 + } 1.171 + 1.172 + if (results == 0) { 1.173 + // All paths ended in uncommon traps. 1.174 + (void) kit.stop(); 1.175 return kit.transfer_exceptions_into_jvms(); 1.176 } 1.177 1.178 - // Generate intrinsic code: 1.179 - JVMState* new_jvms = _intrinsic->generate(kit.sync_jvms(), parent_parser); 1.180 - if (new_jvms == NULL) { 1.181 - // Intrinsic failed, so use slow code or make a direct call. 1.182 - if (slow_map == NULL) { 1.183 - CallGenerator* cg = CallGenerator::for_direct_call(method()); 1.184 - new_jvms = cg->generate(kit.sync_jvms(), parent_parser); 1.185 - } else { 1.186 - kit.set_jvms(slow_jvms); 1.187 - return kit.transfer_exceptions_into_jvms(); 1.188 - } 1.189 - } 1.190 - kit.add_exception_states_from(new_jvms); 1.191 - kit.set_jvms(new_jvms); 1.192 - 1.193 - // Need to merge slow and fast? 1.194 - if (slow_map == NULL) { 1.195 - // The fast path is the only path remaining. 1.196 + if (results == 1) { // Only one path 1.197 + kit.set_jvms(result_jvms[0]); 1.198 return kit.transfer_exceptions_into_jvms(); 1.199 } 1.200 1.201 - if (kit.stopped()) { 1.202 - // Intrinsic method threw an exception, so it's just the slow path after all. 1.203 - kit.set_jvms(slow_jvms); 1.204 - return kit.transfer_exceptions_into_jvms(); 1.205 + // Merge all paths. 1.206 + kit.C->set_has_split_ifs(true); // Has chance for split-if optimization 1.207 + RegionNode* region = new (kit.C) RegionNode(results + 1); 1.208 + Node* iophi = PhiNode::make(region, kit.i_o(), Type::ABIO); 1.209 + for (int i = 0; i < results; i++) { 1.210 + JVMState* jvms = result_jvms[i]; 1.211 + int path = i + 1; 1.212 + SafePointNode* map = jvms->map(); 1.213 + region->init_req(path, map->control()); 1.214 + iophi->set_req(path, map->i_o()); 1.215 + if (i == 0) { 1.216 + kit.set_jvms(jvms); 1.217 + } else { 1.218 + kit.merge_memory(map->merged_memory(), region, path); 1.219 + } 1.220 + } 1.221 + kit.set_control(gvn.transform(region)); 1.222 + kit.set_i_o(gvn.transform(iophi)); 1.223 + // Transform new memory Phis. 1.224 + for (MergeMemStream mms(kit.merged_memory()); mms.next_non_empty();) { 1.225 + Node* phi = mms.memory(); 1.226 + if (phi->is_Phi() && phi->in(0) == region) { 1.227 + mms.set_memory(gvn.transform(phi)); 1.228 + } 1.229 } 1.230 1.231 - // Finish the diamond. 1.232 - kit.C->set_has_split_ifs(true); // Has chance for split-if optimization 1.233 - RegionNode* region = new (kit.C) RegionNode(3); 1.234 - region->init_req(1, kit.control()); 1.235 - region->init_req(2, slow_map->control()); 1.236 - kit.set_control(gvn.transform(region)); 1.237 - Node* iophi = PhiNode::make(region, kit.i_o(), Type::ABIO); 1.238 - iophi->set_req(2, slow_map->i_o()); 1.239 - kit.set_i_o(gvn.transform(iophi)); 1.240 - kit.merge_memory(slow_map->merged_memory(), region, 2); 1.241 + // Merge debug info. 1.242 + Node** ins = NEW_RESOURCE_ARRAY(Node*, results); 1.243 uint tos = kit.jvms()->stkoff() + kit.sp(); 1.244 - uint limit = slow_map->req(); 1.245 + Node* map = kit.map(); 1.246 + uint limit = map->req(); 1.247 for (uint i = TypeFunc::Parms; i < limit; i++) { 1.248 // Skip unused stack slots; fast forward to monoff(); 1.249 if (i == tos) { 1.250 i = kit.jvms()->monoff(); 1.251 if( i >= limit ) break; 1.252 } 1.253 - Node* m = kit.map()->in(i); 1.254 - Node* n = slow_map->in(i); 1.255 - if (m != n) { 1.256 - const Type* t = gvn.type(m)->meet_speculative(gvn.type(n)); 1.257 - Node* phi = PhiNode::make(region, m, t); 1.258 - phi->set_req(2, n); 1.259 - kit.map()->set_req(i, gvn.transform(phi)); 1.260 + Node* n = map->in(i); 1.261 + ins[0] = n; 1.262 + const Type* t = gvn.type(n); 1.263 + bool needs_phi = false; 1.264 + for (int j = 1; j < results; j++) { 1.265 + JVMState* jvms = result_jvms[j]; 1.266 + Node* jmap = jvms->map(); 1.267 + Node* m = NULL; 1.268 + if (jmap->req() > i) { 1.269 + m = jmap->in(i); 1.270 + if (m != n) { 1.271 + needs_phi = true; 1.272 + t = t->meet_speculative(gvn.type(m)); 1.273 + } 1.274 + } 1.275 + ins[j] = m; 1.276 + } 1.277 + if (needs_phi) { 1.278 + Node* phi = PhiNode::make(region, n, t); 1.279 + for (int j = 1; j < results; j++) { 1.280 + phi->set_req(j + 1, ins[j]); 1.281 + } 1.282 + map->set_req(i, gvn.transform(phi)); 1.283 } 1.284 } 1.285 + 1.286 return kit.transfer_exceptions_into_jvms(); 1.287 } 1.288