LCOV - code coverage report
Current view: top level - src/compiler - load-elimination.h (source / functions) Hit Total Coverage
Test: app.info Lines: 33 33 100.0 %
Date: 2019-04-17 Functions: 4 6 66.7 %

          Line data    Source code
       1             : // Copyright 2016 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_LOAD_ELIMINATION_H_
       6             : #define V8_COMPILER_LOAD_ELIMINATION_H_
       7             : 
       8             : #include "src/base/compiler-specific.h"
       9             : #include "src/compiler/graph-reducer.h"
      10             : #include "src/globals.h"
      11             : #include "src/machine-type.h"
      12             : #include "src/maybe-handles.h"
      13             : #include "src/zone/zone-handle-set.h"
      14             : 
      15             : namespace v8 {
      16             : namespace internal {
      17             : 
      18             : // Forward declarations.
      19             : class Factory;
      20             : 
      21             : namespace compiler {
      22             : 
      23             : // Forward declarations.
      24             : class CommonOperatorBuilder;
      25             : struct FieldAccess;
      26             : class Graph;
      27             : class JSGraph;
      28             : 
      29             : class V8_EXPORT_PRIVATE LoadElimination final
      30             :     : public NON_EXPORTED_BASE(AdvancedReducer) {
      31             :  public:
      32             :   LoadElimination(Editor* editor, JSGraph* jsgraph, Zone* zone)
      33      928170 :       : AdvancedReducer(editor), node_states_(zone), jsgraph_(jsgraph) {}
      34      928168 :   ~LoadElimination() final = default;
      35             : 
      36          18 :   const char* reducer_name() const override { return "LoadElimination"; }
      37             : 
      38             :   Reduction Reduce(Node* node) final;
      39             : 
      40             :  private:
      41             :   static const size_t kMaxTrackedElements = 8;
      42             : 
      43             :   // Abstract state to approximate the current state of an element along the
      44             :   // effect paths through the graph.
      45             :   class AbstractElements final : public ZoneObject {
      46             :    public:
      47       56781 :     explicit AbstractElements(Zone* zone) {
      48      965277 :       for (size_t i = 0; i < arraysize(elements_); ++i) {
      49      454248 :         elements_[i] = Element();
      50             :       }
      51             :     }
      52             :     AbstractElements(Node* object, Node* index, Node* value,
      53             :                      MachineRepresentation representation, Zone* zone)
      54             :         : AbstractElements(zone) {
      55       22614 :       elements_[next_index_++] = Element(object, index, value, representation);
      56             :     }
      57             : 
      58       38710 :     AbstractElements const* Extend(Node* object, Node* index, Node* value,
      59             :                                    MachineRepresentation representation,
      60             :                                    Zone* zone) const {
      61       38710 :       AbstractElements* that = new (zone) AbstractElements(*this);
      62       38710 :       that->elements_[that->next_index_] =
      63       38710 :           Element(object, index, value, representation);
      64       38710 :       that->next_index_ = (that->next_index_ + 1) % arraysize(elements_);
      65       38710 :       return that;
      66             :     }
      67             :     Node* Lookup(Node* object, Node* index,
      68             :                  MachineRepresentation representation) const;
      69             :     AbstractElements const* Kill(Node* object, Node* index, Zone* zone) const;
      70             :     bool Equals(AbstractElements const* that) const;
      71             :     AbstractElements const* Merge(AbstractElements const* that,
      72             :                                   Zone* zone) const;
      73             : 
      74             :     void Print() const;
      75             : 
      76             :    private:
      77             :     struct Element {
      78             :       Element() = default;
      79             :       Element(Node* object, Node* index, Node* value,
      80             :               MachineRepresentation representation)
      81             :           : object(object),
      82             :             index(index),
      83             :             value(value),
      84             :             representation(representation) {}
      85             : 
      86             :       Node* object = nullptr;
      87             :       Node* index = nullptr;
      88             :       Node* value = nullptr;
      89             :       MachineRepresentation representation = MachineRepresentation::kNone;
      90             :     };
      91             : 
      92             :     Element elements_[kMaxTrackedElements];
      93             :     size_t next_index_ = 0;
      94             :   };
      95             : 
      96             :   // Information we use to resolve object aliasing. Currently, we consider
      97             :   // object not aliased if they have different maps or if the nodes may
      98             :   // not alias.
      99             :   class AliasStateInfo;
     100             : 
     101             :   // Abstract state to approximate the current state of a certain field along
     102             :   // the effect paths through the graph.
     103             :   class AbstractField final : public ZoneObject {
     104             :    public:
     105             :     explicit AbstractField(Zone* zone) : info_for_node_(zone) {}
     106             :     AbstractField(Node* object, Node* value, MaybeHandle<Name> name, Zone* zone)
     107             :         : info_for_node_(zone) {
     108      999310 :       info_for_node_.insert(std::make_pair(object, Field(value, name)));
     109             :     }
     110             : 
     111      643776 :     AbstractField const* Extend(Node* object, Node* value,
     112             :                                 MaybeHandle<Name> name, Zone* zone) const {
     113             :       AbstractField* that = new (zone) AbstractField(zone);
     114             :       that->info_for_node_ = this->info_for_node_;
     115      643776 :       that->info_for_node_.insert(std::make_pair(object, Field(value, name)));
     116      643776 :       return that;
     117             :     }
     118             :     Node* Lookup(Node* object) const;
     119             :     AbstractField const* Kill(const AliasStateInfo& alias_info,
     120             :                               MaybeHandle<Name> name, Zone* zone) const;
     121             :     bool Equals(AbstractField const* that) const {
     122      499480 :       return this == that || this->info_for_node_ == that->info_for_node_;
     123             :     }
     124      262802 :     AbstractField const* Merge(AbstractField const* that, Zone* zone) const {
     125      262802 :       if (this->Equals(that)) return this;
     126             :       AbstractField* copy = new (zone) AbstractField(zone);
     127       73892 :       for (auto this_it : this->info_for_node_) {
     128       44755 :         Node* this_object = this_it.first;
     129       44755 :         Field this_second = this_it.second;
     130       44755 :         if (this_object->IsDead()) continue;
     131             :         auto that_it = that->info_for_node_.find(this_object);
     132       80035 :         if (that_it != that->info_for_node_.end() &&
     133             :             that_it->second == this_second) {
     134             :           copy->info_for_node_.insert(this_it);
     135             :         }
     136             :       }
     137       29137 :       return copy;
     138             :     }
     139             : 
     140             :     void Print() const;
     141             : 
     142             :    private:
     143             :     struct Field {
     144             :       Field() = default;
     145             :       Field(Node* value, MaybeHandle<Name> name) : value(value), name(name) {}
     146             : 
     147             :       bool operator==(const Field& other) const {
     148      357071 :         return value == other.value && name.address() == other.name.address();
     149             :       }
     150             : 
     151             :       Node* value = nullptr;
     152             :       MaybeHandle<Name> name;
     153             :     };
     154             : 
     155             :     ZoneMap<Node*, Field> info_for_node_;
     156             :   };
     157             : 
     158             :   static size_t const kMaxTrackedFields = 32;
     159             : 
     160             :   // Abstract state to approximate the current map of an object along the
     161             :   // effect paths through the graph.
     162             :   class AbstractMaps final : public ZoneObject {
     163             :    public:
     164             :     explicit AbstractMaps(Zone* zone);
     165             :     AbstractMaps(Node* object, ZoneHandleSet<Map> maps, Zone* zone);
     166             : 
     167             :     AbstractMaps const* Extend(Node* object, ZoneHandleSet<Map> maps,
     168             :                                Zone* zone) const;
     169             :     bool Lookup(Node* object, ZoneHandleSet<Map>* object_maps) const;
     170             :     AbstractMaps const* Kill(const AliasStateInfo& alias_info,
     171             :                              Zone* zone) const;
     172             :     bool Equals(AbstractMaps const* that) const {
     173       67126 :       return this == that || this->info_for_node_ == that->info_for_node_;
     174             :     }
     175             :     AbstractMaps const* Merge(AbstractMaps const* that, Zone* zone) const;
     176             : 
     177             :     void Print() const;
     178             : 
     179             :    private:
     180             :     ZoneMap<Node*, ZoneHandleSet<Map>> info_for_node_;
     181             :   };
     182             : 
     183             :   class AbstractState final : public ZoneObject {
     184             :    public:
     185      464085 :     AbstractState() {
     186    30165525 :       for (size_t i = 0; i < arraysize(fields_); ++i) {
     187    14850720 :         fields_[i] = nullptr;
     188             :       }
     189             :     }
     190             : 
     191             :     bool Equals(AbstractState const* that) const;
     192             :     void Merge(AbstractState const* that, Zone* zone);
     193             : 
     194             :     AbstractState const* SetMaps(Node* object, ZoneHandleSet<Map> maps,
     195             :                                  Zone* zone) const;
     196             :     AbstractState const* KillMaps(Node* object, Zone* zone) const;
     197             :     AbstractState const* KillMaps(const AliasStateInfo& alias_info,
     198             :                                   Zone* zone) const;
     199             :     bool LookupMaps(Node* object, ZoneHandleSet<Map>* object_maps) const;
     200             : 
     201             :     AbstractState const* AddField(Node* object, size_t index, Node* value,
     202             :                                   MaybeHandle<Name> name, Zone* zone) const;
     203             :     AbstractState const* KillField(const AliasStateInfo& alias_info,
     204             :                                    size_t index, MaybeHandle<Name> name,
     205             :                                    Zone* zone) const;
     206             :     AbstractState const* KillField(Node* object, size_t index,
     207             :                                    MaybeHandle<Name> name, Zone* zone) const;
     208             :     AbstractState const* KillFields(Node* object, MaybeHandle<Name> name,
     209             :                                     Zone* zone) const;
     210             :     Node* LookupField(Node* object, size_t index) const;
     211             : 
     212             :     AbstractState const* AddElement(Node* object, Node* index, Node* value,
     213             :                                     MachineRepresentation representation,
     214             :                                     Zone* zone) const;
     215             :     AbstractState const* KillElement(Node* object, Node* index,
     216             :                                      Zone* zone) const;
     217             :     Node* LookupElement(Node* object, Node* index,
     218             :                         MachineRepresentation representation) const;
     219             : 
     220             :     void Print() const;
     221             : 
     222             :    private:
     223             :     AbstractElements const* elements_ = nullptr;
     224             :     AbstractField const* fields_[kMaxTrackedFields];
     225             :     AbstractMaps const* maps_ = nullptr;
     226             :   };
     227             : 
     228      464084 :   class AbstractStateForEffectNodes final : public ZoneObject {
     229             :    public:
     230             :     explicit AbstractStateForEffectNodes(Zone* zone) : info_for_node_(zone) {}
     231             :     AbstractState const* Get(Node* node) const;
     232             :     void Set(Node* node, AbstractState const* state);
     233             : 
     234             :     Zone* zone() const { return info_for_node_.get_allocator().zone(); }
     235             : 
     236             :    private:
     237             :     ZoneVector<AbstractState const*> info_for_node_;
     238             :   };
     239             : 
     240             :   Reduction ReduceCheckMaps(Node* node);
     241             :   Reduction ReduceCompareMaps(Node* node);
     242             :   Reduction ReduceMapGuard(Node* node);
     243             :   Reduction ReduceEnsureWritableFastElements(Node* node);
     244             :   Reduction ReduceMaybeGrowFastElements(Node* node);
     245             :   Reduction ReduceTransitionElementsKind(Node* node);
     246             :   Reduction ReduceLoadField(Node* node, FieldAccess const& access);
     247             :   Reduction ReduceStoreField(Node* node, FieldAccess const& access);
     248             :   Reduction ReduceLoadElement(Node* node);
     249             :   Reduction ReduceStoreElement(Node* node);
     250             :   Reduction ReduceTransitionAndStoreElement(Node* node);
     251             :   Reduction ReduceStoreTypedElement(Node* node);
     252             :   Reduction ReduceEffectPhi(Node* node);
     253             :   Reduction ReduceStart(Node* node);
     254             :   Reduction ReduceStoreMessage(Node* node);
     255             :   Reduction ReduceLoadMessage(Node* node);
     256             :   Reduction ReduceOtherNode(Node* node);
     257             : 
     258             :   Reduction UpdateState(Node* node, AbstractState const* state);
     259             : 
     260             :   AbstractState const* ComputeLoopState(Node* node,
     261             :                                         AbstractState const* state) const;
     262             :   AbstractState const* ComputeLoopStateForStoreField(
     263             :       Node* current, LoadElimination::AbstractState const* state,
     264             :       FieldAccess const& access) const;
     265             :   AbstractState const* UpdateStateForPhi(AbstractState const* state,
     266             :                                          Node* effect_phi, Node* phi);
     267             : 
     268             :   static int FieldIndexOf(int offset);
     269             :   static int FieldIndexOf(FieldAccess const& access);
     270             : 
     271             :   CommonOperatorBuilder* common() const;
     272     3098588 :   AbstractState const* empty_state() const { return &empty_state_; }
     273             :   Isolate* isolate() const;
     274             :   Factory* factory() const;
     275             :   Graph* graph() const;
     276             :   JSGraph* jsgraph() const { return jsgraph_; }
     277             :   Zone* zone() const { return node_states_.zone(); }
     278             : 
     279             :   AbstractState const empty_state_;
     280             :   AbstractStateForEffectNodes node_states_;
     281             :   JSGraph* const jsgraph_;
     282             : 
     283             :   DISALLOW_COPY_AND_ASSIGN(LoadElimination);
     284             : };
     285             : 
     286             : }  // namespace compiler
     287             : }  // namespace internal
     288             : }  // namespace v8
     289             : 
     290             : #endif  // V8_COMPILER_LOAD_ELIMINATION_H_

Generated by: LCOV version 1.10