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