| 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 {
|
|
|