V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
load-elimination.h
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  : AdvancedReducer(editor), node_states_(zone), jsgraph_(jsgraph) {}
34  ~LoadElimination() final = default;
35 
36  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  explicit AbstractElements(Zone* zone) {
48  for (size_t i = 0; i < arraysize(elements_); ++i) {
49  elements_[i] = Element();
50  }
51  }
52  AbstractElements(Node* object, Node* index, Node* value,
53  MachineRepresentation representation, Zone* zone)
54  : AbstractElements(zone) {
55  elements_[next_index_++] = Element(object, index, value, representation);
56  }
57 
58  AbstractElements const* Extend(Node* object, Node* index, Node* value,
59  MachineRepresentation representation,
60  Zone* zone) const {
61  AbstractElements* that = new (zone) AbstractElements(*this);
62  that->elements_[that->next_index_] =
63  Element(object, index, value, representation);
64  that->next_index_ = (that->next_index_ + 1) % arraysize(elements_);
65  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  info_for_node_.insert(std::make_pair(object, Field(value, name)));
109  }
110 
111  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  that->info_for_node_.insert(std::make_pair(object, Field(value, name)));
116  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  return this == that || this->info_for_node_ == that->info_for_node_;
123  }
124  AbstractField const* Merge(AbstractField const* that, Zone* zone) const {
125  if (this->Equals(that)) return this;
126  AbstractField* copy = new (zone) AbstractField(zone);
127  for (auto this_it : this->info_for_node_) {
128  Node* this_object = this_it.first;
129  Field this_second = this_it.second;
130  if (this_object->IsDead()) continue;
131  auto that_it = that->info_for_node_.find(this_object);
132  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  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  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  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  AbstractState() {
186  for (size_t i = 0; i < arraysize(fields_); ++i) {
187  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  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);
247  Reduction ReduceStoreField(Node* node);
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 ReduceOtherNode(Node* node);
255 
256  Reduction UpdateState(Node* node, AbstractState const* state);
257 
258  AbstractState const* ComputeLoopState(Node* node,
259  AbstractState const* state) const;
260  AbstractState const* UpdateStateForPhi(AbstractState const* state,
261  Node* effect_phi, Node* phi);
262 
263  static int FieldIndexOf(int offset);
264  static int FieldIndexOf(FieldAccess const& access);
265 
266  CommonOperatorBuilder* common() const;
267  AbstractState const* empty_state() const { return &empty_state_; }
268  Isolate* isolate() const;
269  Factory* factory() const;
270  Graph* graph() const;
271  JSGraph* jsgraph() const { return jsgraph_; }
272  Zone* zone() const { return node_states_.zone(); }
273 
274  AbstractState const empty_state_;
275  AbstractStateForEffectNodes node_states_;
276  JSGraph* const jsgraph_;
277 
278  DISALLOW_COPY_AND_ASSIGN(LoadElimination);
279 };
280 
281 } // namespace compiler
282 } // namespace internal
283 } // namespace v8
284 
285 #endif // V8_COMPILER_LOAD_ELIMINATION_H_
Definition: libplatform.h:13
Definition: v8.h:3740