1 // Copyright 2015 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 #ifndef V8_COMPILER_JS_INLINING_HEURISTIC_H_ 6 #define V8_COMPILER_JS_INLINING_HEURISTIC_H_ 7 8 #include "src/compiler/js-inlining.h" 9 10 namespace v8 { 11 namespace internal { 12 namespace compiler { 13 14 class JSInliningHeuristic final : public AdvancedReducer { 15 public: 16 enum Mode { kJSOnly, kWasmOnly }; 17 JSInliningHeuristic(Editor * editor,Zone * local_zone,OptimizedCompilationInfo * info,JSGraph * jsgraph,JSHeapBroker * broker,SourcePositionTable * source_positions,Mode mode)18 JSInliningHeuristic(Editor* editor, Zone* local_zone, 19 OptimizedCompilationInfo* info, JSGraph* jsgraph, 20 JSHeapBroker* broker, 21 SourcePositionTable* source_positions, Mode mode) 22 : AdvancedReducer(editor), 23 inliner_(editor, local_zone, info, jsgraph, broker, source_positions), 24 candidates_(local_zone), 25 seen_(local_zone), 26 source_positions_(source_positions), 27 jsgraph_(jsgraph), 28 broker_(broker), 29 mode_(mode), 30 max_inlined_bytecode_size_cumulative_( 31 FLAG_max_inlined_bytecode_size_cumulative), 32 max_inlined_bytecode_size_absolute_( 33 FLAG_max_inlined_bytecode_size_absolute) {} 34 reducer_name()35 const char* reducer_name() const override { return "JSInliningHeuristic"; } 36 37 Reduction Reduce(Node* node) final; 38 39 // Processes the list of candidates gathered while the reducer was running, 40 // and inlines call sites that the heuristic determines to be important. 41 void Finalize() final; 42 total_inlined_bytecode_size()43 int total_inlined_bytecode_size() const { 44 return total_inlined_bytecode_size_; 45 } 46 47 private: 48 // This limit currently matches what the old compiler did. We may want to 49 // re-evaluate and come up with a proper limit for TurboFan. 50 static const int kMaxCallPolymorphism = 4; 51 52 struct Candidate { 53 base::Optional<JSFunctionRef> functions[kMaxCallPolymorphism]; 54 // In the case of polymorphic inlining, this tells if each of the 55 // functions could be inlined. 56 bool can_inline_function[kMaxCallPolymorphism]; 57 // Strong references to bytecode to ensure it is not flushed from SFI 58 // while choosing inlining candidates. 59 base::Optional<BytecodeArrayRef> bytecode[kMaxCallPolymorphism]; 60 // TODO(2206): For now polymorphic inlining is treated orthogonally to 61 // inlining based on SharedFunctionInfo. This should be unified and the 62 // above array should be switched to SharedFunctionInfo instead. Currently 63 // we use {num_functions == 1 && functions[0].is_null()} as an indicator. 64 base::Optional<SharedFunctionInfoRef> shared_info; 65 int num_functions; 66 Node* node = nullptr; // The call site at which to inline. 67 CallFrequency frequency; // Relative frequency of this call site. 68 int total_size = 0; 69 }; 70 71 // Comparator for candidates. 72 struct CandidateCompare { 73 bool operator()(const Candidate& left, const Candidate& right) const; 74 }; 75 76 // Candidates are kept in a sorted set of unique candidates. 77 using Candidates = ZoneSet<Candidate, CandidateCompare>; 78 79 // Dumps candidates to console. 80 void PrintCandidates(); 81 Reduction InlineCandidate(Candidate const& candidate, bool small_function); 82 void CreateOrReuseDispatch(Node* node, Node* callee, 83 Candidate const& candidate, Node** if_successes, 84 Node** calls, Node** inputs, int input_count); 85 bool TryReuseDispatch(Node* node, Node* callee, Node** if_successes, 86 Node** calls, Node** inputs, int input_count); 87 enum StateCloneMode { kCloneState, kChangeInPlace }; 88 FrameState DuplicateFrameStateAndRename(FrameState frame_state, Node* from, 89 Node* to, StateCloneMode mode); 90 Node* DuplicateStateValuesAndRename(Node* state_values, Node* from, Node* to, 91 StateCloneMode mode); 92 Candidate CollectFunctions(Node* node, int functions_size); 93 94 CommonOperatorBuilder* common() const; 95 Graph* graph() const; jsgraph()96 JSGraph* jsgraph() const { return jsgraph_; } 97 // TODO(neis): Make heap broker a component of JSGraph? broker()98 JSHeapBroker* broker() const { return broker_; } 99 CompilationDependencies* dependencies() const; isolate()100 Isolate* isolate() const { return jsgraph_->isolate(); } 101 SimplifiedOperatorBuilder* simplified() const; mode()102 Mode mode() const { return mode_; } 103 104 JSInliner inliner_; 105 Candidates candidates_; 106 ZoneSet<NodeId> seen_; 107 SourcePositionTable* source_positions_; 108 JSGraph* const jsgraph_; 109 JSHeapBroker* const broker_; 110 int total_inlined_bytecode_size_ = 0; 111 const Mode mode_; 112 const int max_inlined_bytecode_size_cumulative_; 113 const int max_inlined_bytecode_size_absolute_; 114 }; 115 116 } // namespace compiler 117 } // namespace internal 118 } // namespace v8 119 120 #endif // V8_COMPILER_JS_INLINING_HEURISTIC_H_ 121