Mercurial > hg > graal-compiler
comparison src/share/vm/opto/parse1.cpp @ 20327:411e30e5fbb8
8026796: Make replace_in_map() on parent maps generic
Summary: propagate node replacements along control flow edges to callers
Reviewed-by: kvn, vlivanov
author | roland |
---|---|
date | Wed, 13 Aug 2014 11:00:22 +0200 |
parents | dbb05f6d93c4 |
children | e7b3d177adda |
comparison
equal
deleted
inserted
replaced
20326:da00a41842a5 | 20327:411e30e5fbb8 |
---|---|
379 } | 379 } |
380 } | 380 } |
381 | 381 |
382 //------------------------------Parse------------------------------------------ | 382 //------------------------------Parse------------------------------------------ |
383 // Main parser constructor. | 383 // Main parser constructor. |
384 Parse::Parse(JVMState* caller, ciMethod* parse_method, float expected_uses, Parse* parent) | 384 Parse::Parse(JVMState* caller, ciMethod* parse_method, float expected_uses) |
385 : _exits(caller), _parent(parent) | 385 : _exits(caller) |
386 { | 386 { |
387 // Init some variables | 387 // Init some variables |
388 _caller = caller; | 388 _caller = caller; |
389 _method = parse_method; | 389 _method = parse_method; |
390 _expected_uses = expected_uses; | 390 _expected_uses = expected_uses; |
393 _wrote_volatile = false; | 393 _wrote_volatile = false; |
394 _alloc_with_final = NULL; | 394 _alloc_with_final = NULL; |
395 _entry_bci = InvocationEntryBci; | 395 _entry_bci = InvocationEntryBci; |
396 _tf = NULL; | 396 _tf = NULL; |
397 _block = NULL; | 397 _block = NULL; |
398 _first_return = true; | |
399 _replaced_nodes_for_exceptions = false; | |
400 _new_idx = C->unique(); | |
398 debug_only(_block_count = -1); | 401 debug_only(_block_count = -1); |
399 debug_only(_blocks = (Block*)-1); | 402 debug_only(_blocks = (Block*)-1); |
400 #ifndef PRODUCT | 403 #ifndef PRODUCT |
401 if (PrintCompilation || PrintOpto) { | 404 if (PrintCompilation || PrintOpto) { |
402 // Make sure I have an inline tree, so I can print messages about it. | 405 // Make sure I have an inline tree, so I can print messages about it. |
893 caller.set_sp(_caller->sp()); | 896 caller.set_sp(_caller->sp()); |
894 // Copy out the standard machine state: | 897 // Copy out the standard machine state: |
895 for (uint i = 0; i < TypeFunc::Parms; i++) { | 898 for (uint i = 0; i < TypeFunc::Parms; i++) { |
896 caller.map()->set_req(i, ex_map->in(i)); | 899 caller.map()->set_req(i, ex_map->in(i)); |
897 } | 900 } |
901 if (ex_map->has_replaced_nodes()) { | |
902 _replaced_nodes_for_exceptions = true; | |
903 } | |
904 caller.map()->transfer_replaced_nodes_from(ex_map, _new_idx); | |
898 // ...and the exception: | 905 // ...and the exception: |
899 Node* ex_oop = saved_ex_oop(ex_map); | 906 Node* ex_oop = saved_ex_oop(ex_map); |
900 SafePointNode* caller_ex_map = caller.make_exception_state(ex_oop); | 907 SafePointNode* caller_ex_map = caller.make_exception_state(ex_oop); |
901 // Finally, collect the new exception state in my exits: | 908 // Finally, collect the new exception state in my exits: |
902 _exits.add_exception_state(caller_ex_map); | 909 _exits.add_exception_state(caller_ex_map); |
961 // (e.g., null checks) arising from multiple points within this method. | 968 // (e.g., null checks) arising from multiple points within this method. |
962 // See GraphKit::add_exception_state, which performs the commoning. | 969 // See GraphKit::add_exception_state, which performs the commoning. |
963 bool do_synch = method()->is_synchronized() && GenerateSynchronizationCode; | 970 bool do_synch = method()->is_synchronized() && GenerateSynchronizationCode; |
964 | 971 |
965 // record exit from a method if compiled while Dtrace is turned on. | 972 // record exit from a method if compiled while Dtrace is turned on. |
966 if (do_synch || C->env()->dtrace_method_probes()) { | 973 if (do_synch || C->env()->dtrace_method_probes() || _replaced_nodes_for_exceptions) { |
967 // First move the exception list out of _exits: | 974 // First move the exception list out of _exits: |
968 GraphKit kit(_exits.transfer_exceptions_into_jvms()); | 975 GraphKit kit(_exits.transfer_exceptions_into_jvms()); |
969 SafePointNode* normal_map = kit.map(); // keep this guy safe | 976 SafePointNode* normal_map = kit.map(); // keep this guy safe |
970 // Now re-collect the exceptions into _exits: | 977 // Now re-collect the exceptions into _exits: |
971 SafePointNode* ex_map; | 978 SafePointNode* ex_map; |
986 kit.shared_unlock(_synch_lock->box_node(), _synch_lock->obj_node()); | 993 kit.shared_unlock(_synch_lock->box_node(), _synch_lock->obj_node()); |
987 } | 994 } |
988 if (C->env()->dtrace_method_probes()) { | 995 if (C->env()->dtrace_method_probes()) { |
989 kit.make_dtrace_method_exit(method()); | 996 kit.make_dtrace_method_exit(method()); |
990 } | 997 } |
998 if (_replaced_nodes_for_exceptions) { | |
999 kit.map()->apply_replaced_nodes(); | |
1000 } | |
991 // Done with exception-path processing. | 1001 // Done with exception-path processing. |
992 ex_map = kit.make_exception_state(ex_oop); | 1002 ex_map = kit.make_exception_state(ex_oop); |
993 assert(ex_jvms->same_calls_as(ex_map->jvms()), "sanity"); | 1003 assert(ex_jvms->same_calls_as(ex_map->jvms()), "sanity"); |
994 // Pop the last vestige of this method: | 1004 // Pop the last vestige of this method: |
995 ex_map->set_jvms(caller->clone_shallow(C)); | 1005 ex_map->set_jvms(caller->clone_shallow(C)); |
1005 SafePointNode* ex_map; | 1015 SafePointNode* ex_map; |
1006 while ((ex_map = caller.pop_exception_state()) != NULL) { | 1016 while ((ex_map = caller.pop_exception_state()) != NULL) { |
1007 _exits.add_exception_state(ex_map); | 1017 _exits.add_exception_state(ex_map); |
1008 } | 1018 } |
1009 } | 1019 } |
1020 _exits.map()->apply_replaced_nodes(); | |
1010 } | 1021 } |
1011 | 1022 |
1012 //-----------------------------create_entry_map------------------------------- | 1023 //-----------------------------create_entry_map------------------------------- |
1013 // Initialize our parser map to contain the types at method entry. | 1024 // Initialize our parser map to contain the types at method entry. |
1014 // For OSR, the map contains a single RawPtr parameter. | 1025 // For OSR, the map contains a single RawPtr parameter. |
1019 if (len >= 32760) { | 1030 if (len >= 32760) { |
1020 C->record_method_not_compilable_all_tiers("too many local variables"); | 1031 C->record_method_not_compilable_all_tiers("too many local variables"); |
1021 return NULL; | 1032 return NULL; |
1022 } | 1033 } |
1023 | 1034 |
1035 // clear current replaced nodes that are of no use from here on (map was cloned in build_exits). | |
1036 _caller->map()->delete_replaced_nodes(); | |
1037 | |
1024 // If this is an inlined method, we may have to do a receiver null check. | 1038 // If this is an inlined method, we may have to do a receiver null check. |
1025 if (_caller->has_method() && is_normal_parse() && !method()->is_static()) { | 1039 if (_caller->has_method() && is_normal_parse() && !method()->is_static()) { |
1026 GraphKit kit(_caller); | 1040 GraphKit kit(_caller); |
1027 kit.null_check_receiver_before_call(method()); | 1041 kit.null_check_receiver_before_call(method()); |
1028 _caller = kit.transfer_exceptions_into_jvms(); | 1042 _caller = kit.transfer_exceptions_into_jvms(); |
1042 record_for_igvn(map()); | 1056 record_for_igvn(map()); |
1043 assert(jvms->endoff() == len, "correct jvms sizing"); | 1057 assert(jvms->endoff() == len, "correct jvms sizing"); |
1044 | 1058 |
1045 SafePointNode* inmap = _caller->map(); | 1059 SafePointNode* inmap = _caller->map(); |
1046 assert(inmap != NULL, "must have inmap"); | 1060 assert(inmap != NULL, "must have inmap"); |
1061 // In case of null check on receiver above | |
1062 map()->transfer_replaced_nodes_from(inmap, _new_idx); | |
1047 | 1063 |
1048 uint i; | 1064 uint i; |
1049 | 1065 |
1050 // Pass thru the predefined input parameters. | 1066 // Pass thru the predefined input parameters. |
1051 for (i = 0; i < TypeFunc::Parms; i++) { | 1067 for (i = 0; i < TypeFunc::Parms; i++) { |
1671 !r->in(0)) { // The occasional useless Region | 1687 !r->in(0)) { // The occasional useless Region |
1672 assert(control() == r, ""); | 1688 assert(control() == r, ""); |
1673 set_control(r->nonnull_req()); | 1689 set_control(r->nonnull_req()); |
1674 } | 1690 } |
1675 | 1691 |
1692 map()->merge_replaced_nodes_with(newin); | |
1693 | |
1676 // newin has been subsumed into the lazy merge, and is now dead. | 1694 // newin has been subsumed into the lazy merge, and is now dead. |
1677 set_block(save_block); | 1695 set_block(save_block); |
1678 | 1696 |
1679 stop(); // done with this guy, for now | 1697 stop(); // done with this guy, for now |
1680 } | 1698 } |
2075 } | 2093 } |
2076 } | 2094 } |
2077 phi->add_req(value); | 2095 phi->add_req(value); |
2078 } | 2096 } |
2079 | 2097 |
2098 if (_first_return) { | |
2099 _exits.map()->transfer_replaced_nodes_from(map(), _new_idx); | |
2100 _first_return = false; | |
2101 } else { | |
2102 _exits.map()->merge_replaced_nodes_with(map()); | |
2103 } | |
2104 | |
2080 stop_and_kill_map(); // This CFG path dies here | 2105 stop_and_kill_map(); // This CFG path dies here |
2081 } | 2106 } |
2082 | 2107 |
2083 | 2108 |
2084 //------------------------------add_safepoint---------------------------------- | 2109 //------------------------------add_safepoint---------------------------------- |