Home | History | Annotate | Download | only in compiler
      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 };
     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 
     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;
     82   JSGraph* jsgraph() const { return jsgraph_; }
     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