 Chromium Code Reviews
 Chromium Code Reviews Issue 10908091:
  Remove classes Computation and BindInstr.  (Closed) 
  Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
    
  
    Issue 10908091:
  Remove classes Computation and BindInstr.  (Closed) 
  Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart| Index: runtime/vm/intermediate_language.h | 
| diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h | 
| index 51720a50cb73b7dc0430c0c64d8cdb13da8adbf5..7ea88bb64e0acb6ffad741720ddaec7886a489f7 100644 | 
| --- a/runtime/vm/intermediate_language.h | 
| +++ b/runtime/vm/intermediate_language.h | 
| @@ -14,13 +14,10 @@ | 
| namespace dart { | 
| -class BindInstr; | 
| class BitVector; | 
| class BlockEntryInstr; | 
| class BufferFormatter; | 
| -class ComparisonComp; | 
| -class ConstantComp; | 
| -class Computation; | 
| +class ComparisonInstr; | 
| class ControlInstruction; | 
| class Definition; | 
| class Environment; | 
| @@ -185,7 +182,6 @@ class EmbeddedArray<T, 0> { | 
| M(JoinEntry) \ | 
| M(TargetEntry) \ | 
| M(Phi) \ | 
| - M(Bind) \ | 
| M(Parameter) \ | 
| M(ParallelMove) \ | 
| M(PushArgument) \ | 
| @@ -194,6 +190,57 @@ class EmbeddedArray<T, 0> { | 
| M(ReThrow) \ | 
| M(Goto) \ | 
| M(Branch) \ | 
| + M(AssertAssignable) \ | 
| + M(AssertBoolean) \ | 
| + M(ArgumentDefinitionTest) \ | 
| + M(CurrentContext) \ | 
| + M(StoreContext) \ | 
| + M(ClosureCall) \ | 
| + M(InstanceCall) \ | 
| + M(PolymorphicInstanceCall) \ | 
| + M(StaticCall) \ | 
| + M(LoadLocal) \ | 
| + M(StoreLocal) \ | 
| + M(StrictCompare) \ | 
| + M(EqualityCompare) \ | 
| + M(RelationalOp) \ | 
| + M(NativeCall) \ | 
| + M(LoadIndexed) \ | 
| + M(StoreIndexed) \ | 
| + M(LoadInstanceField) \ | 
| + M(StoreInstanceField) \ | 
| + M(LoadStaticField) \ | 
| + M(StoreStaticField) \ | 
| + M(BooleanNegate) \ | 
| + M(InstanceOf) \ | 
| + M(CreateArray) \ | 
| + M(CreateClosure) \ | 
| + M(AllocateObject) \ | 
| + M(AllocateObjectWithBoundsCheck) \ | 
| + M(LoadVMField) \ | 
| + M(StoreVMField) \ | 
| + M(InstantiateTypeArguments) \ | 
| + M(ExtractConstructorTypeArguments) \ | 
| + M(ExtractConstructorInstantiator) \ | 
| + M(AllocateContext) \ | 
| + M(ChainContext) \ | 
| + M(CloneContext) \ | 
| + M(CatchEntry) \ | 
| + M(BinarySmiOp) \ | 
| + M(BinaryMintOp) \ | 
| + M(UnarySmiOp) \ | 
| + M(NumberNegate) \ | 
| + M(CheckStackOverflow) \ | 
| + M(DoubleToDouble) \ | 
| + M(SmiToDouble) \ | 
| + M(CheckClass) \ | 
| + M(CheckSmi) \ | 
| + M(Constant) \ | 
| + M(CheckEitherNonSmi) \ | 
| + M(UnboxedDoubleBinaryOp) \ | 
| + M(UnboxDouble) \ | 
| + M(BoxDouble) \ | 
| + M(CheckArrayBound) \ | 
| #define FORWARD_DECLARATION(type) class type##Instr; | 
| @@ -203,17 +250,32 @@ FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) | 
| // Functions required in all concrete instruction classes. | 
| #define DECLARE_INSTRUCTION(type) \ | 
| + virtual Tag tag() const { return k##type; } \ | 
| virtual void Accept(FlowGraphVisitor* visitor); \ | 
| virtual type##Instr* As##type() { return this; } \ | 
| virtual const char* DebugName() const { return #type; } \ | 
| - virtual void PrintTo(BufferFormatter* f) const; \ | 
| - virtual void PrintToVisualizer(BufferFormatter* f) const; | 
| + virtual LocationSummary* MakeLocationSummary() const; \ | 
| + virtual void EmitNativeCode(FlowGraphCompiler* compiler); \ | 
| class Instruction : public ZoneAllocated { | 
| public: | 
| +#define DECLARE_TAG(type) k##type, | 
| + enum Tag { | 
| + FOR_EACH_INSTRUCTION(DECLARE_TAG) | 
| + }; | 
| +#undef DECLARE_TAG | 
| + | 
| Instruction() | 
| - : lifetime_position_(-1), previous_(NULL), next_(NULL), env_(NULL) { } | 
| + : deopt_id_(Isolate::Current()->GetNextDeoptId()), | 
| + lifetime_position_(-1), | 
| + previous_(NULL), | 
| + next_(NULL), | 
| + env_(NULL) { } | 
| + | 
| + virtual Tag tag() const = 0; | 
| + | 
| + intptr_t deopt_id() const { return deopt_id_; } | 
| bool IsBlockEntry() { return (AsBlockEntry() != NULL); } | 
| virtual BlockEntryInstr* AsBlockEntry() { return NULL; } | 
| @@ -228,8 +290,8 @@ class Instruction : public ZoneAllocated { | 
| virtual Value* InputAt(intptr_t i) const = 0; | 
| virtual void SetInputAt(intptr_t i, Value* value) = 0; | 
| - // Call instructions override this function and return the | 
| - // number of pushed arguments. | 
| + // Call instructions override this function and return the number of | 
| + // pushed arguments. | 
| virtual intptr_t ArgumentCount() const = 0; | 
| // Returns true, if this instruction can deoptimize. | 
| @@ -299,6 +361,8 @@ class Instruction : public ZoneAllocated { | 
| virtual void RecordAssignedVars(BitVector* assigned_vars, | 
| intptr_t fixed_parameter_count); | 
| + virtual const char* DebugName() const = 0; | 
| + | 
| // Printing support. | 
| virtual void PrintTo(BufferFormatter* f) const = 0; | 
| virtual void PrintToVisualizer(BufferFormatter* f) const = 0; | 
| @@ -318,6 +382,10 @@ FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK) | 
| return NULL; | 
| } | 
| + virtual LocationSummary* MakeLocationSummary() const = 0; | 
| + | 
| + static LocationSummary* MakeCallSummary(); | 
| + | 
| virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 
| UNIMPLEMENTED(); | 
| } | 
| @@ -352,9 +420,25 @@ FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK) | 
| return Isolate::kNoDeoptId; | 
| } | 
| + protected: | 
| + // Fetch deopt id without checking if this computation can deoptimize. | 
| + intptr_t GetDeoptId() const { | 
| + return deopt_id_; | 
| + } | 
| + | 
| private: | 
| friend class Definition; // Needed for InsertBefore, InsertAfter. | 
| + // Classes that set deopt_id_. | 
| + friend class UnboxDoubleInstr; | 
| + friend class UnboxedDoubleBinaryOpInstr; | 
| + friend class CheckClassInstr; | 
| + friend class CheckSmiInstr; | 
| + friend class CheckNonSmiInstr; | 
| + friend class CheckArrayBoundInstr; | 
| + friend class CheckEitherNonSmiInstr; | 
| + | 
| + intptr_t deopt_id_; | 
| intptr_t lifetime_position_; // Position used by register allocator. | 
| Instruction* previous_; | 
| Instruction* next_; | 
| @@ -382,8 +466,6 @@ class TemplateInstruction: public Instruction { | 
| return locs_; | 
| } | 
| - virtual LocationSummary* MakeLocationSummary() const = 0; | 
| - | 
| protected: | 
| EmbeddedArray<Value*, N> inputs_; | 
| @@ -473,9 +555,8 @@ class ParallelMoveInstr : public TemplateInstruction<0> { | 
| intptr_t NumMoves() const { return moves_.length(); } | 
| - LocationSummary* MakeLocationSummary() const { return NULL; } | 
| - | 
| - void EmitNativeCode(FlowGraphCompiler* compiler) { UNREACHABLE(); } | 
| + virtual void PrintTo(BufferFormatter* f) const; | 
| + virtual void PrintToVisualizer(BufferFormatter* f) const; | 
| private: | 
| GrowableArray<MoveOperands*> moves_; // Elements cannot be null. | 
| @@ -614,6 +695,10 @@ class ForwardInstructionIterator : public ValueObject { | 
| // Removes 'current_' from graph and sets 'current_' to previous instruction. | 
| void RemoveCurrentFromGraph(); | 
| + // Inserts replaces 'current_', which must be a definition, with another | 
| + // definition. The new definition becomes 'current_'. | 
| + void ReplaceCurrentWith(Definition* other); | 
| + | 
| Instruction* Current() const { return current_; } | 
| private: | 
| @@ -676,7 +761,7 @@ class GraphEntryInstr : public BlockEntryInstr { | 
| Environment* start_env() const { return start_env_; } | 
| void set_start_env(Environment* env) { start_env_ = env; } | 
| - Definition* constant_null() const { return constant_null_; } | 
| + ConstantInstr* constant_null() const { return constant_null_; } | 
| intptr_t spill_slot_count() const { return spill_slot_count_; } | 
| void set_spill_slot_count(intptr_t count) { | 
| @@ -686,11 +771,14 @@ class GraphEntryInstr : public BlockEntryInstr { | 
| TargetEntryInstr* normal_entry() const { return normal_entry_; } | 
| + virtual void PrintTo(BufferFormatter* f) const; | 
| + virtual void PrintToVisualizer(BufferFormatter* f) const; | 
| + | 
| private: | 
| TargetEntryInstr* normal_entry_; | 
| GrowableArray<TargetEntryInstr*> catch_entries_; | 
| Environment* start_env_; | 
| - Definition* constant_null_; | 
| + ConstantInstr* constant_null_; | 
| intptr_t spill_slot_count_; | 
| DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr); | 
| @@ -727,6 +815,9 @@ class JoinEntryInstr : public BlockEntryInstr { | 
| intptr_t phi_count() const { return phi_count_; } | 
| + virtual void PrintTo(BufferFormatter* f) const; | 
| + virtual void PrintToVisualizer(BufferFormatter* f) const; | 
| + | 
| private: | 
| GrowableArray<BlockEntryInstr*> predecessors_; | 
| ZoneGrowableArray<PhiInstr*>* phis_; | 
| @@ -777,6 +868,9 @@ class TargetEntryInstr : public BlockEntryInstr { | 
| virtual void PrepareEntry(FlowGraphCompiler* compiler); | 
| + virtual void PrintTo(BufferFormatter* f) const; | 
| + virtual void PrintToVisualizer(BufferFormatter* f) const; | 
| + | 
| private: | 
| BlockEntryInstr* predecessor_; | 
| const intptr_t catch_try_index_; | 
| @@ -802,6 +896,12 @@ class Definition : public Instruction { | 
| virtual Definition* AsDefinition() { return this; } | 
| + bool IsComparison() { return (AsComparison() != NULL); } | 
| + virtual ComparisonInstr* AsComparison() { return NULL; } | 
| + | 
| + // Overridden by definitions that push arguments. | 
| + virtual intptr_t ArgumentCount() const { return 0; } | 
| + | 
| intptr_t temp_index() const { return temp_index_; } | 
| void set_temp_index(intptr_t index) { temp_index_ = index; } | 
| @@ -820,6 +920,8 @@ class Definition : public Instruction { | 
| // propagation during graph building. | 
| virtual RawAbstractType* CompileType() const = 0; | 
| + virtual intptr_t ResultCid() const = 0; | 
| + | 
| bool HasPropagatedType() const { | 
| return !propagated_type_.IsNull(); | 
| } | 
| @@ -841,32 +943,71 @@ class Definition : public Instruction { | 
| bool has_propagated_cid() const { return propagated_cid_ != kIllegalCid; } | 
| intptr_t propagated_cid() const { return propagated_cid_; } | 
| + | 
| // May compute and set propagated cid. | 
| - virtual intptr_t GetPropagatedCid() = 0; | 
| + virtual intptr_t GetPropagatedCid(); | 
| // Returns true if the propagated cid has changed. | 
| bool SetPropagatedCid(intptr_t cid); | 
| + // Returns true if the definition may have side effects. | 
| + // TODO(fschneider): Make this abstract and implement for all definitions | 
| + // instead of returning the safe default (true). | 
| + virtual bool HasSideEffect() const { return true; } | 
| + | 
| Value* input_use_list() { return input_use_list_; } | 
| void set_input_use_list(Value* head) { input_use_list_ = head; } | 
| Value* env_use_list() { return env_use_list_; } | 
| void set_env_use_list(Value* head) { env_use_list_ = head; } | 
| + // Returns a replacement for the definition or NULL if the definition can | 
| + // be eliminated. By default returns the definition (input parameter) | 
| + // which means no change. | 
| + virtual Definition* Canonicalize(); | 
| + | 
| // Replace uses of this definition with uses of other definition or value. | 
| // Precondition: use lists must be properly calculated. | 
| // Postcondition: use lists and use values are still valid. | 
| void ReplaceUsesWith(Definition* other); | 
| + // Replace this definition and all uses with another definition. If | 
| + // replacing during iteration, pass the iterator so that the instruction | 
| + // can be replaced without affecting iteration order, otherwise pass a | 
| + // NULL iterator. | 
| + void ReplaceWith(Definition* other, ForwardInstructionIterator* iterator); | 
| + | 
| // Insert this definition before 'next'. | 
| void InsertBefore(Instruction* next); | 
| // Insert this definition after 'prev'. | 
| void InsertAfter(Instruction* prev); | 
| - // If this definition is a bind of a constant return it. | 
| - // Otherwise return NULL. | 
| - ConstantComp* AsConstant(); | 
| + // Compares two definitions. Returns true, iff: | 
| + // 1. They have the same tag. | 
| + // 2. All input operands are Equals. | 
| + // 3. They satisfy AttributesEqual. | 
| + bool Equals(Definition* other) const; | 
| + | 
| + // Compare attributes of a definition (except input operands and tag). | 
| + // All definition that participate in CSE have to override this function. | 
| + // This function can assume that the argument has the same type as this. | 
| + virtual bool AttributesEqual(Definition* other) const { | 
| + UNREACHABLE(); | 
| + return false; | 
| + } | 
| + | 
| + // Returns a hash code for use with hash maps. | 
| + virtual intptr_t Hashcode() const; | 
| + | 
| + virtual void RecordAssignedVars(BitVector* assigned_vars, | 
| + intptr_t fixed_parameter_count); | 
| + | 
| + // Printing support. These functions are sometimes overridden for custom | 
| + // formatting. Otherwise, it prints in the format "opcode(op1, op2, op3)". | 
| + virtual void PrintTo(BufferFormatter* f) const; | 
| + virtual void PrintOperandsTo(BufferFormatter* f) const; | 
| + virtual void PrintToVisualizer(BufferFormatter* f) const; | 
| private: | 
| intptr_t temp_index_; | 
| @@ -883,48 +1024,6 @@ class Definition : public Instruction { | 
| }; | 
| -class BindInstr : public Definition { | 
| - public: | 
| - BindInstr(UseKind used, Computation* computation) | 
| - : computation_(computation) { | 
| - ASSERT(computation != NULL); | 
| - set_use_kind(used); | 
| - } | 
| - | 
| - DECLARE_INSTRUCTION(Bind) | 
| - | 
| - // Overridden functions from class Instruction. | 
| - virtual intptr_t ArgumentCount() const; | 
| - intptr_t InputCount() const; | 
| - Value* InputAt(intptr_t i) const; | 
| - void SetInputAt(intptr_t i, Value* value); | 
| - virtual bool CanDeoptimize() const; | 
| - virtual void RecordAssignedVars(BitVector* assigned_vars, | 
| - intptr_t fixed_parameter_count); | 
| - virtual LocationSummary* locs(); | 
| - virtual void EmitNativeCode(FlowGraphCompiler* compiler); | 
| - virtual Representation RequiredInputRepresentation(intptr_t i) const; | 
| - virtual Representation representation() const; | 
| - virtual intptr_t DeoptimizationTarget() const; | 
| - | 
| - Computation* computation() const { return computation_; } | 
| - void set_computation(Computation* value) { computation_ = value; } | 
| - | 
| - // Overridden functions from class Definition. | 
| - virtual RawAbstractType* CompileType() const; | 
| - virtual intptr_t GetPropagatedCid(); | 
| - | 
| - // Other functions that forward to the computation. | 
| - intptr_t Hashcode() const; | 
| - bool Equals(BindInstr* other) const; | 
| - | 
| - private: | 
| - Computation* computation_; | 
| - | 
| - DISALLOW_COPY_AND_ASSIGN(BindInstr); | 
| -}; | 
| - | 
| - | 
| class PhiInstr : public Definition { | 
| public: | 
| explicit PhiInstr(JoinEntryInstr* block, intptr_t num_inputs) | 
| @@ -940,7 +1039,7 @@ class PhiInstr : public Definition { | 
| JoinEntryInstr* block() const { return block_; } | 
| virtual RawAbstractType* CompileType() const; | 
| - virtual intptr_t GetPropagatedCid() { return propagated_cid(); } | 
| + virtual intptr_t GetPropagatedCid(); | 
| virtual intptr_t ArgumentCount() const { return 0; } | 
| @@ -971,8 +1070,21 @@ class PhiInstr : public Definition { | 
| representation_ = r; | 
| } | 
| + virtual intptr_t Hashcode() const { | 
| + UNREACHABLE(); | 
| + return 0; | 
| + } | 
| + | 
| + virtual intptr_t ResultCid() const { | 
| + UNREACHABLE(); | 
| + return kIllegalCid; | 
| + } | 
| + | 
| DECLARE_INSTRUCTION(Phi) | 
| + virtual void PrintTo(BufferFormatter* f) const; | 
| + virtual void PrintToVisualizer(BufferFormatter* f) const; | 
| + | 
| private: | 
| JoinEntryInstr* block_; | 
| GrowableArray<Value*> inputs_; | 
| @@ -993,8 +1105,9 @@ class ParameterInstr : public Definition { | 
| // Compile type of the passed-in parameter. | 
| virtual RawAbstractType* CompileType() const; | 
| + | 
| // No known propagated cid for parameters. | 
| - virtual intptr_t GetPropagatedCid() { return propagated_cid(); } | 
| + virtual intptr_t GetPropagatedCid(); | 
| virtual intptr_t ArgumentCount() const { return 0; } | 
| @@ -1007,6 +1120,19 @@ class ParameterInstr : public Definition { | 
| virtual bool CanDeoptimize() const { return false; } | 
| + virtual intptr_t Hashcode() const { | 
| + UNREACHABLE(); | 
| + return 0; | 
| + } | 
| + | 
| + virtual intptr_t ResultCid() const { | 
| + UNREACHABLE(); | 
| + return kIllegalCid; | 
| + } | 
| + | 
| + virtual void PrintTo(BufferFormatter* f) const; | 
| + virtual void PrintToVisualizer(BufferFormatter* f) const; | 
| + | 
| private: | 
| const intptr_t index_; | 
| @@ -1018,6 +1144,7 @@ class PushArgumentInstr : public Definition { | 
| public: | 
| explicit PushArgumentInstr(Value* value) : value_(value), locs_(NULL) { | 
| ASSERT(value != NULL); | 
| + set_use_kind(kEffect); // Override the default. | 
| } | 
| DECLARE_INSTRUCTION(PushArgument) | 
| @@ -1036,6 +1163,7 @@ class PushArgumentInstr : public Definition { | 
| virtual RawAbstractType* CompileType() const; | 
| virtual intptr_t GetPropagatedCid() { return propagated_cid(); } | 
| 
Florian Schneider
2012/09/05 11:14:42
Move to .cc file as well?
 | 
| + virtual intptr_t ResultCid() const { return kIllegalCid; } | 
| 
Florian Schneider
2012/09/05 11:14:42
UNREACHABLE();
 
Kevin Millikin (Google)
2012/09/05 11:27:28
Oops, we can't.  As is, this is called in the type
 | 
| Value* value() const { return value_; } | 
| @@ -1046,12 +1174,16 @@ class PushArgumentInstr : public Definition { | 
| return locs_; | 
| } | 
| - LocationSummary* MakeLocationSummary() const; | 
| - | 
| - virtual void EmitNativeCode(FlowGraphCompiler* compiler); | 
| + virtual intptr_t Hashcode() const { | 
| + UNREACHABLE(); | 
| + return 0; | 
| + } | 
| virtual bool CanDeoptimize() const { return false; } | 
| + virtual void PrintTo(BufferFormatter* f) const; | 
| + virtual void PrintToVisualizer(BufferFormatter* f) const; | 
| + | 
| private: | 
| Value* value_; | 
| LocationSummary* locs_; | 
| @@ -1063,8 +1195,7 @@ class PushArgumentInstr : public Definition { | 
| class ReturnInstr : public TemplateInstruction<1> { | 
| public: | 
| ReturnInstr(intptr_t token_pos, Value* value) | 
| - : deopt_id_(Isolate::Current()->GetNextDeoptId()), | 
| - token_pos_(token_pos) { | 
| + : token_pos_(token_pos) { | 
| ASSERT(value != NULL); | 
| inputs_[0] = value; | 
| } | 
| @@ -1073,18 +1204,15 @@ class ReturnInstr : public TemplateInstruction<1> { | 
| virtual intptr_t ArgumentCount() const { return 0; } | 
| - intptr_t deopt_id() const { return deopt_id_; } | 
| intptr_t token_pos() const { return token_pos_; } | 
| Value* value() const { return inputs_[0]; } | 
| - virtual LocationSummary* MakeLocationSummary() const; | 
| - | 
| - virtual void EmitNativeCode(FlowGraphCompiler* compiler); | 
| - | 
| virtual bool CanDeoptimize() const { return false; } | 
| + virtual void PrintTo(BufferFormatter* f) const; | 
| + virtual void PrintToVisualizer(BufferFormatter* f) const; | 
| + | 
| private: | 
| - const intptr_t deopt_id_; | 
| const intptr_t token_pos_; | 
| DISALLOW_COPY_AND_ASSIGN(ReturnInstr); | 
| @@ -1101,12 +1229,11 @@ class ThrowInstr : public TemplateInstruction<0> { | 
| intptr_t token_pos() const { return token_pos_; } | 
| - virtual LocationSummary* MakeLocationSummary() const; | 
| - | 
| - virtual void EmitNativeCode(FlowGraphCompiler* compiler); | 
| - | 
| virtual bool CanDeoptimize() const { return false; } | 
| + virtual void PrintTo(BufferFormatter* f) const; | 
| + virtual void PrintToVisualizer(BufferFormatter* f) const; | 
| + | 
| private: | 
| const intptr_t token_pos_; | 
| @@ -1124,12 +1251,11 @@ class ReThrowInstr : public TemplateInstruction<0> { | 
| intptr_t token_pos() const { return token_pos_; } | 
| - virtual LocationSummary* MakeLocationSummary() const; | 
| - | 
| - virtual void EmitNativeCode(FlowGraphCompiler* compiler); | 
| - | 
| virtual bool CanDeoptimize() const { return false; } | 
| + virtual void PrintTo(BufferFormatter* f) const; | 
| + virtual void PrintToVisualizer(BufferFormatter* f) const; | 
| + | 
| private: | 
| const intptr_t token_pos_; | 
| @@ -1152,10 +1278,6 @@ class GotoInstr : public TemplateInstruction<0> { | 
| virtual intptr_t SuccessorCount() const; | 
| virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; | 
| - virtual LocationSummary* MakeLocationSummary() const; | 
| - | 
| - virtual void EmitNativeCode(FlowGraphCompiler* compiler); | 
| - | 
| virtual bool CanDeoptimize() const { return false; } | 
| ParallelMoveInstr* parallel_move() const { | 
| @@ -1173,6 +1295,9 @@ class GotoInstr : public TemplateInstruction<0> { | 
| return parallel_move_; | 
| } | 
| + virtual void PrintTo(BufferFormatter* f) const; | 
| + virtual void PrintToVisualizer(BufferFormatter* f) const; | 
| + | 
| private: | 
| JoinEntryInstr* successor_; | 
| @@ -1220,8 +1345,8 @@ class ControlInstruction : public Instruction { | 
| class BranchInstr : public ControlInstruction { | 
| public: | 
| - explicit BranchInstr(ComparisonComp* computation) | 
| - : computation_(computation), locs_(NULL) { } | 
| + explicit BranchInstr(ComparisonInstr* comparison) | 
| + : comparison_(comparison) { } | 
| DECLARE_INSTRUCTION(Branch) | 
| @@ -1231,157 +1356,43 @@ class BranchInstr : public ControlInstruction { | 
| void SetInputAt(intptr_t i, Value* value); | 
| virtual bool CanDeoptimize() const; | 
| - ComparisonComp* computation() const { return computation_; } | 
| - void set_computation(ComparisonComp* value) { computation_ = value; } | 
| - | 
| - virtual void EmitNativeCode(FlowGraphCompiler* compiler); | 
| + ComparisonInstr* comparison() const { return comparison_; } | 
| + void set_comparison(ComparisonInstr* value) { comparison_ = value; } | 
| virtual LocationSummary* locs(); | 
| virtual intptr_t DeoptimizationTarget() const; | 
| virtual Representation RequiredInputRepresentation(intptr_t i) const; | 
| + // Replace the comparison with another, leaving the branch intact. | 
| + void ReplaceWith(ComparisonInstr* other, | 
| + ForwardInstructionIterator* ignored) { | 
| + comparison_ = other; | 
| + } | 
| + | 
| + virtual void PrintTo(BufferFormatter* f) const; | 
| + virtual void PrintToVisualizer(BufferFormatter* f) const; | 
| + | 
| private: | 
| - ComparisonComp* computation_; | 
| - LocationSummary* locs_; | 
| + ComparisonInstr* comparison_; | 
| DISALLOW_COPY_AND_ASSIGN(BranchInstr); | 
| }; | 
| -#undef DECLARE_INSTRUCTION | 
| - | 
| - | 
| -// M is a two argument macro. It is applied to each concrete instruction's | 
| -// (including the values) typename and classname. | 
| -#define FOR_EACH_COMPUTATION(M) \ | 
| - M(AssertAssignable, AssertAssignableComp) \ | 
| - M(AssertBoolean, AssertBooleanComp) \ | 
| - M(ArgumentDefinitionTest, ArgumentDefinitionTestComp) \ | 
| - M(CurrentContext, CurrentContextComp) \ | 
| - M(StoreContext, StoreContextComp) \ | 
| - M(ClosureCall, ClosureCallComp) \ | 
| - M(InstanceCall, InstanceCallComp) \ | 
| - M(PolymorphicInstanceCall, PolymorphicInstanceCallComp) \ | 
| - M(StaticCall, StaticCallComp) \ | 
| - M(LoadLocal, LoadLocalComp) \ | 
| - M(StoreLocal, StoreLocalComp) \ | 
| - M(StrictCompare, StrictCompareComp) \ | 
| - M(EqualityCompare, EqualityCompareComp) \ | 
| - M(RelationalOp, RelationalOpComp) \ | 
| - M(NativeCall, NativeCallComp) \ | 
| - M(LoadIndexed, LoadIndexedComp) \ | 
| - M(StoreIndexed, StoreIndexedComp) \ | 
| - M(LoadInstanceField, LoadInstanceFieldComp) \ | 
| - M(StoreInstanceField, StoreInstanceFieldComp) \ | 
| - M(LoadStaticField, LoadStaticFieldComp) \ | 
| - M(StoreStaticField, StoreStaticFieldComp) \ | 
| - M(BooleanNegate, BooleanNegateComp) \ | 
| - M(InstanceOf, InstanceOfComp) \ | 
| - M(CreateArray, CreateArrayComp) \ | 
| - M(CreateClosure, CreateClosureComp) \ | 
| - M(AllocateObject, AllocateObjectComp) \ | 
| - M(AllocateObjectWithBoundsCheck, AllocateObjectWithBoundsCheckComp) \ | 
| - M(LoadVMField, LoadVMFieldComp) \ | 
| - M(StoreVMField, StoreVMFieldComp) \ | 
| - M(InstantiateTypeArguments, InstantiateTypeArgumentsComp) \ | 
| - M(ExtractConstructorTypeArguments, ExtractConstructorTypeArgumentsComp) \ | 
| - M(ExtractConstructorInstantiator, ExtractConstructorInstantiatorComp) \ | 
| - M(AllocateContext, AllocateContextComp) \ | 
| - M(ChainContext, ChainContextComp) \ | 
| - M(CloneContext, CloneContextComp) \ | 
| - M(CatchEntry, CatchEntryComp) \ | 
| - M(BinarySmiOp, BinarySmiOpComp) \ | 
| - M(BinaryMintOp, BinaryMintOpComp) \ | 
| - M(UnarySmiOp, UnarySmiOpComp) \ | 
| - M(NumberNegate, NumberNegateComp) \ | 
| - M(CheckStackOverflow, CheckStackOverflowComp) \ | 
| - M(DoubleToDouble, DoubleToDoubleComp) \ | 
| - M(SmiToDouble, SmiToDoubleComp) \ | 
| - M(CheckClass, CheckClassComp) \ | 
| - M(CheckSmi, CheckSmiComp) \ | 
| - M(Constant, ConstantComp) \ | 
| - M(CheckEitherNonSmi, CheckEitherNonSmiComp) \ | 
| - M(UnboxedDoubleBinaryOp, UnboxedDoubleBinaryOpComp) \ | 
| - M(UnboxDouble, UnboxDoubleComp) \ | 
| - M(BoxDouble, BoxDoubleComp) \ | 
| - M(CheckArrayBound, CheckArrayBoundComp) | 
| - | 
| - | 
| -#define FORWARD_DECLARATION(ShortName, ClassName) class ClassName; | 
| -FOR_EACH_COMPUTATION(FORWARD_DECLARATION) | 
| -#undef FORWARD_DECLARATION | 
| - | 
| - | 
| -class Computation : public ZoneAllocated { | 
| +template<intptr_t N> | 
| +class TemplateDefinition : public Definition { | 
| public: | 
| - Computation() | 
| - : deopt_id_(Isolate::Current()->GetNextDeoptId()), locs_(NULL) { } | 
| - | 
| - // Unique id used for deoptimization. | 
| - virtual intptr_t deopt_id() const { | 
| - ASSERT(CanDeoptimize()); | 
| - return deopt_id_; | 
| - } | 
| - | 
| - // Visiting support. | 
| - virtual void Accept(FlowGraphVisitor* visitor, BindInstr* instr) = 0; | 
| - | 
| - virtual intptr_t InputCount() const = 0; | 
| - virtual Value* InputAt(intptr_t i) const = 0; | 
| - virtual void SetInputAt(intptr_t i, Value* value) = 0; | 
| - | 
| - // Call computations override this function and return the | 
| - // number of pushed arguments. | 
| - virtual intptr_t ArgumentCount() const = 0; | 
| + TemplateDefinition<N>() : locs_(NULL) { } | 
| - // Returns true, if this computation can deoptimize. | 
| - virtual bool CanDeoptimize() const = 0; | 
| - | 
| - // Returns a replacement for the instruction that wraps this computation. | 
| - // Returns NULL if instr can be eliminated. | 
| - // By default returns instr (input parameter) which means no change. | 
| - virtual Definition* TryReplace(BindInstr* instr) const; | 
| - | 
| - // Compares two computations. Returns true, if: | 
| - // 1. They are of the same kind. | 
| - // 2. All input operands match. | 
| - // 3. All other attributes match. | 
| - bool Equals(Computation* other) const; | 
| - | 
| - // Returns a hash code for use with hash maps. | 
| - virtual intptr_t Hashcode() const; | 
| - | 
| - // Compare attributes of an computation (except input operands and kind). | 
| - // All computations that participate in CSE have to override this function. | 
| - virtual bool AttributesEqual(Computation* other) const { | 
| - UNREACHABLE(); | 
| - return false; | 
| + virtual intptr_t InputCount() const { return N; } | 
| + virtual Value* InputAt(intptr_t i) const { return inputs_[i]; } | 
| + virtual void SetInputAt(intptr_t i, Value* value) { | 
| + ASSERT(value != NULL); | 
| + inputs_[i] = value; | 
| } | 
| - // Returns true if the instruction may have side effects. | 
| - // TODO(fschneider): Make this abstract and implement for all computations | 
| - // instead of returning the safe default (true). | 
| - virtual bool HasSideEffect() const { return true; } | 
| - | 
| - // Compile time type of the computation, which typically depends on the | 
| - // compile time types (and possibly propagated types) of its inputs. | 
| - virtual RawAbstractType* CompileType() const = 0; | 
| - virtual intptr_t ResultCid() const = 0; | 
| - | 
| - // Mutate assigned_vars to add the local variable index for all | 
| - // frame-allocated locals assigned to by the computation. | 
| - virtual void RecordAssignedVars(BitVector* assigned_vars, | 
| - intptr_t fixed_parameter_count); | 
| - | 
| - virtual const char* DebugName() const = 0; | 
| - | 
| - // Printing support. These functions are sometimes overridden for custom | 
| - // formatting. Otherwise, it prints in the format "opcode(op1, op2, op3)". | 
| - virtual void PrintTo(BufferFormatter* f) const; | 
| - virtual void PrintOperandsTo(BufferFormatter* f) const; | 
| - | 
| - // Returns structure describing location constraints required | 
| - // to emit native code for this computation. | 
| + // Returns a structure describing the location constraints required | 
| + // to emit native code for this definition. | 
| LocationSummary* locs() { | 
| if (locs_ == NULL) { | 
| locs_ = MakeLocationSummary(); | 
| @@ -1389,176 +1400,22 @@ class Computation : public ZoneAllocated { | 
| return locs_; | 
| } | 
| - virtual ComparisonComp* AsComparison() { return NULL; } | 
| - | 
| - // Create a location summary for this computation. | 
| - // TODO(fschneider): Temporarily returns NULL for instructions | 
| - // that are not yet converted to the location based code generation. | 
| - virtual LocationSummary* MakeLocationSummary() const = 0; | 
| - | 
| - // TODO(fschneider): Make EmitNativeCode and locs const. | 
| - virtual void EmitNativeCode(FlowGraphCompiler* compiler) = 0; | 
| - | 
| - virtual void EmitBranchCode(FlowGraphCompiler* compiler, | 
| - BranchInstr* branch) { | 
| - UNREACHABLE(); | 
| - } | 
| - | 
| - static LocationSummary* MakeCallSummary(); | 
| - | 
| - // Declare an enum value used to define kind-test predicates. | 
| - enum ComputationKind { | 
| -#define DECLARE_COMPUTATION_KIND(ShortName, ClassName) k##ShortName, | 
| - | 
| - FOR_EACH_COMPUTATION(DECLARE_COMPUTATION_KIND) | 
| - | 
| -#undef DECLARE_COMPUTATION_KIND | 
| - }; | 
| - | 
| - virtual ComputationKind computation_kind() const = 0; | 
| - | 
| - // Returns representation expected for the input operand at the given index. | 
| - virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 
| - return kTagged; | 
| - } | 
| - | 
| - // Representation of the value produced by this computation. | 
| - virtual Representation representation() const { | 
| - return kTagged; | 
| - } | 
| - | 
| - // Returns deoptimization id that corresponds to the deoptimization target | 
| - // that input operands conversions inserted for this instruction can jump | 
| - // to. Can return kNoDeoptId. | 
| - virtual intptr_t DeoptimizationTarget() const { | 
| - UNREACHABLE(); | 
| - return Isolate::kNoDeoptId; | 
| - } | 
| - | 
| - // Declare predicate for each computation. | 
| -#define DECLARE_PREDICATE(ShortName, ClassName) \ | 
| - inline bool Is##ShortName() const; \ | 
| - inline const ClassName* As##ShortName() const; \ | 
| - inline ClassName* As##ShortName(); | 
| -FOR_EACH_COMPUTATION(DECLARE_PREDICATE) | 
| -#undef DECLARE_PREDICATE | 
| - | 
| protected: | 
| - // Fetch deopt id without checking if this computation can deoptimize. | 
| - intptr_t GetDeoptId() const { | 
| - return deopt_id_; | 
| - } | 
| + EmbeddedArray<Value*, N> inputs_; | 
| private: | 
| friend class BranchInstr; | 
| - intptr_t deopt_id_; | 
| LocationSummary* locs_; | 
| - | 
| - DISALLOW_COPY_AND_ASSIGN(Computation); | 
| -}; | 
| - | 
| - | 
| -// Inlined functions from class BindInstr that forward to their computation. | 
| -inline intptr_t BindInstr::ArgumentCount() const { | 
| - return computation()->ArgumentCount(); | 
| -} | 
| - | 
| - | 
| -inline intptr_t BindInstr::InputCount() const { | 
| - return computation()->InputCount(); | 
| -} | 
| - | 
| - | 
| -inline Value* BindInstr::InputAt(intptr_t i) const { | 
| - return computation()->InputAt(i); | 
| -} | 
| - | 
| - | 
| -inline void BindInstr::SetInputAt(intptr_t i, Value* value) { | 
| - computation()->SetInputAt(i, value); | 
| -} | 
| - | 
| -inline bool BindInstr::CanDeoptimize() const { | 
| - return computation()->CanDeoptimize(); | 
| -} | 
| - | 
| - | 
| -inline intptr_t BindInstr::Hashcode() const { | 
| - return computation()->Hashcode(); | 
| -} | 
| - | 
| - | 
| -inline bool BindInstr::Equals(BindInstr* other) const { | 
| - return computation()->Equals(other->computation()); | 
| -} | 
| - | 
| - | 
| -inline LocationSummary* BindInstr::locs() { | 
| - return computation()->locs(); | 
| -} | 
| - | 
| - | 
| -inline Representation BindInstr::RequiredInputRepresentation(intptr_t i) const { | 
| - return computation()->RequiredInputRepresentation(i); | 
| -} | 
| - | 
| - | 
| -inline Representation BindInstr::representation() const { | 
| - return computation()->representation(); | 
| -} | 
| - | 
| - | 
| -inline intptr_t BindInstr::DeoptimizationTarget() const { | 
| - return computation()->DeoptimizationTarget(); | 
| -} | 
| - | 
| - | 
| -template<intptr_t N> | 
| -class TemplateComputation : public Computation { | 
| - public: | 
| - virtual intptr_t InputCount() const { return N; } | 
| - virtual Value* InputAt(intptr_t i) const { return inputs_[i]; } | 
| - virtual void SetInputAt(intptr_t i, Value* value) { | 
| - ASSERT(value != NULL); | 
| - inputs_[i] = value; | 
| - } | 
| - | 
| - protected: | 
| - EmbeddedArray<Value*, N> inputs_; | 
| }; | 
| -// Functions defined in all concrete computation classes. | 
| -#define DECLARE_COMPUTATION(ShortName) \ | 
| - virtual void Accept(FlowGraphVisitor* visitor, BindInstr* instr); \ | 
| - virtual ComputationKind computation_kind() const { \ | 
| - return Computation::k##ShortName; \ | 
| - } \ | 
| - virtual intptr_t ArgumentCount() const { return 0; } \ | 
| - virtual const char* DebugName() const { return #ShortName; } \ | 
| - virtual RawAbstractType* CompileType() const; \ | 
| - virtual LocationSummary* MakeLocationSummary() const; \ | 
| - virtual void EmitNativeCode(FlowGraphCompiler* compiler); | 
| - | 
| - | 
| -// Function defined in all call computation classes. | 
| -#define DECLARE_CALL_COMPUTATION(ShortName) \ | 
| - virtual void Accept(FlowGraphVisitor* visitor, BindInstr* instr); \ | 
| - virtual ComputationKind computation_kind() const { \ | 
| - return Computation::k##ShortName; \ | 
| - } \ | 
| - virtual const char* DebugName() const { return #ShortName; } \ | 
| - virtual RawAbstractType* CompileType() const; \ | 
| - virtual LocationSummary* MakeLocationSummary() const; \ | 
| - virtual void EmitNativeCode(FlowGraphCompiler* compiler); | 
| - | 
| - | 
| -class ConstantComp : public TemplateComputation<0> { | 
| +class ConstantInstr : public TemplateDefinition<0> { | 
| public: | 
| - explicit ConstantComp(const Object& value) : value_(value) { } | 
| + explicit ConstantInstr(const Object& value) : value_(value) { } | 
| - DECLARE_COMPUTATION(Constant) | 
| + DECLARE_INSTRUCTION(Constant) | 
| + virtual RawAbstractType* CompileType() const; | 
| const Object& value() const { return value_; } | 
| @@ -1568,23 +1425,23 @@ class ConstantComp : public TemplateComputation<0> { | 
| virtual intptr_t ResultCid() const; | 
| - virtual bool AttributesEqual(Computation* other) const; | 
| + virtual bool AttributesEqual(Definition* other) const; | 
| private: | 
| const Object& value_; | 
| - DISALLOW_COPY_AND_ASSIGN(ConstantComp); | 
| + DISALLOW_COPY_AND_ASSIGN(ConstantInstr); | 
| }; | 
| -class AssertAssignableComp : public TemplateComputation<3> { | 
| +class AssertAssignableInstr : public TemplateDefinition<3> { | 
| public: | 
| - AssertAssignableComp(intptr_t token_pos, | 
| - Value* value, | 
| - Value* instantiator, | 
| - Value* instantiator_type_arguments, | 
| - const AbstractType& dst_type, | 
| - const String& dst_name) | 
| + AssertAssignableInstr(intptr_t token_pos, | 
| + Value* value, | 
| + Value* instantiator, | 
| + Value* instantiator_type_arguments, | 
| + const AbstractType& dst_type, | 
| + const String& dst_name) | 
| : token_pos_(token_pos), | 
| dst_type_(dst_type), | 
| dst_name_(dst_name), | 
| @@ -1599,7 +1456,8 @@ class AssertAssignableComp : public TemplateComputation<3> { | 
| inputs_[2] = instantiator_type_arguments; | 
| } | 
| - DECLARE_COMPUTATION(AssertAssignable) | 
| + DECLARE_INSTRUCTION(AssertAssignable) | 
| + virtual RawAbstractType* CompileType() const; | 
| Value* value() const { return inputs_[0]; } | 
| Value* instantiator() const { return inputs_[1]; } | 
| @@ -1628,21 +1486,21 @@ class AssertAssignableComp : public TemplateComputation<3> { | 
| const String& dst_name_; | 
| bool is_eliminated_; | 
| - DISALLOW_COPY_AND_ASSIGN(AssertAssignableComp); | 
| + DISALLOW_COPY_AND_ASSIGN(AssertAssignableInstr); | 
| }; | 
| -class AssertBooleanComp : public TemplateComputation<1> { | 
| +class AssertBooleanInstr : public TemplateDefinition<1> { | 
| public: | 
| - AssertBooleanComp(intptr_t token_pos, | 
| - Value* value) | 
| + AssertBooleanInstr(intptr_t token_pos, Value* value) | 
| : token_pos_(token_pos), | 
| is_eliminated_(false) { | 
| ASSERT(value != NULL); | 
| inputs_[0] = value; | 
| } | 
| - DECLARE_COMPUTATION(AssertBoolean) | 
| + DECLARE_INSTRUCTION(AssertBoolean) | 
| + virtual RawAbstractType* CompileType() const; | 
| intptr_t token_pos() const { return token_pos_; } | 
| Value* value() const { return inputs_[0]; } | 
| @@ -1664,20 +1522,21 @@ class AssertBooleanComp : public TemplateComputation<1> { | 
| const intptr_t token_pos_; | 
| bool is_eliminated_; | 
| - DISALLOW_COPY_AND_ASSIGN(AssertBooleanComp); | 
| + DISALLOW_COPY_AND_ASSIGN(AssertBooleanInstr); | 
| }; | 
| -class ArgumentDefinitionTestComp : public TemplateComputation<1> { | 
| +class ArgumentDefinitionTestInstr : public TemplateDefinition<1> { | 
| public: | 
| - ArgumentDefinitionTestComp(ArgumentDefinitionTestNode* node, | 
| - Value* saved_arguments_descriptor) | 
| + ArgumentDefinitionTestInstr(ArgumentDefinitionTestNode* node, | 
| + Value* saved_arguments_descriptor) | 
| : ast_node_(*node) { | 
| ASSERT(saved_arguments_descriptor != NULL); | 
| inputs_[0] = saved_arguments_descriptor; | 
| } | 
| - DECLARE_COMPUTATION(ArgumentDefinitionTest) | 
| + DECLARE_INSTRUCTION(ArgumentDefinitionTest) | 
| + virtual RawAbstractType* CompileType() const; | 
| intptr_t token_pos() const { return ast_node_.token_pos(); } | 
| intptr_t formal_parameter_index() const { | 
| @@ -1696,34 +1555,36 @@ class ArgumentDefinitionTestComp : public TemplateComputation<1> { | 
| private: | 
| const ArgumentDefinitionTestNode& ast_node_; | 
| - DISALLOW_COPY_AND_ASSIGN(ArgumentDefinitionTestComp); | 
| + DISALLOW_COPY_AND_ASSIGN(ArgumentDefinitionTestInstr); | 
| }; | 
| // Denotes the current context, normally held in a register. This is | 
| // a computation, not a value, because it's mutable. | 
| -class CurrentContextComp : public TemplateComputation<0> { | 
| +class CurrentContextInstr : public TemplateDefinition<0> { | 
| public: | 
| - CurrentContextComp() { } | 
| + CurrentContextInstr() { } | 
| - DECLARE_COMPUTATION(CurrentContext) | 
| + DECLARE_INSTRUCTION(CurrentContext) | 
| + virtual RawAbstractType* CompileType() const; | 
| virtual bool CanDeoptimize() const { return false; } | 
| virtual intptr_t ResultCid() const { return kDynamicCid; } | 
| private: | 
| - DISALLOW_COPY_AND_ASSIGN(CurrentContextComp); | 
| + DISALLOW_COPY_AND_ASSIGN(CurrentContextInstr); | 
| }; | 
| -class StoreContextComp : public TemplateComputation<1> { | 
| +class StoreContextInstr : public TemplateDefinition<1> { | 
| public: | 
| - explicit StoreContextComp(Value* value) { | 
| + explicit StoreContextInstr(Value* value) { | 
| ASSERT(value != NULL); | 
| inputs_[0] = value; | 
| } | 
| - DECLARE_COMPUTATION(StoreContext); | 
| + DECLARE_INSTRUCTION(StoreContext); | 
| + virtual RawAbstractType* CompileType() const; | 
| Value* value() const { return inputs_[0]; } | 
| @@ -1731,18 +1592,19 @@ class StoreContextComp : public TemplateComputation<1> { | 
| virtual intptr_t ResultCid() const { return kIllegalCid; } | 
| private: | 
| - DISALLOW_COPY_AND_ASSIGN(StoreContextComp); | 
| + DISALLOW_COPY_AND_ASSIGN(StoreContextInstr); | 
| }; | 
| -class ClosureCallComp : public TemplateComputation<0> { | 
| +class ClosureCallInstr : public TemplateDefinition<0> { | 
| public: | 
| - ClosureCallComp(ClosureCallNode* node, | 
| - ZoneGrowableArray<PushArgumentInstr*>* arguments) | 
| + ClosureCallInstr(ClosureCallNode* node, | 
| + ZoneGrowableArray<PushArgumentInstr*>* arguments) | 
| : ast_node_(*node), | 
| arguments_(arguments) { } | 
| - DECLARE_CALL_COMPUTATION(ClosureCall) | 
| + DECLARE_INSTRUCTION(ClosureCall) | 
| + virtual RawAbstractType* CompileType() const; | 
| const Array& argument_names() const { return ast_node_.arguments()->names(); } | 
| intptr_t token_pos() const { return ast_node_.token_pos(); } | 
| @@ -1761,18 +1623,18 @@ class ClosureCallComp : public TemplateComputation<0> { | 
| const ClosureCallNode& ast_node_; | 
| ZoneGrowableArray<PushArgumentInstr*>* arguments_; | 
| - DISALLOW_COPY_AND_ASSIGN(ClosureCallComp); | 
| + DISALLOW_COPY_AND_ASSIGN(ClosureCallInstr); | 
| }; | 
| -class InstanceCallComp : public TemplateComputation<0> { | 
| +class InstanceCallInstr : public TemplateDefinition<0> { | 
| public: | 
| - InstanceCallComp(intptr_t token_pos, | 
| - const String& function_name, | 
| - Token::Kind token_kind, | 
| - ZoneGrowableArray<PushArgumentInstr*>* arguments, | 
| - const Array& argument_names, | 
| - intptr_t checked_argument_count) | 
| + InstanceCallInstr(intptr_t token_pos, | 
| + const String& function_name, | 
| + Token::Kind token_kind, | 
| + ZoneGrowableArray<PushArgumentInstr*>* arguments, | 
| + const Array& argument_names, | 
| + intptr_t checked_argument_count) | 
| : ic_data_(Isolate::Current()->GetICDataForDeoptId(deopt_id())), | 
| token_pos_(token_pos), | 
| function_name_(function_name), | 
| @@ -1791,7 +1653,8 @@ class InstanceCallComp : public TemplateComputation<0> { | 
| token_kind == Token::kILLEGAL); | 
| } | 
| - DECLARE_CALL_COMPUTATION(InstanceCall) | 
| + DECLARE_INSTRUCTION(InstanceCall) | 
| + virtual RawAbstractType* CompileType() const; | 
| const ICData* ic_data() const { return ic_data_; } | 
| bool HasICData() const { | 
| @@ -1822,47 +1685,50 @@ class InstanceCallComp : public TemplateComputation<0> { | 
| const Array& argument_names_; | 
| const intptr_t checked_argument_count_; | 
| - DISALLOW_COPY_AND_ASSIGN(InstanceCallComp); | 
| + DISALLOW_COPY_AND_ASSIGN(InstanceCallInstr); | 
| }; | 
| -class PolymorphicInstanceCallComp : public TemplateComputation<0> { | 
| +class PolymorphicInstanceCallInstr : public TemplateDefinition<0> { | 
| public: | 
| - PolymorphicInstanceCallComp(InstanceCallComp* comp, | 
| - const ICData& ic_data, | 
| - bool with_checks) | 
| - : instance_call_(comp), ic_data_(ic_data), with_checks_(with_checks) { | 
| + PolymorphicInstanceCallInstr(InstanceCallInstr* instance_call, | 
| + const ICData& ic_data, | 
| + bool with_checks) | 
| + : instance_call_(instance_call), | 
| + ic_data_(ic_data), | 
| + with_checks_(with_checks) { | 
| ASSERT(instance_call_ != NULL); | 
| } | 
| - InstanceCallComp* instance_call() const { return instance_call_; } | 
| + InstanceCallInstr* instance_call() const { return instance_call_; } | 
| bool with_checks() const { return with_checks_; } | 
| - void PrintTo(BufferFormatter* f) const; | 
| - | 
| virtual intptr_t ArgumentCount() const { | 
| return instance_call()->ArgumentCount(); | 
| } | 
| - DECLARE_CALL_COMPUTATION(PolymorphicInstanceCall) | 
| + DECLARE_INSTRUCTION(PolymorphicInstanceCall) | 
| + virtual RawAbstractType* CompileType() const; | 
| const ICData& ic_data() const { return ic_data_; } | 
| virtual bool CanDeoptimize() const { return true; } | 
| virtual intptr_t ResultCid() const { return kDynamicCid; } | 
| + virtual void PrintTo(BufferFormatter* f) const; | 
| + | 
| private: | 
| - InstanceCallComp* instance_call_; | 
| + InstanceCallInstr* instance_call_; | 
| const ICData& ic_data_; | 
| const bool with_checks_; | 
| - DISALLOW_COPY_AND_ASSIGN(PolymorphicInstanceCallComp); | 
| + DISALLOW_COPY_AND_ASSIGN(PolymorphicInstanceCallInstr); | 
| }; | 
| -class ComparisonComp : public TemplateComputation<2> { | 
| +class ComparisonInstr : public TemplateDefinition<2> { | 
| public: | 
| - ComparisonComp(Token::Kind kind, Value* left, Value* right) : kind_(kind) { | 
| + ComparisonInstr(Token::Kind kind, Value* left, Value* right) : kind_(kind) { | 
| ASSERT(left != NULL); | 
| ASSERT(right != NULL); | 
| inputs_[0] = left; | 
| @@ -1872,10 +1738,13 @@ class ComparisonComp : public TemplateComputation<2> { | 
| Value* left() const { return inputs_[0]; } | 
| Value* right() const { return inputs_[1]; } | 
| - virtual ComparisonComp* AsComparison() { return this; } | 
| + virtual ComparisonInstr* AsComparison() { return this; } | 
| Token::Kind kind() const { return kind_; } | 
| + virtual void EmitBranchCode(FlowGraphCompiler* compiler, | 
| + BranchInstr* branch) = 0; | 
| + | 
| private: | 
| Token::Kind kind_; | 
| }; | 
| @@ -1883,66 +1752,67 @@ class ComparisonComp : public TemplateComputation<2> { | 
| // Inlined functions from class BranchInstr that forward to their comparison. | 
| inline intptr_t BranchInstr::ArgumentCount() const { | 
| - return computation()->ArgumentCount(); | 
| + return comparison()->ArgumentCount(); | 
| } | 
| inline intptr_t BranchInstr::InputCount() const { | 
| - return computation()->InputCount(); | 
| + return comparison()->InputCount(); | 
| } | 
| inline Value* BranchInstr::InputAt(intptr_t i) const { | 
| - return computation()->InputAt(i); | 
| + return comparison()->InputAt(i); | 
| } | 
| inline void BranchInstr::SetInputAt(intptr_t i, Value* value) { | 
| - computation()->SetInputAt(i, value); | 
| + comparison()->SetInputAt(i, value); | 
| } | 
| inline bool BranchInstr::CanDeoptimize() const { | 
| - return computation()->CanDeoptimize(); | 
| + return comparison()->CanDeoptimize(); | 
| } | 
| inline LocationSummary* BranchInstr::locs() { | 
| - if (computation_->locs_ == NULL) { | 
| - LocationSummary* summary = computation_->MakeLocationSummary(); | 
| + if (comparison()->locs_ == NULL) { | 
| + LocationSummary* summary = comparison()->MakeLocationSummary(); | 
| // Branches don't produce a result. | 
| summary->set_out(Location::NoLocation()); | 
| - computation_->locs_ = summary; | 
| + comparison()->locs_ = summary; | 
| } | 
| - return computation_->locs_; | 
| + return comparison()->locs_; | 
| } | 
| inline intptr_t BranchInstr::DeoptimizationTarget() const { | 
| - return computation_->DeoptimizationTarget(); | 
| + return comparison()->DeoptimizationTarget(); | 
| } | 
| inline Representation BranchInstr::RequiredInputRepresentation( | 
| intptr_t i) const { | 
| - return computation()->RequiredInputRepresentation(i); | 
| + return comparison()->RequiredInputRepresentation(i); | 
| } | 
| -class StrictCompareComp : public ComparisonComp { | 
| +class StrictCompareInstr : public ComparisonInstr { | 
| public: | 
| - StrictCompareComp(Token::Kind kind, Value* left, Value* right) | 
| - : ComparisonComp(kind, left, right) { | 
| + StrictCompareInstr(Token::Kind kind, Value* left, Value* right) | 
| + : ComparisonInstr(kind, left, right) { | 
| ASSERT((kind == Token::kEQ_STRICT) || (kind == Token::kNE_STRICT)); | 
| } | 
| - DECLARE_COMPUTATION(StrictCompare) | 
| + DECLARE_INSTRUCTION(StrictCompare) | 
| + virtual RawAbstractType* CompileType() const; | 
| virtual void PrintOperandsTo(BufferFormatter* f) const; | 
| virtual bool CanDeoptimize() const { return false; } | 
| - virtual Definition* TryReplace(BindInstr* instr) const; | 
| + virtual Definition* Canonicalize(); | 
| virtual intptr_t ResultCid() const { return kBoolCid; } | 
| @@ -1950,24 +1820,25 @@ class StrictCompareComp : public ComparisonComp { | 
| BranchInstr* branch); | 
| private: | 
| - DISALLOW_COPY_AND_ASSIGN(StrictCompareComp); | 
| + DISALLOW_COPY_AND_ASSIGN(StrictCompareInstr); | 
| }; | 
| -class EqualityCompareComp : public ComparisonComp { | 
| +class EqualityCompareInstr : public ComparisonInstr { | 
| public: | 
| - EqualityCompareComp(intptr_t token_pos, | 
| - Token::Kind kind, | 
| - Value* left, | 
| - Value* right) | 
| - : ComparisonComp(kind, left, right), | 
| + EqualityCompareInstr(intptr_t token_pos, | 
| + Token::Kind kind, | 
| + Value* left, | 
| + Value* right) | 
| + : ComparisonInstr(kind, left, right), | 
| ic_data_(Isolate::Current()->GetICDataForDeoptId(deopt_id())), | 
| token_pos_(token_pos), | 
| receiver_class_id_(kIllegalCid) { | 
| ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); | 
| } | 
| - DECLARE_COMPUTATION(EqualityCompare) | 
| + DECLARE_INSTRUCTION(EqualityCompare) | 
| + virtual RawAbstractType* CompileType() const; | 
| const ICData* ic_data() const { return ic_data_; } | 
| bool HasICData() const { | 
| @@ -2006,24 +1877,25 @@ class EqualityCompareComp : public ComparisonComp { | 
| const intptr_t token_pos_; | 
| intptr_t receiver_class_id_; // Set by optimizer. | 
| - DISALLOW_COPY_AND_ASSIGN(EqualityCompareComp); | 
| + DISALLOW_COPY_AND_ASSIGN(EqualityCompareInstr); | 
| }; | 
| -class RelationalOpComp : public ComparisonComp { | 
| +class RelationalOpInstr : public ComparisonInstr { | 
| public: | 
| - RelationalOpComp(intptr_t token_pos, | 
| - Token::Kind kind, | 
| - Value* left, | 
| - Value* right) | 
| - : ComparisonComp(kind, left, right), | 
| + RelationalOpInstr(intptr_t token_pos, | 
| + Token::Kind kind, | 
| + Value* left, | 
| + Value* right) | 
| + : ComparisonInstr(kind, left, right), | 
| ic_data_(Isolate::Current()->GetICDataForDeoptId(deopt_id())), | 
| token_pos_(token_pos), | 
| operands_class_id_(kIllegalCid) { | 
| ASSERT(Token::IsRelationalOperator(kind)); | 
| } | 
| - DECLARE_COMPUTATION(RelationalOp) | 
| + DECLARE_INSTRUCTION(RelationalOp) | 
| + virtual RawAbstractType* CompileType() const; | 
| const ICData* ic_data() const { return ic_data_; } | 
| bool HasICData() const { | 
| @@ -2067,16 +1939,16 @@ class RelationalOpComp : public ComparisonComp { | 
| const intptr_t token_pos_; | 
| intptr_t operands_class_id_; // class id of both operands. | 
| - DISALLOW_COPY_AND_ASSIGN(RelationalOpComp); | 
| + DISALLOW_COPY_AND_ASSIGN(RelationalOpInstr); | 
| }; | 
| -class StaticCallComp : public TemplateComputation<0> { | 
| +class StaticCallInstr : public TemplateDefinition<0> { | 
| public: | 
| - StaticCallComp(intptr_t token_pos, | 
| - const Function& function, | 
| - const Array& argument_names, | 
| - ZoneGrowableArray<PushArgumentInstr*>* arguments) | 
| + StaticCallInstr(intptr_t token_pos, | 
| + const Function& function, | 
| + const Array& argument_names, | 
| + ZoneGrowableArray<PushArgumentInstr*>* arguments) | 
| : token_pos_(token_pos), | 
| function_(function), | 
| argument_names_(argument_names), | 
| @@ -2086,7 +1958,8 @@ class StaticCallComp : public TemplateComputation<0> { | 
| ASSERT(argument_names.IsZoneHandle()); | 
| } | 
| - DECLARE_CALL_COMPUTATION(StaticCall) | 
| + DECLARE_INSTRUCTION(StaticCall) | 
| + virtual RawAbstractType* CompileType() const; | 
| // Accessors forwarded to the AST node. | 
| const Function& function() const { return function_; } | 
| @@ -2113,17 +1986,18 @@ class StaticCallComp : public TemplateComputation<0> { | 
| ZoneGrowableArray<PushArgumentInstr*>* arguments_; | 
| MethodRecognizer::Kind recognized_; | 
| - DISALLOW_COPY_AND_ASSIGN(StaticCallComp); | 
| + DISALLOW_COPY_AND_ASSIGN(StaticCallInstr); | 
| }; | 
| -class LoadLocalComp : public TemplateComputation<0> { | 
| +class LoadLocalInstr : public TemplateDefinition<0> { | 
| public: | 
| - LoadLocalComp(const LocalVariable& local, intptr_t context_level) | 
| + LoadLocalInstr(const LocalVariable& local, intptr_t context_level) | 
| : local_(local), | 
| context_level_(context_level) { } | 
| - DECLARE_COMPUTATION(LoadLocal) | 
| + DECLARE_INSTRUCTION(LoadLocal) | 
| + virtual RawAbstractType* CompileType() const; | 
| const LocalVariable& local() const { return local_; } | 
| intptr_t context_level() const { return context_level_; } | 
| @@ -2137,22 +2011,23 @@ class LoadLocalComp : public TemplateComputation<0> { | 
| const LocalVariable& local_; | 
| const intptr_t context_level_; | 
| - DISALLOW_COPY_AND_ASSIGN(LoadLocalComp); | 
| + DISALLOW_COPY_AND_ASSIGN(LoadLocalInstr); | 
| }; | 
| -class StoreLocalComp : public TemplateComputation<1> { | 
| +class StoreLocalInstr : public TemplateDefinition<1> { | 
| public: | 
| - StoreLocalComp(const LocalVariable& local, | 
| - Value* value, | 
| - intptr_t context_level) | 
| + StoreLocalInstr(const LocalVariable& local, | 
| + Value* value, | 
| + intptr_t context_level) | 
| : local_(local), | 
| context_level_(context_level) { | 
| ASSERT(value != NULL); | 
| inputs_[0] = value; | 
| } | 
| - DECLARE_COMPUTATION(StoreLocal) | 
| + DECLARE_INSTRUCTION(StoreLocal) | 
| + virtual RawAbstractType* CompileType() const; | 
| const LocalVariable& local() const { return local_; } | 
| Value* value() const { return inputs_[0]; } | 
| @@ -2170,16 +2045,17 @@ class StoreLocalComp : public TemplateComputation<1> { | 
| const LocalVariable& local_; | 
| const intptr_t context_level_; | 
| - DISALLOW_COPY_AND_ASSIGN(StoreLocalComp); | 
| + DISALLOW_COPY_AND_ASSIGN(StoreLocalInstr); | 
| }; | 
| -class NativeCallComp : public TemplateComputation<0> { | 
| +class NativeCallInstr : public TemplateDefinition<0> { | 
| public: | 
| - explicit NativeCallComp(NativeBodyNode* node) | 
| + explicit NativeCallInstr(NativeBodyNode* node) | 
| : ast_node_(*node) {} | 
| - DECLARE_COMPUTATION(NativeCall) | 
| + DECLARE_INSTRUCTION(NativeCall) | 
| + virtual RawAbstractType* CompileType() const; | 
| intptr_t token_pos() const { return ast_node_.token_pos(); } | 
| @@ -2209,18 +2085,19 @@ class NativeCallComp : public TemplateComputation<0> { | 
| private: | 
| const NativeBodyNode& ast_node_; | 
| - DISALLOW_COPY_AND_ASSIGN(NativeCallComp); | 
| + DISALLOW_COPY_AND_ASSIGN(NativeCallInstr); | 
| }; | 
| -class LoadInstanceFieldComp : public TemplateComputation<1> { | 
| +class LoadInstanceFieldInstr : public TemplateDefinition<1> { | 
| public: | 
| - LoadInstanceFieldComp(const Field& field, Value* instance) : field_(field) { | 
| + LoadInstanceFieldInstr(const Field& field, Value* instance) : field_(field) { | 
| ASSERT(instance != NULL); | 
| inputs_[0] = instance; | 
| } | 
| - DECLARE_COMPUTATION(LoadInstanceField) | 
| + DECLARE_INSTRUCTION(LoadInstanceField) | 
| + virtual RawAbstractType* CompileType() const; | 
| const Field& field() const { return field_; } | 
| Value* instance() const { return inputs_[0]; } | 
| @@ -2233,15 +2110,13 @@ class LoadInstanceFieldComp : public TemplateComputation<1> { | 
| private: | 
| const Field& field_; | 
| - DISALLOW_COPY_AND_ASSIGN(LoadInstanceFieldComp); | 
| + DISALLOW_COPY_AND_ASSIGN(LoadInstanceFieldInstr); | 
| }; | 
| -class StoreInstanceFieldComp : public TemplateComputation<2> { | 
| +class StoreInstanceFieldInstr : public TemplateDefinition<2> { | 
| public: | 
| - StoreInstanceFieldComp(const Field& field, | 
| - Value* instance, | 
| - Value* value) | 
| + StoreInstanceFieldInstr(const Field& field, Value* instance, Value* value) | 
| : field_(field) { | 
| ASSERT(instance != NULL); | 
| ASSERT(value != NULL); | 
| @@ -2249,7 +2124,8 @@ class StoreInstanceFieldComp : public TemplateComputation<2> { | 
| inputs_[1] = value; | 
| } | 
| - DECLARE_COMPUTATION(StoreInstanceField) | 
| + DECLARE_INSTRUCTION(StoreInstanceField) | 
| + virtual RawAbstractType* CompileType() const; | 
| const Field& field() const { return field_; } | 
| @@ -2264,15 +2140,16 @@ class StoreInstanceFieldComp : public TemplateComputation<2> { | 
| private: | 
| const Field& field_; | 
| - DISALLOW_COPY_AND_ASSIGN(StoreInstanceFieldComp); | 
| + DISALLOW_COPY_AND_ASSIGN(StoreInstanceFieldInstr); | 
| }; | 
| -class LoadStaticFieldComp : public TemplateComputation<0> { | 
| +class LoadStaticFieldInstr : public TemplateDefinition<0> { | 
| public: | 
| - explicit LoadStaticFieldComp(const Field& field) : field_(field) {} | 
| + explicit LoadStaticFieldInstr(const Field& field) : field_(field) {} | 
| - DECLARE_COMPUTATION(LoadStaticField); | 
| + DECLARE_INSTRUCTION(LoadStaticField); | 
| + virtual RawAbstractType* CompileType() const; | 
| const Field& field() const { return field_; } | 
| @@ -2284,20 +2161,21 @@ class LoadStaticFieldComp : public TemplateComputation<0> { | 
| private: | 
| const Field& field_; | 
| - DISALLOW_COPY_AND_ASSIGN(LoadStaticFieldComp); | 
| + DISALLOW_COPY_AND_ASSIGN(LoadStaticFieldInstr); | 
| }; | 
| -class StoreStaticFieldComp : public TemplateComputation<1> { | 
| +class StoreStaticFieldInstr : public TemplateDefinition<1> { | 
| public: | 
| - StoreStaticFieldComp(const Field& field, Value* value) | 
| + StoreStaticFieldInstr(const Field& field, Value* value) | 
| : field_(field) { | 
| ASSERT(field.IsZoneHandle()); | 
| ASSERT(value != NULL); | 
| inputs_[0] = value; | 
| } | 
| - DECLARE_COMPUTATION(StoreStaticField); | 
| + DECLARE_INSTRUCTION(StoreStaticField); | 
| + virtual RawAbstractType* CompileType() const; | 
| const Field& field() const { return field_; } | 
| Value* value() const { return inputs_[0]; } | 
| @@ -2310,15 +2188,13 @@ class StoreStaticFieldComp : public TemplateComputation<1> { | 
| private: | 
| const Field& field_; | 
| - DISALLOW_COPY_AND_ASSIGN(StoreStaticFieldComp); | 
| + DISALLOW_COPY_AND_ASSIGN(StoreStaticFieldInstr); | 
| }; | 
| -class LoadIndexedComp : public TemplateComputation<2> { | 
| +class LoadIndexedInstr : public TemplateDefinition<2> { | 
| public: | 
| - LoadIndexedComp(Value* array, | 
| - Value* index, | 
| - intptr_t receiver_type) | 
| + LoadIndexedInstr(Value* array, Value* index, intptr_t receiver_type) | 
| : receiver_type_(receiver_type) { | 
| ASSERT(array != NULL); | 
| ASSERT(index != NULL); | 
| @@ -2326,7 +2202,8 @@ class LoadIndexedComp : public TemplateComputation<2> { | 
| inputs_[1] = index; | 
| } | 
| - DECLARE_COMPUTATION(LoadIndexed) | 
| + DECLARE_INSTRUCTION(LoadIndexed) | 
| + virtual RawAbstractType* CompileType() const; | 
| Value* array() const { return inputs_[0]; } | 
| Value* index() const { return inputs_[1]; } | 
| @@ -2339,16 +2216,16 @@ class LoadIndexedComp : public TemplateComputation<2> { | 
| private: | 
| intptr_t receiver_type_; | 
| - DISALLOW_COPY_AND_ASSIGN(LoadIndexedComp); | 
| + DISALLOW_COPY_AND_ASSIGN(LoadIndexedInstr); | 
| }; | 
| -class StoreIndexedComp : public TemplateComputation<3> { | 
| +class StoreIndexedInstr : public TemplateDefinition<3> { | 
| public: | 
| - StoreIndexedComp(Value* array, | 
| - Value* index, | 
| - Value* value, | 
| - intptr_t receiver_type) | 
| + StoreIndexedInstr(Value* array, | 
| + Value* index, | 
| + Value* value, | 
| + intptr_t receiver_type) | 
| : receiver_type_(receiver_type) { | 
| ASSERT(array != NULL); | 
| ASSERT(index != NULL); | 
| @@ -2358,7 +2235,8 @@ class StoreIndexedComp : public TemplateComputation<3> { | 
| inputs_[2] = value; | 
| } | 
| - DECLARE_COMPUTATION(StoreIndexed) | 
| + DECLARE_INSTRUCTION(StoreIndexed) | 
| + virtual RawAbstractType* CompileType() const; | 
| Value* array() const { return inputs_[0]; } | 
| Value* index() const { return inputs_[1]; } | 
| @@ -2372,19 +2250,20 @@ class StoreIndexedComp : public TemplateComputation<3> { | 
| private: | 
| intptr_t receiver_type_; | 
| - DISALLOW_COPY_AND_ASSIGN(StoreIndexedComp); | 
| + DISALLOW_COPY_AND_ASSIGN(StoreIndexedInstr); | 
| }; | 
| // Note overrideable, built-in: value? false : true. | 
| -class BooleanNegateComp : public TemplateComputation<1> { | 
| +class BooleanNegateInstr : public TemplateDefinition<1> { | 
| public: | 
| - explicit BooleanNegateComp(Value* value) { | 
| + explicit BooleanNegateInstr(Value* value) { | 
| ASSERT(value != NULL); | 
| inputs_[0] = value; | 
| } | 
| - DECLARE_COMPUTATION(BooleanNegate) | 
| + DECLARE_INSTRUCTION(BooleanNegate) | 
| + virtual RawAbstractType* CompileType() const; | 
| Value* value() const { return inputs_[0]; } | 
| @@ -2392,18 +2271,18 @@ class BooleanNegateComp : public TemplateComputation<1> { | 
| virtual intptr_t ResultCid() const { return kBoolCid; } | 
| private: | 
| - DISALLOW_COPY_AND_ASSIGN(BooleanNegateComp); | 
| + DISALLOW_COPY_AND_ASSIGN(BooleanNegateInstr); | 
| }; | 
| -class InstanceOfComp : public TemplateComputation<3> { | 
| +class InstanceOfInstr : public TemplateDefinition<3> { | 
| public: | 
| - InstanceOfComp(intptr_t token_pos, | 
| - Value* value, | 
| - Value* instantiator, | 
| - Value* instantiator_type_arguments, | 
| - const AbstractType& type, | 
| - bool negate_result) | 
| + InstanceOfInstr(intptr_t token_pos, | 
| + Value* value, | 
| + Value* instantiator, | 
| + Value* instantiator_type_arguments, | 
| + const AbstractType& type, | 
| + bool negate_result) | 
| : token_pos_(token_pos), | 
| type_(type), | 
| negate_result_(negate_result) { | 
| @@ -2416,7 +2295,8 @@ class InstanceOfComp : public TemplateComputation<3> { | 
| inputs_[2] = instantiator_type_arguments; | 
| } | 
| - DECLARE_COMPUTATION(InstanceOf) | 
| + DECLARE_INSTRUCTION(InstanceOf) | 
| + virtual RawAbstractType* CompileType() const; | 
| Value* value() const { return inputs_[0]; } | 
| Value* instantiator() const { return inputs_[1]; } | 
| @@ -2439,20 +2319,21 @@ class InstanceOfComp : public TemplateComputation<3> { | 
| const AbstractType& type_; | 
| const bool negate_result_; | 
| - DISALLOW_COPY_AND_ASSIGN(InstanceOfComp); | 
| + DISALLOW_COPY_AND_ASSIGN(InstanceOfInstr); | 
| }; | 
| -class AllocateObjectComp : public TemplateComputation<0> { | 
| +class AllocateObjectInstr : public TemplateDefinition<0> { | 
| public: | 
| - AllocateObjectComp(ConstructorCallNode* node, | 
| - ZoneGrowableArray<PushArgumentInstr*>* arguments) | 
| + AllocateObjectInstr(ConstructorCallNode* node, | 
| + ZoneGrowableArray<PushArgumentInstr*>* arguments) | 
| : ast_node_(*node), arguments_(arguments) { | 
| // Either no arguments or one type-argument and one instantiator. | 
| ASSERT(arguments->is_empty() || (arguments->length() == 2)); | 
| } | 
| - DECLARE_CALL_COMPUTATION(AllocateObject) | 
| + DECLARE_INSTRUCTION(AllocateObject) | 
| + virtual RawAbstractType* CompileType() const; | 
| virtual intptr_t ArgumentCount() const { return arguments_->length(); } | 
| PushArgumentInstr* ArgumentAt(intptr_t index) const { | 
| @@ -2471,15 +2352,15 @@ class AllocateObjectComp : public TemplateComputation<0> { | 
| const ConstructorCallNode& ast_node_; | 
| ZoneGrowableArray<PushArgumentInstr*>* const arguments_; | 
| - DISALLOW_COPY_AND_ASSIGN(AllocateObjectComp); | 
| + DISALLOW_COPY_AND_ASSIGN(AllocateObjectInstr); | 
| }; | 
| -class AllocateObjectWithBoundsCheckComp : public TemplateComputation<2> { | 
| +class AllocateObjectWithBoundsCheckInstr : public TemplateDefinition<2> { | 
| public: | 
| - AllocateObjectWithBoundsCheckComp(ConstructorCallNode* node, | 
| - Value* type_arguments, | 
| - Value* instantiator) | 
| + AllocateObjectWithBoundsCheckInstr(ConstructorCallNode* node, | 
| + Value* type_arguments, | 
| + Value* instantiator) | 
| : ast_node_(*node) { | 
| ASSERT(type_arguments != NULL); | 
| ASSERT(instantiator != NULL); | 
| @@ -2487,7 +2368,8 @@ class AllocateObjectWithBoundsCheckComp : public TemplateComputation<2> { | 
| inputs_[1] = instantiator; | 
| } | 
| - DECLARE_COMPUTATION(AllocateObjectWithBoundsCheck) | 
| + DECLARE_INSTRUCTION(AllocateObjectWithBoundsCheck) | 
| + virtual RawAbstractType* CompileType() const; | 
| const Function& constructor() const { return ast_node_.constructor(); } | 
| intptr_t token_pos() const { return ast_node_.token_pos(); } | 
| @@ -2500,16 +2382,16 @@ class AllocateObjectWithBoundsCheckComp : public TemplateComputation<2> { | 
| private: | 
| const ConstructorCallNode& ast_node_; | 
| - DISALLOW_COPY_AND_ASSIGN(AllocateObjectWithBoundsCheckComp); | 
| + DISALLOW_COPY_AND_ASSIGN(AllocateObjectWithBoundsCheckInstr); | 
| }; | 
| -class CreateArrayComp : public TemplateComputation<1> { | 
| +class CreateArrayInstr : public TemplateDefinition<1> { | 
| public: | 
| - CreateArrayComp(intptr_t token_pos, | 
| - ZoneGrowableArray<PushArgumentInstr*>* arguments, | 
| - const AbstractType& type, | 
| - Value* element_type) | 
| + CreateArrayInstr(intptr_t token_pos, | 
| + ZoneGrowableArray<PushArgumentInstr*>* arguments, | 
| + const AbstractType& type, | 
| + Value* element_type) | 
| : token_pos_(token_pos), | 
| arguments_(arguments), | 
| type_(type) { | 
| @@ -2525,7 +2407,8 @@ class CreateArrayComp : public TemplateComputation<1> { | 
| inputs_[0] = element_type; | 
| } | 
| - DECLARE_CALL_COMPUTATION(CreateArray) | 
| + DECLARE_INSTRUCTION(CreateArray) | 
| + virtual RawAbstractType* CompileType() const; | 
| virtual intptr_t ArgumentCount() const { return arguments_->length(); } | 
| @@ -2544,18 +2427,19 @@ class CreateArrayComp : public TemplateComputation<1> { | 
| ZoneGrowableArray<PushArgumentInstr*>* const arguments_; | 
| const AbstractType& type_; | 
| - DISALLOW_COPY_AND_ASSIGN(CreateArrayComp); | 
| + DISALLOW_COPY_AND_ASSIGN(CreateArrayInstr); | 
| }; | 
| -class CreateClosureComp : public TemplateComputation<0> { | 
| +class CreateClosureInstr : public TemplateDefinition<0> { | 
| public: | 
| - CreateClosureComp(ClosureNode* node, | 
| - ZoneGrowableArray<PushArgumentInstr*>* arguments) | 
| + CreateClosureInstr(ClosureNode* node, | 
| + ZoneGrowableArray<PushArgumentInstr*>* arguments) | 
| : ast_node_(*node), | 
| arguments_(arguments) { } | 
| - DECLARE_CALL_COMPUTATION(CreateClosure) | 
| + DECLARE_INSTRUCTION(CreateClosure) | 
| + virtual RawAbstractType* CompileType() const; | 
| intptr_t token_pos() const { return ast_node_.token_pos(); } | 
| const Function& function() const { return ast_node_.function(); } | 
| @@ -2574,15 +2458,15 @@ class CreateClosureComp : public TemplateComputation<0> { | 
| const ClosureNode& ast_node_; | 
| ZoneGrowableArray<PushArgumentInstr*>* arguments_; | 
| - DISALLOW_COPY_AND_ASSIGN(CreateClosureComp); | 
| + DISALLOW_COPY_AND_ASSIGN(CreateClosureInstr); | 
| }; | 
| -class LoadVMFieldComp : public TemplateComputation<1> { | 
| +class LoadVMFieldInstr : public TemplateDefinition<1> { | 
| public: | 
| - LoadVMFieldComp(Value* value, | 
| - intptr_t offset_in_bytes, | 
| - const AbstractType& type) | 
| + LoadVMFieldInstr(Value* value, | 
| + intptr_t offset_in_bytes, | 
| + const AbstractType& type) | 
| : offset_in_bytes_(offset_in_bytes), | 
| type_(type), | 
| result_cid_(kDynamicCid) { | 
| @@ -2591,7 +2475,8 @@ class LoadVMFieldComp : public TemplateComputation<1> { | 
| inputs_[0] = value; | 
| } | 
| - DECLARE_COMPUTATION(LoadVMField) | 
| + DECLARE_INSTRUCTION(LoadVMField) | 
| + virtual RawAbstractType* CompileType() const; | 
| Value* value() const { return inputs_[0]; } | 
| intptr_t offset_in_bytes() const { return offset_in_bytes_; } | 
| @@ -2608,16 +2493,16 @@ class LoadVMFieldComp : public TemplateComputation<1> { | 
| const AbstractType& type_; | 
| intptr_t result_cid_; | 
| - DISALLOW_COPY_AND_ASSIGN(LoadVMFieldComp); | 
| + DISALLOW_COPY_AND_ASSIGN(LoadVMFieldInstr); | 
| }; | 
| -class StoreVMFieldComp : public TemplateComputation<2> { | 
| +class StoreVMFieldInstr : public TemplateDefinition<2> { | 
| public: | 
| - StoreVMFieldComp(Value* dest, | 
| - intptr_t offset_in_bytes, | 
| - Value* value, | 
| - const AbstractType& type) | 
| + StoreVMFieldInstr(Value* dest, | 
| + intptr_t offset_in_bytes, | 
| + Value* value, | 
| + const AbstractType& type) | 
| : offset_in_bytes_(offset_in_bytes), type_(type) { | 
| ASSERT(value != NULL); | 
| ASSERT(dest != NULL); | 
| @@ -2626,7 +2511,8 @@ class StoreVMFieldComp : public TemplateComputation<2> { | 
| inputs_[1] = dest; | 
| } | 
| - DECLARE_COMPUTATION(StoreVMField) | 
| + DECLARE_INSTRUCTION(StoreVMField) | 
| + virtual RawAbstractType* CompileType() const; | 
| Value* value() const { return inputs_[0]; } | 
| Value* dest() const { return inputs_[1]; } | 
| @@ -2642,15 +2528,15 @@ class StoreVMFieldComp : public TemplateComputation<2> { | 
| const intptr_t offset_in_bytes_; | 
| const AbstractType& type_; | 
| - DISALLOW_COPY_AND_ASSIGN(StoreVMFieldComp); | 
| + DISALLOW_COPY_AND_ASSIGN(StoreVMFieldInstr); | 
| }; | 
| -class InstantiateTypeArgumentsComp : public TemplateComputation<1> { | 
| +class InstantiateTypeArgumentsInstr : public TemplateDefinition<1> { | 
| public: | 
| - InstantiateTypeArgumentsComp(intptr_t token_pos, | 
| - const AbstractTypeArguments& type_arguments, | 
| - Value* instantiator) | 
| + InstantiateTypeArgumentsInstr(intptr_t token_pos, | 
| + const AbstractTypeArguments& type_arguments, | 
| + Value* instantiator) | 
| : token_pos_(token_pos), | 
| type_arguments_(type_arguments) { | 
| ASSERT(type_arguments.IsZoneHandle()); | 
| @@ -2658,7 +2544,8 @@ class InstantiateTypeArgumentsComp : public TemplateComputation<1> { | 
| inputs_[0] = instantiator; | 
| } | 
| - DECLARE_COMPUTATION(InstantiateTypeArguments) | 
| + DECLARE_INSTRUCTION(InstantiateTypeArguments) | 
| + virtual RawAbstractType* CompileType() const; | 
| Value* instantiator() const { return inputs_[0]; } | 
| const AbstractTypeArguments& type_arguments() const { | 
| @@ -2675,13 +2562,13 @@ class InstantiateTypeArgumentsComp : public TemplateComputation<1> { | 
| const intptr_t token_pos_; | 
| const AbstractTypeArguments& type_arguments_; | 
| - DISALLOW_COPY_AND_ASSIGN(InstantiateTypeArgumentsComp); | 
| + DISALLOW_COPY_AND_ASSIGN(InstantiateTypeArgumentsInstr); | 
| }; | 
| -class ExtractConstructorTypeArgumentsComp : public TemplateComputation<1> { | 
| +class ExtractConstructorTypeArgumentsInstr : public TemplateDefinition<1> { | 
| public: | 
| - ExtractConstructorTypeArgumentsComp( | 
| + ExtractConstructorTypeArgumentsInstr( | 
| intptr_t token_pos, | 
| const AbstractTypeArguments& type_arguments, | 
| Value* instantiator) | 
| @@ -2691,7 +2578,8 @@ class ExtractConstructorTypeArgumentsComp : public TemplateComputation<1> { | 
| inputs_[0] = instantiator; | 
| } | 
| - DECLARE_COMPUTATION(ExtractConstructorTypeArguments) | 
| + DECLARE_INSTRUCTION(ExtractConstructorTypeArguments) | 
| + virtual RawAbstractType* CompileType() const; | 
| Value* instantiator() const { return inputs_[0]; } | 
| const AbstractTypeArguments& type_arguments() const { | 
| @@ -2708,20 +2596,21 @@ class ExtractConstructorTypeArgumentsComp : public TemplateComputation<1> { | 
| const intptr_t token_pos_; | 
| const AbstractTypeArguments& type_arguments_; | 
| - DISALLOW_COPY_AND_ASSIGN(ExtractConstructorTypeArgumentsComp); | 
| + DISALLOW_COPY_AND_ASSIGN(ExtractConstructorTypeArgumentsInstr); | 
| }; | 
| -class ExtractConstructorInstantiatorComp : public TemplateComputation<1> { | 
| +class ExtractConstructorInstantiatorInstr : public TemplateDefinition<1> { | 
| public: | 
| - ExtractConstructorInstantiatorComp(ConstructorCallNode* ast_node, | 
| - Value* instantiator) | 
| + ExtractConstructorInstantiatorInstr(ConstructorCallNode* ast_node, | 
| + Value* instantiator) | 
| : ast_node_(*ast_node) { | 
| ASSERT(instantiator != NULL); | 
| inputs_[0] = instantiator; | 
| } | 
| - DECLARE_COMPUTATION(ExtractConstructorInstantiator) | 
| + DECLARE_INSTRUCTION(ExtractConstructorInstantiator) | 
| + virtual RawAbstractType* CompileType() const; | 
| Value* instantiator() const { return inputs_[0]; } | 
| const AbstractTypeArguments& type_arguments() const { | 
| @@ -2736,18 +2625,19 @@ class ExtractConstructorInstantiatorComp : public TemplateComputation<1> { | 
| private: | 
| const ConstructorCallNode& ast_node_; | 
| - DISALLOW_COPY_AND_ASSIGN(ExtractConstructorInstantiatorComp); | 
| + DISALLOW_COPY_AND_ASSIGN(ExtractConstructorInstantiatorInstr); | 
| }; | 
| -class AllocateContextComp : public TemplateComputation<0> { | 
| +class AllocateContextInstr : public TemplateDefinition<0> { | 
| public: | 
| - AllocateContextComp(intptr_t token_pos, | 
| - intptr_t num_context_variables) | 
| + AllocateContextInstr(intptr_t token_pos, | 
| + intptr_t num_context_variables) | 
| : token_pos_(token_pos), | 
| num_context_variables_(num_context_variables) {} | 
| - DECLARE_COMPUTATION(AllocateContext); | 
| + DECLARE_INSTRUCTION(AllocateContext); | 
| + virtual RawAbstractType* CompileType() const; | 
| intptr_t token_pos() const { return token_pos_; } | 
| intptr_t num_context_variables() const { return num_context_variables_; } | 
| @@ -2761,18 +2651,19 @@ class AllocateContextComp : public TemplateComputation<0> { | 
| const intptr_t token_pos_; | 
| const intptr_t num_context_variables_; | 
| - DISALLOW_COPY_AND_ASSIGN(AllocateContextComp); | 
| + DISALLOW_COPY_AND_ASSIGN(AllocateContextInstr); | 
| }; | 
| -class ChainContextComp : public TemplateComputation<1> { | 
| +class ChainContextInstr : public TemplateDefinition<1> { | 
| public: | 
| - explicit ChainContextComp(Value* context_value) { | 
| + explicit ChainContextInstr(Value* context_value) { | 
| ASSERT(context_value != NULL); | 
| inputs_[0] = context_value; | 
| } | 
| - DECLARE_COMPUTATION(ChainContext) | 
| + DECLARE_INSTRUCTION(ChainContext) | 
| + virtual RawAbstractType* CompileType() const; | 
| Value* context_value() const { return inputs_[0]; } | 
| @@ -2780,14 +2671,13 @@ class ChainContextComp : public TemplateComputation<1> { | 
| virtual intptr_t ResultCid() const { return kIllegalCid; } | 
| private: | 
| - DISALLOW_COPY_AND_ASSIGN(ChainContextComp); | 
| + DISALLOW_COPY_AND_ASSIGN(ChainContextInstr); | 
| }; | 
| -class CloneContextComp : public TemplateComputation<1> { | 
| +class CloneContextInstr : public TemplateDefinition<1> { | 
| public: | 
| - CloneContextComp(intptr_t token_pos, | 
| - Value* context_value) | 
| + CloneContextInstr(intptr_t token_pos, Value* context_value) | 
| : token_pos_(token_pos) { | 
| ASSERT(context_value != NULL); | 
| inputs_[0] = context_value; | 
| @@ -2796,7 +2686,8 @@ class CloneContextComp : public TemplateComputation<1> { | 
| intptr_t token_pos() const { return token_pos_; } | 
| Value* context_value() const { return inputs_[0]; } | 
| - DECLARE_COMPUTATION(CloneContext) | 
| + DECLARE_INSTRUCTION(CloneContext) | 
| + virtual RawAbstractType* CompileType() const; | 
| virtual bool CanDeoptimize() const { return false; } | 
| virtual intptr_t ResultCid() const { return kIllegalCid; } | 
| @@ -2804,20 +2695,21 @@ class CloneContextComp : public TemplateComputation<1> { | 
| private: | 
| const intptr_t token_pos_; | 
| - DISALLOW_COPY_AND_ASSIGN(CloneContextComp); | 
| + DISALLOW_COPY_AND_ASSIGN(CloneContextInstr); | 
| }; | 
| -class CatchEntryComp : public TemplateComputation<0> { | 
| +class CatchEntryInstr : public TemplateDefinition<0> { | 
| public: | 
| - CatchEntryComp(const LocalVariable& exception_var, | 
| - const LocalVariable& stacktrace_var) | 
| + CatchEntryInstr(const LocalVariable& exception_var, | 
| + const LocalVariable& stacktrace_var) | 
| : exception_var_(exception_var), stacktrace_var_(stacktrace_var) {} | 
| const LocalVariable& exception_var() const { return exception_var_; } | 
| const LocalVariable& stacktrace_var() const { return stacktrace_var_; } | 
| - DECLARE_COMPUTATION(CatchEntry) | 
| + DECLARE_INSTRUCTION(CatchEntry) | 
| + virtual RawAbstractType* CompileType() const; | 
| virtual void PrintOperandsTo(BufferFormatter* f) const; | 
| @@ -2828,28 +2720,29 @@ class CatchEntryComp : public TemplateComputation<0> { | 
| const LocalVariable& exception_var_; | 
| const LocalVariable& stacktrace_var_; | 
| - DISALLOW_COPY_AND_ASSIGN(CatchEntryComp); | 
| + DISALLOW_COPY_AND_ASSIGN(CatchEntryInstr); | 
| }; | 
| -class CheckEitherNonSmiComp : public TemplateComputation<2> { | 
| +class CheckEitherNonSmiInstr : public TemplateDefinition<2> { | 
| public: | 
| - CheckEitherNonSmiComp(Value* left, | 
| - Value* right, | 
| - InstanceCallComp* instance_call) | 
| - : instance_call_(instance_call) { | 
| + CheckEitherNonSmiInstr(Value* left, | 
| + Value* right, | 
| + InstanceCallInstr* instance_call) { | 
| ASSERT(left != NULL); | 
| ASSERT(right != NULL); | 
| inputs_[0] = left; | 
| inputs_[1] = right; | 
| + deopt_id_ = instance_call->deopt_id(); | 
| } | 
| - DECLARE_COMPUTATION(CheckEitherNonSmi) | 
| + DECLARE_INSTRUCTION(CheckEitherNonSmi) | 
| + virtual RawAbstractType* CompileType() const; | 
| virtual bool CanDeoptimize() const { return true; } | 
| virtual intptr_t ResultCid() const { return kIllegalCid; } | 
| - virtual bool AttributesEqual(Computation* other) const { return true; } | 
| + virtual bool AttributesEqual(Definition* other) const { return true; } | 
| virtual bool HasSideEffect() const { return false; } | 
| @@ -2857,18 +2750,16 @@ class CheckEitherNonSmiComp : public TemplateComputation<2> { | 
| Value* right() const { return inputs_[1]; } | 
| - virtual Definition* TryReplace(BindInstr* instr) const; | 
| + virtual Definition* Canonicalize(); | 
| private: | 
| - InstanceCallComp* instance_call_; | 
| - | 
| - DISALLOW_COPY_AND_ASSIGN(CheckEitherNonSmiComp); | 
| + DISALLOW_COPY_AND_ASSIGN(CheckEitherNonSmiInstr); | 
| }; | 
| -class BoxDoubleComp : public TemplateComputation<1> { | 
| +class BoxDoubleInstr : public TemplateDefinition<1> { | 
| public: | 
| - BoxDoubleComp(Value* value, InstanceCallComp* instance_call) | 
| + BoxDoubleInstr(Value* value, InstanceCallInstr* instance_call) | 
| : token_pos_((instance_call != NULL) ? instance_call->token_pos() : 0) { | 
| ASSERT(value != NULL); | 
| inputs_[0] = value; | 
| @@ -2880,7 +2771,7 @@ class BoxDoubleComp : public TemplateComputation<1> { | 
| virtual bool CanDeoptimize() const { return false; } | 
| virtual bool HasSideEffect() const { return false; } | 
| - virtual bool AttributesEqual(Computation* other) const { return true; } | 
| + virtual bool AttributesEqual(Definition* other) const { return true; } | 
| virtual intptr_t ResultCid() const; | 
| @@ -2889,21 +2780,22 @@ class BoxDoubleComp : public TemplateComputation<1> { | 
| return kUnboxedDouble; | 
| } | 
| - DECLARE_COMPUTATION(BoxDouble) | 
| + DECLARE_INSTRUCTION(BoxDouble) | 
| + virtual RawAbstractType* CompileType() const; | 
| private: | 
| const intptr_t token_pos_; | 
| - DISALLOW_COPY_AND_ASSIGN(BoxDoubleComp); | 
| + DISALLOW_COPY_AND_ASSIGN(BoxDoubleInstr); | 
| }; | 
| -class UnboxDoubleComp : public TemplateComputation<1> { | 
| +class UnboxDoubleInstr : public TemplateDefinition<1> { | 
| public: | 
| - UnboxDoubleComp(Value* value, intptr_t deopt_id) | 
| - : deopt_id_(deopt_id) { | 
| + UnboxDoubleInstr(Value* value, intptr_t deopt_id) { | 
| ASSERT(value != NULL); | 
| inputs_[0] = value; | 
| + deopt_id_ = deopt_id; | 
| } | 
| Value* value() const { return inputs_[0]; } | 
| @@ -2920,28 +2812,28 @@ class UnboxDoubleComp : public TemplateComputation<1> { | 
| } | 
| virtual bool HasSideEffect() const { return false; } | 
| - virtual bool AttributesEqual(Computation* other) const { return true; } | 
| + virtual bool AttributesEqual(Definition* other) const { return true; } | 
| - DECLARE_COMPUTATION(UnboxDouble) | 
| + DECLARE_INSTRUCTION(UnboxDouble) | 
| + virtual RawAbstractType* CompileType() const; | 
| private: | 
| - const intptr_t deopt_id_; | 
| - | 
| - DISALLOW_COPY_AND_ASSIGN(UnboxDoubleComp); | 
| + DISALLOW_COPY_AND_ASSIGN(UnboxDoubleInstr); | 
| }; | 
| -class UnboxedDoubleBinaryOpComp : public TemplateComputation<2> { | 
| +class UnboxedDoubleBinaryOpInstr : public TemplateDefinition<2> { | 
| public: | 
| - UnboxedDoubleBinaryOpComp(Token::Kind op_kind, | 
| - Value* left, | 
| - Value* right, | 
| - InstanceCallComp* call) | 
| - : op_kind_(op_kind), deopt_id_(call->deopt_id()) { | 
| + UnboxedDoubleBinaryOpInstr(Token::Kind op_kind, | 
| + Value* left, | 
| + Value* right, | 
| + InstanceCallInstr* instance_call) | 
| + : op_kind_(op_kind) { | 
| ASSERT(left != NULL); | 
| ASSERT(right != NULL); | 
| inputs_[0] = left; | 
| inputs_[1] = right; | 
| + deopt_id_ = instance_call->deopt_id(); | 
| } | 
| Value* left() const { return inputs_[0]; } | 
| @@ -2954,7 +2846,7 @@ class UnboxedDoubleBinaryOpComp : public TemplateComputation<2> { | 
| virtual bool CanDeoptimize() const { return false; } | 
| virtual bool HasSideEffect() const { return false; } | 
| - virtual bool AttributesEqual(Computation* other) const { | 
| + virtual bool AttributesEqual(Definition* other) const { | 
| return op_kind() == other->AsUnboxedDoubleBinaryOp()->op_kind(); | 
| } | 
| @@ -2971,25 +2863,25 @@ class UnboxedDoubleBinaryOpComp : public TemplateComputation<2> { | 
| } | 
| virtual intptr_t DeoptimizationTarget() const { | 
| - return deopt_id_; | 
| + return deopt_id(); | 
| } | 
| - DECLARE_COMPUTATION(UnboxedDoubleBinaryOp) | 
| + DECLARE_INSTRUCTION(UnboxedDoubleBinaryOp) | 
| + virtual RawAbstractType* CompileType() const; | 
| private: | 
| const Token::Kind op_kind_; | 
| - const intptr_t deopt_id_; | 
| - DISALLOW_COPY_AND_ASSIGN(UnboxedDoubleBinaryOpComp); | 
| + DISALLOW_COPY_AND_ASSIGN(UnboxedDoubleBinaryOpInstr); | 
| }; | 
| -class BinarySmiOpComp : public TemplateComputation<2> { | 
| +class BinarySmiOpInstr : public TemplateDefinition<2> { | 
| public: | 
| - BinarySmiOpComp(Token::Kind op_kind, | 
| - InstanceCallComp* instance_call, | 
| - Value* left, | 
| - Value* right) | 
| + BinarySmiOpInstr(Token::Kind op_kind, | 
| + InstanceCallInstr* instance_call, | 
| + Value* left, | 
| + Value* right) | 
| : op_kind_(op_kind), | 
| instance_call_(instance_call) { | 
| ASSERT(left != NULL); | 
| @@ -3003,13 +2895,14 @@ class BinarySmiOpComp : public TemplateComputation<2> { | 
| Token::Kind op_kind() const { return op_kind_; } | 
| - InstanceCallComp* instance_call() const { return instance_call_; } | 
| + InstanceCallInstr* instance_call() const { return instance_call_; } | 
| const ICData* ic_data() const { return instance_call()->ic_data(); } | 
| virtual void PrintOperandsTo(BufferFormatter* f) const; | 
| - DECLARE_COMPUTATION(BinarySmiOp) | 
| + DECLARE_INSTRUCTION(BinarySmiOp) | 
| + virtual RawAbstractType* CompileType() const; | 
| virtual bool CanDeoptimize() const; | 
| @@ -3017,18 +2910,18 @@ class BinarySmiOpComp : public TemplateComputation<2> { | 
| private: | 
| const Token::Kind op_kind_; | 
| - InstanceCallComp* instance_call_; | 
| + InstanceCallInstr* instance_call_; | 
| - DISALLOW_COPY_AND_ASSIGN(BinarySmiOpComp); | 
| + DISALLOW_COPY_AND_ASSIGN(BinarySmiOpInstr); | 
| }; | 
| -class BinaryMintOpComp : public TemplateComputation<2> { | 
| +class BinaryMintOpInstr : public TemplateDefinition<2> { | 
| public: | 
| - BinaryMintOpComp(Token::Kind op_kind, | 
| - InstanceCallComp* instance_call, | 
| - Value* left, | 
| - Value* right) | 
| + BinaryMintOpInstr(Token::Kind op_kind, | 
| + InstanceCallInstr* instance_call, | 
| + Value* left, | 
| + Value* right) | 
| : op_kind_(op_kind), | 
| instance_call_(instance_call) { | 
| ASSERT(left != NULL); | 
| @@ -3042,31 +2935,32 @@ class BinaryMintOpComp : public TemplateComputation<2> { | 
| Token::Kind op_kind() const { return op_kind_; } | 
| - InstanceCallComp* instance_call() const { return instance_call_; } | 
| + InstanceCallInstr* instance_call() const { return instance_call_; } | 
| const ICData* ic_data() const { return instance_call()->ic_data(); } | 
| virtual void PrintOperandsTo(BufferFormatter* f) const; | 
| - DECLARE_COMPUTATION(BinaryMintOp) | 
| + DECLARE_INSTRUCTION(BinaryMintOp) | 
| + virtual RawAbstractType* CompileType() const; | 
| virtual bool CanDeoptimize() const { return true; } | 
| virtual intptr_t ResultCid() const; | 
| private: | 
| const Token::Kind op_kind_; | 
| - InstanceCallComp* instance_call_; | 
| + InstanceCallInstr* instance_call_; | 
| - DISALLOW_COPY_AND_ASSIGN(BinaryMintOpComp); | 
| + DISALLOW_COPY_AND_ASSIGN(BinaryMintOpInstr); | 
| }; | 
| // Handles both Smi operations: BIT_OR and NEGATE. | 
| -class UnarySmiOpComp : public TemplateComputation<1> { | 
| +class UnarySmiOpInstr : public TemplateDefinition<1> { | 
| public: | 
| - UnarySmiOpComp(Token::Kind op_kind, | 
| - InstanceCallComp* instance_call, | 
| - Value* value) | 
| + UnarySmiOpInstr(Token::Kind op_kind, | 
| + InstanceCallInstr* instance_call, | 
| + Value* value) | 
| : op_kind_(op_kind), instance_call_(instance_call) { | 
| ASSERT((op_kind == Token::kNEGATE) || (op_kind == Token::kBIT_NOT)); | 
| ASSERT(value != NULL); | 
| @@ -3076,58 +2970,61 @@ class UnarySmiOpComp : public TemplateComputation<1> { | 
| Value* value() const { return inputs_[0]; } | 
| Token::Kind op_kind() const { return op_kind_; } | 
| - InstanceCallComp* instance_call() const { return instance_call_; } | 
| + InstanceCallInstr* instance_call() const { return instance_call_; } | 
| virtual void PrintOperandsTo(BufferFormatter* f) const; | 
| - DECLARE_COMPUTATION(UnarySmiOp) | 
| + DECLARE_INSTRUCTION(UnarySmiOp) | 
| + virtual RawAbstractType* CompileType() const; | 
| virtual bool CanDeoptimize() const { return op_kind() == Token::kNEGATE; } | 
| virtual intptr_t ResultCid() const { return kSmiCid; } | 
| private: | 
| const Token::Kind op_kind_; | 
| - InstanceCallComp* instance_call_; | 
| + InstanceCallInstr* instance_call_; | 
| - DISALLOW_COPY_AND_ASSIGN(UnarySmiOpComp); | 
| + DISALLOW_COPY_AND_ASSIGN(UnarySmiOpInstr); | 
| }; | 
| // Handles non-Smi NEGATE operations | 
| -class NumberNegateComp : public TemplateComputation<1> { | 
| +class NumberNegateInstr : public TemplateDefinition<1> { | 
| public: | 
| - NumberNegateComp(InstanceCallComp* instance_call, | 
| - Value* value) : instance_call_(instance_call) { | 
| + NumberNegateInstr(InstanceCallInstr* instance_call, Value* value) | 
| + : instance_call_(instance_call) { | 
| ASSERT(value != NULL); | 
| inputs_[0] = value; | 
| } | 
| Value* value() const { return inputs_[0]; } | 
| - InstanceCallComp* instance_call() const { return instance_call_; } | 
| + InstanceCallInstr* instance_call() const { return instance_call_; } | 
| const ICData* ic_data() const { return instance_call()->ic_data(); } | 
| - DECLARE_COMPUTATION(NumberNegate) | 
| + DECLARE_INSTRUCTION(NumberNegate) | 
| + virtual RawAbstractType* CompileType() const; | 
| virtual bool CanDeoptimize() const { return true; } | 
| virtual intptr_t ResultCid() const { return kDoubleCid; } | 
| private: | 
| - InstanceCallComp* instance_call_; | 
| + InstanceCallInstr* instance_call_; | 
| - DISALLOW_COPY_AND_ASSIGN(NumberNegateComp); | 
| + DISALLOW_COPY_AND_ASSIGN(NumberNegateInstr); | 
| }; | 
| -class CheckStackOverflowComp : public TemplateComputation<0> { | 
| +class CheckStackOverflowInstr : public TemplateDefinition<0> { | 
| public: | 
| - explicit CheckStackOverflowComp(intptr_t token_pos) | 
| + explicit CheckStackOverflowInstr(intptr_t token_pos) | 
| : token_pos_(token_pos) {} | 
| intptr_t token_pos() const { return token_pos_; } | 
| - DECLARE_COMPUTATION(CheckStackOverflow) | 
| + DECLARE_INSTRUCTION(CheckStackOverflow) | 
| + virtual RawAbstractType* CompileType() const; | 
| virtual bool CanDeoptimize() const { return false; } | 
| virtual intptr_t ResultCid() const { return kIllegalCid; } | 
| @@ -3135,13 +3032,13 @@ class CheckStackOverflowComp : public TemplateComputation<0> { | 
| private: | 
| const intptr_t token_pos_; | 
| - DISALLOW_COPY_AND_ASSIGN(CheckStackOverflowComp); | 
| + DISALLOW_COPY_AND_ASSIGN(CheckStackOverflowInstr); | 
| }; | 
| -class DoubleToDoubleComp : public TemplateComputation<1> { | 
| +class DoubleToDoubleInstr : public TemplateDefinition<1> { | 
| public: | 
| - DoubleToDoubleComp(Value* value, InstanceCallComp* instance_call) | 
| + DoubleToDoubleInstr(Value* value, InstanceCallInstr* instance_call) | 
| : instance_call_(instance_call) { | 
| ASSERT(value != NULL); | 
| inputs_[0] = value; | 
| @@ -3149,28 +3046,30 @@ class DoubleToDoubleComp : public TemplateComputation<1> { | 
| Value* value() const { return inputs_[0]; } | 
| - InstanceCallComp* instance_call() const { return instance_call_; } | 
| + InstanceCallInstr* instance_call() const { return instance_call_; } | 
| - DECLARE_COMPUTATION(DoubleToDouble) | 
| + DECLARE_INSTRUCTION(DoubleToDouble) | 
| + virtual RawAbstractType* CompileType() const; | 
| virtual bool CanDeoptimize() const { return true; } | 
| virtual intptr_t ResultCid() const { return kDoubleCid; } | 
| private: | 
| - InstanceCallComp* instance_call_; | 
| + InstanceCallInstr* instance_call_; | 
| - DISALLOW_COPY_AND_ASSIGN(DoubleToDoubleComp); | 
| + DISALLOW_COPY_AND_ASSIGN(DoubleToDoubleInstr); | 
| }; | 
| -class SmiToDoubleComp : public TemplateComputation<0> { | 
| +class SmiToDoubleInstr : public TemplateDefinition<0> { | 
| public: | 
| - explicit SmiToDoubleComp(InstanceCallComp* instance_call) | 
| + explicit SmiToDoubleInstr(InstanceCallInstr* instance_call) | 
| : instance_call_(instance_call) { } | 
| - InstanceCallComp* instance_call() const { return instance_call_; } | 
| + InstanceCallInstr* instance_call() const { return instance_call_; } | 
| - DECLARE_CALL_COMPUTATION(SmiToDouble) | 
| + DECLARE_INSTRUCTION(SmiToDouble) | 
| + virtual RawAbstractType* CompileType() const; | 
| virtual intptr_t ArgumentCount() const { return 1; } | 
| @@ -3178,29 +3077,30 @@ class SmiToDoubleComp : public TemplateComputation<0> { | 
| virtual intptr_t ResultCid() const { return kDoubleCid; } | 
| private: | 
| - InstanceCallComp* instance_call_; | 
| + InstanceCallInstr* instance_call_; | 
| - DISALLOW_COPY_AND_ASSIGN(SmiToDoubleComp); | 
| + DISALLOW_COPY_AND_ASSIGN(SmiToDoubleInstr); | 
| }; | 
| -class CheckClassComp : public TemplateComputation<1> { | 
| +class CheckClassInstr : public TemplateDefinition<1> { | 
| public: | 
| - CheckClassComp(Value* value, | 
| - InstanceCallComp* instance_call, | 
| - const ICData& unary_checks) | 
| - : instance_call_(instance_call), | 
| - unary_checks_(unary_checks) { | 
| + CheckClassInstr(Value* value, | 
| + InstanceCallInstr* instance_call, | 
| + const ICData& unary_checks) | 
| + : unary_checks_(unary_checks) { | 
| ASSERT(value != NULL); | 
| inputs_[0] = value; | 
| + deopt_id_ = instance_call->deopt_id(); | 
| } | 
| - DECLARE_COMPUTATION(CheckClass) | 
| + DECLARE_INSTRUCTION(CheckClass) | 
| + virtual RawAbstractType* CompileType() const; | 
| virtual bool CanDeoptimize() const { return true; } | 
| virtual intptr_t ResultCid() const { return kIllegalCid; } | 
| - virtual bool AttributesEqual(Computation* other) const; | 
| + virtual bool AttributesEqual(Definition* other) const; | 
| virtual bool HasSideEffect() const { return false; } | 
| @@ -3208,70 +3108,66 @@ class CheckClassComp : public TemplateComputation<1> { | 
| const ICData& unary_checks() const { return unary_checks_; } | 
| - virtual intptr_t deopt_id() const { return instance_call_->deopt_id(); } | 
| - | 
| - virtual Definition* TryReplace(BindInstr* instr) const; | 
| + virtual Definition* Canonicalize(); | 
| virtual void PrintOperandsTo(BufferFormatter* f) const; | 
| private: | 
| - InstanceCallComp* instance_call_; | 
| const ICData& unary_checks_; | 
| - DISALLOW_COPY_AND_ASSIGN(CheckClassComp); | 
| + DISALLOW_COPY_AND_ASSIGN(CheckClassInstr); | 
| }; | 
| -class CheckSmiComp : public TemplateComputation<1> { | 
| +class CheckSmiInstr : public TemplateDefinition<1> { | 
| public: | 
| - CheckSmiComp(Value* value, intptr_t original_deopt_id) | 
| - : original_deopt_id_(original_deopt_id) { | 
| + CheckSmiInstr(Value* value, intptr_t original_deopt_id) { | 
| ASSERT(value != NULL); | 
| ASSERT(original_deopt_id != Isolate::kNoDeoptId); | 
| inputs_[0] = value; | 
| + deopt_id_ = original_deopt_id; | 
| } | 
| - DECLARE_COMPUTATION(CheckSmi) | 
| + DECLARE_INSTRUCTION(CheckSmi) | 
| + virtual RawAbstractType* CompileType() const; | 
| virtual bool CanDeoptimize() const { return true; } | 
| virtual intptr_t ResultCid() const { return kIllegalCid; } | 
| - virtual bool AttributesEqual(Computation* other) const { return true; } | 
| + virtual bool AttributesEqual(Definition* other) const { return true; } | 
| virtual bool HasSideEffect() const { return false; } | 
| - virtual Definition* TryReplace(BindInstr* instr) const; | 
| + virtual Definition* Canonicalize(); | 
| Value* value() const { return inputs_[0]; } | 
| - virtual intptr_t deopt_id() const { return original_deopt_id_; } | 
| - | 
| private: | 
| - const intptr_t original_deopt_id_; | 
| - | 
| - DISALLOW_COPY_AND_ASSIGN(CheckSmiComp); | 
| + DISALLOW_COPY_AND_ASSIGN(CheckSmiInstr); | 
| }; | 
| -class CheckArrayBoundComp : public TemplateComputation<2> { | 
| +class CheckArrayBoundInstr : public TemplateDefinition<2> { | 
| public: | 
| - CheckArrayBoundComp(Value* array, | 
| - Value* index, | 
| - intptr_t array_type, | 
| - InstanceCallComp* instance_call) | 
| - : array_type_(array_type), instance_call_(instance_call) { | 
| + CheckArrayBoundInstr(Value* array, | 
| + Value* index, | 
| + intptr_t array_type, | 
| + InstanceCallInstr* instance_call) | 
| + : array_type_(array_type) { | 
| ASSERT(array != NULL); | 
| ASSERT(index != NULL); | 
| inputs_[0] = array; | 
| inputs_[1] = index; | 
| + deopt_id_ = instance_call->deopt_id(); | 
| } | 
| - DECLARE_COMPUTATION(CheckArrayBound) | 
| + DECLARE_INSTRUCTION(CheckArrayBound) | 
| + virtual RawAbstractType* CompileType() const; | 
| virtual bool CanDeoptimize() const { return true; } | 
| virtual intptr_t ResultCid() const { return kIllegalCid; } | 
| - virtual bool AttributesEqual(Computation* other) const; | 
| + virtual bool AttributesEqual(Definition* other) const; | 
| virtual bool HasSideEffect() const { return false; } | 
| @@ -3280,34 +3176,14 @@ class CheckArrayBoundComp : public TemplateComputation<2> { | 
| intptr_t array_type() const { return array_type_; } | 
| - virtual intptr_t deopt_id() const { return instance_call_->deopt_id(); } | 
| - | 
| private: | 
| intptr_t array_type_; | 
| - InstanceCallComp* instance_call_; | 
| - DISALLOW_COPY_AND_ASSIGN(CheckArrayBoundComp); | 
| + DISALLOW_COPY_AND_ASSIGN(CheckArrayBoundInstr); | 
| }; | 
| -#undef DECLARE_COMPUTATION | 
| - | 
| - | 
| -// Implementation of type testers and cast functins. | 
| -#define DEFINE_COMPUTATION_PREDICATE(ShortName, ClassName) \ | 
| -bool Computation::Is##ShortName() const { \ | 
| - return computation_kind() == k##ShortName; \ | 
| -} \ | 
| -const ClassName* Computation::As##ShortName() const { \ | 
| - if (!Is##ShortName()) return NULL; \ | 
| - return static_cast<const ClassName*>(this); \ | 
| -} \ | 
| -ClassName* Computation::As##ShortName() { \ | 
| - if (!Is##ShortName()) return NULL; \ | 
| - return static_cast<ClassName*>(this); \ | 
| -} | 
| -FOR_EACH_COMPUTATION(DEFINE_COMPUTATION_PREDICATE) | 
| -#undef DEFINE_COMPUTATION_PREDICATE | 
| +#undef DECLARE_INSTRUCTION | 
| class Environment : public ZoneAllocated { | 
| @@ -3377,18 +3253,13 @@ class FlowGraphVisitor : public ValueObject { | 
| // instructions in order from the block entry to exit. | 
| virtual void VisitBlocks(); | 
| - // Visit functions for instruction and computation classes, with empty | 
| - // default implementations. | 
| -#define DECLARE_VISIT_COMPUTATION(ShortName, ClassName) \ | 
| - virtual void Visit##ShortName(ClassName* comp, BindInstr* instr) { } | 
| - | 
| + // Visit functions for instruction classes, with an empty default | 
| + // implementation. | 
| #define DECLARE_VISIT_INSTRUCTION(ShortName) \ | 
| virtual void Visit##ShortName(ShortName##Instr* instr) { } | 
| - FOR_EACH_COMPUTATION(DECLARE_VISIT_COMPUTATION) | 
| FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION) | 
| -#undef DECLARE_VISIT_COMPUTATION | 
| #undef DECLARE_VISIT_INSTRUCTION | 
| protected: |