OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/flow_graph_type_propagator.h" | 5 #include "vm/flow_graph_type_propagator.h" |
6 | 6 |
7 #include "vm/cha.h" | 7 #include "vm/cha.h" |
8 #include "vm/bit_vector.h" | 8 #include "vm/bit_vector.h" |
9 #include "vm/il_printer.h" | 9 #include "vm/il_printer.h" |
10 #include "vm/regexp_assembler.h" | 10 #include "vm/regexp_assembler.h" |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 GotoInstr* goto_instr = block->last_instruction()->AsGoto(); | 142 GotoInstr* goto_instr = block->last_instruction()->AsGoto(); |
143 if (goto_instr != NULL) { | 143 if (goto_instr != NULL) { |
144 JoinEntryInstr* join = goto_instr->successor(); | 144 JoinEntryInstr* join = goto_instr->successor(); |
145 intptr_t pred_index = join->IndexOfPredecessor(block); | 145 intptr_t pred_index = join->IndexOfPredecessor(block); |
146 ASSERT(pred_index >= 0); | 146 ASSERT(pred_index >= 0); |
147 for (PhiIterator it(join); !it.Done(); it.Advance()) { | 147 for (PhiIterator it(join); !it.Done(); it.Advance()) { |
148 VisitValue(it.Current()->InputAt(pred_index)); | 148 VisitValue(it.Current()->InputAt(pred_index)); |
149 } | 149 } |
150 } | 150 } |
151 | 151 |
152 HandleBranchOnStrictCompare(block); | |
153 | |
154 for (intptr_t i = 0; i < block->dominated_blocks().length(); ++i) { | 152 for (intptr_t i = 0; i < block->dominated_blocks().length(); ++i) { |
155 PropagateRecursive(block->dominated_blocks()[i]); | 153 PropagateRecursive(block->dominated_blocks()[i]); |
156 } | 154 } |
157 | 155 |
158 RollbackTo(rollback_point); | 156 RollbackTo(rollback_point); |
159 } | 157 } |
160 | 158 |
161 | 159 |
162 void FlowGraphTypePropagator::HandleBranchOnStrictCompare( | |
163 BlockEntryInstr* block) { | |
164 BranchInstr* branch = block->last_instruction()->AsBranch(); | |
165 if (branch == NULL) { | |
166 return; | |
167 } | |
168 | |
169 StrictCompareInstr* compare = branch->comparison()->AsStrictCompare(); | |
170 if ((compare == NULL) || !compare->right()->BindsToConstant()) { | |
171 return; | |
172 } | |
173 | |
174 const intptr_t rollback_point = rollback_.length(); | |
175 | |
176 Definition* defn = compare->left()->definition(); | |
177 const Object& right = compare->right()->BoundConstant(); | |
178 intptr_t cid = right.GetClassId(); | |
179 | |
180 if (defn->IsLoadClassId() && right.IsSmi()) { | |
181 defn = defn->AsLoadClassId()->object()->definition(); | |
182 cid = Smi::Cast(right).Value(); | |
183 } | |
184 | |
185 if (!CheckClassInstr::IsImmutableClassId(cid)) { | |
186 if ((cid == kOneByteStringCid) || (cid == kTwoByteStringCid)) { | |
187 SetTypeOf(defn, ZoneCompileType::Wrap(CompileType::String())); | |
188 PropagateRecursive((compare->kind() == Token::kEQ_STRICT) ? | |
189 branch->true_successor() : branch->false_successor()); | |
190 RollbackTo(rollback_point); | |
191 } | |
192 return; | |
193 } | |
194 | |
195 if (compare->kind() == Token::kEQ_STRICT) { | |
196 if (cid == kNullCid) { | |
197 branch->set_constrained_type(MarkNonNullable(defn)); | |
198 PropagateRecursive(branch->false_successor()); | |
199 } | |
200 | |
201 SetCid(defn, cid); | |
202 PropagateRecursive(branch->true_successor()); | |
203 } else if (compare->kind() == Token::kNE_STRICT) { | |
204 if (cid == kNullCid) { | |
205 branch->set_constrained_type(MarkNonNullable(defn)); | |
206 PropagateRecursive(branch->true_successor()); | |
207 } | |
208 | |
209 SetCid(defn, cid); | |
210 PropagateRecursive(branch->false_successor()); | |
211 } | |
212 | |
213 RollbackTo(rollback_point); | |
214 } | |
215 | |
216 | |
217 void FlowGraphTypePropagator::RollbackTo(intptr_t rollback_point) { | 160 void FlowGraphTypePropagator::RollbackTo(intptr_t rollback_point) { |
218 for (intptr_t i = rollback_.length() - 1; i >= rollback_point; i--) { | 161 for (intptr_t i = rollback_.length() - 1; i >= rollback_point; i--) { |
219 types_[rollback_[i].index()] = rollback_[i].type(); | 162 types_[rollback_[i].index()] = rollback_[i].type(); |
220 } | 163 } |
221 rollback_.TruncateTo(rollback_point); | 164 rollback_.TruncateTo(rollback_point); |
222 } | 165 } |
223 | 166 |
224 | 167 |
225 CompileType* FlowGraphTypePropagator::TypeOf(Definition* def) { | 168 CompileType* FlowGraphTypePropagator::TypeOf(Definition* def) { |
226 const intptr_t index = def->ssa_temp_index(); | 169 const intptr_t index = def->ssa_temp_index(); |
(...skipping 1220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1447 CompileType MergedMathInstr::ComputeType() const { | 1390 CompileType MergedMathInstr::ComputeType() const { |
1448 return CompileType::Dynamic(); | 1391 return CompileType::Dynamic(); |
1449 } | 1392 } |
1450 | 1393 |
1451 | 1394 |
1452 CompileType ExtractNthOutputInstr::ComputeType() const { | 1395 CompileType ExtractNthOutputInstr::ComputeType() const { |
1453 return CompileType::FromCid(definition_cid_); | 1396 return CompileType::FromCid(definition_cid_); |
1454 } | 1397 } |
1455 | 1398 |
1456 } // namespace dart | 1399 } // namespace dart |
OLD | NEW |