Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(366)

Side by Side Diff: runtime/vm/intermediate_language.h

Issue 683433003: Integrate the Irregexp Regular Expression Engine. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: more comments Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/il_printer.cc ('k') | runtime/vm/intermediate_language.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 423
424 // Instructions. 424 // Instructions.
425 425
426 // M is a single argument macro. It is applied to each concrete instruction 426 // M is a single argument macro. It is applied to each concrete instruction
427 // type name. The concrete instruction classes are the name with Instr 427 // type name. The concrete instruction classes are the name with Instr
428 // concatenated. 428 // concatenated.
429 #define FOR_EACH_INSTRUCTION(M) \ 429 #define FOR_EACH_INSTRUCTION(M) \
430 M(GraphEntry) \ 430 M(GraphEntry) \
431 M(JoinEntry) \ 431 M(JoinEntry) \
432 M(TargetEntry) \ 432 M(TargetEntry) \
433 M(IndirectEntry) \
433 M(CatchBlockEntry) \ 434 M(CatchBlockEntry) \
434 M(Phi) \ 435 M(Phi) \
435 M(Redefinition) \ 436 M(Redefinition) \
436 M(Parameter) \ 437 M(Parameter) \
437 M(ParallelMove) \ 438 M(ParallelMove) \
438 M(PushArgument) \ 439 M(PushArgument) \
439 M(Return) \ 440 M(Return) \
440 M(Throw) \ 441 M(Throw) \
441 M(ReThrow) \ 442 M(ReThrow) \
442 M(Goto) \ 443 M(Goto) \
444 M(IndirectGoto) \
443 M(Branch) \ 445 M(Branch) \
444 M(AssertAssignable) \ 446 M(AssertAssignable) \
445 M(AssertBoolean) \ 447 M(AssertBoolean) \
446 M(CurrentContext) \ 448 M(CurrentContext) \
447 M(ClosureCall) \ 449 M(ClosureCall) \
448 M(InstanceCall) \ 450 M(InstanceCall) \
449 M(PolymorphicInstanceCall) \ 451 M(PolymorphicInstanceCall) \
450 M(StaticCall) \ 452 M(StaticCall) \
451 M(LoadLocal) \ 453 M(LoadLocal) \
452 M(PushTemp) \ 454 M(PushTemp) \
453 M(DropTemps) \ 455 M(DropTemps) \
454 M(StoreLocal) \ 456 M(StoreLocal) \
455 M(StrictCompare) \ 457 M(StrictCompare) \
456 M(EqualityCompare) \ 458 M(EqualityCompare) \
457 M(RelationalOp) \ 459 M(RelationalOp) \
458 M(NativeCall) \ 460 M(NativeCall) \
459 M(DebugStepCheck) \ 461 M(DebugStepCheck) \
460 M(LoadIndexed) \ 462 M(LoadIndexed) \
463 M(LoadCodeUnits) \
461 M(StoreIndexed) \ 464 M(StoreIndexed) \
462 M(StoreInstanceField) \ 465 M(StoreInstanceField) \
463 M(InitStaticField) \ 466 M(InitStaticField) \
464 M(LoadStaticField) \ 467 M(LoadStaticField) \
465 M(StoreStaticField) \ 468 M(StoreStaticField) \
466 M(BooleanNegate) \ 469 M(BooleanNegate) \
467 M(InstanceOf) \ 470 M(InstanceOf) \
468 M(CreateArray) \ 471 M(CreateArray) \
469 M(AllocateObject) \ 472 M(AllocateObject) \
470 M(LoadField) \ 473 M(LoadField) \
(...skipping 23 matching lines...) Expand all
494 M(Constant) \ 497 M(Constant) \
495 M(UnboxedConstant) \ 498 M(UnboxedConstant) \
496 M(CheckEitherNonSmi) \ 499 M(CheckEitherNonSmi) \
497 M(BinaryDoubleOp) \ 500 M(BinaryDoubleOp) \
498 M(MathUnary) \ 501 M(MathUnary) \
499 M(MathMinMax) \ 502 M(MathMinMax) \
500 M(Box) \ 503 M(Box) \
501 M(Unbox) \ 504 M(Unbox) \
502 M(BoxInt64) \ 505 M(BoxInt64) \
503 M(UnboxInt64) \ 506 M(UnboxInt64) \
507 M(CaseInsensitiveCompareUC16) \
504 M(BinaryMintOp) \ 508 M(BinaryMintOp) \
505 M(ShiftMintOp) \ 509 M(ShiftMintOp) \
506 M(UnaryMintOp) \ 510 M(UnaryMintOp) \
507 M(CheckArrayBound) \ 511 M(CheckArrayBound) \
508 M(Constraint) \ 512 M(Constraint) \
509 M(StringToCharCode) \ 513 M(StringToCharCode) \
510 M(StringFromCharCode) \ 514 M(StringFromCharCode) \
511 M(StringInterpolate) \ 515 M(StringInterpolate) \
512 M(InvokeMathCFunction) \ 516 M(InvokeMathCFunction) \
513 M(MergedMath) \ 517 M(MergedMath) \
(...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after
1160 return const_cast<BlockEntryInstr*>(this); 1164 return const_cast<BlockEntryInstr*>(this);
1161 } 1165 }
1162 1166
1163 // Helper to mutate the graph during inlining. This block should be 1167 // Helper to mutate the graph during inlining. This block should be
1164 // replaced with new_block as a predecessor of all of this block's 1168 // replaced with new_block as a predecessor of all of this block's
1165 // successors. 1169 // successors.
1166 void ReplaceAsPredecessorWith(BlockEntryInstr* new_block); 1170 void ReplaceAsPredecessorWith(BlockEntryInstr* new_block);
1167 1171
1168 void set_block_id(intptr_t block_id) { block_id_ = block_id; } 1172 void set_block_id(intptr_t block_id) { block_id_ = block_id; }
1169 1173
1174 intptr_t offset() const { return offset_; }
1175 void set_offset(intptr_t offset) { offset_ = offset; }
1176
1170 // For all instruction in this block: Remove all inputs (including in the 1177 // For all instruction in this block: Remove all inputs (including in the
1171 // environment) from their definition's use lists for all instructions. 1178 // environment) from their definition's use lists for all instructions.
1172 void ClearAllInstructions(); 1179 void ClearAllInstructions();
1173 1180
1174 DEFINE_INSTRUCTION_TYPE_CHECK(BlockEntry) 1181 DEFINE_INSTRUCTION_TYPE_CHECK(BlockEntry)
1175 1182
1176 protected: 1183 protected:
1177 BlockEntryInstr(intptr_t block_id, intptr_t try_index) 1184 BlockEntryInstr(intptr_t block_id, intptr_t try_index)
1178 : Instruction(Isolate::Current()->GetNextDeoptId()), 1185 : Instruction(Isolate::Current()->GetNextDeoptId()),
1179 block_id_(block_id), 1186 block_id_(block_id),
1180 try_index_(try_index), 1187 try_index_(try_index),
1181 preorder_number_(-1), 1188 preorder_number_(-1),
1182 postorder_number_(-1), 1189 postorder_number_(-1),
1183 dominator_(NULL), 1190 dominator_(NULL),
1184 dominated_blocks_(1), 1191 dominated_blocks_(1),
1185 last_instruction_(NULL), 1192 last_instruction_(NULL),
1193 offset_(-1),
1186 parallel_move_(NULL), 1194 parallel_move_(NULL),
1187 loop_info_(NULL) { 1195 loop_info_(NULL) {
1188 } 1196 }
1189 1197
1190 private: 1198 private:
1191 virtual void RawSetInputAt(intptr_t i, Value* value) { UNREACHABLE(); } 1199 virtual void RawSetInputAt(intptr_t i, Value* value) { UNREACHABLE(); }
1192 1200
1193 virtual void ClearPredecessors() = 0; 1201 virtual void ClearPredecessors() = 0;
1194 virtual void AddPredecessor(BlockEntryInstr* predecessor) = 0; 1202 virtual void AddPredecessor(BlockEntryInstr* predecessor) = 0;
1195 1203
1196 void set_dominator(BlockEntryInstr* instr) { dominator_ = instr; } 1204 void set_dominator(BlockEntryInstr* instr) { dominator_ = instr; }
1197 1205
1198 intptr_t block_id_; 1206 intptr_t block_id_;
1199 const intptr_t try_index_; 1207 const intptr_t try_index_;
1200 intptr_t preorder_number_; 1208 intptr_t preorder_number_;
1201 intptr_t postorder_number_; 1209 intptr_t postorder_number_;
1202 // Starting and ending lifetime positions for this block. Used by 1210 // Starting and ending lifetime positions for this block. Used by
1203 // the linear scan register allocator. 1211 // the linear scan register allocator.
1204 intptr_t start_pos_; 1212 intptr_t start_pos_;
1205 intptr_t end_pos_; 1213 intptr_t end_pos_;
1206 BlockEntryInstr* dominator_; // Immediate dominator, NULL for graph entry. 1214 BlockEntryInstr* dominator_; // Immediate dominator, NULL for graph entry.
1207 // TODO(fschneider): Optimize the case of one child to save space. 1215 // TODO(fschneider): Optimize the case of one child to save space.
1208 GrowableArray<BlockEntryInstr*> dominated_blocks_; 1216 GrowableArray<BlockEntryInstr*> dominated_blocks_;
1209 Instruction* last_instruction_; 1217 Instruction* last_instruction_;
1210 1218
1219 // Offset of this block from the start of the emitted code.
1220 intptr_t offset_;
1221
1211 // Parallel move that will be used by linear scan register allocator to 1222 // Parallel move that will be used by linear scan register allocator to
1212 // connect live ranges at the start of the block. 1223 // connect live ranges at the start of the block.
1213 ParallelMoveInstr* parallel_move_; 1224 ParallelMoveInstr* parallel_move_;
1214 1225
1215 // Bit vector containg loop blocks for a loop header indexed by block 1226 // Bit vector containg loop blocks for a loop header indexed by block
1216 // preorder number. 1227 // preorder number.
1217 BitVector* loop_info_; 1228 BitVector* loop_info_;
1218 1229
1219 DISALLOW_COPY_AND_ASSIGN(BlockEntryInstr); 1230 DISALLOW_COPY_AND_ASSIGN(BlockEntryInstr);
1220 }; 1231 };
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1281 UNREACHABLE(); 1292 UNREACHABLE();
1282 return NULL; 1293 return NULL;
1283 } 1294 }
1284 virtual intptr_t SuccessorCount() const; 1295 virtual intptr_t SuccessorCount() const;
1285 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; 1296 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const;
1286 1297
1287 void AddCatchEntry(CatchBlockEntryInstr* entry) { catch_entries_.Add(entry); } 1298 void AddCatchEntry(CatchBlockEntryInstr* entry) { catch_entries_.Add(entry); }
1288 1299
1289 CatchBlockEntryInstr* GetCatchEntry(intptr_t index); 1300 CatchBlockEntryInstr* GetCatchEntry(intptr_t index);
1290 1301
1302 void AddIndirectEntry(IndirectEntryInstr* entry) {
1303 indirect_entries_.Add(entry);
1304 }
1305
1291 GrowableArray<Definition*>* initial_definitions() { 1306 GrowableArray<Definition*>* initial_definitions() {
1292 return &initial_definitions_; 1307 return &initial_definitions_;
1293 } 1308 }
1294 ConstantInstr* constant_null(); 1309 ConstantInstr* constant_null();
1295 1310
1296 bool IsCompiledForOsr() const { return osr_id_ != Isolate::kNoDeoptId; } 1311 bool IsCompiledForOsr() const { return osr_id_ != Isolate::kNoDeoptId; }
1297 1312
1298 intptr_t entry_count() const { return entry_count_; } 1313 intptr_t entry_count() const { return entry_count_; }
1299 void set_entry_count(intptr_t count) { entry_count_ = count; } 1314 void set_entry_count(intptr_t count) { entry_count_ = count; }
1300 1315
(...skipping 14 matching lines...) Expand all
1315 TargetEntryInstr* normal_entry() const { return normal_entry_; } 1330 TargetEntryInstr* normal_entry() const { return normal_entry_; }
1316 1331
1317 const ParsedFunction& parsed_function() const { 1332 const ParsedFunction& parsed_function() const {
1318 return *parsed_function_; 1333 return *parsed_function_;
1319 } 1334 }
1320 1335
1321 const GrowableArray<CatchBlockEntryInstr*>& catch_entries() const { 1336 const GrowableArray<CatchBlockEntryInstr*>& catch_entries() const {
1322 return catch_entries_; 1337 return catch_entries_;
1323 } 1338 }
1324 1339
1340 const GrowableArray<IndirectEntryInstr*>& indirect_entries() const {
1341 return indirect_entries_;
1342 }
1343
1325 virtual void PrintTo(BufferFormatter* f) const; 1344 virtual void PrintTo(BufferFormatter* f) const;
1326 1345
1327 private: 1346 private:
1328 virtual void ClearPredecessors() {} 1347 virtual void ClearPredecessors() {}
1329 virtual void AddPredecessor(BlockEntryInstr* predecessor) { UNREACHABLE(); } 1348 virtual void AddPredecessor(BlockEntryInstr* predecessor) { UNREACHABLE(); }
1330 1349
1331 const ParsedFunction* parsed_function_; 1350 const ParsedFunction* parsed_function_;
1332 TargetEntryInstr* normal_entry_; 1351 TargetEntryInstr* normal_entry_;
1333 GrowableArray<CatchBlockEntryInstr*> catch_entries_; 1352 GrowableArray<CatchBlockEntryInstr*> catch_entries_;
1353 // Indirect targets are blocks reachable only through indirect gotos.
1354 GrowableArray<IndirectEntryInstr*> indirect_entries_;
1334 GrowableArray<Definition*> initial_definitions_; 1355 GrowableArray<Definition*> initial_definitions_;
1335 const intptr_t osr_id_; 1356 const intptr_t osr_id_;
1336 intptr_t entry_count_; 1357 intptr_t entry_count_;
1337 intptr_t spill_slot_count_; 1358 intptr_t spill_slot_count_;
1338 intptr_t fixed_slot_count_; // For try-catch in optimized code. 1359 intptr_t fixed_slot_count_; // For try-catch in optimized code.
1339 1360
1340 DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr); 1361 DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr);
1341 }; 1362 };
1342 1363
1343 1364
(...skipping 25 matching lines...) Expand all
1369 virtual void PrintTo(BufferFormatter* f) const; 1390 virtual void PrintTo(BufferFormatter* f) const;
1370 1391
1371 virtual EffectSet Effects() const { return EffectSet::None(); } 1392 virtual EffectSet Effects() const { return EffectSet::None(); }
1372 virtual EffectSet Dependencies() const { return EffectSet::None(); } 1393 virtual EffectSet Dependencies() const { return EffectSet::None(); }
1373 1394
1374 private: 1395 private:
1375 // Classes that have access to predecessors_ when inlining. 1396 // Classes that have access to predecessors_ when inlining.
1376 friend class BlockEntryInstr; 1397 friend class BlockEntryInstr;
1377 friend class InlineExitCollector; 1398 friend class InlineExitCollector;
1378 friend class PolymorphicInliner; 1399 friend class PolymorphicInliner;
1400 friend class IndirectEntryInstr; // Access in il_printer.cc.
1379 1401
1380 // Direct access to phis_ in order to resize it due to phi elimination. 1402 // Direct access to phis_ in order to resize it due to phi elimination.
1381 friend class ConstantPropagator; 1403 friend class ConstantPropagator;
1382 friend class DeadCodeElimination; 1404 friend class DeadCodeElimination;
1383 1405
1384 virtual void ClearPredecessors() { predecessors_.Clear(); } 1406 virtual void ClearPredecessors() { predecessors_.Clear(); }
1385 virtual void AddPredecessor(BlockEntryInstr* predecessor); 1407 virtual void AddPredecessor(BlockEntryInstr* predecessor);
1386 1408
1387 GrowableArray<BlockEntryInstr*> predecessors_; 1409 GrowableArray<BlockEntryInstr*> predecessors_;
1388 ZoneGrowableArray<PhiInstr*>* phis_; 1410 ZoneGrowableArray<PhiInstr*>* phis_;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1447 predecessor_ = predecessor; 1469 predecessor_ = predecessor;
1448 } 1470 }
1449 1471
1450 BlockEntryInstr* predecessor_; 1472 BlockEntryInstr* predecessor_;
1451 double edge_weight_; 1473 double edge_weight_;
1452 1474
1453 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); 1475 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr);
1454 }; 1476 };
1455 1477
1456 1478
1479 class IndirectEntryInstr : public JoinEntryInstr {
1480 public:
1481 IndirectEntryInstr(intptr_t block_id,
1482 intptr_t indirect_id,
1483 intptr_t try_index)
1484 : JoinEntryInstr(block_id, try_index),
1485 indirect_id_(indirect_id) { }
1486
1487 DECLARE_INSTRUCTION(IndirectEntry)
1488
1489 virtual void PrintTo(BufferFormatter* f) const;
1490
1491 intptr_t indirect_id() const { return indirect_id_; }
1492
1493 private:
1494 const intptr_t indirect_id_;
1495 };
1496
1497
1457 class CatchBlockEntryInstr : public BlockEntryInstr { 1498 class CatchBlockEntryInstr : public BlockEntryInstr {
1458 public: 1499 public:
1459 CatchBlockEntryInstr(intptr_t block_id, 1500 CatchBlockEntryInstr(intptr_t block_id,
1460 intptr_t try_index, 1501 intptr_t try_index,
1461 const Array& handler_types, 1502 const Array& handler_types,
1462 intptr_t catch_try_index, 1503 intptr_t catch_try_index,
1463 const LocalVariable& exception_var, 1504 const LocalVariable& exception_var,
1464 const LocalVariable& stacktrace_var, 1505 const LocalVariable& stacktrace_var,
1465 bool needs_stacktrace) 1506 bool needs_stacktrace)
1466 : BlockEntryInstr(block_id, try_index), 1507 : BlockEntryInstr(block_id, try_index),
(...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after
2119 private: 2160 private:
2120 JoinEntryInstr* successor_; 2161 JoinEntryInstr* successor_;
2121 double edge_weight_; 2162 double edge_weight_;
2122 2163
2123 // Parallel move that will be used by linear scan register allocator to 2164 // Parallel move that will be used by linear scan register allocator to
2124 // connect live ranges at the end of the block and resolve phis. 2165 // connect live ranges at the end of the block and resolve phis.
2125 ParallelMoveInstr* parallel_move_; 2166 ParallelMoveInstr* parallel_move_;
2126 }; 2167 };
2127 2168
2128 2169
2170 // IndirectGotoInstr represents a dynamically computed jump. Only
2171 // IndirectEntryInstr targets are valid targets of an indirect goto. The
2172 // concrete target to jump to is given as a parameter to the indirect goto.
2173 //
2174 // In order to preserve split-edge form, an indirect goto does not itself point
2175 // to its targets. Instead, for each possible target, the successors_ field
2176 // will contain an ordinary goto instruction that jumps to the target.
2177 //
2178 // Byte offsets of all possible targets are stored in the offsets_ array. The
2179 // desired offset is looked up while the generated code is executing, and passed
2180 // to IndirectGoto as an input.
2181 class IndirectGotoInstr : public TemplateInstruction<1, NoThrow> {
2182 public:
2183 IndirectGotoInstr(GrowableObjectArray* offsets,
2184 Value* offset_from_start)
2185 : offsets_(*offsets) {
2186 SetInputAt(0, offset_from_start);
2187 }
2188
2189 DECLARE_INSTRUCTION(IndirectGoto)
2190
2191 virtual intptr_t ArgumentCount() const { return 0; }
2192
2193 void AddSuccessor(TargetEntryInstr* successor) {
2194 ASSERT(successor->next()->IsGoto());
2195 ASSERT(successor->next()->AsGoto()->successor()->IsIndirectEntry());
2196 successors_.Add(successor);
2197 }
2198
2199 virtual intptr_t SuccessorCount() const { return successors_.length(); }
2200 virtual TargetEntryInstr* SuccessorAt(intptr_t index) const {
2201 ASSERT(index < SuccessorCount());
2202 return successors_[index];
2203 }
2204
2205 virtual bool CanDeoptimize() const { return false; }
2206 virtual bool CanBecomeDeoptimizationTarget() const { return false; }
2207
2208 virtual EffectSet Effects() const { return EffectSet::None(); }
2209
2210 virtual void PrintTo(BufferFormatter* f) const;
2211
2212 const GrowableObjectArray& offsets() const { return offsets_; }
2213 void SetOffsetCount(Isolate* isolate, intptr_t count) {
2214 if (offsets_.Capacity() < count) {
2215 offsets_.Grow(count, Heap::kOld);
2216 }
2217 if (offsets_.Length() < count) {
2218 offsets_.SetLength(count);
2219 }
2220 }
2221 void SetOffsetAt(Isolate* isolate, intptr_t index, intptr_t offset) {
2222 offsets_.SetAt(index, Smi::ZoneHandle(isolate, Smi::New(offset)));
2223 }
2224
2225 private:
2226 GrowableArray<TargetEntryInstr*> successors_;
2227 GrowableObjectArray& offsets_;
2228 };
2229
2230
2129 class ComparisonInstr : public TemplateDefinition<2, NoThrow, Pure> { 2231 class ComparisonInstr : public TemplateDefinition<2, NoThrow, Pure> {
2130 public: 2232 public:
2131 Value* left() const { return inputs_[0]; } 2233 Value* left() const { return inputs_[0]; }
2132 Value* right() const { return inputs_[1]; } 2234 Value* right() const { return inputs_[1]; }
2133 2235
2134 virtual intptr_t token_pos() const { return token_pos_; } 2236 virtual intptr_t token_pos() const { return token_pos_; }
2135 Token::Kind kind() const { return kind_; } 2237 Token::Kind kind() const { return kind_; }
2136 2238
2137 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right) = 0; 2239 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right) = 0;
2138 2240
(...skipping 1437 matching lines...) Expand 10 before | Expand all | Expand 10 after
3576 3678
3577 private: 3679 private:
3578 const intptr_t index_scale_; 3680 const intptr_t index_scale_;
3579 const intptr_t class_id_; 3681 const intptr_t class_id_;
3580 const intptr_t token_pos_; 3682 const intptr_t token_pos_;
3581 3683
3582 DISALLOW_COPY_AND_ASSIGN(LoadIndexedInstr); 3684 DISALLOW_COPY_AND_ASSIGN(LoadIndexedInstr);
3583 }; 3685 };
3584 3686
3585 3687
3688 // Loads the specified number of code units from the given string, packing
3689 // multiple code units into a single datatype. In essence, this is a specialized
3690 // version of LoadIndexedInstr which accepts only string targets and can load
3691 // multiple elements at once. The result datatype differs depending on the
3692 // string type, element count, and architecture; if possible, the result is
3693 // packed into a Smi, falling back to a Mint otherwise.
3694 // TODO(zerny): Add support for loading into UnboxedInt32x4.
3695 class LoadCodeUnitsInstr : public TemplateDefinition<2, NoThrow> {
3696 public:
3697 LoadCodeUnitsInstr(Value* str,
3698 Value* index,
3699 intptr_t element_count,
3700 intptr_t class_id,
3701 intptr_t token_pos)
3702 : class_id_(class_id),
3703 token_pos_(token_pos),
3704 element_count_(element_count) {
3705 ASSERT(element_count == 1 || element_count == 2 || element_count == 4);
3706 ASSERT(class_id == kOneByteStringCid || class_id == kTwoByteStringCid);
3707 SetInputAt(0, str);
3708 SetInputAt(1, index);
3709 }
3710
3711 intptr_t token_pos() const { return token_pos_; }
3712
3713 DECLARE_INSTRUCTION(LoadCodeUnits)
3714 virtual CompileType ComputeType() const;
3715
3716 bool IsExternal() const {
3717 return array()->definition()->representation() == kUntagged;
3718 }
3719
3720 Value* array() const { return inputs_[0]; }
3721 Value* index() const { return inputs_[1]; }
3722 intptr_t index_scale() const { return Instance::ElementSizeFor(class_id_); }
3723 intptr_t class_id() const { return class_id_; }
3724 intptr_t element_count() const { return element_count_; }
3725
3726 bool can_pack_into_smi() const {
3727 return element_count() <= kSmiBits / (index_scale() * kBitsPerByte);
3728 }
3729
3730 virtual bool CanDeoptimize() const { return false; }
3731
3732 virtual Representation representation() const;
3733 virtual void InferRange(RangeAnalysis* analysis, Range* range);
3734
3735 virtual EffectSet Effects() const { return EffectSet::None(); }
3736
3737 private:
3738 const intptr_t class_id_;
3739 const intptr_t token_pos_;
3740 const intptr_t element_count_;
3741
3742 DISALLOW_COPY_AND_ASSIGN(LoadCodeUnitsInstr);
3743 };
3744
3745
3586 class StringFromCharCodeInstr : public TemplateDefinition<1, NoThrow, Pure> { 3746 class StringFromCharCodeInstr : public TemplateDefinition<1, NoThrow, Pure> {
3587 public: 3747 public:
3588 StringFromCharCodeInstr(Value* char_code, intptr_t cid) : cid_(cid) { 3748 StringFromCharCodeInstr(Value* char_code, intptr_t cid) : cid_(cid) {
3589 ASSERT(char_code != NULL); 3749 ASSERT(char_code != NULL);
3590 ASSERT(char_code->definition()->IsLoadIndexed()); 3750 ASSERT(char_code->definition()->IsLoadIndexed());
3591 ASSERT(char_code->definition()->AsLoadIndexed()->class_id() == 3751 ASSERT(char_code->definition()->AsLoadIndexed()->class_id() ==
3592 kOneByteStringCid); 3752 kOneByteStringCid);
3593 SetInputAt(0, char_code); 3753 SetInputAt(0, char_code);
3594 } 3754 }
3595 3755
(...skipping 1184 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 2963 matching lines...) Expand 10 before | Expand all | Expand 10 after
7763 Isolate* isolate, bool opt) const { \ 7977 Isolate* isolate, bool opt) const { \
7764 UNIMPLEMENTED(); \ 7978 UNIMPLEMENTED(); \
7765 return NULL; \ 7979 return NULL; \
7766 } \ 7980 } \
7767 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } 7981 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); }
7768 7982
7769 7983
7770 } // namespace dart 7984 } // namespace dart
7771 7985
7772 #endif // VM_INTERMEDIATE_LANGUAGE_H_ 7986 #endif // VM_INTERMEDIATE_LANGUAGE_H_
OLDNEW
« no previous file with comments | « runtime/vm/il_printer.cc ('k') | runtime/vm/intermediate_language.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698