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 { kGeneralInlining, kRestrictedInlining, kStressInlining }; JSInliningHeuristic(Editor * editor,Mode mode,Zone * local_zone,OptimizedCompilationInfo * info,JSGraph * jsgraph,SourcePositionTable * source_positions)17 JSInliningHeuristic(Editor* editor, Mode mode, Zone* local_zone, 18 OptimizedCompilationInfo* info, JSGraph* jsgraph, 19 SourcePositionTable* source_positions) 20 : AdvancedReducer(editor), 21 mode_(mode), 22 inliner_(editor, local_zone, info, jsgraph, source_positions), 23 candidates_(local_zone), 24 seen_(local_zone), 25 source_positions_(source_positions), 26 jsgraph_(jsgraph) {} 27 reducer_name()28 const char* reducer_name() const override { return "JSInliningHeuristic"; } 29 30 Reduction Reduce(Node* node) final; 31 32 // Processes the list of candidates gathered while the reducer was running, 33 // and inlines call sites that the heuristic determines to be important. 34 void Finalize() final; 35 36 private: 37 // This limit currently matches what the old compiler did. We may want to 38 // re-evaluate and come up with a proper limit for TurboFan. 39 static const int kMaxCallPolymorphism = 4; 40 41 struct Candidate { 42 Handle<JSFunction> functions[kMaxCallPolymorphism]; 43 // In the case of polymorphic inlining, this tells if each of the 44 // functions could be inlined. 45 bool can_inline_function[kMaxCallPolymorphism]; 46 // TODO(2206): For now polymorphic inlining is treated orthogonally to 47 // inlining based on SharedFunctionInfo. This should be unified and the 48 // above array should be switched to SharedFunctionInfo instead. Currently 49 // we use {num_functions == 1 && functions[0].is_null()} as an indicator. 50 Handle<SharedFunctionInfo> shared_info; 51 int num_functions; 52 Node* node = nullptr; // The call site at which to inline. 53 CallFrequency frequency; // Relative frequency of this call site. 54 int total_size = 0; 55 }; 56 57 // Comparator for candidates. 58 struct CandidateCompare { 59 bool operator()(const Candidate& left, const Candidate& right) const; 60 }; 61 62 // Candidates are kept in a sorted set of unique candidates. 63 typedef ZoneSet<Candidate, CandidateCompare> Candidates; 64 65 // Dumps candidates to console. 66 void PrintCandidates(); 67 Reduction InlineCandidate(Candidate const& candidate, bool small_function); 68 void CreateOrReuseDispatch(Node* node, Node* callee, 69 Candidate const& candidate, Node** if_successes, 70 Node** calls, Node** inputs, int input_count); 71 bool TryReuseDispatch(Node* node, Node* callee, Candidate const& candidate, 72 Node** if_successes, Node** calls, Node** inputs, 73 int input_count); 74 enum StateCloneMode { kCloneState, kChangeInPlace }; 75 Node* DuplicateFrameStateAndRename(Node* frame_state, Node* from, Node* to, 76 StateCloneMode mode); 77 Node* DuplicateStateValuesAndRename(Node* state_values, Node* from, Node* to, 78 StateCloneMode mode); 79 80 CommonOperatorBuilder* common() const; 81 Graph* graph() const; jsgraph()82 JSGraph* jsgraph() const { return jsgraph_; } isolate()83 Isolate* isolate() const { return jsgraph_->isolate(); } 84 SimplifiedOperatorBuilder* simplified() const; 85 86 Mode const mode_; 87 JSInliner inliner_; 88 Candidates candidates_; 89 ZoneSet<NodeId> seen_; 90 SourcePositionTable* source_positions_; 91 JSGraph* const jsgraph_; 92 int cumulative_count_ = 0; 93 }; 94 95 } // namespace compiler 96 } // namespace internal 97 } // namespace v8 98 99 #endif // V8_COMPILER_JS_INLINING_HEURISTIC_H_ 100