• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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