| Index: runtime/vm/intermediate_language.h
|
| diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
|
| index c99d69bf9c3c4604060688445e0404b298c666cf..d02f2957c99ddc4876f8b07cdf6f21d908391f77 100644
|
| --- a/runtime/vm/intermediate_language.h
|
| +++ b/runtime/vm/intermediate_language.h
|
| @@ -781,6 +781,10 @@ FOR_EACH_ABSTRACT_INSTRUCTION(INSTRUCTION_TYPE_CHECK)
|
| // instruction.
|
| Instruction* AppendInstruction(Instruction* tail);
|
|
|
| + virtual bool AllowsDCE() const {
|
| + return false;
|
| + }
|
| +
|
| // Returns true if CSE and LICM are allowed for this instruction.
|
| virtual bool AllowsCSE() const {
|
| return false;
|
| @@ -834,6 +838,8 @@ FOR_EACH_ABSTRACT_INSTRUCTION(INSTRUCTION_TYPE_CHECK)
|
|
|
| virtual bool MayThrow() const = 0;
|
|
|
| + bool IsDominatedBy(Instruction* dom);
|
| +
|
| protected:
|
| // Fetch deopt id without checking if this computation can deoptimize.
|
| intptr_t GetDeoptId() const {
|
| @@ -893,6 +899,7 @@ FOR_EACH_ABSTRACT_INSTRUCTION(INSTRUCTION_TYPE_CHECK)
|
| friend class CheckArrayBoundInstr;
|
| friend class CheckEitherNonSmiInstr;
|
| friend class LICM;
|
| + friend class Scheduler;
|
| friend class DoubleToSmiInstr;
|
| friend class DoubleToDoubleInstr;
|
| friend class DoubleToFloatInstr;
|
| @@ -1106,6 +1113,7 @@ class BlockEntryInstr : public Instruction {
|
| intptr_t end_pos() const { return end_pos_; }
|
|
|
| BlockEntryInstr* dominator() const { return dominator_; }
|
| + BlockEntryInstr* ImmediateDominator() const;
|
|
|
| const GrowableArray<BlockEntryInstr*>& dominated_blocks() {
|
| return dominated_blocks_;
|
| @@ -1850,6 +1858,9 @@ struct BranchLabels {
|
| };
|
|
|
|
|
| +struct InductionVariableInfo;
|
| +
|
| +
|
| class PhiInstr : public Definition {
|
| public:
|
| PhiInstr(JoinEntryInstr* block, intptr_t num_inputs)
|
| @@ -1857,7 +1868,8 @@ class PhiInstr : public Definition {
|
| inputs_(num_inputs),
|
| is_alive_(false),
|
| representation_(kTagged),
|
| - reaching_defs_(NULL) {
|
| + reaching_defs_(NULL),
|
| + loop_variable_info_(NULL) {
|
| for (intptr_t i = 0; i < num_inputs; ++i) {
|
| inputs_.Add(NULL);
|
| }
|
| @@ -1921,6 +1933,14 @@ class PhiInstr : public Definition {
|
| // A phi is redundant if all input operands are the same.
|
| bool IsRedundant() const;
|
|
|
| + void set_induction_variable_info(InductionVariableInfo* info) {
|
| + loop_variable_info_ = info;
|
| + }
|
| +
|
| + InductionVariableInfo* induction_variable_info() {
|
| + return loop_variable_info_;
|
| + }
|
| +
|
| private:
|
| // Direct access to inputs_ in order to resize it due to unreachable
|
| // predecessors.
|
| @@ -1934,6 +1954,7 @@ class PhiInstr : public Definition {
|
| Representation representation_;
|
|
|
| BitVector* reaching_defs_;
|
| + InductionVariableInfo* loop_variable_info_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(PhiInstr);
|
| };
|
| @@ -2411,7 +2432,7 @@ class RedefinitionInstr : public TemplateDefinition<1> {
|
| };
|
|
|
|
|
| -class ConstraintInstr : public TemplateDefinition<2> {
|
| +class ConstraintInstr : public TemplateDefinition<1> {
|
| public:
|
| ConstraintInstr(Value* value, Range* constraint)
|
| : constraint_(constraint),
|
| @@ -2421,10 +2442,6 @@ class ConstraintInstr : public TemplateDefinition<2> {
|
|
|
| DECLARE_INSTRUCTION(Constraint)
|
|
|
| - virtual intptr_t InputCount() const {
|
| - return (inputs_[1] == NULL) ? 1 : 2;
|
| - }
|
| -
|
| virtual CompileType ComputeType() const;
|
|
|
| virtual bool CanDeoptimize() const { return false; }
|
| @@ -2445,12 +2462,6 @@ class ConstraintInstr : public TemplateDefinition<2> {
|
|
|
| virtual void InferRange(RangeAnalysis* analysis, Range* range);
|
|
|
| - void AddDependency(Definition* defn) {
|
| - Value* val = new Value(defn);
|
| - defn->AddInputUse(val);
|
| - SetInputAt(1, val);
|
| - }
|
| -
|
| // Constraints for branches have their target block stored in order
|
| // to find the the comparsion that generated the constraint:
|
| // target->predecessor->last_instruction->comparison.
|
| @@ -2462,10 +2473,6 @@ class ConstraintInstr : public TemplateDefinition<2> {
|
| }
|
|
|
| private:
|
| - Value* dependency() {
|
| - return inputs_[1];
|
| - }
|
| -
|
| Range* constraint_;
|
| TargetEntryInstr* target_;
|
|
|
| @@ -6937,6 +6944,25 @@ class BinaryIntegerOpInstr : public TemplateDefinition<2> {
|
|
|
| virtual Definition* Canonicalize(FlowGraph* flow_graph);
|
|
|
| + virtual bool AllowsDCE() const {
|
| + switch (op_kind()) {
|
| + case Token::kADD:
|
| + case Token::kSUB:
|
| + case Token::kMUL:
|
| + case Token::kBIT_AND:
|
| + case Token::kBIT_OR:
|
| + case Token::kBIT_XOR:
|
| + return true;
|
| +
|
| + case Token::kSHR:
|
| + case Token::kSHL:
|
| + // These instructions throw on negative shifts.
|
| + return !CanDeoptimize();
|
| +
|
| + default:
|
| + return false;
|
| + }
|
| + }
|
| virtual bool AllowsCSE() const { return true; }
|
| virtual EffectSet Effects() const { return EffectSet::None(); }
|
| virtual EffectSet Dependencies() const { return EffectSet::None(); }
|
| @@ -7907,7 +7933,8 @@ class CheckClassIdInstr : public TemplateInstruction<1> {
|
|
|
| class CheckArrayBoundInstr : public TemplateInstruction<2> {
|
| public:
|
| - CheckArrayBoundInstr(Value* length, Value* index, intptr_t deopt_id) {
|
| + CheckArrayBoundInstr(Value* length, Value* index, intptr_t deopt_id)
|
| + : generalized_(false) {
|
| SetInputAt(kLengthPos, length);
|
| SetInputAt(kIndexPos, index);
|
| // Override generated deopt-id.
|
| @@ -7925,6 +7952,10 @@ class CheckArrayBoundInstr : public TemplateInstruction<2> {
|
|
|
| bool IsRedundant(const RangeBoundary& length);
|
|
|
| + void mark_generalized() {
|
| + generalized_ = true;
|
| + }
|
| +
|
| virtual Instruction* Canonicalize(FlowGraph* flow_graph);
|
|
|
| // Returns the length offset for array and string types.
|
| @@ -7946,6 +7977,8 @@ class CheckArrayBoundInstr : public TemplateInstruction<2> {
|
| };
|
|
|
| private:
|
| + bool generalized_;
|
| +
|
| DISALLOW_COPY_AND_ASSIGN(CheckArrayBoundInstr);
|
| };
|
|
|
|
|