src/share/vm/c1/c1_Optimizer.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/c1

src/share/vm/c1/c1_Optimizer.cpp

Print this page
rev 5349 : 8023657: New type profiling points: arguments to call
Summary: x86 interpreter and c1 type profiling for arguments at calls
Reviewed-by:


 640 
 641   // Handlers for relevant instructions
 642   // (separated out from NullCheckVisitor for clarity)
 643 
 644   // The basic contract is that these must leave the instruction in
 645   // the desired state; must not assume anything about the state of
 646   // the instruction. We make multiple passes over some basic blocks
 647   // and the last pass is the only one whose result is valid.
 648   void handle_AccessField     (AccessField* x);
 649   void handle_ArrayLength     (ArrayLength* x);
 650   void handle_LoadIndexed     (LoadIndexed* x);
 651   void handle_StoreIndexed    (StoreIndexed* x);
 652   void handle_NullCheck       (NullCheck* x);
 653   void handle_Invoke          (Invoke* x);
 654   void handle_NewInstance     (NewInstance* x);
 655   void handle_NewArray        (NewArray* x);
 656   void handle_AccessMonitor   (AccessMonitor* x);
 657   void handle_Intrinsic       (Intrinsic* x);
 658   void handle_ExceptionObject (ExceptionObject* x);
 659   void handle_Phi             (Phi* x);

 660 };
 661 
 662 
 663 // NEEDS_CLEANUP
 664 // There may be other instructions which need to clear the last
 665 // explicit null check. Anything across which we can not hoist the
 666 // debug information for a NullCheck instruction must clear it. It
 667 // might be safer to pattern match "NullCheck ; {AccessField,
 668 // ArrayLength, LoadIndexed}" but it is more easily structured this way.
 669 // Should test to see performance hit of clearing it for all handlers
 670 // with empty bodies below. If it is negligible then we should leave
 671 // that in for safety, otherwise should think more about it.
 672 void NullCheckVisitor::do_Phi            (Phi*             x) { nce()->handle_Phi(x);      }
 673 void NullCheckVisitor::do_Local          (Local*           x) {}
 674 void NullCheckVisitor::do_Constant       (Constant*        x) { /* FIXME: handle object constants */ }
 675 void NullCheckVisitor::do_LoadField      (LoadField*       x) { nce()->handle_AccessField(x); }
 676 void NullCheckVisitor::do_StoreField     (StoreField*      x) { nce()->handle_AccessField(x); }
 677 void NullCheckVisitor::do_ArrayLength    (ArrayLength*     x) { nce()->handle_ArrayLength(x); }
 678 void NullCheckVisitor::do_LoadIndexed    (LoadIndexed*     x) { nce()->handle_LoadIndexed(x); }
 679 void NullCheckVisitor::do_StoreIndexed   (StoreIndexed*    x) { nce()->handle_StoreIndexed(x); }


 698 void NullCheckVisitor::do_Intrinsic      (Intrinsic*       x) { nce()->handle_Intrinsic(x);     }
 699 void NullCheckVisitor::do_BlockBegin     (BlockBegin*      x) {}
 700 void NullCheckVisitor::do_Goto           (Goto*            x) {}
 701 void NullCheckVisitor::do_If             (If*              x) {}
 702 void NullCheckVisitor::do_IfInstanceOf   (IfInstanceOf*    x) {}
 703 void NullCheckVisitor::do_TableSwitch    (TableSwitch*     x) {}
 704 void NullCheckVisitor::do_LookupSwitch   (LookupSwitch*    x) {}
 705 void NullCheckVisitor::do_Return         (Return*          x) {}
 706 void NullCheckVisitor::do_Throw          (Throw*           x) { nce()->clear_last_explicit_null_check(); }
 707 void NullCheckVisitor::do_Base           (Base*            x) {}
 708 void NullCheckVisitor::do_OsrEntry       (OsrEntry*        x) {}
 709 void NullCheckVisitor::do_ExceptionObject(ExceptionObject* x) { nce()->handle_ExceptionObject(x); }
 710 void NullCheckVisitor::do_RoundFP        (RoundFP*         x) {}
 711 void NullCheckVisitor::do_UnsafeGetRaw   (UnsafeGetRaw*    x) {}
 712 void NullCheckVisitor::do_UnsafePutRaw   (UnsafePutRaw*    x) {}
 713 void NullCheckVisitor::do_UnsafeGetObject(UnsafeGetObject* x) {}
 714 void NullCheckVisitor::do_UnsafePutObject(UnsafePutObject* x) {}
 715 void NullCheckVisitor::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) {}
 716 void NullCheckVisitor::do_UnsafePrefetchRead (UnsafePrefetchRead*  x) {}
 717 void NullCheckVisitor::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {}
 718 void NullCheckVisitor::do_ProfileCall    (ProfileCall*     x) { nce()->clear_last_explicit_null_check(); }

 719 void NullCheckVisitor::do_ProfileInvoke  (ProfileInvoke*   x) {}
 720 void NullCheckVisitor::do_RuntimeCall    (RuntimeCall*     x) {}
 721 void NullCheckVisitor::do_MemBar         (MemBar*          x) {}
 722 void NullCheckVisitor::do_RangeCheckPredicate(RangeCheckPredicate* x) {}
 723 #ifdef ASSERT
 724 void NullCheckVisitor::do_Assert         (Assert*          x) {}
 725 #endif
 726 
 727 void NullCheckEliminator::visit(Value* p) {
 728   assert(*p != NULL, "should not find NULL instructions");
 729   if (visitable(*p)) {
 730     mark_visited(*p);
 731     (*p)->visit(&_visitor);
 732   }
 733 }
 734 
 735 bool NullCheckEliminator::merge_state_for(BlockBegin* block, ValueSet* incoming_state) {
 736   ValueSet* state = state_for(block);
 737   if (state == NULL) {
 738     state = incoming_state->copy();


1117   } else {
1118     for (i = 0; i < x->operand_count(); i++) {
1119       Value input = x->operand_at(i);
1120       if (!set_contains(input)) {
1121         all_non_null = false;
1122       }
1123     }
1124   }
1125 
1126   if (all_non_null) {
1127     // Value is non-null => update Phi
1128     if (PrintNullCheckElimination) {
1129       tty->print_cr("Eliminated Phi %d's null check for phifun because all inputs are non-null", x->id());
1130     }
1131     x->set_needs_null_check(false);
1132   } else if (set_contains(x)) {
1133     set_remove(x);
1134   }
1135 }
1136 





1137 
1138 void Optimizer::eliminate_null_checks() {
1139   ResourceMark rm;
1140 
1141   NullCheckEliminator nce(this);
1142 
1143   if (PrintNullCheckElimination) {
1144     tty->print_cr("Starting null check elimination for method %s::%s%s",
1145                   ir()->method()->holder()->name()->as_utf8(),
1146                   ir()->method()->name()->as_utf8(),
1147                   ir()->method()->signature()->as_symbol()->as_utf8());
1148   }
1149 
1150   // Apply to graph
1151   nce.iterate(ir()->start());
1152 
1153   // walk over the graph looking for exception
1154   // handlers and iterate over them as well
1155   int nblocks = BlockBegin::number_of_blocks();
1156   BlockList blocks(nblocks);




 640 
 641   // Handlers for relevant instructions
 642   // (separated out from NullCheckVisitor for clarity)
 643 
 644   // The basic contract is that these must leave the instruction in
 645   // the desired state; must not assume anything about the state of
 646   // the instruction. We make multiple passes over some basic blocks
 647   // and the last pass is the only one whose result is valid.
 648   void handle_AccessField     (AccessField* x);
 649   void handle_ArrayLength     (ArrayLength* x);
 650   void handle_LoadIndexed     (LoadIndexed* x);
 651   void handle_StoreIndexed    (StoreIndexed* x);
 652   void handle_NullCheck       (NullCheck* x);
 653   void handle_Invoke          (Invoke* x);
 654   void handle_NewInstance     (NewInstance* x);
 655   void handle_NewArray        (NewArray* x);
 656   void handle_AccessMonitor   (AccessMonitor* x);
 657   void handle_Intrinsic       (Intrinsic* x);
 658   void handle_ExceptionObject (ExceptionObject* x);
 659   void handle_Phi             (Phi* x);
 660   void handle_ProfileCall     (ProfileCall* x);
 661 };
 662 
 663 
 664 // NEEDS_CLEANUP
 665 // There may be other instructions which need to clear the last
 666 // explicit null check. Anything across which we can not hoist the
 667 // debug information for a NullCheck instruction must clear it. It
 668 // might be safer to pattern match "NullCheck ; {AccessField,
 669 // ArrayLength, LoadIndexed}" but it is more easily structured this way.
 670 // Should test to see performance hit of clearing it for all handlers
 671 // with empty bodies below. If it is negligible then we should leave
 672 // that in for safety, otherwise should think more about it.
 673 void NullCheckVisitor::do_Phi            (Phi*             x) { nce()->handle_Phi(x);      }
 674 void NullCheckVisitor::do_Local          (Local*           x) {}
 675 void NullCheckVisitor::do_Constant       (Constant*        x) { /* FIXME: handle object constants */ }
 676 void NullCheckVisitor::do_LoadField      (LoadField*       x) { nce()->handle_AccessField(x); }
 677 void NullCheckVisitor::do_StoreField     (StoreField*      x) { nce()->handle_AccessField(x); }
 678 void NullCheckVisitor::do_ArrayLength    (ArrayLength*     x) { nce()->handle_ArrayLength(x); }
 679 void NullCheckVisitor::do_LoadIndexed    (LoadIndexed*     x) { nce()->handle_LoadIndexed(x); }
 680 void NullCheckVisitor::do_StoreIndexed   (StoreIndexed*    x) { nce()->handle_StoreIndexed(x); }


 699 void NullCheckVisitor::do_Intrinsic      (Intrinsic*       x) { nce()->handle_Intrinsic(x);     }
 700 void NullCheckVisitor::do_BlockBegin     (BlockBegin*      x) {}
 701 void NullCheckVisitor::do_Goto           (Goto*            x) {}
 702 void NullCheckVisitor::do_If             (If*              x) {}
 703 void NullCheckVisitor::do_IfInstanceOf   (IfInstanceOf*    x) {}
 704 void NullCheckVisitor::do_TableSwitch    (TableSwitch*     x) {}
 705 void NullCheckVisitor::do_LookupSwitch   (LookupSwitch*    x) {}
 706 void NullCheckVisitor::do_Return         (Return*          x) {}
 707 void NullCheckVisitor::do_Throw          (Throw*           x) { nce()->clear_last_explicit_null_check(); }
 708 void NullCheckVisitor::do_Base           (Base*            x) {}
 709 void NullCheckVisitor::do_OsrEntry       (OsrEntry*        x) {}
 710 void NullCheckVisitor::do_ExceptionObject(ExceptionObject* x) { nce()->handle_ExceptionObject(x); }
 711 void NullCheckVisitor::do_RoundFP        (RoundFP*         x) {}
 712 void NullCheckVisitor::do_UnsafeGetRaw   (UnsafeGetRaw*    x) {}
 713 void NullCheckVisitor::do_UnsafePutRaw   (UnsafePutRaw*    x) {}
 714 void NullCheckVisitor::do_UnsafeGetObject(UnsafeGetObject* x) {}
 715 void NullCheckVisitor::do_UnsafePutObject(UnsafePutObject* x) {}
 716 void NullCheckVisitor::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) {}
 717 void NullCheckVisitor::do_UnsafePrefetchRead (UnsafePrefetchRead*  x) {}
 718 void NullCheckVisitor::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {}
 719 void NullCheckVisitor::do_ProfileCall    (ProfileCall*     x) { nce()->clear_last_explicit_null_check();
 720                                                                 nce()->handle_ProfileCall(x); }
 721 void NullCheckVisitor::do_ProfileInvoke  (ProfileInvoke*   x) {}
 722 void NullCheckVisitor::do_RuntimeCall    (RuntimeCall*     x) {}
 723 void NullCheckVisitor::do_MemBar         (MemBar*          x) {}
 724 void NullCheckVisitor::do_RangeCheckPredicate(RangeCheckPredicate* x) {}
 725 #ifdef ASSERT
 726 void NullCheckVisitor::do_Assert         (Assert*          x) {}
 727 #endif
 728 
 729 void NullCheckEliminator::visit(Value* p) {
 730   assert(*p != NULL, "should not find NULL instructions");
 731   if (visitable(*p)) {
 732     mark_visited(*p);
 733     (*p)->visit(&_visitor);
 734   }
 735 }
 736 
 737 bool NullCheckEliminator::merge_state_for(BlockBegin* block, ValueSet* incoming_state) {
 738   ValueSet* state = state_for(block);
 739   if (state == NULL) {
 740     state = incoming_state->copy();


1119   } else {
1120     for (i = 0; i < x->operand_count(); i++) {
1121       Value input = x->operand_at(i);
1122       if (!set_contains(input)) {
1123         all_non_null = false;
1124       }
1125     }
1126   }
1127 
1128   if (all_non_null) {
1129     // Value is non-null => update Phi
1130     if (PrintNullCheckElimination) {
1131       tty->print_cr("Eliminated Phi %d's null check for phifun because all inputs are non-null", x->id());
1132     }
1133     x->set_needs_null_check(false);
1134   } else if (set_contains(x)) {
1135     set_remove(x);
1136   }
1137 }
1138 
1139 void NullCheckEliminator::handle_ProfileCall(ProfileCall* x) {
1140   for (int i = 0; i < x->nb_profiled_args(); i++) {
1141     x->set_arg_needs_null_check(i, !set_contains(x->profiled_arg_at(i)));
1142   }
1143 }
1144 
1145 void Optimizer::eliminate_null_checks() {
1146   ResourceMark rm;
1147 
1148   NullCheckEliminator nce(this);
1149 
1150   if (PrintNullCheckElimination) {
1151     tty->print_cr("Starting null check elimination for method %s::%s%s",
1152                   ir()->method()->holder()->name()->as_utf8(),
1153                   ir()->method()->name()->as_utf8(),
1154                   ir()->method()->signature()->as_symbol()->as_utf8());
1155   }
1156 
1157   // Apply to graph
1158   nce.iterate(ir()->start());
1159 
1160   // walk over the graph looking for exception
1161   // handlers and iterate over them as well
1162   int nblocks = BlockBegin::number_of_blocks();
1163   BlockList blocks(nblocks);


src/share/vm/c1/c1_Optimizer.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File