Chromium Code Reviews| Index: runtime/vm/intermediate_language.h |
| diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h |
| index 1177d698a6d5b0920465e0619d3c4d5ac1380e4e..a969e2001127e16d614131034951acabfbf11cad 100644 |
| --- a/runtime/vm/intermediate_language.h |
| +++ b/runtime/vm/intermediate_language.h |
| @@ -779,6 +779,8 @@ class EmbeddedArray<T, 0> { |
| M(Simd64x2Shuffle) \ |
| M(Float64x2ZeroArg) \ |
| M(Float64x2OneArg) \ |
| + M(MergedMath2) \ |
| + M(ExtractNthOutput) \ |
| #define FORWARD_DECLARATION(type) class type##Instr; |
| @@ -1099,6 +1101,7 @@ FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK) |
| friend class FloatToDoubleInstr; |
| friend class InvokeMathCFunctionInstr; |
| friend class MergedMathInstr; |
| + friend class MergedMath2Instr; |
| friend class FlowGraphOptimizer; |
| friend class LoadIndexedInstr; |
| friend class StoreIndexedInstr; |
| @@ -1765,6 +1768,21 @@ class Definition : public Instruction { |
| bool HasSSATemp() const { return ssa_temp_index_ >= 0; } |
| void ClearSSATempIndex() { ssa_temp_index_ = -1; } |
| + |
| + virtual bool RequiresTwoSSATempIndexes() const { |
| + return false; |
| + } |
| + |
| + intptr_t ssa_temp_index2() const { return ssa_temp_index2_; } |
| + void set_ssa_temp_index2(intptr_t index) { |
| + ASSERT(index >= 0); |
| + ASSERT(is_used()); |
| + ASSERT(RequiresTwoSSATempIndexes()); |
| + ssa_temp_index2_ = index; |
| + } |
| + void ClearSSATempIndex2() { ssa_temp_index2_ = -1; } |
| + |
| + |
| bool is_used() const { return (use_kind_ != kEffect); } |
| void set_use_kind(UseKind kind) { use_kind_ = kind; } |
| @@ -1888,6 +1906,7 @@ class Definition : public Instruction { |
| private: |
| intptr_t temp_index_; |
| intptr_t ssa_temp_index_; |
| + intptr_t ssa_temp_index2_; |
|
Vyacheslav Egorov (Google)
2014/04/03 18:10:09
Can we sink it down into instructions that actuall
Cutch
2014/04/03 18:35:07
Done.
|
| Value* input_use_list_; |
| Value* env_use_list_; |
| UseKind use_kind_; |
| @@ -7286,6 +7305,165 @@ class InvokeMathCFunctionInstr : public Definition { |
| }; |
| +class ExtractNthOutputInstr : public TemplateDefinition<1> { |
| + public: |
| + // Extract the Nth output register from value. |
| + ExtractNthOutputInstr(Value* value, intptr_t n, Representation rep) |
| + : index_(n), |
| + rep_(rep) { |
| + SetInputAt(0, value); |
| + } |
| + |
| + Value* value() const { return inputs_[0]; } |
| + |
| + DECLARE_INSTRUCTION(ExtractNthOutput) |
| + |
| + virtual CompileType ComputeType() const; |
| + virtual void PrintOperandsTo(BufferFormatter* f) const; |
| + virtual bool CanDeoptimize() const { return false; } |
| + |
| + intptr_t index() const { return index_; } |
| + |
| + virtual Representation representation() const { |
| + return rep_; |
| + } |
| + |
| + virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
| + ASSERT(idx == 0); |
| + if (representation() == kTagged) { |
| + return kPairOfTagged; |
| + } else if (representation() == kUnboxedDouble) { |
| + return kPairOfUnboxedDouble; |
| + } |
| + UNREACHABLE(); |
| + return rep_; |
| + } |
| + |
| + 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 { |
| + ExtractNthOutputInstr* other_extract = other->AsExtractNthOutput(); |
| + return (other_extract->representation() == representation()) && |
| + (other_extract->index() == index()); |
| + } |
| + |
| + virtual bool MayThrow() const { return false; } |
| + |
| + private: |
| + const intptr_t index_; |
| + const Representation rep_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(ExtractNthOutputInstr); |
| +}; |
| + |
| + |
| +class MergedMath2Instr : public Definition { |
| + public: |
| + enum Kind { |
| + kTruncDivMod, |
| + kSinCos, |
| + }; |
| + |
| + MergedMath2Instr(ZoneGrowableArray<Value*>* inputs, |
| + intptr_t original_deopt_id, |
| + MergedMath2Instr::Kind kind); |
| + |
| + static intptr_t InputCountFor(MergedMath2Instr::Kind kind) { |
| + if (kind == kTruncDivMod) { |
| + return 2; |
| + } else if (kind == kSinCos) { |
| + return 1; |
| + } else { |
| + UNIMPLEMENTED(); |
| + return -1; |
| + } |
| + } |
| + |
| + virtual bool RequiresTwoSSATempIndexes() const { |
| + return true; |
| + } |
| + |
| + MergedMath2Instr::Kind kind() const { return kind_; } |
| + |
| + virtual intptr_t InputCount() const { return inputs_->length(); } |
| + |
| + virtual Value* InputAt(intptr_t i) const { |
| + return (*inputs_)[i]; |
| + } |
| + |
| + static intptr_t OutputIndexOf(intptr_t kind); |
| + static intptr_t OutputIndexOf(Token::Kind token); |
| + |
| + virtual CompileType ComputeType() const; |
| + virtual void PrintOperandsTo(BufferFormatter* f) const; |
| + |
| + virtual bool CanDeoptimize() const { |
| + if (kind_ == kTruncDivMod) { |
| + return true; |
| + } else if (kind_ == kSinCos) { |
| + return false; |
| + } else { |
| + UNIMPLEMENTED(); |
| + return false; |
| + } |
| + } |
| + |
| + virtual Representation representation() const { |
| + if (kind_ == kTruncDivMod) { |
| + return kPairOfTagged; |
| + } else if (kind_ == kSinCos) { |
| + return kPairOfUnboxedDouble; |
| + } else { |
| + UNIMPLEMENTED(); |
| + return kTagged; |
| + } |
| + } |
| + |
| + virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
| + ASSERT((0 <= idx) && (idx < InputCount())); |
| + if (kind_ == kTruncDivMod) { |
| + return kTagged; |
| + } else if (kind_ == kSinCos) { |
| + return kUnboxedDouble; |
| + } else { |
| + UNIMPLEMENTED(); |
| + return kTagged; |
| + } |
| + } |
| + |
| + virtual intptr_t DeoptimizationTarget() const { return deopt_id_; } |
| + |
| + DECLARE_INSTRUCTION(MergedMath2) |
| + |
| + 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 { |
| + MergedMath2Instr* other_invoke = other->AsMergedMath2(); |
| + return other_invoke->kind() == kind(); |
| + } |
| + |
| + virtual bool MayThrow() const { return false; } |
| + |
| + static const char* KindToCString(MergedMath2Instr::Kind kind) { |
| + if (kind == kTruncDivMod) return "TruncDivMod"; |
| + if (kind == kSinCos) return "SinCos"; |
| + UNIMPLEMENTED(); |
| + return ""; |
| + } |
| + |
| + private: |
| + virtual void RawSetInputAt(intptr_t i, Value* value) { |
| + (*inputs_)[i] = value; |
| + } |
| + |
| + ZoneGrowableArray<Value*>* inputs_; |
| + MergedMath2Instr::Kind kind_; |
| + DISALLOW_COPY_AND_ASSIGN(MergedMath2Instr); |
| +}; |
| + |
| + |
| class MergedMathInstr : public Definition { |
| public: |
| enum Kind { |