11cb0ef41Sopenharmony_ci// Copyright 2021 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#if !V8_ENABLE_WEBASSEMBLY 61cb0ef41Sopenharmony_ci#error This header should only be included if WebAssembly is enabled. 71cb0ef41Sopenharmony_ci#endif // !V8_ENABLE_WEBASSEMBLY 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_ci#ifndef V8_COMPILER_WASM_INLINING_H_ 101cb0ef41Sopenharmony_ci#define V8_COMPILER_WASM_INLINING_H_ 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_ci#include "src/compiler/graph-reducer.h" 131cb0ef41Sopenharmony_ci#include "src/compiler/js-graph.h" 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_cinamespace v8 { 161cb0ef41Sopenharmony_cinamespace internal { 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_cinamespace wasm { 191cb0ef41Sopenharmony_cistruct CompilationEnv; 201cb0ef41Sopenharmony_cistruct WasmModule; 211cb0ef41Sopenharmony_cistruct WasmFunction; 221cb0ef41Sopenharmony_ciclass WireBytesStorage; 231cb0ef41Sopenharmony_ci} // namespace wasm 241cb0ef41Sopenharmony_ci 251cb0ef41Sopenharmony_ciclass BytecodeOffset; 261cb0ef41Sopenharmony_ciclass OptimizedCompilationInfo; 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_cinamespace compiler { 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_ciclass NodeOriginTable; 311cb0ef41Sopenharmony_ciclass SourcePositionTable; 321cb0ef41Sopenharmony_cistruct WasmLoopInfo; 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ci// The WasmInliner provides the core graph inlining machinery for Webassembly 351cb0ef41Sopenharmony_ci// graphs. 361cb0ef41Sopenharmony_ciclass WasmInliner final : public AdvancedReducer { 371cb0ef41Sopenharmony_ci public: 381cb0ef41Sopenharmony_ci WasmInliner(Editor* editor, wasm::CompilationEnv* env, 391cb0ef41Sopenharmony_ci uint32_t function_index, SourcePositionTable* source_positions, 401cb0ef41Sopenharmony_ci NodeOriginTable* node_origins, MachineGraph* mcgraph, 411cb0ef41Sopenharmony_ci const wasm::WireBytesStorage* wire_bytes, 421cb0ef41Sopenharmony_ci std::vector<WasmLoopInfo>* loop_infos, const char* debug_name) 431cb0ef41Sopenharmony_ci : AdvancedReducer(editor), 441cb0ef41Sopenharmony_ci env_(env), 451cb0ef41Sopenharmony_ci function_index_(function_index), 461cb0ef41Sopenharmony_ci source_positions_(source_positions), 471cb0ef41Sopenharmony_ci node_origins_(node_origins), 481cb0ef41Sopenharmony_ci mcgraph_(mcgraph), 491cb0ef41Sopenharmony_ci wire_bytes_(wire_bytes), 501cb0ef41Sopenharmony_ci loop_infos_(loop_infos), 511cb0ef41Sopenharmony_ci debug_name_(debug_name), 521cb0ef41Sopenharmony_ci initial_graph_size_(mcgraph->graph()->NodeCount()), 531cb0ef41Sopenharmony_ci current_graph_size_(initial_graph_size_), 541cb0ef41Sopenharmony_ci inlining_candidates_() {} 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_ci const char* reducer_name() const override { return "WasmInliner"; } 571cb0ef41Sopenharmony_ci 581cb0ef41Sopenharmony_ci Reduction Reduce(Node* node) final; 591cb0ef41Sopenharmony_ci void Finalize() final; 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_ci static bool graph_size_allows_inlining(size_t initial_graph_size) { 621cb0ef41Sopenharmony_ci return initial_graph_size < 5000; 631cb0ef41Sopenharmony_ci } 641cb0ef41Sopenharmony_ci 651cb0ef41Sopenharmony_ci private: 661cb0ef41Sopenharmony_ci struct CandidateInfo { 671cb0ef41Sopenharmony_ci Node* node; 681cb0ef41Sopenharmony_ci uint32_t inlinee_index; 691cb0ef41Sopenharmony_ci int call_count; 701cb0ef41Sopenharmony_ci int wire_byte_size; 711cb0ef41Sopenharmony_ci }; 721cb0ef41Sopenharmony_ci 731cb0ef41Sopenharmony_ci struct LexicographicOrdering { 741cb0ef41Sopenharmony_ci // Returns if c1 should be prioritized less than c2. 751cb0ef41Sopenharmony_ci bool operator()(CandidateInfo& c1, CandidateInfo& c2) { 761cb0ef41Sopenharmony_ci if (c1.call_count > c2.call_count) return false; 771cb0ef41Sopenharmony_ci if (c2.call_count > c1.call_count) return true; 781cb0ef41Sopenharmony_ci return c1.wire_byte_size > c2.wire_byte_size; 791cb0ef41Sopenharmony_ci } 801cb0ef41Sopenharmony_ci }; 811cb0ef41Sopenharmony_ci 821cb0ef41Sopenharmony_ci uint32_t FindOriginatingFunction(Node* call); 831cb0ef41Sopenharmony_ci 841cb0ef41Sopenharmony_ci Zone* zone() const { return mcgraph_->zone(); } 851cb0ef41Sopenharmony_ci CommonOperatorBuilder* common() const { return mcgraph_->common(); } 861cb0ef41Sopenharmony_ci Graph* graph() const { return mcgraph_->graph(); } 871cb0ef41Sopenharmony_ci MachineGraph* mcgraph() const { return mcgraph_; } 881cb0ef41Sopenharmony_ci const wasm::WasmModule* module() const; 891cb0ef41Sopenharmony_ci 901cb0ef41Sopenharmony_ci Reduction ReduceCall(Node* call); 911cb0ef41Sopenharmony_ci void InlineCall(Node* call, Node* callee_start, Node* callee_end, 921cb0ef41Sopenharmony_ci const wasm::FunctionSig* inlinee_sig, 931cb0ef41Sopenharmony_ci size_t subgraph_min_node_id); 941cb0ef41Sopenharmony_ci void InlineTailCall(Node* call, Node* callee_start, Node* callee_end); 951cb0ef41Sopenharmony_ci void RewireFunctionEntry(Node* call, Node* callee_start); 961cb0ef41Sopenharmony_ci 971cb0ef41Sopenharmony_ci int GetCallCount(Node* call); 981cb0ef41Sopenharmony_ci 991cb0ef41Sopenharmony_ci void Trace(Node* call, int inlinee, const char* decision); 1001cb0ef41Sopenharmony_ci void Trace(const CandidateInfo& candidate, const char* decision); 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_ci wasm::CompilationEnv* const env_; 1031cb0ef41Sopenharmony_ci uint32_t function_index_; 1041cb0ef41Sopenharmony_ci SourcePositionTable* const source_positions_; 1051cb0ef41Sopenharmony_ci NodeOriginTable* const node_origins_; 1061cb0ef41Sopenharmony_ci MachineGraph* const mcgraph_; 1071cb0ef41Sopenharmony_ci const wasm::WireBytesStorage* const wire_bytes_; 1081cb0ef41Sopenharmony_ci std::vector<WasmLoopInfo>* const loop_infos_; 1091cb0ef41Sopenharmony_ci const char* debug_name_; 1101cb0ef41Sopenharmony_ci const size_t initial_graph_size_; 1111cb0ef41Sopenharmony_ci size_t current_graph_size_; 1121cb0ef41Sopenharmony_ci std::priority_queue<CandidateInfo, std::vector<CandidateInfo>, 1131cb0ef41Sopenharmony_ci LexicographicOrdering> 1141cb0ef41Sopenharmony_ci inlining_candidates_; 1151cb0ef41Sopenharmony_ci std::unordered_set<Node*> seen_; 1161cb0ef41Sopenharmony_ci std::vector<uint32_t> inlined_functions_; 1171cb0ef41Sopenharmony_ci // Stores the graph size before an inlining was performed, to make it 1181cb0ef41Sopenharmony_ci // possible to map back from nodes to the function they came from. 1191cb0ef41Sopenharmony_ci // Guaranteed to have the same length as {inlined_functions_}. 1201cb0ef41Sopenharmony_ci std::vector<uint32_t> first_node_id_; 1211cb0ef41Sopenharmony_ci}; 1221cb0ef41Sopenharmony_ci 1231cb0ef41Sopenharmony_ci} // namespace compiler 1241cb0ef41Sopenharmony_ci} // namespace internal 1251cb0ef41Sopenharmony_ci} // namespace v8 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_ci#endif // V8_COMPILER_WASM_INLINING_H_ 128