| // Copyright 2015 the V8 project authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef V8_COMPILER_JS_INLINING_HEURISTIC_H_ |
| #define V8_COMPILER_JS_INLINING_HEURISTIC_H_ |
| |
| #include "src/compiler/js-inlining.h" |
| |
| namespace v8 { |
| namespace internal { |
| namespace compiler { |
| |
| class JSInliningHeuristic final : public AdvancedReducer { |
| public: |
| JSInliningHeuristic(Editor* editor, Zone* local_zone, |
| OptimizedCompilationInfo* info, JSGraph* jsgraph, |
| JSHeapBroker* broker, |
| SourcePositionTable* source_positions) |
| : AdvancedReducer(editor), |
| inliner_(editor, local_zone, info, jsgraph, broker, source_positions), |
| candidates_(local_zone), |
| seen_(local_zone), |
| source_positions_(source_positions), |
| jsgraph_(jsgraph), |
| broker_(broker) {} |
| |
| const char* reducer_name() const override { return "JSInliningHeuristic"; } |
| |
| Reduction Reduce(Node* node) final; |
| |
| // Processes the list of candidates gathered while the reducer was running, |
| // and inlines call sites that the heuristic determines to be important. |
| void Finalize() final; |
| |
| int total_inlined_bytecode_size() const { |
| return total_inlined_bytecode_size_; |
| } |
| |
| private: |
| // This limit currently matches what the old compiler did. We may want to |
| // re-evaluate and come up with a proper limit for TurboFan. |
| static const int kMaxCallPolymorphism = 4; |
| |
| struct Candidate { |
| base::Optional<JSFunctionRef> functions[kMaxCallPolymorphism]; |
| // In the case of polymorphic inlining, this tells if each of the |
| // functions could be inlined. |
| bool can_inline_function[kMaxCallPolymorphism]; |
| // Strong references to bytecode to ensure it is not flushed from SFI |
| // while choosing inlining candidates. |
| base::Optional<BytecodeArrayRef> bytecode[kMaxCallPolymorphism]; |
| // TODO(2206): For now polymorphic inlining is treated orthogonally to |
| // inlining based on SharedFunctionInfo. This should be unified and the |
| // above array should be switched to SharedFunctionInfo instead. Currently |
| // we use {num_functions == 1 && functions[0].is_null()} as an indicator. |
| base::Optional<SharedFunctionInfoRef> shared_info; |
| int num_functions; |
| Node* node = nullptr; // The call site at which to inline. |
| CallFrequency frequency; // Relative frequency of this call site. |
| int total_size = 0; |
| }; |
| |
| // Comparator for candidates. |
| struct CandidateCompare { |
| bool operator()(const Candidate& left, const Candidate& right) const; |
| }; |
| |
| // Candidates are kept in a sorted set of unique candidates. |
| using Candidates = ZoneSet<Candidate, CandidateCompare>; |
| |
| // Dumps candidates to console. |
| void PrintCandidates(); |
| Reduction InlineCandidate(Candidate const& candidate, bool small_function); |
| void CreateOrReuseDispatch(Node* node, Node* callee, |
| Candidate const& candidate, Node** if_successes, |
| Node** calls, Node** inputs, int input_count); |
| bool TryReuseDispatch(Node* node, Node* callee, Node** if_successes, |
| Node** calls, Node** inputs, int input_count); |
| enum StateCloneMode { kCloneState, kChangeInPlace }; |
| Node* DuplicateFrameStateAndRename(Node* frame_state, Node* from, Node* to, |
| StateCloneMode mode); |
| Node* DuplicateStateValuesAndRename(Node* state_values, Node* from, Node* to, |
| StateCloneMode mode); |
| Candidate CollectFunctions(Node* node, int functions_size); |
| |
| CommonOperatorBuilder* common() const; |
| Graph* graph() const; |
| JSGraph* jsgraph() const { return jsgraph_; } |
| // TODO(neis): Make heap broker a component of JSGraph? |
| JSHeapBroker* broker() const { return broker_; } |
| Isolate* isolate() const { return jsgraph_->isolate(); } |
| SimplifiedOperatorBuilder* simplified() const; |
| |
| JSInliner inliner_; |
| Candidates candidates_; |
| ZoneSet<NodeId> seen_; |
| SourcePositionTable* source_positions_; |
| JSGraph* const jsgraph_; |
| JSHeapBroker* const broker_; |
| int total_inlined_bytecode_size_ = 0; |
| }; |
| |
| } // namespace compiler |
| } // namespace internal |
| } // namespace v8 |
| |
| #endif // V8_COMPILER_JS_INLINING_HEURISTIC_H_ |