Mercurial > hg > truffle
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------------------------------ |