| Index: runtime/vm/intermediate_language.h
|
| diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
|
| index fd02f8cd6bed6c863adcf7201f6ffad4d7acc2d7..fa211946fe2b2cd153212c4865a7c4358ffd350e 100644
|
| --- a/runtime/vm/intermediate_language.h
|
| +++ b/runtime/vm/intermediate_language.h
|
| @@ -386,8 +386,9 @@ class Instruction : public ZoneAllocated {
|
| virtual const char* DebugName() const = 0;
|
|
|
| // Printing support.
|
| - virtual void PrintTo(BufferFormatter* f) const = 0;
|
| - virtual void PrintToVisualizer(BufferFormatter* f) const = 0;
|
| + virtual void PrintTo(BufferFormatter* f) const;
|
| + virtual void PrintOperandsTo(BufferFormatter* f) const;
|
| + virtual void PrintToVisualizer(BufferFormatter* f) const;
|
|
|
| #define INSTRUCTION_TYPE_CHECK(type) \
|
| bool Is##type() { return (As##type() != NULL); } \
|
| @@ -442,10 +443,48 @@ FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK)
|
| return Isolate::kNoDeoptId;
|
| }
|
|
|
| + // Returns a replacement for the instruction or NULL if the instruction can
|
| + // be eliminated. By default returns the this instruction which means no
|
| + // change.
|
| + virtual Instruction* Canonicalize();
|
| +
|
| + // Insert this instruction before 'next'.
|
| + void InsertBefore(Instruction* next);
|
| +
|
| + // Insert this instruction after 'prev'.
|
| + void InsertAfter(Instruction* prev);
|
| +
|
| + // Returns true if the instruction is affected by side effects.
|
| + // Only instructions that are not affected by side effects can participate
|
| + // in redundancy elimination or loop invariant code motion.
|
| + // TODO(fschneider): Make this abstract and implement for all instructions
|
| + // instead of returning the safe default (true).
|
| + virtual bool AffectedBySideEffect() const { return true; }
|
| +
|
| + // Get the block entry for this instruction.
|
| + virtual BlockEntryInstr* GetBlock() const;
|
| +
|
| // Id for instructions used in CSE.
|
| intptr_t expr_id() const { return expr_id_; }
|
| void set_expr_id(intptr_t expr_id) { expr_id_ = expr_id; }
|
|
|
| + // Returns a hash code for use with hash maps.
|
| + virtual intptr_t Hashcode() const;
|
| +
|
| + // Compares two instructions. Returns true, iff:
|
| + // 1. They have the same tag.
|
| + // 2. All input operands are Equals.
|
| + // 3. They satisfy AttributesEqual.
|
| + bool Equals(Instruction* other) const;
|
| +
|
| + // Compare attributes of a instructions (except input operands and tag).
|
| + // All instructions that participate in CSE have to override this function.
|
| + // This function can assume that the argument has the same type as this.
|
| + virtual bool AttributesEqual(Instruction* other) const {
|
| + UNREACHABLE();
|
| + return false;
|
| + }
|
| +
|
| protected:
|
| // Fetch deopt id without checking if this computation can deoptimize.
|
| intptr_t GetDeoptId() const {
|
| @@ -996,24 +1035,12 @@ class Definition : public Instruction {
|
| // Returns true if the propagated cid has changed.
|
| bool SetPropagatedCid(intptr_t cid);
|
|
|
| - // Returns true if the definition is affected by side effects.
|
| - // Only instructions that are not affected by side effects can participate
|
| - // in redundancy elimination or loop invariant code motion.
|
| - // TODO(fschneider): Make this abstract and implement for all definitions
|
| - // instead of returning the safe default (true).
|
| - virtual bool AffectedBySideEffect() const { return true; }
|
| -
|
| Value* input_use_list() { return input_use_list_; }
|
| void set_input_use_list(Value* head) { input_use_list_ = head; }
|
|
|
| Value* env_use_list() { return env_use_list_; }
|
| void set_env_use_list(Value* head) { env_use_list_ = head; }
|
|
|
| - // Returns a replacement for the definition or NULL if the definition can
|
| - // be eliminated. By default returns the definition (input parameter)
|
| - // which means no change.
|
| - virtual Definition* Canonicalize();
|
| -
|
| // Replace uses of this definition with uses of other definition or value.
|
| // Precondition: use lists must be properly calculated.
|
| // Postcondition: use lists and use values are still valid.
|
| @@ -1025,41 +1052,20 @@ class Definition : public Instruction {
|
| // NULL iterator.
|
| void ReplaceWith(Definition* other, ForwardInstructionIterator* iterator);
|
|
|
| - // Insert this definition before 'next'.
|
| - void InsertBefore(Instruction* next);
|
| -
|
| - // Insert this definition after 'prev'.
|
| - void InsertAfter(Instruction* prev);
|
| -
|
| - // Compares two definitions. Returns true, iff:
|
| - // 1. They have the same tag.
|
| - // 2. All input operands are Equals.
|
| - // 3. They satisfy AttributesEqual.
|
| - bool Equals(Definition* other) const;
|
| -
|
| - // Compare attributes of a definition (except input operands and tag).
|
| - // All definition that participate in CSE have to override this function.
|
| - // This function can assume that the argument has the same type as this.
|
| - virtual bool AttributesEqual(Definition* other) const {
|
| - UNREACHABLE();
|
| - return false;
|
| - }
|
| -
|
| - // Returns a hash code for use with hash maps.
|
| - virtual intptr_t Hashcode() const;
|
| -
|
| virtual void RecordAssignedVars(BitVector* assigned_vars,
|
| intptr_t fixed_parameter_count);
|
|
|
| - // Get the block entry for that instruction.
|
| - virtual BlockEntryInstr* GetBlock() const;
|
| -
|
| // Printing support. These functions are sometimes overridden for custom
|
| // formatting. Otherwise, it prints in the format "opcode(op1, op2, op3)".
|
| virtual void PrintTo(BufferFormatter* f) const;
|
| virtual void PrintOperandsTo(BufferFormatter* f) const;
|
| virtual void PrintToVisualizer(BufferFormatter* f) const;
|
|
|
| + // Definitions can be canonicalized only into definitions to ensure
|
| + // this check statically we override base Canonicalize with a Canonicalize
|
| + // returning Definition (return type is covariant).
|
| + virtual Definition* Canonicalize();
|
| +
|
| private:
|
| intptr_t temp_index_;
|
| intptr_t ssa_temp_index_;
|
| @@ -1278,9 +1284,6 @@ class ReturnInstr : public TemplateInstruction<1> {
|
|
|
| virtual bool HasSideEffect() const { return false; }
|
|
|
| - virtual void PrintTo(BufferFormatter* f) const;
|
| - virtual void PrintToVisualizer(BufferFormatter* f) const;
|
| -
|
| private:
|
| const intptr_t token_pos_;
|
|
|
| @@ -1302,9 +1305,6 @@ class ThrowInstr : public TemplateInstruction<0> {
|
|
|
| virtual bool HasSideEffect() const { return true; }
|
|
|
| - virtual void PrintTo(BufferFormatter* f) const;
|
| - virtual void PrintToVisualizer(BufferFormatter* f) const;
|
| -
|
| private:
|
| const intptr_t token_pos_;
|
|
|
| @@ -1326,9 +1326,6 @@ class ReThrowInstr : public TemplateInstruction<0> {
|
|
|
| virtual bool HasSideEffect() const { return true; }
|
|
|
| - virtual void PrintTo(BufferFormatter* f) const;
|
| - virtual void PrintToVisualizer(BufferFormatter* f) const;
|
| -
|
| private:
|
| const intptr_t token_pos_;
|
|
|
| @@ -1458,6 +1455,29 @@ class BranchInstr : public ControlInstruction {
|
| };
|
|
|
|
|
| +class StoreContextInstr : public TemplateInstruction<1> {
|
| + public:
|
| + explicit StoreContextInstr(Value* value) {
|
| + ASSERT(value != NULL);
|
| + inputs_[0] = value;
|
| + }
|
| +
|
| + DECLARE_INSTRUCTION(StoreContext);
|
| + virtual RawAbstractType* CompileType() const;
|
| +
|
| + virtual intptr_t ArgumentCount() const { return 0; }
|
| +
|
| + Value* value() const { return inputs_[0]; }
|
| +
|
| + virtual bool CanDeoptimize() const { return false; }
|
| +
|
| + virtual bool HasSideEffect() const { return false; }
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(StoreContextInstr);
|
| +};
|
| +
|
| +
|
| template<intptr_t N>
|
| class TemplateDefinition : public Definition {
|
| public:
|
| @@ -1506,7 +1526,7 @@ class ConstantInstr : public TemplateDefinition<0> {
|
|
|
| virtual intptr_t ResultCid() const;
|
|
|
| - virtual bool AttributesEqual(Definition* other) const;
|
| + virtual bool AttributesEqual(Instruction* other) const;
|
| virtual bool AffectedBySideEffect() const { return false; }
|
|
|
| private:
|
| @@ -1670,29 +1690,6 @@ class CurrentContextInstr : public TemplateDefinition<0> {
|
| };
|
|
|
|
|
| -class StoreContextInstr : public TemplateDefinition<1> {
|
| - public:
|
| - explicit StoreContextInstr(Value* value) {
|
| - ASSERT(value != NULL);
|
| - inputs_[0] = value;
|
| - }
|
| -
|
| - DECLARE_INSTRUCTION(StoreContext);
|
| - virtual RawAbstractType* CompileType() const;
|
| -
|
| - Value* value() const { return inputs_[0]; }
|
| -
|
| - virtual bool CanDeoptimize() const { return false; }
|
| -
|
| - virtual bool HasSideEffect() const { return false; }
|
| -
|
| - virtual intptr_t ResultCid() const { return kIllegalCid; }
|
| -
|
| - private:
|
| - DISALLOW_COPY_AND_ASSIGN(StoreContextInstr);
|
| -};
|
| -
|
| -
|
| class ClosureCallInstr : public TemplateDefinition<0> {
|
| public:
|
| ClosureCallInstr(ClosureCallNode* node,
|
| @@ -1928,7 +1925,7 @@ class StrictCompareInstr : public ComparisonInstr {
|
|
|
| virtual bool HasSideEffect() const { return false; }
|
|
|
| - virtual bool AttributesEqual(Definition* other) const;
|
| + virtual bool AttributesEqual(Instruction* other) const;
|
| virtual bool AffectedBySideEffect() const { return false; }
|
|
|
| virtual Definition* Canonicalize();
|
| @@ -2290,7 +2287,7 @@ class LoadStaticFieldInstr : public TemplateDefinition<0> {
|
| virtual intptr_t ResultCid() const { return kDynamicCid; }
|
|
|
| virtual bool AffectedBySideEffect() const { return !field().is_final(); }
|
| - virtual bool AttributesEqual(Definition* other) const;
|
| + virtual bool AttributesEqual(Instruction* other) const;
|
|
|
| private:
|
| const Field& field_;
|
| @@ -2651,7 +2648,7 @@ class LoadFieldInstr : public TemplateDefinition<1> {
|
|
|
| virtual intptr_t ResultCid() const { return result_cid_; }
|
|
|
| - virtual bool AttributesEqual(Definition* other) const;
|
| + virtual bool AttributesEqual(Instruction* other) const;
|
|
|
| virtual bool AffectedBySideEffect() const { return !immutable_; }
|
|
|
| @@ -2838,7 +2835,7 @@ class AllocateContextInstr : public TemplateDefinition<0> {
|
| };
|
|
|
|
|
| -class ChainContextInstr : public TemplateDefinition<1> {
|
| +class ChainContextInstr : public TemplateInstruction<1> {
|
| public:
|
| explicit ChainContextInstr(Value* context_value) {
|
| ASSERT(context_value != NULL);
|
| @@ -2848,14 +2845,14 @@ class ChainContextInstr : public TemplateDefinition<1> {
|
| DECLARE_INSTRUCTION(ChainContext)
|
| virtual RawAbstractType* CompileType() const;
|
|
|
| + virtual intptr_t ArgumentCount() const { return 0; }
|
| +
|
| Value* context_value() const { return inputs_[0]; }
|
|
|
| virtual bool CanDeoptimize() const { return false; }
|
|
|
| virtual bool HasSideEffect() const { return true; }
|
|
|
| - virtual intptr_t ResultCid() const { return kIllegalCid; }
|
| -
|
| private:
|
| DISALLOW_COPY_AND_ASSIGN(ChainContextInstr);
|
| };
|
| @@ -2879,7 +2876,7 @@ class CloneContextInstr : public TemplateDefinition<1> {
|
|
|
| virtual bool HasSideEffect() const { return false; }
|
|
|
| - virtual intptr_t ResultCid() const { return kIllegalCid; }
|
| + virtual intptr_t ResultCid() const { return kContextCid; }
|
|
|
| private:
|
| const intptr_t token_pos_;
|
| @@ -2888,7 +2885,7 @@ class CloneContextInstr : public TemplateDefinition<1> {
|
| };
|
|
|
|
|
| -class CatchEntryInstr : public TemplateDefinition<0> {
|
| +class CatchEntryInstr : public TemplateInstruction<0> {
|
| public:
|
| CatchEntryInstr(const LocalVariable& exception_var,
|
| const LocalVariable& stacktrace_var)
|
| @@ -2900,14 +2897,14 @@ class CatchEntryInstr : public TemplateDefinition<0> {
|
| DECLARE_INSTRUCTION(CatchEntry)
|
| virtual RawAbstractType* CompileType() const;
|
|
|
| + virtual intptr_t ArgumentCount() const { return 0; }
|
| +
|
| virtual void PrintOperandsTo(BufferFormatter* f) const;
|
|
|
| virtual bool CanDeoptimize() const { return false; }
|
|
|
| virtual bool HasSideEffect() const { return true; }
|
|
|
| - virtual intptr_t ResultCid() const { return kIllegalCid; }
|
| -
|
| private:
|
| const LocalVariable& exception_var_;
|
| const LocalVariable& stacktrace_var_;
|
| @@ -2916,7 +2913,7 @@ class CatchEntryInstr : public TemplateDefinition<0> {
|
| };
|
|
|
|
|
| -class CheckEitherNonSmiInstr : public TemplateDefinition<2> {
|
| +class CheckEitherNonSmiInstr : public TemplateInstruction<2> {
|
| public:
|
| CheckEitherNonSmiInstr(Value* left,
|
| Value* right,
|
| @@ -2931,13 +2928,13 @@ class CheckEitherNonSmiInstr : public TemplateDefinition<2> {
|
| DECLARE_INSTRUCTION(CheckEitherNonSmi)
|
| virtual RawAbstractType* CompileType() const;
|
|
|
| + virtual intptr_t ArgumentCount() const { return 0; }
|
| +
|
| virtual bool CanDeoptimize() const { return true; }
|
|
|
| virtual bool HasSideEffect() const { return false; }
|
|
|
| - virtual intptr_t ResultCid() const { return kIllegalCid; }
|
| -
|
| - virtual bool AttributesEqual(Definition* other) const { return true; }
|
| + virtual bool AttributesEqual(Instruction* other) const { return true; }
|
|
|
| virtual bool AffectedBySideEffect() const { return false; }
|
|
|
| @@ -2945,7 +2942,7 @@ class CheckEitherNonSmiInstr : public TemplateDefinition<2> {
|
|
|
| Value* right() const { return inputs_[1]; }
|
|
|
| - virtual Definition* Canonicalize();
|
| + virtual Instruction* Canonicalize();
|
|
|
| private:
|
| DISALLOW_COPY_AND_ASSIGN(CheckEitherNonSmiInstr);
|
| @@ -2969,7 +2966,7 @@ class BoxDoubleInstr : public TemplateDefinition<1> {
|
| virtual bool HasSideEffect() const { return false; }
|
|
|
| virtual bool AffectedBySideEffect() const { return false; }
|
| - virtual bool AttributesEqual(Definition* other) const { return true; }
|
| + virtual bool AttributesEqual(Instruction* other) const { return true; }
|
|
|
| virtual intptr_t ResultCid() const;
|
|
|
| @@ -3013,7 +3010,7 @@ class UnboxDoubleInstr : public TemplateDefinition<1> {
|
| }
|
|
|
| virtual bool AffectedBySideEffect() const { return false; }
|
| - virtual bool AttributesEqual(Definition* other) const { return true; }
|
| + virtual bool AttributesEqual(Instruction* other) const { return true; }
|
|
|
| DECLARE_INSTRUCTION(UnboxDouble)
|
| virtual RawAbstractType* CompileType() const;
|
| @@ -3037,7 +3034,7 @@ class MathSqrtInstr : public TemplateDefinition<1> {
|
|
|
| virtual bool HasSideEffect() const { return false; }
|
|
|
| - virtual bool AttributesEqual(Definition* other) const {
|
| + virtual bool AttributesEqual(Instruction* other) const {
|
| return true;
|
| }
|
|
|
| @@ -3094,7 +3091,7 @@ class UnboxedDoubleBinaryOpInstr : public TemplateDefinition<2> {
|
|
|
| virtual bool AffectedBySideEffect() const { return false; }
|
|
|
| - virtual bool AttributesEqual(Definition* other) const {
|
| + virtual bool AttributesEqual(Instruction* other) const {
|
| return op_kind() == other->AsUnboxedDoubleBinaryOp()->op_kind();
|
| }
|
|
|
| @@ -3159,7 +3156,7 @@ class BinarySmiOpInstr : public TemplateDefinition<2> {
|
| virtual bool HasSideEffect() const { return false; }
|
|
|
| virtual bool AffectedBySideEffect() const { return false; }
|
| - virtual bool AttributesEqual(Definition* other) const;
|
| + virtual bool AttributesEqual(Instruction* other) const;
|
|
|
| virtual intptr_t ResultCid() const;
|
|
|
| @@ -3249,7 +3246,7 @@ class UnarySmiOpInstr : public TemplateDefinition<1> {
|
| };
|
|
|
|
|
| -class CheckStackOverflowInstr : public TemplateDefinition<0> {
|
| +class CheckStackOverflowInstr : public TemplateInstruction<0> {
|
| public:
|
| explicit CheckStackOverflowInstr(intptr_t token_pos)
|
| : token_pos_(token_pos) {}
|
| @@ -3259,12 +3256,12 @@ class CheckStackOverflowInstr : public TemplateDefinition<0> {
|
| DECLARE_INSTRUCTION(CheckStackOverflow)
|
| virtual RawAbstractType* CompileType() const;
|
|
|
| + virtual intptr_t ArgumentCount() const { return 0; }
|
| +
|
| virtual bool CanDeoptimize() const { return false; }
|
|
|
| virtual bool HasSideEffect() const { return false; }
|
|
|
| - virtual intptr_t ResultCid() const { return kIllegalCid; }
|
| -
|
| private:
|
| const intptr_t token_pos_;
|
|
|
| @@ -3325,7 +3322,7 @@ class SmiToDoubleInstr : public TemplateDefinition<0> {
|
| };
|
|
|
|
|
| -class CheckClassInstr : public TemplateDefinition<1> {
|
| +class CheckClassInstr : public TemplateInstruction<1> {
|
| public:
|
| CheckClassInstr(Value* value,
|
| InstanceCallInstr* instance_call,
|
| @@ -3339,13 +3336,13 @@ class CheckClassInstr : public TemplateDefinition<1> {
|
| DECLARE_INSTRUCTION(CheckClass)
|
| virtual RawAbstractType* CompileType() const;
|
|
|
| + virtual intptr_t ArgumentCount() const { return 0; }
|
| +
|
| virtual bool CanDeoptimize() const { return true; }
|
|
|
| virtual bool HasSideEffect() const { return false; }
|
|
|
| - virtual intptr_t ResultCid() const { return kIllegalCid; }
|
| -
|
| - virtual bool AttributesEqual(Definition* other) const;
|
| + virtual bool AttributesEqual(Instruction* other) const;
|
|
|
| virtual bool AffectedBySideEffect() const { return false; }
|
|
|
| @@ -3353,7 +3350,7 @@ class CheckClassInstr : public TemplateDefinition<1> {
|
|
|
| const ICData& unary_checks() const { return unary_checks_; }
|
|
|
| - virtual Definition* Canonicalize();
|
| + virtual Instruction* Canonicalize();
|
|
|
| virtual void PrintOperandsTo(BufferFormatter* f) const;
|
|
|
| @@ -3364,7 +3361,7 @@ class CheckClassInstr : public TemplateDefinition<1> {
|
| };
|
|
|
|
|
| -class CheckSmiInstr : public TemplateDefinition<1> {
|
| +class CheckSmiInstr : public TemplateInstruction<1> {
|
| public:
|
| CheckSmiInstr(Value* value, intptr_t original_deopt_id) {
|
| ASSERT(value != NULL);
|
| @@ -3376,17 +3373,17 @@ class CheckSmiInstr : public TemplateDefinition<1> {
|
| DECLARE_INSTRUCTION(CheckSmi)
|
| virtual RawAbstractType* CompileType() const;
|
|
|
| + virtual intptr_t ArgumentCount() const { return 0; }
|
| +
|
| virtual bool CanDeoptimize() const { return true; }
|
|
|
| virtual bool HasSideEffect() const { return false; }
|
|
|
| - virtual intptr_t ResultCid() const { return kIllegalCid; }
|
| -
|
| - virtual bool AttributesEqual(Definition* other) const { return true; }
|
| + virtual bool AttributesEqual(Instruction* other) const { return true; }
|
|
|
| virtual bool AffectedBySideEffect() const { return false; }
|
|
|
| - virtual Definition* Canonicalize();
|
| + virtual Instruction* Canonicalize();
|
|
|
| Value* value() const { return inputs_[0]; }
|
|
|
| @@ -3395,7 +3392,7 @@ class CheckSmiInstr : public TemplateDefinition<1> {
|
| };
|
|
|
|
|
| -class CheckArrayBoundInstr : public TemplateDefinition<2> {
|
| +class CheckArrayBoundInstr : public TemplateInstruction<2> {
|
| public:
|
| CheckArrayBoundInstr(Value* array,
|
| Value* index,
|
| @@ -3412,13 +3409,13 @@ class CheckArrayBoundInstr : public TemplateDefinition<2> {
|
| DECLARE_INSTRUCTION(CheckArrayBound)
|
| virtual RawAbstractType* CompileType() const;
|
|
|
| + virtual intptr_t ArgumentCount() const { return 0; }
|
| +
|
| virtual bool CanDeoptimize() const { return true; }
|
|
|
| virtual bool HasSideEffect() const { return false; }
|
|
|
| - virtual intptr_t ResultCid() const { return kIllegalCid; }
|
| -
|
| - virtual bool AttributesEqual(Definition* other) const;
|
| + virtual bool AttributesEqual(Instruction* other) const;
|
|
|
| virtual bool AffectedBySideEffect() const { return false; }
|
|
|
|
|