Mercurial > hg > truffle
comparison src/share/vm/c1/c1_Instruction.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 | 37c18711a0df |
children | d13d7aba8c12 |
comparison
equal
deleted
inserted
replaced
8780:98f3af397705 | 8860:46f6f063b272 |
---|---|
32 | 32 |
33 | 33 |
34 // Implementation of Instruction | 34 // Implementation of Instruction |
35 | 35 |
36 | 36 |
37 int Instruction::dominator_depth() { | |
38 int result = -1; | |
39 if (block()) { | |
40 result = block()->dominator_depth(); | |
41 } | |
42 assert(result != -1 || this->as_Local(), "Only locals have dominator depth -1"); | |
43 return result; | |
44 } | |
45 | |
37 Instruction::Condition Instruction::mirror(Condition cond) { | 46 Instruction::Condition Instruction::mirror(Condition cond) { |
38 switch (cond) { | 47 switch (cond) { |
39 case eql: return eql; | 48 case eql: return eql; |
40 case neq: return neq; | 49 case neq: return neq; |
41 case lss: return gtr; | 50 case lss: return gtr; |
42 case leq: return geq; | 51 case leq: return geq; |
43 case gtr: return lss; | 52 case gtr: return lss; |
44 case geq: return leq; | 53 case geq: return leq; |
54 case aeq: return beq; | |
55 case beq: return aeq; | |
45 } | 56 } |
46 ShouldNotReachHere(); | 57 ShouldNotReachHere(); |
47 return eql; | 58 return eql; |
48 } | 59 } |
49 | 60 |
54 case neq: return eql; | 65 case neq: return eql; |
55 case lss: return geq; | 66 case lss: return geq; |
56 case leq: return gtr; | 67 case leq: return gtr; |
57 case gtr: return leq; | 68 case gtr: return leq; |
58 case geq: return lss; | 69 case geq: return lss; |
70 case aeq: assert(false, "Above equal cannot be negated"); | |
71 case beq: assert(false, "Below equal cannot be negated"); | |
59 } | 72 } |
60 ShouldNotReachHere(); | 73 ShouldNotReachHere(); |
61 return eql; | 74 return eql; |
62 } | 75 } |
63 | 76 |
68 } else { | 81 } else { |
69 _exception_state = NULL; | 82 _exception_state = NULL; |
70 } | 83 } |
71 } | 84 } |
72 | 85 |
73 | 86 // Prev without need to have BlockBegin |
74 Instruction* Instruction::prev(BlockBegin* block) { | 87 Instruction* Instruction::prev() { |
75 Instruction* p = NULL; | 88 Instruction* p = NULL; |
76 Instruction* q = block; | 89 Instruction* q = block(); |
77 while (q != this) { | 90 while (q != this) { |
78 assert(q != NULL, "this is not in the block's instruction list"); | 91 assert(q != NULL, "this is not in the block's instruction list"); |
79 p = q; q = q->next(); | 92 p = q; q = q->next(); |
80 } | 93 } |
81 return p; | 94 return p; |
120 #endif // PRODUCT | 133 #endif // PRODUCT |
121 | 134 |
122 | 135 |
123 // perform constant and interval tests on index value | 136 // perform constant and interval tests on index value |
124 bool AccessIndexed::compute_needs_range_check() { | 137 bool AccessIndexed::compute_needs_range_check() { |
125 Constant* clength = length()->as_Constant(); | 138 |
126 Constant* cindex = index()->as_Constant(); | 139 if (length()) { |
127 if (clength && cindex) { | 140 |
128 IntConstant* l = clength->type()->as_IntConstant(); | 141 Constant* clength = length()->as_Constant(); |
129 IntConstant* i = cindex->type()->as_IntConstant(); | 142 Constant* cindex = index()->as_Constant(); |
130 if (l && i && i->value() < l->value() && i->value() >= 0) { | 143 if (clength && cindex) { |
131 return false; | 144 IntConstant* l = clength->type()->as_IntConstant(); |
132 } | 145 IntConstant* i = cindex->type()->as_IntConstant(); |
133 } | 146 if (l && i && i->value() < l->value() && i->value() >= 0) { |
147 return false; | |
148 } | |
149 } | |
150 } | |
151 | |
152 if (!this->check_flag(NeedsRangeCheckFlag)) { | |
153 return false; | |
154 } | |
155 | |
134 return true; | 156 return true; |
135 } | 157 } |
136 | 158 |
137 | 159 |
138 ciType* Local::exact_type() const { | 160 ciType* Local::exact_type() const { |
629 | 651 |
630 // In general it is not possible to calculate a value for the field "depth_first_number" | 652 // In general it is not possible to calculate a value for the field "depth_first_number" |
631 // of the inserted block, without recomputing the values of the other blocks | 653 // of the inserted block, without recomputing the values of the other blocks |
632 // in the CFG. Therefore the value of "depth_first_number" in BlockBegin becomes meaningless. | 654 // in the CFG. Therefore the value of "depth_first_number" in BlockBegin becomes meaningless. |
633 BlockBegin* BlockBegin::insert_block_between(BlockBegin* sux) { | 655 BlockBegin* BlockBegin::insert_block_between(BlockBegin* sux) { |
634 BlockBegin* new_sux = new BlockBegin(end()->state()->bci()); | 656 int bci = sux->bci(); |
657 // critical edge splitting may introduce a goto after a if and array | |
658 // bound check elimination may insert a predicate between the if and | |
659 // goto. The bci of the goto can't be the one of the if otherwise | |
660 // the state and bci are inconsistent and a deoptimization triggered | |
661 // by the predicate would lead to incorrect execution/a crash. | |
662 BlockBegin* new_sux = new BlockBegin(bci); | |
635 | 663 |
636 // mark this block (special treatment when block order is computed) | 664 // mark this block (special treatment when block order is computed) |
637 new_sux->set(critical_edge_split_flag); | 665 new_sux->set(critical_edge_split_flag); |
638 | 666 |
639 // This goto is not a safepoint. | 667 // This goto is not a safepoint. |
640 Goto* e = new Goto(sux, false); | 668 Goto* e = new Goto(sux, false); |
641 new_sux->set_next(e, end()->state()->bci()); | 669 new_sux->set_next(e, bci); |
642 new_sux->set_end(e); | 670 new_sux->set_end(e); |
643 // setup states | 671 // setup states |
644 ValueStack* s = end()->state(); | 672 ValueStack* s = end()->state(); |
645 new_sux->set_state(s->copy()); | 673 new_sux->set_state(s->copy(s->kind(), bci)); |
646 e->set_state(s->copy()); | 674 e->set_state(s->copy(s->kind(), bci)); |
647 assert(new_sux->state()->locals_size() == s->locals_size(), "local size mismatch!"); | 675 assert(new_sux->state()->locals_size() == s->locals_size(), "local size mismatch!"); |
648 assert(new_sux->state()->stack_size() == s->stack_size(), "stack size mismatch!"); | 676 assert(new_sux->state()->stack_size() == s->stack_size(), "stack size mismatch!"); |
649 assert(new_sux->state()->locks_size() == s->locks_size(), "locks size mismatch!"); | 677 assert(new_sux->state()->locks_size() == s->locks_size(), "locks size mismatch!"); |
650 | 678 |
651 // link predecessor to new block | 679 // link predecessor to new block |
958 | 986 |
959 void BlockEnd::set_begin(BlockBegin* begin) { | 987 void BlockEnd::set_begin(BlockBegin* begin) { |
960 BlockList* sux = NULL; | 988 BlockList* sux = NULL; |
961 if (begin != NULL) { | 989 if (begin != NULL) { |
962 sux = begin->successors(); | 990 sux = begin->successors(); |
963 } else if (_begin != NULL) { | 991 } else if (this->begin() != NULL) { |
964 // copy our sux list | 992 // copy our sux list |
965 BlockList* sux = new BlockList(_begin->number_of_sux()); | 993 BlockList* sux = new BlockList(this->begin()->number_of_sux()); |
966 for (int i = 0; i < _begin->number_of_sux(); i++) { | 994 for (int i = 0; i < this->begin()->number_of_sux(); i++) { |
967 sux->append(_begin->sux_at(i)); | 995 sux->append(this->begin()->sux_at(i)); |
968 } | 996 } |
969 } | 997 } |
970 _sux = sux; | 998 _sux = sux; |
971 _begin = begin; | |
972 } | 999 } |
973 | 1000 |
974 | 1001 |
975 void BlockEnd::substitute_sux(BlockBegin* old_sux, BlockBegin* new_sux) { | 1002 void BlockEnd::substitute_sux(BlockBegin* old_sux, BlockBegin* new_sux) { |
976 substitute(*_sux, old_sux, new_sux); | 1003 substitute(*_sux, old_sux, new_sux); |
1006 } else { | 1033 } else { |
1007 return _block->number_of_preds(); | 1034 return _block->number_of_preds(); |
1008 } | 1035 } |
1009 } | 1036 } |
1010 | 1037 |
1011 | 1038 #ifdef ASSERT |
1039 // Constructor of Assert | |
1040 Assert::Assert(Value x, Condition cond, bool unordered_is_true, Value y) : Instruction(illegalType) | |
1041 , _x(x) | |
1042 , _cond(cond) | |
1043 , _y(y) | |
1044 { | |
1045 set_flag(UnorderedIsTrueFlag, unordered_is_true); | |
1046 assert(x->type()->tag() == y->type()->tag(), "types must match"); | |
1047 pin(); | |
1048 | |
1049 stringStream strStream; | |
1050 Compilation::current()->method()->print_name(&strStream); | |
1051 | |
1052 stringStream strStream1; | |
1053 InstructionPrinter ip1(1, &strStream1); | |
1054 ip1.print_instr(x); | |
1055 | |
1056 stringStream strStream2; | |
1057 InstructionPrinter ip2(1, &strStream2); | |
1058 ip2.print_instr(y); | |
1059 | |
1060 stringStream ss; | |
1061 ss.print("Assertion %s %s %s in method %s", strStream1.as_string(), ip2.cond_name(cond), strStream2.as_string(), strStream.as_string()); | |
1062 | |
1063 _message = ss.as_string(); | |
1064 } | |
1065 #endif | |
1066 | |
1067 void RangeCheckPredicate::check_state() { | |
1068 assert(state()->kind() != ValueStack::EmptyExceptionState && state()->kind() != ValueStack::ExceptionState, "will deopt with empty state"); | |
1069 } | |
1012 | 1070 |
1013 void ProfileInvoke::state_values_do(ValueVisitor* f) { | 1071 void ProfileInvoke::state_values_do(ValueVisitor* f) { |
1014 if (state() != NULL) state()->values_do(f); | 1072 if (state() != NULL) state()->values_do(f); |
1015 } | 1073 } |