Home | History | Annotate | Download | only in compiler
      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 class NodeHashCache {
     23  public:
     24   NodeHashCache(Graph* graph, Zone* zone)
     25       : 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         : 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     void ReplaceValueInput(Node* input, int i) {
     40       if (!tmp_ && input == NodeProperties::GetValueInput(from_, i)) return;
     41       Node* node = MutableNode();
     42       NodeProperties::ReplaceValueInput(node, input, i);
     43     }
     44     void ReplaceInput(Node* input, int i) {
     45       if (!tmp_ && input == from_->InputAt(i)) return;
     46       Node* node = MutableNode();
     47       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       return NodeProperties::Equals(a, b);
     71     }
     72   };
     73   struct NodeHashCode {
     74     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 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   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_
    122