Mercurial > hg > graal-compiler
comparison src/share/vm/opto/matcher.cpp @ 14440:41b780b43b74
8029015: PPC64 (part 216): opto: trap based null and range checks
Summary: On PPC64 use tdi instruction that does a compare and raises SIGTRAP for NULL and range checks.
Reviewed-by: kvn
author | goetz |
---|---|
date | Wed, 27 Nov 2013 16:16:21 -0800 |
parents | 50fdb38839eb |
children | ad6695638a35 |
comparison
equal
deleted
inserted
replaced
14439:50fdb38839eb | 14440:41b780b43b74 |
---|---|
2393 } | 2393 } |
2394 } | 2394 } |
2395 return false; | 2395 return false; |
2396 } | 2396 } |
2397 | 2397 |
2398 // Check whether node n is a branch to an uncommon trap that we could | |
2399 // optimize as test with very high branch costs in case of going to | |
2400 // the uncommon trap. The code must be able to be recompiled to use | |
2401 // a cheaper test. | |
2402 bool Matcher::branches_to_uncommon_trap(const Node *n) { | |
2403 // Don't do it for natives, adapters, or runtime stubs | |
2404 Compile *C = Compile::current(); | |
2405 if (!C->is_method_compilation()) return false; | |
2406 | |
2407 assert(n->is_If(), "You should only call this on if nodes."); | |
2408 IfNode *ifn = n->as_If(); | |
2409 | |
2410 Node *ifFalse = NULL; | |
2411 for (DUIterator_Fast imax, i = ifn->fast_outs(imax); i < imax; i++) { | |
2412 if (ifn->fast_out(i)->is_IfFalse()) { | |
2413 ifFalse = ifn->fast_out(i); | |
2414 break; | |
2415 } | |
2416 } | |
2417 assert(ifFalse, "An If should have an ifFalse. Graph is broken."); | |
2418 | |
2419 Node *reg = ifFalse; | |
2420 int cnt = 4; // We must protect against cycles. Limit to 4 iterations. | |
2421 // Alternatively use visited set? Seems too expensive. | |
2422 while (reg != NULL && cnt > 0) { | |
2423 CallNode *call = NULL; | |
2424 RegionNode *nxt_reg = NULL; | |
2425 for (DUIterator_Fast imax, i = reg->fast_outs(imax); i < imax; i++) { | |
2426 Node *o = reg->fast_out(i); | |
2427 if (o->is_Call()) { | |
2428 call = o->as_Call(); | |
2429 } | |
2430 if (o->is_Region()) { | |
2431 nxt_reg = o->as_Region(); | |
2432 } | |
2433 } | |
2434 | |
2435 if (call && | |
2436 call->entry_point() == SharedRuntime::uncommon_trap_blob()->entry_point()) { | |
2437 const Type* trtype = call->in(TypeFunc::Parms)->bottom_type(); | |
2438 if (trtype->isa_int() && trtype->is_int()->is_con()) { | |
2439 jint tr_con = trtype->is_int()->get_con(); | |
2440 Deoptimization::DeoptReason reason = Deoptimization::trap_request_reason(tr_con); | |
2441 Deoptimization::DeoptAction action = Deoptimization::trap_request_action(tr_con); | |
2442 assert((int)reason < (int)BitsPerInt, "recode bit map"); | |
2443 | |
2444 if (is_set_nth_bit(C->allowed_deopt_reasons(), (int)reason) | |
2445 && action != Deoptimization::Action_none) { | |
2446 // This uncommon trap is sure to recompile, eventually. | |
2447 // When that happens, C->too_many_traps will prevent | |
2448 // this transformation from happening again. | |
2449 return true; | |
2450 } | |
2451 } | |
2452 } | |
2453 | |
2454 reg = nxt_reg; | |
2455 cnt--; | |
2456 } | |
2457 | |
2458 return false; | |
2459 } | |
2460 | |
2398 //============================================================================= | 2461 //============================================================================= |
2399 //---------------------------State--------------------------------------------- | 2462 //---------------------------State--------------------------------------------- |
2400 State::State(void) { | 2463 State::State(void) { |
2401 #ifdef ASSERT | 2464 #ifdef ASSERT |
2402 _id = 0; | 2465 _id = 0; |