11cb0ef41Sopenharmony_ci// Copyright 2016 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#ifndef V8_COMPILER_MEMORY_OPTIMIZER_H_
61cb0ef41Sopenharmony_ci#define V8_COMPILER_MEMORY_OPTIMIZER_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include "src/compiler/graph-assembler.h"
91cb0ef41Sopenharmony_ci#include "src/compiler/memory-lowering.h"
101cb0ef41Sopenharmony_ci#include "src/zone/zone-containers.h"
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_cinamespace v8 {
131cb0ef41Sopenharmony_cinamespace internal {
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ciclass TickCounter;
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_cinamespace compiler {
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ciclass JSGraph;
201cb0ef41Sopenharmony_ciclass Graph;
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ci// NodeIds are identifying numbers for nodes that can be used to index auxiliary
231cb0ef41Sopenharmony_ci// out-of-line data associated with each node.
241cb0ef41Sopenharmony_ciusing NodeId = uint32_t;
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_ci// Performs allocation folding and store write barrier elimination
271cb0ef41Sopenharmony_ci// implicitly, while lowering all simplified memory access and allocation
281cb0ef41Sopenharmony_ci// related nodes (i.e. Allocate, LoadField, StoreField and friends) to machine
291cb0ef41Sopenharmony_ci// operators.
301cb0ef41Sopenharmony_ciclass MemoryOptimizer final {
311cb0ef41Sopenharmony_ci public:
321cb0ef41Sopenharmony_ci  MemoryOptimizer(JSGraph* jsgraph, Zone* zone,
331cb0ef41Sopenharmony_ci                  MemoryLowering::AllocationFolding allocation_folding,
341cb0ef41Sopenharmony_ci                  const char* function_debug_name, TickCounter* tick_counter);
351cb0ef41Sopenharmony_ci  ~MemoryOptimizer() = default;
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_ci  void Optimize();
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci private:
401cb0ef41Sopenharmony_ci  using AllocationState = MemoryLowering::AllocationState;
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ci  // An array of allocation states used to collect states on merges.
431cb0ef41Sopenharmony_ci  using AllocationStates = ZoneVector<AllocationState const*>;
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ci  // We thread through tokens to represent the current state on a given effect
461cb0ef41Sopenharmony_ci  // path through the graph.
471cb0ef41Sopenharmony_ci  struct Token {
481cb0ef41Sopenharmony_ci    Node* node;
491cb0ef41Sopenharmony_ci    AllocationState const* state;
501cb0ef41Sopenharmony_ci  };
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ci  void VisitNode(Node*, AllocationState const*);
531cb0ef41Sopenharmony_ci  void VisitAllocateRaw(Node*, AllocationState const*);
541cb0ef41Sopenharmony_ci  void VisitCall(Node*, AllocationState const*);
551cb0ef41Sopenharmony_ci  void VisitLoadFromObject(Node*, AllocationState const*);
561cb0ef41Sopenharmony_ci  void VisitLoadElement(Node*, AllocationState const*);
571cb0ef41Sopenharmony_ci  void VisitLoadField(Node*, AllocationState const*);
581cb0ef41Sopenharmony_ci  void VisitStoreToObject(Node*, AllocationState const*);
591cb0ef41Sopenharmony_ci  void VisitStoreElement(Node*, AllocationState const*);
601cb0ef41Sopenharmony_ci  void VisitStoreField(Node*, AllocationState const*);
611cb0ef41Sopenharmony_ci  void VisitStore(Node*, AllocationState const*);
621cb0ef41Sopenharmony_ci  void VisitOtherEffect(Node*, AllocationState const*);
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci  AllocationState const* MergeStates(AllocationStates const& states);
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ci  void EnqueueMerge(Node*, int, AllocationState const*);
671cb0ef41Sopenharmony_ci  void EnqueueUses(Node*, AllocationState const*);
681cb0ef41Sopenharmony_ci  void EnqueueUse(Node*, int, AllocationState const*);
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_ci  void ReplaceUsesAndKillNode(Node* node, Node* replacement);
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ci  // Returns true if the AllocationType of the current AllocateRaw node that we
731cb0ef41Sopenharmony_ci  // are visiting needs to be updated to kOld, due to propagation of tenuring
741cb0ef41Sopenharmony_ci  // from outer to inner allocations.
751cb0ef41Sopenharmony_ci  bool AllocationTypeNeedsUpdateToOld(Node* const user, const Edge edge);
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_ci  AllocationState const* empty_state() const { return empty_state_; }
781cb0ef41Sopenharmony_ci  MemoryLowering* memory_lowering() { return &memory_lowering_; }
791cb0ef41Sopenharmony_ci  Graph* graph() const;
801cb0ef41Sopenharmony_ci  JSGraph* jsgraph() const { return jsgraph_; }
811cb0ef41Sopenharmony_ci  Zone* zone() const { return zone_; }
821cb0ef41Sopenharmony_ci
831cb0ef41Sopenharmony_ci  JSGraphAssembler graph_assembler_;
841cb0ef41Sopenharmony_ci  MemoryLowering memory_lowering_;
851cb0ef41Sopenharmony_ci  JSGraph* jsgraph_;
861cb0ef41Sopenharmony_ci  AllocationState const* const empty_state_;
871cb0ef41Sopenharmony_ci  ZoneMap<NodeId, AllocationStates> pending_;
881cb0ef41Sopenharmony_ci  ZoneQueue<Token> tokens_;
891cb0ef41Sopenharmony_ci  Zone* const zone_;
901cb0ef41Sopenharmony_ci  TickCounter* const tick_counter_;
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_ci  DISALLOW_IMPLICIT_CONSTRUCTORS(MemoryOptimizer);
931cb0ef41Sopenharmony_ci};
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_ci}  // namespace compiler
961cb0ef41Sopenharmony_ci}  // namespace internal
971cb0ef41Sopenharmony_ci}  // namespace v8
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ci#endif  // V8_COMPILER_MEMORY_OPTIMIZER_H_
100