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 #ifndef VM_INTERMEDIATE_LANGUAGE_H_ | 5 #ifndef VM_INTERMEDIATE_LANGUAGE_H_ |
6 #define VM_INTERMEDIATE_LANGUAGE_H_ | 6 #define VM_INTERMEDIATE_LANGUAGE_H_ |
7 | 7 |
8 #include "vm/allocation.h" | 8 #include "vm/allocation.h" |
9 #include "vm/ast.h" | 9 #include "vm/ast.h" |
10 #include "vm/growable_array.h" | 10 #include "vm/growable_array.h" |
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
416 | 416 |
417 // Instructions. | 417 // Instructions. |
418 | 418 |
419 // M is a single argument macro. It is applied to each concrete instruction | 419 // M is a single argument macro. It is applied to each concrete instruction |
420 // type name. The concrete instruction classes are the name with Instr | 420 // type name. The concrete instruction classes are the name with Instr |
421 // concatenated. | 421 // concatenated. |
422 #define FOR_EACH_INSTRUCTION(M) \ | 422 #define FOR_EACH_INSTRUCTION(M) \ |
423 M(GraphEntry) \ | 423 M(GraphEntry) \ |
424 M(JoinEntry) \ | 424 M(JoinEntry) \ |
425 M(TargetEntry) \ | 425 M(TargetEntry) \ |
426 M(IndirectEntry) \ | |
426 M(CatchBlockEntry) \ | 427 M(CatchBlockEntry) \ |
427 M(Phi) \ | 428 M(Phi) \ |
428 M(Redefinition) \ | 429 M(Redefinition) \ |
429 M(Parameter) \ | 430 M(Parameter) \ |
430 M(ParallelMove) \ | 431 M(ParallelMove) \ |
431 M(PushArgument) \ | 432 M(PushArgument) \ |
432 M(Return) \ | 433 M(Return) \ |
433 M(Throw) \ | 434 M(Throw) \ |
434 M(ReThrow) \ | 435 M(ReThrow) \ |
435 M(Goto) \ | 436 M(Goto) \ |
437 M(IndirectGoto) \ | |
436 M(Branch) \ | 438 M(Branch) \ |
437 M(AssertAssignable) \ | 439 M(AssertAssignable) \ |
438 M(AssertBoolean) \ | 440 M(AssertBoolean) \ |
439 M(CurrentContext) \ | 441 M(CurrentContext) \ |
440 M(ClosureCall) \ | 442 M(ClosureCall) \ |
441 M(InstanceCall) \ | 443 M(InstanceCall) \ |
442 M(PolymorphicInstanceCall) \ | 444 M(PolymorphicInstanceCall) \ |
443 M(StaticCall) \ | 445 M(StaticCall) \ |
444 M(LoadLocal) \ | 446 M(LoadLocal) \ |
445 M(PushTemp) \ | 447 M(PushTemp) \ |
446 M(DropTemps) \ | 448 M(DropTemps) \ |
447 M(StoreLocal) \ | 449 M(StoreLocal) \ |
448 M(StrictCompare) \ | 450 M(StrictCompare) \ |
449 M(EqualityCompare) \ | 451 M(EqualityCompare) \ |
450 M(RelationalOp) \ | 452 M(RelationalOp) \ |
451 M(NativeCall) \ | 453 M(NativeCall) \ |
452 M(DebugStepCheck) \ | 454 M(DebugStepCheck) \ |
453 M(LoadIndexed) \ | 455 M(LoadIndexed) \ |
456 M(LoadCodeUnits) \ | |
454 M(StoreIndexed) \ | 457 M(StoreIndexed) \ |
455 M(StoreInstanceField) \ | 458 M(StoreInstanceField) \ |
456 M(InitStaticField) \ | 459 M(InitStaticField) \ |
457 M(LoadStaticField) \ | 460 M(LoadStaticField) \ |
458 M(StoreStaticField) \ | 461 M(StoreStaticField) \ |
459 M(BooleanNegate) \ | 462 M(BooleanNegate) \ |
460 M(InstanceOf) \ | 463 M(InstanceOf) \ |
461 M(CreateArray) \ | 464 M(CreateArray) \ |
462 M(AllocateObject) \ | 465 M(AllocateObject) \ |
463 M(LoadField) \ | 466 M(LoadField) \ |
(...skipping 23 matching lines...) Expand all Loading... | |
487 M(Constant) \ | 490 M(Constant) \ |
488 M(UnboxedConstant) \ | 491 M(UnboxedConstant) \ |
489 M(CheckEitherNonSmi) \ | 492 M(CheckEitherNonSmi) \ |
490 M(BinaryDoubleOp) \ | 493 M(BinaryDoubleOp) \ |
491 M(MathUnary) \ | 494 M(MathUnary) \ |
492 M(MathMinMax) \ | 495 M(MathMinMax) \ |
493 M(Box) \ | 496 M(Box) \ |
494 M(Unbox) \ | 497 M(Unbox) \ |
495 M(BoxInt64) \ | 498 M(BoxInt64) \ |
496 M(UnboxInt64) \ | 499 M(UnboxInt64) \ |
500 M(CaseInsensitiveCompareUC16) \ | |
497 M(BinaryMintOp) \ | 501 M(BinaryMintOp) \ |
498 M(ShiftMintOp) \ | 502 M(ShiftMintOp) \ |
499 M(UnaryMintOp) \ | 503 M(UnaryMintOp) \ |
500 M(CheckArrayBound) \ | 504 M(CheckArrayBound) \ |
501 M(Constraint) \ | 505 M(Constraint) \ |
502 M(StringToCharCode) \ | 506 M(StringToCharCode) \ |
503 M(StringFromCharCode) \ | 507 M(StringFromCharCode) \ |
504 M(StringInterpolate) \ | 508 M(StringInterpolate) \ |
505 M(InvokeMathCFunction) \ | 509 M(InvokeMathCFunction) \ |
506 M(MergedMath) \ | 510 M(MergedMath) \ |
(...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1151 return const_cast<BlockEntryInstr*>(this); | 1155 return const_cast<BlockEntryInstr*>(this); |
1152 } | 1156 } |
1153 | 1157 |
1154 // Helper to mutate the graph during inlining. This block should be | 1158 // Helper to mutate the graph during inlining. This block should be |
1155 // replaced with new_block as a predecessor of all of this block's | 1159 // replaced with new_block as a predecessor of all of this block's |
1156 // successors. | 1160 // successors. |
1157 void ReplaceAsPredecessorWith(BlockEntryInstr* new_block); | 1161 void ReplaceAsPredecessorWith(BlockEntryInstr* new_block); |
1158 | 1162 |
1159 void set_block_id(intptr_t block_id) { block_id_ = block_id; } | 1163 void set_block_id(intptr_t block_id) { block_id_ = block_id; } |
1160 | 1164 |
1165 intptr_t offset() const { return offset_; } | |
1166 void set_offset(intptr_t offset) { offset_ = offset; } | |
1167 | |
1161 // For all instruction in this block: Remove all inputs (including in the | 1168 // For all instruction in this block: Remove all inputs (including in the |
1162 // environment) from their definition's use lists for all instructions. | 1169 // environment) from their definition's use lists for all instructions. |
1163 void ClearAllInstructions(); | 1170 void ClearAllInstructions(); |
1164 | 1171 |
1165 DEFINE_INSTRUCTION_TYPE_CHECK(BlockEntry) | 1172 DEFINE_INSTRUCTION_TYPE_CHECK(BlockEntry) |
1166 | 1173 |
1167 protected: | 1174 protected: |
1168 BlockEntryInstr(intptr_t block_id, intptr_t try_index) | 1175 BlockEntryInstr(intptr_t block_id, intptr_t try_index) |
1169 : Instruction(Isolate::Current()->GetNextDeoptId()), | 1176 : Instruction(Isolate::Current()->GetNextDeoptId()), |
1170 block_id_(block_id), | 1177 block_id_(block_id), |
1171 try_index_(try_index), | 1178 try_index_(try_index), |
1172 preorder_number_(-1), | 1179 preorder_number_(-1), |
1173 postorder_number_(-1), | 1180 postorder_number_(-1), |
1174 dominator_(NULL), | 1181 dominator_(NULL), |
1175 dominated_blocks_(1), | 1182 dominated_blocks_(1), |
1176 last_instruction_(NULL), | 1183 last_instruction_(NULL), |
1184 offset_(-1), | |
1177 parallel_move_(NULL), | 1185 parallel_move_(NULL), |
1178 loop_info_(NULL) { | 1186 loop_info_(NULL) { |
1179 } | 1187 } |
1180 | 1188 |
1181 private: | 1189 private: |
1182 virtual void RawSetInputAt(intptr_t i, Value* value) { UNREACHABLE(); } | 1190 virtual void RawSetInputAt(intptr_t i, Value* value) { UNREACHABLE(); } |
1183 | 1191 |
1184 virtual void ClearPredecessors() = 0; | 1192 virtual void ClearPredecessors() = 0; |
1185 virtual void AddPredecessor(BlockEntryInstr* predecessor) = 0; | 1193 virtual void AddPredecessor(BlockEntryInstr* predecessor) = 0; |
1186 | 1194 |
1187 void set_dominator(BlockEntryInstr* instr) { dominator_ = instr; } | 1195 void set_dominator(BlockEntryInstr* instr) { dominator_ = instr; } |
1188 | 1196 |
1189 intptr_t block_id_; | 1197 intptr_t block_id_; |
1190 const intptr_t try_index_; | 1198 const intptr_t try_index_; |
1191 intptr_t preorder_number_; | 1199 intptr_t preorder_number_; |
1192 intptr_t postorder_number_; | 1200 intptr_t postorder_number_; |
1193 // Starting and ending lifetime positions for this block. Used by | 1201 // Starting and ending lifetime positions for this block. Used by |
1194 // the linear scan register allocator. | 1202 // the linear scan register allocator. |
1195 intptr_t start_pos_; | 1203 intptr_t start_pos_; |
1196 intptr_t end_pos_; | 1204 intptr_t end_pos_; |
1197 BlockEntryInstr* dominator_; // Immediate dominator, NULL for graph entry. | 1205 BlockEntryInstr* dominator_; // Immediate dominator, NULL for graph entry. |
1198 // TODO(fschneider): Optimize the case of one child to save space. | 1206 // TODO(fschneider): Optimize the case of one child to save space. |
1199 GrowableArray<BlockEntryInstr*> dominated_blocks_; | 1207 GrowableArray<BlockEntryInstr*> dominated_blocks_; |
1200 Instruction* last_instruction_; | 1208 Instruction* last_instruction_; |
1201 | 1209 |
1210 // Offset of this block from the start of the emitted code. | |
1211 intptr_t offset_; | |
1212 | |
1202 // Parallel move that will be used by linear scan register allocator to | 1213 // Parallel move that will be used by linear scan register allocator to |
1203 // connect live ranges at the start of the block. | 1214 // connect live ranges at the start of the block. |
1204 ParallelMoveInstr* parallel_move_; | 1215 ParallelMoveInstr* parallel_move_; |
1205 | 1216 |
1206 // Bit vector containg loop blocks for a loop header indexed by block | 1217 // Bit vector containg loop blocks for a loop header indexed by block |
1207 // preorder number. | 1218 // preorder number. |
1208 BitVector* loop_info_; | 1219 BitVector* loop_info_; |
1209 | 1220 |
1210 DISALLOW_COPY_AND_ASSIGN(BlockEntryInstr); | 1221 DISALLOW_COPY_AND_ASSIGN(BlockEntryInstr); |
1211 }; | 1222 }; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1272 UNREACHABLE(); | 1283 UNREACHABLE(); |
1273 return NULL; | 1284 return NULL; |
1274 } | 1285 } |
1275 virtual intptr_t SuccessorCount() const; | 1286 virtual intptr_t SuccessorCount() const; |
1276 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; | 1287 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; |
1277 | 1288 |
1278 void AddCatchEntry(CatchBlockEntryInstr* entry) { catch_entries_.Add(entry); } | 1289 void AddCatchEntry(CatchBlockEntryInstr* entry) { catch_entries_.Add(entry); } |
1279 | 1290 |
1280 CatchBlockEntryInstr* GetCatchEntry(intptr_t index); | 1291 CatchBlockEntryInstr* GetCatchEntry(intptr_t index); |
1281 | 1292 |
1293 void AddIndirectEntry(IndirectEntryInstr* entry) { | |
Ivan Posva
2014/11/10 08:16:23
It is very unclear what these entries are used for
zerny-google
2014/11/10 09:10:42
As far as I understand, the graph entry is the mai
| |
1294 indirect_entries_.Add(entry); | |
1295 } | |
1296 | |
1282 GrowableArray<Definition*>* initial_definitions() { | 1297 GrowableArray<Definition*>* initial_definitions() { |
1283 return &initial_definitions_; | 1298 return &initial_definitions_; |
1284 } | 1299 } |
1285 ConstantInstr* constant_null(); | 1300 ConstantInstr* constant_null(); |
1286 | 1301 |
1287 bool IsCompiledForOsr() const { return osr_id_ != Isolate::kNoDeoptId; } | 1302 bool IsCompiledForOsr() const { return osr_id_ != Isolate::kNoDeoptId; } |
1288 | 1303 |
1289 intptr_t entry_count() const { return entry_count_; } | 1304 intptr_t entry_count() const { return entry_count_; } |
1290 void set_entry_count(intptr_t count) { entry_count_ = count; } | 1305 void set_entry_count(intptr_t count) { entry_count_ = count; } |
1291 | 1306 |
(...skipping 14 matching lines...) Expand all Loading... | |
1306 TargetEntryInstr* normal_entry() const { return normal_entry_; } | 1321 TargetEntryInstr* normal_entry() const { return normal_entry_; } |
1307 | 1322 |
1308 const ParsedFunction& parsed_function() const { | 1323 const ParsedFunction& parsed_function() const { |
1309 return *parsed_function_; | 1324 return *parsed_function_; |
1310 } | 1325 } |
1311 | 1326 |
1312 const GrowableArray<CatchBlockEntryInstr*>& catch_entries() const { | 1327 const GrowableArray<CatchBlockEntryInstr*>& catch_entries() const { |
1313 return catch_entries_; | 1328 return catch_entries_; |
1314 } | 1329 } |
1315 | 1330 |
1331 const GrowableArray<IndirectEntryInstr*>& indirect_entries() const { | |
1332 return indirect_entries_; | |
1333 } | |
1334 | |
1316 virtual void PrintTo(BufferFormatter* f) const; | 1335 virtual void PrintTo(BufferFormatter* f) const; |
1317 | 1336 |
1318 private: | 1337 private: |
1319 virtual void ClearPredecessors() {} | 1338 virtual void ClearPredecessors() {} |
1320 virtual void AddPredecessor(BlockEntryInstr* predecessor) { UNREACHABLE(); } | 1339 virtual void AddPredecessor(BlockEntryInstr* predecessor) { UNREACHABLE(); } |
1321 | 1340 |
1322 const ParsedFunction* parsed_function_; | 1341 const ParsedFunction* parsed_function_; |
1323 TargetEntryInstr* normal_entry_; | 1342 TargetEntryInstr* normal_entry_; |
1324 GrowableArray<CatchBlockEntryInstr*> catch_entries_; | 1343 GrowableArray<CatchBlockEntryInstr*> catch_entries_; |
1344 // Indirect targets are blocks reachable only through indirect gotos. | |
1345 GrowableArray<IndirectEntryInstr*> indirect_entries_; | |
1325 GrowableArray<Definition*> initial_definitions_; | 1346 GrowableArray<Definition*> initial_definitions_; |
1326 const intptr_t osr_id_; | 1347 const intptr_t osr_id_; |
1327 intptr_t entry_count_; | 1348 intptr_t entry_count_; |
1328 intptr_t spill_slot_count_; | 1349 intptr_t spill_slot_count_; |
1329 intptr_t fixed_slot_count_; // For try-catch in optimized code. | 1350 intptr_t fixed_slot_count_; // For try-catch in optimized code. |
1330 | 1351 |
1331 DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr); | 1352 DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr); |
1332 }; | 1353 }; |
1333 | 1354 |
1334 | 1355 |
(...skipping 25 matching lines...) Expand all Loading... | |
1360 virtual void PrintTo(BufferFormatter* f) const; | 1381 virtual void PrintTo(BufferFormatter* f) const; |
1361 | 1382 |
1362 virtual EffectSet Effects() const { return EffectSet::None(); } | 1383 virtual EffectSet Effects() const { return EffectSet::None(); } |
1363 virtual EffectSet Dependencies() const { return EffectSet::None(); } | 1384 virtual EffectSet Dependencies() const { return EffectSet::None(); } |
1364 | 1385 |
1365 private: | 1386 private: |
1366 // Classes that have access to predecessors_ when inlining. | 1387 // Classes that have access to predecessors_ when inlining. |
1367 friend class BlockEntryInstr; | 1388 friend class BlockEntryInstr; |
1368 friend class InlineExitCollector; | 1389 friend class InlineExitCollector; |
1369 friend class PolymorphicInliner; | 1390 friend class PolymorphicInliner; |
1391 friend class IndirectEntryInstr; // Access in il_printer.cc. | |
1370 | 1392 |
1371 // Direct access to phis_ in order to resize it due to phi elimination. | 1393 // Direct access to phis_ in order to resize it due to phi elimination. |
1372 friend class ConstantPropagator; | 1394 friend class ConstantPropagator; |
1373 friend class DeadCodeElimination; | 1395 friend class DeadCodeElimination; |
1374 | 1396 |
1375 virtual void ClearPredecessors() { predecessors_.Clear(); } | 1397 virtual void ClearPredecessors() { predecessors_.Clear(); } |
1376 virtual void AddPredecessor(BlockEntryInstr* predecessor); | 1398 virtual void AddPredecessor(BlockEntryInstr* predecessor); |
1377 | 1399 |
1378 GrowableArray<BlockEntryInstr*> predecessors_; | 1400 GrowableArray<BlockEntryInstr*> predecessors_; |
1379 ZoneGrowableArray<PhiInstr*>* phis_; | 1401 ZoneGrowableArray<PhiInstr*>* phis_; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1438 predecessor_ = predecessor; | 1460 predecessor_ = predecessor; |
1439 } | 1461 } |
1440 | 1462 |
1441 BlockEntryInstr* predecessor_; | 1463 BlockEntryInstr* predecessor_; |
1442 double edge_weight_; | 1464 double edge_weight_; |
1443 | 1465 |
1444 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); | 1466 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); |
1445 }; | 1467 }; |
1446 | 1468 |
1447 | 1469 |
1470 class IndirectEntryInstr : public JoinEntryInstr { | |
1471 public: | |
1472 IndirectEntryInstr(intptr_t block_id, | |
1473 intptr_t indirect_id, | |
1474 intptr_t try_index) | |
1475 : JoinEntryInstr(block_id, try_index), | |
1476 indirect_id_(indirect_id) { } | |
1477 | |
1478 DECLARE_INSTRUCTION(IndirectEntry) | |
1479 | |
1480 virtual void PrintTo(BufferFormatter* f) const; | |
1481 | |
1482 intptr_t indirect_id() const { return indirect_id_; } | |
1483 | |
1484 private: | |
1485 const intptr_t indirect_id_; | |
1486 }; | |
1487 | |
1488 | |
1448 class CatchBlockEntryInstr : public BlockEntryInstr { | 1489 class CatchBlockEntryInstr : public BlockEntryInstr { |
1449 public: | 1490 public: |
1450 CatchBlockEntryInstr(intptr_t block_id, | 1491 CatchBlockEntryInstr(intptr_t block_id, |
1451 intptr_t try_index, | 1492 intptr_t try_index, |
1452 const Array& handler_types, | 1493 const Array& handler_types, |
1453 intptr_t catch_try_index, | 1494 intptr_t catch_try_index, |
1454 const LocalVariable& exception_var, | 1495 const LocalVariable& exception_var, |
1455 const LocalVariable& stacktrace_var, | 1496 const LocalVariable& stacktrace_var, |
1456 bool needs_stacktrace) | 1497 bool needs_stacktrace) |
1457 : BlockEntryInstr(block_id, try_index), | 1498 : BlockEntryInstr(block_id, try_index), |
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2136 private: | 2177 private: |
2137 JoinEntryInstr* successor_; | 2178 JoinEntryInstr* successor_; |
2138 double edge_weight_; | 2179 double edge_weight_; |
2139 | 2180 |
2140 // Parallel move that will be used by linear scan register allocator to | 2181 // Parallel move that will be used by linear scan register allocator to |
2141 // connect live ranges at the end of the block and resolve phis. | 2182 // connect live ranges at the end of the block and resolve phis. |
2142 ParallelMoveInstr* parallel_move_; | 2183 ParallelMoveInstr* parallel_move_; |
2143 }; | 2184 }; |
2144 | 2185 |
2145 | 2186 |
2187 // As a high level description, an indirect goto takes the indirect_id of an | |
2188 // indirect entry as a parameter, and jumps to that location. | |
2189 // | |
2190 // In more detail: in order to preserve split-edge form, an intermediate target | |
2191 // entry consisting of a goto to the final indirect entry is inserted on | |
Ivan Posva
2014/11/10 08:16:23
This comment is unclear. What is "final" in this c
zerny-google
2014/11/10 09:10:42
I'll update the comment to be more clear.
What th
| |
2192 // each possible indirect goto -> indirect entry edge. These target entries are | |
2193 // accessible through successors_. | |
2194 // | |
2195 // Byte offsets of all possible indirect targets are stored in the offsets_ | |
2196 // array. The desired offset is looked up while the generated code is executing, | |
2197 // and passed to IndirectGoto as an input. | |
2198 class IndirectGotoInstr : public TemplateInstruction<1, NoThrow> { | |
2199 public: | |
2200 IndirectGotoInstr(GrowableObjectArray* offsets, | |
2201 Value* offset_from_start) | |
2202 : offsets_(*offsets) { | |
2203 SetInputAt(0, offset_from_start); | |
2204 } | |
2205 | |
2206 DECLARE_INSTRUCTION(IndirectGoto) | |
2207 | |
2208 virtual intptr_t ArgumentCount() const { return 0; } | |
2209 | |
2210 void AddSuccessor(TargetEntryInstr* successor) { | |
2211 ASSERT(successor->next()->IsGoto()); | |
2212 ASSERT(successor->next()->AsGoto()->successor()->IsIndirectEntry()); | |
2213 successors_.Add(successor); | |
2214 } | |
2215 | |
2216 virtual intptr_t SuccessorCount() const { return successors_.length(); } | |
2217 virtual TargetEntryInstr* SuccessorAt(intptr_t index) const { | |
2218 ASSERT(index < SuccessorCount()); | |
2219 return successors_[index]; | |
2220 } | |
2221 | |
2222 virtual bool CanDeoptimize() const { return false; } | |
2223 virtual bool CanBecomeDeoptimizationTarget() const { return false; } | |
2224 | |
2225 virtual EffectSet Effects() const { return EffectSet::None(); } | |
2226 | |
2227 virtual void PrintTo(BufferFormatter* f) const; | |
2228 | |
2229 const GrowableObjectArray& offsets() const { return offsets_; } | |
2230 void SetOffsetCount(Isolate* isolate, intptr_t count) { | |
2231 if (offsets_.Capacity() < count) { | |
2232 offsets_.Grow(count, Heap::kOld); | |
2233 } | |
2234 if (offsets_.Length() < count) { | |
2235 offsets_.SetLength(count); | |
2236 } | |
2237 } | |
2238 void SetOffsetAt(Isolate* isolate, intptr_t index, intptr_t offset) { | |
2239 offsets_.SetAt(index, Smi::ZoneHandle(isolate, Smi::New(offset))); | |
2240 } | |
2241 | |
2242 private: | |
2243 GrowableArray<TargetEntryInstr*> successors_; | |
Ivan Posva
2014/11/10 08:16:23
How many of these successors and corresponding off
zerny-google
2014/11/10 09:10:42
One for each possible target. The number of target
| |
2244 GrowableObjectArray& offsets_; | |
2245 }; | |
2246 | |
2247 | |
2146 class ComparisonInstr : public TemplateDefinition<2, NoThrow, Pure> { | 2248 class ComparisonInstr : public TemplateDefinition<2, NoThrow, Pure> { |
2147 public: | 2249 public: |
2148 Value* left() const { return inputs_[0]; } | 2250 Value* left() const { return inputs_[0]; } |
2149 Value* right() const { return inputs_[1]; } | 2251 Value* right() const { return inputs_[1]; } |
2150 | 2252 |
2151 virtual intptr_t token_pos() const { return token_pos_; } | 2253 virtual intptr_t token_pos() const { return token_pos_; } |
2152 Token::Kind kind() const { return kind_; } | 2254 Token::Kind kind() const { return kind_; } |
2153 | 2255 |
2154 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right) = 0; | 2256 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right) = 0; |
2155 | 2257 |
(...skipping 1449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3605 | 3707 |
3606 private: | 3708 private: |
3607 const intptr_t index_scale_; | 3709 const intptr_t index_scale_; |
3608 const intptr_t class_id_; | 3710 const intptr_t class_id_; |
3609 const intptr_t token_pos_; | 3711 const intptr_t token_pos_; |
3610 | 3712 |
3611 DISALLOW_COPY_AND_ASSIGN(LoadIndexedInstr); | 3713 DISALLOW_COPY_AND_ASSIGN(LoadIndexedInstr); |
3612 }; | 3714 }; |
3613 | 3715 |
3614 | 3716 |
3717 // Loads the specified number of code units from the given string, packing | |
3718 // multiple code units into a single datatype. In essence, this is a specialized | |
3719 // version of LoadIndexedInstr which accepts only string targets and can load | |
3720 // multiple elements at once. The result datatype differs depending on the | |
3721 // string type, element count, and architecture; if possible, the result is | |
3722 // packed into a Smi, falling back to a Mint otherwise. | |
3723 // TODO(zerny): Add support for loading into UnboxedInt32x4. | |
3724 class LoadCodeUnitsInstr : public TemplateDefinition<2, NoThrow> { | |
3725 public: | |
3726 LoadCodeUnitsInstr(Value* str, | |
3727 Value* index, | |
3728 intptr_t element_count, | |
3729 intptr_t class_id, | |
3730 intptr_t token_pos) | |
3731 : class_id_(class_id), | |
3732 token_pos_(token_pos), | |
3733 element_count_(element_count) { | |
3734 ASSERT(element_count == 1 || element_count == 2 || element_count == 4); | |
3735 ASSERT(class_id == kOneByteStringCid || class_id == kTwoByteStringCid); | |
3736 SetInputAt(0, str); | |
3737 SetInputAt(1, index); | |
3738 } | |
3739 | |
3740 intptr_t token_pos() const { return token_pos_; } | |
3741 | |
3742 DECLARE_INSTRUCTION(LoadCodeUnits) | |
3743 virtual CompileType ComputeType() const; | |
3744 | |
3745 bool IsExternal() const { | |
3746 return array()->definition()->representation() == kUntagged; | |
3747 } | |
3748 | |
3749 Value* array() const { return inputs_[0]; } | |
3750 Value* index() const { return inputs_[1]; } | |
3751 intptr_t index_scale() const { return Instance::ElementSizeFor(class_id_); } | |
3752 intptr_t class_id() const { return class_id_; } | |
3753 intptr_t element_count() const { return element_count_; } | |
3754 | |
3755 bool can_pack_into_smi() const { | |
3756 return element_count() <= kSmiBits / (index_scale() * kBitsPerByte); | |
3757 } | |
3758 | |
3759 virtual bool CanDeoptimize() const { return false; } | |
3760 | |
3761 virtual Representation representation() const; | |
3762 virtual void InferRange(RangeAnalysis* analysis, Range* range); | |
3763 | |
3764 virtual EffectSet Effects() const { return EffectSet::None(); } | |
3765 | |
3766 private: | |
3767 const intptr_t class_id_; | |
3768 const intptr_t token_pos_; | |
3769 const intptr_t element_count_; | |
3770 | |
3771 DISALLOW_COPY_AND_ASSIGN(LoadCodeUnitsInstr); | |
3772 }; | |
3773 | |
3774 | |
3615 class StringFromCharCodeInstr : public TemplateDefinition<1, NoThrow, Pure> { | 3775 class StringFromCharCodeInstr : public TemplateDefinition<1, NoThrow, Pure> { |
3616 public: | 3776 public: |
3617 StringFromCharCodeInstr(Value* char_code, intptr_t cid) : cid_(cid) { | 3777 StringFromCharCodeInstr(Value* char_code, intptr_t cid) : cid_(cid) { |
3618 ASSERT(char_code != NULL); | 3778 ASSERT(char_code != NULL); |
3619 ASSERT(char_code->definition()->IsLoadIndexed()); | 3779 ASSERT(char_code->definition()->IsLoadIndexed()); |
3620 ASSERT(char_code->definition()->AsLoadIndexed()->class_id() == | 3780 ASSERT(char_code->definition()->AsLoadIndexed()->class_id() == |
3621 kOneByteStringCid); | 3781 kOneByteStringCid); |
3622 SetInputAt(0, char_code); | 3782 SetInputAt(0, char_code); |
3623 } | 3783 } |
3624 | 3784 |
(...skipping 1155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4780 | 4940 |
4781 static const char* KindToCString(MathUnaryKind kind); | 4941 static const char* KindToCString(MathUnaryKind kind); |
4782 | 4942 |
4783 private: | 4943 private: |
4784 const MathUnaryKind kind_; | 4944 const MathUnaryKind kind_; |
4785 | 4945 |
4786 DISALLOW_COPY_AND_ASSIGN(MathUnaryInstr); | 4946 DISALLOW_COPY_AND_ASSIGN(MathUnaryInstr); |
4787 }; | 4947 }; |
4788 | 4948 |
4789 | 4949 |
4950 // Calls into the runtime and performs a case-insensitive comparison of the | |
4951 // UTF16 strings (i.e. TwoByteString or ExternalTwoByteString) located at | |
4952 // str[lhs_index:lhs_index + length] and str[rhs_index:rhs_index + length]. | |
4953 // | |
4954 // TODO(zerny): Remove this once (if) functions inherited from unibrow | |
4955 // are moved to dart code. | |
4956 class CaseInsensitiveCompareUC16Instr | |
4957 : public TemplateDefinition<4, NoThrow, Pure> { | |
4958 public: | |
4959 CaseInsensitiveCompareUC16Instr( | |
4960 Value* str, | |
4961 Value* lhs_index, | |
4962 Value* rhs_index, | |
4963 Value* length, | |
4964 intptr_t cid) | |
4965 : cid_(cid) { | |
4966 ASSERT(cid == kTwoByteStringCid || cid == kExternalTwoByteStringCid); | |
4967 ASSERT(index_scale() == 2); | |
4968 SetInputAt(0, str); | |
4969 SetInputAt(1, lhs_index); | |
4970 SetInputAt(2, rhs_index); | |
4971 SetInputAt(3, length); | |
4972 } | |
4973 | |
4974 Value* str() const { return inputs_[0]; } | |
4975 Value* lhs_index() const { return inputs_[1]; } | |
4976 Value* rhs_index() const { return inputs_[2]; } | |
4977 Value* length() const { return inputs_[3]; } | |
4978 | |
4979 const RuntimeEntry& TargetFunction() const; | |
4980 bool IsExternal() const { return cid_ == kExternalTwoByteStringCid; } | |
4981 intptr_t class_id() const { return cid_; } | |
4982 intptr_t index_scale() const { return Instance::ElementSizeFor(cid_); } | |
4983 | |
4984 virtual bool CanDeoptimize() const { return false; } | |
4985 | |
4986 virtual Representation representation() const { | |
4987 return kTagged; | |
4988 } | |
4989 | |
4990 DECLARE_INSTRUCTION(CaseInsensitiveCompareUC16) | |
4991 virtual CompileType ComputeType() const; | |
4992 | |
4993 virtual bool AttributesEqual(Instruction* other) const { | |
4994 return other->AsCaseInsensitiveCompareUC16()->cid_ == cid_; | |
4995 } | |
4996 | |
4997 private: | |
4998 const intptr_t cid_; | |
4999 | |
5000 DISALLOW_COPY_AND_ASSIGN(CaseInsensitiveCompareUC16Instr); | |
5001 }; | |
5002 | |
5003 | |
4790 // Represents Math's static min and max functions. | 5004 // Represents Math's static min and max functions. |
4791 class MathMinMaxInstr : public TemplateDefinition<2, NoThrow, Pure> { | 5005 class MathMinMaxInstr : public TemplateDefinition<2, NoThrow, Pure> { |
4792 public: | 5006 public: |
4793 MathMinMaxInstr(MethodRecognizer::Kind op_kind, | 5007 MathMinMaxInstr(MethodRecognizer::Kind op_kind, |
4794 Value* left_value, | 5008 Value* left_value, |
4795 Value* right_value, | 5009 Value* right_value, |
4796 intptr_t deopt_id, | 5010 intptr_t deopt_id, |
4797 intptr_t result_cid) | 5011 intptr_t result_cid) |
4798 : TemplateDefinition(deopt_id), | 5012 : TemplateDefinition(deopt_id), |
4799 op_kind_(op_kind), | 5013 op_kind_(op_kind), |
(...skipping 2968 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7768 Isolate* isolate, bool opt) const { \ | 7982 Isolate* isolate, bool opt) const { \ |
7769 UNIMPLEMENTED(); \ | 7983 UNIMPLEMENTED(); \ |
7770 return NULL; \ | 7984 return NULL; \ |
7771 } \ | 7985 } \ |
7772 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } | 7986 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } |
7773 | 7987 |
7774 | 7988 |
7775 } // namespace dart | 7989 } // namespace dart |
7776 | 7990 |
7777 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 7991 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
OLD | NEW |