| 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 |