Home | History | Annotate | Download | only in compiler
      1 // Copyright 2015 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_STATE_VALUES_UTILS_H_
      6 #define V8_COMPILER_STATE_VALUES_UTILS_H_
      7 
      8 #include <array>
      9 #include "src/compiler/common-operator.h"
     10 #include "src/compiler/js-graph.h"
     11 #include "src/globals.h"
     12 
     13 namespace v8 {
     14 namespace internal {
     15 
     16 class BitVector;
     17 
     18 namespace compiler {
     19 
     20 class Graph;
     21 
     22 class V8_EXPORT_PRIVATE StateValuesCache {
     23  public:
     24   explicit StateValuesCache(JSGraph* js_graph);
     25 
     26   Node* GetNodeForValues(Node** values, size_t count,
     27                          const BitVector* liveness = nullptr,
     28                          int liveness_offset = 0);
     29 
     30  private:
     31   static const size_t kMaxInputCount = 8;
     32   typedef std::array<Node*, kMaxInputCount> WorkingBuffer;
     33 
     34   struct NodeKey {
     35     Node* node;
     36 
     37     explicit NodeKey(Node* node) : node(node) {}
     38   };
     39 
     40   struct StateValuesKey : public NodeKey {
     41     // ValueArray - array of nodes ({node} has to be nullptr).
     42     size_t count;
     43     SparseInputMask mask;
     44     Node** values;
     45 
     46     StateValuesKey(size_t count, SparseInputMask mask, Node** values)
     47         : NodeKey(nullptr), count(count), mask(mask), values(values) {}
     48   };
     49 
     50   static bool AreKeysEqual(void* key1, void* key2);
     51   static bool IsKeysEqualToNode(StateValuesKey* key, Node* node);
     52   static bool AreValueKeysEqual(StateValuesKey* key1, StateValuesKey* key2);
     53 
     54   // Fills {node_buffer}, starting from {node_count}, with {values}, starting
     55   // at {values_idx}, sparsely encoding according to {liveness}. {node_count} is
     56   // updated with the new number of inputs in {node_buffer}, and a bitmask of
     57   // the sparse encoding is returned.
     58   SparseInputMask::BitMaskType FillBufferWithValues(WorkingBuffer* node_buffer,
     59                                                     size_t* node_count,
     60                                                     size_t* values_idx,
     61                                                     Node** values, size_t count,
     62                                                     const BitVector* liveness,
     63                                                     int liveness_offset);
     64 
     65   Node* BuildTree(size_t* values_idx, Node** values, size_t count,
     66                   const BitVector* liveness, int liveness_offset, size_t level);
     67 
     68   WorkingBuffer* GetWorkingSpace(size_t level);
     69   Node* GetEmptyStateValues();
     70   Node* GetValuesNodeFromCache(Node** nodes, size_t count,
     71                                SparseInputMask mask);
     72 
     73   Graph* graph() { return js_graph_->graph(); }
     74   CommonOperatorBuilder* common() { return js_graph_->common(); }
     75 
     76   Zone* zone() { return graph()->zone(); }
     77 
     78   JSGraph* js_graph_;
     79   CustomMatcherZoneHashMap hash_map_;
     80   ZoneVector<WorkingBuffer> working_space_;  // One working space per level.
     81   Node* empty_state_values_;
     82 };
     83 
     84 class V8_EXPORT_PRIVATE StateValuesAccess {
     85  public:
     86   struct TypedNode {
     87     Node* node;
     88     MachineType type;
     89     TypedNode(Node* node, MachineType type) : node(node), type(type) {}
     90   };
     91 
     92   class V8_EXPORT_PRIVATE iterator {
     93    public:
     94     // Bare minimum of operators needed for range iteration.
     95     bool operator!=(iterator& other);
     96     iterator& operator++();
     97     TypedNode operator*();
     98 
     99    private:
    100     friend class StateValuesAccess;
    101 
    102     iterator() : current_depth_(-1) {}
    103     explicit iterator(Node* node);
    104 
    105     Node* node();
    106     MachineType type();
    107     bool done();
    108     void Advance();
    109     void EnsureValid();
    110 
    111     SparseInputMask::InputIterator* Top();
    112     void Push(Node* node);
    113     void Pop();
    114 
    115     static const int kMaxInlineDepth = 8;
    116     SparseInputMask::InputIterator stack_[kMaxInlineDepth];
    117     int current_depth_;
    118   };
    119 
    120   explicit StateValuesAccess(Node* node) : node_(node) {}
    121 
    122   size_t size();
    123   iterator begin() { return iterator(node_); }
    124   iterator end() { return iterator(); }
    125 
    126  private:
    127   Node* node_;
    128 };
    129 
    130 }  // namespace compiler
    131 }  // namespace internal
    132 }  // namespace v8
    133 
    134 #endif  // V8_COMPILER_STATE_VALUES_UTILS_H_
    135