Index: runtime/vm/intermediate_language.h |
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h |
index e081354b6cb6f45b3942605554029ef6806bfb18..f5f59ac0fa81656ad530b3cd9edc262f2fd7e711 100644 |
--- a/runtime/vm/intermediate_language.h |
+++ b/runtime/vm/intermediate_language.h |
@@ -564,15 +564,21 @@ FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) |
// Functions required in all concrete instruction classes. |
-#define DECLARE_INSTRUCTION(type) \ |
+#define DECLARE_INSTRUCTION_NO_BACKEND(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; } \ |
+ |
+#define DECLARE_INSTRUCTION_BACKEND(type) \ |
virtual LocationSummary* MakeLocationSummary(Isolate* isolate, \ |
bool optimizing) const; \ |
virtual void EmitNativeCode(FlowGraphCompiler* compiler); \ |
+// Functions required in all concrete instruction classes. |
+#define DECLARE_INSTRUCTION(type) \ |
+ DECLARE_INSTRUCTION_NO_BACKEND(type) \ |
+ DECLARE_INSTRUCTION_BACKEND(type) \ |
class Instruction : public ZoneAllocated { |
public: |
@@ -7963,10 +7969,12 @@ class UnaryUint32OpInstr : public TemplateDefinition<1> { |
class BoxIntNInstr : public TemplateDefinition<1> { |
public: |
BoxIntNInstr(Representation representation, Value* value) |
- : representation_(representation) { |
+ : from_representation_(representation) { |
SetInputAt(0, value); |
} |
+ Representation from_representation() const { return from_representation_; } |
+ |
Value* value() const { return inputs_[0]; } |
virtual bool ValueFitsSmi() const; |
@@ -7981,14 +7989,14 @@ class BoxIntNInstr : public TemplateDefinition<1> { |
virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
ASSERT(idx == 0); |
- return representation_; |
+ return from_representation_; |
} |
virtual bool AllowsCSE() const { return true; } |
virtual EffectSet Effects() const { return EffectSet::None(); } |
virtual EffectSet Dependencies() const { return EffectSet::None(); } |
virtual bool AttributesEqual(Instruction* other) const { |
- return other->AsBoxIntN()->representation_ == representation_; |
+ return other->AsBoxIntN()->from_representation_ == from_representation_; |
} |
virtual bool MayThrow() const { return false; } |
@@ -7997,8 +8005,10 @@ class BoxIntNInstr : public TemplateDefinition<1> { |
virtual BoxIntNInstr* AsBoxIntN() { return this; } |
+ DECLARE_INSTRUCTION_BACKEND(BoxIntN) |
+ |
private: |
- const Representation representation_; |
+ const Representation from_representation_; |
DISALLOW_COPY_AND_ASSIGN(BoxIntNInstr); |
}; |
@@ -8009,7 +8019,7 @@ class BoxUint32Instr : public BoxIntNInstr { |
explicit BoxUint32Instr(Value* value) |
: BoxIntNInstr(kUnboxedUint32, value) { } |
- DECLARE_INSTRUCTION(BoxUint32) |
+ DECLARE_INSTRUCTION_NO_BACKEND(BoxUint32) |
private: |
DISALLOW_COPY_AND_ASSIGN(BoxUint32Instr); |
@@ -8023,7 +8033,7 @@ class BoxInt32Instr : public BoxIntNInstr { |
virtual void InferRange(RangeAnalysis* analysis, Range* range); |
- DECLARE_INSTRUCTION(BoxInt32) |
+ DECLARE_INSTRUCTION_NO_BACKEND(BoxInt32) |
private: |
DISALLOW_COPY_AND_ASSIGN(BoxInt32Instr); |
@@ -8035,13 +8045,17 @@ class UnboxIntNInstr : public TemplateDefinition<1> { |
UnboxIntNInstr(Representation representation, |
Value* value, |
intptr_t deopt_id) |
- : representation_(representation) { |
+ : representation_(representation), |
+ is_truncating_(representation == kUnboxedUint32) { |
SetInputAt(0, value); |
deopt_id_ = deopt_id; |
} |
Value* value() const { return inputs_[0]; } |
+ bool is_truncating() const { return is_truncating_; } |
+ void mark_truncating() { is_truncating_ = true; } |
+ |
virtual Representation representation() const { |
return representation_; |
} |
@@ -8052,7 +8066,9 @@ class UnboxIntNInstr : public TemplateDefinition<1> { |
virtual EffectSet Effects() const { return EffectSet::None(); } |
virtual EffectSet Dependencies() const { return EffectSet::None(); } |
virtual bool AttributesEqual(Instruction* other) const { |
- return other->AsUnboxIntN()->representation_ == representation_; |
+ UnboxIntNInstr* other_unbox = other->AsUnboxIntN(); |
+ return (other_unbox->representation_ == representation_) && |
+ (other_unbox->is_truncating_ == is_truncating_); |
} |
virtual bool MayThrow() const { return false; } |
@@ -8061,8 +8077,13 @@ class UnboxIntNInstr : public TemplateDefinition<1> { |
virtual UnboxIntNInstr* AsUnboxIntN() { return this; } |
+ virtual void PrintOperandsTo(BufferFormatter* f) const; |
+ |
+ DECLARE_INSTRUCTION_BACKEND(UnboxIntNInstr); |
+ |
private: |
const Representation representation_; |
+ bool is_truncating_; |
DISALLOW_COPY_AND_ASSIGN(UnboxIntNInstr); |
}; |
@@ -8072,6 +8093,7 @@ class UnboxUint32Instr : public UnboxIntNInstr { |
public: |
UnboxUint32Instr(Value* value, intptr_t deopt_id) |
: UnboxIntNInstr(kUnboxedUint32, value, deopt_id) { |
+ ASSERT(is_truncating()); |
} |
virtual bool CanDeoptimize() const { |
@@ -8079,7 +8101,7 @@ class UnboxUint32Instr : public UnboxIntNInstr { |
&& (value()->Type()->ToCid() != kMintCid); |
} |
- DECLARE_INSTRUCTION(UnboxUint32) |
+ DECLARE_INSTRUCTION_NO_BACKEND(UnboxUint32) |
private: |
DISALLOW_COPY_AND_ASSIGN(UnboxUint32Instr); |
@@ -8098,7 +8120,7 @@ class UnboxInt32Instr : public UnboxIntNInstr { |
virtual Definition* Canonicalize(FlowGraph* flow_graph); |
- DECLARE_INSTRUCTION(UnboxInt32) |
+ DECLARE_INSTRUCTION_NO_BACKEND(UnboxInt32) |
private: |
DISALLOW_COPY_AND_ASSIGN(UnboxInt32Instr); |
@@ -8112,7 +8134,8 @@ class UnboxedIntConverterInstr : public TemplateDefinition<1> { |
Value* value, |
intptr_t deopt_id) |
: from_representation_(from), |
- to_representation_(to) { |
+ to_representation_(to), |
+ is_truncating_(to == kUnboxedUint32) { |
ASSERT(from != to); |
ASSERT((from == kUnboxedMint) || |
(from == kUnboxedUint32) || |
@@ -8129,6 +8152,9 @@ class UnboxedIntConverterInstr : public TemplateDefinition<1> { |
Representation from() const { return from_representation_; } |
Representation to() const { return to_representation_; } |
+ bool is_truncating() const { return is_truncating_; } |
+ |
+ void mark_truncating() { is_truncating_ = true; } |
Definition* Canonicalize(FlowGraph* flow_graph); |
@@ -8148,7 +8174,9 @@ class UnboxedIntConverterInstr : public TemplateDefinition<1> { |
virtual bool AttributesEqual(Instruction* other) const { |
ASSERT(other->IsUnboxedIntConverter()); |
UnboxedIntConverterInstr* converter = other->AsUnboxedIntConverter(); |
- return (converter->from() == from()) && (converter->to() == to()); |
+ return (converter->from() == from()) && |
+ (converter->to() == to()) && |
+ (converter->is_truncating() == is_truncating()); |
} |
virtual bool MayThrow() const { return false; } |
@@ -8162,6 +8190,8 @@ class UnboxedIntConverterInstr : public TemplateDefinition<1> { |
private: |
const Representation from_representation_; |
const Representation to_representation_; |
+ bool is_truncating_; |
+ |
DISALLOW_COPY_AND_ASSIGN(UnboxedIntConverterInstr); |
}; |