• 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:
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