Index: runtime/vm/intermediate_language.h |
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h |
index 1177d698a6d5b0920465e0619d3c4d5ac1380e4e..bd31a6812ada468ce5e8ebdcbf8dbe75cc727992 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,11 @@ class Definition : public Instruction { |
bool HasSSATemp() const { return ssa_temp_index_ >= 0; } |
void ClearSSATempIndex() { ssa_temp_index_ = -1; } |
+ // Definitions which output register pairs need a second SSA index. |
+ virtual bool RequiresPairSSAIndex() const { return false; } |
+ virtual intptr_t pair_ssa_index() const { return -1; } |
+ virtual void set_pair_ssa_index(intptr_t idx) { UNIMPLEMENTED(); } |
+ |
bool is_used() const { return (use_kind_ != kEffect); } |
void set_use_kind(UseKind kind) { use_kind_ = kind; } |
@@ -7286,6 +7294,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 RequiresPairSSAIndex() const { return true; } |
+ virtual intptr_t pair_ssa_index() const { return pair_ssa_index_; } |
+ virtual void set_pair_ssa_index(intptr_t idx) { pair_ssa_index_ = idx; } |
+ |
+ 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; |
+ } |
+ intptr_t pair_ssa_index_; |
+ ZoneGrowableArray<Value*>* inputs_; |
+ MergedMath2Instr::Kind kind_; |
+ DISALLOW_COPY_AND_ASSIGN(MergedMath2Instr); |
+}; |
+ |
+ |
class MergedMathInstr : public Definition { |
public: |
enum Kind { |