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

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

Issue 10912094: Reapply "Remove classes Computation and BindInstr." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 3 months 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
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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"
11 #include "vm/handles_impl.h" 11 #include "vm/handles_impl.h"
12 #include "vm/locations.h" 12 #include "vm/locations.h"
13 #include "vm/object.h" 13 #include "vm/object.h"
14 14
15 namespace dart { 15 namespace dart {
16 16
17 class BindInstr;
18 class BitVector; 17 class BitVector;
19 class BlockEntryInstr; 18 class BlockEntryInstr;
20 class BufferFormatter; 19 class BufferFormatter;
21 class ComparisonComp; 20 class ComparisonInstr;
22 class ConstantComp;
23 class Computation;
24 class ControlInstruction; 21 class ControlInstruction;
25 class Definition; 22 class Definition;
26 class Environment; 23 class Environment;
27 class FlowGraphCompiler; 24 class FlowGraphCompiler;
28 class FlowGraphVisitor; 25 class FlowGraphVisitor;
29 class Instruction; 26 class Instruction;
30 class LocalVariable; 27 class LocalVariable;
31 28
32 29
33 // TODO(srdjan): Add _ByteArrayBase, get:length. 30 // TODO(srdjan): Add _ByteArrayBase, get:length.
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 // Instructions. 175 // Instructions.
179 176
180 // M is a single argument macro. It is applied to each concrete instruction 177 // M is a single argument macro. It is applied to each concrete instruction
181 // type name. The concrete instruction classes are the name with Instr 178 // type name. The concrete instruction classes are the name with Instr
182 // concatenated. 179 // concatenated.
183 #define FOR_EACH_INSTRUCTION(M) \ 180 #define FOR_EACH_INSTRUCTION(M) \
184 M(GraphEntry) \ 181 M(GraphEntry) \
185 M(JoinEntry) \ 182 M(JoinEntry) \
186 M(TargetEntry) \ 183 M(TargetEntry) \
187 M(Phi) \ 184 M(Phi) \
188 M(Bind) \
189 M(Parameter) \ 185 M(Parameter) \
190 M(ParallelMove) \ 186 M(ParallelMove) \
191 M(PushArgument) \ 187 M(PushArgument) \
192 M(Return) \ 188 M(Return) \
193 M(Throw) \ 189 M(Throw) \
194 M(ReThrow) \ 190 M(ReThrow) \
195 M(Goto) \ 191 M(Goto) \
196 M(Branch) \ 192 M(Branch) \
193 M(AssertAssignable) \
194 M(AssertBoolean) \
195 M(ArgumentDefinitionTest) \
196 M(CurrentContext) \
197 M(StoreContext) \
198 M(ClosureCall) \
199 M(InstanceCall) \
200 M(PolymorphicInstanceCall) \
201 M(StaticCall) \
202 M(LoadLocal) \
203 M(StoreLocal) \
204 M(StrictCompare) \
205 M(EqualityCompare) \
206 M(RelationalOp) \
207 M(NativeCall) \
208 M(LoadIndexed) \
209 M(StoreIndexed) \
210 M(LoadInstanceField) \
211 M(StoreInstanceField) \
212 M(LoadStaticField) \
213 M(StoreStaticField) \
214 M(BooleanNegate) \
215 M(InstanceOf) \
216 M(CreateArray) \
217 M(CreateClosure) \
218 M(AllocateObject) \
219 M(AllocateObjectWithBoundsCheck) \
220 M(LoadVMField) \
221 M(StoreVMField) \
222 M(InstantiateTypeArguments) \
223 M(ExtractConstructorTypeArguments) \
224 M(ExtractConstructorInstantiator) \
225 M(AllocateContext) \
226 M(ChainContext) \
227 M(CloneContext) \
228 M(CatchEntry) \
229 M(BinarySmiOp) \
230 M(BinaryMintOp) \
231 M(UnarySmiOp) \
232 M(NumberNegate) \
233 M(CheckStackOverflow) \
234 M(DoubleToDouble) \
235 M(SmiToDouble) \
236 M(CheckClass) \
237 M(CheckSmi) \
238 M(Constant) \
239 M(CheckEitherNonSmi) \
240 M(UnboxedDoubleBinaryOp) \
241 M(UnboxDouble) \
242 M(BoxDouble) \
243 M(CheckArrayBound) \
197 244
198 245
199 #define FORWARD_DECLARATION(type) class type##Instr; 246 #define FORWARD_DECLARATION(type) class type##Instr;
200 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) 247 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION)
201 #undef FORWARD_DECLARATION 248 #undef FORWARD_DECLARATION
202 249
203 250
204 // Functions required in all concrete instruction classes. 251 // Functions required in all concrete instruction classes.
205 #define DECLARE_INSTRUCTION(type) \ 252 #define DECLARE_INSTRUCTION(type) \
253 virtual Tag tag() const { return k##type; } \
206 virtual void Accept(FlowGraphVisitor* visitor); \ 254 virtual void Accept(FlowGraphVisitor* visitor); \
207 virtual type##Instr* As##type() { return this; } \ 255 virtual type##Instr* As##type() { return this; } \
208 virtual const char* DebugName() const { return #type; } \ 256 virtual const char* DebugName() const { return #type; } \
209 virtual void PrintTo(BufferFormatter* f) const; \ 257 virtual LocationSummary* MakeLocationSummary() const; \
210 virtual void PrintToVisualizer(BufferFormatter* f) const; 258 virtual void EmitNativeCode(FlowGraphCompiler* compiler); \
211 259
212 260
213 class Instruction : public ZoneAllocated { 261 class Instruction : public ZoneAllocated {
214 public: 262 public:
263 #define DECLARE_TAG(type) k##type,
264 enum Tag {
265 FOR_EACH_INSTRUCTION(DECLARE_TAG)
266 };
267 #undef DECLARE_TAG
268
215 Instruction() 269 Instruction()
216 : lifetime_position_(-1), previous_(NULL), next_(NULL), env_(NULL) { } 270 : deopt_id_(Isolate::Current()->GetNextDeoptId()),
271 lifetime_position_(-1),
272 previous_(NULL),
273 next_(NULL),
274 env_(NULL) { }
275
276 virtual Tag tag() const = 0;
277
278 intptr_t deopt_id() const { return deopt_id_; }
217 279
218 bool IsBlockEntry() { return (AsBlockEntry() != NULL); } 280 bool IsBlockEntry() { return (AsBlockEntry() != NULL); }
219 virtual BlockEntryInstr* AsBlockEntry() { return NULL; } 281 virtual BlockEntryInstr* AsBlockEntry() { return NULL; }
220 282
221 bool IsDefinition() { return (AsDefinition() != NULL); } 283 bool IsDefinition() { return (AsDefinition() != NULL); }
222 virtual Definition* AsDefinition() { return NULL; } 284 virtual Definition* AsDefinition() { return NULL; }
223 285
224 bool IsControl() { return (AsControl() != NULL); } 286 bool IsControl() { return (AsControl() != NULL); }
225 virtual ControlInstruction* AsControl() { return NULL; } 287 virtual ControlInstruction* AsControl() { return NULL; }
226 288
227 virtual intptr_t InputCount() const = 0; 289 virtual intptr_t InputCount() const = 0;
228 virtual Value* InputAt(intptr_t i) const = 0; 290 virtual Value* InputAt(intptr_t i) const = 0;
229 virtual void SetInputAt(intptr_t i, Value* value) = 0; 291 virtual void SetInputAt(intptr_t i, Value* value) = 0;
230 292
231 // Call instructions override this function and return the 293 // Call instructions override this function and return the number of
232 // number of pushed arguments. 294 // pushed arguments.
233 virtual intptr_t ArgumentCount() const = 0; 295 virtual intptr_t ArgumentCount() const = 0;
234 296
235 // Returns true, if this instruction can deoptimize. 297 // Returns true, if this instruction can deoptimize.
236 virtual bool CanDeoptimize() const = 0; 298 virtual bool CanDeoptimize() const = 0;
237 299
238 // Visiting support. 300 // Visiting support.
239 virtual void Accept(FlowGraphVisitor* visitor) = 0; 301 virtual void Accept(FlowGraphVisitor* visitor) = 0;
240 302
241 Instruction* previous() const { return previous_; } 303 Instruction* previous() const { return previous_; }
242 void set_previous(Instruction* instr) { 304 void set_previous(Instruction* instr) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 intptr_t fixed_parameter_count) { 354 intptr_t fixed_parameter_count) {
293 // Never called for instructions except block entries and branches. 355 // Never called for instructions except block entries and branches.
294 UNREACHABLE(); 356 UNREACHABLE();
295 } 357 }
296 358
297 // Mutate assigned_vars to add the local variable index for all 359 // Mutate assigned_vars to add the local variable index for all
298 // frame-allocated locals assigned to by the instruction. 360 // frame-allocated locals assigned to by the instruction.
299 virtual void RecordAssignedVars(BitVector* assigned_vars, 361 virtual void RecordAssignedVars(BitVector* assigned_vars,
300 intptr_t fixed_parameter_count); 362 intptr_t fixed_parameter_count);
301 363
364 virtual const char* DebugName() const = 0;
365
302 // Printing support. 366 // Printing support.
303 virtual void PrintTo(BufferFormatter* f) const = 0; 367 virtual void PrintTo(BufferFormatter* f) const = 0;
304 virtual void PrintToVisualizer(BufferFormatter* f) const = 0; 368 virtual void PrintToVisualizer(BufferFormatter* f) const = 0;
305 369
306 #define INSTRUCTION_TYPE_CHECK(type) \ 370 #define INSTRUCTION_TYPE_CHECK(type) \
307 bool Is##type() { return (As##type() != NULL); } \ 371 bool Is##type() { return (As##type() != NULL); } \
308 virtual type##Instr* As##type() { return NULL; } 372 virtual type##Instr* As##type() { return NULL; }
309 FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK) 373 FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK)
310 #undef INSTRUCTION_TYPE_CHECK 374 #undef INSTRUCTION_TYPE_CHECK
311 375
312 // Returns structure describing location constraints required 376 // Returns structure describing location constraints required
313 // to emit native code for this instruction. 377 // to emit native code for this instruction.
314 virtual LocationSummary* locs() { 378 virtual LocationSummary* locs() {
315 // TODO(vegorov): This should be pure virtual method. 379 // TODO(vegorov): This should be pure virtual method.
316 // However we are temporary using NULL for instructions that 380 // However we are temporary using NULL for instructions that
317 // were not converted to the location based code generation yet. 381 // were not converted to the location based code generation yet.
318 return NULL; 382 return NULL;
319 } 383 }
320 384
385 virtual LocationSummary* MakeLocationSummary() const = 0;
386
387 static LocationSummary* MakeCallSummary();
388
321 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 389 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
322 UNIMPLEMENTED(); 390 UNIMPLEMENTED();
323 } 391 }
324 392
325 Environment* env() const { return env_; } 393 Environment* env() const { return env_; }
326 void set_env(Environment* env) { env_ = env; } 394 void set_env(Environment* env) { env_ = env; }
327 395
328 intptr_t lifetime_position() const { return lifetime_position_; } 396 intptr_t lifetime_position() const { return lifetime_position_; }
329 void set_lifetime_position(intptr_t pos) { 397 void set_lifetime_position(intptr_t pos) {
330 lifetime_position_ = pos; 398 lifetime_position_ = pos;
(...skipping 14 matching lines...) Expand all
345 } 413 }
346 414
347 // Returns deoptimization id that corresponds to the deoptimization target 415 // Returns deoptimization id that corresponds to the deoptimization target
348 // that input operands conversions inserted for this instruction can jump 416 // that input operands conversions inserted for this instruction can jump
349 // to. 417 // to.
350 virtual intptr_t DeoptimizationTarget() const { 418 virtual intptr_t DeoptimizationTarget() const {
351 UNREACHABLE(); 419 UNREACHABLE();
352 return Isolate::kNoDeoptId; 420 return Isolate::kNoDeoptId;
353 } 421 }
354 422
423 protected:
424 // Fetch deopt id without checking if this computation can deoptimize.
425 intptr_t GetDeoptId() const {
426 return deopt_id_;
427 }
428
355 private: 429 private:
356 friend class Definition; // Needed for InsertBefore, InsertAfter. 430 friend class Definition; // Needed for InsertBefore, InsertAfter.
357 431
432 // Classes that set deopt_id_.
433 friend class UnboxDoubleInstr;
434 friend class UnboxedDoubleBinaryOpInstr;
435 friend class CheckClassInstr;
436 friend class CheckSmiInstr;
437 friend class CheckNonSmiInstr;
438 friend class CheckArrayBoundInstr;
439 friend class CheckEitherNonSmiInstr;
440
441 intptr_t deopt_id_;
358 intptr_t lifetime_position_; // Position used by register allocator. 442 intptr_t lifetime_position_; // Position used by register allocator.
359 Instruction* previous_; 443 Instruction* previous_;
360 Instruction* next_; 444 Instruction* next_;
361 Environment* env_; 445 Environment* env_;
362 DISALLOW_COPY_AND_ASSIGN(Instruction); 446 DISALLOW_COPY_AND_ASSIGN(Instruction);
363 }; 447 };
364 448
365 449
366 template<intptr_t N> 450 template<intptr_t N>
367 class TemplateInstruction: public Instruction { 451 class TemplateInstruction: public Instruction {
368 public: 452 public:
369 TemplateInstruction<N>() : locs_(NULL) { } 453 TemplateInstruction<N>() : locs_(NULL) { }
370 454
371 virtual intptr_t InputCount() const { return N; } 455 virtual intptr_t InputCount() const { return N; }
372 virtual Value* InputAt(intptr_t i) const { return inputs_[i]; } 456 virtual Value* InputAt(intptr_t i) const { return inputs_[i]; }
373 virtual void SetInputAt(intptr_t i, Value* value) { 457 virtual void SetInputAt(intptr_t i, Value* value) {
374 ASSERT(value != NULL); 458 ASSERT(value != NULL);
375 inputs_[i] = value; 459 inputs_[i] = value;
376 } 460 }
377 461
378 virtual LocationSummary* locs() { 462 virtual LocationSummary* locs() {
379 if (locs_ == NULL) { 463 if (locs_ == NULL) {
380 locs_ = MakeLocationSummary(); 464 locs_ = MakeLocationSummary();
381 } 465 }
382 return locs_; 466 return locs_;
383 } 467 }
384 468
385 virtual LocationSummary* MakeLocationSummary() const = 0;
386
387 protected: 469 protected:
388 EmbeddedArray<Value*, N> inputs_; 470 EmbeddedArray<Value*, N> inputs_;
389 471
390 private: 472 private:
391 LocationSummary* locs_; 473 LocationSummary* locs_;
392 }; 474 };
393 475
394 476
395 class MoveOperands : public ZoneAllocated { 477 class MoveOperands : public ZoneAllocated {
396 public: 478 public:
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
466 return move; 548 return move;
467 } 549 }
468 550
469 MoveOperands* MoveOperandsAt(intptr_t index) const { return moves_[index]; } 551 MoveOperands* MoveOperandsAt(intptr_t index) const { return moves_[index]; }
470 552
471 void SetSrcSlotAt(intptr_t index, const Location& loc); 553 void SetSrcSlotAt(intptr_t index, const Location& loc);
472 void SetDestSlotAt(intptr_t index, const Location& loc); 554 void SetDestSlotAt(intptr_t index, const Location& loc);
473 555
474 intptr_t NumMoves() const { return moves_.length(); } 556 intptr_t NumMoves() const { return moves_.length(); }
475 557
476 LocationSummary* MakeLocationSummary() const { return NULL; } 558 virtual void PrintTo(BufferFormatter* f) const;
477 559 virtual void PrintToVisualizer(BufferFormatter* f) const;
478 void EmitNativeCode(FlowGraphCompiler* compiler) { UNREACHABLE(); }
479 560
480 private: 561 private:
481 GrowableArray<MoveOperands*> moves_; // Elements cannot be null. 562 GrowableArray<MoveOperands*> moves_; // Elements cannot be null.
482 563
483 DISALLOW_COPY_AND_ASSIGN(ParallelMoveInstr); 564 DISALLOW_COPY_AND_ASSIGN(ParallelMoveInstr);
484 }; 565 };
485 566
486 567
487 // Basic block entries are administrative nodes. There is a distinguished 568 // Basic block entries are administrative nodes. There is a distinguished
488 // graph entry with no predecessor. Joins are the only nodes with multiple 569 // graph entry with no predecessor. Joins are the only nodes with multiple
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
607 void Advance() { 688 void Advance() {
608 ASSERT(!Done()); 689 ASSERT(!Done());
609 current_ = current_->next(); 690 current_ = current_->next();
610 } 691 }
611 692
612 bool Done() const { return current_ == NULL; } 693 bool Done() const { return current_ == NULL; }
613 694
614 // Removes 'current_' from graph and sets 'current_' to previous instruction. 695 // Removes 'current_' from graph and sets 'current_' to previous instruction.
615 void RemoveCurrentFromGraph(); 696 void RemoveCurrentFromGraph();
616 697
698 // Inserts replaces 'current_', which must be a definition, with another
699 // definition. The new definition becomes 'current_'.
700 void ReplaceCurrentWith(Definition* other);
701
617 Instruction* Current() const { return current_; } 702 Instruction* Current() const { return current_; }
618 703
619 private: 704 private:
620 BlockEntryInstr* block_entry_; 705 BlockEntryInstr* block_entry_;
621 Instruction* current_; 706 Instruction* current_;
622 }; 707 };
623 708
624 709
625 class BackwardInstructionIterator : public ValueObject { 710 class BackwardInstructionIterator : public ValueObject {
626 public: 711 public:
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
669 intptr_t variable_count, 754 intptr_t variable_count,
670 intptr_t fixed_parameter_count); 755 intptr_t fixed_parameter_count);
671 756
672 void AddCatchEntry(TargetEntryInstr* entry) { catch_entries_.Add(entry); } 757 void AddCatchEntry(TargetEntryInstr* entry) { catch_entries_.Add(entry); }
673 758
674 virtual void PrepareEntry(FlowGraphCompiler* compiler); 759 virtual void PrepareEntry(FlowGraphCompiler* compiler);
675 760
676 Environment* start_env() const { return start_env_; } 761 Environment* start_env() const { return start_env_; }
677 void set_start_env(Environment* env) { start_env_ = env; } 762 void set_start_env(Environment* env) { start_env_ = env; }
678 763
679 Definition* constant_null() const { return constant_null_; } 764 ConstantInstr* constant_null() const { return constant_null_; }
680 765
681 intptr_t spill_slot_count() const { return spill_slot_count_; } 766 intptr_t spill_slot_count() const { return spill_slot_count_; }
682 void set_spill_slot_count(intptr_t count) { 767 void set_spill_slot_count(intptr_t count) {
683 ASSERT(count >= 0); 768 ASSERT(count >= 0);
684 spill_slot_count_ = count; 769 spill_slot_count_ = count;
685 } 770 }
686 771
687 TargetEntryInstr* normal_entry() const { return normal_entry_; } 772 TargetEntryInstr* normal_entry() const { return normal_entry_; }
688 773
774 virtual void PrintTo(BufferFormatter* f) const;
775 virtual void PrintToVisualizer(BufferFormatter* f) const;
776
689 private: 777 private:
690 TargetEntryInstr* normal_entry_; 778 TargetEntryInstr* normal_entry_;
691 GrowableArray<TargetEntryInstr*> catch_entries_; 779 GrowableArray<TargetEntryInstr*> catch_entries_;
692 Environment* start_env_; 780 Environment* start_env_;
693 Definition* constant_null_; 781 ConstantInstr* constant_null_;
694 intptr_t spill_slot_count_; 782 intptr_t spill_slot_count_;
695 783
696 DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr); 784 DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr);
697 }; 785 };
698 786
699 787
700 class JoinEntryInstr : public BlockEntryInstr { 788 class JoinEntryInstr : public BlockEntryInstr {
701 public: 789 public:
702 explicit JoinEntryInstr(intptr_t try_index) 790 explicit JoinEntryInstr(intptr_t try_index)
703 : BlockEntryInstr(try_index), 791 : BlockEntryInstr(try_index),
(...skipping 16 matching lines...) Expand all
720 808
721 ZoneGrowableArray<PhiInstr*>* phis() const { return phis_; } 809 ZoneGrowableArray<PhiInstr*>* phis() const { return phis_; }
722 810
723 virtual void PrepareEntry(FlowGraphCompiler* compiler); 811 virtual void PrepareEntry(FlowGraphCompiler* compiler);
724 812
725 void InsertPhi(intptr_t var_index, intptr_t var_count); 813 void InsertPhi(intptr_t var_index, intptr_t var_count);
726 void RemoveDeadPhis(); 814 void RemoveDeadPhis();
727 815
728 intptr_t phi_count() const { return phi_count_; } 816 intptr_t phi_count() const { return phi_count_; }
729 817
818 virtual void PrintTo(BufferFormatter* f) const;
819 virtual void PrintToVisualizer(BufferFormatter* f) const;
820
730 private: 821 private:
731 GrowableArray<BlockEntryInstr*> predecessors_; 822 GrowableArray<BlockEntryInstr*> predecessors_;
732 ZoneGrowableArray<PhiInstr*>* phis_; 823 ZoneGrowableArray<PhiInstr*>* phis_;
733 intptr_t phi_count_; 824 intptr_t phi_count_;
734 825
735 DISALLOW_COPY_AND_ASSIGN(JoinEntryInstr); 826 DISALLOW_COPY_AND_ASSIGN(JoinEntryInstr);
736 }; 827 };
737 828
738 829
739 class TargetEntryInstr : public BlockEntryInstr { 830 class TargetEntryInstr : public BlockEntryInstr {
(...skipping 30 matching lines...) Expand all
770 861
771 // Returns try index for the try block to which this catch handler 862 // Returns try index for the try block to which this catch handler
772 // corresponds. 863 // corresponds.
773 intptr_t catch_try_index() const { 864 intptr_t catch_try_index() const {
774 ASSERT(IsCatchEntry()); 865 ASSERT(IsCatchEntry());
775 return catch_try_index_; 866 return catch_try_index_;
776 } 867 }
777 868
778 virtual void PrepareEntry(FlowGraphCompiler* compiler); 869 virtual void PrepareEntry(FlowGraphCompiler* compiler);
779 870
871 virtual void PrintTo(BufferFormatter* f) const;
872 virtual void PrintToVisualizer(BufferFormatter* f) const;
873
780 private: 874 private:
781 BlockEntryInstr* predecessor_; 875 BlockEntryInstr* predecessor_;
782 const intptr_t catch_try_index_; 876 const intptr_t catch_try_index_;
783 877
784 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); 878 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr);
785 }; 879 };
786 880
787 881
788 // Abstract super-class of all instructions that define a value (Bind, Phi). 882 // Abstract super-class of all instructions that define a value (Bind, Phi).
789 class Definition : public Instruction { 883 class Definition : public Instruction {
790 public: 884 public:
791 enum UseKind { kEffect, kValue }; 885 enum UseKind { kEffect, kValue };
792 886
793 Definition() 887 Definition()
794 : temp_index_(-1), 888 : temp_index_(-1),
795 ssa_temp_index_(-1), 889 ssa_temp_index_(-1),
796 propagated_type_(AbstractType::Handle()), 890 propagated_type_(AbstractType::Handle()),
797 propagated_cid_(kIllegalCid), 891 propagated_cid_(kIllegalCid),
798 input_use_list_(NULL), 892 input_use_list_(NULL),
799 env_use_list_(NULL), 893 env_use_list_(NULL),
800 use_kind_(kValue) { // Phis and parameters rely on this default. 894 use_kind_(kValue) { // Phis and parameters rely on this default.
801 } 895 }
802 896
803 virtual Definition* AsDefinition() { return this; } 897 virtual Definition* AsDefinition() { return this; }
804 898
899 bool IsComparison() { return (AsComparison() != NULL); }
900 virtual ComparisonInstr* AsComparison() { return NULL; }
901
902 // Overridden by definitions that push arguments.
903 virtual intptr_t ArgumentCount() const { return 0; }
904
805 intptr_t temp_index() const { return temp_index_; } 905 intptr_t temp_index() const { return temp_index_; }
806 void set_temp_index(intptr_t index) { temp_index_ = index; } 906 void set_temp_index(intptr_t index) { temp_index_ = index; }
807 907
808 intptr_t ssa_temp_index() const { return ssa_temp_index_; } 908 intptr_t ssa_temp_index() const { return ssa_temp_index_; }
809 void set_ssa_temp_index(intptr_t index) { 909 void set_ssa_temp_index(intptr_t index) {
810 ASSERT(index >= 0); 910 ASSERT(index >= 0);
811 ASSERT(is_used()); 911 ASSERT(is_used());
812 ssa_temp_index_ = index; 912 ssa_temp_index_ = index;
813 } 913 }
814 bool HasSSATemp() const { return ssa_temp_index_ >= 0; } 914 bool HasSSATemp() const { return ssa_temp_index_ >= 0; }
815 915
816 bool is_used() const { return (use_kind_ != kEffect); } 916 bool is_used() const { return (use_kind_ != kEffect); }
817 void set_use_kind(UseKind kind) { use_kind_ = kind; } 917 void set_use_kind(UseKind kind) { use_kind_ = kind; }
818 918
819 // Compile time type of the definition, which may be requested before type 919 // Compile time type of the definition, which may be requested before type
820 // propagation during graph building. 920 // propagation during graph building.
821 virtual RawAbstractType* CompileType() const = 0; 921 virtual RawAbstractType* CompileType() const = 0;
822 922
923 virtual intptr_t ResultCid() const = 0;
924
823 bool HasPropagatedType() const { 925 bool HasPropagatedType() const {
824 return !propagated_type_.IsNull(); 926 return !propagated_type_.IsNull();
825 } 927 }
826 RawAbstractType* PropagatedType() const { 928 RawAbstractType* PropagatedType() const {
827 ASSERT(HasPropagatedType()); 929 ASSERT(HasPropagatedType());
828 return propagated_type_.raw(); 930 return propagated_type_.raw();
829 } 931 }
830 // Returns true if the propagated type has changed. 932 // Returns true if the propagated type has changed.
831 bool SetPropagatedType(const AbstractType& propagated_type) { 933 bool SetPropagatedType(const AbstractType& propagated_type) {
832 if (propagated_type.IsNull()) { 934 if (propagated_type.IsNull()) {
833 // Not a typed definition, e.g. access to a VM field. 935 // Not a typed definition, e.g. access to a VM field.
834 return false; 936 return false;
835 } 937 }
836 const bool changed = 938 const bool changed =
837 propagated_type_.IsNull() || !propagated_type.Equals(propagated_type_); 939 propagated_type_.IsNull() || !propagated_type.Equals(propagated_type_);
838 propagated_type_ = propagated_type.raw(); 940 propagated_type_ = propagated_type.raw();
839 return changed; 941 return changed;
840 } 942 }
841 943
842 bool has_propagated_cid() const { return propagated_cid_ != kIllegalCid; } 944 bool has_propagated_cid() const { return propagated_cid_ != kIllegalCid; }
843 intptr_t propagated_cid() const { return propagated_cid_; } 945 intptr_t propagated_cid() const { return propagated_cid_; }
946
844 // May compute and set propagated cid. 947 // May compute and set propagated cid.
845 virtual intptr_t GetPropagatedCid() = 0; 948 virtual intptr_t GetPropagatedCid();
846 949
847 // Returns true if the propagated cid has changed. 950 // Returns true if the propagated cid has changed.
848 bool SetPropagatedCid(intptr_t cid); 951 bool SetPropagatedCid(intptr_t cid);
849 952
953 // Returns true if the definition may have side effects.
954 // TODO(fschneider): Make this abstract and implement for all definitions
955 // instead of returning the safe default (true).
956 virtual bool HasSideEffect() const { return true; }
957
850 Value* input_use_list() { return input_use_list_; } 958 Value* input_use_list() { return input_use_list_; }
851 void set_input_use_list(Value* head) { input_use_list_ = head; } 959 void set_input_use_list(Value* head) { input_use_list_ = head; }
852 960
853 Value* env_use_list() { return env_use_list_; } 961 Value* env_use_list() { return env_use_list_; }
854 void set_env_use_list(Value* head) { env_use_list_ = head; } 962 void set_env_use_list(Value* head) { env_use_list_ = head; }
855 963
964 // Returns a replacement for the definition or NULL if the definition can
965 // be eliminated. By default returns the definition (input parameter)
966 // which means no change.
967 virtual Definition* Canonicalize();
968
856 // Replace uses of this definition with uses of other definition or value. 969 // Replace uses of this definition with uses of other definition or value.
857 // Precondition: use lists must be properly calculated. 970 // Precondition: use lists must be properly calculated.
858 // Postcondition: use lists and use values are still valid. 971 // Postcondition: use lists and use values are still valid.
859 void ReplaceUsesWith(Definition* other); 972 void ReplaceUsesWith(Definition* other);
860 973
974 // Replace this definition and all uses with another definition. If
975 // replacing during iteration, pass the iterator so that the instruction
976 // can be replaced without affecting iteration order, otherwise pass a
977 // NULL iterator.
978 void ReplaceWith(Definition* other, ForwardInstructionIterator* iterator);
979
861 // Insert this definition before 'next'. 980 // Insert this definition before 'next'.
862 void InsertBefore(Instruction* next); 981 void InsertBefore(Instruction* next);
863 982
864 // Insert this definition after 'prev'. 983 // Insert this definition after 'prev'.
865 void InsertAfter(Instruction* prev); 984 void InsertAfter(Instruction* prev);
866 985
867 // If this definition is a bind of a constant return it. 986 // Compares two definitions. Returns true, iff:
868 // Otherwise return NULL. 987 // 1. They have the same tag.
869 ConstantComp* AsConstant(); 988 // 2. All input operands are Equals.
989 // 3. They satisfy AttributesEqual.
990 bool Equals(Definition* other) const;
991
992 // Compare attributes of a definition (except input operands and tag).
993 // All definition that participate in CSE have to override this function.
994 // This function can assume that the argument has the same type as this.
995 virtual bool AttributesEqual(Definition* other) const {
996 UNREACHABLE();
997 return false;
998 }
999
1000 // Returns a hash code for use with hash maps.
1001 virtual intptr_t Hashcode() const;
1002
1003 virtual void RecordAssignedVars(BitVector* assigned_vars,
1004 intptr_t fixed_parameter_count);
1005
1006 // Printing support. These functions are sometimes overridden for custom
1007 // formatting. Otherwise, it prints in the format "opcode(op1, op2, op3)".
1008 virtual void PrintTo(BufferFormatter* f) const;
1009 virtual void PrintOperandsTo(BufferFormatter* f) const;
1010 virtual void PrintToVisualizer(BufferFormatter* f) const;
870 1011
871 private: 1012 private:
872 intptr_t temp_index_; 1013 intptr_t temp_index_;
873 intptr_t ssa_temp_index_; 1014 intptr_t ssa_temp_index_;
874 // TODO(regis): GrowableArray<const AbstractType*> propagated_types_; 1015 // TODO(regis): GrowableArray<const AbstractType*> propagated_types_;
875 // For now: 1016 // For now:
876 AbstractType& propagated_type_; 1017 AbstractType& propagated_type_;
877 intptr_t propagated_cid_; 1018 intptr_t propagated_cid_;
878 Value* input_use_list_; 1019 Value* input_use_list_;
879 Value* env_use_list_; 1020 Value* env_use_list_;
880 UseKind use_kind_; 1021 UseKind use_kind_;
881 1022
882 DISALLOW_COPY_AND_ASSIGN(Definition); 1023 DISALLOW_COPY_AND_ASSIGN(Definition);
883 }; 1024 };
884 1025
885 1026
886 class BindInstr : public Definition {
887 public:
888 BindInstr(UseKind used, Computation* computation)
889 : computation_(computation) {
890 ASSERT(computation != NULL);
891 set_use_kind(used);
892 }
893
894 DECLARE_INSTRUCTION(Bind)
895
896 // Overridden functions from class Instruction.
897 virtual intptr_t ArgumentCount() const;
898 intptr_t InputCount() const;
899 Value* InputAt(intptr_t i) const;
900 void SetInputAt(intptr_t i, Value* value);
901 virtual bool CanDeoptimize() const;
902 virtual void RecordAssignedVars(BitVector* assigned_vars,
903 intptr_t fixed_parameter_count);
904 virtual LocationSummary* locs();
905 virtual void EmitNativeCode(FlowGraphCompiler* compiler);
906 virtual Representation RequiredInputRepresentation(intptr_t i) const;
907 virtual Representation representation() const;
908 virtual intptr_t DeoptimizationTarget() const;
909
910 Computation* computation() const { return computation_; }
911 void set_computation(Computation* value) { computation_ = value; }
912
913 // Overridden functions from class Definition.
914 virtual RawAbstractType* CompileType() const;
915 virtual intptr_t GetPropagatedCid();
916
917 // Other functions that forward to the computation.
918 intptr_t Hashcode() const;
919 bool Equals(BindInstr* other) const;
920
921 private:
922 Computation* computation_;
923
924 DISALLOW_COPY_AND_ASSIGN(BindInstr);
925 };
926
927
928 class PhiInstr : public Definition { 1027 class PhiInstr : public Definition {
929 public: 1028 public:
930 explicit PhiInstr(JoinEntryInstr* block, intptr_t num_inputs) 1029 explicit PhiInstr(JoinEntryInstr* block, intptr_t num_inputs)
931 : block_(block), 1030 : block_(block),
932 inputs_(num_inputs), 1031 inputs_(num_inputs),
933 is_alive_(false), 1032 is_alive_(false),
934 representation_(kTagged) { 1033 representation_(kTagged) {
935 for (intptr_t i = 0; i < num_inputs; ++i) { 1034 for (intptr_t i = 0; i < num_inputs; ++i) {
936 inputs_.Add(NULL); 1035 inputs_.Add(NULL);
937 } 1036 }
938 } 1037 }
939 1038
940 JoinEntryInstr* block() const { return block_; } 1039 JoinEntryInstr* block() const { return block_; }
941 1040
942 virtual RawAbstractType* CompileType() const; 1041 virtual RawAbstractType* CompileType() const;
943 virtual intptr_t GetPropagatedCid() { return propagated_cid(); } 1042 virtual intptr_t GetPropagatedCid();
944 1043
945 virtual intptr_t ArgumentCount() const { return 0; } 1044 virtual intptr_t ArgumentCount() const { return 0; }
946 1045
947 intptr_t InputCount() const { return inputs_.length(); } 1046 intptr_t InputCount() const { return inputs_.length(); }
948 1047
949 Value* InputAt(intptr_t i) const { return inputs_[i]; } 1048 Value* InputAt(intptr_t i) const { return inputs_[i]; }
950 1049
951 void SetInputAt(intptr_t i, Value* value) { inputs_[i] = value; } 1050 void SetInputAt(intptr_t i, Value* value) { inputs_[i] = value; }
952 1051
953 virtual bool CanDeoptimize() const { return false; } 1052 virtual bool CanDeoptimize() const { return false; }
(...skipping 10 matching lines...) Expand all
964 } 1063 }
965 1064
966 virtual Representation representation() const { 1065 virtual Representation representation() const {
967 return representation_; 1066 return representation_;
968 } 1067 }
969 1068
970 virtual void set_representation(Representation r) { 1069 virtual void set_representation(Representation r) {
971 representation_ = r; 1070 representation_ = r;
972 } 1071 }
973 1072
1073 virtual intptr_t Hashcode() const {
1074 UNREACHABLE();
1075 return 0;
1076 }
1077
1078 virtual intptr_t ResultCid() const {
1079 UNREACHABLE();
1080 return kIllegalCid;
1081 }
1082
974 DECLARE_INSTRUCTION(Phi) 1083 DECLARE_INSTRUCTION(Phi)
975 1084
1085 virtual void PrintTo(BufferFormatter* f) const;
1086 virtual void PrintToVisualizer(BufferFormatter* f) const;
1087
976 private: 1088 private:
977 JoinEntryInstr* block_; 1089 JoinEntryInstr* block_;
978 GrowableArray<Value*> inputs_; 1090 GrowableArray<Value*> inputs_;
979 bool is_alive_; 1091 bool is_alive_;
980 Representation representation_; 1092 Representation representation_;
981 1093
982 DISALLOW_COPY_AND_ASSIGN(PhiInstr); 1094 DISALLOW_COPY_AND_ASSIGN(PhiInstr);
983 }; 1095 };
984 1096
985 1097
986 class ParameterInstr : public Definition { 1098 class ParameterInstr : public Definition {
987 public: 1099 public:
988 explicit ParameterInstr(intptr_t index) : index_(index) { } 1100 explicit ParameterInstr(intptr_t index) : index_(index) { }
989 1101
990 DECLARE_INSTRUCTION(Parameter) 1102 DECLARE_INSTRUCTION(Parameter)
991 1103
992 intptr_t index() const { return index_; } 1104 intptr_t index() const { return index_; }
993 1105
994 // Compile type of the passed-in parameter. 1106 // Compile type of the passed-in parameter.
995 virtual RawAbstractType* CompileType() const; 1107 virtual RawAbstractType* CompileType() const;
1108
996 // No known propagated cid for parameters. 1109 // No known propagated cid for parameters.
997 virtual intptr_t GetPropagatedCid() { return propagated_cid(); } 1110 virtual intptr_t GetPropagatedCid();
998 1111
999 virtual intptr_t ArgumentCount() const { return 0; } 1112 virtual intptr_t ArgumentCount() const { return 0; }
1000 1113
1001 intptr_t InputCount() const { return 0; } 1114 intptr_t InputCount() const { return 0; }
1002 Value* InputAt(intptr_t i) const { 1115 Value* InputAt(intptr_t i) const {
1003 UNREACHABLE(); 1116 UNREACHABLE();
1004 return NULL; 1117 return NULL;
1005 } 1118 }
1006 void SetInputAt(intptr_t i, Value* value) { UNREACHABLE(); } 1119 void SetInputAt(intptr_t i, Value* value) { UNREACHABLE(); }
1007 1120
1008 virtual bool CanDeoptimize() const { return false; } 1121 virtual bool CanDeoptimize() const { return false; }
1009 1122
1123 virtual intptr_t Hashcode() const {
1124 UNREACHABLE();
1125 return 0;
1126 }
1127
1128 virtual intptr_t ResultCid() const {
1129 UNREACHABLE();
1130 return kIllegalCid;
1131 }
1132
1133 virtual void PrintTo(BufferFormatter* f) const;
1134 virtual void PrintToVisualizer(BufferFormatter* f) const;
1135
1010 private: 1136 private:
1011 const intptr_t index_; 1137 const intptr_t index_;
1012 1138
1013 DISALLOW_COPY_AND_ASSIGN(ParameterInstr); 1139 DISALLOW_COPY_AND_ASSIGN(ParameterInstr);
1014 }; 1140 };
1015 1141
1016 1142
1017 class PushArgumentInstr : public Definition { 1143 class PushArgumentInstr : public Definition {
1018 public: 1144 public:
1019 explicit PushArgumentInstr(Value* value) : value_(value), locs_(NULL) { 1145 explicit PushArgumentInstr(Value* value) : value_(value), locs_(NULL) {
1020 ASSERT(value != NULL); 1146 ASSERT(value != NULL);
1147 set_use_kind(kEffect); // Override the default.
1021 } 1148 }
1022 1149
1023 DECLARE_INSTRUCTION(PushArgument) 1150 DECLARE_INSTRUCTION(PushArgument)
1024 1151
1025 intptr_t InputCount() const { return 1; } 1152 intptr_t InputCount() const { return 1; }
1026 Value* InputAt(intptr_t i) const { 1153 Value* InputAt(intptr_t i) const {
1027 ASSERT(i == 0); 1154 ASSERT(i == 0);
1028 return value_; 1155 return value_;
1029 } 1156 }
1030 void SetInputAt(intptr_t i, Value* value) { 1157 void SetInputAt(intptr_t i, Value* value) {
1031 ASSERT(i == 0); 1158 ASSERT(i == 0);
1032 value_ = value; 1159 value_ = value;
1033 } 1160 }
1034 1161
1035 virtual intptr_t ArgumentCount() const { return 0; } 1162 virtual intptr_t ArgumentCount() const { return 0; }
1036 1163
1037 virtual RawAbstractType* CompileType() const; 1164 virtual RawAbstractType* CompileType() const;
1038 virtual intptr_t GetPropagatedCid() { return propagated_cid(); } 1165 virtual intptr_t GetPropagatedCid() { return propagated_cid(); }
1166 virtual intptr_t ResultCid() const {
1167 UNREACHABLE();
1168 return kIllegalCid;
1169 }
1039 1170
1040 Value* value() const { return value_; } 1171 Value* value() const { return value_; }
1041 1172
1042 virtual LocationSummary* locs() { 1173 virtual LocationSummary* locs() {
1043 if (locs_ == NULL) { 1174 if (locs_ == NULL) {
1044 locs_ = MakeLocationSummary(); 1175 locs_ = MakeLocationSummary();
1045 } 1176 }
1046 return locs_; 1177 return locs_;
1047 } 1178 }
1048 1179
1049 LocationSummary* MakeLocationSummary() const; 1180 virtual intptr_t Hashcode() const {
1050 1181 UNREACHABLE();
1051 virtual void EmitNativeCode(FlowGraphCompiler* compiler); 1182 return 0;
1183 }
1052 1184
1053 virtual bool CanDeoptimize() const { return false; } 1185 virtual bool CanDeoptimize() const { return false; }
1054 1186
1187 virtual void PrintTo(BufferFormatter* f) const;
1188 virtual void PrintToVisualizer(BufferFormatter* f) const;
1189
1055 private: 1190 private:
1056 Value* value_; 1191 Value* value_;
1057 LocationSummary* locs_; 1192 LocationSummary* locs_;
1058 1193
1059 DISALLOW_COPY_AND_ASSIGN(PushArgumentInstr); 1194 DISALLOW_COPY_AND_ASSIGN(PushArgumentInstr);
1060 }; 1195 };
1061 1196
1062 1197
1063 class ReturnInstr : public TemplateInstruction<1> { 1198 class ReturnInstr : public TemplateInstruction<1> {
1064 public: 1199 public:
1065 ReturnInstr(intptr_t token_pos, Value* value) 1200 ReturnInstr(intptr_t token_pos, Value* value)
1066 : deopt_id_(Isolate::Current()->GetNextDeoptId()), 1201 : token_pos_(token_pos) {
1067 token_pos_(token_pos) {
1068 ASSERT(value != NULL); 1202 ASSERT(value != NULL);
1069 inputs_[0] = value; 1203 inputs_[0] = value;
1070 } 1204 }
1071 1205
1072 DECLARE_INSTRUCTION(Return) 1206 DECLARE_INSTRUCTION(Return)
1073 1207
1074 virtual intptr_t ArgumentCount() const { return 0; } 1208 virtual intptr_t ArgumentCount() const { return 0; }
1075 1209
1076 intptr_t deopt_id() const { return deopt_id_; }
1077 intptr_t token_pos() const { return token_pos_; } 1210 intptr_t token_pos() const { return token_pos_; }
1078 Value* value() const { return inputs_[0]; } 1211 Value* value() const { return inputs_[0]; }
1079 1212
1080 virtual LocationSummary* MakeLocationSummary() const;
1081
1082 virtual void EmitNativeCode(FlowGraphCompiler* compiler);
1083
1084 virtual bool CanDeoptimize() const { return false; } 1213 virtual bool CanDeoptimize() const { return false; }
1085 1214
1215 virtual void PrintTo(BufferFormatter* f) const;
1216 virtual void PrintToVisualizer(BufferFormatter* f) const;
1217
1086 private: 1218 private:
1087 const intptr_t deopt_id_;
1088 const intptr_t token_pos_; 1219 const intptr_t token_pos_;
1089 1220
1090 DISALLOW_COPY_AND_ASSIGN(ReturnInstr); 1221 DISALLOW_COPY_AND_ASSIGN(ReturnInstr);
1091 }; 1222 };
1092 1223
1093 1224
1094 class ThrowInstr : public TemplateInstruction<0> { 1225 class ThrowInstr : public TemplateInstruction<0> {
1095 public: 1226 public:
1096 explicit ThrowInstr(intptr_t token_pos) : token_pos_(token_pos) { } 1227 explicit ThrowInstr(intptr_t token_pos) : token_pos_(token_pos) { }
1097 1228
1098 DECLARE_INSTRUCTION(Throw) 1229 DECLARE_INSTRUCTION(Throw)
1099 1230
1100 virtual intptr_t ArgumentCount() const { return 1; } 1231 virtual intptr_t ArgumentCount() const { return 1; }
1101 1232
1102 intptr_t token_pos() const { return token_pos_; } 1233 intptr_t token_pos() const { return token_pos_; }
1103 1234
1104 virtual LocationSummary* MakeLocationSummary() const; 1235 virtual bool CanDeoptimize() const { return false; }
1105 1236
1106 virtual void EmitNativeCode(FlowGraphCompiler* compiler); 1237 virtual void PrintTo(BufferFormatter* f) const;
1107 1238 virtual void PrintToVisualizer(BufferFormatter* f) const;
1108 virtual bool CanDeoptimize() const { return false; }
1109 1239
1110 private: 1240 private:
1111 const intptr_t token_pos_; 1241 const intptr_t token_pos_;
1112 1242
1113 DISALLOW_COPY_AND_ASSIGN(ThrowInstr); 1243 DISALLOW_COPY_AND_ASSIGN(ThrowInstr);
1114 }; 1244 };
1115 1245
1116 1246
1117 class ReThrowInstr : public TemplateInstruction<0> { 1247 class ReThrowInstr : public TemplateInstruction<0> {
1118 public: 1248 public:
1119 explicit ReThrowInstr(intptr_t token_pos) : token_pos_(token_pos) { } 1249 explicit ReThrowInstr(intptr_t token_pos) : token_pos_(token_pos) { }
1120 1250
1121 DECLARE_INSTRUCTION(ReThrow) 1251 DECLARE_INSTRUCTION(ReThrow)
1122 1252
1123 virtual intptr_t ArgumentCount() const { return 2; } 1253 virtual intptr_t ArgumentCount() const { return 2; }
1124 1254
1125 intptr_t token_pos() const { return token_pos_; } 1255 intptr_t token_pos() const { return token_pos_; }
1126 1256
1127 virtual LocationSummary* MakeLocationSummary() const; 1257 virtual bool CanDeoptimize() const { return false; }
1128 1258
1129 virtual void EmitNativeCode(FlowGraphCompiler* compiler); 1259 virtual void PrintTo(BufferFormatter* f) const;
1130 1260 virtual void PrintToVisualizer(BufferFormatter* f) const;
1131 virtual bool CanDeoptimize() const { return false; }
1132 1261
1133 private: 1262 private:
1134 const intptr_t token_pos_; 1263 const intptr_t token_pos_;
1135 1264
1136 DISALLOW_COPY_AND_ASSIGN(ReThrowInstr); 1265 DISALLOW_COPY_AND_ASSIGN(ReThrowInstr);
1137 }; 1266 };
1138 1267
1139 1268
1140 class GotoInstr : public TemplateInstruction<0> { 1269 class GotoInstr : public TemplateInstruction<0> {
1141 public: 1270 public:
1142 explicit GotoInstr(JoinEntryInstr* entry) 1271 explicit GotoInstr(JoinEntryInstr* entry)
1143 : successor_(entry), 1272 : successor_(entry),
1144 parallel_move_(NULL) { } 1273 parallel_move_(NULL) { }
1145 1274
1146 DECLARE_INSTRUCTION(Goto) 1275 DECLARE_INSTRUCTION(Goto)
1147 1276
1148 virtual intptr_t ArgumentCount() const { return 0; } 1277 virtual intptr_t ArgumentCount() const { return 0; }
1149 1278
1150 JoinEntryInstr* successor() const { return successor_; } 1279 JoinEntryInstr* successor() const { return successor_; }
1151 void set_successor(JoinEntryInstr* successor) { successor_ = successor; } 1280 void set_successor(JoinEntryInstr* successor) { successor_ = successor; }
1152 virtual intptr_t SuccessorCount() const; 1281 virtual intptr_t SuccessorCount() const;
1153 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; 1282 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const;
1154 1283
1155 virtual LocationSummary* MakeLocationSummary() const;
1156
1157 virtual void EmitNativeCode(FlowGraphCompiler* compiler);
1158
1159 virtual bool CanDeoptimize() const { return false; } 1284 virtual bool CanDeoptimize() const { return false; }
1160 1285
1161 ParallelMoveInstr* parallel_move() const { 1286 ParallelMoveInstr* parallel_move() const {
1162 return parallel_move_; 1287 return parallel_move_;
1163 } 1288 }
1164 1289
1165 bool HasParallelMove() const { 1290 bool HasParallelMove() const {
1166 return parallel_move_ != NULL; 1291 return parallel_move_ != NULL;
1167 } 1292 }
1168 1293
1169 ParallelMoveInstr* GetParallelMove() { 1294 ParallelMoveInstr* GetParallelMove() {
1170 if (parallel_move_ == NULL) { 1295 if (parallel_move_ == NULL) {
1171 parallel_move_ = new ParallelMoveInstr(); 1296 parallel_move_ = new ParallelMoveInstr();
1172 } 1297 }
1173 return parallel_move_; 1298 return parallel_move_;
1174 } 1299 }
1175 1300
1301 virtual void PrintTo(BufferFormatter* f) const;
1302 virtual void PrintToVisualizer(BufferFormatter* f) const;
1303
1176 private: 1304 private:
1177 JoinEntryInstr* successor_; 1305 JoinEntryInstr* successor_;
1178 1306
1179 // Parallel move that will be used by linear scan register allocator to 1307 // Parallel move that will be used by linear scan register allocator to
1180 // connect live ranges at the end of the block and resolve phis. 1308 // connect live ranges at the end of the block and resolve phis.
1181 ParallelMoveInstr* parallel_move_; 1309 ParallelMoveInstr* parallel_move_;
1182 }; 1310 };
1183 1311
1184 1312
1185 class ControlInstruction : public Instruction { 1313 class ControlInstruction : public Instruction {
(...skipping 27 matching lines...) Expand all
1213 private: 1341 private:
1214 TargetEntryInstr* true_successor_; 1342 TargetEntryInstr* true_successor_;
1215 TargetEntryInstr* false_successor_; 1343 TargetEntryInstr* false_successor_;
1216 1344
1217 DISALLOW_COPY_AND_ASSIGN(ControlInstruction); 1345 DISALLOW_COPY_AND_ASSIGN(ControlInstruction);
1218 }; 1346 };
1219 1347
1220 1348
1221 class BranchInstr : public ControlInstruction { 1349 class BranchInstr : public ControlInstruction {
1222 public: 1350 public:
1223 explicit BranchInstr(ComparisonComp* computation) 1351 explicit BranchInstr(ComparisonInstr* comparison)
1224 : computation_(computation), locs_(NULL) { } 1352 : comparison_(comparison) { }
1225 1353
1226 DECLARE_INSTRUCTION(Branch) 1354 DECLARE_INSTRUCTION(Branch)
1227 1355
1228 virtual intptr_t ArgumentCount() const; 1356 virtual intptr_t ArgumentCount() const;
1229 intptr_t InputCount() const; 1357 intptr_t InputCount() const;
1230 Value* InputAt(intptr_t i) const; 1358 Value* InputAt(intptr_t i) const;
1231 void SetInputAt(intptr_t i, Value* value); 1359 void SetInputAt(intptr_t i, Value* value);
1232 virtual bool CanDeoptimize() const; 1360 virtual bool CanDeoptimize() const;
1233 1361
1234 ComparisonComp* computation() const { return computation_; } 1362 ComparisonInstr* comparison() const { return comparison_; }
1235 void set_computation(ComparisonComp* value) { computation_ = value; } 1363 void set_comparison(ComparisonInstr* value) { comparison_ = value; }
1236
1237 virtual void EmitNativeCode(FlowGraphCompiler* compiler);
1238 1364
1239 virtual LocationSummary* locs(); 1365 virtual LocationSummary* locs();
1240 virtual intptr_t DeoptimizationTarget() const; 1366 virtual intptr_t DeoptimizationTarget() const;
1241 virtual Representation RequiredInputRepresentation(intptr_t i) const; 1367 virtual Representation RequiredInputRepresentation(intptr_t i) const;
1242 1368
1369 // Replace the comparison with another, leaving the branch intact.
1370 void ReplaceWith(ComparisonInstr* other,
1371 ForwardInstructionIterator* ignored) {
1372 comparison_ = other;
1373 }
1374
1375 virtual void PrintTo(BufferFormatter* f) const;
1376 virtual void PrintToVisualizer(BufferFormatter* f) const;
1377
1243 private: 1378 private:
1244 ComparisonComp* computation_; 1379 ComparisonInstr* comparison_;
1245 LocationSummary* locs_;
1246 1380
1247 DISALLOW_COPY_AND_ASSIGN(BranchInstr); 1381 DISALLOW_COPY_AND_ASSIGN(BranchInstr);
1248 }; 1382 };
1249 1383
1250 1384
1251 #undef DECLARE_INSTRUCTION 1385 template<intptr_t N>
1386 class TemplateDefinition : public Definition {
1387 public:
1388 TemplateDefinition<N>() : locs_(NULL) { }
1252 1389
1253 1390 virtual intptr_t InputCount() const { return N; }
1254 // M is a two argument macro. It is applied to each concrete instruction's 1391 virtual Value* InputAt(intptr_t i) const { return inputs_[i]; }
1255 // (including the values) typename and classname. 1392 virtual void SetInputAt(intptr_t i, Value* value) {
1256 #define FOR_EACH_COMPUTATION(M) \ 1393 ASSERT(value != NULL);
1257 M(AssertAssignable, AssertAssignableComp) \ 1394 inputs_[i] = value;
1258 M(AssertBoolean, AssertBooleanComp) \
1259 M(ArgumentDefinitionTest, ArgumentDefinitionTestComp) \
1260 M(CurrentContext, CurrentContextComp) \
1261 M(StoreContext, StoreContextComp) \
1262 M(ClosureCall, ClosureCallComp) \
1263 M(InstanceCall, InstanceCallComp) \
1264 M(PolymorphicInstanceCall, PolymorphicInstanceCallComp) \
1265 M(StaticCall, StaticCallComp) \
1266 M(LoadLocal, LoadLocalComp) \
1267 M(StoreLocal, StoreLocalComp) \
1268 M(StrictCompare, StrictCompareComp) \
1269 M(EqualityCompare, EqualityCompareComp) \
1270 M(RelationalOp, RelationalOpComp) \
1271 M(NativeCall, NativeCallComp) \
1272 M(LoadIndexed, LoadIndexedComp) \
1273 M(StoreIndexed, StoreIndexedComp) \
1274 M(LoadInstanceField, LoadInstanceFieldComp) \
1275 M(StoreInstanceField, StoreInstanceFieldComp) \
1276 M(LoadStaticField, LoadStaticFieldComp) \
1277 M(StoreStaticField, StoreStaticFieldComp) \
1278 M(BooleanNegate, BooleanNegateComp) \
1279 M(InstanceOf, InstanceOfComp) \
1280 M(CreateArray, CreateArrayComp) \
1281 M(CreateClosure, CreateClosureComp) \
1282 M(AllocateObject, AllocateObjectComp) \
1283 M(AllocateObjectWithBoundsCheck, AllocateObjectWithBoundsCheckComp) \
1284 M(LoadVMField, LoadVMFieldComp) \
1285 M(StoreVMField, StoreVMFieldComp) \
1286 M(InstantiateTypeArguments, InstantiateTypeArgumentsComp) \
1287 M(ExtractConstructorTypeArguments, ExtractConstructorTypeArgumentsComp) \
1288 M(ExtractConstructorInstantiator, ExtractConstructorInstantiatorComp) \
1289 M(AllocateContext, AllocateContextComp) \
1290 M(ChainContext, ChainContextComp) \
1291 M(CloneContext, CloneContextComp) \
1292 M(CatchEntry, CatchEntryComp) \
1293 M(BinarySmiOp, BinarySmiOpComp) \
1294 M(BinaryMintOp, BinaryMintOpComp) \
1295 M(UnarySmiOp, UnarySmiOpComp) \
1296 M(NumberNegate, NumberNegateComp) \
1297 M(CheckStackOverflow, CheckStackOverflowComp) \
1298 M(DoubleToDouble, DoubleToDoubleComp) \
1299 M(SmiToDouble, SmiToDoubleComp) \
1300 M(CheckClass, CheckClassComp) \
1301 M(CheckSmi, CheckSmiComp) \
1302 M(Constant, ConstantComp) \
1303 M(CheckEitherNonSmi, CheckEitherNonSmiComp) \
1304 M(UnboxedDoubleBinaryOp, UnboxedDoubleBinaryOpComp) \
1305 M(UnboxDouble, UnboxDoubleComp) \
1306 M(BoxDouble, BoxDoubleComp) \
1307 M(CheckArrayBound, CheckArrayBoundComp)
1308
1309
1310 #define FORWARD_DECLARATION(ShortName, ClassName) class ClassName;
1311 FOR_EACH_COMPUTATION(FORWARD_DECLARATION)
1312 #undef FORWARD_DECLARATION
1313
1314
1315 class Computation : public ZoneAllocated {
1316 public:
1317 Computation()
1318 : deopt_id_(Isolate::Current()->GetNextDeoptId()), locs_(NULL) { }
1319
1320 // Unique id used for deoptimization.
1321 virtual intptr_t deopt_id() const {
1322 ASSERT(CanDeoptimize());
1323 return deopt_id_;
1324 } 1395 }
1325 1396
1326 // Visiting support. 1397 // Returns a structure describing the location constraints required
1327 virtual void Accept(FlowGraphVisitor* visitor, BindInstr* instr) = 0; 1398 // to emit native code for this definition.
1328
1329 virtual intptr_t InputCount() const = 0;
1330 virtual Value* InputAt(intptr_t i) const = 0;
1331 virtual void SetInputAt(intptr_t i, Value* value) = 0;
1332
1333 // Call computations override this function and return the
1334 // number of pushed arguments.
1335 virtual intptr_t ArgumentCount() const = 0;
1336
1337 // Returns true, if this computation can deoptimize.
1338 virtual bool CanDeoptimize() const = 0;
1339
1340 // Returns a replacement for the instruction that wraps this computation.
1341 // Returns NULL if instr can be eliminated.
1342 // By default returns instr (input parameter) which means no change.
1343 virtual Definition* TryReplace(BindInstr* instr) const;
1344
1345 // Compares two computations. Returns true, if:
1346 // 1. They are of the same kind.
1347 // 2. All input operands match.
1348 // 3. All other attributes match.
1349 bool Equals(Computation* other) const;
1350
1351 // Returns a hash code for use with hash maps.
1352 virtual intptr_t Hashcode() const;
1353
1354 // Compare attributes of an computation (except input operands and kind).
1355 // All computations that participate in CSE have to override this function.
1356 virtual bool AttributesEqual(Computation* other) const {
1357 UNREACHABLE();
1358 return false;
1359 }
1360
1361 // Returns true if the instruction may have side effects.
1362 // TODO(fschneider): Make this abstract and implement for all computations
1363 // instead of returning the safe default (true).
1364 virtual bool HasSideEffect() const { return true; }
1365
1366 // Compile time type of the computation, which typically depends on the
1367 // compile time types (and possibly propagated types) of its inputs.
1368 virtual RawAbstractType* CompileType() const = 0;
1369 virtual intptr_t ResultCid() const = 0;
1370
1371 // Mutate assigned_vars to add the local variable index for all
1372 // frame-allocated locals assigned to by the computation.
1373 virtual void RecordAssignedVars(BitVector* assigned_vars,
1374 intptr_t fixed_parameter_count);
1375
1376 virtual const char* DebugName() const = 0;
1377
1378 // Printing support. These functions are sometimes overridden for custom
1379 // formatting. Otherwise, it prints in the format "opcode(op1, op2, op3)".
1380 virtual void PrintTo(BufferFormatter* f) const;
1381 virtual void PrintOperandsTo(BufferFormatter* f) const;
1382
1383 // Returns structure describing location constraints required
1384 // to emit native code for this computation.
1385 LocationSummary* locs() { 1399 LocationSummary* locs() {
1386 if (locs_ == NULL) { 1400 if (locs_ == NULL) {
1387 locs_ = MakeLocationSummary(); 1401 locs_ = MakeLocationSummary();
1388 } 1402 }
1389 return locs_; 1403 return locs_;
1390 } 1404 }
1391 1405
1392 virtual ComparisonComp* AsComparison() { return NULL; }
1393
1394 // Create a location summary for this computation.
1395 // TODO(fschneider): Temporarily returns NULL for instructions
1396 // that are not yet converted to the location based code generation.
1397 virtual LocationSummary* MakeLocationSummary() const = 0;
1398
1399 // TODO(fschneider): Make EmitNativeCode and locs const.
1400 virtual void EmitNativeCode(FlowGraphCompiler* compiler) = 0;
1401
1402 virtual void EmitBranchCode(FlowGraphCompiler* compiler,
1403 BranchInstr* branch) {
1404 UNREACHABLE();
1405 }
1406
1407 static LocationSummary* MakeCallSummary();
1408
1409 // Declare an enum value used to define kind-test predicates.
1410 enum ComputationKind {
1411 #define DECLARE_COMPUTATION_KIND(ShortName, ClassName) k##ShortName,
1412
1413 FOR_EACH_COMPUTATION(DECLARE_COMPUTATION_KIND)
1414
1415 #undef DECLARE_COMPUTATION_KIND
1416 };
1417
1418 virtual ComputationKind computation_kind() const = 0;
1419
1420 // Returns representation expected for the input operand at the given index.
1421 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
1422 return kTagged;
1423 }
1424
1425 // Representation of the value produced by this computation.
1426 virtual Representation representation() const {
1427 return kTagged;
1428 }
1429
1430 // Returns deoptimization id that corresponds to the deoptimization target
1431 // that input operands conversions inserted for this instruction can jump
1432 // to. Can return kNoDeoptId.
1433 virtual intptr_t DeoptimizationTarget() const {
1434 UNREACHABLE();
1435 return Isolate::kNoDeoptId;
1436 }
1437
1438 // Declare predicate for each computation.
1439 #define DECLARE_PREDICATE(ShortName, ClassName) \
1440 inline bool Is##ShortName() const; \
1441 inline const ClassName* As##ShortName() const; \
1442 inline ClassName* As##ShortName();
1443 FOR_EACH_COMPUTATION(DECLARE_PREDICATE)
1444 #undef DECLARE_PREDICATE
1445
1446 protected: 1406 protected:
1447 // Fetch deopt id without checking if this computation can deoptimize. 1407 EmbeddedArray<Value*, N> inputs_;
1448 intptr_t GetDeoptId() const {
1449 return deopt_id_;
1450 }
1451 1408
1452 private: 1409 private:
1453 friend class BranchInstr; 1410 friend class BranchInstr;
1454 1411
1455 intptr_t deopt_id_;
1456 LocationSummary* locs_; 1412 LocationSummary* locs_;
1457
1458 DISALLOW_COPY_AND_ASSIGN(Computation);
1459 }; 1413 };
1460 1414
1461 1415
1462 // Inlined functions from class BindInstr that forward to their computation. 1416 class ConstantInstr : public TemplateDefinition<0> {
1463 inline intptr_t BindInstr::ArgumentCount() const { 1417 public:
1464 return computation()->ArgumentCount(); 1418 explicit ConstantInstr(const Object& value) : value_(value) { }
1465 }
1466 1419
1467 1420 DECLARE_INSTRUCTION(Constant)
1468 inline intptr_t BindInstr::InputCount() const { 1421 virtual RawAbstractType* CompileType() const;
1469 return computation()->InputCount();
1470 }
1471
1472
1473 inline Value* BindInstr::InputAt(intptr_t i) const {
1474 return computation()->InputAt(i);
1475 }
1476
1477
1478 inline void BindInstr::SetInputAt(intptr_t i, Value* value) {
1479 computation()->SetInputAt(i, value);
1480 }
1481
1482 inline bool BindInstr::CanDeoptimize() const {
1483 return computation()->CanDeoptimize();
1484 }
1485
1486
1487 inline intptr_t BindInstr::Hashcode() const {
1488 return computation()->Hashcode();
1489 }
1490
1491
1492 inline bool BindInstr::Equals(BindInstr* other) const {
1493 return computation()->Equals(other->computation());
1494 }
1495
1496
1497 inline LocationSummary* BindInstr::locs() {
1498 return computation()->locs();
1499 }
1500
1501
1502 inline Representation BindInstr::RequiredInputRepresentation(intptr_t i) const {
1503 return computation()->RequiredInputRepresentation(i);
1504 }
1505
1506
1507 inline Representation BindInstr::representation() const {
1508 return computation()->representation();
1509 }
1510
1511
1512 inline intptr_t BindInstr::DeoptimizationTarget() const {
1513 return computation()->DeoptimizationTarget();
1514 }
1515
1516
1517 template<intptr_t N>
1518 class TemplateComputation : public Computation {
1519 public:
1520 virtual intptr_t InputCount() const { return N; }
1521 virtual Value* InputAt(intptr_t i) const { return inputs_[i]; }
1522 virtual void SetInputAt(intptr_t i, Value* value) {
1523 ASSERT(value != NULL);
1524 inputs_[i] = value;
1525 }
1526
1527 protected:
1528 EmbeddedArray<Value*, N> inputs_;
1529 };
1530
1531
1532 // Functions defined in all concrete computation classes.
1533 #define DECLARE_COMPUTATION(ShortName) \
1534 virtual void Accept(FlowGraphVisitor* visitor, BindInstr* instr); \
1535 virtual ComputationKind computation_kind() const { \
1536 return Computation::k##ShortName; \
1537 } \
1538 virtual intptr_t ArgumentCount() const { return 0; } \
1539 virtual const char* DebugName() const { return #ShortName; } \
1540 virtual RawAbstractType* CompileType() const; \
1541 virtual LocationSummary* MakeLocationSummary() const; \
1542 virtual void EmitNativeCode(FlowGraphCompiler* compiler);
1543
1544
1545 // Function defined in all call computation classes.
1546 #define DECLARE_CALL_COMPUTATION(ShortName) \
1547 virtual void Accept(FlowGraphVisitor* visitor, BindInstr* instr); \
1548 virtual ComputationKind computation_kind() const { \
1549 return Computation::k##ShortName; \
1550 } \
1551 virtual const char* DebugName() const { return #ShortName; } \
1552 virtual RawAbstractType* CompileType() const; \
1553 virtual LocationSummary* MakeLocationSummary() const; \
1554 virtual void EmitNativeCode(FlowGraphCompiler* compiler);
1555
1556
1557 class ConstantComp : public TemplateComputation<0> {
1558 public:
1559 explicit ConstantComp(const Object& value) : value_(value) { }
1560
1561 DECLARE_COMPUTATION(Constant)
1562 1422
1563 const Object& value() const { return value_; } 1423 const Object& value() const { return value_; }
1564 1424
1565 virtual void PrintOperandsTo(BufferFormatter* f) const; 1425 virtual void PrintOperandsTo(BufferFormatter* f) const;
1566 1426
1567 virtual bool CanDeoptimize() const { return false; } 1427 virtual bool CanDeoptimize() const { return false; }
1568 1428
1569 virtual intptr_t ResultCid() const; 1429 virtual intptr_t ResultCid() const;
1570 1430
1571 virtual bool AttributesEqual(Computation* other) const; 1431 virtual bool AttributesEqual(Definition* other) const;
1572 1432
1573 private: 1433 private:
1574 const Object& value_; 1434 const Object& value_;
1575 1435
1576 DISALLOW_COPY_AND_ASSIGN(ConstantComp); 1436 DISALLOW_COPY_AND_ASSIGN(ConstantInstr);
1577 }; 1437 };
1578 1438
1579 1439
1580 class AssertAssignableComp : public TemplateComputation<3> { 1440 class AssertAssignableInstr : public TemplateDefinition<3> {
1581 public: 1441 public:
1582 AssertAssignableComp(intptr_t token_pos, 1442 AssertAssignableInstr(intptr_t token_pos,
1583 Value* value, 1443 Value* value,
1584 Value* instantiator, 1444 Value* instantiator,
1585 Value* instantiator_type_arguments, 1445 Value* instantiator_type_arguments,
1586 const AbstractType& dst_type, 1446 const AbstractType& dst_type,
1587 const String& dst_name) 1447 const String& dst_name)
1588 : token_pos_(token_pos), 1448 : token_pos_(token_pos),
1589 dst_type_(dst_type), 1449 dst_type_(dst_type),
1590 dst_name_(dst_name), 1450 dst_name_(dst_name),
1591 is_eliminated_(false) { 1451 is_eliminated_(false) {
1592 ASSERT(value != NULL); 1452 ASSERT(value != NULL);
1593 ASSERT(instantiator != NULL); 1453 ASSERT(instantiator != NULL);
1594 ASSERT(instantiator_type_arguments != NULL); 1454 ASSERT(instantiator_type_arguments != NULL);
1595 ASSERT(!dst_type.IsNull()); 1455 ASSERT(!dst_type.IsNull());
1596 ASSERT(!dst_name.IsNull()); 1456 ASSERT(!dst_name.IsNull());
1597 inputs_[0] = value; 1457 inputs_[0] = value;
1598 inputs_[1] = instantiator; 1458 inputs_[1] = instantiator;
1599 inputs_[2] = instantiator_type_arguments; 1459 inputs_[2] = instantiator_type_arguments;
1600 } 1460 }
1601 1461
1602 DECLARE_COMPUTATION(AssertAssignable) 1462 DECLARE_INSTRUCTION(AssertAssignable)
1463 virtual RawAbstractType* CompileType() const;
1603 1464
1604 Value* value() const { return inputs_[0]; } 1465 Value* value() const { return inputs_[0]; }
1605 Value* instantiator() const { return inputs_[1]; } 1466 Value* instantiator() const { return inputs_[1]; }
1606 Value* instantiator_type_arguments() const { return inputs_[2]; } 1467 Value* instantiator_type_arguments() const { return inputs_[2]; }
1607 1468
1608 intptr_t token_pos() const { return token_pos_; } 1469 intptr_t token_pos() const { return token_pos_; }
1609 const AbstractType& dst_type() const { return dst_type_; } 1470 const AbstractType& dst_type() const { return dst_type_; }
1610 const String& dst_name() const { return dst_name_; } 1471 const String& dst_name() const { return dst_name_; }
1611 1472
1612 bool is_eliminated() const { 1473 bool is_eliminated() const {
1613 return is_eliminated_; 1474 return is_eliminated_;
1614 } 1475 }
1615 void eliminate() { 1476 void eliminate() {
1616 ASSERT(!is_eliminated_); 1477 ASSERT(!is_eliminated_);
1617 is_eliminated_ = true; 1478 is_eliminated_ = true;
1618 } 1479 }
1619 1480
1620 virtual void PrintOperandsTo(BufferFormatter* f) const; 1481 virtual void PrintOperandsTo(BufferFormatter* f) const;
1621 1482
1622 virtual bool CanDeoptimize() const { return false; } 1483 virtual bool CanDeoptimize() const { return false; }
1623 virtual intptr_t ResultCid() const { return kDynamicCid; } 1484 virtual intptr_t ResultCid() const { return kDynamicCid; }
1624 1485
1625 private: 1486 private:
1626 const intptr_t token_pos_; 1487 const intptr_t token_pos_;
1627 const AbstractType& dst_type_; 1488 const AbstractType& dst_type_;
1628 const String& dst_name_; 1489 const String& dst_name_;
1629 bool is_eliminated_; 1490 bool is_eliminated_;
1630 1491
1631 DISALLOW_COPY_AND_ASSIGN(AssertAssignableComp); 1492 DISALLOW_COPY_AND_ASSIGN(AssertAssignableInstr);
1632 }; 1493 };
1633 1494
1634 1495
1635 class AssertBooleanComp : public TemplateComputation<1> { 1496 class AssertBooleanInstr : public TemplateDefinition<1> {
1636 public: 1497 public:
1637 AssertBooleanComp(intptr_t token_pos, 1498 AssertBooleanInstr(intptr_t token_pos, Value* value)
1638 Value* value)
1639 : token_pos_(token_pos), 1499 : token_pos_(token_pos),
1640 is_eliminated_(false) { 1500 is_eliminated_(false) {
1641 ASSERT(value != NULL); 1501 ASSERT(value != NULL);
1642 inputs_[0] = value; 1502 inputs_[0] = value;
1643 } 1503 }
1644 1504
1645 DECLARE_COMPUTATION(AssertBoolean) 1505 DECLARE_INSTRUCTION(AssertBoolean)
1506 virtual RawAbstractType* CompileType() const;
1646 1507
1647 intptr_t token_pos() const { return token_pos_; } 1508 intptr_t token_pos() const { return token_pos_; }
1648 Value* value() const { return inputs_[0]; } 1509 Value* value() const { return inputs_[0]; }
1649 1510
1650 bool is_eliminated() const { 1511 bool is_eliminated() const {
1651 return is_eliminated_; 1512 return is_eliminated_;
1652 } 1513 }
1653 void eliminate() { 1514 void eliminate() {
1654 ASSERT(!is_eliminated_); 1515 ASSERT(!is_eliminated_);
1655 is_eliminated_ = true; 1516 is_eliminated_ = true;
1656 } 1517 }
1657 1518
1658 virtual void PrintOperandsTo(BufferFormatter* f) const; 1519 virtual void PrintOperandsTo(BufferFormatter* f) const;
1659 1520
1660 virtual bool CanDeoptimize() const { return false; } 1521 virtual bool CanDeoptimize() const { return false; }
1661 virtual intptr_t ResultCid() const { return kBoolCid; } 1522 virtual intptr_t ResultCid() const { return kBoolCid; }
1662 1523
1663 private: 1524 private:
1664 const intptr_t token_pos_; 1525 const intptr_t token_pos_;
1665 bool is_eliminated_; 1526 bool is_eliminated_;
1666 1527
1667 DISALLOW_COPY_AND_ASSIGN(AssertBooleanComp); 1528 DISALLOW_COPY_AND_ASSIGN(AssertBooleanInstr);
1668 }; 1529 };
1669 1530
1670 1531
1671 class ArgumentDefinitionTestComp : public TemplateComputation<1> { 1532 class ArgumentDefinitionTestInstr : public TemplateDefinition<1> {
1672 public: 1533 public:
1673 ArgumentDefinitionTestComp(ArgumentDefinitionTestNode* node, 1534 ArgumentDefinitionTestInstr(ArgumentDefinitionTestNode* node,
1674 Value* saved_arguments_descriptor) 1535 Value* saved_arguments_descriptor)
1675 : ast_node_(*node) { 1536 : ast_node_(*node) {
1676 ASSERT(saved_arguments_descriptor != NULL); 1537 ASSERT(saved_arguments_descriptor != NULL);
1677 inputs_[0] = saved_arguments_descriptor; 1538 inputs_[0] = saved_arguments_descriptor;
1678 } 1539 }
1679 1540
1680 DECLARE_COMPUTATION(ArgumentDefinitionTest) 1541 DECLARE_INSTRUCTION(ArgumentDefinitionTest)
1542 virtual RawAbstractType* CompileType() const;
1681 1543
1682 intptr_t token_pos() const { return ast_node_.token_pos(); } 1544 intptr_t token_pos() const { return ast_node_.token_pos(); }
1683 intptr_t formal_parameter_index() const { 1545 intptr_t formal_parameter_index() const {
1684 return ast_node_.formal_parameter_index(); 1546 return ast_node_.formal_parameter_index();
1685 } 1547 }
1686 const String& formal_parameter_name() const { 1548 const String& formal_parameter_name() const {
1687 return ast_node_.formal_parameter_name(); 1549 return ast_node_.formal_parameter_name();
1688 } 1550 }
1689 Value* saved_arguments_descriptor() const { return inputs_[0]; } 1551 Value* saved_arguments_descriptor() const { return inputs_[0]; }
1690 1552
1691 virtual void PrintOperandsTo(BufferFormatter* f) const; 1553 virtual void PrintOperandsTo(BufferFormatter* f) const;
1692 1554
1693 virtual bool CanDeoptimize() const { return false; } 1555 virtual bool CanDeoptimize() const { return false; }
1694 virtual intptr_t ResultCid() const { return kBoolCid; } 1556 virtual intptr_t ResultCid() const { return kBoolCid; }
1695 1557
1696 private: 1558 private:
1697 const ArgumentDefinitionTestNode& ast_node_; 1559 const ArgumentDefinitionTestNode& ast_node_;
1698 1560
1699 DISALLOW_COPY_AND_ASSIGN(ArgumentDefinitionTestComp); 1561 DISALLOW_COPY_AND_ASSIGN(ArgumentDefinitionTestInstr);
1700 }; 1562 };
1701 1563
1702 1564
1703 // Denotes the current context, normally held in a register. This is 1565 // Denotes the current context, normally held in a register. This is
1704 // a computation, not a value, because it's mutable. 1566 // a computation, not a value, because it's mutable.
1705 class CurrentContextComp : public TemplateComputation<0> { 1567 class CurrentContextInstr : public TemplateDefinition<0> {
1706 public: 1568 public:
1707 CurrentContextComp() { } 1569 CurrentContextInstr() { }
1708 1570
1709 DECLARE_COMPUTATION(CurrentContext) 1571 DECLARE_INSTRUCTION(CurrentContext)
1572 virtual RawAbstractType* CompileType() const;
1710 1573
1711 virtual bool CanDeoptimize() const { return false; } 1574 virtual bool CanDeoptimize() const { return false; }
1712 virtual intptr_t ResultCid() const { return kDynamicCid; } 1575 virtual intptr_t ResultCid() const { return kDynamicCid; }
1713 1576
1714 private: 1577 private:
1715 DISALLOW_COPY_AND_ASSIGN(CurrentContextComp); 1578 DISALLOW_COPY_AND_ASSIGN(CurrentContextInstr);
1716 }; 1579 };
1717 1580
1718 1581
1719 class StoreContextComp : public TemplateComputation<1> { 1582 class StoreContextInstr : public TemplateDefinition<1> {
1720 public: 1583 public:
1721 explicit StoreContextComp(Value* value) { 1584 explicit StoreContextInstr(Value* value) {
1722 ASSERT(value != NULL); 1585 ASSERT(value != NULL);
1723 inputs_[0] = value; 1586 inputs_[0] = value;
1724 } 1587 }
1725 1588
1726 DECLARE_COMPUTATION(StoreContext); 1589 DECLARE_INSTRUCTION(StoreContext);
1590 virtual RawAbstractType* CompileType() const;
1727 1591
1728 Value* value() const { return inputs_[0]; } 1592 Value* value() const { return inputs_[0]; }
1729 1593
1730 virtual bool CanDeoptimize() const { return false; } 1594 virtual bool CanDeoptimize() const { return false; }
1731 virtual intptr_t ResultCid() const { return kIllegalCid; } 1595 virtual intptr_t ResultCid() const { return kIllegalCid; }
1732 1596
1733 private: 1597 private:
1734 DISALLOW_COPY_AND_ASSIGN(StoreContextComp); 1598 DISALLOW_COPY_AND_ASSIGN(StoreContextInstr);
1735 }; 1599 };
1736 1600
1737 1601
1738 class ClosureCallComp : public TemplateComputation<0> { 1602 class ClosureCallInstr : public TemplateDefinition<0> {
1739 public: 1603 public:
1740 ClosureCallComp(ClosureCallNode* node, 1604 ClosureCallInstr(ClosureCallNode* node,
1741 ZoneGrowableArray<PushArgumentInstr*>* arguments) 1605 ZoneGrowableArray<PushArgumentInstr*>* arguments)
1742 : ast_node_(*node), 1606 : ast_node_(*node),
1743 arguments_(arguments) { } 1607 arguments_(arguments) { }
1744 1608
1745 DECLARE_CALL_COMPUTATION(ClosureCall) 1609 DECLARE_INSTRUCTION(ClosureCall)
1610 virtual RawAbstractType* CompileType() const;
1746 1611
1747 const Array& argument_names() const { return ast_node_.arguments()->names(); } 1612 const Array& argument_names() const { return ast_node_.arguments()->names(); }
1748 intptr_t token_pos() const { return ast_node_.token_pos(); } 1613 intptr_t token_pos() const { return ast_node_.token_pos(); }
1749 1614
1750 virtual intptr_t ArgumentCount() const { return arguments_->length(); } 1615 virtual intptr_t ArgumentCount() const { return arguments_->length(); }
1751 PushArgumentInstr* ArgumentAt(intptr_t index) const { 1616 PushArgumentInstr* ArgumentAt(intptr_t index) const {
1752 return (*arguments_)[index]; 1617 return (*arguments_)[index];
1753 } 1618 }
1754 1619
1755 virtual void PrintOperandsTo(BufferFormatter* f) const; 1620 virtual void PrintOperandsTo(BufferFormatter* f) const;
1756 1621
1757 virtual bool CanDeoptimize() const { return true; } 1622 virtual bool CanDeoptimize() const { return true; }
1758 virtual intptr_t ResultCid() const { return kDynamicCid; } 1623 virtual intptr_t ResultCid() const { return kDynamicCid; }
1759 1624
1760 private: 1625 private:
1761 const ClosureCallNode& ast_node_; 1626 const ClosureCallNode& ast_node_;
1762 ZoneGrowableArray<PushArgumentInstr*>* arguments_; 1627 ZoneGrowableArray<PushArgumentInstr*>* arguments_;
1763 1628
1764 DISALLOW_COPY_AND_ASSIGN(ClosureCallComp); 1629 DISALLOW_COPY_AND_ASSIGN(ClosureCallInstr);
1765 }; 1630 };
1766 1631
1767 1632
1768 class InstanceCallComp : public TemplateComputation<0> { 1633 class InstanceCallInstr : public TemplateDefinition<0> {
1769 public: 1634 public:
1770 InstanceCallComp(intptr_t token_pos, 1635 InstanceCallInstr(intptr_t token_pos,
1771 const String& function_name, 1636 const String& function_name,
1772 Token::Kind token_kind, 1637 Token::Kind token_kind,
1773 ZoneGrowableArray<PushArgumentInstr*>* arguments, 1638 ZoneGrowableArray<PushArgumentInstr*>* arguments,
1774 const Array& argument_names, 1639 const Array& argument_names,
1775 intptr_t checked_argument_count) 1640 intptr_t checked_argument_count)
1776 : ic_data_(Isolate::Current()->GetICDataForDeoptId(deopt_id())), 1641 : ic_data_(Isolate::Current()->GetICDataForDeoptId(deopt_id())),
1777 token_pos_(token_pos), 1642 token_pos_(token_pos),
1778 function_name_(function_name), 1643 function_name_(function_name),
1779 token_kind_(token_kind), 1644 token_kind_(token_kind),
1780 arguments_(arguments), 1645 arguments_(arguments),
1781 argument_names_(argument_names), 1646 argument_names_(argument_names),
1782 checked_argument_count_(checked_argument_count) { 1647 checked_argument_count_(checked_argument_count) {
1783 ASSERT(function_name.IsZoneHandle()); 1648 ASSERT(function_name.IsZoneHandle());
1784 ASSERT(!arguments->is_empty()); 1649 ASSERT(!arguments->is_empty());
1785 ASSERT(argument_names.IsZoneHandle()); 1650 ASSERT(argument_names.IsZoneHandle());
1786 ASSERT(Token::IsBinaryToken(token_kind) || 1651 ASSERT(Token::IsBinaryToken(token_kind) ||
1787 Token::IsUnaryToken(token_kind) || 1652 Token::IsUnaryToken(token_kind) ||
1788 Token::IsIndexOperator(token_kind) || 1653 Token::IsIndexOperator(token_kind) ||
1789 token_kind == Token::kGET || 1654 token_kind == Token::kGET ||
1790 token_kind == Token::kSET || 1655 token_kind == Token::kSET ||
1791 token_kind == Token::kILLEGAL); 1656 token_kind == Token::kILLEGAL);
1792 } 1657 }
1793 1658
1794 DECLARE_CALL_COMPUTATION(InstanceCall) 1659 DECLARE_INSTRUCTION(InstanceCall)
1660 virtual RawAbstractType* CompileType() const;
1795 1661
1796 const ICData* ic_data() const { return ic_data_; } 1662 const ICData* ic_data() const { return ic_data_; }
1797 bool HasICData() const { 1663 bool HasICData() const {
1798 return (ic_data() != NULL) && !ic_data()->IsNull(); 1664 return (ic_data() != NULL) && !ic_data()->IsNull();
1799 } 1665 }
1800 1666
1801 intptr_t token_pos() const { return token_pos_; } 1667 intptr_t token_pos() const { return token_pos_; }
1802 const String& function_name() const { return function_name_; } 1668 const String& function_name() const { return function_name_; }
1803 Token::Kind token_kind() const { return token_kind_; } 1669 Token::Kind token_kind() const { return token_kind_; }
1804 virtual intptr_t ArgumentCount() const { return arguments_->length(); } 1670 virtual intptr_t ArgumentCount() const { return arguments_->length(); }
(...skipping 10 matching lines...) Expand all
1815 1681
1816 private: 1682 private:
1817 const ICData* ic_data_; 1683 const ICData* ic_data_;
1818 const intptr_t token_pos_; 1684 const intptr_t token_pos_;
1819 const String& function_name_; 1685 const String& function_name_;
1820 const Token::Kind token_kind_; // Binary op, unary op, kGET or kILLEGAL. 1686 const Token::Kind token_kind_; // Binary op, unary op, kGET or kILLEGAL.
1821 ZoneGrowableArray<PushArgumentInstr*>* const arguments_; 1687 ZoneGrowableArray<PushArgumentInstr*>* const arguments_;
1822 const Array& argument_names_; 1688 const Array& argument_names_;
1823 const intptr_t checked_argument_count_; 1689 const intptr_t checked_argument_count_;
1824 1690
1825 DISALLOW_COPY_AND_ASSIGN(InstanceCallComp); 1691 DISALLOW_COPY_AND_ASSIGN(InstanceCallInstr);
1826 }; 1692 };
1827 1693
1828 1694
1829 class PolymorphicInstanceCallComp : public TemplateComputation<0> { 1695 class PolymorphicInstanceCallInstr : public TemplateDefinition<0> {
1830 public: 1696 public:
1831 PolymorphicInstanceCallComp(InstanceCallComp* comp, 1697 PolymorphicInstanceCallInstr(InstanceCallInstr* instance_call,
1832 const ICData& ic_data, 1698 const ICData& ic_data,
1833 bool with_checks) 1699 bool with_checks)
1834 : instance_call_(comp), ic_data_(ic_data), with_checks_(with_checks) { 1700 : instance_call_(instance_call),
1701 ic_data_(ic_data),
1702 with_checks_(with_checks) {
1835 ASSERT(instance_call_ != NULL); 1703 ASSERT(instance_call_ != NULL);
1836 } 1704 }
1837 1705
1838 InstanceCallComp* instance_call() const { return instance_call_; } 1706 InstanceCallInstr* instance_call() const { return instance_call_; }
1839 bool with_checks() const { return with_checks_; } 1707 bool with_checks() const { return with_checks_; }
1840 1708
1841 void PrintTo(BufferFormatter* f) const;
1842
1843 virtual intptr_t ArgumentCount() const { 1709 virtual intptr_t ArgumentCount() const {
1844 return instance_call()->ArgumentCount(); 1710 return instance_call()->ArgumentCount();
1845 } 1711 }
1846 1712
1847 DECLARE_CALL_COMPUTATION(PolymorphicInstanceCall) 1713 DECLARE_INSTRUCTION(PolymorphicInstanceCall)
1714 virtual RawAbstractType* CompileType() const;
1848 1715
1849 const ICData& ic_data() const { return ic_data_; } 1716 const ICData& ic_data() const { return ic_data_; }
1850 1717
1851 virtual bool CanDeoptimize() const { return true; } 1718 virtual bool CanDeoptimize() const { return true; }
1852 virtual intptr_t ResultCid() const { return kDynamicCid; } 1719 virtual intptr_t ResultCid() const { return kDynamicCid; }
1853 1720
1721 virtual void PrintTo(BufferFormatter* f) const;
1722
1854 private: 1723 private:
1855 InstanceCallComp* instance_call_; 1724 InstanceCallInstr* instance_call_;
1856 const ICData& ic_data_; 1725 const ICData& ic_data_;
1857 const bool with_checks_; 1726 const bool with_checks_;
1858 1727
1859 DISALLOW_COPY_AND_ASSIGN(PolymorphicInstanceCallComp); 1728 DISALLOW_COPY_AND_ASSIGN(PolymorphicInstanceCallInstr);
1860 }; 1729 };
1861 1730
1862 1731
1863 class ComparisonComp : public TemplateComputation<2> { 1732 class ComparisonInstr : public TemplateDefinition<2> {
1864 public: 1733 public:
1865 ComparisonComp(Token::Kind kind, Value* left, Value* right) : kind_(kind) { 1734 ComparisonInstr(Token::Kind kind, Value* left, Value* right) : kind_(kind) {
1866 ASSERT(left != NULL); 1735 ASSERT(left != NULL);
1867 ASSERT(right != NULL); 1736 ASSERT(right != NULL);
1868 inputs_[0] = left; 1737 inputs_[0] = left;
1869 inputs_[1] = right; 1738 inputs_[1] = right;
1870 } 1739 }
1871 1740
1872 Value* left() const { return inputs_[0]; } 1741 Value* left() const { return inputs_[0]; }
1873 Value* right() const { return inputs_[1]; } 1742 Value* right() const { return inputs_[1]; }
1874 1743
1875 virtual ComparisonComp* AsComparison() { return this; } 1744 virtual ComparisonInstr* AsComparison() { return this; }
1876 1745
1877 Token::Kind kind() const { return kind_; } 1746 Token::Kind kind() const { return kind_; }
1878 1747
1748 virtual void EmitBranchCode(FlowGraphCompiler* compiler,
1749 BranchInstr* branch) = 0;
1750
1879 private: 1751 private:
1880 Token::Kind kind_; 1752 Token::Kind kind_;
1881 }; 1753 };
1882 1754
1883 1755
1884 // Inlined functions from class BranchInstr that forward to their comparison. 1756 // Inlined functions from class BranchInstr that forward to their comparison.
1885 inline intptr_t BranchInstr::ArgumentCount() const { 1757 inline intptr_t BranchInstr::ArgumentCount() const {
1886 return computation()->ArgumentCount(); 1758 return comparison()->ArgumentCount();
1887 } 1759 }
1888 1760
1889 1761
1890 inline intptr_t BranchInstr::InputCount() const { 1762 inline intptr_t BranchInstr::InputCount() const {
1891 return computation()->InputCount(); 1763 return comparison()->InputCount();
1892 } 1764 }
1893 1765
1894 1766
1895 inline Value* BranchInstr::InputAt(intptr_t i) const { 1767 inline Value* BranchInstr::InputAt(intptr_t i) const {
1896 return computation()->InputAt(i); 1768 return comparison()->InputAt(i);
1897 } 1769 }
1898 1770
1899 1771
1900 inline void BranchInstr::SetInputAt(intptr_t i, Value* value) { 1772 inline void BranchInstr::SetInputAt(intptr_t i, Value* value) {
1901 computation()->SetInputAt(i, value); 1773 comparison()->SetInputAt(i, value);
1902 } 1774 }
1903 1775
1904 1776
1905 inline bool BranchInstr::CanDeoptimize() const { 1777 inline bool BranchInstr::CanDeoptimize() const {
1906 return computation()->CanDeoptimize(); 1778 return comparison()->CanDeoptimize();
1907 } 1779 }
1908 1780
1909 1781
1910 inline LocationSummary* BranchInstr::locs() { 1782 inline LocationSummary* BranchInstr::locs() {
1911 if (computation_->locs_ == NULL) { 1783 if (comparison()->locs_ == NULL) {
1912 LocationSummary* summary = computation_->MakeLocationSummary(); 1784 LocationSummary* summary = comparison()->MakeLocationSummary();
1913 // Branches don't produce a result. 1785 // Branches don't produce a result.
1914 summary->set_out(Location::NoLocation()); 1786 summary->set_out(Location::NoLocation());
1915 computation_->locs_ = summary; 1787 comparison()->locs_ = summary;
1916 } 1788 }
1917 return computation_->locs_; 1789 return comparison()->locs_;
1918 } 1790 }
1919 1791
1920 1792
1921 inline intptr_t BranchInstr::DeoptimizationTarget() const { 1793 inline intptr_t BranchInstr::DeoptimizationTarget() const {
1922 return computation_->DeoptimizationTarget(); 1794 return comparison()->DeoptimizationTarget();
1923 } 1795 }
1924 1796
1925 1797
1926 inline Representation BranchInstr::RequiredInputRepresentation( 1798 inline Representation BranchInstr::RequiredInputRepresentation(
1927 intptr_t i) const { 1799 intptr_t i) const {
1928 return computation()->RequiredInputRepresentation(i); 1800 return comparison()->RequiredInputRepresentation(i);
1929 } 1801 }
1930 1802
1931 1803
1932 class StrictCompareComp : public ComparisonComp { 1804 class StrictCompareInstr : public ComparisonInstr {
1933 public: 1805 public:
1934 StrictCompareComp(Token::Kind kind, Value* left, Value* right) 1806 StrictCompareInstr(Token::Kind kind, Value* left, Value* right)
1935 : ComparisonComp(kind, left, right) { 1807 : ComparisonInstr(kind, left, right) {
1936 ASSERT((kind == Token::kEQ_STRICT) || (kind == Token::kNE_STRICT)); 1808 ASSERT((kind == Token::kEQ_STRICT) || (kind == Token::kNE_STRICT));
1937 } 1809 }
1938 1810
1939 DECLARE_COMPUTATION(StrictCompare) 1811 DECLARE_INSTRUCTION(StrictCompare)
1812 virtual RawAbstractType* CompileType() const;
1940 1813
1941 virtual void PrintOperandsTo(BufferFormatter* f) const; 1814 virtual void PrintOperandsTo(BufferFormatter* f) const;
1942 1815
1943 virtual bool CanDeoptimize() const { return false; } 1816 virtual bool CanDeoptimize() const { return false; }
1944 1817
1945 virtual Definition* TryReplace(BindInstr* instr) const; 1818 virtual Definition* Canonicalize();
1946 1819
1947 virtual intptr_t ResultCid() const { return kBoolCid; } 1820 virtual intptr_t ResultCid() const { return kBoolCid; }
1948 1821
1949 virtual void EmitBranchCode(FlowGraphCompiler* compiler, 1822 virtual void EmitBranchCode(FlowGraphCompiler* compiler,
1950 BranchInstr* branch); 1823 BranchInstr* branch);
1951 1824
1952 private: 1825 private:
1953 DISALLOW_COPY_AND_ASSIGN(StrictCompareComp); 1826 DISALLOW_COPY_AND_ASSIGN(StrictCompareInstr);
1954 }; 1827 };
1955 1828
1956 1829
1957 class EqualityCompareComp : public ComparisonComp { 1830 class EqualityCompareInstr : public ComparisonInstr {
1958 public: 1831 public:
1959 EqualityCompareComp(intptr_t token_pos, 1832 EqualityCompareInstr(intptr_t token_pos,
1960 Token::Kind kind, 1833 Token::Kind kind,
1961 Value* left, 1834 Value* left,
1962 Value* right) 1835 Value* right)
1963 : ComparisonComp(kind, left, right), 1836 : ComparisonInstr(kind, left, right),
1964 ic_data_(Isolate::Current()->GetICDataForDeoptId(deopt_id())), 1837 ic_data_(Isolate::Current()->GetICDataForDeoptId(deopt_id())),
1965 token_pos_(token_pos), 1838 token_pos_(token_pos),
1966 receiver_class_id_(kIllegalCid) { 1839 receiver_class_id_(kIllegalCid) {
1967 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); 1840 ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
1968 } 1841 }
1969 1842
1970 DECLARE_COMPUTATION(EqualityCompare) 1843 DECLARE_INSTRUCTION(EqualityCompare)
1844 virtual RawAbstractType* CompileType() const;
1971 1845
1972 const ICData* ic_data() const { return ic_data_; } 1846 const ICData* ic_data() const { return ic_data_; }
1973 bool HasICData() const { 1847 bool HasICData() const {
1974 return (ic_data() != NULL) && !ic_data()->IsNull(); 1848 return (ic_data() != NULL) && !ic_data()->IsNull();
1975 } 1849 }
1976 1850
1977 intptr_t token_pos() const { return token_pos_; } 1851 intptr_t token_pos() const { return token_pos_; }
1978 1852
1979 // Receiver class id is computed from collected ICData. 1853 // Receiver class id is computed from collected ICData.
1980 void set_receiver_class_id(intptr_t value) { receiver_class_id_ = value; } 1854 void set_receiver_class_id(intptr_t value) { receiver_class_id_ = value; }
(...skipping 18 matching lines...) Expand all
1999 virtual Representation RequiredInputRepresentation(intptr_t idx) const { 1873 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
2000 ASSERT((idx == 0) || (idx == 1)); 1874 ASSERT((idx == 0) || (idx == 1));
2001 return (receiver_class_id() == kDoubleCid) ? kUnboxedDouble : kTagged; 1875 return (receiver_class_id() == kDoubleCid) ? kUnboxedDouble : kTagged;
2002 } 1876 }
2003 1877
2004 private: 1878 private:
2005 const ICData* ic_data_; 1879 const ICData* ic_data_;
2006 const intptr_t token_pos_; 1880 const intptr_t token_pos_;
2007 intptr_t receiver_class_id_; // Set by optimizer. 1881 intptr_t receiver_class_id_; // Set by optimizer.
2008 1882
2009 DISALLOW_COPY_AND_ASSIGN(EqualityCompareComp); 1883 DISALLOW_COPY_AND_ASSIGN(EqualityCompareInstr);
2010 }; 1884 };
2011 1885
2012 1886
2013 class RelationalOpComp : public ComparisonComp { 1887 class RelationalOpInstr : public ComparisonInstr {
2014 public: 1888 public:
2015 RelationalOpComp(intptr_t token_pos, 1889 RelationalOpInstr(intptr_t token_pos,
2016 Token::Kind kind, 1890 Token::Kind kind,
2017 Value* left, 1891 Value* left,
2018 Value* right) 1892 Value* right)
2019 : ComparisonComp(kind, left, right), 1893 : ComparisonInstr(kind, left, right),
2020 ic_data_(Isolate::Current()->GetICDataForDeoptId(deopt_id())), 1894 ic_data_(Isolate::Current()->GetICDataForDeoptId(deopt_id())),
2021 token_pos_(token_pos), 1895 token_pos_(token_pos),
2022 operands_class_id_(kIllegalCid) { 1896 operands_class_id_(kIllegalCid) {
2023 ASSERT(Token::IsRelationalOperator(kind)); 1897 ASSERT(Token::IsRelationalOperator(kind));
2024 } 1898 }
2025 1899
2026 DECLARE_COMPUTATION(RelationalOp) 1900 DECLARE_INSTRUCTION(RelationalOp)
1901 virtual RawAbstractType* CompileType() const;
2027 1902
2028 const ICData* ic_data() const { return ic_data_; } 1903 const ICData* ic_data() const { return ic_data_; }
2029 bool HasICData() const { 1904 bool HasICData() const {
2030 return (ic_data() != NULL) && !ic_data()->IsNull(); 1905 return (ic_data() != NULL) && !ic_data()->IsNull();
2031 } 1906 }
2032 1907
2033 intptr_t token_pos() const { return token_pos_; } 1908 intptr_t token_pos() const { return token_pos_; }
2034 1909
2035 // TODO(srdjan): instead of class-id pass an enum that can differentiate 1910 // TODO(srdjan): instead of class-id pass an enum that can differentiate
2036 // between boxed and unboxed doubles and integers. 1911 // between boxed and unboxed doubles and integers.
(...skipping 23 matching lines...) Expand all
2060 virtual Representation RequiredInputRepresentation(intptr_t idx) const { 1935 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
2061 ASSERT((idx == 0) || (idx == 1)); 1936 ASSERT((idx == 0) || (idx == 1));
2062 return (operands_class_id() == kDoubleCid) ? kUnboxedDouble : kTagged; 1937 return (operands_class_id() == kDoubleCid) ? kUnboxedDouble : kTagged;
2063 } 1938 }
2064 1939
2065 private: 1940 private:
2066 const ICData* ic_data_; 1941 const ICData* ic_data_;
2067 const intptr_t token_pos_; 1942 const intptr_t token_pos_;
2068 intptr_t operands_class_id_; // class id of both operands. 1943 intptr_t operands_class_id_; // class id of both operands.
2069 1944
2070 DISALLOW_COPY_AND_ASSIGN(RelationalOpComp); 1945 DISALLOW_COPY_AND_ASSIGN(RelationalOpInstr);
2071 }; 1946 };
2072 1947
2073 1948
2074 class StaticCallComp : public TemplateComputation<0> { 1949 class StaticCallInstr : public TemplateDefinition<0> {
2075 public: 1950 public:
2076 StaticCallComp(intptr_t token_pos, 1951 StaticCallInstr(intptr_t token_pos,
2077 const Function& function, 1952 const Function& function,
2078 const Array& argument_names, 1953 const Array& argument_names,
2079 ZoneGrowableArray<PushArgumentInstr*>* arguments) 1954 ZoneGrowableArray<PushArgumentInstr*>* arguments)
2080 : token_pos_(token_pos), 1955 : token_pos_(token_pos),
2081 function_(function), 1956 function_(function),
2082 argument_names_(argument_names), 1957 argument_names_(argument_names),
2083 arguments_(arguments), 1958 arguments_(arguments),
2084 recognized_(MethodRecognizer::kUnknown) { 1959 recognized_(MethodRecognizer::kUnknown) {
2085 ASSERT(function.IsZoneHandle()); 1960 ASSERT(function.IsZoneHandle());
2086 ASSERT(argument_names.IsZoneHandle()); 1961 ASSERT(argument_names.IsZoneHandle());
2087 } 1962 }
2088 1963
2089 DECLARE_CALL_COMPUTATION(StaticCall) 1964 DECLARE_INSTRUCTION(StaticCall)
1965 virtual RawAbstractType* CompileType() const;
2090 1966
2091 // Accessors forwarded to the AST node. 1967 // Accessors forwarded to the AST node.
2092 const Function& function() const { return function_; } 1968 const Function& function() const { return function_; }
2093 const Array& argument_names() const { return argument_names_; } 1969 const Array& argument_names() const { return argument_names_; }
2094 intptr_t token_pos() const { return token_pos_; } 1970 intptr_t token_pos() const { return token_pos_; }
2095 1971
2096 virtual intptr_t ArgumentCount() const { return arguments_->length(); } 1972 virtual intptr_t ArgumentCount() const { return arguments_->length(); }
2097 PushArgumentInstr* ArgumentAt(intptr_t index) const { 1973 PushArgumentInstr* ArgumentAt(intptr_t index) const {
2098 return (*arguments_)[index]; 1974 return (*arguments_)[index];
2099 } 1975 }
2100 1976
2101 MethodRecognizer::Kind recognized() const { return recognized_; } 1977 MethodRecognizer::Kind recognized() const { return recognized_; }
2102 void set_recognized(MethodRecognizer::Kind kind) { recognized_ = kind; } 1978 void set_recognized(MethodRecognizer::Kind kind) { recognized_ = kind; }
2103 1979
2104 virtual void PrintOperandsTo(BufferFormatter* f) const; 1980 virtual void PrintOperandsTo(BufferFormatter* f) const;
2105 1981
2106 virtual bool CanDeoptimize() const { return true; } 1982 virtual bool CanDeoptimize() const { return true; }
2107 virtual intptr_t ResultCid() const { return kDynamicCid; } 1983 virtual intptr_t ResultCid() const { return kDynamicCid; }
2108 1984
2109 private: 1985 private:
2110 const intptr_t token_pos_; 1986 const intptr_t token_pos_;
2111 const Function& function_; 1987 const Function& function_;
2112 const Array& argument_names_; 1988 const Array& argument_names_;
2113 ZoneGrowableArray<PushArgumentInstr*>* arguments_; 1989 ZoneGrowableArray<PushArgumentInstr*>* arguments_;
2114 MethodRecognizer::Kind recognized_; 1990 MethodRecognizer::Kind recognized_;
2115 1991
2116 DISALLOW_COPY_AND_ASSIGN(StaticCallComp); 1992 DISALLOW_COPY_AND_ASSIGN(StaticCallInstr);
2117 }; 1993 };
2118 1994
2119 1995
2120 class LoadLocalComp : public TemplateComputation<0> { 1996 class LoadLocalInstr : public TemplateDefinition<0> {
2121 public: 1997 public:
2122 LoadLocalComp(const LocalVariable& local, intptr_t context_level) 1998 LoadLocalInstr(const LocalVariable& local, intptr_t context_level)
2123 : local_(local), 1999 : local_(local),
2124 context_level_(context_level) { } 2000 context_level_(context_level) { }
2125 2001
2126 DECLARE_COMPUTATION(LoadLocal) 2002 DECLARE_INSTRUCTION(LoadLocal)
2003 virtual RawAbstractType* CompileType() const;
2127 2004
2128 const LocalVariable& local() const { return local_; } 2005 const LocalVariable& local() const { return local_; }
2129 intptr_t context_level() const { return context_level_; } 2006 intptr_t context_level() const { return context_level_; }
2130 2007
2131 virtual void PrintOperandsTo(BufferFormatter* f) const; 2008 virtual void PrintOperandsTo(BufferFormatter* f) const;
2132 2009
2133 virtual bool CanDeoptimize() const { return false; } 2010 virtual bool CanDeoptimize() const { return false; }
2134 virtual intptr_t ResultCid() const { return kDynamicCid; } 2011 virtual intptr_t ResultCid() const { return kDynamicCid; }
2135 2012
2136 private: 2013 private:
2137 const LocalVariable& local_; 2014 const LocalVariable& local_;
2138 const intptr_t context_level_; 2015 const intptr_t context_level_;
2139 2016
2140 DISALLOW_COPY_AND_ASSIGN(LoadLocalComp); 2017 DISALLOW_COPY_AND_ASSIGN(LoadLocalInstr);
2141 }; 2018 };
2142 2019
2143 2020
2144 class StoreLocalComp : public TemplateComputation<1> { 2021 class StoreLocalInstr : public TemplateDefinition<1> {
2145 public: 2022 public:
2146 StoreLocalComp(const LocalVariable& local, 2023 StoreLocalInstr(const LocalVariable& local,
2147 Value* value, 2024 Value* value,
2148 intptr_t context_level) 2025 intptr_t context_level)
2149 : local_(local), 2026 : local_(local),
2150 context_level_(context_level) { 2027 context_level_(context_level) {
2151 ASSERT(value != NULL); 2028 ASSERT(value != NULL);
2152 inputs_[0] = value; 2029 inputs_[0] = value;
2153 } 2030 }
2154 2031
2155 DECLARE_COMPUTATION(StoreLocal) 2032 DECLARE_INSTRUCTION(StoreLocal)
2033 virtual RawAbstractType* CompileType() const;
2156 2034
2157 const LocalVariable& local() const { return local_; } 2035 const LocalVariable& local() const { return local_; }
2158 Value* value() const { return inputs_[0]; } 2036 Value* value() const { return inputs_[0]; }
2159 intptr_t context_level() const { return context_level_; } 2037 intptr_t context_level() const { return context_level_; }
2160 2038
2161 virtual void RecordAssignedVars(BitVector* assigned_vars, 2039 virtual void RecordAssignedVars(BitVector* assigned_vars,
2162 intptr_t fixed_parameter_count); 2040 intptr_t fixed_parameter_count);
2163 2041
2164 virtual void PrintOperandsTo(BufferFormatter* f) const; 2042 virtual void PrintOperandsTo(BufferFormatter* f) const;
2165 2043
2166 virtual bool CanDeoptimize() const { return false; } 2044 virtual bool CanDeoptimize() const { return false; }
2167 virtual intptr_t ResultCid() const { return kDynamicCid; } 2045 virtual intptr_t ResultCid() const { return kDynamicCid; }
2168 2046
2169 private: 2047 private:
2170 const LocalVariable& local_; 2048 const LocalVariable& local_;
2171 const intptr_t context_level_; 2049 const intptr_t context_level_;
2172 2050
2173 DISALLOW_COPY_AND_ASSIGN(StoreLocalComp); 2051 DISALLOW_COPY_AND_ASSIGN(StoreLocalInstr);
2174 }; 2052 };
2175 2053
2176 2054
2177 class NativeCallComp : public TemplateComputation<0> { 2055 class NativeCallInstr : public TemplateDefinition<0> {
2178 public: 2056 public:
2179 explicit NativeCallComp(NativeBodyNode* node) 2057 explicit NativeCallInstr(NativeBodyNode* node)
2180 : ast_node_(*node) {} 2058 : ast_node_(*node) {}
2181 2059
2182 DECLARE_COMPUTATION(NativeCall) 2060 DECLARE_INSTRUCTION(NativeCall)
2061 virtual RawAbstractType* CompileType() const;
2183 2062
2184 intptr_t token_pos() const { return ast_node_.token_pos(); } 2063 intptr_t token_pos() const { return ast_node_.token_pos(); }
2185 2064
2186 const String& native_name() const { 2065 const String& native_name() const {
2187 return ast_node_.native_c_function_name(); 2066 return ast_node_.native_c_function_name();
2188 } 2067 }
2189 2068
2190 NativeFunction native_c_function() const { 2069 NativeFunction native_c_function() const {
2191 return ast_node_.native_c_function(); 2070 return ast_node_.native_c_function();
2192 } 2071 }
2193 2072
2194 intptr_t argument_count() const { return ast_node_.argument_count(); } 2073 intptr_t argument_count() const { return ast_node_.argument_count(); }
2195 2074
2196 bool has_optional_parameters() const { 2075 bool has_optional_parameters() const {
2197 return ast_node_.has_optional_parameters(); 2076 return ast_node_.has_optional_parameters();
2198 } 2077 }
2199 2078
2200 bool is_native_instance_closure() const { 2079 bool is_native_instance_closure() const {
2201 return ast_node_.is_native_instance_closure(); 2080 return ast_node_.is_native_instance_closure();
2202 } 2081 }
2203 2082
2204 virtual void PrintOperandsTo(BufferFormatter* f) const; 2083 virtual void PrintOperandsTo(BufferFormatter* f) const;
2205 2084
2206 virtual bool CanDeoptimize() const { return false; } 2085 virtual bool CanDeoptimize() const { return false; }
2207 virtual intptr_t ResultCid() const { return kDynamicCid; } 2086 virtual intptr_t ResultCid() const { return kDynamicCid; }
2208 2087
2209 private: 2088 private:
2210 const NativeBodyNode& ast_node_; 2089 const NativeBodyNode& ast_node_;
2211 2090
2212 DISALLOW_COPY_AND_ASSIGN(NativeCallComp); 2091 DISALLOW_COPY_AND_ASSIGN(NativeCallInstr);
2213 }; 2092 };
2214 2093
2215 2094
2216 class LoadInstanceFieldComp : public TemplateComputation<1> { 2095 class LoadInstanceFieldInstr : public TemplateDefinition<1> {
2217 public: 2096 public:
2218 LoadInstanceFieldComp(const Field& field, Value* instance) : field_(field) { 2097 LoadInstanceFieldInstr(const Field& field, Value* instance) : field_(field) {
2219 ASSERT(instance != NULL); 2098 ASSERT(instance != NULL);
2220 inputs_[0] = instance; 2099 inputs_[0] = instance;
2221 } 2100 }
2222 2101
2223 DECLARE_COMPUTATION(LoadInstanceField) 2102 DECLARE_INSTRUCTION(LoadInstanceField)
2103 virtual RawAbstractType* CompileType() const;
2224 2104
2225 const Field& field() const { return field_; } 2105 const Field& field() const { return field_; }
2226 Value* instance() const { return inputs_[0]; } 2106 Value* instance() const { return inputs_[0]; }
2227 2107
2228 virtual void PrintOperandsTo(BufferFormatter* f) const; 2108 virtual void PrintOperandsTo(BufferFormatter* f) const;
2229 2109
2230 virtual bool CanDeoptimize() const { return false; } 2110 virtual bool CanDeoptimize() const { return false; }
2231 virtual intptr_t ResultCid() const { return kDynamicCid; } 2111 virtual intptr_t ResultCid() const { return kDynamicCid; }
2232 2112
2233 private: 2113 private:
2234 const Field& field_; 2114 const Field& field_;
2235 2115
2236 DISALLOW_COPY_AND_ASSIGN(LoadInstanceFieldComp); 2116 DISALLOW_COPY_AND_ASSIGN(LoadInstanceFieldInstr);
2237 }; 2117 };
2238 2118
2239 2119
2240 class StoreInstanceFieldComp : public TemplateComputation<2> { 2120 class StoreInstanceFieldInstr : public TemplateDefinition<2> {
2241 public: 2121 public:
2242 StoreInstanceFieldComp(const Field& field, 2122 StoreInstanceFieldInstr(const Field& field, Value* instance, Value* value)
2243 Value* instance,
2244 Value* value)
2245 : field_(field) { 2123 : field_(field) {
2246 ASSERT(instance != NULL); 2124 ASSERT(instance != NULL);
2247 ASSERT(value != NULL); 2125 ASSERT(value != NULL);
2248 inputs_[0] = instance; 2126 inputs_[0] = instance;
2249 inputs_[1] = value; 2127 inputs_[1] = value;
2250 } 2128 }
2251 2129
2252 DECLARE_COMPUTATION(StoreInstanceField) 2130 DECLARE_INSTRUCTION(StoreInstanceField)
2131 virtual RawAbstractType* CompileType() const;
2253 2132
2254 const Field& field() const { return field_; } 2133 const Field& field() const { return field_; }
2255 2134
2256 Value* instance() const { return inputs_[0]; } 2135 Value* instance() const { return inputs_[0]; }
2257 Value* value() const { return inputs_[1]; } 2136 Value* value() const { return inputs_[1]; }
2258 2137
2259 virtual void PrintOperandsTo(BufferFormatter* f) const; 2138 virtual void PrintOperandsTo(BufferFormatter* f) const;
2260 2139
2261 virtual bool CanDeoptimize() const { return false; } 2140 virtual bool CanDeoptimize() const { return false; }
2262 virtual intptr_t ResultCid() const { return kDynamicCid; } 2141 virtual intptr_t ResultCid() const { return kDynamicCid; }
2263 2142
2264 private: 2143 private:
2265 const Field& field_; 2144 const Field& field_;
2266 2145
2267 DISALLOW_COPY_AND_ASSIGN(StoreInstanceFieldComp); 2146 DISALLOW_COPY_AND_ASSIGN(StoreInstanceFieldInstr);
2268 }; 2147 };
2269 2148
2270 2149
2271 class LoadStaticFieldComp : public TemplateComputation<0> { 2150 class LoadStaticFieldInstr : public TemplateDefinition<0> {
2272 public: 2151 public:
2273 explicit LoadStaticFieldComp(const Field& field) : field_(field) {} 2152 explicit LoadStaticFieldInstr(const Field& field) : field_(field) {}
2274 2153
2275 DECLARE_COMPUTATION(LoadStaticField); 2154 DECLARE_INSTRUCTION(LoadStaticField);
2155 virtual RawAbstractType* CompileType() const;
2276 2156
2277 const Field& field() const { return field_; } 2157 const Field& field() const { return field_; }
2278 2158
2279 virtual void PrintOperandsTo(BufferFormatter* f) const; 2159 virtual void PrintOperandsTo(BufferFormatter* f) const;
2280 2160
2281 virtual bool CanDeoptimize() const { return false; } 2161 virtual bool CanDeoptimize() const { return false; }
2282 virtual intptr_t ResultCid() const { return kDynamicCid; } 2162 virtual intptr_t ResultCid() const { return kDynamicCid; }
2283 2163
2284 private: 2164 private:
2285 const Field& field_; 2165 const Field& field_;
2286 2166
2287 DISALLOW_COPY_AND_ASSIGN(LoadStaticFieldComp); 2167 DISALLOW_COPY_AND_ASSIGN(LoadStaticFieldInstr);
2288 }; 2168 };
2289 2169
2290 2170
2291 class StoreStaticFieldComp : public TemplateComputation<1> { 2171 class StoreStaticFieldInstr : public TemplateDefinition<1> {
2292 public: 2172 public:
2293 StoreStaticFieldComp(const Field& field, Value* value) 2173 StoreStaticFieldInstr(const Field& field, Value* value)
2294 : field_(field) { 2174 : field_(field) {
2295 ASSERT(field.IsZoneHandle()); 2175 ASSERT(field.IsZoneHandle());
2296 ASSERT(value != NULL); 2176 ASSERT(value != NULL);
2297 inputs_[0] = value; 2177 inputs_[0] = value;
2298 } 2178 }
2299 2179
2300 DECLARE_COMPUTATION(StoreStaticField); 2180 DECLARE_INSTRUCTION(StoreStaticField);
2181 virtual RawAbstractType* CompileType() const;
2301 2182
2302 const Field& field() const { return field_; } 2183 const Field& field() const { return field_; }
2303 Value* value() const { return inputs_[0]; } 2184 Value* value() const { return inputs_[0]; }
2304 2185
2305 virtual void PrintOperandsTo(BufferFormatter* f) const; 2186 virtual void PrintOperandsTo(BufferFormatter* f) const;
2306 2187
2307 virtual bool CanDeoptimize() const { return false; } 2188 virtual bool CanDeoptimize() const { return false; }
2308 virtual intptr_t ResultCid() const { return kDynamicCid; } 2189 virtual intptr_t ResultCid() const { return kDynamicCid; }
2309 2190
2310 private: 2191 private:
2311 const Field& field_; 2192 const Field& field_;
2312 2193
2313 DISALLOW_COPY_AND_ASSIGN(StoreStaticFieldComp); 2194 DISALLOW_COPY_AND_ASSIGN(StoreStaticFieldInstr);
2314 }; 2195 };
2315 2196
2316 2197
2317 class LoadIndexedComp : public TemplateComputation<2> { 2198 class LoadIndexedInstr : public TemplateDefinition<2> {
2318 public: 2199 public:
2319 LoadIndexedComp(Value* array, 2200 LoadIndexedInstr(Value* array, Value* index, intptr_t receiver_type)
2320 Value* index,
2321 intptr_t receiver_type)
2322 : receiver_type_(receiver_type) { 2201 : receiver_type_(receiver_type) {
2323 ASSERT(array != NULL); 2202 ASSERT(array != NULL);
2324 ASSERT(index != NULL); 2203 ASSERT(index != NULL);
2325 inputs_[0] = array; 2204 inputs_[0] = array;
2326 inputs_[1] = index; 2205 inputs_[1] = index;
2327 } 2206 }
2328 2207
2329 DECLARE_COMPUTATION(LoadIndexed) 2208 DECLARE_INSTRUCTION(LoadIndexed)
2209 virtual RawAbstractType* CompileType() const;
2330 2210
2331 Value* array() const { return inputs_[0]; } 2211 Value* array() const { return inputs_[0]; }
2332 Value* index() const { return inputs_[1]; } 2212 Value* index() const { return inputs_[1]; }
2333 2213
2334 intptr_t receiver_type() const { return receiver_type_; } 2214 intptr_t receiver_type() const { return receiver_type_; }
2335 2215
2336 virtual bool CanDeoptimize() const { return false; } 2216 virtual bool CanDeoptimize() const { return false; }
2337 virtual intptr_t ResultCid() const { return kDynamicCid; } 2217 virtual intptr_t ResultCid() const { return kDynamicCid; }
2338 2218
2339 private: 2219 private:
2340 intptr_t receiver_type_; 2220 intptr_t receiver_type_;
2341 2221
2342 DISALLOW_COPY_AND_ASSIGN(LoadIndexedComp); 2222 DISALLOW_COPY_AND_ASSIGN(LoadIndexedInstr);
2343 }; 2223 };
2344 2224
2345 2225
2346 class StoreIndexedComp : public TemplateComputation<3> { 2226 class StoreIndexedInstr : public TemplateDefinition<3> {
2347 public: 2227 public:
2348 StoreIndexedComp(Value* array, 2228 StoreIndexedInstr(Value* array,
2349 Value* index, 2229 Value* index,
2350 Value* value, 2230 Value* value,
2351 intptr_t receiver_type) 2231 intptr_t receiver_type)
2352 : receiver_type_(receiver_type) { 2232 : receiver_type_(receiver_type) {
2353 ASSERT(array != NULL); 2233 ASSERT(array != NULL);
2354 ASSERT(index != NULL); 2234 ASSERT(index != NULL);
2355 ASSERT(value != NULL); 2235 ASSERT(value != NULL);
2356 inputs_[0] = array; 2236 inputs_[0] = array;
2357 inputs_[1] = index; 2237 inputs_[1] = index;
2358 inputs_[2] = value; 2238 inputs_[2] = value;
2359 } 2239 }
2360 2240
2361 DECLARE_COMPUTATION(StoreIndexed) 2241 DECLARE_INSTRUCTION(StoreIndexed)
2242 virtual RawAbstractType* CompileType() const;
2362 2243
2363 Value* array() const { return inputs_[0]; } 2244 Value* array() const { return inputs_[0]; }
2364 Value* index() const { return inputs_[1]; } 2245 Value* index() const { return inputs_[1]; }
2365 Value* value() const { return inputs_[2]; } 2246 Value* value() const { return inputs_[2]; }
2366 2247
2367 intptr_t receiver_type() const { return receiver_type_; } 2248 intptr_t receiver_type() const { return receiver_type_; }
2368 2249
2369 virtual bool CanDeoptimize() const { return false; } 2250 virtual bool CanDeoptimize() const { return false; }
2370 virtual intptr_t ResultCid() const { return kDynamicCid; } 2251 virtual intptr_t ResultCid() const { return kDynamicCid; }
2371 2252
2372 private: 2253 private:
2373 intptr_t receiver_type_; 2254 intptr_t receiver_type_;
2374 2255
2375 DISALLOW_COPY_AND_ASSIGN(StoreIndexedComp); 2256 DISALLOW_COPY_AND_ASSIGN(StoreIndexedInstr);
2376 }; 2257 };
2377 2258
2378 2259
2379 // Note overrideable, built-in: value? false : true. 2260 // Note overrideable, built-in: value? false : true.
2380 class BooleanNegateComp : public TemplateComputation<1> { 2261 class BooleanNegateInstr : public TemplateDefinition<1> {
2381 public: 2262 public:
2382 explicit BooleanNegateComp(Value* value) { 2263 explicit BooleanNegateInstr(Value* value) {
2383 ASSERT(value != NULL); 2264 ASSERT(value != NULL);
2384 inputs_[0] = value; 2265 inputs_[0] = value;
2385 } 2266 }
2386 2267
2387 DECLARE_COMPUTATION(BooleanNegate) 2268 DECLARE_INSTRUCTION(BooleanNegate)
2269 virtual RawAbstractType* CompileType() const;
2388 2270
2389 Value* value() const { return inputs_[0]; } 2271 Value* value() const { return inputs_[0]; }
2390 2272
2391 virtual bool CanDeoptimize() const { return false; } 2273 virtual bool CanDeoptimize() const { return false; }
2392 virtual intptr_t ResultCid() const { return kBoolCid; } 2274 virtual intptr_t ResultCid() const { return kBoolCid; }
2393 2275
2394 private: 2276 private:
2395 DISALLOW_COPY_AND_ASSIGN(BooleanNegateComp); 2277 DISALLOW_COPY_AND_ASSIGN(BooleanNegateInstr);
2396 }; 2278 };
2397 2279
2398 2280
2399 class InstanceOfComp : public TemplateComputation<3> { 2281 class InstanceOfInstr : public TemplateDefinition<3> {
2400 public: 2282 public:
2401 InstanceOfComp(intptr_t token_pos, 2283 InstanceOfInstr(intptr_t token_pos,
2402 Value* value, 2284 Value* value,
2403 Value* instantiator, 2285 Value* instantiator,
2404 Value* instantiator_type_arguments, 2286 Value* instantiator_type_arguments,
2405 const AbstractType& type, 2287 const AbstractType& type,
2406 bool negate_result) 2288 bool negate_result)
2407 : token_pos_(token_pos), 2289 : token_pos_(token_pos),
2408 type_(type), 2290 type_(type),
2409 negate_result_(negate_result) { 2291 negate_result_(negate_result) {
2410 ASSERT(value != NULL); 2292 ASSERT(value != NULL);
2411 ASSERT(instantiator != NULL); 2293 ASSERT(instantiator != NULL);
2412 ASSERT(instantiator_type_arguments != NULL); 2294 ASSERT(instantiator_type_arguments != NULL);
2413 ASSERT(!type.IsNull()); 2295 ASSERT(!type.IsNull());
2414 inputs_[0] = value; 2296 inputs_[0] = value;
2415 inputs_[1] = instantiator; 2297 inputs_[1] = instantiator;
2416 inputs_[2] = instantiator_type_arguments; 2298 inputs_[2] = instantiator_type_arguments;
2417 } 2299 }
2418 2300
2419 DECLARE_COMPUTATION(InstanceOf) 2301 DECLARE_INSTRUCTION(InstanceOf)
2302 virtual RawAbstractType* CompileType() const;
2420 2303
2421 Value* value() const { return inputs_[0]; } 2304 Value* value() const { return inputs_[0]; }
2422 Value* instantiator() const { return inputs_[1]; } 2305 Value* instantiator() const { return inputs_[1]; }
2423 Value* instantiator_type_arguments() const { return inputs_[2]; } 2306 Value* instantiator_type_arguments() const { return inputs_[2]; }
2424 2307
2425 bool negate_result() const { return negate_result_; } 2308 bool negate_result() const { return negate_result_; }
2426 const AbstractType& type() const { return type_; } 2309 const AbstractType& type() const { return type_; }
2427 intptr_t token_pos() const { return token_pos_; } 2310 intptr_t token_pos() const { return token_pos_; }
2428 2311
2429 virtual void PrintOperandsTo(BufferFormatter* f) const; 2312 virtual void PrintOperandsTo(BufferFormatter* f) const;
2430 2313
2431 virtual bool CanDeoptimize() const { return false; } 2314 virtual bool CanDeoptimize() const { return false; }
2432 virtual intptr_t ResultCid() const { return kBoolCid; } 2315 virtual intptr_t ResultCid() const { return kBoolCid; }
2433 2316
2434 private: 2317 private:
2435 const intptr_t token_pos_; 2318 const intptr_t token_pos_;
2436 Value* value_; 2319 Value* value_;
2437 Value* instantiator_; 2320 Value* instantiator_;
2438 Value* type_arguments_; 2321 Value* type_arguments_;
2439 const AbstractType& type_; 2322 const AbstractType& type_;
2440 const bool negate_result_; 2323 const bool negate_result_;
2441 2324
2442 DISALLOW_COPY_AND_ASSIGN(InstanceOfComp); 2325 DISALLOW_COPY_AND_ASSIGN(InstanceOfInstr);
2443 }; 2326 };
2444 2327
2445 2328
2446 class AllocateObjectComp : public TemplateComputation<0> { 2329 class AllocateObjectInstr : public TemplateDefinition<0> {
2447 public: 2330 public:
2448 AllocateObjectComp(ConstructorCallNode* node, 2331 AllocateObjectInstr(ConstructorCallNode* node,
2449 ZoneGrowableArray<PushArgumentInstr*>* arguments) 2332 ZoneGrowableArray<PushArgumentInstr*>* arguments)
2450 : ast_node_(*node), arguments_(arguments) { 2333 : ast_node_(*node), arguments_(arguments) {
2451 // Either no arguments or one type-argument and one instantiator. 2334 // Either no arguments or one type-argument and one instantiator.
2452 ASSERT(arguments->is_empty() || (arguments->length() == 2)); 2335 ASSERT(arguments->is_empty() || (arguments->length() == 2));
2453 } 2336 }
2454 2337
2455 DECLARE_CALL_COMPUTATION(AllocateObject) 2338 DECLARE_INSTRUCTION(AllocateObject)
2339 virtual RawAbstractType* CompileType() const;
2456 2340
2457 virtual intptr_t ArgumentCount() const { return arguments_->length(); } 2341 virtual intptr_t ArgumentCount() const { return arguments_->length(); }
2458 PushArgumentInstr* ArgumentAt(intptr_t index) const { 2342 PushArgumentInstr* ArgumentAt(intptr_t index) const {
2459 return (*arguments_)[index]; 2343 return (*arguments_)[index];
2460 } 2344 }
2461 2345
2462 const Function& constructor() const { return ast_node_.constructor(); } 2346 const Function& constructor() const { return ast_node_.constructor(); }
2463 intptr_t token_pos() const { return ast_node_.token_pos(); } 2347 intptr_t token_pos() const { return ast_node_.token_pos(); }
2464 2348
2465 virtual void PrintOperandsTo(BufferFormatter* f) const; 2349 virtual void PrintOperandsTo(BufferFormatter* f) const;
2466 2350
2467 virtual bool CanDeoptimize() const { return false; } 2351 virtual bool CanDeoptimize() const { return false; }
2468 virtual intptr_t ResultCid() const { return kDynamicCid; } 2352 virtual intptr_t ResultCid() const { return kDynamicCid; }
2469 2353
2470 private: 2354 private:
2471 const ConstructorCallNode& ast_node_; 2355 const ConstructorCallNode& ast_node_;
2472 ZoneGrowableArray<PushArgumentInstr*>* const arguments_; 2356 ZoneGrowableArray<PushArgumentInstr*>* const arguments_;
2473 2357
2474 DISALLOW_COPY_AND_ASSIGN(AllocateObjectComp); 2358 DISALLOW_COPY_AND_ASSIGN(AllocateObjectInstr);
2475 }; 2359 };
2476 2360
2477 2361
2478 class AllocateObjectWithBoundsCheckComp : public TemplateComputation<2> { 2362 class AllocateObjectWithBoundsCheckInstr : public TemplateDefinition<2> {
2479 public: 2363 public:
2480 AllocateObjectWithBoundsCheckComp(ConstructorCallNode* node, 2364 AllocateObjectWithBoundsCheckInstr(ConstructorCallNode* node,
2481 Value* type_arguments, 2365 Value* type_arguments,
2482 Value* instantiator) 2366 Value* instantiator)
2483 : ast_node_(*node) { 2367 : ast_node_(*node) {
2484 ASSERT(type_arguments != NULL); 2368 ASSERT(type_arguments != NULL);
2485 ASSERT(instantiator != NULL); 2369 ASSERT(instantiator != NULL);
2486 inputs_[0] = type_arguments; 2370 inputs_[0] = type_arguments;
2487 inputs_[1] = instantiator; 2371 inputs_[1] = instantiator;
2488 } 2372 }
2489 2373
2490 DECLARE_COMPUTATION(AllocateObjectWithBoundsCheck) 2374 DECLARE_INSTRUCTION(AllocateObjectWithBoundsCheck)
2375 virtual RawAbstractType* CompileType() const;
2491 2376
2492 const Function& constructor() const { return ast_node_.constructor(); } 2377 const Function& constructor() const { return ast_node_.constructor(); }
2493 intptr_t token_pos() const { return ast_node_.token_pos(); } 2378 intptr_t token_pos() const { return ast_node_.token_pos(); }
2494 2379
2495 virtual void PrintOperandsTo(BufferFormatter* f) const; 2380 virtual void PrintOperandsTo(BufferFormatter* f) const;
2496 2381
2497 virtual bool CanDeoptimize() const { return false; } 2382 virtual bool CanDeoptimize() const { return false; }
2498 virtual intptr_t ResultCid() const { return kDynamicCid; } 2383 virtual intptr_t ResultCid() const { return kDynamicCid; }
2499 2384
2500 private: 2385 private:
2501 const ConstructorCallNode& ast_node_; 2386 const ConstructorCallNode& ast_node_;
2502 2387
2503 DISALLOW_COPY_AND_ASSIGN(AllocateObjectWithBoundsCheckComp); 2388 DISALLOW_COPY_AND_ASSIGN(AllocateObjectWithBoundsCheckInstr);
2504 }; 2389 };
2505 2390
2506 2391
2507 class CreateArrayComp : public TemplateComputation<1> { 2392 class CreateArrayInstr : public TemplateDefinition<1> {
2508 public: 2393 public:
2509 CreateArrayComp(intptr_t token_pos, 2394 CreateArrayInstr(intptr_t token_pos,
2510 ZoneGrowableArray<PushArgumentInstr*>* arguments, 2395 ZoneGrowableArray<PushArgumentInstr*>* arguments,
2511 const AbstractType& type, 2396 const AbstractType& type,
2512 Value* element_type) 2397 Value* element_type)
2513 : token_pos_(token_pos), 2398 : token_pos_(token_pos),
2514 arguments_(arguments), 2399 arguments_(arguments),
2515 type_(type) { 2400 type_(type) {
2516 #if defined(DEBUG) 2401 #if defined(DEBUG)
2517 for (int i = 0; i < ArgumentCount(); ++i) { 2402 for (int i = 0; i < ArgumentCount(); ++i) {
2518 ASSERT(ArgumentAt(i) != NULL); 2403 ASSERT(ArgumentAt(i) != NULL);
2519 } 2404 }
2520 ASSERT(element_type != NULL); 2405 ASSERT(element_type != NULL);
2521 ASSERT(type_.IsZoneHandle()); 2406 ASSERT(type_.IsZoneHandle());
2522 ASSERT(!type_.IsNull()); 2407 ASSERT(!type_.IsNull());
2523 ASSERT(type_.IsFinalized()); 2408 ASSERT(type_.IsFinalized());
2524 #endif 2409 #endif
2525 inputs_[0] = element_type; 2410 inputs_[0] = element_type;
2526 } 2411 }
2527 2412
2528 DECLARE_CALL_COMPUTATION(CreateArray) 2413 DECLARE_INSTRUCTION(CreateArray)
2414 virtual RawAbstractType* CompileType() const;
2529 2415
2530 virtual intptr_t ArgumentCount() const { return arguments_->length(); } 2416 virtual intptr_t ArgumentCount() const { return arguments_->length(); }
2531 2417
2532 intptr_t token_pos() const { return token_pos_; } 2418 intptr_t token_pos() const { return token_pos_; }
2533 PushArgumentInstr* ArgumentAt(intptr_t i) const { return (*arguments_)[i]; } 2419 PushArgumentInstr* ArgumentAt(intptr_t i) const { return (*arguments_)[i]; }
2534 const AbstractType& type() const { return type_; } 2420 const AbstractType& type() const { return type_; }
2535 Value* element_type() const { return inputs_[0]; } 2421 Value* element_type() const { return inputs_[0]; }
2536 2422
2537 virtual void PrintOperandsTo(BufferFormatter* f) const; 2423 virtual void PrintOperandsTo(BufferFormatter* f) const;
2538 2424
2539 virtual bool CanDeoptimize() const { return false; } 2425 virtual bool CanDeoptimize() const { return false; }
2540 virtual intptr_t ResultCid() const { return kDynamicCid; } 2426 virtual intptr_t ResultCid() const { return kDynamicCid; }
2541 2427
2542 private: 2428 private:
2543 const intptr_t token_pos_; 2429 const intptr_t token_pos_;
2544 ZoneGrowableArray<PushArgumentInstr*>* const arguments_; 2430 ZoneGrowableArray<PushArgumentInstr*>* const arguments_;
2545 const AbstractType& type_; 2431 const AbstractType& type_;
2546 2432
2547 DISALLOW_COPY_AND_ASSIGN(CreateArrayComp); 2433 DISALLOW_COPY_AND_ASSIGN(CreateArrayInstr);
2548 }; 2434 };
2549 2435
2550 2436
2551 class CreateClosureComp : public TemplateComputation<0> { 2437 class CreateClosureInstr : public TemplateDefinition<0> {
2552 public: 2438 public:
2553 CreateClosureComp(ClosureNode* node, 2439 CreateClosureInstr(ClosureNode* node,
2554 ZoneGrowableArray<PushArgumentInstr*>* arguments) 2440 ZoneGrowableArray<PushArgumentInstr*>* arguments)
2555 : ast_node_(*node), 2441 : ast_node_(*node),
2556 arguments_(arguments) { } 2442 arguments_(arguments) { }
2557 2443
2558 DECLARE_CALL_COMPUTATION(CreateClosure) 2444 DECLARE_INSTRUCTION(CreateClosure)
2445 virtual RawAbstractType* CompileType() const;
2559 2446
2560 intptr_t token_pos() const { return ast_node_.token_pos(); } 2447 intptr_t token_pos() const { return ast_node_.token_pos(); }
2561 const Function& function() const { return ast_node_.function(); } 2448 const Function& function() const { return ast_node_.function(); }
2562 2449
2563 virtual intptr_t ArgumentCount() const { return arguments_->length(); } 2450 virtual intptr_t ArgumentCount() const { return arguments_->length(); }
2564 PushArgumentInstr* ArgumentAt(intptr_t index) const { 2451 PushArgumentInstr* ArgumentAt(intptr_t index) const {
2565 return (*arguments_)[index]; 2452 return (*arguments_)[index];
2566 } 2453 }
2567 2454
2568 virtual void PrintOperandsTo(BufferFormatter* f) const; 2455 virtual void PrintOperandsTo(BufferFormatter* f) const;
2569 2456
2570 virtual bool CanDeoptimize() const { return false; } 2457 virtual bool CanDeoptimize() const { return false; }
2571 virtual intptr_t ResultCid() const { return kDynamicCid; } 2458 virtual intptr_t ResultCid() const { return kDynamicCid; }
2572 2459
2573 private: 2460 private:
2574 const ClosureNode& ast_node_; 2461 const ClosureNode& ast_node_;
2575 ZoneGrowableArray<PushArgumentInstr*>* arguments_; 2462 ZoneGrowableArray<PushArgumentInstr*>* arguments_;
2576 2463
2577 DISALLOW_COPY_AND_ASSIGN(CreateClosureComp); 2464 DISALLOW_COPY_AND_ASSIGN(CreateClosureInstr);
2578 }; 2465 };
2579 2466
2580 2467
2581 class LoadVMFieldComp : public TemplateComputation<1> { 2468 class LoadVMFieldInstr : public TemplateDefinition<1> {
2582 public: 2469 public:
2583 LoadVMFieldComp(Value* value, 2470 LoadVMFieldInstr(Value* value,
2584 intptr_t offset_in_bytes, 2471 intptr_t offset_in_bytes,
2585 const AbstractType& type) 2472 const AbstractType& type)
2586 : offset_in_bytes_(offset_in_bytes), 2473 : offset_in_bytes_(offset_in_bytes),
2587 type_(type), 2474 type_(type),
2588 result_cid_(kDynamicCid) { 2475 result_cid_(kDynamicCid) {
2589 ASSERT(value != NULL); 2476 ASSERT(value != NULL);
2590 ASSERT(type.IsZoneHandle()); // May be null if field is not an instance. 2477 ASSERT(type.IsZoneHandle()); // May be null if field is not an instance.
2591 inputs_[0] = value; 2478 inputs_[0] = value;
2592 } 2479 }
2593 2480
2594 DECLARE_COMPUTATION(LoadVMField) 2481 DECLARE_INSTRUCTION(LoadVMField)
2482 virtual RawAbstractType* CompileType() const;
2595 2483
2596 Value* value() const { return inputs_[0]; } 2484 Value* value() const { return inputs_[0]; }
2597 intptr_t offset_in_bytes() const { return offset_in_bytes_; } 2485 intptr_t offset_in_bytes() const { return offset_in_bytes_; }
2598 const AbstractType& type() const { return type_; } 2486 const AbstractType& type() const { return type_; }
2599 void set_result_cid(intptr_t value) { result_cid_ = value; } 2487 void set_result_cid(intptr_t value) { result_cid_ = value; }
2600 2488
2601 virtual void PrintOperandsTo(BufferFormatter* f) const; 2489 virtual void PrintOperandsTo(BufferFormatter* f) const;
2602 2490
2603 virtual bool CanDeoptimize() const { return false; } 2491 virtual bool CanDeoptimize() const { return false; }
2604 virtual intptr_t ResultCid() const { return result_cid_; } 2492 virtual intptr_t ResultCid() const { return result_cid_; }
2605 2493
2606 private: 2494 private:
2607 const intptr_t offset_in_bytes_; 2495 const intptr_t offset_in_bytes_;
2608 const AbstractType& type_; 2496 const AbstractType& type_;
2609 intptr_t result_cid_; 2497 intptr_t result_cid_;
2610 2498
2611 DISALLOW_COPY_AND_ASSIGN(LoadVMFieldComp); 2499 DISALLOW_COPY_AND_ASSIGN(LoadVMFieldInstr);
2612 }; 2500 };
2613 2501
2614 2502
2615 class StoreVMFieldComp : public TemplateComputation<2> { 2503 class StoreVMFieldInstr : public TemplateDefinition<2> {
2616 public: 2504 public:
2617 StoreVMFieldComp(Value* dest, 2505 StoreVMFieldInstr(Value* dest,
2618 intptr_t offset_in_bytes, 2506 intptr_t offset_in_bytes,
2619 Value* value, 2507 Value* value,
2620 const AbstractType& type) 2508 const AbstractType& type)
2621 : offset_in_bytes_(offset_in_bytes), type_(type) { 2509 : offset_in_bytes_(offset_in_bytes), type_(type) {
2622 ASSERT(value != NULL); 2510 ASSERT(value != NULL);
2623 ASSERT(dest != NULL); 2511 ASSERT(dest != NULL);
2624 ASSERT(type.IsZoneHandle()); // May be null if field is not an instance. 2512 ASSERT(type.IsZoneHandle()); // May be null if field is not an instance.
2625 inputs_[0] = value; 2513 inputs_[0] = value;
2626 inputs_[1] = dest; 2514 inputs_[1] = dest;
2627 } 2515 }
2628 2516
2629 DECLARE_COMPUTATION(StoreVMField) 2517 DECLARE_INSTRUCTION(StoreVMField)
2518 virtual RawAbstractType* CompileType() const;
2630 2519
2631 Value* value() const { return inputs_[0]; } 2520 Value* value() const { return inputs_[0]; }
2632 Value* dest() const { return inputs_[1]; } 2521 Value* dest() const { return inputs_[1]; }
2633 intptr_t offset_in_bytes() const { return offset_in_bytes_; } 2522 intptr_t offset_in_bytes() const { return offset_in_bytes_; }
2634 const AbstractType& type() const { return type_; } 2523 const AbstractType& type() const { return type_; }
2635 2524
2636 virtual void PrintOperandsTo(BufferFormatter* f) const; 2525 virtual void PrintOperandsTo(BufferFormatter* f) const;
2637 2526
2638 virtual bool CanDeoptimize() const { return false; } 2527 virtual bool CanDeoptimize() const { return false; }
2639 virtual intptr_t ResultCid() const { return kDynamicCid; } 2528 virtual intptr_t ResultCid() const { return kDynamicCid; }
2640 2529
2641 private: 2530 private:
2642 const intptr_t offset_in_bytes_; 2531 const intptr_t offset_in_bytes_;
2643 const AbstractType& type_; 2532 const AbstractType& type_;
2644 2533
2645 DISALLOW_COPY_AND_ASSIGN(StoreVMFieldComp); 2534 DISALLOW_COPY_AND_ASSIGN(StoreVMFieldInstr);
2646 }; 2535 };
2647 2536
2648 2537
2649 class InstantiateTypeArgumentsComp : public TemplateComputation<1> { 2538 class InstantiateTypeArgumentsInstr : public TemplateDefinition<1> {
2650 public: 2539 public:
2651 InstantiateTypeArgumentsComp(intptr_t token_pos, 2540 InstantiateTypeArgumentsInstr(intptr_t token_pos,
2652 const AbstractTypeArguments& type_arguments, 2541 const AbstractTypeArguments& type_arguments,
2653 Value* instantiator) 2542 Value* instantiator)
2654 : token_pos_(token_pos), 2543 : token_pos_(token_pos),
2655 type_arguments_(type_arguments) { 2544 type_arguments_(type_arguments) {
2656 ASSERT(type_arguments.IsZoneHandle()); 2545 ASSERT(type_arguments.IsZoneHandle());
2657 ASSERT(instantiator != NULL); 2546 ASSERT(instantiator != NULL);
2658 inputs_[0] = instantiator; 2547 inputs_[0] = instantiator;
2659 } 2548 }
2660 2549
2661 DECLARE_COMPUTATION(InstantiateTypeArguments) 2550 DECLARE_INSTRUCTION(InstantiateTypeArguments)
2551 virtual RawAbstractType* CompileType() const;
2662 2552
2663 Value* instantiator() const { return inputs_[0]; } 2553 Value* instantiator() const { return inputs_[0]; }
2664 const AbstractTypeArguments& type_arguments() const { 2554 const AbstractTypeArguments& type_arguments() const {
2665 return type_arguments_; 2555 return type_arguments_;
2666 } 2556 }
2667 intptr_t token_pos() const { return token_pos_; } 2557 intptr_t token_pos() const { return token_pos_; }
2668 2558
2669 virtual void PrintOperandsTo(BufferFormatter* f) const; 2559 virtual void PrintOperandsTo(BufferFormatter* f) const;
2670 2560
2671 virtual bool CanDeoptimize() const { return false; } 2561 virtual bool CanDeoptimize() const { return false; }
2672 virtual intptr_t ResultCid() const { return kDynamicCid; } 2562 virtual intptr_t ResultCid() const { return kDynamicCid; }
2673 2563
2674 private: 2564 private:
2675 const intptr_t token_pos_; 2565 const intptr_t token_pos_;
2676 const AbstractTypeArguments& type_arguments_; 2566 const AbstractTypeArguments& type_arguments_;
2677 2567
2678 DISALLOW_COPY_AND_ASSIGN(InstantiateTypeArgumentsComp); 2568 DISALLOW_COPY_AND_ASSIGN(InstantiateTypeArgumentsInstr);
2679 }; 2569 };
2680 2570
2681 2571
2682 class ExtractConstructorTypeArgumentsComp : public TemplateComputation<1> { 2572 class ExtractConstructorTypeArgumentsInstr : public TemplateDefinition<1> {
2683 public: 2573 public:
2684 ExtractConstructorTypeArgumentsComp( 2574 ExtractConstructorTypeArgumentsInstr(
2685 intptr_t token_pos, 2575 intptr_t token_pos,
2686 const AbstractTypeArguments& type_arguments, 2576 const AbstractTypeArguments& type_arguments,
2687 Value* instantiator) 2577 Value* instantiator)
2688 : token_pos_(token_pos), 2578 : token_pos_(token_pos),
2689 type_arguments_(type_arguments) { 2579 type_arguments_(type_arguments) {
2690 ASSERT(instantiator != NULL); 2580 ASSERT(instantiator != NULL);
2691 inputs_[0] = instantiator; 2581 inputs_[0] = instantiator;
2692 } 2582 }
2693 2583
2694 DECLARE_COMPUTATION(ExtractConstructorTypeArguments) 2584 DECLARE_INSTRUCTION(ExtractConstructorTypeArguments)
2585 virtual RawAbstractType* CompileType() const;
2695 2586
2696 Value* instantiator() const { return inputs_[0]; } 2587 Value* instantiator() const { return inputs_[0]; }
2697 const AbstractTypeArguments& type_arguments() const { 2588 const AbstractTypeArguments& type_arguments() const {
2698 return type_arguments_; 2589 return type_arguments_;
2699 } 2590 }
2700 intptr_t token_pos() const { return token_pos_; } 2591 intptr_t token_pos() const { return token_pos_; }
2701 2592
2702 virtual void PrintOperandsTo(BufferFormatter* f) const; 2593 virtual void PrintOperandsTo(BufferFormatter* f) const;
2703 2594
2704 virtual bool CanDeoptimize() const { return false; } 2595 virtual bool CanDeoptimize() const { return false; }
2705 virtual intptr_t ResultCid() const { return kDynamicCid; } 2596 virtual intptr_t ResultCid() const { return kDynamicCid; }
2706 2597
2707 private: 2598 private:
2708 const intptr_t token_pos_; 2599 const intptr_t token_pos_;
2709 const AbstractTypeArguments& type_arguments_; 2600 const AbstractTypeArguments& type_arguments_;
2710 2601
2711 DISALLOW_COPY_AND_ASSIGN(ExtractConstructorTypeArgumentsComp); 2602 DISALLOW_COPY_AND_ASSIGN(ExtractConstructorTypeArgumentsInstr);
2712 }; 2603 };
2713 2604
2714 2605
2715 class ExtractConstructorInstantiatorComp : public TemplateComputation<1> { 2606 class ExtractConstructorInstantiatorInstr : public TemplateDefinition<1> {
2716 public: 2607 public:
2717 ExtractConstructorInstantiatorComp(ConstructorCallNode* ast_node, 2608 ExtractConstructorInstantiatorInstr(ConstructorCallNode* ast_node,
2718 Value* instantiator) 2609 Value* instantiator)
2719 : ast_node_(*ast_node) { 2610 : ast_node_(*ast_node) {
2720 ASSERT(instantiator != NULL); 2611 ASSERT(instantiator != NULL);
2721 inputs_[0] = instantiator; 2612 inputs_[0] = instantiator;
2722 } 2613 }
2723 2614
2724 DECLARE_COMPUTATION(ExtractConstructorInstantiator) 2615 DECLARE_INSTRUCTION(ExtractConstructorInstantiator)
2616 virtual RawAbstractType* CompileType() const;
2725 2617
2726 Value* instantiator() const { return inputs_[0]; } 2618 Value* instantiator() const { return inputs_[0]; }
2727 const AbstractTypeArguments& type_arguments() const { 2619 const AbstractTypeArguments& type_arguments() const {
2728 return ast_node_.type_arguments(); 2620 return ast_node_.type_arguments();
2729 } 2621 }
2730 const Function& constructor() const { return ast_node_.constructor(); } 2622 const Function& constructor() const { return ast_node_.constructor(); }
2731 intptr_t token_pos() const { return ast_node_.token_pos(); } 2623 intptr_t token_pos() const { return ast_node_.token_pos(); }
2732 2624
2733 virtual bool CanDeoptimize() const { return false; } 2625 virtual bool CanDeoptimize() const { return false; }
2734 virtual intptr_t ResultCid() const { return kDynamicCid; } 2626 virtual intptr_t ResultCid() const { return kDynamicCid; }
2735 2627
2736 private: 2628 private:
2737 const ConstructorCallNode& ast_node_; 2629 const ConstructorCallNode& ast_node_;
2738 2630
2739 DISALLOW_COPY_AND_ASSIGN(ExtractConstructorInstantiatorComp); 2631 DISALLOW_COPY_AND_ASSIGN(ExtractConstructorInstantiatorInstr);
2740 }; 2632 };
2741 2633
2742 2634
2743 class AllocateContextComp : public TemplateComputation<0> { 2635 class AllocateContextInstr : public TemplateDefinition<0> {
2744 public: 2636 public:
2745 AllocateContextComp(intptr_t token_pos, 2637 AllocateContextInstr(intptr_t token_pos,
2746 intptr_t num_context_variables) 2638 intptr_t num_context_variables)
2747 : token_pos_(token_pos), 2639 : token_pos_(token_pos),
2748 num_context_variables_(num_context_variables) {} 2640 num_context_variables_(num_context_variables) {}
2749 2641
2750 DECLARE_COMPUTATION(AllocateContext); 2642 DECLARE_INSTRUCTION(AllocateContext);
2643 virtual RawAbstractType* CompileType() const;
2751 2644
2752 intptr_t token_pos() const { return token_pos_; } 2645 intptr_t token_pos() const { return token_pos_; }
2753 intptr_t num_context_variables() const { return num_context_variables_; } 2646 intptr_t num_context_variables() const { return num_context_variables_; }
2754 2647
2755 virtual void PrintOperandsTo(BufferFormatter* f) const; 2648 virtual void PrintOperandsTo(BufferFormatter* f) const;
2756 2649
2757 virtual bool CanDeoptimize() const { return false; } 2650 virtual bool CanDeoptimize() const { return false; }
2758 virtual intptr_t ResultCid() const { return kDynamicCid; } 2651 virtual intptr_t ResultCid() const { return kDynamicCid; }
2759 2652
2760 private: 2653 private:
2761 const intptr_t token_pos_; 2654 const intptr_t token_pos_;
2762 const intptr_t num_context_variables_; 2655 const intptr_t num_context_variables_;
2763 2656
2764 DISALLOW_COPY_AND_ASSIGN(AllocateContextComp); 2657 DISALLOW_COPY_AND_ASSIGN(AllocateContextInstr);
2765 }; 2658 };
2766 2659
2767 2660
2768 class ChainContextComp : public TemplateComputation<1> { 2661 class ChainContextInstr : public TemplateDefinition<1> {
2769 public: 2662 public:
2770 explicit ChainContextComp(Value* context_value) { 2663 explicit ChainContextInstr(Value* context_value) {
2771 ASSERT(context_value != NULL); 2664 ASSERT(context_value != NULL);
2772 inputs_[0] = context_value; 2665 inputs_[0] = context_value;
2773 } 2666 }
2774 2667
2775 DECLARE_COMPUTATION(ChainContext) 2668 DECLARE_INSTRUCTION(ChainContext)
2669 virtual RawAbstractType* CompileType() const;
2776 2670
2777 Value* context_value() const { return inputs_[0]; } 2671 Value* context_value() const { return inputs_[0]; }
2778 2672
2779 virtual bool CanDeoptimize() const { return false; } 2673 virtual bool CanDeoptimize() const { return false; }
2780 virtual intptr_t ResultCid() const { return kIllegalCid; } 2674 virtual intptr_t ResultCid() const { return kIllegalCid; }
2781 2675
2782 private: 2676 private:
2783 DISALLOW_COPY_AND_ASSIGN(ChainContextComp); 2677 DISALLOW_COPY_AND_ASSIGN(ChainContextInstr);
2784 }; 2678 };
2785 2679
2786 2680
2787 class CloneContextComp : public TemplateComputation<1> { 2681 class CloneContextInstr : public TemplateDefinition<1> {
2788 public: 2682 public:
2789 CloneContextComp(intptr_t token_pos, 2683 CloneContextInstr(intptr_t token_pos, Value* context_value)
2790 Value* context_value)
2791 : token_pos_(token_pos) { 2684 : token_pos_(token_pos) {
2792 ASSERT(context_value != NULL); 2685 ASSERT(context_value != NULL);
2793 inputs_[0] = context_value; 2686 inputs_[0] = context_value;
2794 } 2687 }
2795 2688
2796 intptr_t token_pos() const { return token_pos_; } 2689 intptr_t token_pos() const { return token_pos_; }
2797 Value* context_value() const { return inputs_[0]; } 2690 Value* context_value() const { return inputs_[0]; }
2798 2691
2799 DECLARE_COMPUTATION(CloneContext) 2692 DECLARE_INSTRUCTION(CloneContext)
2693 virtual RawAbstractType* CompileType() const;
2800 2694
2801 virtual bool CanDeoptimize() const { return false; } 2695 virtual bool CanDeoptimize() const { return false; }
2802 virtual intptr_t ResultCid() const { return kIllegalCid; } 2696 virtual intptr_t ResultCid() const { return kIllegalCid; }
2803 2697
2804 private: 2698 private:
2805 const intptr_t token_pos_; 2699 const intptr_t token_pos_;
2806 2700
2807 DISALLOW_COPY_AND_ASSIGN(CloneContextComp); 2701 DISALLOW_COPY_AND_ASSIGN(CloneContextInstr);
2808 }; 2702 };
2809 2703
2810 2704
2811 class CatchEntryComp : public TemplateComputation<0> { 2705 class CatchEntryInstr : public TemplateDefinition<0> {
2812 public: 2706 public:
2813 CatchEntryComp(const LocalVariable& exception_var, 2707 CatchEntryInstr(const LocalVariable& exception_var,
2814 const LocalVariable& stacktrace_var) 2708 const LocalVariable& stacktrace_var)
2815 : exception_var_(exception_var), stacktrace_var_(stacktrace_var) {} 2709 : exception_var_(exception_var), stacktrace_var_(stacktrace_var) {}
2816 2710
2817 const LocalVariable& exception_var() const { return exception_var_; } 2711 const LocalVariable& exception_var() const { return exception_var_; }
2818 const LocalVariable& stacktrace_var() const { return stacktrace_var_; } 2712 const LocalVariable& stacktrace_var() const { return stacktrace_var_; }
2819 2713
2820 DECLARE_COMPUTATION(CatchEntry) 2714 DECLARE_INSTRUCTION(CatchEntry)
2715 virtual RawAbstractType* CompileType() const;
2821 2716
2822 virtual void PrintOperandsTo(BufferFormatter* f) const; 2717 virtual void PrintOperandsTo(BufferFormatter* f) const;
2823 2718
2824 virtual bool CanDeoptimize() const { return false; } 2719 virtual bool CanDeoptimize() const { return false; }
2825 virtual intptr_t ResultCid() const { return kIllegalCid; } 2720 virtual intptr_t ResultCid() const { return kIllegalCid; }
2826 2721
2827 private: 2722 private:
2828 const LocalVariable& exception_var_; 2723 const LocalVariable& exception_var_;
2829 const LocalVariable& stacktrace_var_; 2724 const LocalVariable& stacktrace_var_;
2830 2725
2831 DISALLOW_COPY_AND_ASSIGN(CatchEntryComp); 2726 DISALLOW_COPY_AND_ASSIGN(CatchEntryInstr);
2832 }; 2727 };
2833 2728
2834 2729
2835 class CheckEitherNonSmiComp : public TemplateComputation<2> { 2730 class CheckEitherNonSmiInstr : public TemplateDefinition<2> {
2836 public: 2731 public:
2837 CheckEitherNonSmiComp(Value* left, 2732 CheckEitherNonSmiInstr(Value* left,
2838 Value* right, 2733 Value* right,
2839 InstanceCallComp* instance_call) 2734 InstanceCallInstr* instance_call) {
2840 : instance_call_(instance_call) {
2841 ASSERT(left != NULL); 2735 ASSERT(left != NULL);
2842 ASSERT(right != NULL); 2736 ASSERT(right != NULL);
2843 inputs_[0] = left; 2737 inputs_[0] = left;
2844 inputs_[1] = right; 2738 inputs_[1] = right;
2739 deopt_id_ = instance_call->deopt_id();
2845 } 2740 }
2846 2741
2847 DECLARE_COMPUTATION(CheckEitherNonSmi) 2742 DECLARE_INSTRUCTION(CheckEitherNonSmi)
2743 virtual RawAbstractType* CompileType() const;
2848 2744
2849 virtual bool CanDeoptimize() const { return true; } 2745 virtual bool CanDeoptimize() const { return true; }
2850 virtual intptr_t ResultCid() const { return kIllegalCid; } 2746 virtual intptr_t ResultCid() const { return kIllegalCid; }
2851 2747
2852 virtual bool AttributesEqual(Computation* other) const { return true; } 2748 virtual bool AttributesEqual(Definition* other) const { return true; }
2853 2749
2854 virtual bool HasSideEffect() const { return false; } 2750 virtual bool HasSideEffect() const { return false; }
2855 2751
2856 Value* left() const { return inputs_[0]; } 2752 Value* left() const { return inputs_[0]; }
2857 2753
2858 Value* right() const { return inputs_[1]; } 2754 Value* right() const { return inputs_[1]; }
2859 2755
2860 virtual Definition* TryReplace(BindInstr* instr) const; 2756 virtual Definition* Canonicalize();
2861 2757
2862 private: 2758 private:
2863 InstanceCallComp* instance_call_; 2759 DISALLOW_COPY_AND_ASSIGN(CheckEitherNonSmiInstr);
2864
2865 DISALLOW_COPY_AND_ASSIGN(CheckEitherNonSmiComp);
2866 }; 2760 };
2867 2761
2868 2762
2869 class BoxDoubleComp : public TemplateComputation<1> { 2763 class BoxDoubleInstr : public TemplateDefinition<1> {
2870 public: 2764 public:
2871 BoxDoubleComp(Value* value, InstanceCallComp* instance_call) 2765 BoxDoubleInstr(Value* value, InstanceCallInstr* instance_call)
2872 : token_pos_((instance_call != NULL) ? instance_call->token_pos() : 0) { 2766 : token_pos_((instance_call != NULL) ? instance_call->token_pos() : 0) {
2873 ASSERT(value != NULL); 2767 ASSERT(value != NULL);
2874 inputs_[0] = value; 2768 inputs_[0] = value;
2875 } 2769 }
2876 2770
2877 Value* value() const { return inputs_[0]; } 2771 Value* value() const { return inputs_[0]; }
2878 2772
2879 intptr_t token_pos() const { return token_pos_; } 2773 intptr_t token_pos() const { return token_pos_; }
2880 2774
2881 virtual bool CanDeoptimize() const { return false; } 2775 virtual bool CanDeoptimize() const { return false; }
2882 virtual bool HasSideEffect() const { return false; } 2776 virtual bool HasSideEffect() const { return false; }
2883 virtual bool AttributesEqual(Computation* other) const { return true; } 2777 virtual bool AttributesEqual(Definition* other) const { return true; }
2884 2778
2885 virtual intptr_t ResultCid() const; 2779 virtual intptr_t ResultCid() const;
2886 2780
2887 virtual Representation RequiredInputRepresentation(intptr_t idx) const { 2781 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
2888 ASSERT(idx == 0); 2782 ASSERT(idx == 0);
2889 return kUnboxedDouble; 2783 return kUnboxedDouble;
2890 } 2784 }
2891 2785
2892 DECLARE_COMPUTATION(BoxDouble) 2786 DECLARE_INSTRUCTION(BoxDouble)
2787 virtual RawAbstractType* CompileType() const;
2893 2788
2894 private: 2789 private:
2895 const intptr_t token_pos_; 2790 const intptr_t token_pos_;
2896 2791
2897 DISALLOW_COPY_AND_ASSIGN(BoxDoubleComp); 2792 DISALLOW_COPY_AND_ASSIGN(BoxDoubleInstr);
2898 }; 2793 };
2899 2794
2900 2795
2901 class UnboxDoubleComp : public TemplateComputation<1> { 2796 class UnboxDoubleInstr : public TemplateDefinition<1> {
2902 public: 2797 public:
2903 UnboxDoubleComp(Value* value, intptr_t deopt_id) 2798 UnboxDoubleInstr(Value* value, intptr_t deopt_id) {
2904 : deopt_id_(deopt_id) {
2905 ASSERT(value != NULL); 2799 ASSERT(value != NULL);
2906 inputs_[0] = value; 2800 inputs_[0] = value;
2801 deopt_id_ = deopt_id;
2907 } 2802 }
2908 2803
2909 Value* value() const { return inputs_[0]; } 2804 Value* value() const { return inputs_[0]; }
2910 2805
2911 virtual bool CanDeoptimize() const { 2806 virtual bool CanDeoptimize() const {
2912 return value()->ResultCid() != kDoubleCid; 2807 return value()->ResultCid() != kDoubleCid;
2913 } 2808 }
2914 2809
2915 // The output is not an instance but when it is boxed it becomes double. 2810 // The output is not an instance but when it is boxed it becomes double.
2916 virtual intptr_t ResultCid() const { return kDoubleCid; } 2811 virtual intptr_t ResultCid() const { return kDoubleCid; }
2917 2812
2918 virtual Representation representation() const { 2813 virtual Representation representation() const {
2919 return kUnboxedDouble; 2814 return kUnboxedDouble;
2920 } 2815 }
2921 2816
2922 virtual bool HasSideEffect() const { return false; } 2817 virtual bool HasSideEffect() const { return false; }
2923 virtual bool AttributesEqual(Computation* other) const { return true; } 2818 virtual bool AttributesEqual(Definition* other) const { return true; }
2924 2819
2925 DECLARE_COMPUTATION(UnboxDouble) 2820 DECLARE_INSTRUCTION(UnboxDouble)
2821 virtual RawAbstractType* CompileType() const;
2926 2822
2927 private: 2823 private:
2928 const intptr_t deopt_id_; 2824 DISALLOW_COPY_AND_ASSIGN(UnboxDoubleInstr);
2929
2930 DISALLOW_COPY_AND_ASSIGN(UnboxDoubleComp);
2931 }; 2825 };
2932 2826
2933 2827
2934 class UnboxedDoubleBinaryOpComp : public TemplateComputation<2> { 2828 class UnboxedDoubleBinaryOpInstr : public TemplateDefinition<2> {
2935 public: 2829 public:
2936 UnboxedDoubleBinaryOpComp(Token::Kind op_kind, 2830 UnboxedDoubleBinaryOpInstr(Token::Kind op_kind,
2937 Value* left, 2831 Value* left,
2938 Value* right, 2832 Value* right,
2939 InstanceCallComp* call) 2833 InstanceCallInstr* instance_call)
2940 : op_kind_(op_kind), deopt_id_(call->deopt_id()) { 2834 : op_kind_(op_kind) {
2941 ASSERT(left != NULL); 2835 ASSERT(left != NULL);
2942 ASSERT(right != NULL); 2836 ASSERT(right != NULL);
2943 inputs_[0] = left; 2837 inputs_[0] = left;
2944 inputs_[1] = right; 2838 inputs_[1] = right;
2839 deopt_id_ = instance_call->deopt_id();
2945 } 2840 }
2946 2841
2947 Value* left() const { return inputs_[0]; } 2842 Value* left() const { return inputs_[0]; }
2948 Value* right() const { return inputs_[1]; } 2843 Value* right() const { return inputs_[1]; }
2949 2844
2950 Token::Kind op_kind() const { return op_kind_; } 2845 Token::Kind op_kind() const { return op_kind_; }
2951 2846
2952 virtual void PrintOperandsTo(BufferFormatter* f) const; 2847 virtual void PrintOperandsTo(BufferFormatter* f) const;
2953 2848
2954 virtual bool CanDeoptimize() const { return false; } 2849 virtual bool CanDeoptimize() const { return false; }
2955 virtual bool HasSideEffect() const { return false; } 2850 virtual bool HasSideEffect() const { return false; }
2956 2851
2957 virtual bool AttributesEqual(Computation* other) const { 2852 virtual bool AttributesEqual(Definition* other) const {
2958 return op_kind() == other->AsUnboxedDoubleBinaryOp()->op_kind(); 2853 return op_kind() == other->AsUnboxedDoubleBinaryOp()->op_kind();
2959 } 2854 }
2960 2855
2961 // The output is not an instance but when it is boxed it becomes double. 2856 // The output is not an instance but when it is boxed it becomes double.
2962 virtual intptr_t ResultCid() const { return kDoubleCid; } 2857 virtual intptr_t ResultCid() const { return kDoubleCid; }
2963 2858
2964 virtual Representation representation() const { 2859 virtual Representation representation() const {
2965 return kUnboxedDouble; 2860 return kUnboxedDouble;
2966 } 2861 }
2967 2862
2968 virtual Representation RequiredInputRepresentation(intptr_t idx) const { 2863 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
2969 ASSERT((idx == 0) || (idx == 1)); 2864 ASSERT((idx == 0) || (idx == 1));
2970 return kUnboxedDouble; 2865 return kUnboxedDouble;
2971 } 2866 }
2972 2867
2973 virtual intptr_t DeoptimizationTarget() const { 2868 virtual intptr_t DeoptimizationTarget() const {
2974 return deopt_id_; 2869 return deopt_id();
2975 } 2870 }
2976 2871
2977 DECLARE_COMPUTATION(UnboxedDoubleBinaryOp) 2872 DECLARE_INSTRUCTION(UnboxedDoubleBinaryOp)
2873 virtual RawAbstractType* CompileType() const;
2978 2874
2979 private: 2875 private:
2980 const Token::Kind op_kind_; 2876 const Token::Kind op_kind_;
2981 const intptr_t deopt_id_;
2982 2877
2983 DISALLOW_COPY_AND_ASSIGN(UnboxedDoubleBinaryOpComp); 2878 DISALLOW_COPY_AND_ASSIGN(UnboxedDoubleBinaryOpInstr);
2984 }; 2879 };
2985 2880
2986 2881
2987 class BinarySmiOpComp : public TemplateComputation<2> { 2882 class BinarySmiOpInstr : public TemplateDefinition<2> {
2988 public: 2883 public:
2989 BinarySmiOpComp(Token::Kind op_kind, 2884 BinarySmiOpInstr(Token::Kind op_kind,
2990 InstanceCallComp* instance_call, 2885 InstanceCallInstr* instance_call,
2991 Value* left, 2886 Value* left,
2992 Value* right) 2887 Value* right)
2993 : op_kind_(op_kind), 2888 : op_kind_(op_kind),
2994 instance_call_(instance_call) { 2889 instance_call_(instance_call) {
2995 ASSERT(left != NULL); 2890 ASSERT(left != NULL);
2996 ASSERT(right != NULL); 2891 ASSERT(right != NULL);
2997 inputs_[0] = left; 2892 inputs_[0] = left;
2998 inputs_[1] = right; 2893 inputs_[1] = right;
2999 } 2894 }
3000 2895
3001 Value* left() const { return inputs_[0]; } 2896 Value* left() const { return inputs_[0]; }
3002 Value* right() const { return inputs_[1]; } 2897 Value* right() const { return inputs_[1]; }
3003 2898
3004 Token::Kind op_kind() const { return op_kind_; } 2899 Token::Kind op_kind() const { return op_kind_; }
3005 2900
3006 InstanceCallComp* instance_call() const { return instance_call_; } 2901 InstanceCallInstr* instance_call() const { return instance_call_; }
3007 2902
3008 const ICData* ic_data() const { return instance_call()->ic_data(); } 2903 const ICData* ic_data() const { return instance_call()->ic_data(); }
3009 2904
3010 virtual void PrintOperandsTo(BufferFormatter* f) const; 2905 virtual void PrintOperandsTo(BufferFormatter* f) const;
3011 2906
3012 DECLARE_COMPUTATION(BinarySmiOp) 2907 DECLARE_INSTRUCTION(BinarySmiOp)
2908 virtual RawAbstractType* CompileType() const;
3013 2909
3014 virtual bool CanDeoptimize() const; 2910 virtual bool CanDeoptimize() const;
3015 2911
3016 virtual intptr_t ResultCid() const; 2912 virtual intptr_t ResultCid() const;
3017 2913
3018 private: 2914 private:
3019 const Token::Kind op_kind_; 2915 const Token::Kind op_kind_;
3020 InstanceCallComp* instance_call_; 2916 InstanceCallInstr* instance_call_;
3021 2917
3022 DISALLOW_COPY_AND_ASSIGN(BinarySmiOpComp); 2918 DISALLOW_COPY_AND_ASSIGN(BinarySmiOpInstr);
3023 }; 2919 };
3024 2920
3025 2921
3026 class BinaryMintOpComp : public TemplateComputation<2> { 2922 class BinaryMintOpInstr : public TemplateDefinition<2> {
3027 public: 2923 public:
3028 BinaryMintOpComp(Token::Kind op_kind, 2924 BinaryMintOpInstr(Token::Kind op_kind,
3029 InstanceCallComp* instance_call, 2925 InstanceCallInstr* instance_call,
3030 Value* left, 2926 Value* left,
3031 Value* right) 2927 Value* right)
3032 : op_kind_(op_kind), 2928 : op_kind_(op_kind),
3033 instance_call_(instance_call) { 2929 instance_call_(instance_call) {
3034 ASSERT(left != NULL); 2930 ASSERT(left != NULL);
3035 ASSERT(right != NULL); 2931 ASSERT(right != NULL);
3036 inputs_[0] = left; 2932 inputs_[0] = left;
3037 inputs_[1] = right; 2933 inputs_[1] = right;
3038 } 2934 }
3039 2935
3040 Value* left() const { return inputs_[0]; } 2936 Value* left() const { return inputs_[0]; }
3041 Value* right() const { return inputs_[1]; } 2937 Value* right() const { return inputs_[1]; }
3042 2938
3043 Token::Kind op_kind() const { return op_kind_; } 2939 Token::Kind op_kind() const { return op_kind_; }
3044 2940
3045 InstanceCallComp* instance_call() const { return instance_call_; } 2941 InstanceCallInstr* instance_call() const { return instance_call_; }
3046 2942
3047 const ICData* ic_data() const { return instance_call()->ic_data(); } 2943 const ICData* ic_data() const { return instance_call()->ic_data(); }
3048 2944
3049 virtual void PrintOperandsTo(BufferFormatter* f) const; 2945 virtual void PrintOperandsTo(BufferFormatter* f) const;
3050 2946
3051 DECLARE_COMPUTATION(BinaryMintOp) 2947 DECLARE_INSTRUCTION(BinaryMintOp)
2948 virtual RawAbstractType* CompileType() const;
3052 2949
3053 virtual bool CanDeoptimize() const { return true; } 2950 virtual bool CanDeoptimize() const { return true; }
3054 virtual intptr_t ResultCid() const; 2951 virtual intptr_t ResultCid() const;
3055 2952
3056 private: 2953 private:
3057 const Token::Kind op_kind_; 2954 const Token::Kind op_kind_;
3058 InstanceCallComp* instance_call_; 2955 InstanceCallInstr* instance_call_;
3059 2956
3060 DISALLOW_COPY_AND_ASSIGN(BinaryMintOpComp); 2957 DISALLOW_COPY_AND_ASSIGN(BinaryMintOpInstr);
3061 }; 2958 };
3062 2959
3063 2960
3064 // Handles both Smi operations: BIT_OR and NEGATE. 2961 // Handles both Smi operations: BIT_OR and NEGATE.
3065 class UnarySmiOpComp : public TemplateComputation<1> { 2962 class UnarySmiOpInstr : public TemplateDefinition<1> {
3066 public: 2963 public:
3067 UnarySmiOpComp(Token::Kind op_kind, 2964 UnarySmiOpInstr(Token::Kind op_kind,
3068 InstanceCallComp* instance_call, 2965 InstanceCallInstr* instance_call,
3069 Value* value) 2966 Value* value)
3070 : op_kind_(op_kind), instance_call_(instance_call) { 2967 : op_kind_(op_kind), instance_call_(instance_call) {
3071 ASSERT((op_kind == Token::kNEGATE) || (op_kind == Token::kBIT_NOT)); 2968 ASSERT((op_kind == Token::kNEGATE) || (op_kind == Token::kBIT_NOT));
3072 ASSERT(value != NULL); 2969 ASSERT(value != NULL);
3073 inputs_[0] = value; 2970 inputs_[0] = value;
3074 } 2971 }
3075 2972
3076 Value* value() const { return inputs_[0]; } 2973 Value* value() const { return inputs_[0]; }
3077 Token::Kind op_kind() const { return op_kind_; } 2974 Token::Kind op_kind() const { return op_kind_; }
3078 2975
3079 InstanceCallComp* instance_call() const { return instance_call_; } 2976 InstanceCallInstr* instance_call() const { return instance_call_; }
3080 2977
3081 virtual void PrintOperandsTo(BufferFormatter* f) const; 2978 virtual void PrintOperandsTo(BufferFormatter* f) const;
3082 2979
3083 DECLARE_COMPUTATION(UnarySmiOp) 2980 DECLARE_INSTRUCTION(UnarySmiOp)
2981 virtual RawAbstractType* CompileType() const;
3084 2982
3085 virtual bool CanDeoptimize() const { return op_kind() == Token::kNEGATE; } 2983 virtual bool CanDeoptimize() const { return op_kind() == Token::kNEGATE; }
3086 virtual intptr_t ResultCid() const { return kSmiCid; } 2984 virtual intptr_t ResultCid() const { return kSmiCid; }
3087 2985
3088 private: 2986 private:
3089 const Token::Kind op_kind_; 2987 const Token::Kind op_kind_;
3090 InstanceCallComp* instance_call_; 2988 InstanceCallInstr* instance_call_;
3091 2989
3092 DISALLOW_COPY_AND_ASSIGN(UnarySmiOpComp); 2990 DISALLOW_COPY_AND_ASSIGN(UnarySmiOpInstr);
3093 }; 2991 };
3094 2992
3095 2993
3096 // Handles non-Smi NEGATE operations 2994 // Handles non-Smi NEGATE operations
3097 class NumberNegateComp : public TemplateComputation<1> { 2995 class NumberNegateInstr : public TemplateDefinition<1> {
3098 public: 2996 public:
3099 NumberNegateComp(InstanceCallComp* instance_call, 2997 NumberNegateInstr(InstanceCallInstr* instance_call, Value* value)
3100 Value* value) : instance_call_(instance_call) { 2998 : instance_call_(instance_call) {
3101 ASSERT(value != NULL); 2999 ASSERT(value != NULL);
3102 inputs_[0] = value; 3000 inputs_[0] = value;
3103 } 3001 }
3104 3002
3105 Value* value() const { return inputs_[0]; } 3003 Value* value() const { return inputs_[0]; }
3106 3004
3107 InstanceCallComp* instance_call() const { return instance_call_; } 3005 InstanceCallInstr* instance_call() const { return instance_call_; }
3108 3006
3109 const ICData* ic_data() const { return instance_call()->ic_data(); } 3007 const ICData* ic_data() const { return instance_call()->ic_data(); }
3110 3008
3111 DECLARE_COMPUTATION(NumberNegate) 3009 DECLARE_INSTRUCTION(NumberNegate)
3010 virtual RawAbstractType* CompileType() const;
3112 3011
3113 virtual bool CanDeoptimize() const { return true; } 3012 virtual bool CanDeoptimize() const { return true; }
3114 virtual intptr_t ResultCid() const { return kDoubleCid; } 3013 virtual intptr_t ResultCid() const { return kDoubleCid; }
3115 3014
3116 private: 3015 private:
3117 InstanceCallComp* instance_call_; 3016 InstanceCallInstr* instance_call_;
3118 3017
3119 DISALLOW_COPY_AND_ASSIGN(NumberNegateComp); 3018 DISALLOW_COPY_AND_ASSIGN(NumberNegateInstr);
3120 }; 3019 };
3121 3020
3122 3021
3123 class CheckStackOverflowComp : public TemplateComputation<0> { 3022 class CheckStackOverflowInstr : public TemplateDefinition<0> {
3124 public: 3023 public:
3125 explicit CheckStackOverflowComp(intptr_t token_pos) 3024 explicit CheckStackOverflowInstr(intptr_t token_pos)
3126 : token_pos_(token_pos) {} 3025 : token_pos_(token_pos) {}
3127 3026
3128 intptr_t token_pos() const { return token_pos_; } 3027 intptr_t token_pos() const { return token_pos_; }
3129 3028
3130 DECLARE_COMPUTATION(CheckStackOverflow) 3029 DECLARE_INSTRUCTION(CheckStackOverflow)
3030 virtual RawAbstractType* CompileType() const;
3131 3031
3132 virtual bool CanDeoptimize() const { return false; } 3032 virtual bool CanDeoptimize() const { return false; }
3133 virtual intptr_t ResultCid() const { return kIllegalCid; } 3033 virtual intptr_t ResultCid() const { return kIllegalCid; }
3134 3034
3135 private: 3035 private:
3136 const intptr_t token_pos_; 3036 const intptr_t token_pos_;
3137 3037
3138 DISALLOW_COPY_AND_ASSIGN(CheckStackOverflowComp); 3038 DISALLOW_COPY_AND_ASSIGN(CheckStackOverflowInstr);
3139 }; 3039 };
3140 3040
3141 3041
3142 class DoubleToDoubleComp : public TemplateComputation<1> { 3042 class DoubleToDoubleInstr : public TemplateDefinition<1> {
3143 public: 3043 public:
3144 DoubleToDoubleComp(Value* value, InstanceCallComp* instance_call) 3044 DoubleToDoubleInstr(Value* value, InstanceCallInstr* instance_call)
3145 : instance_call_(instance_call) { 3045 : instance_call_(instance_call) {
3146 ASSERT(value != NULL); 3046 ASSERT(value != NULL);
3147 inputs_[0] = value; 3047 inputs_[0] = value;
3148 } 3048 }
3149 3049
3150 Value* value() const { return inputs_[0]; } 3050 Value* value() const { return inputs_[0]; }
3151 3051
3152 InstanceCallComp* instance_call() const { return instance_call_; } 3052 InstanceCallInstr* instance_call() const { return instance_call_; }
3153 3053
3154 DECLARE_COMPUTATION(DoubleToDouble) 3054 DECLARE_INSTRUCTION(DoubleToDouble)
3055 virtual RawAbstractType* CompileType() const;
3155 3056
3156 virtual bool CanDeoptimize() const { return true; } 3057 virtual bool CanDeoptimize() const { return true; }
3157 virtual intptr_t ResultCid() const { return kDoubleCid; } 3058 virtual intptr_t ResultCid() const { return kDoubleCid; }
3158 3059
3159 private: 3060 private:
3160 InstanceCallComp* instance_call_; 3061 InstanceCallInstr* instance_call_;
3161 3062
3162 DISALLOW_COPY_AND_ASSIGN(DoubleToDoubleComp); 3063 DISALLOW_COPY_AND_ASSIGN(DoubleToDoubleInstr);
3163 }; 3064 };
3164 3065
3165 3066
3166 class SmiToDoubleComp : public TemplateComputation<0> { 3067 class SmiToDoubleInstr : public TemplateDefinition<0> {
3167 public: 3068 public:
3168 explicit SmiToDoubleComp(InstanceCallComp* instance_call) 3069 explicit SmiToDoubleInstr(InstanceCallInstr* instance_call)
3169 : instance_call_(instance_call) { } 3070 : instance_call_(instance_call) { }
3170 3071
3171 InstanceCallComp* instance_call() const { return instance_call_; } 3072 InstanceCallInstr* instance_call() const { return instance_call_; }
3172 3073
3173 DECLARE_CALL_COMPUTATION(SmiToDouble) 3074 DECLARE_INSTRUCTION(SmiToDouble)
3075 virtual RawAbstractType* CompileType() const;
3174 3076
3175 virtual intptr_t ArgumentCount() const { return 1; } 3077 virtual intptr_t ArgumentCount() const { return 1; }
3176 3078
3177 virtual bool CanDeoptimize() const { return true; } 3079 virtual bool CanDeoptimize() const { return true; }
3178 virtual intptr_t ResultCid() const { return kDoubleCid; } 3080 virtual intptr_t ResultCid() const { return kDoubleCid; }
3179 3081
3180 private: 3082 private:
3181 InstanceCallComp* instance_call_; 3083 InstanceCallInstr* instance_call_;
3182 3084
3183 DISALLOW_COPY_AND_ASSIGN(SmiToDoubleComp); 3085 DISALLOW_COPY_AND_ASSIGN(SmiToDoubleInstr);
3184 }; 3086 };
3185 3087
3186 3088
3187 class CheckClassComp : public TemplateComputation<1> { 3089 class CheckClassInstr : public TemplateDefinition<1> {
3188 public: 3090 public:
3189 CheckClassComp(Value* value, 3091 CheckClassInstr(Value* value,
3190 InstanceCallComp* instance_call, 3092 InstanceCallInstr* instance_call,
3191 const ICData& unary_checks) 3093 const ICData& unary_checks)
3192 : instance_call_(instance_call), 3094 : unary_checks_(unary_checks) {
3193 unary_checks_(unary_checks) {
3194 ASSERT(value != NULL); 3095 ASSERT(value != NULL);
3195 inputs_[0] = value; 3096 inputs_[0] = value;
3097 deopt_id_ = instance_call->deopt_id();
3196 } 3098 }
3197 3099
3198 DECLARE_COMPUTATION(CheckClass) 3100 DECLARE_INSTRUCTION(CheckClass)
3101 virtual RawAbstractType* CompileType() const;
3199 3102
3200 virtual bool CanDeoptimize() const { return true; } 3103 virtual bool CanDeoptimize() const { return true; }
3201 virtual intptr_t ResultCid() const { return kIllegalCid; } 3104 virtual intptr_t ResultCid() const { return kIllegalCid; }
3202 3105
3203 virtual bool AttributesEqual(Computation* other) const; 3106 virtual bool AttributesEqual(Definition* other) const;
3204 3107
3205 virtual bool HasSideEffect() const { return false; } 3108 virtual bool HasSideEffect() const { return false; }
3206 3109
3207 Value* value() const { return inputs_[0]; } 3110 Value* value() const { return inputs_[0]; }
3208 3111
3209 const ICData& unary_checks() const { return unary_checks_; } 3112 const ICData& unary_checks() const { return unary_checks_; }
3210 3113
3211 virtual intptr_t deopt_id() const { return instance_call_->deopt_id(); } 3114 virtual Definition* Canonicalize();
3212
3213 virtual Definition* TryReplace(BindInstr* instr) const;
3214 3115
3215 virtual void PrintOperandsTo(BufferFormatter* f) const; 3116 virtual void PrintOperandsTo(BufferFormatter* f) const;
3216 3117
3217 private: 3118 private:
3218 InstanceCallComp* instance_call_;
3219 const ICData& unary_checks_; 3119 const ICData& unary_checks_;
3220 3120
3221 DISALLOW_COPY_AND_ASSIGN(CheckClassComp); 3121 DISALLOW_COPY_AND_ASSIGN(CheckClassInstr);
3222 }; 3122 };
3223 3123
3224 3124
3225 class CheckSmiComp : public TemplateComputation<1> { 3125 class CheckSmiInstr : public TemplateDefinition<1> {
3226 public: 3126 public:
3227 CheckSmiComp(Value* value, intptr_t original_deopt_id) 3127 CheckSmiInstr(Value* value, intptr_t original_deopt_id) {
3228 : original_deopt_id_(original_deopt_id) {
3229 ASSERT(value != NULL); 3128 ASSERT(value != NULL);
3230 ASSERT(original_deopt_id != Isolate::kNoDeoptId); 3129 ASSERT(original_deopt_id != Isolate::kNoDeoptId);
3231 inputs_[0] = value; 3130 inputs_[0] = value;
3131 deopt_id_ = original_deopt_id;
3232 } 3132 }
3233 3133
3234 DECLARE_COMPUTATION(CheckSmi) 3134 DECLARE_INSTRUCTION(CheckSmi)
3135 virtual RawAbstractType* CompileType() const;
3235 3136
3236 virtual bool CanDeoptimize() const { return true; } 3137 virtual bool CanDeoptimize() const { return true; }
3237 virtual intptr_t ResultCid() const { return kIllegalCid; } 3138 virtual intptr_t ResultCid() const { return kIllegalCid; }
3238 3139
3239 virtual bool AttributesEqual(Computation* other) const { return true; } 3140 virtual bool AttributesEqual(Definition* other) const { return true; }
3240 3141
3241 virtual bool HasSideEffect() const { return false; } 3142 virtual bool HasSideEffect() const { return false; }
3242 3143
3243 virtual Definition* TryReplace(BindInstr* instr) const; 3144 virtual Definition* Canonicalize();
3244 3145
3245 Value* value() const { return inputs_[0]; } 3146 Value* value() const { return inputs_[0]; }
3246 3147
3247 virtual intptr_t deopt_id() const { return original_deopt_id_; }
3248
3249 private: 3148 private:
3250 const intptr_t original_deopt_id_; 3149 DISALLOW_COPY_AND_ASSIGN(CheckSmiInstr);
3251
3252 DISALLOW_COPY_AND_ASSIGN(CheckSmiComp);
3253 }; 3150 };
3254 3151
3255 3152
3256 class CheckArrayBoundComp : public TemplateComputation<2> { 3153 class CheckArrayBoundInstr : public TemplateDefinition<2> {
3257 public: 3154 public:
3258 CheckArrayBoundComp(Value* array, 3155 CheckArrayBoundInstr(Value* array,
3259 Value* index, 3156 Value* index,
3260 intptr_t array_type, 3157 intptr_t array_type,
3261 InstanceCallComp* instance_call) 3158 InstanceCallInstr* instance_call)
3262 : array_type_(array_type), instance_call_(instance_call) { 3159 : array_type_(array_type) {
3263 ASSERT(array != NULL); 3160 ASSERT(array != NULL);
3264 ASSERT(index != NULL); 3161 ASSERT(index != NULL);
3265 inputs_[0] = array; 3162 inputs_[0] = array;
3266 inputs_[1] = index; 3163 inputs_[1] = index;
3164 deopt_id_ = instance_call->deopt_id();
3267 } 3165 }
3268 3166
3269 DECLARE_COMPUTATION(CheckArrayBound) 3167 DECLARE_INSTRUCTION(CheckArrayBound)
3168 virtual RawAbstractType* CompileType() const;
3270 3169
3271 virtual bool CanDeoptimize() const { return true; } 3170 virtual bool CanDeoptimize() const { return true; }
3272 virtual intptr_t ResultCid() const { return kIllegalCid; } 3171 virtual intptr_t ResultCid() const { return kIllegalCid; }
3273 3172
3274 virtual bool AttributesEqual(Computation* other) const; 3173 virtual bool AttributesEqual(Definition* other) const;
3275 3174
3276 virtual bool HasSideEffect() const { return false; } 3175 virtual bool HasSideEffect() const { return false; }
3277 3176
3278 Value* array() const { return inputs_[0]; } 3177 Value* array() const { return inputs_[0]; }
3279 Value* index() const { return inputs_[1]; } 3178 Value* index() const { return inputs_[1]; }
3280 3179
3281 intptr_t array_type() const { return array_type_; } 3180 intptr_t array_type() const { return array_type_; }
3282 3181
3283 virtual intptr_t deopt_id() const { return instance_call_->deopt_id(); }
3284
3285 private: 3182 private:
3286 intptr_t array_type_; 3183 intptr_t array_type_;
3287 InstanceCallComp* instance_call_;
3288 3184
3289 DISALLOW_COPY_AND_ASSIGN(CheckArrayBoundComp); 3185 DISALLOW_COPY_AND_ASSIGN(CheckArrayBoundInstr);
3290 }; 3186 };
3291 3187
3292 3188
3293 #undef DECLARE_COMPUTATION 3189 #undef DECLARE_INSTRUCTION
3294
3295
3296 // Implementation of type testers and cast functins.
3297 #define DEFINE_COMPUTATION_PREDICATE(ShortName, ClassName) \
3298 bool Computation::Is##ShortName() const { \
3299 return computation_kind() == k##ShortName; \
3300 } \
3301 const ClassName* Computation::As##ShortName() const { \
3302 if (!Is##ShortName()) return NULL; \
3303 return static_cast<const ClassName*>(this); \
3304 } \
3305 ClassName* Computation::As##ShortName() { \
3306 if (!Is##ShortName()) return NULL; \
3307 return static_cast<ClassName*>(this); \
3308 }
3309 FOR_EACH_COMPUTATION(DEFINE_COMPUTATION_PREDICATE)
3310 #undef DEFINE_COMPUTATION_PREDICATE
3311 3190
3312 3191
3313 class Environment : public ZoneAllocated { 3192 class Environment : public ZoneAllocated {
3314 public: 3193 public:
3315 // Construct an environment by constructing uses from an array of definitions. 3194 // Construct an environment by constructing uses from an array of definitions.
3316 Environment(const GrowableArray<Definition*>& definitions, 3195 Environment(const GrowableArray<Definition*>& definitions,
3317 intptr_t fixed_parameter_count); 3196 intptr_t fixed_parameter_count);
3318 3197
3319 void set_locations(Location* locations) { 3198 void set_locations(Location* locations) {
3320 ASSERT(locations_ == NULL); 3199 ASSERT(locations_ == NULL);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
3370 virtual ~FlowGraphVisitor() { } 3249 virtual ~FlowGraphVisitor() { }
3371 3250
3372 ForwardInstructionIterator* current_iterator() const { 3251 ForwardInstructionIterator* current_iterator() const {
3373 return current_iterator_; 3252 return current_iterator_;
3374 } 3253 }
3375 3254
3376 // Visit each block in the block order, and for each block its 3255 // Visit each block in the block order, and for each block its
3377 // instructions in order from the block entry to exit. 3256 // instructions in order from the block entry to exit.
3378 virtual void VisitBlocks(); 3257 virtual void VisitBlocks();
3379 3258
3380 // Visit functions for instruction and computation classes, with empty 3259 // Visit functions for instruction classes, with an empty default
3381 // default implementations. 3260 // implementation.
3382 #define DECLARE_VISIT_COMPUTATION(ShortName, ClassName) \
3383 virtual void Visit##ShortName(ClassName* comp, BindInstr* instr) { }
3384
3385 #define DECLARE_VISIT_INSTRUCTION(ShortName) \ 3261 #define DECLARE_VISIT_INSTRUCTION(ShortName) \
3386 virtual void Visit##ShortName(ShortName##Instr* instr) { } 3262 virtual void Visit##ShortName(ShortName##Instr* instr) { }
3387 3263
3388 FOR_EACH_COMPUTATION(DECLARE_VISIT_COMPUTATION)
3389 FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION) 3264 FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION)
3390 3265
3391 #undef DECLARE_VISIT_COMPUTATION
3392 #undef DECLARE_VISIT_INSTRUCTION 3266 #undef DECLARE_VISIT_INSTRUCTION
3393 3267
3394 protected: 3268 protected:
3395 const GrowableArray<BlockEntryInstr*>& block_order_; 3269 const GrowableArray<BlockEntryInstr*>& block_order_;
3396 ForwardInstructionIterator* current_iterator_; 3270 ForwardInstructionIterator* current_iterator_;
3397 3271
3398 private: 3272 private:
3399 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); 3273 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor);
3400 }; 3274 };
3401 3275
3402 3276
3403 } // namespace dart 3277 } // namespace dart
3404 3278
3405 #endif // VM_INTERMEDIATE_LANGUAGE_H_ 3279 #endif // VM_INTERMEDIATE_LANGUAGE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698