comparison src/share/vm/opto/graphKit.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 922c87c9aed4
children e7b3d177adda
comparison
equal deleted inserted replaced
20326:da00a41842a5 20327:411e30e5fbb8
426 _gvn.set_type(phi, dsttype); 426 _gvn.set_type(phi, dsttype);
427 } 427 }
428 } 428 }
429 } 429 }
430 } 430 }
431 phi_map->merge_replaced_nodes_with(ex_map);
431 } 432 }
432 433
433 //--------------------------use_exception_state-------------------------------- 434 //--------------------------use_exception_state--------------------------------
434 Node* GraphKit::use_exception_state(SafePointNode* phi_map) { 435 Node* GraphKit::use_exception_state(SafePointNode* phi_map) {
435 if (failing()) { stop(); return top(); } 436 if (failing()) { stop(); return top(); }
639 debug_only(kit->verify_map()); 640 debug_only(kit->verify_map());
640 _kit = kit; 641 _kit = kit;
641 _map = kit->map(); // preserve the map 642 _map = kit->map(); // preserve the map
642 _sp = kit->sp(); 643 _sp = kit->sp();
643 kit->set_map(clone_map ? kit->clone_map() : NULL); 644 kit->set_map(clone_map ? kit->clone_map() : NULL);
644 Compile::current()->inc_preserve_jvm_state();
645 #ifdef ASSERT 645 #ifdef ASSERT
646 _bci = kit->bci(); 646 _bci = kit->bci();
647 Parse* parser = kit->is_Parse(); 647 Parse* parser = kit->is_Parse();
648 int block = (parser == NULL || parser->block() == NULL) ? -1 : parser->block()->rpo(); 648 int block = (parser == NULL || parser->block() == NULL) ? -1 : parser->block()->rpo();
649 _block = block; 649 _block = block;
657 int block = (parser == NULL || parser->block() == NULL) ? -1 : parser->block()->rpo(); 657 int block = (parser == NULL || parser->block() == NULL) ? -1 : parser->block()->rpo();
658 assert(block == _block, "block must not shift"); 658 assert(block == _block, "block must not shift");
659 #endif 659 #endif
660 kit->set_map(_map); 660 kit->set_map(_map);
661 kit->set_sp(_sp); 661 kit->set_sp(_sp);
662 Compile::current()->dec_preserve_jvm_state();
663 } 662 }
664 663
665 664
666 //-----------------------------BuildCutout------------------------------------- 665 //-----------------------------BuildCutout-------------------------------------
667 BuildCutout::BuildCutout(GraphKit* kit, Node* p, float prob, float cnt) 666 BuildCutout::BuildCutout(GraphKit* kit, Node* p, float prob, float cnt)
1396 1395
1397 // Note: This operation potentially replaces any edge 1396 // Note: This operation potentially replaces any edge
1398 // on the map. This includes locals, stack, and monitors 1397 // on the map. This includes locals, stack, and monitors
1399 // of the current (innermost) JVM state. 1398 // of the current (innermost) JVM state.
1400 1399
1401 if (!ReplaceInParentMaps) { 1400 // don't let inconsistent types from profiling escape this
1401 // method
1402
1403 const Type* told = _gvn.type(old);
1404 const Type* tnew = _gvn.type(neww);
1405
1406 if (!tnew->higher_equal(told)) {
1402 return; 1407 return;
1403 } 1408 }
1404 1409
1405 // PreserveJVMState doesn't do a deep copy so we can't modify 1410 map()->record_replaced_node(old, neww);
1406 // parents
1407 if (Compile::current()->has_preserve_jvm_state()) {
1408 return;
1409 }
1410
1411 Parse* parser = is_Parse();
1412 bool progress = true;
1413 Node* ctrl = map()->in(0);
1414 // Follow the chain of parsers and see whether the update can be
1415 // done in the map of callers. We can do the replace for a caller if
1416 // the current control post dominates the control of a caller.
1417 while (parser != NULL && parser->caller() != NULL && progress) {
1418 progress = false;
1419 Node* parent_map = parser->caller()->map();
1420 assert(parser->exits().map()->jvms()->depth() == parser->caller()->depth(), "map mismatch");
1421
1422 Node* parent_ctrl = parent_map->in(0);
1423
1424 while (parent_ctrl->is_Region()) {
1425 Node* n = parent_ctrl->as_Region()->is_copy();
1426 if (n == NULL) {
1427 break;
1428 }
1429 parent_ctrl = n;
1430 }
1431
1432 for (;;) {
1433 if (ctrl == parent_ctrl) {
1434 // update the map of the exits which is the one that will be
1435 // used when compilation resume after inlining
1436 parser->exits().map()->replace_edge(old, neww);
1437 progress = true;
1438 break;
1439 }
1440 if (ctrl->is_Proj() && ctrl->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none)) {
1441 ctrl = ctrl->in(0)->in(0);
1442 } else if (ctrl->is_Region()) {
1443 Node* n = ctrl->as_Region()->is_copy();
1444 if (n == NULL) {
1445 break;
1446 }
1447 ctrl = n;
1448 } else {
1449 break;
1450 }
1451 }
1452
1453 parser = parser->parent_parser();
1454 }
1455 } 1411 }
1456 1412
1457 1413
1458 //============================================================================= 1414 //=============================================================================
1459 //--------------------------------memory--------------------------------------- 1415 //--------------------------------memory---------------------------------------
1853 } 1809 }
1854 } 1810 }
1855 1811
1856 1812
1857 // Replace the call with the current state of the kit. 1813 // Replace the call with the current state of the kit.
1858 void GraphKit::replace_call(CallNode* call, Node* result) { 1814 void GraphKit::replace_call(CallNode* call, Node* result, bool do_replaced_nodes) {
1859 JVMState* ejvms = NULL; 1815 JVMState* ejvms = NULL;
1860 if (has_exceptions()) { 1816 if (has_exceptions()) {
1861 ejvms = transfer_exceptions_into_jvms(); 1817 ejvms = transfer_exceptions_into_jvms();
1862 } 1818 }
1819
1820 ReplacedNodes replaced_nodes = map()->replaced_nodes();
1821 ReplacedNodes replaced_nodes_exception;
1822 Node* ex_ctl = top();
1863 1823
1864 SafePointNode* final_state = stop(); 1824 SafePointNode* final_state = stop();
1865 1825
1866 // Find all the needed outputs of this call 1826 // Find all the needed outputs of this call
1867 CallProjections callprojs; 1827 CallProjections callprojs;
1875 // Replace all the old call edges with the edges from the inlining result 1835 // Replace all the old call edges with the edges from the inlining result
1876 if (callprojs.fallthrough_catchproj != NULL) { 1836 if (callprojs.fallthrough_catchproj != NULL) {
1877 C->gvn_replace_by(callprojs.fallthrough_catchproj, final_ctl); 1837 C->gvn_replace_by(callprojs.fallthrough_catchproj, final_ctl);
1878 } 1838 }
1879 if (callprojs.fallthrough_memproj != NULL) { 1839 if (callprojs.fallthrough_memproj != NULL) {
1840 if (final_mem->is_MergeMem()) {
1841 // Parser's exits MergeMem was not transformed but may be optimized
1842 final_mem = _gvn.transform(final_mem);
1843 }
1880 C->gvn_replace_by(callprojs.fallthrough_memproj, final_mem); 1844 C->gvn_replace_by(callprojs.fallthrough_memproj, final_mem);
1881 } 1845 }
1882 if (callprojs.fallthrough_ioproj != NULL) { 1846 if (callprojs.fallthrough_ioproj != NULL) {
1883 C->gvn_replace_by(callprojs.fallthrough_ioproj, final_io); 1847 C->gvn_replace_by(callprojs.fallthrough_ioproj, final_io);
1884 } 1848 }
1906 } else { 1870 } else {
1907 GraphKit ekit(ejvms); 1871 GraphKit ekit(ejvms);
1908 1872
1909 // Load my combined exception state into the kit, with all phis transformed: 1873 // Load my combined exception state into the kit, with all phis transformed:
1910 SafePointNode* ex_map = ekit.combine_and_pop_all_exception_states(); 1874 SafePointNode* ex_map = ekit.combine_and_pop_all_exception_states();
1875 replaced_nodes_exception = ex_map->replaced_nodes();
1911 1876
1912 Node* ex_oop = ekit.use_exception_state(ex_map); 1877 Node* ex_oop = ekit.use_exception_state(ex_map);
1878
1913 if (callprojs.catchall_catchproj != NULL) { 1879 if (callprojs.catchall_catchproj != NULL) {
1914 C->gvn_replace_by(callprojs.catchall_catchproj, ekit.control()); 1880 C->gvn_replace_by(callprojs.catchall_catchproj, ekit.control());
1881 ex_ctl = ekit.control();
1915 } 1882 }
1916 if (callprojs.catchall_memproj != NULL) { 1883 if (callprojs.catchall_memproj != NULL) {
1917 C->gvn_replace_by(callprojs.catchall_memproj, ekit.reset_memory()); 1884 C->gvn_replace_by(callprojs.catchall_memproj, ekit.reset_memory());
1918 } 1885 }
1919 if (callprojs.catchall_ioproj != NULL) { 1886 if (callprojs.catchall_ioproj != NULL) {
1941 } 1908 }
1942 } 1909 }
1943 while (wl.size() > 0) { 1910 while (wl.size() > 0) {
1944 _gvn.transform(wl.pop()); 1911 _gvn.transform(wl.pop());
1945 } 1912 }
1913 }
1914
1915 if (callprojs.fallthrough_catchproj != NULL && !final_ctl->is_top() && do_replaced_nodes) {
1916 replaced_nodes.apply(C, final_ctl);
1917 }
1918 if (!ex_ctl->is_top() && do_replaced_nodes) {
1919 replaced_nodes_exception.apply(C, ex_ctl);
1946 } 1920 }
1947 } 1921 }
1948 1922
1949 1923
1950 //------------------------------increment_counter------------------------------ 1924 //------------------------------increment_counter------------------------------