Mercurial > hg > truffle
comparison src/share/vm/opto/compile.cpp @ 8048:8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
Summary: Add support for expensive nodes.
Reviewed-by: kvn
author | roland |
---|---|
date | Tue, 12 Feb 2013 12:56:11 +0100 |
parents | 5b8548391bf3 |
children | 571076d3c79d |
comparison
equal
deleted
inserted
replaced
8047:1e5e28bac299 | 8048:8b3da8d14c93 |
---|---|
407 Node* n = C->macro_node(i); | 407 Node* n = C->macro_node(i); |
408 if (!useful.member(n)) { | 408 if (!useful.member(n)) { |
409 remove_macro_node(n); | 409 remove_macro_node(n); |
410 } | 410 } |
411 } | 411 } |
412 // Remove useless expensive node | |
413 for (int i = C->expensive_count()-1; i >= 0; i--) { | |
414 Node* n = C->expensive_node(i); | |
415 if (!useful.member(n)) { | |
416 remove_expensive_node(n); | |
417 } | |
418 } | |
412 // clean up the late inline lists | 419 // clean up the late inline lists |
413 remove_useless_late_inlines(&_string_late_inlines, useful); | 420 remove_useless_late_inlines(&_string_late_inlines, useful); |
414 remove_useless_late_inlines(&_late_inlines, useful); | 421 remove_useless_late_inlines(&_late_inlines, useful); |
415 debug_only(verify_graph_edges(true/*check for no_dead_code*/);) | 422 debug_only(verify_graph_edges(true/*check for no_dead_code*/);) |
416 } | 423 } |
1059 probe_alias_cache(NULL)->_index = AliasIdxTop; | 1066 probe_alias_cache(NULL)->_index = AliasIdxTop; |
1060 | 1067 |
1061 _intrinsics = NULL; | 1068 _intrinsics = NULL; |
1062 _macro_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); | 1069 _macro_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); |
1063 _predicate_opaqs = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); | 1070 _predicate_opaqs = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); |
1071 _expensive_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); | |
1064 register_library_intrinsics(); | 1072 register_library_intrinsics(); |
1065 } | 1073 } |
1066 | 1074 |
1067 //---------------------------init_start---------------------------------------- | 1075 //---------------------------init_start---------------------------------------- |
1068 // Install the StartNode on this compile object. | 1076 // Install the StartNode on this compile object. |
1924 inline_incrementally(igvn); | 1932 inline_incrementally(igvn); |
1925 | 1933 |
1926 print_method("Incremental Inline", 2); | 1934 print_method("Incremental Inline", 2); |
1927 | 1935 |
1928 if (failing()) return; | 1936 if (failing()) return; |
1937 | |
1938 // No more new expensive nodes will be added to the list from here | |
1939 // so keep only the actual candidates for optimizations. | |
1940 cleanup_expensive_nodes(igvn); | |
1929 | 1941 |
1930 // Perform escape analysis | 1942 // Perform escape analysis |
1931 if (_do_escape_analysis && ConnectionGraph::has_candidates(this)) { | 1943 if (_do_escape_analysis && ConnectionGraph::has_candidates(this)) { |
1932 if (has_loops()) { | 1944 if (has_loops()) { |
1933 // Cleanup graph (remove dead nodes). | 1945 // Cleanup graph (remove dead nodes). |
3008 if (root()->req() == 1) { | 3020 if (root()->req() == 1) { |
3009 record_method_not_compilable("trivial infinite loop"); | 3021 record_method_not_compilable("trivial infinite loop"); |
3010 return true; | 3022 return true; |
3011 } | 3023 } |
3012 | 3024 |
3025 // Expensive nodes have their control input set to prevent the GVN | |
3026 // from freely commoning them. There's no GVN beyond this point so | |
3027 // no need to keep the control input. We want the expensive nodes to | |
3028 // be freely moved to the least frequent code path by gcm. | |
3029 assert(OptimizeExpensiveOps || expensive_count() == 0, "optimization off but list non empty?"); | |
3030 for (int i = 0; i < expensive_count(); i++) { | |
3031 _expensive_nodes->at(i)->set_req(0, NULL); | |
3032 } | |
3033 | |
3013 Final_Reshape_Counts frc; | 3034 Final_Reshape_Counts frc; |
3014 | 3035 |
3015 // Visit everybody reachable! | 3036 // Visit everybody reachable! |
3016 // Allocate stack of size C->unique()/2 to avoid frequent realloc | 3037 // Allocate stack of size C->unique()/2 to avoid frequent realloc |
3017 Node_Stack nstack(unique() >> 1); | 3038 Node_Stack nstack(unique() >> 1); |
3523 for (int i = 0; i < _print_inlining_list->length(); i++) { | 3544 for (int i = 0; i < _print_inlining_list->length(); i++) { |
3524 tty->print(_print_inlining_list->at(i).ss()->as_string()); | 3545 tty->print(_print_inlining_list->at(i).ss()->as_string()); |
3525 } | 3546 } |
3526 } | 3547 } |
3527 } | 3548 } |
3549 | |
3550 int Compile::cmp_expensive_nodes(Node* n1, Node* n2) { | |
3551 if (n1->Opcode() < n2->Opcode()) return -1; | |
3552 else if (n1->Opcode() > n2->Opcode()) return 1; | |
3553 | |
3554 assert(n1->req() == n2->req(), err_msg_res("can't compare %s nodes: n1->req() = %d, n2->req() = %d", NodeClassNames[n1->Opcode()], n1->req(), n2->req())); | |
3555 for (uint i = 1; i < n1->req(); i++) { | |
3556 if (n1->in(i) < n2->in(i)) return -1; | |
3557 else if (n1->in(i) > n2->in(i)) return 1; | |
3558 } | |
3559 | |
3560 return 0; | |
3561 } | |
3562 | |
3563 int Compile::cmp_expensive_nodes(Node** n1p, Node** n2p) { | |
3564 Node* n1 = *n1p; | |
3565 Node* n2 = *n2p; | |
3566 | |
3567 return cmp_expensive_nodes(n1, n2); | |
3568 } | |
3569 | |
3570 void Compile::sort_expensive_nodes() { | |
3571 if (!expensive_nodes_sorted()) { | |
3572 _expensive_nodes->sort(cmp_expensive_nodes); | |
3573 } | |
3574 } | |
3575 | |
3576 bool Compile::expensive_nodes_sorted() const { | |
3577 for (int i = 1; i < _expensive_nodes->length(); i++) { | |
3578 if (cmp_expensive_nodes(_expensive_nodes->adr_at(i), _expensive_nodes->adr_at(i-1)) < 0) { | |
3579 return false; | |
3580 } | |
3581 } | |
3582 return true; | |
3583 } | |
3584 | |
3585 bool Compile::should_optimize_expensive_nodes(PhaseIterGVN &igvn) { | |
3586 if (_expensive_nodes->length() == 0) { | |
3587 return false; | |
3588 } | |
3589 | |
3590 assert(OptimizeExpensiveOps, "optimization off?"); | |
3591 | |
3592 // Take this opportunity to remove dead nodes from the list | |
3593 int j = 0; | |
3594 for (int i = 0; i < _expensive_nodes->length(); i++) { | |
3595 Node* n = _expensive_nodes->at(i); | |
3596 if (!n->is_unreachable(igvn)) { | |
3597 assert(n->is_expensive(), "should be expensive"); | |
3598 _expensive_nodes->at_put(j, n); | |
3599 j++; | |
3600 } | |
3601 } | |
3602 _expensive_nodes->trunc_to(j); | |
3603 | |
3604 // Then sort the list so that similar nodes are next to each other | |
3605 // and check for at least two nodes of identical kind with same data | |
3606 // inputs. | |
3607 sort_expensive_nodes(); | |
3608 | |
3609 for (int i = 0; i < _expensive_nodes->length()-1; i++) { | |
3610 if (cmp_expensive_nodes(_expensive_nodes->adr_at(i), _expensive_nodes->adr_at(i+1)) == 0) { | |
3611 return true; | |
3612 } | |
3613 } | |
3614 | |
3615 return false; | |
3616 } | |
3617 | |
3618 void Compile::cleanup_expensive_nodes(PhaseIterGVN &igvn) { | |
3619 if (_expensive_nodes->length() == 0) { | |
3620 return; | |
3621 } | |
3622 | |
3623 assert(OptimizeExpensiveOps, "optimization off?"); | |
3624 | |
3625 // Sort to bring similar nodes next to each other and clear the | |
3626 // control input of nodes for which there's only a single copy. | |
3627 sort_expensive_nodes(); | |
3628 | |
3629 int j = 0; | |
3630 int identical = 0; | |
3631 int i = 0; | |
3632 for (; i < _expensive_nodes->length()-1; i++) { | |
3633 assert(j <= i, "can't write beyond current index"); | |
3634 if (_expensive_nodes->at(i)->Opcode() == _expensive_nodes->at(i+1)->Opcode()) { | |
3635 identical++; | |
3636 _expensive_nodes->at_put(j++, _expensive_nodes->at(i)); | |
3637 continue; | |
3638 } | |
3639 if (identical > 0) { | |
3640 _expensive_nodes->at_put(j++, _expensive_nodes->at(i)); | |
3641 identical = 0; | |
3642 } else { | |
3643 Node* n = _expensive_nodes->at(i); | |
3644 igvn.hash_delete(n); | |
3645 n->set_req(0, NULL); | |
3646 igvn.hash_insert(n); | |
3647 } | |
3648 } | |
3649 if (identical > 0) { | |
3650 _expensive_nodes->at_put(j++, _expensive_nodes->at(i)); | |
3651 } else if (_expensive_nodes->length() >= 1) { | |
3652 Node* n = _expensive_nodes->at(i); | |
3653 igvn.hash_delete(n); | |
3654 n->set_req(0, NULL); | |
3655 igvn.hash_insert(n); | |
3656 } | |
3657 _expensive_nodes->trunc_to(j); | |
3658 } | |
3659 | |
3660 void Compile::add_expensive_node(Node * n) { | |
3661 assert(!_expensive_nodes->contains(n), "duplicate entry in expensive list"); | |
3662 assert(n->is_expensive(), "expensive nodes with non-null control here only"); | |
3663 assert(!n->is_CFG() && !n->is_Mem(), "no cfg or memory nodes here"); | |
3664 if (OptimizeExpensiveOps) { | |
3665 _expensive_nodes->append(n); | |
3666 } else { | |
3667 // Clear control input and let IGVN optimize expensive nodes if | |
3668 // OptimizeExpensiveOps is off. | |
3669 n->set_req(0, NULL); | |
3670 } | |
3671 } |