< prev index next >

src/share/vm/opto/stringopts.cpp

Print this page




 756           // skip through a potential MergeMem chain, linked through Bot
 757           mem = mem->in(Compile::AliasIdxBot);
 758           NOT_PRODUCT(path.push(mem);)
 759         }
 760         // now let it fall through, and see if we have a projection
 761         if (mem->is_Proj()) {
 762           // Should point to a previous known call
 763           Node *prev = mem->in(0);
 764           NOT_PRODUCT(path.push(prev);)
 765           if (!prev->is_Call() || !_control.contains(prev)) {
 766 #ifndef PRODUCT
 767             if (PrintOptimizeStringConcat) {
 768               tty->print("fusion has incorrect memory flow (unknown call) for ");
 769               _begin->jvms()->dump_spec(tty); tty->cr();
 770               path.dump();
 771             }
 772 #endif
 773             return false;
 774           }
 775         } else {
 776           assert(mem->is_Store() || mem->is_LoadStore(), err_msg_res("unexpected node type: %s", mem->Name()));
 777 #ifndef PRODUCT
 778           if (PrintOptimizeStringConcat) {
 779             tty->print("fusion has incorrect memory flow (unexpected source) for ");
 780             _begin->jvms()->dump_spec(tty); tty->cr();
 781             path.dump();
 782           }
 783 #endif
 784           return false;
 785         }
 786       } else {
 787         // For memory that feeds into constructors it's more complicated.
 788         // However the advantage is that any side effect that happens between the Allocate/Initialize and
 789         // the constructor will have to be control-dependent on Initialize.
 790         // So we actually don't have to do anything, since it's going to be caught by the control flow
 791         // analysis.
 792 #ifdef ASSERT
 793         // Do a quick verification of the control pattern between the constructor and the initialize node
 794         assert(curr->is_Call(), "constructor should be a call");
 795         // Go up the control starting from the constructor call
 796         Node* ctrl = curr->in(0);
 797         IfNode* iff = NULL;
 798         RegionNode* copy = NULL;
 799 
 800         while (true) {
 801           // skip known check patterns
 802           if (ctrl->is_Region()) {
 803             if (ctrl->as_Region()->is_copy()) {
 804               copy = ctrl->as_Region();
 805               ctrl = copy->is_copy();
 806             } else { // a cast
 807               assert(ctrl->req() == 3 &&
 808                      ctrl->in(1) != NULL && ctrl->in(1)->is_Proj() &&
 809                      ctrl->in(2) != NULL && ctrl->in(2)->is_Proj() &&
 810                      ctrl->in(1)->in(0) == ctrl->in(2)->in(0) &&
 811                      ctrl->in(1)->in(0) != NULL && ctrl->in(1)->in(0)->is_If(),
 812                      "must be a simple diamond");
 813               Node* true_proj = ctrl->in(1)->is_IfTrue() ? ctrl->in(1) : ctrl->in(2);
 814               for (SimpleDUIterator i(true_proj); i.has_next(); i.next()) {
 815                 Node* use = i.get();
 816                 assert(use == ctrl || use->is_ConstraintCast(),
 817                        err_msg_res("unexpected user: %s", use->Name()));
 818               }
 819 
 820               iff = ctrl->in(1)->in(0)->as_If();
 821               ctrl = iff->in(0);
 822             }
 823           } else if (ctrl->is_IfTrue()) { // null checks, class checks
 824             iff = ctrl->in(0)->as_If();
 825             assert(iff->is_If(), "must be if");
 826             // Verify that the other arm is an uncommon trap
 827             Node* otherproj = iff->proj_out(1 - ctrl->as_Proj()->_con);
 828             CallStaticJavaNode* call = otherproj->unique_out()->isa_CallStaticJava();
 829             assert(strcmp(call->_name, "uncommon_trap") == 0, "must be uncommond trap");
 830             ctrl = iff->in(0);
 831           } else {
 832             break;
 833           }
 834         }
 835 
 836         assert(ctrl->is_Proj(), "must be a projection");
 837         assert(ctrl->in(0)->is_Initialize(), "should be initialize");
 838         for (SimpleDUIterator i(ctrl); i.has_next(); i.next()) {
 839           Node* use = i.get();
 840           assert(use == copy || use == iff || use == curr || use->is_CheckCastPP() || use->is_Load(),
 841                  err_msg_res("unexpected user: %s", use->Name()));
 842         }
 843 #endif // ASSERT
 844       }
 845     }
 846   }
 847 
 848 #ifndef PRODUCT
 849   if (PrintOptimizeStringConcat) {
 850     tty->print("fusion has correct memory flow for ");
 851     _begin->jvms()->dump_spec(tty); tty->cr();
 852     tty->cr();
 853   }
 854 #endif
 855   return true;
 856 }
 857 
 858 bool StringConcat::validate_control_flow() {
 859   // We found all the calls and arguments now lets see if it's
 860   // safe to transform the graph as we would expect.
 861 




 756           // skip through a potential MergeMem chain, linked through Bot
 757           mem = mem->in(Compile::AliasIdxBot);
 758           NOT_PRODUCT(path.push(mem);)
 759         }
 760         // now let it fall through, and see if we have a projection
 761         if (mem->is_Proj()) {
 762           // Should point to a previous known call
 763           Node *prev = mem->in(0);
 764           NOT_PRODUCT(path.push(prev);)
 765           if (!prev->is_Call() || !_control.contains(prev)) {
 766 #ifndef PRODUCT
 767             if (PrintOptimizeStringConcat) {
 768               tty->print("fusion has incorrect memory flow (unknown call) for ");
 769               _begin->jvms()->dump_spec(tty); tty->cr();
 770               path.dump();
 771             }
 772 #endif
 773             return false;
 774           }
 775         } else {
 776           assert(mem->is_Store() || mem->is_LoadStore(), "unexpected node type: %s", mem->Name());
 777 #ifndef PRODUCT
 778           if (PrintOptimizeStringConcat) {
 779             tty->print("fusion has incorrect memory flow (unexpected source) for ");
 780             _begin->jvms()->dump_spec(tty); tty->cr();
 781             path.dump();
 782           }
 783 #endif
 784           return false;
 785         }
 786       } else {
 787         // For memory that feeds into constructors it's more complicated.
 788         // However the advantage is that any side effect that happens between the Allocate/Initialize and
 789         // the constructor will have to be control-dependent on Initialize.
 790         // So we actually don't have to do anything, since it's going to be caught by the control flow
 791         // analysis.
 792 #ifdef ASSERT
 793         // Do a quick verification of the control pattern between the constructor and the initialize node
 794         assert(curr->is_Call(), "constructor should be a call");
 795         // Go up the control starting from the constructor call
 796         Node* ctrl = curr->in(0);
 797         IfNode* iff = NULL;
 798         RegionNode* copy = NULL;
 799 
 800         while (true) {
 801           // skip known check patterns
 802           if (ctrl->is_Region()) {
 803             if (ctrl->as_Region()->is_copy()) {
 804               copy = ctrl->as_Region();
 805               ctrl = copy->is_copy();
 806             } else { // a cast
 807               assert(ctrl->req() == 3 &&
 808                      ctrl->in(1) != NULL && ctrl->in(1)->is_Proj() &&
 809                      ctrl->in(2) != NULL && ctrl->in(2)->is_Proj() &&
 810                      ctrl->in(1)->in(0) == ctrl->in(2)->in(0) &&
 811                      ctrl->in(1)->in(0) != NULL && ctrl->in(1)->in(0)->is_If(),
 812                      "must be a simple diamond");
 813               Node* true_proj = ctrl->in(1)->is_IfTrue() ? ctrl->in(1) : ctrl->in(2);
 814               for (SimpleDUIterator i(true_proj); i.has_next(); i.next()) {
 815                 Node* use = i.get();
 816                 assert(use == ctrl || use->is_ConstraintCast(),
 817                        "unexpected user: %s", use->Name());
 818               }
 819 
 820               iff = ctrl->in(1)->in(0)->as_If();
 821               ctrl = iff->in(0);
 822             }
 823           } else if (ctrl->is_IfTrue()) { // null checks, class checks
 824             iff = ctrl->in(0)->as_If();
 825             assert(iff->is_If(), "must be if");
 826             // Verify that the other arm is an uncommon trap
 827             Node* otherproj = iff->proj_out(1 - ctrl->as_Proj()->_con);
 828             CallStaticJavaNode* call = otherproj->unique_out()->isa_CallStaticJava();
 829             assert(strcmp(call->_name, "uncommon_trap") == 0, "must be uncommond trap");
 830             ctrl = iff->in(0);
 831           } else {
 832             break;
 833           }
 834         }
 835 
 836         assert(ctrl->is_Proj(), "must be a projection");
 837         assert(ctrl->in(0)->is_Initialize(), "should be initialize");
 838         for (SimpleDUIterator i(ctrl); i.has_next(); i.next()) {
 839           Node* use = i.get();
 840           assert(use == copy || use == iff || use == curr || use->is_CheckCastPP() || use->is_Load(),
 841                  "unexpected user: %s", use->Name());
 842         }
 843 #endif // ASSERT
 844       }
 845     }
 846   }
 847 
 848 #ifndef PRODUCT
 849   if (PrintOptimizeStringConcat) {
 850     tty->print("fusion has correct memory flow for ");
 851     _begin->jvms()->dump_spec(tty); tty->cr();
 852     tty->cr();
 853   }
 854 #endif
 855   return true;
 856 }
 857 
 858 bool StringConcat::validate_control_flow() {
 859   // We found all the calls and arguments now lets see if it's
 860   // safe to transform the graph as we would expect.
 861 


< prev index next >