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 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
417 | 417 |
418 // Instructions. | 418 // Instructions. |
419 | 419 |
420 // M is a single argument macro. It is applied to each concrete instruction | 420 // M is a single argument macro. It is applied to each concrete instruction |
421 // type name. The concrete instruction classes are the name with Instr | 421 // type name. The concrete instruction classes are the name with Instr |
422 // concatenated. | 422 // concatenated. |
423 #define FOR_EACH_INSTRUCTION(M) \ | 423 #define FOR_EACH_INSTRUCTION(M) \ |
424 M(GraphEntry) \ | 424 M(GraphEntry) \ |
425 M(JoinEntry) \ | 425 M(JoinEntry) \ |
426 M(TargetEntry) \ | 426 M(TargetEntry) \ |
427 M(IndirectEntry) \ | |
427 M(CatchBlockEntry) \ | 428 M(CatchBlockEntry) \ |
428 M(Phi) \ | 429 M(Phi) \ |
429 M(Redefinition) \ | 430 M(Redefinition) \ |
430 M(Parameter) \ | 431 M(Parameter) \ |
431 M(ParallelMove) \ | 432 M(ParallelMove) \ |
432 M(PushArgument) \ | 433 M(PushArgument) \ |
433 M(Return) \ | 434 M(Return) \ |
434 M(Throw) \ | 435 M(Throw) \ |
435 M(ReThrow) \ | 436 M(ReThrow) \ |
436 M(Goto) \ | 437 M(Goto) \ |
438 M(IndirectGoto) \ | |
437 M(Branch) \ | 439 M(Branch) \ |
438 M(AssertAssignable) \ | 440 M(AssertAssignable) \ |
439 M(AssertBoolean) \ | 441 M(AssertBoolean) \ |
440 M(CurrentContext) \ | 442 M(CurrentContext) \ |
441 M(StoreContext) \ | 443 M(StoreContext) \ |
442 M(ClosureCall) \ | 444 M(ClosureCall) \ |
443 M(InstanceCall) \ | 445 M(InstanceCall) \ |
444 M(PolymorphicInstanceCall) \ | 446 M(PolymorphicInstanceCall) \ |
445 M(StaticCall) \ | 447 M(StaticCall) \ |
446 M(LoadLocal) \ | 448 M(LoadLocal) \ |
447 M(PushTemp) \ | 449 M(PushTemp) \ |
448 M(DropTemps) \ | 450 M(DropTemps) \ |
449 M(StoreLocal) \ | 451 M(StoreLocal) \ |
450 M(StrictCompare) \ | 452 M(StrictCompare) \ |
451 M(EqualityCompare) \ | 453 M(EqualityCompare) \ |
452 M(RelationalOp) \ | 454 M(RelationalOp) \ |
453 M(NativeCall) \ | 455 M(NativeCall) \ |
454 M(DebugStepCheck) \ | 456 M(DebugStepCheck) \ |
455 M(LoadIndexed) \ | 457 M(LoadIndexed) \ |
458 M(LoadCodeUnits) \ | |
456 M(StoreIndexed) \ | 459 M(StoreIndexed) \ |
457 M(StoreInstanceField) \ | 460 M(StoreInstanceField) \ |
458 M(InitStaticField) \ | 461 M(InitStaticField) \ |
459 M(LoadStaticField) \ | 462 M(LoadStaticField) \ |
460 M(StoreStaticField) \ | 463 M(StoreStaticField) \ |
461 M(BooleanNegate) \ | 464 M(BooleanNegate) \ |
462 M(InstanceOf) \ | 465 M(InstanceOf) \ |
463 M(CreateArray) \ | 466 M(CreateArray) \ |
464 M(AllocateObject) \ | 467 M(AllocateObject) \ |
465 M(LoadField) \ | 468 M(LoadField) \ |
(...skipping 19 matching lines...) Expand all Loading... | |
485 M(FloatToDouble) \ | 488 M(FloatToDouble) \ |
486 M(CheckClass) \ | 489 M(CheckClass) \ |
487 M(CheckClassId) \ | 490 M(CheckClassId) \ |
488 M(CheckSmi) \ | 491 M(CheckSmi) \ |
489 M(Constant) \ | 492 M(Constant) \ |
490 M(UnboxedConstant) \ | 493 M(UnboxedConstant) \ |
491 M(CheckEitherNonSmi) \ | 494 M(CheckEitherNonSmi) \ |
492 M(BinaryDoubleOp) \ | 495 M(BinaryDoubleOp) \ |
493 M(MathUnary) \ | 496 M(MathUnary) \ |
494 M(MathMinMax) \ | 497 M(MathMinMax) \ |
498 M(CaseInsensitiveCompareUC16) \ | |
495 M(UnboxDouble) \ | 499 M(UnboxDouble) \ |
496 M(BoxDouble) \ | 500 M(BoxDouble) \ |
497 M(BoxFloat32x4) \ | 501 M(BoxFloat32x4) \ |
498 M(UnboxFloat32x4) \ | 502 M(UnboxFloat32x4) \ |
499 M(BoxInt32x4) \ | 503 M(BoxInt32x4) \ |
500 M(UnboxInt32x4) \ | 504 M(UnboxInt32x4) \ |
501 M(UnboxInteger) \ | 505 M(UnboxInteger) \ |
502 M(BoxInteger) \ | 506 M(BoxInteger) \ |
503 M(BinaryMintOp) \ | 507 M(BinaryMintOp) \ |
504 M(ShiftMintOp) \ | 508 M(ShiftMintOp) \ |
(...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1201 return const_cast<BlockEntryInstr*>(this); | 1205 return const_cast<BlockEntryInstr*>(this); |
1202 } | 1206 } |
1203 | 1207 |
1204 // Helper to mutate the graph during inlining. This block should be | 1208 // Helper to mutate the graph during inlining. This block should be |
1205 // replaced with new_block as a predecessor of all of this block's | 1209 // replaced with new_block as a predecessor of all of this block's |
1206 // successors. | 1210 // successors. |
1207 void ReplaceAsPredecessorWith(BlockEntryInstr* new_block); | 1211 void ReplaceAsPredecessorWith(BlockEntryInstr* new_block); |
1208 | 1212 |
1209 void set_block_id(intptr_t block_id) { block_id_ = block_id; } | 1213 void set_block_id(intptr_t block_id) { block_id_ = block_id; } |
1210 | 1214 |
1215 intptr_t offset() const { return offset_; } | |
1216 void set_offset(intptr_t offset) { offset_ = offset; } | |
1217 | |
1211 // For all instruction in this block: Remove all inputs (including in the | 1218 // For all instruction in this block: Remove all inputs (including in the |
1212 // environment) from their definition's use lists for all instructions. | 1219 // environment) from their definition's use lists for all instructions. |
1213 void ClearAllInstructions(); | 1220 void ClearAllInstructions(); |
1214 | 1221 |
1215 DEFINE_INSTRUCTION_TYPE_CHECK(BlockEntry) | 1222 DEFINE_INSTRUCTION_TYPE_CHECK(BlockEntry) |
1216 | 1223 |
1217 protected: | 1224 protected: |
1218 BlockEntryInstr(intptr_t block_id, intptr_t try_index) | 1225 BlockEntryInstr(intptr_t block_id, intptr_t try_index) |
1219 : block_id_(block_id), | 1226 : block_id_(block_id), |
1220 try_index_(try_index), | 1227 try_index_(try_index), |
1221 preorder_number_(-1), | 1228 preorder_number_(-1), |
1222 postorder_number_(-1), | 1229 postorder_number_(-1), |
1223 dominator_(NULL), | 1230 dominator_(NULL), |
1224 dominated_blocks_(1), | 1231 dominated_blocks_(1), |
1225 last_instruction_(NULL), | 1232 last_instruction_(NULL), |
1233 offset_(-1), | |
1226 parallel_move_(NULL), | 1234 parallel_move_(NULL), |
1227 loop_info_(NULL) { | 1235 loop_info_(NULL) { |
1228 deopt_id_ = Isolate::Current()->GetNextDeoptId(); | 1236 deopt_id_ = Isolate::Current()->GetNextDeoptId(); |
1229 } | 1237 } |
1230 | 1238 |
1231 private: | 1239 private: |
1232 virtual void RawSetInputAt(intptr_t i, Value* value) { UNREACHABLE(); } | 1240 virtual void RawSetInputAt(intptr_t i, Value* value) { UNREACHABLE(); } |
1233 | 1241 |
1234 virtual void ClearPredecessors() = 0; | 1242 virtual void ClearPredecessors() = 0; |
1235 virtual void AddPredecessor(BlockEntryInstr* predecessor) = 0; | 1243 virtual void AddPredecessor(BlockEntryInstr* predecessor) = 0; |
1236 | 1244 |
1237 void set_dominator(BlockEntryInstr* instr) { dominator_ = instr; } | 1245 void set_dominator(BlockEntryInstr* instr) { dominator_ = instr; } |
1238 | 1246 |
1239 intptr_t block_id_; | 1247 intptr_t block_id_; |
1240 const intptr_t try_index_; | 1248 const intptr_t try_index_; |
1241 intptr_t preorder_number_; | 1249 intptr_t preorder_number_; |
1242 intptr_t postorder_number_; | 1250 intptr_t postorder_number_; |
1243 // Starting and ending lifetime positions for this block. Used by | 1251 // Starting and ending lifetime positions for this block. Used by |
1244 // the linear scan register allocator. | 1252 // the linear scan register allocator. |
1245 intptr_t start_pos_; | 1253 intptr_t start_pos_; |
1246 intptr_t end_pos_; | 1254 intptr_t end_pos_; |
1247 BlockEntryInstr* dominator_; // Immediate dominator, NULL for graph entry. | 1255 BlockEntryInstr* dominator_; // Immediate dominator, NULL for graph entry. |
1248 // TODO(fschneider): Optimize the case of one child to save space. | 1256 // TODO(fschneider): Optimize the case of one child to save space. |
1249 GrowableArray<BlockEntryInstr*> dominated_blocks_; | 1257 GrowableArray<BlockEntryInstr*> dominated_blocks_; |
1250 Instruction* last_instruction_; | 1258 Instruction* last_instruction_; |
1251 | 1259 |
1260 // Offset of this block from the start of the emitted code. | |
1261 intptr_t offset_; | |
1262 | |
1252 // Parallel move that will be used by linear scan register allocator to | 1263 // Parallel move that will be used by linear scan register allocator to |
1253 // connect live ranges at the start of the block. | 1264 // connect live ranges at the start of the block. |
1254 ParallelMoveInstr* parallel_move_; | 1265 ParallelMoveInstr* parallel_move_; |
1255 | 1266 |
1256 // Bit vector containg loop blocks for a loop header indexed by block | 1267 // Bit vector containg loop blocks for a loop header indexed by block |
1257 // preorder number. | 1268 // preorder number. |
1258 BitVector* loop_info_; | 1269 BitVector* loop_info_; |
1259 | 1270 |
1260 DISALLOW_COPY_AND_ASSIGN(BlockEntryInstr); | 1271 DISALLOW_COPY_AND_ASSIGN(BlockEntryInstr); |
1261 }; | 1272 }; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1322 UNREACHABLE(); | 1333 UNREACHABLE(); |
1323 return NULL; | 1334 return NULL; |
1324 } | 1335 } |
1325 virtual intptr_t SuccessorCount() const; | 1336 virtual intptr_t SuccessorCount() const; |
1326 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; | 1337 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; |
1327 | 1338 |
1328 void AddCatchEntry(CatchBlockEntryInstr* entry) { catch_entries_.Add(entry); } | 1339 void AddCatchEntry(CatchBlockEntryInstr* entry) { catch_entries_.Add(entry); } |
1329 | 1340 |
1330 CatchBlockEntryInstr* GetCatchEntry(intptr_t index); | 1341 CatchBlockEntryInstr* GetCatchEntry(intptr_t index); |
1331 | 1342 |
1343 void AddIndirectEntry(IndirectEntryInstr* entry) { | |
1344 indirect_entries_.Add(entry); | |
1345 } | |
1346 | |
1332 GrowableArray<Definition*>* initial_definitions() { | 1347 GrowableArray<Definition*>* initial_definitions() { |
1333 return &initial_definitions_; | 1348 return &initial_definitions_; |
1334 } | 1349 } |
1335 ConstantInstr* constant_null(); | 1350 ConstantInstr* constant_null(); |
1336 | 1351 |
1337 bool IsCompiledForOsr() const { return osr_id_ != Isolate::kNoDeoptId; } | 1352 bool IsCompiledForOsr() const { return osr_id_ != Isolate::kNoDeoptId; } |
1338 | 1353 |
1339 intptr_t entry_count() const { return entry_count_; } | 1354 intptr_t entry_count() const { return entry_count_; } |
1340 void set_entry_count(intptr_t count) { entry_count_ = count; } | 1355 void set_entry_count(intptr_t count) { entry_count_ = count; } |
1341 | 1356 |
(...skipping 14 matching lines...) Expand all Loading... | |
1356 TargetEntryInstr* normal_entry() const { return normal_entry_; } | 1371 TargetEntryInstr* normal_entry() const { return normal_entry_; } |
1357 | 1372 |
1358 const ParsedFunction& parsed_function() const { | 1373 const ParsedFunction& parsed_function() const { |
1359 return *parsed_function_; | 1374 return *parsed_function_; |
1360 } | 1375 } |
1361 | 1376 |
1362 const GrowableArray<CatchBlockEntryInstr*>& catch_entries() const { | 1377 const GrowableArray<CatchBlockEntryInstr*>& catch_entries() const { |
1363 return catch_entries_; | 1378 return catch_entries_; |
1364 } | 1379 } |
1365 | 1380 |
1381 const GrowableArray<IndirectEntryInstr*>& indirect_entries() const { | |
1382 return indirect_entries_; | |
1383 } | |
1384 | |
1366 virtual void PrintTo(BufferFormatter* f) const; | 1385 virtual void PrintTo(BufferFormatter* f) const; |
1367 | 1386 |
1368 private: | 1387 private: |
1369 virtual void ClearPredecessors() {} | 1388 virtual void ClearPredecessors() {} |
1370 virtual void AddPredecessor(BlockEntryInstr* predecessor) { UNREACHABLE(); } | 1389 virtual void AddPredecessor(BlockEntryInstr* predecessor) { UNREACHABLE(); } |
1371 | 1390 |
1372 const ParsedFunction* parsed_function_; | 1391 const ParsedFunction* parsed_function_; |
1373 TargetEntryInstr* normal_entry_; | 1392 TargetEntryInstr* normal_entry_; |
1374 GrowableArray<CatchBlockEntryInstr*> catch_entries_; | 1393 GrowableArray<CatchBlockEntryInstr*> catch_entries_; |
1394 // Indirect targets are blocks reachable only through indirect gotos. | |
1395 GrowableArray<IndirectEntryInstr*> indirect_entries_; | |
1375 GrowableArray<Definition*> initial_definitions_; | 1396 GrowableArray<Definition*> initial_definitions_; |
1376 const intptr_t osr_id_; | 1397 const intptr_t osr_id_; |
1377 intptr_t entry_count_; | 1398 intptr_t entry_count_; |
1378 intptr_t spill_slot_count_; | 1399 intptr_t spill_slot_count_; |
1379 intptr_t fixed_slot_count_; // For try-catch in optimized code. | 1400 intptr_t fixed_slot_count_; // For try-catch in optimized code. |
1380 | 1401 |
1381 DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr); | 1402 DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr); |
1382 }; | 1403 }; |
1383 | 1404 |
1384 | 1405 |
(...skipping 25 matching lines...) Expand all Loading... | |
1410 virtual void PrintTo(BufferFormatter* f) const; | 1431 virtual void PrintTo(BufferFormatter* f) const; |
1411 | 1432 |
1412 virtual EffectSet Effects() const { return EffectSet::None(); } | 1433 virtual EffectSet Effects() const { return EffectSet::None(); } |
1413 virtual EffectSet Dependencies() const { return EffectSet::None(); } | 1434 virtual EffectSet Dependencies() const { return EffectSet::None(); } |
1414 | 1435 |
1415 private: | 1436 private: |
1416 // Classes that have access to predecessors_ when inlining. | 1437 // Classes that have access to predecessors_ when inlining. |
1417 friend class BlockEntryInstr; | 1438 friend class BlockEntryInstr; |
1418 friend class InlineExitCollector; | 1439 friend class InlineExitCollector; |
1419 friend class PolymorphicInliner; | 1440 friend class PolymorphicInliner; |
1441 friend class IndirectEntryInstr; // Access in il_printer.cc. | |
1420 | 1442 |
1421 // Direct access to phis_ in order to resize it due to phi elimination. | 1443 // Direct access to phis_ in order to resize it due to phi elimination. |
1422 friend class ConstantPropagator; | 1444 friend class ConstantPropagator; |
1423 friend class DeadCodeElimination; | 1445 friend class DeadCodeElimination; |
1424 | 1446 |
1425 virtual void ClearPredecessors() { predecessors_.Clear(); } | 1447 virtual void ClearPredecessors() { predecessors_.Clear(); } |
1426 virtual void AddPredecessor(BlockEntryInstr* predecessor); | 1448 virtual void AddPredecessor(BlockEntryInstr* predecessor); |
1427 | 1449 |
1428 GrowableArray<BlockEntryInstr*> predecessors_; | 1450 GrowableArray<BlockEntryInstr*> predecessors_; |
1429 ZoneGrowableArray<PhiInstr*>* phis_; | 1451 ZoneGrowableArray<PhiInstr*>* phis_; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1488 predecessor_ = predecessor; | 1510 predecessor_ = predecessor; |
1489 } | 1511 } |
1490 | 1512 |
1491 BlockEntryInstr* predecessor_; | 1513 BlockEntryInstr* predecessor_; |
1492 double edge_weight_; | 1514 double edge_weight_; |
1493 | 1515 |
1494 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); | 1516 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); |
1495 }; | 1517 }; |
1496 | 1518 |
1497 | 1519 |
1520 class IndirectEntryInstr : public JoinEntryInstr { | |
1521 public: | |
1522 IndirectEntryInstr(intptr_t block_id, | |
1523 intptr_t indirect_id, | |
1524 intptr_t try_index) | |
1525 : JoinEntryInstr(block_id, try_index), | |
1526 indirect_id_(indirect_id) { } | |
1527 | |
1528 DECLARE_INSTRUCTION(IndirectEntry) | |
1529 | |
1530 virtual void PrintTo(BufferFormatter* f) const; | |
1531 | |
1532 intptr_t indirect_id() const { return indirect_id_; } | |
1533 | |
1534 private: | |
1535 const intptr_t indirect_id_; | |
1536 }; | |
1537 | |
1538 | |
1498 class CatchBlockEntryInstr : public BlockEntryInstr { | 1539 class CatchBlockEntryInstr : public BlockEntryInstr { |
1499 public: | 1540 public: |
1500 CatchBlockEntryInstr(intptr_t block_id, | 1541 CatchBlockEntryInstr(intptr_t block_id, |
1501 intptr_t try_index, | 1542 intptr_t try_index, |
1502 const Array& handler_types, | 1543 const Array& handler_types, |
1503 intptr_t catch_try_index, | 1544 intptr_t catch_try_index, |
1504 const LocalVariable& exception_var, | 1545 const LocalVariable& exception_var, |
1505 const LocalVariable& stacktrace_var, | 1546 const LocalVariable& stacktrace_var, |
1506 bool needs_stacktrace) | 1547 bool needs_stacktrace) |
1507 : BlockEntryInstr(block_id, try_index), | 1548 : BlockEntryInstr(block_id, try_index), |
(...skipping 654 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2162 private: | 2203 private: |
2163 JoinEntryInstr* successor_; | 2204 JoinEntryInstr* successor_; |
2164 double edge_weight_; | 2205 double edge_weight_; |
2165 | 2206 |
2166 // Parallel move that will be used by linear scan register allocator to | 2207 // Parallel move that will be used by linear scan register allocator to |
2167 // connect live ranges at the end of the block and resolve phis. | 2208 // connect live ranges at the end of the block and resolve phis. |
2168 ParallelMoveInstr* parallel_move_; | 2209 ParallelMoveInstr* parallel_move_; |
2169 }; | 2210 }; |
2170 | 2211 |
2171 | 2212 |
2213 // As a high level description, an indirect goto takes the indirect_id of an | |
2214 // indirect entry as a parameter, and jumps to that location. | |
2215 // | |
2216 // In more detail: in order to preserve split-edge form, an intermediate target | |
2217 // entry consisting of a goto to the final indirect entry is inserted on | |
2218 // each possible indirect goto -> indirect entry edge. These target entries are | |
2219 // accessible through successors_. | |
2220 // | |
2221 // Byte offsets of all possible indirect targets are stored in the offsets_ | |
2222 // array and are looked up at runtime. | |
2223 class IndirectGotoInstr : public TemplateInstruction<1> { | |
2224 public: | |
2225 IndirectGotoInstr(GrowableObjectArray* offsets, | |
2226 Value* offset_from_start) | |
2227 : offsets_(*offsets) { | |
2228 SetInputAt(0, offset_from_start); | |
2229 } | |
2230 | |
2231 DECLARE_INSTRUCTION(IndirectGoto) | |
2232 | |
2233 virtual intptr_t ArgumentCount() const { return 0; } | |
2234 | |
2235 void AddSuccessor(TargetEntryInstr* successor) { | |
2236 ASSERT(successor->next()->IsGoto()); | |
2237 ASSERT(successor->next()->AsGoto()->successor()->IsIndirectEntry()); | |
2238 successors_.Add(successor); | |
2239 } | |
2240 | |
2241 virtual intptr_t SuccessorCount() const { return successors_.length(); } | |
2242 virtual TargetEntryInstr* SuccessorAt(intptr_t index) const { | |
2243 ASSERT(index < SuccessorCount()); | |
2244 return successors_[index]; | |
2245 } | |
2246 | |
2247 virtual bool CanDeoptimize() const { return false; } | |
2248 virtual bool CanBecomeDeoptimizationTarget() const { return false; } | |
2249 | |
2250 virtual EffectSet Effects() const { return EffectSet::None(); } | |
2251 | |
2252 virtual void PrintTo(BufferFormatter* f) const; | |
2253 | |
2254 virtual bool MayThrow() const { return false; } | |
2255 | |
2256 const GrowableObjectArray& offsets() const { return offsets_; } | |
2257 void SetOffsetCount(Isolate* isolate, intptr_t count) { | |
2258 if (offsets_.Capacity() < count) { | |
2259 offsets_.Grow(count, Heap::kOld); | |
2260 } | |
2261 if (offsets_.Length() < count) { | |
2262 offsets_.SetLength(count); | |
2263 } | |
2264 } | |
2265 void SetOffsetAt(Isolate* isolate, intptr_t index, intptr_t offset) { | |
2266 offsets_.SetAt(index, Smi::ZoneHandle(isolate, Smi::New(offset))); | |
2267 } | |
2268 | |
2269 private: | |
2270 GrowableArray<TargetEntryInstr*> successors_; | |
2271 GrowableObjectArray& offsets_; | |
2272 }; | |
2273 | |
2274 | |
2172 class ComparisonInstr : public TemplateDefinition<2> { | 2275 class ComparisonInstr : public TemplateDefinition<2> { |
2173 public: | 2276 public: |
2174 Value* left() const { return inputs_[0]; } | 2277 Value* left() const { return inputs_[0]; } |
2175 Value* right() const { return inputs_[1]; } | 2278 Value* right() const { return inputs_[1]; } |
2176 | 2279 |
2177 virtual intptr_t token_pos() const { return token_pos_; } | 2280 virtual intptr_t token_pos() const { return token_pos_; } |
2178 Token::Kind kind() const { return kind_; } | 2281 Token::Kind kind() const { return kind_; } |
2179 | 2282 |
2180 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right) = 0; | 2283 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right) = 0; |
2181 | 2284 |
(...skipping 1618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3800 | 3903 |
3801 private: | 3904 private: |
3802 const intptr_t index_scale_; | 3905 const intptr_t index_scale_; |
3803 const intptr_t class_id_; | 3906 const intptr_t class_id_; |
3804 const intptr_t token_pos_; | 3907 const intptr_t token_pos_; |
3805 | 3908 |
3806 DISALLOW_COPY_AND_ASSIGN(LoadIndexedInstr); | 3909 DISALLOW_COPY_AND_ASSIGN(LoadIndexedInstr); |
3807 }; | 3910 }; |
3808 | 3911 |
3809 | 3912 |
3913 // Loads the specified number of code units from the given string, packing | |
3914 // multiple code units into a single datatype. In essence, this is a specialized | |
3915 // version of LoadIndexedInstr which accepts only string targets may load | |
zerny-google
2014/10/07 12:18:35
which accepts only string targets may load
->
whic
jgruber1
2014/10/07 15:00:25
Done.
| |
3916 // multiple elements at once. The result datatype differs depending on the | |
3917 // string type, element count, and architecture; if possible, the result is | |
3918 // packed into a Smi, falling back to a Mint otherwise. | |
3919 // TODO(jgruber): Add support for loading into UnboxedInt32x4. | |
3920 class LoadCodeUnitsInstr : public TemplateDefinition<2> { | |
3921 public: | |
3922 LoadCodeUnitsInstr(Value* array, | |
3923 Value* index, | |
3924 intptr_t element_count, | |
3925 intptr_t class_id, | |
3926 intptr_t token_pos) | |
3927 : class_id_(class_id), | |
3928 token_pos_(token_pos), | |
3929 element_count_(element_count) { | |
3930 ASSERT(class_id == kOneByteStringCid || class_id == kTwoByteStringCid); | |
3931 SetInputAt(0, array); | |
3932 SetInputAt(1, index); | |
3933 } | |
3934 | |
3935 intptr_t token_pos() const { return token_pos_; } | |
3936 | |
3937 DECLARE_INSTRUCTION(LoadCodeUnits) | |
3938 virtual CompileType ComputeType() const; | |
3939 | |
3940 bool IsExternal() const { | |
3941 return array()->definition()->representation() == kUntagged; | |
3942 } | |
3943 | |
3944 Value* array() const { return inputs_[0]; } | |
3945 Value* index() const { return inputs_[1]; } | |
3946 intptr_t index_scale() const { return Instance::ElementSizeFor(class_id_); } | |
3947 intptr_t class_id() const { return class_id_; } | |
3948 intptr_t element_count() const { return element_count_; } | |
3949 | |
3950 virtual bool CanDeoptimize() const { return false; } | |
3951 | |
3952 virtual Representation representation() const; | |
3953 virtual void InferRange(RangeAnalysis* analysis, Range* range); | |
3954 | |
3955 virtual bool AllowsCSE() const { return false; } | |
3956 virtual EffectSet Effects() const { return EffectSet::None(); } | |
3957 virtual EffectSet Dependencies() const { return EffectSet::All(); } | |
3958 virtual bool AttributesEqual(Instruction* other) const; | |
3959 | |
3960 virtual bool MayThrow() const { return false; } | |
3961 | |
3962 private: | |
3963 const intptr_t class_id_; | |
3964 const intptr_t token_pos_; | |
3965 const intptr_t element_count_; | |
3966 | |
3967 DISALLOW_COPY_AND_ASSIGN(LoadCodeUnitsInstr); | |
3968 }; | |
3969 | |
3970 | |
3810 class StringFromCharCodeInstr : public TemplateDefinition<1> { | 3971 class StringFromCharCodeInstr : public TemplateDefinition<1> { |
3811 public: | 3972 public: |
3812 StringFromCharCodeInstr(Value* char_code, intptr_t cid) : cid_(cid) { | 3973 StringFromCharCodeInstr(Value* char_code, intptr_t cid) : cid_(cid) { |
3813 ASSERT(char_code != NULL); | 3974 ASSERT(char_code != NULL); |
3814 ASSERT(char_code->definition()->IsLoadIndexed()); | 3975 ASSERT(char_code->definition()->IsLoadIndexed()); |
3815 ASSERT(char_code->definition()->AsLoadIndexed()->class_id() == | 3976 ASSERT(char_code->definition()->AsLoadIndexed()->class_id() == |
3816 kOneByteStringCid); | 3977 kOneByteStringCid); |
3817 SetInputAt(0, char_code); | 3978 SetInputAt(0, char_code); |
3818 } | 3979 } |
3819 | 3980 |
(...skipping 1214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5034 | 5195 |
5035 static const char* KindToCString(MathUnaryKind kind); | 5196 static const char* KindToCString(MathUnaryKind kind); |
5036 | 5197 |
5037 private: | 5198 private: |
5038 const MathUnaryKind kind_; | 5199 const MathUnaryKind kind_; |
5039 | 5200 |
5040 DISALLOW_COPY_AND_ASSIGN(MathUnaryInstr); | 5201 DISALLOW_COPY_AND_ASSIGN(MathUnaryInstr); |
5041 }; | 5202 }; |
5042 | 5203 |
5043 | 5204 |
5205 // Calls into the runtime and performs a case-insensitive comparison of the | |
5206 // UTF16 strings (i.e. TwoByteString or ExternalTwoByteString) located at | |
5207 // str[lhs_index:lhs_index + length] and str[rhs_index:rhs_index + length]. | |
5208 // | |
5209 // TODO(jgruber): Remove this once (if) functions inherited from unibrow | |
5210 // are moved to dart code. | |
5211 class CaseInsensitiveCompareUC16Instr : public TemplateDefinition<4> { | |
5212 public: | |
5213 CaseInsensitiveCompareUC16Instr( | |
5214 Value* str, | |
5215 Value* lhs_index, | |
5216 Value* rhs_index, | |
5217 Value* length, | |
5218 intptr_t cid) | |
5219 : cid_(cid) { | |
5220 ASSERT(cid == kTwoByteStringCid || cid == kExternalTwoByteStringCid); | |
5221 ASSERT(index_scale() == 2); | |
5222 SetInputAt(0, str); | |
5223 SetInputAt(1, lhs_index); | |
5224 SetInputAt(2, rhs_index); | |
5225 SetInputAt(3, length); | |
5226 } | |
5227 | |
5228 Value* str() const { return inputs_[0]; } | |
5229 Value* lhs_index() const { return inputs_[1]; } | |
5230 Value* rhs_index() const { return inputs_[2]; } | |
5231 Value* length() const { return inputs_[3]; } | |
5232 | |
5233 const RuntimeEntry& TargetFunction() const; | |
5234 bool IsExternal() const { return cid_ == kExternalTwoByteStringCid; } | |
5235 intptr_t class_id() const { return cid_; } | |
5236 intptr_t index_scale() const { return Instance::ElementSizeFor(cid_); } | |
5237 | |
5238 virtual bool CanDeoptimize() const { return false; } | |
5239 | |
5240 virtual Representation representation() const { | |
5241 return kTagged; | |
5242 } | |
5243 | |
5244 DECLARE_INSTRUCTION(CaseInsensitiveCompareUC16) | |
5245 virtual CompileType ComputeType() const; | |
5246 | |
5247 virtual bool AllowsCSE() const { return true; } | |
5248 virtual EffectSet Effects() const { return EffectSet::None(); } | |
5249 virtual EffectSet Dependencies() const { return EffectSet::None(); } | |
5250 | |
5251 virtual bool MayThrow() const { return false; } | |
5252 | |
5253 private: | |
5254 const intptr_t cid_; | |
5255 | |
5256 DISALLOW_COPY_AND_ASSIGN(CaseInsensitiveCompareUC16Instr); | |
5257 }; | |
5258 | |
5259 | |
5044 // Represents Math's static min and max functions. | 5260 // Represents Math's static min and max functions. |
5045 class MathMinMaxInstr : public TemplateDefinition<2> { | 5261 class MathMinMaxInstr : public TemplateDefinition<2> { |
5046 public: | 5262 public: |
5047 MathMinMaxInstr(MethodRecognizer::Kind op_kind, | 5263 MathMinMaxInstr(MethodRecognizer::Kind op_kind, |
5048 Value* left_value, | 5264 Value* left_value, |
5049 Value* right_value, | 5265 Value* right_value, |
5050 intptr_t deopt_id, | 5266 intptr_t deopt_id, |
5051 intptr_t result_cid) | 5267 intptr_t result_cid) |
5052 : op_kind_(op_kind), result_cid_(result_cid) { | 5268 : op_kind_(op_kind), result_cid_(result_cid) { |
5053 ASSERT((result_cid == kSmiCid) || (result_cid == kDoubleCid)); | 5269 ASSERT((result_cid == kSmiCid) || (result_cid == kDoubleCid)); |
(...skipping 3355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8409 Isolate* isolate, bool opt) const { \ | 8625 Isolate* isolate, bool opt) const { \ |
8410 UNIMPLEMENTED(); \ | 8626 UNIMPLEMENTED(); \ |
8411 return NULL; \ | 8627 return NULL; \ |
8412 } \ | 8628 } \ |
8413 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } | 8629 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } |
8414 | 8630 |
8415 | 8631 |
8416 } // namespace dart | 8632 } // namespace dart |
8417 | 8633 |
8418 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 8634 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
OLD | NEW |