Mercurial > hg > graal-compiler
comparison src/share/vm/c1/c1_IR.cpp @ 8860:46f6f063b272
7153771: array bound check elimination for c1
Summary: when possible optimize out array bound checks, inserting predicates when needed.
Reviewed-by: never, kvn, twisti
Contributed-by: thomaswue <thomas.wuerthinger@oracle.com>
author | roland |
---|---|
date | Thu, 21 Mar 2013 09:27:54 +0100 |
parents | b9a9ed0f8eeb |
children | b9a918201d47 ef57c43512d6 |
comparison
equal
deleted
inserted
replaced
8780:98f3af397705 | 8860:46f6f063b272 |
---|---|
180 | 180 |
181 | 181 |
182 // Implementation of CodeEmitInfo | 182 // Implementation of CodeEmitInfo |
183 | 183 |
184 // Stack must be NON-null | 184 // Stack must be NON-null |
185 CodeEmitInfo::CodeEmitInfo(ValueStack* stack, XHandlers* exception_handlers) | 185 CodeEmitInfo::CodeEmitInfo(ValueStack* stack, XHandlers* exception_handlers, bool deoptimize_on_exception) |
186 : _scope(stack->scope()) | 186 : _scope(stack->scope()) |
187 , _scope_debug_info(NULL) | 187 , _scope_debug_info(NULL) |
188 , _oop_map(NULL) | 188 , _oop_map(NULL) |
189 , _stack(stack) | 189 , _stack(stack) |
190 , _exception_handlers(exception_handlers) | 190 , _exception_handlers(exception_handlers) |
191 , _is_method_handle_invoke(false) { | 191 , _is_method_handle_invoke(false) |
192 , _deoptimize_on_exception(deoptimize_on_exception) { | |
192 assert(_stack != NULL, "must be non null"); | 193 assert(_stack != NULL, "must be non null"); |
193 } | 194 } |
194 | 195 |
195 | 196 |
196 CodeEmitInfo::CodeEmitInfo(CodeEmitInfo* info, ValueStack* stack) | 197 CodeEmitInfo::CodeEmitInfo(CodeEmitInfo* info, ValueStack* stack) |
197 : _scope(info->_scope) | 198 : _scope(info->_scope) |
198 , _exception_handlers(NULL) | 199 , _exception_handlers(NULL) |
199 , _scope_debug_info(NULL) | 200 , _scope_debug_info(NULL) |
200 , _oop_map(NULL) | 201 , _oop_map(NULL) |
201 , _stack(stack == NULL ? info->_stack : stack) | 202 , _stack(stack == NULL ? info->_stack : stack) |
202 , _is_method_handle_invoke(info->_is_method_handle_invoke) { | 203 , _is_method_handle_invoke(info->_is_method_handle_invoke) |
204 , _deoptimize_on_exception(info->_deoptimize_on_exception) { | |
203 | 205 |
204 // deep copy of exception handlers | 206 // deep copy of exception handlers |
205 if (info->_exception_handlers != NULL) { | 207 if (info->_exception_handlers != NULL) { |
206 _exception_handlers = new XHandlers(info->_exception_handlers); | 208 _exception_handlers = new XHandlers(info->_exception_handlers); |
207 } | 209 } |
237 _top_scope = new IRScope(compilation, NULL, -1, method, osr_bci, true); | 239 _top_scope = new IRScope(compilation, NULL, -1, method, osr_bci, true); |
238 _code = NULL; | 240 _code = NULL; |
239 } | 241 } |
240 | 242 |
241 | 243 |
242 void IR::optimize() { | 244 void IR::optimize_blocks() { |
243 Optimizer opt(this); | 245 Optimizer opt(this); |
244 if (!compilation()->profile_branches()) { | 246 if (!compilation()->profile_branches()) { |
245 if (DoCEE) { | 247 if (DoCEE) { |
246 opt.eliminate_conditional_expressions(); | 248 opt.eliminate_conditional_expressions(); |
247 #ifndef PRODUCT | 249 #ifndef PRODUCT |
255 if (PrintCFG || PrintCFG1) { tty->print_cr("CFG after block elimination"); print(true); } | 257 if (PrintCFG || PrintCFG1) { tty->print_cr("CFG after block elimination"); print(true); } |
256 if (PrintIR || PrintIR1 ) { tty->print_cr("IR after block elimination"); print(false); } | 258 if (PrintIR || PrintIR1 ) { tty->print_cr("IR after block elimination"); print(false); } |
257 #endif | 259 #endif |
258 } | 260 } |
259 } | 261 } |
262 } | |
263 | |
264 void IR::eliminate_null_checks() { | |
265 Optimizer opt(this); | |
260 if (EliminateNullChecks) { | 266 if (EliminateNullChecks) { |
261 opt.eliminate_null_checks(); | 267 opt.eliminate_null_checks(); |
262 #ifndef PRODUCT | 268 #ifndef PRODUCT |
263 if (PrintCFG || PrintCFG1) { tty->print_cr("CFG after null check elimination"); print(true); } | 269 if (PrintCFG || PrintCFG1) { tty->print_cr("CFG after null check elimination"); print(true); } |
264 if (PrintIR || PrintIR1 ) { tty->print_cr("IR after null check elimination"); print(false); } | 270 if (PrintIR || PrintIR1 ) { tty->print_cr("IR after null check elimination"); print(false); } |
427 BitMap _dominator_blocks; // temproary BitMap used for computation of dominator | 433 BitMap _dominator_blocks; // temproary BitMap used for computation of dominator |
428 intArray _forward_branches; // number of incoming forward branches for each block | 434 intArray _forward_branches; // number of incoming forward branches for each block |
429 BlockList _loop_end_blocks; // list of all loop end blocks collected during count_edges | 435 BlockList _loop_end_blocks; // list of all loop end blocks collected during count_edges |
430 BitMap2D _loop_map; // two-dimensional bit set: a bit is set if a block is contained in a loop | 436 BitMap2D _loop_map; // two-dimensional bit set: a bit is set if a block is contained in a loop |
431 BlockList _work_list; // temporary list (used in mark_loops and compute_order) | 437 BlockList _work_list; // temporary list (used in mark_loops and compute_order) |
438 BlockList _loop_headers; | |
432 | 439 |
433 Compilation* _compilation; | 440 Compilation* _compilation; |
434 | 441 |
435 // accessors for _visited_blocks and _active_blocks | 442 // accessors for _visited_blocks and _active_blocks |
436 void init_visited() { _active_blocks.clear(); _visited_blocks.clear(); } | 443 void init_visited() { _active_blocks.clear(); _visited_blocks.clear(); } |
592 if (cur->is_set(BlockBegin::linear_scan_loop_header_flag)) { | 599 if (cur->is_set(BlockBegin::linear_scan_loop_header_flag)) { |
593 assert(cur->loop_index() == -1, "cannot set loop-index twice"); | 600 assert(cur->loop_index() == -1, "cannot set loop-index twice"); |
594 TRACE_LINEAR_SCAN(3, tty->print_cr("Block B%d is loop header of loop %d", cur->block_id(), _num_loops)); | 601 TRACE_LINEAR_SCAN(3, tty->print_cr("Block B%d is loop header of loop %d", cur->block_id(), _num_loops)); |
595 | 602 |
596 cur->set_loop_index(_num_loops); | 603 cur->set_loop_index(_num_loops); |
604 _loop_headers.append(cur); | |
597 _num_loops++; | 605 _num_loops++; |
598 } | 606 } |
599 | 607 |
600 TRACE_LINEAR_SCAN(3, tty->print_cr("Finished count_edges for block B%d", cur->block_id())); | 608 TRACE_LINEAR_SCAN(3, tty->print_cr("Finished count_edges for block B%d", cur->block_id())); |
601 } | 609 } |
653 for (int i = _num_loops - 1; i >= 0; i--) { | 661 for (int i = _num_loops - 1; i >= 0; i--) { |
654 if (is_block_in_loop(i, start_block)) { | 662 if (is_block_in_loop(i, start_block)) { |
655 // loop i contains the entry block of the method | 663 // loop i contains the entry block of the method |
656 // -> this is not a natural loop, so ignore it | 664 // -> this is not a natural loop, so ignore it |
657 TRACE_LINEAR_SCAN(2, tty->print_cr("Loop %d is non-natural, so it is ignored", i)); | 665 TRACE_LINEAR_SCAN(2, tty->print_cr("Loop %d is non-natural, so it is ignored", i)); |
666 | |
667 BlockBegin *loop_header = _loop_headers.at(i); | |
668 assert(loop_header->is_set(BlockBegin::linear_scan_loop_header_flag), "Must be loop header"); | |
669 | |
670 for (int j = 0; j < loop_header->number_of_preds(); j++) { | |
671 BlockBegin *pred = loop_header->pred_at(j); | |
672 pred->clear(BlockBegin::linear_scan_loop_end_flag); | |
673 } | |
674 | |
675 loop_header->clear(BlockBegin::linear_scan_loop_header_flag); | |
658 | 676 |
659 for (int block_id = _max_block_id - 1; block_id >= 0; block_id--) { | 677 for (int block_id = _max_block_id - 1; block_id >= 0; block_id--) { |
660 clear_block_in_loop(i, block_id); | 678 clear_block_in_loop(i, block_id); |
661 } | 679 } |
662 _iterative_dominators = true; | 680 _iterative_dominators = true; |
727 TRACE_LINEAR_SCAN(4, tty->print_cr("DOM: initializing dominator of B%d to B%d", cur->block_id(), parent->block_id())); | 745 TRACE_LINEAR_SCAN(4, tty->print_cr("DOM: initializing dominator of B%d to B%d", cur->block_id(), parent->block_id())); |
728 cur->set_dominator(parent); | 746 cur->set_dominator(parent); |
729 | 747 |
730 } else if (!(cur->is_set(BlockBegin::linear_scan_loop_header_flag) && parent->is_set(BlockBegin::linear_scan_loop_end_flag))) { | 748 } else if (!(cur->is_set(BlockBegin::linear_scan_loop_header_flag) && parent->is_set(BlockBegin::linear_scan_loop_end_flag))) { |
731 TRACE_LINEAR_SCAN(4, tty->print_cr("DOM: computing dominator of B%d: common dominator of B%d and B%d is B%d", cur->block_id(), parent->block_id(), cur->dominator()->block_id(), common_dominator(cur->dominator(), parent)->block_id())); | 749 TRACE_LINEAR_SCAN(4, tty->print_cr("DOM: computing dominator of B%d: common dominator of B%d and B%d is B%d", cur->block_id(), parent->block_id(), cur->dominator()->block_id(), common_dominator(cur->dominator(), parent)->block_id())); |
732 assert(cur->number_of_preds() > 1, ""); | 750 // Does not hold for exception blocks |
751 assert(cur->number_of_preds() > 1 || cur->is_set(BlockBegin::exception_entry_flag), ""); | |
733 cur->set_dominator(common_dominator(cur->dominator(), parent)); | 752 cur->set_dominator(common_dominator(cur->dominator(), parent)); |
753 } | |
754 | |
755 // Additional edge to xhandler of all our successors | |
756 // range check elimination needs that the state at the end of a | |
757 // block be valid in every block it dominates so cur must dominate | |
758 // the exception handlers of its successors. | |
759 int num_cur_xhandler = cur->number_of_exception_handlers(); | |
760 for (int j = 0; j < num_cur_xhandler; j++) { | |
761 BlockBegin* xhandler = cur->exception_handler_at(j); | |
762 compute_dominator(xhandler, parent); | |
734 } | 763 } |
735 } | 764 } |
736 | 765 |
737 | 766 |
738 int ComputeLinearScanOrder::compute_weight(BlockBegin* cur) { | 767 int ComputeLinearScanOrder::compute_weight(BlockBegin* cur) { |
896 } | 925 } |
897 } | 926 } |
898 num_sux = cur->number_of_exception_handlers(); | 927 num_sux = cur->number_of_exception_handlers(); |
899 for (i = 0; i < num_sux; i++) { | 928 for (i = 0; i < num_sux; i++) { |
900 BlockBegin* sux = cur->exception_handler_at(i); | 929 BlockBegin* sux = cur->exception_handler_at(i); |
901 compute_dominator(sux, cur); | |
902 if (ready_for_processing(sux)) { | 930 if (ready_for_processing(sux)) { |
903 sort_into_work_list(sux); | 931 sort_into_work_list(sux); |
904 } | 932 } |
905 } | 933 } |
906 } while (_work_list.length() > 0); | 934 } while (_work_list.length() > 0); |
916 for (int i = 1; i < num_blocks; i++) { | 944 for (int i = 1; i < num_blocks; i++) { |
917 BlockBegin* block = _linear_scan_order->at(i); | 945 BlockBegin* block = _linear_scan_order->at(i); |
918 | 946 |
919 BlockBegin* dominator = block->pred_at(0); | 947 BlockBegin* dominator = block->pred_at(0); |
920 int num_preds = block->number_of_preds(); | 948 int num_preds = block->number_of_preds(); |
921 for (int i = 1; i < num_preds; i++) { | 949 |
922 dominator = common_dominator(dominator, block->pred_at(i)); | 950 TRACE_LINEAR_SCAN(4, tty->print_cr("DOM: Processing B%d", block->block_id())); |
951 | |
952 for (int j = 0; j < num_preds; j++) { | |
953 | |
954 BlockBegin *pred = block->pred_at(j); | |
955 TRACE_LINEAR_SCAN(4, tty->print_cr(" DOM: Subrocessing B%d", pred->block_id())); | |
956 | |
957 if (block->is_set(BlockBegin::exception_entry_flag)) { | |
958 dominator = common_dominator(dominator, pred); | |
959 int num_pred_preds = pred->number_of_preds(); | |
960 for (int k = 0; k < num_pred_preds; k++) { | |
961 dominator = common_dominator(dominator, pred->pred_at(k)); | |
962 } | |
963 } else { | |
964 dominator = common_dominator(dominator, pred); | |
965 } | |
923 } | 966 } |
924 | 967 |
925 if (dominator != block->dominator()) { | 968 if (dominator != block->dominator()) { |
926 TRACE_LINEAR_SCAN(4, tty->print_cr("DOM: updating dominator of B%d from B%d to B%d", block->block_id(), block->dominator()->block_id(), dominator->block_id())); | 969 TRACE_LINEAR_SCAN(4, tty->print_cr("DOM: updating dominator of B%d from B%d to B%d", block->block_id(), block->dominator()->block_id(), dominator->block_id())); |
927 | 970 |
944 } while (compute_dominators_iter()); | 987 } while (compute_dominators_iter()); |
945 } | 988 } |
946 | 989 |
947 // check that dominators are correct | 990 // check that dominators are correct |
948 assert(!compute_dominators_iter(), "fix point not reached"); | 991 assert(!compute_dominators_iter(), "fix point not reached"); |
992 | |
993 // Add Blocks to dominates-Array | |
994 int num_blocks = _linear_scan_order->length(); | |
995 for (int i = 0; i < num_blocks; i++) { | |
996 BlockBegin* block = _linear_scan_order->at(i); | |
997 | |
998 BlockBegin *dom = block->dominator(); | |
999 if (dom) { | |
1000 assert(dom->dominator_depth() != -1, "Dominator must have been visited before"); | |
1001 dom->dominates()->append(block); | |
1002 block->set_dominator_depth(dom->dominator_depth() + 1); | |
1003 } else { | |
1004 block->set_dominator_depth(0); | |
1005 } | |
1006 } | |
949 } | 1007 } |
950 | 1008 |
951 | 1009 |
952 #ifndef PRODUCT | 1010 #ifndef PRODUCT |
953 void ComputeLinearScanOrder::print_blocks() { | 1011 void ComputeLinearScanOrder::print_blocks() { |
1030 int j; | 1088 int j; |
1031 for (j = cur->number_of_sux() - 1; j >= 0; j--) { | 1089 for (j = cur->number_of_sux() - 1; j >= 0; j--) { |
1032 BlockBegin* sux = cur->sux_at(j); | 1090 BlockBegin* sux = cur->sux_at(j); |
1033 | 1091 |
1034 assert(sux->linear_scan_number() >= 0 && sux->linear_scan_number() == _linear_scan_order->index_of(sux), "incorrect linear_scan_number"); | 1092 assert(sux->linear_scan_number() >= 0 && sux->linear_scan_number() == _linear_scan_order->index_of(sux), "incorrect linear_scan_number"); |
1035 if (!cur->is_set(BlockBegin::linear_scan_loop_end_flag)) { | 1093 if (!sux->is_set(BlockBegin::backward_branch_target_flag)) { |
1036 assert(cur->linear_scan_number() < sux->linear_scan_number(), "invalid order"); | 1094 assert(cur->linear_scan_number() < sux->linear_scan_number(), "invalid order"); |
1037 } | 1095 } |
1038 if (cur->loop_depth() == sux->loop_depth()) { | 1096 if (cur->loop_depth() == sux->loop_depth()) { |
1039 assert(cur->loop_index() == sux->loop_index() || sux->is_set(BlockBegin::linear_scan_loop_header_flag), "successing blocks with same loop depth must have same loop index"); | 1097 assert(cur->loop_index() == sux->loop_index() || sux->is_set(BlockBegin::linear_scan_loop_header_flag), "successing blocks with same loop depth must have same loop index"); |
1040 } | 1098 } |
1042 | 1100 |
1043 for (j = cur->number_of_preds() - 1; j >= 0; j--) { | 1101 for (j = cur->number_of_preds() - 1; j >= 0; j--) { |
1044 BlockBegin* pred = cur->pred_at(j); | 1102 BlockBegin* pred = cur->pred_at(j); |
1045 | 1103 |
1046 assert(pred->linear_scan_number() >= 0 && pred->linear_scan_number() == _linear_scan_order->index_of(pred), "incorrect linear_scan_number"); | 1104 assert(pred->linear_scan_number() >= 0 && pred->linear_scan_number() == _linear_scan_order->index_of(pred), "incorrect linear_scan_number"); |
1047 if (!cur->is_set(BlockBegin::linear_scan_loop_header_flag)) { | 1105 if (!cur->is_set(BlockBegin::backward_branch_target_flag)) { |
1048 assert(cur->linear_scan_number() > pred->linear_scan_number(), "invalid order"); | 1106 assert(cur->linear_scan_number() > pred->linear_scan_number(), "invalid order"); |
1049 } | 1107 } |
1050 if (cur->loop_depth() == pred->loop_depth()) { | 1108 if (cur->loop_depth() == pred->loop_depth()) { |
1051 assert(cur->loop_index() == pred->loop_index() || cur->is_set(BlockBegin::linear_scan_loop_header_flag), "successing blocks with same loop depth must have same loop index"); | 1109 assert(cur->loop_index() == pred->loop_index() || cur->is_set(BlockBegin::linear_scan_loop_header_flag), "successing blocks with same loop depth must have same loop index"); |
1052 } | 1110 } |
1058 if (i == 0) { | 1116 if (i == 0) { |
1059 assert(cur->dominator() == NULL, "first block has no dominator"); | 1117 assert(cur->dominator() == NULL, "first block has no dominator"); |
1060 } else { | 1118 } else { |
1061 assert(cur->dominator() != NULL, "all but first block must have dominator"); | 1119 assert(cur->dominator() != NULL, "all but first block must have dominator"); |
1062 } | 1120 } |
1063 assert(cur->number_of_preds() != 1 || cur->dominator() == cur->pred_at(0), "Single predecessor must also be dominator"); | 1121 // Assertion does not hold for exception handlers |
1122 assert(cur->number_of_preds() != 1 || cur->dominator() == cur->pred_at(0) || cur->is_set(BlockBegin::exception_entry_flag), "Single predecessor must also be dominator"); | |
1064 } | 1123 } |
1065 | 1124 |
1066 // check that all loops are continuous | 1125 // check that all loops are continuous |
1067 for (int loop_idx = 0; loop_idx < _num_loops; loop_idx++) { | 1126 for (int loop_idx = 0; loop_idx < _num_loops; loop_idx++) { |
1068 int block_idx = 0; | 1127 int block_idx = 0; |
1247 preds->append(block); | 1306 preds->append(block); |
1248 } | 1307 } |
1249 } | 1308 } |
1250 }; | 1309 }; |
1251 | 1310 |
1311 class VerifyBlockBeginField : public BlockClosure { | |
1312 | |
1313 public: | |
1314 | |
1315 virtual void block_do(BlockBegin *block) { | |
1316 for ( Instruction *cur = block; cur != NULL; cur = cur->next()) { | |
1317 assert(cur->block() == block, "Block begin is not correct"); | |
1318 } | |
1319 } | |
1320 }; | |
1321 | |
1252 void IR::verify() { | 1322 void IR::verify() { |
1253 #ifdef ASSERT | 1323 #ifdef ASSERT |
1254 PredecessorValidator pv(this); | 1324 PredecessorValidator pv(this); |
1325 VerifyBlockBeginField verifier; | |
1326 this->iterate_postorder(&verifier); | |
1255 #endif | 1327 #endif |
1256 } | 1328 } |
1257 | 1329 |
1258 #endif // PRODUCT | 1330 #endif // PRODUCT |
1259 | 1331 |