11cb0ef41Sopenharmony_ci// Copyright 2015 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_JS_INLINING_HEURISTIC_H_ 61cb0ef41Sopenharmony_ci#define V8_COMPILER_JS_INLINING_HEURISTIC_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include "src/compiler/js-inlining.h" 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_cinamespace v8 { 111cb0ef41Sopenharmony_cinamespace internal { 121cb0ef41Sopenharmony_cinamespace compiler { 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_ciclass JSInliningHeuristic final : public AdvancedReducer { 151cb0ef41Sopenharmony_ci public: 161cb0ef41Sopenharmony_ci enum Mode { kJSOnly, kWasmOnly }; 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_ci JSInliningHeuristic(Editor* editor, Zone* local_zone, 191cb0ef41Sopenharmony_ci OptimizedCompilationInfo* info, JSGraph* jsgraph, 201cb0ef41Sopenharmony_ci JSHeapBroker* broker, 211cb0ef41Sopenharmony_ci SourcePositionTable* source_positions, Mode mode) 221cb0ef41Sopenharmony_ci : AdvancedReducer(editor), 231cb0ef41Sopenharmony_ci inliner_(editor, local_zone, info, jsgraph, broker, source_positions), 241cb0ef41Sopenharmony_ci candidates_(local_zone), 251cb0ef41Sopenharmony_ci seen_(local_zone), 261cb0ef41Sopenharmony_ci source_positions_(source_positions), 271cb0ef41Sopenharmony_ci jsgraph_(jsgraph), 281cb0ef41Sopenharmony_ci broker_(broker), 291cb0ef41Sopenharmony_ci mode_(mode), 301cb0ef41Sopenharmony_ci max_inlined_bytecode_size_cumulative_( 311cb0ef41Sopenharmony_ci FLAG_max_inlined_bytecode_size_cumulative), 321cb0ef41Sopenharmony_ci max_inlined_bytecode_size_absolute_( 331cb0ef41Sopenharmony_ci FLAG_max_inlined_bytecode_size_absolute) {} 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ci const char* reducer_name() const override { return "JSInliningHeuristic"; } 361cb0ef41Sopenharmony_ci 371cb0ef41Sopenharmony_ci Reduction Reduce(Node* node) final; 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ci // Processes the list of candidates gathered while the reducer was running, 401cb0ef41Sopenharmony_ci // and inlines call sites that the heuristic determines to be important. 411cb0ef41Sopenharmony_ci void Finalize() final; 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_ci int total_inlined_bytecode_size() const { 441cb0ef41Sopenharmony_ci return total_inlined_bytecode_size_; 451cb0ef41Sopenharmony_ci } 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ci private: 481cb0ef41Sopenharmony_ci // This limit currently matches what the old compiler did. We may want to 491cb0ef41Sopenharmony_ci // re-evaluate and come up with a proper limit for TurboFan. 501cb0ef41Sopenharmony_ci static const int kMaxCallPolymorphism = 4; 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ci struct Candidate { 531cb0ef41Sopenharmony_ci base::Optional<JSFunctionRef> functions[kMaxCallPolymorphism]; 541cb0ef41Sopenharmony_ci // In the case of polymorphic inlining, this tells if each of the 551cb0ef41Sopenharmony_ci // functions could be inlined. 561cb0ef41Sopenharmony_ci bool can_inline_function[kMaxCallPolymorphism]; 571cb0ef41Sopenharmony_ci // Strong references to bytecode to ensure it is not flushed from SFI 581cb0ef41Sopenharmony_ci // while choosing inlining candidates. 591cb0ef41Sopenharmony_ci base::Optional<BytecodeArrayRef> bytecode[kMaxCallPolymorphism]; 601cb0ef41Sopenharmony_ci // TODO(2206): For now polymorphic inlining is treated orthogonally to 611cb0ef41Sopenharmony_ci // inlining based on SharedFunctionInfo. This should be unified and the 621cb0ef41Sopenharmony_ci // above array should be switched to SharedFunctionInfo instead. Currently 631cb0ef41Sopenharmony_ci // we use {num_functions == 1 && functions[0].is_null()} as an indicator. 641cb0ef41Sopenharmony_ci base::Optional<SharedFunctionInfoRef> shared_info; 651cb0ef41Sopenharmony_ci int num_functions; 661cb0ef41Sopenharmony_ci Node* node = nullptr; // The call site at which to inline. 671cb0ef41Sopenharmony_ci CallFrequency frequency; // Relative frequency of this call site. 681cb0ef41Sopenharmony_ci int total_size = 0; 691cb0ef41Sopenharmony_ci }; 701cb0ef41Sopenharmony_ci 711cb0ef41Sopenharmony_ci // Comparator for candidates. 721cb0ef41Sopenharmony_ci struct CandidateCompare { 731cb0ef41Sopenharmony_ci bool operator()(const Candidate& left, const Candidate& right) const; 741cb0ef41Sopenharmony_ci }; 751cb0ef41Sopenharmony_ci 761cb0ef41Sopenharmony_ci // Candidates are kept in a sorted set of unique candidates. 771cb0ef41Sopenharmony_ci using Candidates = ZoneSet<Candidate, CandidateCompare>; 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_ci // Dumps candidates to console. 801cb0ef41Sopenharmony_ci void PrintCandidates(); 811cb0ef41Sopenharmony_ci Reduction InlineCandidate(Candidate const& candidate, bool small_function); 821cb0ef41Sopenharmony_ci void CreateOrReuseDispatch(Node* node, Node* callee, 831cb0ef41Sopenharmony_ci Candidate const& candidate, Node** if_successes, 841cb0ef41Sopenharmony_ci Node** calls, Node** inputs, int input_count); 851cb0ef41Sopenharmony_ci bool TryReuseDispatch(Node* node, Node* callee, Node** if_successes, 861cb0ef41Sopenharmony_ci Node** calls, Node** inputs, int input_count); 871cb0ef41Sopenharmony_ci enum StateCloneMode { kCloneState, kChangeInPlace }; 881cb0ef41Sopenharmony_ci FrameState DuplicateFrameStateAndRename(FrameState frame_state, Node* from, 891cb0ef41Sopenharmony_ci Node* to, StateCloneMode mode); 901cb0ef41Sopenharmony_ci Node* DuplicateStateValuesAndRename(Node* state_values, Node* from, Node* to, 911cb0ef41Sopenharmony_ci StateCloneMode mode); 921cb0ef41Sopenharmony_ci Candidate CollectFunctions(Node* node, int functions_size); 931cb0ef41Sopenharmony_ci 941cb0ef41Sopenharmony_ci CommonOperatorBuilder* common() const; 951cb0ef41Sopenharmony_ci Graph* graph() const; 961cb0ef41Sopenharmony_ci JSGraph* jsgraph() const { return jsgraph_; } 971cb0ef41Sopenharmony_ci // TODO(neis): Make heap broker a component of JSGraph? 981cb0ef41Sopenharmony_ci JSHeapBroker* broker() const { return broker_; } 991cb0ef41Sopenharmony_ci CompilationDependencies* dependencies() const; 1001cb0ef41Sopenharmony_ci Isolate* isolate() const { return jsgraph_->isolate(); } 1011cb0ef41Sopenharmony_ci SimplifiedOperatorBuilder* simplified() const; 1021cb0ef41Sopenharmony_ci Mode mode() const { return mode_; } 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ci JSInliner inliner_; 1051cb0ef41Sopenharmony_ci Candidates candidates_; 1061cb0ef41Sopenharmony_ci ZoneSet<NodeId> seen_; 1071cb0ef41Sopenharmony_ci SourcePositionTable* source_positions_; 1081cb0ef41Sopenharmony_ci JSGraph* const jsgraph_; 1091cb0ef41Sopenharmony_ci JSHeapBroker* const broker_; 1101cb0ef41Sopenharmony_ci int total_inlined_bytecode_size_ = 0; 1111cb0ef41Sopenharmony_ci const Mode mode_; 1121cb0ef41Sopenharmony_ci const int max_inlined_bytecode_size_cumulative_; 1131cb0ef41Sopenharmony_ci const int max_inlined_bytecode_size_absolute_; 1141cb0ef41Sopenharmony_ci}; 1151cb0ef41Sopenharmony_ci 1161cb0ef41Sopenharmony_ci} // namespace compiler 1171cb0ef41Sopenharmony_ci} // namespace internal 1181cb0ef41Sopenharmony_ci} // namespace v8 1191cb0ef41Sopenharmony_ci 1201cb0ef41Sopenharmony_ci#endif // V8_COMPILER_JS_INLINING_HEURISTIC_H_ 121