| Index: src/hydrogen-flow-engine.h
 | 
| diff --git a/src/hydrogen-flow-engine.h b/src/hydrogen-flow-engine.h
 | 
| deleted file mode 100644
 | 
| index 9735ea811aee9712a0f439d62f3651a91ec5b3b0..0000000000000000000000000000000000000000
 | 
| --- a/src/hydrogen-flow-engine.h
 | 
| +++ /dev/null
 | 
| @@ -1,220 +0,0 @@
 | 
| -// Copyright 2013 the V8 project authors. All rights reserved.
 | 
| -// Use of this source code is governed by a BSD-style license that can be
 | 
| -// found in the LICENSE file.
 | 
| -
 | 
| -#ifndef V8_HYDROGEN_FLOW_ENGINE_H_
 | 
| -#define V8_HYDROGEN_FLOW_ENGINE_H_
 | 
| -
 | 
| -#include "src/hydrogen.h"
 | 
| -#include "src/hydrogen-instructions.h"
 | 
| -#include "src/zone.h"
 | 
| -
 | 
| -namespace v8 {
 | 
| -namespace internal {
 | 
| -
 | 
| -// An example implementation of effects that doesn't collect anything.
 | 
| -class NoEffects : public ZoneObject {
 | 
| - public:
 | 
| -  explicit NoEffects(Zone* zone) { }
 | 
| -
 | 
| -  inline bool Disabled() {
 | 
| -    return true;  // Nothing to do.
 | 
| -  }
 | 
| -  template <class State>
 | 
| -  inline void Apply(State* state) {
 | 
| -    // do nothing.
 | 
| -  }
 | 
| -  inline void Process(HInstruction* value, Zone* zone) {
 | 
| -    // do nothing.
 | 
| -  }
 | 
| -  inline void Union(NoEffects* other, Zone* zone) {
 | 
| -    // do nothing.
 | 
| -  }
 | 
| -};
 | 
| -
 | 
| -
 | 
| -// An example implementation of state that doesn't track anything.
 | 
| -class NoState {
 | 
| - public:
 | 
| -  inline NoState* Copy(HBasicBlock* succ, Zone* zone) {
 | 
| -    return this;
 | 
| -  }
 | 
| -  inline NoState* Process(HInstruction* value, Zone* zone) {
 | 
| -    return this;
 | 
| -  }
 | 
| -  inline NoState* Merge(HBasicBlock* succ, NoState* other, Zone* zone) {
 | 
| -    return this;
 | 
| -  }
 | 
| -};
 | 
| -
 | 
| -
 | 
| -// This class implements an engine that can drive flow-sensitive analyses
 | 
| -// over a graph of basic blocks, either one block at a time (local analysis)
 | 
| -// or over the entire graph (global analysis). The flow engine is parameterized
 | 
| -// by the type of the state and the effects collected while walking over the
 | 
| -// graph.
 | 
| -//
 | 
| -// The "State" collects which facts are known while passing over instructions
 | 
| -// in control flow order, and the "Effects" collect summary information about
 | 
| -// which facts could be invalidated on other control flow paths. The effects
 | 
| -// are necessary to correctly handle loops in the control flow graph without
 | 
| -// doing a fixed-point iteration. Thus the flow engine is guaranteed to visit
 | 
| -// each block at most twice; once for state, and optionally once for effects.
 | 
| -//
 | 
| -// The flow engine requires the State and Effects classes to implement methods
 | 
| -// like the example NoState and NoEffects above. It's not necessary to provide
 | 
| -// an effects implementation for local analysis.
 | 
| -template <class State, class Effects>
 | 
| -class HFlowEngine {
 | 
| - public:
 | 
| -  HFlowEngine(HGraph* graph, Zone* zone)
 | 
| -    : graph_(graph),
 | 
| -      zone_(zone),
 | 
| -#if DEBUG
 | 
| -      pred_counts_(graph->blocks()->length(), zone),
 | 
| -#endif
 | 
| -      block_states_(graph->blocks()->length(), zone),
 | 
| -      loop_effects_(graph->blocks()->length(), zone) {
 | 
| -    loop_effects_.AddBlock(NULL, graph_->blocks()->length(), zone);
 | 
| -  }
 | 
| -
 | 
| -  // Local analysis. Iterates over the instructions in the given block.
 | 
| -  State* AnalyzeOneBlock(HBasicBlock* block, State* state) {
 | 
| -    // Go through all instructions of the current block, updating the state.
 | 
| -    for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
 | 
| -      state = state->Process(it.Current(), zone_);
 | 
| -    }
 | 
| -    return state;
 | 
| -  }
 | 
| -
 | 
| -  // Global analysis. Iterates over all blocks that are dominated by the given
 | 
| -  // block, starting with the initial state. Computes effects for nested loops.
 | 
| -  void AnalyzeDominatedBlocks(HBasicBlock* root, State* initial) {
 | 
| -    InitializeStates();
 | 
| -    SetStateAt(root, initial);
 | 
| -
 | 
| -    // Iterate all dominated blocks starting from the given start block.
 | 
| -    for (int i = root->block_id(); i < graph_->blocks()->length(); i++) {
 | 
| -      HBasicBlock* block = graph_->blocks()->at(i);
 | 
| -
 | 
| -      // Skip blocks not dominated by the root node.
 | 
| -      if (SkipNonDominatedBlock(root, block)) continue;
 | 
| -      State* state = State::Finish(StateAt(block), block, zone_);
 | 
| -
 | 
| -      if (block->IsReachable()) {
 | 
| -        DCHECK(state != NULL);
 | 
| -        if (block->IsLoopHeader()) {
 | 
| -          // Apply loop effects before analyzing loop body.
 | 
| -          ComputeLoopEffects(block)->Apply(state);
 | 
| -        } else {
 | 
| -          // Must have visited all predecessors before this block.
 | 
| -          CheckPredecessorCount(block);
 | 
| -        }
 | 
| -
 | 
| -        // Go through all instructions of the current block, updating the state.
 | 
| -        for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
 | 
| -          state = state->Process(it.Current(), zone_);
 | 
| -        }
 | 
| -      }
 | 
| -
 | 
| -      // Propagate the block state forward to all successor blocks.
 | 
| -      int max = block->end()->SuccessorCount();
 | 
| -      for (int i = 0; i < max; i++) {
 | 
| -        HBasicBlock* succ = block->end()->SuccessorAt(i);
 | 
| -        IncrementPredecessorCount(succ);
 | 
| -
 | 
| -        if (max == 1 && succ->predecessors()->length() == 1) {
 | 
| -          // Optimization: successor can inherit this state.
 | 
| -          SetStateAt(succ, state);
 | 
| -        } else {
 | 
| -          // Merge the current state with the state already at the successor.
 | 
| -          SetStateAt(succ,
 | 
| -                     State::Merge(StateAt(succ), succ, state, block, zone_));
 | 
| -        }
 | 
| -      }
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| - private:
 | 
| -  // Computes and caches the loop effects for the loop which has the given
 | 
| -  // block as its loop header.
 | 
| -  Effects* ComputeLoopEffects(HBasicBlock* block) {
 | 
| -    DCHECK(block->IsLoopHeader());
 | 
| -    Effects* effects = loop_effects_[block->block_id()];
 | 
| -    if (effects != NULL) return effects;  // Already analyzed this loop.
 | 
| -
 | 
| -    effects = new(zone_) Effects(zone_);
 | 
| -    loop_effects_[block->block_id()] = effects;
 | 
| -    if (effects->Disabled()) return effects;  // No effects for this analysis.
 | 
| -
 | 
| -    HLoopInformation* loop = block->loop_information();
 | 
| -    int end = loop->GetLastBackEdge()->block_id();
 | 
| -    // Process the blocks between the header and the end.
 | 
| -    for (int i = block->block_id(); i <= end; i++) {
 | 
| -      HBasicBlock* member = graph_->blocks()->at(i);
 | 
| -      if (i != block->block_id() && member->IsLoopHeader()) {
 | 
| -        // Recursively compute and cache the effects of the nested loop.
 | 
| -        DCHECK(member->loop_information()->parent_loop() == loop);
 | 
| -        Effects* nested = ComputeLoopEffects(member);
 | 
| -        effects->Union(nested, zone_);
 | 
| -        // Skip the nested loop's blocks.
 | 
| -        i = member->loop_information()->GetLastBackEdge()->block_id();
 | 
| -      } else {
 | 
| -        // Process all the effects of the block.
 | 
| -        if (member->IsUnreachable()) continue;
 | 
| -        DCHECK(member->current_loop() == loop);
 | 
| -        for (HInstructionIterator it(member); !it.Done(); it.Advance()) {
 | 
| -          effects->Process(it.Current(), zone_);
 | 
| -        }
 | 
| -      }
 | 
| -    }
 | 
| -    return effects;
 | 
| -  }
 | 
| -
 | 
| -  inline bool SkipNonDominatedBlock(HBasicBlock* root, HBasicBlock* other) {
 | 
| -    if (root->block_id() == 0) return false;  // Visit the whole graph.
 | 
| -    if (root == other) return false;          // Always visit the root.
 | 
| -    return !root->Dominates(other);           // Only visit dominated blocks.
 | 
| -  }
 | 
| -
 | 
| -  inline State* StateAt(HBasicBlock* block) {
 | 
| -    return block_states_.at(block->block_id());
 | 
| -  }
 | 
| -
 | 
| -  inline void SetStateAt(HBasicBlock* block, State* state) {
 | 
| -    block_states_.Set(block->block_id(), state);
 | 
| -  }
 | 
| -
 | 
| -  inline void InitializeStates() {
 | 
| -#if DEBUG
 | 
| -    pred_counts_.Rewind(0);
 | 
| -    pred_counts_.AddBlock(0, graph_->blocks()->length(), zone_);
 | 
| -#endif
 | 
| -    block_states_.Rewind(0);
 | 
| -    block_states_.AddBlock(NULL, graph_->blocks()->length(), zone_);
 | 
| -  }
 | 
| -
 | 
| -  inline void CheckPredecessorCount(HBasicBlock* block) {
 | 
| -    DCHECK(block->predecessors()->length() == pred_counts_[block->block_id()]);
 | 
| -  }
 | 
| -
 | 
| -  inline void IncrementPredecessorCount(HBasicBlock* block) {
 | 
| -#if DEBUG
 | 
| -    pred_counts_[block->block_id()]++;
 | 
| -#endif
 | 
| -  }
 | 
| -
 | 
| -  HGraph* graph_;                    // The hydrogen graph.
 | 
| -  Zone* zone_;                       // Temporary zone.
 | 
| -#if DEBUG
 | 
| -  ZoneList<int> pred_counts_;        // Finished predecessors (by block id).
 | 
| -#endif
 | 
| -  ZoneList<State*> block_states_;    // Block states (by block id).
 | 
| -  ZoneList<Effects*> loop_effects_;  // Loop effects (by block id).
 | 
| -};
 | 
| -
 | 
| -
 | 
| -}  // namespace internal
 | 
| -}  // namespace v8
 | 
| -
 | 
| -#endif  // V8_HYDROGEN_FLOW_ENGINE_H_
 | 
| 
 |