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 }