1 /* |
1 /* |
2 * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
29 #include "c1/c1_ValueSet.hpp" |
29 #include "c1/c1_ValueSet.hpp" |
30 #include "c1/c1_ValueStack.hpp" |
30 #include "c1/c1_ValueStack.hpp" |
31 #include "utilities/bitMap.inline.hpp" |
31 #include "utilities/bitMap.inline.hpp" |
32 #include "compiler/compileLog.hpp" |
32 #include "compiler/compileLog.hpp" |
33 |
33 |
34 define_array(ValueSetArray, ValueSet*); |
34 typedef GrowableArray<ValueSet*> ValueSetList; |
35 define_stack(ValueSetList, ValueSetArray); |
|
36 |
|
37 |
35 |
38 Optimizer::Optimizer(IR* ir) { |
36 Optimizer::Optimizer(IR* ir) { |
39 assert(ir->is_valid(), "IR must be valid"); |
37 assert(ir->is_valid(), "IR must be valid"); |
40 _ir = ir; |
38 _ir = ir; |
41 } |
39 } |
581 void iterate_all(); |
579 void iterate_all(); |
582 void iterate_one(BlockBegin* block); |
580 void iterate_one(BlockBegin* block); |
583 |
581 |
584 ValueSet* state() { return _set; } |
582 ValueSet* state() { return _set; } |
585 void set_state_from (ValueSet* state) { _set->set_from(state); } |
583 void set_state_from (ValueSet* state) { _set->set_from(state); } |
586 ValueSet* state_for (BlockBegin* block) { return _block_states[block->block_id()]; } |
584 ValueSet* state_for (BlockBegin* block) { return _block_states.at(block->block_id()); } |
587 void set_state_for (BlockBegin* block, ValueSet* stack) { _block_states[block->block_id()] = stack; } |
585 void set_state_for (BlockBegin* block, ValueSet* stack) { _block_states.at_put(block->block_id(), stack); } |
588 // Returns true if caused a change in the block's state. |
586 // Returns true if caused a change in the block's state. |
589 bool merge_state_for(BlockBegin* block, |
587 bool merge_state_for(BlockBegin* block, |
590 ValueSet* incoming_state); |
588 ValueSet* incoming_state); |
591 |
589 |
592 public: |
590 public: |
593 // constructor |
591 // constructor |
594 NullCheckEliminator(Optimizer* opt) |
592 NullCheckEliminator(Optimizer* opt) |
595 : _opt(opt) |
593 : _opt(opt) |
596 , _set(new ValueSet()) |
594 , _set(new ValueSet()) |
597 , _last_explicit_null_check(NULL) |
595 , _last_explicit_null_check(NULL) |
598 , _block_states(BlockBegin::number_of_blocks(), NULL) |
596 , _block_states(BlockBegin::number_of_blocks(), BlockBegin::number_of_blocks(), NULL) |
599 , _work_list(new BlockList()) { |
597 , _work_list(new BlockList()) { |
600 _visitable_instructions = new ValueSet(); |
598 _visitable_instructions = new ValueSet(); |
601 _visitor.set_eliminator(this); |
599 _visitor.set_eliminator(this); |
602 CompileLog* log = _opt->ir()->compilation()->log(); |
600 CompileLog* log = _opt->ir()->compilation()->log(); |
603 if (log != NULL) |
601 if (log != NULL) |
1162 |
1160 |
1163 // walk over the graph looking for exception |
1161 // walk over the graph looking for exception |
1164 // handlers and iterate over them as well |
1162 // handlers and iterate over them as well |
1165 int nblocks = BlockBegin::number_of_blocks(); |
1163 int nblocks = BlockBegin::number_of_blocks(); |
1166 BlockList blocks(nblocks); |
1164 BlockList blocks(nblocks); |
1167 boolArray visited_block(nblocks, false); |
1165 boolArray visited_block(nblocks, nblocks, false); |
1168 |
1166 |
1169 blocks.push(ir()->start()); |
1167 blocks.push(ir()->start()); |
1170 visited_block[ir()->start()->block_id()] = true; |
1168 visited_block.at_put(ir()->start()->block_id(), true); |
1171 for (int i = 0; i < blocks.length(); i++) { |
1169 for (int i = 0; i < blocks.length(); i++) { |
1172 BlockBegin* b = blocks[i]; |
1170 BlockBegin* b = blocks.at(i); |
1173 // exception handlers need to be treated as additional roots |
1171 // exception handlers need to be treated as additional roots |
1174 for (int e = b->number_of_exception_handlers(); e-- > 0; ) { |
1172 for (int e = b->number_of_exception_handlers(); e-- > 0; ) { |
1175 BlockBegin* excp = b->exception_handler_at(e); |
1173 BlockBegin* excp = b->exception_handler_at(e); |
1176 int id = excp->block_id(); |
1174 int id = excp->block_id(); |
1177 if (!visited_block[id]) { |
1175 if (!visited_block.at(id)) { |
1178 blocks.push(excp); |
1176 blocks.push(excp); |
1179 visited_block[id] = true; |
1177 visited_block.at_put(id, true); |
1180 nce.iterate(excp); |
1178 nce.iterate(excp); |
1181 } |
1179 } |
1182 } |
1180 } |
1183 // traverse successors |
1181 // traverse successors |
1184 BlockEnd *end = b->end(); |
1182 BlockEnd *end = b->end(); |
1185 for (int s = end->number_of_sux(); s-- > 0; ) { |
1183 for (int s = end->number_of_sux(); s-- > 0; ) { |
1186 BlockBegin* next = end->sux_at(s); |
1184 BlockBegin* next = end->sux_at(s); |
1187 int id = next->block_id(); |
1185 int id = next->block_id(); |
1188 if (!visited_block[id]) { |
1186 if (!visited_block.at(id)) { |
1189 blocks.push(next); |
1187 blocks.push(next); |
1190 visited_block[id] = true; |
1188 visited_block.at_put(id, true); |
1191 } |
1189 } |
1192 } |
1190 } |
1193 } |
1191 } |
1194 |
1192 |
1195 |
1193 |