Index: runtime/vm/intermediate_language.h |
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h |
index fba6104a7c188e00544816ba140b7d803852e596..91204226fea004588dc55945c565becf0af1a6ce 100644 |
--- a/runtime/vm/intermediate_language.h |
+++ b/runtime/vm/intermediate_language.h |
@@ -103,7 +103,11 @@ class LocalVariable; |
M(DoubleToDouble, DoubleToDoubleComp) \ |
M(SmiToDouble, SmiToDoubleComp) \ |
M(CheckClass, CheckClassComp) \ |
- M(Materialize, MaterializeComp) |
+ M(Materialize, MaterializeComp) \ |
+ M(CheckEitherNonSmi, CheckEitherNonSmiComp) \ |
+ M(UnboxedDoubleBinaryOp, UnboxedDoubleBinaryOpComp) \ |
+ M(UnboxDouble, UnboxDoubleComp) \ |
+ M(BoxDouble, BoxDoubleComp) |
#define FORWARD_DECLARATION(ShortName, ClassName) class ClassName; |
@@ -121,6 +125,12 @@ class Instruction; |
class PushArgumentInstr; |
class Value; |
+ |
+enum Representation { |
+ kTagged, kUnboxedDouble |
+}; |
+ |
+ |
class Computation : public ZoneAllocated { |
public: |
Computation() : deopt_id_(Isolate::kNoDeoptId), ic_data_(NULL), locs_(NULL) { |
@@ -225,6 +235,10 @@ class Computation : public ZoneAllocated { |
virtual ComputationKind computation_kind() const = 0; |
+ virtual Representation representation() const { |
+ return kTagged; |
+ } |
+ |
// Declare predicate for each computation. |
#define DECLARE_PREDICATE(ShortName, ClassName) \ |
inline bool Is##ShortName() const; \ |
@@ -427,6 +441,7 @@ class UseVal : public Value { |
private: |
void AddToUseList(); |
+ |
Definition* definition_; |
UseVal* next_use_; |
UseVal* previous_use_; |
@@ -1650,6 +1665,125 @@ class CatchEntryComp : public TemplateComputation<0> { |
}; |
+class CheckEitherNonSmiComp : public TemplateComputation<2> { |
+ public: |
+ CheckEitherNonSmiComp(Value* left, Value* right, InstanceCallComp* original) |
+ : original_(original) { |
+ ASSERT(left != NULL); |
+ ASSERT(right != NULL); |
+ inputs_[0] = left; |
+ inputs_[1] = right; |
+ } |
+ |
+ DECLARE_COMPUTATION(CheckEitherNonSmi) |
+ |
+ virtual bool CanDeoptimize() const { return true; } |
+ |
+ virtual bool HasSideEffect() const { return false; } |
+ |
+ Value* left() const { return inputs_[0]; } |
+ |
+ Value* right() const { return inputs_[0]; } |
+ |
+ intptr_t deopt_id() const { return original_->deopt_id(); } |
Florian Schneider
2012/08/24 11:09:28
Either add accessors to the other deoptimizing ins
Vyacheslav Egorov (Google)
2012/08/24 13:23:01
Done.
Vyacheslav Egorov (Google)
2012/08/24 13:23:01
Done.
|
+ intptr_t try_index() const { return original_->try_index(); } |
+ |
+ private: |
+ InstanceCallComp* original_; |
Florian Schneider
2012/08/24 11:09:28
Maybe rename to instance_call_ for consistency?
Vyacheslav Egorov (Google)
2012/08/24 13:23:01
Done.
|
+ |
+ DISALLOW_COPY_AND_ASSIGN(CheckEitherNonSmiComp); |
+}; |
+ |
+ |
+class BoxDoubleComp : public TemplateComputation<1> { |
+ public: |
+ BoxDoubleComp(Value* value, InstanceCallComp* instance_call) |
+ : instance_call_(instance_call) { |
+ ASSERT(value != NULL); |
+ inputs_[0] = value; |
+ } |
+ |
+ Value* value() const { return inputs_[0]; } |
+ InstanceCallComp* instance_call() const { return instance_call_; } |
+ |
+ virtual bool CanDeoptimize() const { return false; } |
+ |
+ virtual intptr_t ResultCid() const; |
+ |
+ DECLARE_COMPUTATION(BoxDouble) |
+ |
+ private: |
+ InstanceCallComp* instance_call_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(BoxDoubleComp); |
+}; |
+ |
+ |
+class UnboxDoubleComp : public TemplateComputation<1> { |
+ public: |
+ UnboxDoubleComp(Value* value, InstanceCallComp* instance_call) |
+ : instance_call_(instance_call) { |
+ ASSERT(value != NULL); |
+ inputs_[0] = value; |
+ } |
+ |
+ Value* value() const { return inputs_[0]; } |
+ InstanceCallComp* instance_call() const { return instance_call_; } |
+ |
+ virtual bool CanDeoptimize() const { return true; } |
Florian Schneider
2012/08/24 11:09:28
More precisely:
return (value()->ResultCid() != k
Vyacheslav Egorov (Google)
2012/08/24 13:23:01
Done.
|
+ |
+ virtual Representation representation() const { |
+ return kUnboxedDouble; |
+ } |
+ |
+ DECLARE_COMPUTATION(UnboxDouble) |
+ |
+ private: |
+ InstanceCallComp* instance_call_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(UnboxDoubleComp); |
+}; |
+ |
+ |
+class UnboxedDoubleBinaryOpComp : public TemplateComputation<2> { |
+ public: |
+ UnboxedDoubleBinaryOpComp(Token::Kind op_kind, |
+ InstanceCallComp* instance_call, |
+ Value* left, |
+ Value* right) |
+ : op_kind_(op_kind), |
+ instance_call_(instance_call) { |
+ ASSERT(left != NULL); |
+ ASSERT(right != NULL); |
+ inputs_[0] = left; |
+ inputs_[1] = right; |
+ } |
+ |
+ Value* left() const { return inputs_[0]; } |
+ Value* right() const { return inputs_[1]; } |
+ |
+ Token::Kind op_kind() const { return op_kind_; } |
+ |
+ InstanceCallComp* instance_call() const { return instance_call_; } |
+ |
+ virtual void PrintOperandsTo(BufferFormatter* f) const; |
+ |
+ virtual bool CanDeoptimize() const { return false; } |
+ |
+ virtual Representation representation() const { |
+ return kUnboxedDouble; |
+ } |
+ |
+ DECLARE_COMPUTATION(UnboxedDoubleBinaryOp) |
+ |
+ private: |
+ const Token::Kind op_kind_; |
+ InstanceCallComp* instance_call_; |
Florian Schneider
2012/08/24 11:09:28
No need for instance_call_ here. This instruction
Vyacheslav Egorov (Google)
2012/08/24 13:23:01
Done.
|
+ |
+ DISALLOW_COPY_AND_ASSIGN(UnboxedDoubleBinaryOpComp); |
+}; |
+ |
+ |
class BinarySmiOpComp : public TemplateComputation<2> { |
public: |
BinarySmiOpComp(Token::Kind op_kind, |
@@ -2093,6 +2227,10 @@ FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK) |
lifetime_position_ = pos; |
} |
+ virtual Representation representation() const { |
+ return kTagged; |
+ } |
+ |
private: |
friend class BindInstr; // Needed for BindInstr::InsertBefore. |
@@ -2661,6 +2799,10 @@ class BindInstr : public Definition { |
// Insert this instruction before 'next'. |
void InsertBefore(BindInstr* next); |
+ virtual Representation representation() const { |
+ return computation()->representation(); |
+ } |
+ |
private: |
Computation* computation_; |
const bool is_used_; |
@@ -3065,7 +3207,14 @@ class Environment : public ZoneAllocated { |
void PrintTo(BufferFormatter* f) const; |
+ Environment* Clone() const { |
+ return new Environment(values_, fixed_parameter_count_); |
+ } |
+ |
private: |
+ Environment(const GrowableArray<Value*>& values, |
+ intptr_t fixed_parameter_count); |
+ |
GrowableArray<Value*> values_; |
Location* locations_; |
const intptr_t fixed_parameter_count_; |