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