escape-analysis-reducer.h 3.91 KB
Newer Older
1
// Copyright 2017 the V8 project authors. All rights reserved.
2 3 4 5 6 7
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_COMPILER_ESCAPE_ANALYSIS_REDUCER_H_
#define V8_COMPILER_ESCAPE_ANALYSIS_REDUCER_H_

8
#include "src/base/compiler-specific.h"
9
#include "src/common/globals.h"
10
#include "src/compiler/access-builder.h"
11 12 13 14 15 16 17
#include "src/compiler/escape-analysis.h"
#include "src/compiler/graph-reducer.h"

namespace v8 {
namespace internal {
namespace compiler {

18
class Deduplicator;
19 20
class JSGraph;

21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
// Perform hash-consing when creating or mutating nodes. Used to avoid duplicate
// nodes when creating ObjectState, StateValues and FrameState nodes
class NodeHashCache {
 public:
  NodeHashCache(Graph* graph, Zone* zone)
      : graph_(graph), cache_(zone), temp_nodes_(zone) {}

  // Handle to a conceptually new mutable node. Tries to re-use existing nodes
  // and to recycle memory if possible.
  class Constructor {
   public:
    // Construct a new node as a clone of [from].
    Constructor(NodeHashCache* cache, Node* from)
        : node_cache_(cache), from_(from), tmp_(nullptr) {}
    // Construct a new node from scratch.
    Constructor(NodeHashCache* cache, const Operator* op, int input_count,
37
                Node** inputs, Type type);
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82

    // Modify the new node.
    void ReplaceValueInput(Node* input, int i) {
      if (!tmp_ && input == NodeProperties::GetValueInput(from_, i)) return;
      Node* node = MutableNode();
      NodeProperties::ReplaceValueInput(node, input, i);
    }
    void ReplaceInput(Node* input, int i) {
      if (!tmp_ && input == from_->InputAt(i)) return;
      Node* node = MutableNode();
      node->ReplaceInput(i, input);
    }

    // Obtain the mutated node or a cached copy. Invalidates the [Constructor].
    Node* Get();

   private:
    Node* MutableNode();

    NodeHashCache* node_cache_;
    // Original node, copied on write.
    Node* from_;
    // Temporary node used for mutations, can be recycled if cache is hit.
    Node* tmp_;
  };

 private:
  Node* Query(Node* node);
  void Insert(Node* node) { cache_.insert(node); }

  Graph* graph_;
  struct NodeEquals {
    bool operator()(Node* a, Node* b) const {
      return NodeProperties::Equals(a, b);
    }
  };
  struct NodeHashCode {
    size_t operator()(Node* n) const { return NodeProperties::HashCode(n); }
  };
  ZoneUnorderedSet<Node*, NodeHashCode, NodeEquals> cache_;
  // Unused nodes whose memory can be recycled.
  ZoneVector<Node*> temp_nodes_;
};

// Modify the graph according to the information computed in the previous phase.
83 84
class V8_EXPORT_PRIVATE EscapeAnalysisReducer final
    : public NON_EXPORTED_BASE(AdvancedReducer) {
85 86
 public:
  EscapeAnalysisReducer(Editor* editor, JSGraph* jsgraph,
87
                        EscapeAnalysisResult analysis_result, Zone* zone);
88

89
  Reduction Reduce(Node* node) override;
90
  const char* reducer_name() const override { return "EscapeAnalysisReducer"; }
91 92
  void Finalize() override;

93
  // Verifies that all virtual allocation nodes have been dealt with. Run it
94
  // after this reducer has been applied.
95
  void VerifyReplacement() const;
96 97

 private:
98 99 100
  void ReduceFrameStateInputs(Node* node);
  Node* ReduceDeoptState(Node* node, Node* effect, Deduplicator* deduplicator);
  Node* ObjectIdNode(const VirtualObject* vobject);
101
  Reduction ReplaceNode(Node* original, Node* replacement);
102 103

  JSGraph* jsgraph() const { return jsgraph_; }
104
  Isolate* isolate() const { return jsgraph_->isolate(); }
105
  EscapeAnalysisResult analysis_result() const { return analysis_result_; }
106 107 108
  Zone* zone() const { return zone_; }

  JSGraph* const jsgraph_;
109 110 111 112
  EscapeAnalysisResult analysis_result_;
  ZoneVector<Node*> object_id_cache_;
  NodeHashCache node_cache_;
  ZoneSet<Node*> arguments_elements_;
113 114 115 116 117 118 119 120 121 122
  Zone* const zone_;

  DISALLOW_COPY_AND_ASSIGN(EscapeAnalysisReducer);
};

}  // namespace compiler
}  // namespace internal
}  // namespace v8

#endif  // V8_COMPILER_ESCAPE_ANALYSIS_REDUCER_H_