Line data Source code
1 : // Copyright 2017 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #ifndef V8_COMPILER_ESCAPE_ANALYSIS_REDUCER_H_
6 : #define V8_COMPILER_ESCAPE_ANALYSIS_REDUCER_H_
7 :
8 : #include "src/base/compiler-specific.h"
9 : #include "src/compiler/escape-analysis.h"
10 : #include "src/compiler/graph-reducer.h"
11 : #include "src/globals.h"
12 :
13 : namespace v8 {
14 : namespace internal {
15 : namespace compiler {
16 :
17 : class Deduplicator;
18 : class JSGraph;
19 :
20 : // Perform hash-consing when creating or mutating nodes. Used to avoid duplicate
21 : // nodes when creating ObjectState, StateValues and FrameState nodes
22 464162 : class NodeHashCache {
23 : public:
24 464162 : NodeHashCache(Graph* graph, Zone* zone)
25 928326 : : graph_(graph), cache_(zone), temp_nodes_(zone) {}
26 :
27 : // Handle to a conceptually new mutable node. Tries to re-use existing nodes
28 : // and to recycle memory if possible.
29 : class Constructor {
30 : public:
31 : // Construct a new node as a clone of [from].
32 : Constructor(NodeHashCache* cache, Node* from)
33 19732790 : : node_cache_(cache), from_(from), tmp_(nullptr) {}
34 : // Construct a new node from scratch.
35 : Constructor(NodeHashCache* cache, const Operator* op, int input_count,
36 : Node** inputs, Type type);
37 :
38 : // Modify the new node.
39 28731825 : void ReplaceValueInput(Node* input, int i) {
40 28731825 : if (!tmp_ && input == NodeProperties::GetValueInput(from_, i)) return;
41 209644 : Node* node = MutableNode();
42 209644 : NodeProperties::ReplaceValueInput(node, input, i);
43 : }
44 37396385 : void ReplaceInput(Node* input, int i) {
45 74206017 : if (!tmp_ && input == from_->InputAt(i)) return;
46 755502 : Node* node = MutableNode();
47 755502 : node->ReplaceInput(i, input);
48 : }
49 :
50 : // Obtain the mutated node or a cached copy. Invalidates the [Constructor].
51 : Node* Get();
52 :
53 : private:
54 : Node* MutableNode();
55 :
56 : NodeHashCache* node_cache_;
57 : // Original node, copied on write.
58 : Node* from_;
59 : // Temporary node used for mutations, can be recycled if cache is hit.
60 : Node* tmp_;
61 : };
62 :
63 : private:
64 : Node* Query(Node* node);
65 : void Insert(Node* node) { cache_.insert(node); }
66 :
67 : Graph* graph_;
68 : struct NodeEquals {
69 : bool operator()(Node* a, Node* b) const {
70 231029 : return NodeProperties::Equals(a, b);
71 : }
72 : };
73 : struct NodeHashCode {
74 19975285 : size_t operator()(Node* n) const { return NodeProperties::HashCode(n); }
75 : };
76 : ZoneUnorderedSet<Node*, NodeHashCode, NodeEquals> cache_;
77 : // Unused nodes whose memory can be recycled.
78 : ZoneVector<Node*> temp_nodes_;
79 : };
80 :
81 : // Modify the graph according to the information computed in the previous phase.
82 928325 : class V8_EXPORT_PRIVATE EscapeAnalysisReducer final
83 : : public NON_EXPORTED_BASE(AdvancedReducer) {
84 : public:
85 : EscapeAnalysisReducer(Editor* editor, JSGraph* jsgraph,
86 : EscapeAnalysisResult analysis_result, Zone* zone);
87 :
88 : Reduction Reduce(Node* node) override;
89 17 : const char* reducer_name() const override { return "EscapeAnalysisReducer"; }
90 : void Finalize() override;
91 :
92 : // Verifies that all virtual allocation nodes have been dealt with. Run it
93 : // after this reducer has been applied.
94 : void VerifyReplacement() const;
95 :
96 : private:
97 : void ReduceFrameStateInputs(Node* node);
98 : Node* ReduceDeoptState(Node* node, Node* effect, Deduplicator* deduplicator);
99 : Node* ObjectIdNode(const VirtualObject* vobject);
100 : Reduction ReplaceNode(Node* original, Node* replacement);
101 :
102 : JSGraph* jsgraph() const { return jsgraph_; }
103 : Isolate* isolate() const { return jsgraph_->isolate(); }
104 : EscapeAnalysisResult analysis_result() const { return analysis_result_; }
105 : Zone* zone() const { return zone_; }
106 :
107 : JSGraph* const jsgraph_;
108 : EscapeAnalysisResult analysis_result_;
109 : ZoneVector<Node*> object_id_cache_;
110 : NodeHashCache node_cache_;
111 : ZoneSet<Node*> arguments_elements_;
112 : Zone* const zone_;
113 :
114 : DISALLOW_COPY_AND_ASSIGN(EscapeAnalysisReducer);
115 : };
116 :
117 : } // namespace compiler
118 : } // namespace internal
119 : } // namespace v8
120 :
121 : #endif // V8_COMPILER_ESCAPE_ANALYSIS_REDUCER_H_
|