< prev index next >

src/hotspot/share/opto/cfgnode.cpp

Print this page




 697                 Node *if_max= gvn->register_new_node_with_optimizer(new IfTrueNode (iff));
 698                 ifF         = gvn->register_new_node_with_optimizer(new IfFalseNode(iff));
 699                 // update input edges to region node
 700                 set_req_X( min_idx, if_min, gvn );
 701                 set_req_X( max_idx, if_max, gvn );
 702                 set_req_X( val_idx, ifF,    gvn );
 703                 // remove unnecessary 'LShiftI; RShiftI' idiom
 704                 gvn->hash_delete(phi);
 705                 phi->set_req_X( val_idx, convf2i, gvn );
 706                 gvn->hash_find_insert(phi);
 707                 // Return transformed region node
 708                 return this;
 709               }
 710             }
 711           }
 712         }
 713       }
 714     }
 715   }
 716 




 717   return modified ? this : NULL;
 718 }
 719 
 720 




























































































































 721 
 722 const RegMask &RegionNode::out_RegMask() const {
 723   return RegMask::Empty;
 724 }
 725 
 726 // Find the one non-null required input.  RegionNode only
 727 Node *Node::nonnull_req() const {
 728   assert( is_Region(), "" );
 729   for( uint i = 1; i < _cnt; i++ )
 730     if( in(i) )
 731       return in(i);
 732   ShouldNotReachHere();
 733   return NULL;
 734 }
 735 
 736 
 737 //=============================================================================
 738 // note that these functions assume that the _adr_type field is flattened
 739 uint PhiNode::hash() const {
 740   const Type* at = _adr_type;




 697                 Node *if_max= gvn->register_new_node_with_optimizer(new IfTrueNode (iff));
 698                 ifF         = gvn->register_new_node_with_optimizer(new IfFalseNode(iff));
 699                 // update input edges to region node
 700                 set_req_X( min_idx, if_min, gvn );
 701                 set_req_X( max_idx, if_max, gvn );
 702                 set_req_X( val_idx, ifF,    gvn );
 703                 // remove unnecessary 'LShiftI; RShiftI' idiom
 704                 gvn->hash_delete(phi);
 705                 phi->set_req_X( val_idx, convf2i, gvn );
 706                 gvn->hash_find_insert(phi);
 707                 // Return transformed region node
 708                 return this;
 709               }
 710             }
 711           }
 712         }
 713       }
 714     }
 715   }
 716 
 717   if (can_reshape) {
 718     modified |= optimize_trichotomy(phase->is_IterGVN());
 719   }
 720 
 721   return modified ? this : NULL;
 722 }
 723 
 724 //------------------------------optimize_trichotomy--------------------------
 725 // Optimize nested comparisons of the following kind:
 726 // 
 727 // int compare(int a, int b) {
 728 //   return (a < b) ? -1 : (a == b) ? 0 : 1;
 729 // }
 730 //
 731 // Shape 1:
 732 // if (compare(a, b) == 1) { ... } -> if (a > b) { ... }
 733 //
 734 // Shape 2:
 735 // if (compare(a, b) == 0) { ... } -> if (a == b) { ... }
 736 // 
 737 // Above code leads to the following IR shapes where both Ifs compare the
 738 // same value and two out of three region inputs idx1 and idx2 map to
 739 // the same value and control flow.
 740 //
 741 // (1)   If                 (2)   If
 742 //      /  \                     /  \
 743 //   Proj  Proj               Proj  Proj
 744 //     |      \                |      \
 745 //     |       If              |      If                      If
 746 //     |      /  \             |     /  \                    /  \
 747 //     |   Proj  Proj          |  Proj  Proj      ==>     Proj  Proj
 748 //     |   /      /            \    |    /                  |    /
 749 //    Region     /              \   |   /                   |   /
 750 //         \    /                \  |  /                    |  /
 751 //         Region                Region                    Region
 752 //
 753 // The method returns true if 'this' is modified and false otherwise.
 754 bool RegionNode::optimize_trichotomy(PhaseIterGVN* igvn) {
 755   int idx1 = 1, idx2 = 2;
 756   Node* region = NULL;
 757   if (req() == 3 && in(1) != NULL && in(2) != NULL) {
 758     // Shape 1: Check if one of the inputs is a region that merges two control
 759     // inputs and has no other users (especially no Phi users).
 760     region = in(1)->isa_Region() ? in(1) : in(2)->isa_Region();
 761     if (region == NULL || region->outcnt() != 2 || region->req() != 3) {
 762       return false; // No suitable region input found
 763     }
 764   } else if (req() == 4) {
 765     // Shape 2: Check if two control inputs map to the same value of the unique phi
 766     // user and treat these as if they would come from another region (shape (1)).
 767     PhiNode* phi = has_unique_phi();
 768     if (phi == NULL) {
 769       return false; // No unique phi user
 770     }
 771     if (phi->in(idx1) != phi->in(idx2)) {
 772       idx2 = 3;
 773       if (phi->in(idx1) != phi->in(idx2)) {
 774         idx1 = 2;
 775         if (phi->in(idx1) != phi->in(idx2)) {
 776           return false; // No equal phi inputs found
 777         }
 778       }
 779     }
 780     assert(phi->in(idx1) == phi->in(idx2), "must be"); // Region is merging same value
 781     region = this;
 782   }
 783   if (region == NULL || region->in(idx1) == NULL || region->in(idx2) == NULL) {
 784     return false; // Region does not merge two control inputs
 785   }
 786   // At this point we know that region->in(idx1) and region->(idx2) map to the same
 787   // value and control flow. Now search for ifs that feed into these region inputs.
 788   ProjNode* proj1 = region->in(idx1)->isa_Proj();
 789   ProjNode* proj2 = region->in(idx2)->isa_Proj();
 790   if (proj1 == NULL || proj1->outcnt() != 1 ||
 791       proj2 == NULL || proj2->outcnt() != 1) {
 792     return false; // No projection inputs with region as unique user found
 793   }
 794   IfNode* iff1 = proj1->in(0)->isa_If();
 795   IfNode* iff2 = proj2->in(0)->isa_If();
 796   if (iff1 == NULL || iff1->outcnt() != 2 ||
 797       iff2 == NULL || iff2->outcnt() != 2) {
 798     return false; // No ifs found
 799   }
 800   if (iff1 == iff2) {
 801     igvn->replace_input_of(region, idx1, iff1->in(0));
 802     igvn->replace_input_of(region, idx2, igvn->C->top());
 803     return (region == this); // Remove useless if (both projections map to the same control/value)
 804   }
 805   BoolNode* bol1 = iff1->in(1)->isa_Bool();
 806   BoolNode* bol2 = iff2->in(1)->isa_Bool();
 807   if (bol1 == NULL || bol2 == NULL) {
 808     return false; // No bool inputs found
 809   }
 810   Node* cmp1 = bol1->in(1);
 811   Node* cmp2 = bol2->in(1);
 812   bool commute = false;
 813   if (cmp1 != cmp2) {
 814     if (cmp1->in(1) == cmp2->in(2) &&
 815         cmp1->in(2) == cmp2->in(1)) {
 816       commute = true; // Same but swapped inputs, commute the test
 817     } else {
 818       return false; // Ifs are not comparing the same values
 819     }
 820   }
 821   proj1 = proj1->other_if_proj();
 822   proj2 = proj2->other_if_proj();
 823   if (!((proj1->unique_ctrl_out() == iff2 &&
 824          proj2->unique_ctrl_out() == this) ||
 825         (proj2->unique_ctrl_out() == iff1 &&
 826          proj1->unique_ctrl_out() == this))) {
 827     return false; // Ifs are not connected through other projs
 828   }
 829   // Found 'iff -> proj -> iff -> proj -> this' shape where all other projs are merged
 830   // through 'region' and map to the same value. Merge the boolean tests and replace
 831   // the ifs by a single comparison.
 832   BoolTest test1 = (proj1->_con == 1) ? bol1->_test : bol1->_test.negate();
 833   BoolTest test2 = (proj2->_con == 1) ? bol2->_test : bol2->_test.negate();
 834   test1 = commute ? test1.commute() : test1;
 835   BoolTest::mask res = test1.merge(test2);
 836   // Adjust iff1 to always pass (only iff2 will remain)
 837   igvn->replace_input_of(iff1, 1, igvn->intcon(proj1->_con));
 838   if (res == BoolTest::never) {
 839     // Merged test is always false, adjust iff2 to always fail
 840     igvn->replace_input_of(iff2, 1, igvn->intcon(1 - proj2->_con));
 841   } else {
 842     // Replace bool input of iff2 with merged test
 843     assert(res != BoolTest::illegal, "Unexpected bool result %d", res);
 844     BoolNode* new_bol = new BoolNode(bol2->in(1), res);
 845     igvn->replace_input_of(iff2, 1, igvn->transform((proj2->_con == 1) ? new_bol : new_bol->negate(igvn)));
 846   }
 847   return false;
 848 }
 849 
 850 const RegMask &RegionNode::out_RegMask() const {
 851   return RegMask::Empty;
 852 }
 853 
 854 // Find the one non-null required input.  RegionNode only
 855 Node *Node::nonnull_req() const {
 856   assert( is_Region(), "" );
 857   for( uint i = 1; i < _cnt; i++ )
 858     if( in(i) )
 859       return in(i);
 860   ShouldNotReachHere();
 861   return NULL;
 862 }
 863 
 864 
 865 //=============================================================================
 866 // note that these functions assume that the _adr_type field is flattened
 867 uint PhiNode::hash() const {
 868   const Type* at = _adr_type;


< prev index next >