1 // Copyright 2021 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 #if !V8_ENABLE_WEBASSEMBLY 6 #error This header should only be included if WebAssembly is enabled. 7 #endif // !V8_ENABLE_WEBASSEMBLY 8 9 #ifndef V8_COMPILER_WASM_INLINING_H_ 10 #define V8_COMPILER_WASM_INLINING_H_ 11 12 #include "src/compiler/graph-reducer.h" 13 #include "src/compiler/js-graph.h" 14 15 namespace v8 { 16 namespace internal { 17 18 namespace wasm { 19 struct CompilationEnv; 20 struct WasmModule; 21 struct WasmFunction; 22 class WireBytesStorage; 23 } // namespace wasm 24 25 class BytecodeOffset; 26 class OptimizedCompilationInfo; 27 28 namespace compiler { 29 30 class NodeOriginTable; 31 class SourcePositionTable; 32 struct WasmLoopInfo; 33 34 // The WasmInliner provides the core graph inlining machinery for Webassembly 35 // graphs. 36 class WasmInliner final : public AdvancedReducer { 37 public: WasmInliner(Editor * editor,wasm::CompilationEnv * env,uint32_t function_index,SourcePositionTable * source_positions,NodeOriginTable * node_origins,MachineGraph * mcgraph,const wasm::WireBytesStorage * wire_bytes,std::vector<WasmLoopInfo> * loop_infos,const char * debug_name)38 WasmInliner(Editor* editor, wasm::CompilationEnv* env, 39 uint32_t function_index, SourcePositionTable* source_positions, 40 NodeOriginTable* node_origins, MachineGraph* mcgraph, 41 const wasm::WireBytesStorage* wire_bytes, 42 std::vector<WasmLoopInfo>* loop_infos, const char* debug_name) 43 : AdvancedReducer(editor), 44 env_(env), 45 function_index_(function_index), 46 source_positions_(source_positions), 47 node_origins_(node_origins), 48 mcgraph_(mcgraph), 49 wire_bytes_(wire_bytes), 50 loop_infos_(loop_infos), 51 debug_name_(debug_name), 52 initial_graph_size_(mcgraph->graph()->NodeCount()), 53 current_graph_size_(initial_graph_size_), 54 inlining_candidates_() {} 55 reducer_name()56 const char* reducer_name() const override { return "WasmInliner"; } 57 58 Reduction Reduce(Node* node) final; 59 void Finalize() final; 60 graph_size_allows_inlining(size_t initial_graph_size)61 static bool graph_size_allows_inlining(size_t initial_graph_size) { 62 return initial_graph_size < 5000; 63 } 64 65 private: 66 struct CandidateInfo { 67 Node* node; 68 uint32_t inlinee_index; 69 int call_count; 70 int wire_byte_size; 71 }; 72 73 struct LexicographicOrdering { 74 // Returns if c1 should be prioritized less than c2. operatorLexicographicOrdering75 bool operator()(CandidateInfo& c1, CandidateInfo& c2) { 76 if (c1.call_count > c2.call_count) return false; 77 if (c2.call_count > c1.call_count) return true; 78 return c1.wire_byte_size > c2.wire_byte_size; 79 } 80 }; 81 82 uint32_t FindOriginatingFunction(Node* call); 83 zone()84 Zone* zone() const { return mcgraph_->zone(); } common()85 CommonOperatorBuilder* common() const { return mcgraph_->common(); } graph()86 Graph* graph() const { return mcgraph_->graph(); } mcgraph()87 MachineGraph* mcgraph() const { return mcgraph_; } 88 const wasm::WasmModule* module() const; 89 90 Reduction ReduceCall(Node* call); 91 void InlineCall(Node* call, Node* callee_start, Node* callee_end, 92 const wasm::FunctionSig* inlinee_sig, 93 size_t subgraph_min_node_id); 94 void InlineTailCall(Node* call, Node* callee_start, Node* callee_end); 95 void RewireFunctionEntry(Node* call, Node* callee_start); 96 97 int GetCallCount(Node* call); 98 99 void Trace(Node* call, int inlinee, const char* decision); 100 void Trace(const CandidateInfo& candidate, const char* decision); 101 102 wasm::CompilationEnv* const env_; 103 uint32_t function_index_; 104 SourcePositionTable* const source_positions_; 105 NodeOriginTable* const node_origins_; 106 MachineGraph* const mcgraph_; 107 const wasm::WireBytesStorage* const wire_bytes_; 108 std::vector<WasmLoopInfo>* const loop_infos_; 109 const char* debug_name_; 110 const size_t initial_graph_size_; 111 size_t current_graph_size_; 112 std::priority_queue<CandidateInfo, std::vector<CandidateInfo>, 113 LexicographicOrdering> 114 inlining_candidates_; 115 std::unordered_set<Node*> seen_; 116 std::vector<uint32_t> inlined_functions_; 117 // Stores the graph size before an inlining was performed, to make it 118 // possible to map back from nodes to the function they came from. 119 // Guaranteed to have the same length as {inlined_functions_}. 120 std::vector<uint32_t> first_node_id_; 121 }; 122 123 } // namespace compiler 124 } // namespace internal 125 } // namespace v8 126 127 #endif // V8_COMPILER_WASM_INLINING_H_ 128