LCOV - code coverage report
Current view: top level - src/compiler - pipeline.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 649 772 84.1 %
Date: 2017-04-26 Functions: 125 144 86.8 %

          Line data    Source code
       1             : // Copyright 2014 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             : #include "src/compiler/pipeline.h"
       6             : 
       7             : #include <fstream>  // NOLINT(readability/streams)
       8             : #include <memory>
       9             : #include <sstream>
      10             : 
      11             : #include "src/base/adapters.h"
      12             : #include "src/base/platform/elapsed-timer.h"
      13             : #include "src/compilation-info.h"
      14             : #include "src/compiler.h"
      15             : #include "src/compiler/ast-graph-builder.h"
      16             : #include "src/compiler/ast-loop-assignment-analyzer.h"
      17             : #include "src/compiler/basic-block-instrumentor.h"
      18             : #include "src/compiler/branch-elimination.h"
      19             : #include "src/compiler/bytecode-graph-builder.h"
      20             : #include "src/compiler/checkpoint-elimination.h"
      21             : #include "src/compiler/code-generator.h"
      22             : #include "src/compiler/common-operator-reducer.h"
      23             : #include "src/compiler/control-flow-optimizer.h"
      24             : #include "src/compiler/dead-code-elimination.h"
      25             : #include "src/compiler/effect-control-linearizer.h"
      26             : #include "src/compiler/escape-analysis-reducer.h"
      27             : #include "src/compiler/escape-analysis.h"
      28             : #include "src/compiler/frame-elider.h"
      29             : #include "src/compiler/graph-trimmer.h"
      30             : #include "src/compiler/graph-visualizer.h"
      31             : #include "src/compiler/instruction-selector.h"
      32             : #include "src/compiler/instruction.h"
      33             : #include "src/compiler/js-builtin-reducer.h"
      34             : #include "src/compiler/js-call-reducer.h"
      35             : #include "src/compiler/js-context-specialization.h"
      36             : #include "src/compiler/js-create-lowering.h"
      37             : #include "src/compiler/js-frame-specialization.h"
      38             : #include "src/compiler/js-generic-lowering.h"
      39             : #include "src/compiler/js-inlining-heuristic.h"
      40             : #include "src/compiler/js-intrinsic-lowering.h"
      41             : #include "src/compiler/js-native-context-specialization.h"
      42             : #include "src/compiler/js-typed-lowering.h"
      43             : #include "src/compiler/jump-threading.h"
      44             : #include "src/compiler/live-range-separator.h"
      45             : #include "src/compiler/load-elimination.h"
      46             : #include "src/compiler/loop-analysis.h"
      47             : #include "src/compiler/loop-peeling.h"
      48             : #include "src/compiler/loop-variable-optimizer.h"
      49             : #include "src/compiler/machine-graph-verifier.h"
      50             : #include "src/compiler/machine-operator-reducer.h"
      51             : #include "src/compiler/memory-optimizer.h"
      52             : #include "src/compiler/move-optimizer.h"
      53             : #include "src/compiler/osr.h"
      54             : #include "src/compiler/pipeline-statistics.h"
      55             : #include "src/compiler/redundancy-elimination.h"
      56             : #include "src/compiler/register-allocator-verifier.h"
      57             : #include "src/compiler/register-allocator.h"
      58             : #include "src/compiler/schedule.h"
      59             : #include "src/compiler/scheduler.h"
      60             : #include "src/compiler/select-lowering.h"
      61             : #include "src/compiler/simplified-lowering.h"
      62             : #include "src/compiler/simplified-operator-reducer.h"
      63             : #include "src/compiler/simplified-operator.h"
      64             : #include "src/compiler/store-store-elimination.h"
      65             : #include "src/compiler/tail-call-optimization.h"
      66             : #include "src/compiler/typed-optimization.h"
      67             : #include "src/compiler/typer.h"
      68             : #include "src/compiler/value-numbering-reducer.h"
      69             : #include "src/compiler/verifier.h"
      70             : #include "src/compiler/zone-stats.h"
      71             : #include "src/isolate-inl.h"
      72             : #include "src/ostreams.h"
      73             : #include "src/parsing/parse-info.h"
      74             : #include "src/register-configuration.h"
      75             : #include "src/trap-handler/trap-handler.h"
      76             : #include "src/type-info.h"
      77             : #include "src/utils.h"
      78             : 
      79             : namespace v8 {
      80             : namespace internal {
      81             : namespace compiler {
      82             : 
      83             : class PipelineData {
      84             :  public:
      85             :   // For main entry point.
      86      423221 :   PipelineData(ZoneStats* zone_stats, CompilationInfo* info,
      87             :                PipelineStatistics* pipeline_statistics)
      88             :       : isolate_(info->isolate()),
      89             :         info_(info),
      90             :         debug_name_(info_->GetDebugName()),
      91      423221 :         outer_zone_(info_->zone()),
      92             :         zone_stats_(zone_stats),
      93             :         pipeline_statistics_(pipeline_statistics),
      94             :         graph_zone_scope_(zone_stats_, ZONE_NAME),
      95      423221 :         graph_zone_(graph_zone_scope_.zone()),
      96             :         instruction_zone_scope_(zone_stats_, ZONE_NAME),
      97      423222 :         instruction_zone_(instruction_zone_scope_.zone()),
      98             :         register_allocation_zone_scope_(zone_stats_, ZONE_NAME),
      99     2539329 :         register_allocation_zone_(register_allocation_zone_scope_.zone()) {
     100             :     PhaseScope scope(pipeline_statistics, "init pipeline data");
     101      846443 :     graph_ = new (graph_zone_) Graph(graph_zone_);
     102      846442 :     source_positions_ = new (graph_zone_) SourcePositionTable(graph_);
     103      846444 :     simplified_ = new (graph_zone_) SimplifiedOperatorBuilder(graph_zone_);
     104             :     machine_ = new (graph_zone_) MachineOperatorBuilder(
     105             :         graph_zone_, MachineType::PointerRepresentation(),
     106             :         InstructionSelector::SupportedMachineOperatorFlags(),
     107      846443 :         InstructionSelector::AlignmentRequirements());
     108      846443 :     common_ = new (graph_zone_) CommonOperatorBuilder(graph_zone_);
     109      846443 :     javascript_ = new (graph_zone_) JSOperatorBuilder(graph_zone_);
     110             :     jsgraph_ = new (graph_zone_)
     111     1269666 :         JSGraph(isolate_, graph_, common_, javascript_, simplified_, machine_);
     112      846444 :     is_asm_ = info->shared_info()->asm_function();
     113      423222 :   }
     114             : 
     115             :   // For WASM compile entry point.
     116      352783 :   PipelineData(ZoneStats* zone_stats, CompilationInfo* info, JSGraph* jsgraph,
     117             :                PipelineStatistics* pipeline_statistics,
     118             :                SourcePositionTable* source_positions,
     119             :                ZoneVector<trap_handler::ProtectedInstructionData>*
     120             :                    protected_instructions)
     121             :       : isolate_(info->isolate()),
     122             :         info_(info),
     123             :         debug_name_(info_->GetDebugName()),
     124             :         zone_stats_(zone_stats),
     125             :         pipeline_statistics_(pipeline_statistics),
     126             :         graph_zone_scope_(zone_stats_, ZONE_NAME),
     127             :         graph_(jsgraph->graph()),
     128             :         source_positions_(source_positions),
     129             :         machine_(jsgraph->machine()),
     130             :         common_(jsgraph->common()),
     131             :         javascript_(jsgraph->javascript()),
     132             :         jsgraph_(jsgraph),
     133             :         instruction_zone_scope_(zone_stats_, ZONE_NAME),
     134       70555 :         instruction_zone_(instruction_zone_scope_.zone()),
     135             :         register_allocation_zone_scope_(zone_stats_, ZONE_NAME),
     136       70569 :         register_allocation_zone_(register_allocation_zone_scope_.zone()),
     137      635057 :         protected_instructions_(protected_instructions) {
     138             :     is_asm_ =
     139      141135 :         info->has_shared_info() ? info->shared_info()->asm_function() : false;
     140       70560 :   }
     141             : 
     142             :   // For machine graph testing entry point.
     143      449994 :   PipelineData(ZoneStats* zone_stats, CompilationInfo* info, Graph* graph,
     144             :                Schedule* schedule, SourcePositionTable* source_positions)
     145             :       : isolate_(info->isolate()),
     146             :         info_(info),
     147             :         debug_name_(info_->GetDebugName()),
     148             :         zone_stats_(zone_stats),
     149             :         graph_zone_scope_(zone_stats_, ZONE_NAME),
     150             :         graph_(graph),
     151             :         source_positions_(source_positions),
     152             :         schedule_(schedule),
     153             :         instruction_zone_scope_(zone_stats_, ZONE_NAME),
     154      449994 :         instruction_zone_(instruction_zone_scope_.zone()),
     155             :         register_allocation_zone_scope_(zone_stats_, ZONE_NAME),
     156     2249970 :         register_allocation_zone_(register_allocation_zone_scope_.zone()) {
     157      449994 :     is_asm_ = false;
     158      449994 :   }
     159             :   // For register allocation testing entry point.
     160          42 :   PipelineData(ZoneStats* zone_stats, CompilationInfo* info,
     161          42 :                InstructionSequence* sequence)
     162             :       : isolate_(info->isolate()),
     163             :         info_(info),
     164             :         debug_name_(info_->GetDebugName()),
     165             :         zone_stats_(zone_stats),
     166             :         graph_zone_scope_(zone_stats_, ZONE_NAME),
     167             :         instruction_zone_scope_(zone_stats_, ZONE_NAME),
     168             :         instruction_zone_(sequence->zone()),
     169             :         sequence_(sequence),
     170             :         register_allocation_zone_scope_(zone_stats_, ZONE_NAME),
     171         210 :         register_allocation_zone_(register_allocation_zone_scope_.zone()) {
     172             :     is_asm_ =
     173          84 :         info->has_shared_info() ? info->shared_info()->asm_function() : false;
     174          42 :   }
     175             : 
     176      943845 :   ~PipelineData() {
     177      943845 :     DeleteRegisterAllocationZone();
     178      943845 :     DeleteInstructionZone();
     179      943845 :     DeleteGraphZone();
     180      943845 :   }
     181             : 
     182             :   Isolate* isolate() const { return isolate_; }
     183             :   CompilationInfo* info() const { return info_; }
     184             :   ZoneStats* zone_stats() const { return zone_stats_; }
     185             :   PipelineStatistics* pipeline_statistics() { return pipeline_statistics_; }
     186             :   bool compilation_failed() const { return compilation_failed_; }
     187           0 :   void set_compilation_failed() { compilation_failed_ = true; }
     188             : 
     189             :   bool is_asm() const { return is_asm_; }
     190             :   bool verify_graph() const { return verify_graph_; }
     191      111827 :   void set_verify_graph(bool value) { verify_graph_ = value; }
     192             : 
     193             :   Handle<Code> code() { return code_; }
     194             :   void set_code(Handle<Code> code) {
     195             :     DCHECK(code_.is_null());
     196      912392 :     code_ = code;
     197             :   }
     198             : 
     199             :   // RawMachineAssembler generally produces graphs which cannot be verified.
     200             :   bool MayHaveUnverifiableGraph() const { return outer_zone_ == nullptr; }
     201             : 
     202             :   Zone* graph_zone() const { return graph_zone_; }
     203             :   Graph* graph() const { return graph_; }
     204             :   SourcePositionTable* source_positions() const { return source_positions_; }
     205             :   MachineOperatorBuilder* machine() const { return machine_; }
     206             :   CommonOperatorBuilder* common() const { return common_; }
     207             :   JSOperatorBuilder* javascript() const { return javascript_; }
     208             :   JSGraph* jsgraph() const { return jsgraph_; }
     209     1581370 :   Handle<Context> native_context() const {
     210     3162742 :     return handle(info()->native_context(), isolate());
     211             :   }
     212             :   Handle<JSGlobalObject> global_object() const {
     213             :     return handle(info()->global_object(), isolate());
     214             :   }
     215             : 
     216             :   LoopAssignmentAnalysis* loop_assignment() const { return loop_assignment_; }
     217             :   void set_loop_assignment(LoopAssignmentAnalysis* loop_assignment) {
     218             :     DCHECK(!loop_assignment_);
     219        2507 :     loop_assignment_ = loop_assignment;
     220             :   }
     221             : 
     222             :   Schedule* schedule() const { return schedule_; }
     223             :   void set_schedule(Schedule* schedule) {
     224             :     DCHECK(!schedule_);
     225      568260 :     schedule_ = schedule;
     226             :   }
     227             :   void reset_schedule() { schedule_ = nullptr; }
     228             : 
     229             :   Zone* instruction_zone() const { return instruction_zone_; }
     230             :   InstructionSequence* sequence() const { return sequence_; }
     231             :   Frame* frame() const { return frame_; }
     232             : 
     233             :   Zone* register_allocation_zone() const { return register_allocation_zone_; }
     234             :   RegisterAllocationData* register_allocation_data() const {
     235             :     return register_allocation_data_;
     236             :   }
     237             : 
     238             :   BasicBlockProfiler::Data* profiler_data() const { return profiler_data_; }
     239             :   void set_profiler_data(BasicBlockProfiler::Data* profiler_data) {
     240          14 :     profiler_data_ = profiler_data;
     241             :   }
     242             : 
     243             :   std::string const& source_position_output() const {
     244             :     return source_position_output_;
     245             :   }
     246             :   void set_source_position_output(std::string const& source_position_output) {
     247           0 :     source_position_output_ = source_position_output;
     248             :   }
     249             : 
     250             :   ZoneVector<trap_handler::ProtectedInstructionData>* protected_instructions()
     251             :       const {
     252             :     return protected_instructions_;
     253             :   }
     254             : 
     255     1859723 :   void DeleteGraphZone() {
     256     3719447 :     if (graph_zone_ == nullptr) return;
     257      423221 :     graph_zone_scope_.Destroy();
     258      423222 :     graph_zone_ = nullptr;
     259      423222 :     graph_ = nullptr;
     260      423222 :     source_positions_ = nullptr;
     261      423222 :     loop_assignment_ = nullptr;
     262      423222 :     simplified_ = nullptr;
     263      423222 :     machine_ = nullptr;
     264      423222 :     common_ = nullptr;
     265      423222 :     javascript_ = nullptr;
     266      423222 :     jsgraph_ = nullptr;
     267      423222 :     schedule_ = nullptr;
     268             :   }
     269             : 
     270      943845 :   void DeleteInstructionZone() {
     271     1887690 :     if (instruction_zone_ == nullptr) return;
     272      943845 :     instruction_zone_scope_.Destroy();
     273      943845 :     instruction_zone_ = nullptr;
     274      943845 :     sequence_ = nullptr;
     275      943845 :     frame_ = nullptr;
     276             :   }
     277             : 
     278     1859754 :   void DeleteRegisterAllocationZone() {
     279     3719522 :     if (register_allocation_zone_ == nullptr) return;
     280      943835 :     register_allocation_zone_scope_.Destroy();
     281      943849 :     register_allocation_zone_ = nullptr;
     282      943849 :     register_allocation_data_ = nullptr;
     283             :   }
     284             : 
     285     2747580 :   void InitializeInstructionSequence(const CallDescriptor* descriptor) {
     286             :     DCHECK(sequence_ == nullptr);
     287             :     InstructionBlocks* instruction_blocks =
     288             :         InstructionSequence::InstructionBlocksFor(instruction_zone(),
     289      915848 :                                                   schedule());
     290             :     sequence_ = new (instruction_zone()) InstructionSequence(
     291     1831736 :         info()->isolate(), instruction_zone(), instruction_blocks);
     292     1831711 :     if (descriptor && descriptor->RequiresFrameAsIncoming()) {
     293      684305 :       sequence_->instruction_blocks()[0]->mark_needs_frame();
     294             :     } else {
     295             :       DCHECK_EQ(0u, descriptor->CalleeSavedFPRegisters());
     296             :       DCHECK_EQ(0u, descriptor->CalleeSavedRegisters());
     297             :     }
     298      915855 :   }
     299             : 
     300     1831803 :   void InitializeFrameData(CallDescriptor* descriptor) {
     301             :     DCHECK(frame_ == nullptr);
     302             :     int fixed_frame_size = 0;
     303      915899 :     if (descriptor != nullptr) {
     304      915859 :       fixed_frame_size = descriptor->CalculateFixedFrameSize();
     305             :     }
     306      915908 :     frame_ = new (instruction_zone()) Frame(fixed_frame_size);
     307      915882 :   }
     308             : 
     309      915904 :   void InitializeRegisterAllocationData(const RegisterConfiguration* config,
     310      915904 :                                         CallDescriptor* descriptor) {
     311             :     DCHECK(register_allocation_data_ == nullptr);
     312             :     register_allocation_data_ = new (register_allocation_zone())
     313             :         RegisterAllocationData(config, register_allocation_zone(), frame(),
     314      915929 :                                sequence(), debug_name());
     315      915908 :   }
     316             : 
     317     3014219 :   void BeginPhaseKind(const char* phase_kind_name) {
     318     3014219 :     if (pipeline_statistics() != nullptr) {
     319           0 :       pipeline_statistics()->BeginPhaseKind(phase_kind_name);
     320             :     }
     321             :   }
     322             : 
     323     1311228 :   void EndPhaseKind() {
     324     1311228 :     if (pipeline_statistics() != nullptr) {
     325           0 :       pipeline_statistics()->EndPhaseKind();
     326             :     }
     327             :   }
     328             : 
     329             :   const char* debug_name() const { return debug_name_.get(); }
     330             : 
     331             :  private:
     332             :   Isolate* const isolate_;
     333             :   CompilationInfo* const info_;
     334             :   std::unique_ptr<char[]> debug_name_;
     335             :   Zone* outer_zone_ = nullptr;
     336             :   ZoneStats* const zone_stats_;
     337             :   PipelineStatistics* pipeline_statistics_ = nullptr;
     338             :   bool compilation_failed_ = false;
     339             :   bool verify_graph_ = false;
     340             :   bool is_asm_ = false;
     341             :   Handle<Code> code_ = Handle<Code>::null();
     342             : 
     343             :   // All objects in the following group of fields are allocated in graph_zone_.
     344             :   // They are all set to nullptr when the graph_zone_ is destroyed.
     345             :   ZoneStats::Scope graph_zone_scope_;
     346             :   Zone* graph_zone_ = nullptr;
     347             :   Graph* graph_ = nullptr;
     348             :   SourcePositionTable* source_positions_ = nullptr;
     349             :   LoopAssignmentAnalysis* loop_assignment_ = nullptr;
     350             :   SimplifiedOperatorBuilder* simplified_ = nullptr;
     351             :   MachineOperatorBuilder* machine_ = nullptr;
     352             :   CommonOperatorBuilder* common_ = nullptr;
     353             :   JSOperatorBuilder* javascript_ = nullptr;
     354             :   JSGraph* jsgraph_ = nullptr;
     355             :   Schedule* schedule_ = nullptr;
     356             : 
     357             :   // All objects in the following group of fields are allocated in
     358             :   // instruction_zone_.  They are all set to nullptr when the instruction_zone_
     359             :   // is
     360             :   // destroyed.
     361             :   ZoneStats::Scope instruction_zone_scope_;
     362             :   Zone* instruction_zone_;
     363             :   InstructionSequence* sequence_ = nullptr;
     364             :   Frame* frame_ = nullptr;
     365             : 
     366             :   // All objects in the following group of fields are allocated in
     367             :   // register_allocation_zone_.  They are all set to nullptr when the zone is
     368             :   // destroyed.
     369             :   ZoneStats::Scope register_allocation_zone_scope_;
     370             :   Zone* register_allocation_zone_;
     371             :   RegisterAllocationData* register_allocation_data_ = nullptr;
     372             : 
     373             :   // Basic block profiling support.
     374             :   BasicBlockProfiler::Data* profiler_data_ = nullptr;
     375             : 
     376             :   // Source position output for --trace-turbo.
     377             :   std::string source_position_output_;
     378             : 
     379             :   ZoneVector<trap_handler::ProtectedInstructionData>* protected_instructions_ =
     380             :       nullptr;
     381             : 
     382             :   DISALLOW_COPY_AND_ASSIGN(PipelineData);
     383             : };
     384             : 
     385             : class PipelineImpl final {
     386             :  public:
     387      943815 :   explicit PipelineImpl(PipelineData* data) : data_(data) {}
     388             : 
     389             :   // Helpers for executing pipeline phases.
     390             :   template <typename Phase>
     391             :   void Run();
     392             :   template <typename Phase, typename Arg0>
     393             :   void Run(Arg0 arg_0);
     394             :   template <typename Phase, typename Arg0, typename Arg1>
     395             :   void Run(Arg0 arg_0, Arg1 arg_1);
     396             : 
     397             :   // Run the graph creation and initial optimization passes.
     398             :   bool CreateGraph();
     399             : 
     400             :   // Run the concurrent optimization passes.
     401             :   bool OptimizeGraph(Linkage* linkage);
     402             : 
     403             :   // Perform the actual code generation and return handle to a code object.
     404             :   Handle<Code> GenerateCode(Linkage* linkage);
     405             : 
     406             :   bool ScheduleAndSelectInstructions(Linkage* linkage, bool trim_graph);
     407             :   void RunPrintAndVerify(const char* phase, bool untyped = false);
     408             :   Handle<Code> ScheduleAndGenerateCode(CallDescriptor* call_descriptor);
     409             :   void AllocateRegisters(const RegisterConfiguration* config,
     410             :                          CallDescriptor* descriptor, bool run_verifier);
     411             : 
     412             :   CompilationInfo* info() const;
     413             :   Isolate* isolate() const;
     414             : 
     415             :   PipelineData* const data_;
     416             : };
     417             : 
     418             : namespace {
     419             : 
     420           0 : struct TurboCfgFile : public std::ofstream {
     421           0 :   explicit TurboCfgFile(Isolate* isolate)
     422             :       : std::ofstream(isolate->GetTurboCfgFileName().c_str(),
     423           0 :                       std::ios_base::app) {}
     424             : };
     425             : 
     426           0 : struct TurboJsonFile : public std::ofstream {
     427           0 :   TurboJsonFile(CompilationInfo* info, std::ios_base::openmode mode)
     428           0 :       : std::ofstream(GetVisualizerLogFileName(info, nullptr, "json").get(),
     429           0 :                       mode) {}
     430             : };
     431             : 
     432     1311173 : void TraceSchedule(CompilationInfo* info, Schedule* schedule) {
     433     1311174 :   if (FLAG_trace_turbo) {
     434             :     AllowHandleDereference allow_deref;
     435           0 :     TurboJsonFile json_of(info, std::ios_base::app);
     436           0 :     json_of << "{\"name\":\"Schedule\",\"type\":\"schedule\",\"data\":\"";
     437           0 :     std::stringstream schedule_stream;
     438           0 :     schedule_stream << *schedule;
     439             :     std::string schedule_string(schedule_stream.str());
     440           0 :     for (const auto& c : schedule_string) {
     441           0 :       json_of << AsEscapedUC16ForJSON(c);
     442             :     }
     443           0 :     json_of << "\"},\n";
     444             :   }
     445     1311174 :   if (FLAG_trace_turbo_graph || FLAG_trace_turbo_scheduler) {
     446             :     AllowHandleDereference allow_deref;
     447           0 :     CodeTracer::Scope tracing_scope(info->isolate()->GetCodeTracer());
     448           0 :     OFStream os(tracing_scope.file());
     449           0 :     os << "-- Schedule --------------------------------------\n" << *schedule;
     450             :   }
     451     1311175 : }
     452             : 
     453             : 
     454             : class SourcePositionWrapper final : public Reducer {
     455             :  public:
     456             :   SourcePositionWrapper(Reducer* reducer, SourcePositionTable* table)
     457     1716258 :       : reducer_(reducer), table_(table) {}
     458           0 :   ~SourcePositionWrapper() final {}
     459             : 
     460   235524297 :   Reduction Reduce(Node* node) final {
     461   235524297 :     SourcePosition const pos = table_->GetSourcePosition(node);
     462   235524652 :     SourcePositionTable::Scope position(table_, pos);
     463   471047930 :     return reducer_->Reduce(node);
     464             :   }
     465             : 
     466     1721370 :   void Finalize() final { reducer_->Finalize(); }
     467             : 
     468             :  private:
     469             :   Reducer* const reducer_;
     470             :   SourcePositionTable* const table_;
     471             : 
     472             :   DISALLOW_COPY_AND_ASSIGN(SourcePositionWrapper);
     473             : };
     474             : 
     475             : 
     476             : class JSGraphReducer final : public GraphReducer {
     477             :  public:
     478     5750787 :   JSGraphReducer(JSGraph* jsgraph, Zone* zone)
     479     5750787 :       : GraphReducer(zone, jsgraph->graph(), jsgraph->Dead()) {}
     480     2875288 :   ~JSGraphReducer() final {}
     481             : };
     482             : 
     483             : 
     484    19150426 : void AddReducer(PipelineData* data, GraphReducer* graph_reducer,
     485             :                 Reducer* reducer) {
     486    15717908 :   if (data->info()->is_source_positions_enabled()) {
     487     1716259 :     void* const buffer = data->graph_zone()->New(sizeof(SourcePositionWrapper));
     488             :     SourcePositionWrapper* const wrapper =
     489     1716259 :         new (buffer) SourcePositionWrapper(reducer, data->source_positions());
     490     1716259 :     graph_reducer->AddReducer(wrapper);
     491             :   } else {
     492    14001649 :     graph_reducer->AddReducer(reducer);
     493             :   }
     494    15717846 : }
     495             : 
     496             : 
     497    50414903 : class PipelineRunScope {
     498             :  public:
     499    75509070 :   PipelineRunScope(PipelineData* data, const char* phase_name)
     500             :       : phase_scope_(
     501             :             phase_name == nullptr ? nullptr : data->pipeline_statistics(),
     502             :             phase_name),
     503    50413902 :         zone_scope_(data->zone_stats(), ZONE_NAME) {}
     504             : 
     505    25279293 :   Zone* zone() { return zone_scope_.zone(); }
     506             : 
     507             :  private:
     508             :   PhaseScope phase_scope_;
     509             :   ZoneStats::Scope zone_scope_;
     510             : };
     511             : 
     512      493789 : PipelineStatistics* CreatePipelineStatistics(CompilationInfo* info,
     513             :                                              ZoneStats* zone_stats) {
     514             :   PipelineStatistics* pipeline_statistics = nullptr;
     515             : 
     516      493789 :   if (FLAG_turbo_stats || FLAG_turbo_stats_nvp) {
     517           0 :     pipeline_statistics = new PipelineStatistics(info, zone_stats);
     518           0 :     pipeline_statistics->BeginPhaseKind("initializing");
     519             :   }
     520             : 
     521      493790 :   if (FLAG_trace_turbo) {
     522           0 :     TurboJsonFile json_of(info, std::ios_base::trunc);
     523           0 :     std::unique_ptr<char[]> function_name = info->GetDebugName();
     524           0 :     int pos = info->parse_info() ? info->shared_info()->start_position() : 0;
     525           0 :     json_of << "{\"function\":\"" << function_name.get()
     526           0 :             << "\", \"sourcePosition\":" << pos << ", \"source\":\"";
     527             :     Isolate* isolate = info->isolate();
     528             :     Handle<Script> script =
     529           0 :         info->parse_info() ? info->script() : Handle<Script>::null();
     530           0 :     if (!script.is_null() && !script->source()->IsUndefined(isolate)) {
     531             :       DisallowHeapAllocation no_allocation;
     532           0 :       int start = info->shared_info()->start_position();
     533           0 :       int len = info->shared_info()->end_position() - start;
     534             :       String::SubStringRange source(String::cast(script->source()), start, len);
     535           0 :       for (const auto& c : source) {
     536           0 :         json_of << AsEscapedUC16ForJSON(c);
     537             :       }
     538             :     }
     539           0 :     json_of << "\",\n\"phases\":[";
     540             :   }
     541             : 
     542      493790 :   return pipeline_statistics;
     543             : }
     544             : 
     545             : }  // namespace
     546             : 
     547     1673328 : class PipelineCompilationJob final : public CompilationJob {
     548             :  public:
     549      418335 :   PipelineCompilationJob(ParseInfo* parse_info, Handle<JSFunction> function)
     550             :       // Note that the CompilationInfo is not initialized at the time we pass it
     551             :       // to the CompilationJob constructor, but it is not dereferenced there.
     552             :       : CompilationJob(function->GetIsolate(), &info_, "TurboFan"),
     553             :         parse_info_(parse_info),
     554             :         zone_stats_(function->GetIsolate()->allocator()),
     555             :         info_(parse_info_.get()->zone(), parse_info_.get(),
     556             :               function->GetIsolate(), function),
     557             :         pipeline_statistics_(CreatePipelineStatistics(info(), &zone_stats_)),
     558             :         data_(&zone_stats_, info(), pipeline_statistics_.get()),
     559             :         pipeline_(&data_),
     560     2510011 :         linkage_(nullptr) {}
     561             : 
     562             :  protected:
     563             :   Status PrepareJobImpl() final;
     564             :   Status ExecuteJobImpl() final;
     565             :   Status FinalizeJobImpl() final;
     566             : 
     567             :  private:
     568             :   std::unique_ptr<ParseInfo> parse_info_;
     569             :   ZoneStats zone_stats_;
     570             :   CompilationInfo info_;
     571             :   std::unique_ptr<PipelineStatistics> pipeline_statistics_;
     572             :   PipelineData data_;
     573             :   PipelineImpl pipeline_;
     574             :   Linkage* linkage_;
     575             : 
     576             :   DISALLOW_COPY_AND_ASSIGN(PipelineCompilationJob);
     577             : };
     578             : 
     579      390457 : PipelineCompilationJob::Status PipelineCompilationJob::PrepareJobImpl() {
     580     4346213 :   if (info()->shared_info()->asm_function()) {
     581        2191 :     if (info()->osr_frame() && !info()->is_optimizing_from_bytecode()) {
     582             :       info()->MarkAsFrameSpecializing();
     583             :     }
     584             :     info()->MarkAsFunctionContextSpecializing();
     585             :   } else {
     586      388346 :     if (!FLAG_always_opt) {
     587             :       info()->MarkAsBailoutOnUninitialized();
     588             :     }
     589      388346 :     if (FLAG_turbo_loop_peeling) {
     590             :       info()->MarkAsLoopPeelingEnabled();
     591             :     }
     592             :   }
     593     1171371 :   if (info()->is_optimizing_from_bytecode() ||
     594      394603 :       !info()->shared_info()->asm_function()) {
     595             :     info()->MarkAsDeoptimizationEnabled();
     596      388388 :     if (FLAG_inline_accessors) {
     597             :       info()->MarkAsAccessorInliningEnabled();
     598             :     }
     599      388388 :     if (info()->closure()->feedback_vector_cell()->map() ==
     600      388388 :         isolate()->heap()->one_closure_cell_map()) {
     601             :       info()->MarkAsFunctionContextSpecializing();
     602             :     }
     603             :   }
     604      390457 :   if (!info()->is_optimizing_from_bytecode()) {
     605        2073 :     if (!Compiler::EnsureDeoptimizationSupport(info())) return FAILED;
     606      388384 :   } else if (FLAG_turbo_inlining) {
     607             :     info()->MarkAsInliningEnabled();
     608             :   }
     609             : 
     610      390457 :   linkage_ = new (info()->zone())
     611      780914 :       Linkage(Linkage::ComputeIncoming(info()->zone(), info()));
     612             : 
     613      390457 :   if (!pipeline_.CreateGraph()) {
     614           0 :     if (isolate()->has_pending_exception()) return FAILED;  // Stack overflowed.
     615           0 :     return AbortOptimization(kGraphBuildingFailed);
     616             :   }
     617             : 
     618             :   return SUCCEEDED;
     619             : }
     620             : 
     621      390417 : PipelineCompilationJob::Status PipelineCompilationJob::ExecuteJobImpl() {
     622      390417 :   if (!pipeline_.OptimizeGraph(linkage_)) return FAILED;
     623      390409 :   return SUCCEEDED;
     624             : }
     625             : 
     626      386919 : PipelineCompilationJob::Status PipelineCompilationJob::FinalizeJobImpl() {
     627      386919 :   Handle<Code> code = pipeline_.GenerateCode(linkage_);
     628      386920 :   if (code.is_null()) {
     629      773841 :     if (info()->bailout_reason() == kNoReason) {
     630           0 :       return AbortOptimization(kCodeGenerationFailed);
     631             :     }
     632             :     return FAILED;
     633             :   }
     634      386920 :   info()->dependencies()->Commit(code);
     635             :   info()->SetCode(code);
     636      386921 :   if (info()->is_deoptimization_enabled()) {
     637      769736 :     info()->context()->native_context()->AddOptimizedCode(*code);
     638      384867 :     RegisterWeakObjectsInOptimizedCode(code);
     639             :   }
     640             :   return SUCCEEDED;
     641             : }
     642             : 
     643      282364 : class PipelineWasmCompilationJob final : public CompilationJob {
     644             :  public:
     645       70586 :   explicit PipelineWasmCompilationJob(
     646      141164 :       CompilationInfo* info, JSGraph* jsgraph, CallDescriptor* descriptor,
     647             :       SourcePositionTable* source_positions,
     648             :       ZoneVector<trap_handler::ProtectedInstructionData>* protected_insts,
     649             :       bool allow_signalling_nan)
     650             :       : CompilationJob(info->isolate(), info, "TurboFan",
     651             :                        State::kReadyToExecute),
     652             :         zone_stats_(info->isolate()->allocator()),
     653             :         pipeline_statistics_(CreatePipelineStatistics(info, &zone_stats_)),
     654             :         data_(&zone_stats_, info, jsgraph, pipeline_statistics_.get(),
     655             :               source_positions, protected_insts),
     656             :         pipeline_(&data_),
     657             :         linkage_(descriptor),
     658      282289 :         allow_signalling_nan_(allow_signalling_nan) {}
     659             : 
     660             :  protected:
     661             :   Status PrepareJobImpl() final;
     662             :   Status ExecuteJobImpl() final;
     663             :   Status FinalizeJobImpl() final;
     664             : 
     665             :  private:
     666             :   ZoneStats zone_stats_;
     667             :   std::unique_ptr<PipelineStatistics> pipeline_statistics_;
     668             :   PipelineData data_;
     669             :   PipelineImpl pipeline_;
     670             :   Linkage linkage_;
     671             :   bool allow_signalling_nan_;
     672             : };
     673             : 
     674             : PipelineWasmCompilationJob::Status
     675           0 : PipelineWasmCompilationJob::PrepareJobImpl() {
     676           0 :   UNREACHABLE();  // Prepare should always be skipped for WasmCompilationJob.
     677             :   return SUCCEEDED;
     678             : }
     679             : 
     680             : PipelineWasmCompilationJob::Status
     681       70510 : PipelineWasmCompilationJob::ExecuteJobImpl() {
     682       70510 :   if (FLAG_trace_turbo) {
     683           0 :     TurboJsonFile json_of(info(), std::ios_base::trunc);
     684           0 :     json_of << "{\"function\":\"" << info()->GetDebugName().get()
     685           0 :             << "\", \"source\":\"\",\n\"phases\":[";
     686             :   }
     687             : 
     688       70510 :   pipeline_.RunPrintAndVerify("Machine", true);
     689       70517 :   if (FLAG_wasm_opt) {
     690      423333 :     PipelineData* data = &data_;
     691       70508 :     PipelineRunScope scope(data, "WASM optimization");
     692       70583 :     JSGraphReducer graph_reducer(data->jsgraph(), scope.zone());
     693             :     DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
     694       70573 :                                               data->common());
     695      211624 :     ValueNumberingReducer value_numbering(scope.zone(), data->graph()->zone());
     696             :     MachineOperatorReducer machine_reducer(data->jsgraph(),
     697      211664 :                                            allow_signalling_nan_);
     698             :     CommonOperatorReducer common_reducer(&graph_reducer, data->graph(),
     699       70554 :                                          data->common(), data->machine());
     700       70537 :     AddReducer(data, &graph_reducer, &dead_code_elimination);
     701       70502 :     AddReducer(data, &graph_reducer, &machine_reducer);
     702       70530 :     AddReducer(data, &graph_reducer, &common_reducer);
     703       70535 :     AddReducer(data, &graph_reducer, &value_numbering);
     704       70553 :     graph_reducer.ReduceGraph();
     705      141035 :     pipeline_.RunPrintAndVerify("Optimized Machine", true);
     706             :   }
     707             : 
     708       70599 :   if (!pipeline_.ScheduleAndSelectInstructions(&linkage_, true)) return FAILED;
     709       70570 :   return SUCCEEDED;
     710             : }
     711             : 
     712             : PipelineWasmCompilationJob::Status
     713       70591 : PipelineWasmCompilationJob::FinalizeJobImpl() {
     714       70591 :   pipeline_.GenerateCode(&linkage_);
     715       70591 :   return SUCCEEDED;
     716             : }
     717             : 
     718             : template <typename Phase>
     719    21886864 : void PipelineImpl::Run() {
     720    21886864 :   PipelineRunScope scope(this->data_, Phase::phase_name());
     721             :   Phase phase;
     722    23725812 :   phase.Run(this->data_, scope.zone());
     723    21887104 : }
     724             : 
     725             : template <typename Phase, typename Arg0>
     726     3139357 : void PipelineImpl::Run(Arg0 arg_0) {
     727     3139357 :   PipelineRunScope scope(this->data_, Phase::phase_name());
     728             :   Phase phase;
     729     4055323 :   phase.Run(this->data_, scope.zone(), arg_0);
     730     3139507 : }
     731             : 
     732             : template <typename Phase, typename Arg0, typename Arg1>
     733      111827 : void PipelineImpl::Run(Arg0 arg_0, Arg1 arg_1) {
     734      111827 :   PipelineRunScope scope(this->data_, Phase::phase_name());
     735             :   Phase phase;
     736      223654 :   phase.Run(this->data_, scope.zone(), arg_0, arg_1);
     737      111827 : }
     738             : 
     739             : struct LoopAssignmentAnalysisPhase {
     740             :   static const char* phase_name() { return "loop assignment analysis"; }
     741             : 
     742      394630 :   void Run(PipelineData* data, Zone* temp_zone) {
     743      392123 :     if (!data->info()->is_optimizing_from_bytecode()) {
     744        2507 :       AstLoopAssignmentAnalyzer analyzer(data->graph_zone(), data->info());
     745        2507 :       LoopAssignmentAnalysis* loop_assignment = analyzer.Analyze();
     746             :       data->set_loop_assignment(loop_assignment);
     747             :     }
     748      392123 :   }
     749             : };
     750             : 
     751             : 
     752             : struct GraphBuilderPhase {
     753             :   static const char* phase_name() { return "graph builder"; }
     754             : 
     755     1183522 :   void Run(PipelineData* data, Zone* temp_zone) {
     756             :     bool succeeded = false;
     757             : 
     758      395343 :     if (data->info()->is_optimizing_from_bytecode()) {
     759             :       // Bytecode graph builder assumes deoptimziation is enabled.
     760             :       DCHECK(data->info()->is_deoptimization_enabled());
     761             :       JSTypeHintLowering::Flags flags = JSTypeHintLowering::kNoFlags;
     762      392836 :       if (data->info()->is_bailout_on_uninitialized()) {
     763             :         flags |= JSTypeHintLowering::kBailoutOnUninitialized;
     764             :       }
     765             :       BytecodeGraphBuilder graph_builder(
     766             :           temp_zone, data->info()->shared_info(),
     767             :           handle(data->info()->closure()->feedback_vector()),
     768             :           data->info()->osr_ast_id(), data->jsgraph(), 1.0f,
     769      392836 :           data->source_positions(), SourcePosition::kNotInlined, flags);
     770      392836 :       succeeded = graph_builder.CreateGraph();
     771             :     } else {
     772             :       AstGraphBuilderWithPositions graph_builder(
     773             :           temp_zone, data->info(), data->jsgraph(), 1.0f,
     774        2507 :           data->loop_assignment(), data->source_positions());
     775        2507 :       succeeded = graph_builder.CreateGraph();
     776             :     }
     777             : 
     778      395343 :     if (!succeeded) {
     779             :       data->set_compilation_failed();
     780             :     }
     781      395343 :   }
     782             : };
     783             : 
     784             : 
     785             : struct InliningPhase {
     786             :   static const char* phase_name() { return "inlining"; }
     787             : 
     788     5139455 :   void Run(PipelineData* data, Zone* temp_zone) {
     789      395343 :     JSGraphReducer graph_reducer(data->jsgraph(), temp_zone);
     790             :     DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
     791      395342 :                                               data->common());
     792      395343 :     CheckpointElimination checkpoint_elimination(&graph_reducer);
     793             :     CommonOperatorReducer common_reducer(&graph_reducer, data->graph(),
     794      395342 :                                          data->common(), data->machine());
     795             :     JSCallReducer call_reducer(&graph_reducer, data->jsgraph(),
     796             :                                data->native_context(),
     797      395342 :                                data->info()->dependencies());
     798             :     JSContextSpecialization context_specialization(
     799             :         &graph_reducer, data->jsgraph(),
     800             :         data->info()->is_function_context_specializing()
     801             :             ? handle(data->info()->context())
     802             :             : MaybeHandle<Context>(),
     803             :         data->info()->is_function_context_specializing()
     804             :             ? data->info()->closure()
     805      395343 :             : MaybeHandle<JSFunction>());
     806             :     JSFrameSpecialization frame_specialization(
     807      395343 :         &graph_reducer, data->info()->osr_frame(), data->jsgraph());
     808             :     JSNativeContextSpecialization::Flags flags =
     809             :         JSNativeContextSpecialization::kNoFlags;
     810      395343 :     if (data->info()->is_accessor_inlining_enabled()) {
     811             :       flags |= JSNativeContextSpecialization::kAccessorInliningEnabled;
     812             :     }
     813      395343 :     if (data->info()->is_bailout_on_uninitialized()) {
     814             :       flags |= JSNativeContextSpecialization::kBailoutOnUninitialized;
     815             :     }
     816             :     JSNativeContextSpecialization native_context_specialization(
     817             :         &graph_reducer, data->jsgraph(), flags, data->native_context(),
     818      790686 :         data->info()->dependencies(), temp_zone);
     819             :     JSInliningHeuristic inlining(
     820             :         &graph_reducer, data->info()->is_inlining_enabled()
     821             :                             ? JSInliningHeuristic::kGeneralInlining
     822             :                             : JSInliningHeuristic::kRestrictedInlining,
     823      790685 :         temp_zone, data->info(), data->jsgraph(), data->source_positions());
     824             :     JSIntrinsicLowering intrinsic_lowering(
     825             :         &graph_reducer, data->jsgraph(),
     826             :         data->info()->is_deoptimization_enabled()
     827             :             ? JSIntrinsicLowering::kDeoptimizationEnabled
     828      395342 :             : JSIntrinsicLowering::kDeoptimizationDisabled);
     829      395342 :     AddReducer(data, &graph_reducer, &dead_code_elimination);
     830      395342 :     AddReducer(data, &graph_reducer, &checkpoint_elimination);
     831      395343 :     AddReducer(data, &graph_reducer, &common_reducer);
     832      395343 :     if (data->info()->is_frame_specializing()) {
     833          68 :       AddReducer(data, &graph_reducer, &frame_specialization);
     834             :     }
     835      395343 :     if (data->info()->is_deoptimization_enabled()) {
     836      393274 :       AddReducer(data, &graph_reducer, &native_context_specialization);
     837             :     }
     838      395343 :     AddReducer(data, &graph_reducer, &context_specialization);
     839      395343 :     AddReducer(data, &graph_reducer, &intrinsic_lowering);
     840      395343 :     if (data->info()->is_deoptimization_enabled()) {
     841      393274 :       AddReducer(data, &graph_reducer, &call_reducer);
     842             :     }
     843      395343 :     AddReducer(data, &graph_reducer, &inlining);
     844      395343 :     graph_reducer.ReduceGraph();
     845      395343 :   }
     846             : };
     847             : 
     848             : 
     849             : struct TyperPhase {
     850             :   static const char* phase_name() { return "typer"; }
     851             : 
     852     1186029 :   void Run(PipelineData* data, Zone* temp_zone, Typer* typer) {
     853             :     NodeVector roots(temp_zone);
     854      395343 :     data->jsgraph()->GetCachedNodes(&roots);
     855             :     LoopVariableOptimizer induction_vars(data->jsgraph()->graph(),
     856      395343 :                                          data->common(), temp_zone);
     857      395343 :     if (FLAG_turbo_loop_variable) induction_vars.Run();
     858      395343 :     typer->Run(roots, &induction_vars);
     859      395343 :   }
     860             : };
     861             : 
     862             : struct UntyperPhase {
     863             :   static const char* phase_name() { return "untyper"; }
     864             : 
     865             :   void Run(PipelineData* data, Zone* temp_zone) {
     866           0 :     class RemoveTypeReducer final : public Reducer {
     867             :      public:
     868           0 :       Reduction Reduce(Node* node) final {
     869           0 :         if (NodeProperties::IsTyped(node)) {
     870             :           NodeProperties::RemoveType(node);
     871             :           return Changed(node);
     872             :         }
     873             :         return NoChange();
     874             :       }
     875             :     };
     876             : 
     877             :     NodeVector roots(temp_zone);
     878             :     data->jsgraph()->GetCachedNodes(&roots);
     879             :     for (Node* node : roots) {
     880             :       NodeProperties::RemoveType(node);
     881             :     }
     882             : 
     883             :     JSGraphReducer graph_reducer(data->jsgraph(), temp_zone);
     884             :     RemoveTypeReducer remove_type_reducer;
     885             :     AddReducer(data, &graph_reducer, &remove_type_reducer);
     886             :     graph_reducer.ReduceGraph();
     887             :   }
     888             : };
     889             : 
     890             : struct OsrDeconstructionPhase {
     891             :   static const char* phase_name() { return "OSR deconstruction"; }
     892             : 
     893       23252 :   void Run(PipelineData* data, Zone* temp_zone) {
     894        5813 :     GraphTrimmer trimmer(temp_zone, data->graph());
     895             :     NodeVector roots(temp_zone);
     896        5813 :     data->jsgraph()->GetCachedNodes(&roots);
     897        5813 :     trimmer.TrimGraph(roots.begin(), roots.end());
     898             : 
     899        5813 :     OsrHelper osr_helper(data->info());
     900        5813 :     osr_helper.Deconstruct(data->jsgraph(), data->common(), temp_zone);
     901        5813 :   }
     902             : };
     903             : 
     904             : 
     905             : struct TypedLoweringPhase {
     906             :   static const char* phase_name() { return "typed lowering"; }
     907             : 
     908     3953430 :   void Run(PipelineData* data, Zone* temp_zone) {
     909      395343 :     JSGraphReducer graph_reducer(data->jsgraph(), temp_zone);
     910             :     DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
     911      395343 :                                               data->common());
     912             :     JSBuiltinReducer builtin_reducer(
     913             :         &graph_reducer, data->jsgraph(),
     914             :         data->info()->is_deoptimization_enabled()
     915             :             ? JSBuiltinReducer::kDeoptimizationEnabled
     916             :             : JSBuiltinReducer::kNoFlags,
     917     1581372 :         data->info()->dependencies(), data->native_context());
     918             :     Handle<FeedbackVector> feedback_vector(
     919             :         data->info()->closure()->feedback_vector());
     920             :     JSCreateLowering create_lowering(
     921             :         &graph_reducer, data->info()->dependencies(), data->jsgraph(),
     922      790686 :         feedback_vector, data->native_context(), temp_zone);
     923             :     JSTypedLowering::Flags typed_lowering_flags = JSTypedLowering::kNoFlags;
     924      395343 :     if (data->info()->is_deoptimization_enabled()) {
     925             :       typed_lowering_flags |= JSTypedLowering::kDeoptimizationEnabled;
     926             :     }
     927             :     JSTypedLowering typed_lowering(&graph_reducer, data->info()->dependencies(),
     928             :                                    typed_lowering_flags, data->jsgraph(),
     929      395343 :                                    temp_zone);
     930             :     TypedOptimization typed_optimization(
     931             :         &graph_reducer, data->info()->dependencies(),
     932             :         data->info()->is_deoptimization_enabled()
     933             :             ? TypedOptimization::kDeoptimizationEnabled
     934             :             : TypedOptimization::kNoFlags,
     935     1186029 :         data->jsgraph());
     936      790686 :     SimplifiedOperatorReducer simple_reducer(&graph_reducer, data->jsgraph());
     937      395343 :     CheckpointElimination checkpoint_elimination(&graph_reducer);
     938             :     CommonOperatorReducer common_reducer(&graph_reducer, data->graph(),
     939      395343 :                                          data->common(), data->machine());
     940      395343 :     AddReducer(data, &graph_reducer, &dead_code_elimination);
     941      395343 :     AddReducer(data, &graph_reducer, &builtin_reducer);
     942      395343 :     if (data->info()->is_deoptimization_enabled()) {
     943      393274 :       AddReducer(data, &graph_reducer, &create_lowering);
     944             :     }
     945      395343 :     AddReducer(data, &graph_reducer, &typed_optimization);
     946      395343 :     AddReducer(data, &graph_reducer, &typed_lowering);
     947      395343 :     AddReducer(data, &graph_reducer, &simple_reducer);
     948      395343 :     AddReducer(data, &graph_reducer, &checkpoint_elimination);
     949      395343 :     AddReducer(data, &graph_reducer, &common_reducer);
     950      395343 :     graph_reducer.ReduceGraph();
     951      395343 :   }
     952             : };
     953             : 
     954             : 
     955             : struct EscapeAnalysisPhase {
     956             :   static const char* phase_name() { return "escape analysis"; }
     957             : 
     958      865906 :   void Run(PipelineData* data, Zone* temp_zone) {
     959             :     EscapeAnalysis escape_analysis(data->graph(), data->jsgraph()->common(),
     960      786386 :                                    temp_zone);
     961      746626 :     if (!escape_analysis.Run()) return;
     962       39760 :     JSGraphReducer graph_reducer(data->jsgraph(), temp_zone);
     963             :     EscapeAnalysisReducer escape_reducer(&graph_reducer, data->jsgraph(),
     964       39760 :                                          &escape_analysis, temp_zone);
     965       39760 :     AddReducer(data, &graph_reducer, &escape_reducer);
     966       39760 :     graph_reducer.ReduceGraph();
     967       39760 :     if (escape_reducer.compilation_failed()) {
     968             :       data->set_compilation_failed();
     969             :       return;
     970             :     }
     971       79520 :     escape_reducer.VerifyReplacement();
     972             :   }
     973             : };
     974             : 
     975             : struct SimplifiedLoweringPhase {
     976             :   static const char* phase_name() { return "simplified lowering"; }
     977             : 
     978      395303 :   void Run(PipelineData* data, Zone* temp_zone) {
     979             :     SimplifiedLowering lowering(data->jsgraph(), temp_zone,
     980      395303 :                                 data->source_positions());
     981      395303 :     lowering.LowerAllNodes();
     982      395302 :   }
     983             : };
     984             : 
     985             : struct LoopPeelingPhase {
     986             :   static const char* phase_name() { return "loop peeling"; }
     987             : 
     988     1553228 :   void Run(PipelineData* data, Zone* temp_zone) {
     989      388307 :     GraphTrimmer trimmer(temp_zone, data->graph());
     990             :     NodeVector roots(temp_zone);
     991      388307 :     data->jsgraph()->GetCachedNodes(&roots);
     992      388307 :     trimmer.TrimGraph(roots.begin(), roots.end());
     993             : 
     994             :     LoopTree* loop_tree =
     995      388307 :         LoopFinder::BuildLoopTree(data->jsgraph()->graph(), temp_zone);
     996             :     LoopPeeler::PeelInnerLoopsOfTree(data->graph(), data->common(), loop_tree,
     997      388307 :                                      temp_zone);
     998      388307 :   }
     999             : };
    1000             : 
    1001             : struct LoopExitEliminationPhase {
    1002             :   static const char* phase_name() { return "loop exit elimination"; }
    1003             : 
    1004        6996 :   void Run(PipelineData* data, Zone* temp_zone) {
    1005        6996 :     LoopPeeler::EliminateLoopExits(data->graph(), temp_zone);
    1006             :   }
    1007             : };
    1008             : 
    1009             : struct ConcurrentOptimizationPrepPhase {
    1010             :   static const char* phase_name() { return "concurrency preparation"; }
    1011             : 
    1012     1976715 :   void Run(PipelineData* data, Zone* temp_zone) {
    1013             :     // Make sure we cache these code stubs.
    1014      395343 :     data->jsgraph()->CEntryStubConstant(1);
    1015      395343 :     data->jsgraph()->CEntryStubConstant(2);
    1016      395343 :     data->jsgraph()->CEntryStubConstant(3);
    1017             : 
    1018             :     // This is needed for escape analysis.
    1019      395343 :     NodeProperties::SetType(data->jsgraph()->FalseConstant(), Type::Boolean());
    1020      395343 :     NodeProperties::SetType(data->jsgraph()->TrueConstant(), Type::Boolean());
    1021      395343 :   }
    1022             : };
    1023             : 
    1024             : struct GenericLoweringPhase {
    1025             :   static const char* phase_name() { return "generic lowering"; }
    1026             : 
    1027      790605 :   void Run(PipelineData* data, Zone* temp_zone) {
    1028      395302 :     JSGraphReducer graph_reducer(data->jsgraph(), temp_zone);
    1029      790604 :     JSGenericLowering generic_lowering(data->jsgraph());
    1030      395302 :     AddReducer(data, &graph_reducer, &generic_lowering);
    1031      395303 :     graph_reducer.ReduceGraph();
    1032      395302 :   }
    1033             : };
    1034             : 
    1035             : struct EarlyOptimizationPhase {
    1036             :   static const char* phase_name() { return "early optimization"; }
    1037             : 
    1038     2371817 :   void Run(PipelineData* data, Zone* temp_zone) {
    1039      395302 :     JSGraphReducer graph_reducer(data->jsgraph(), temp_zone);
    1040             :     DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
    1041      395303 :                                               data->common());
    1042      790603 :     SimplifiedOperatorReducer simple_reducer(&graph_reducer, data->jsgraph());
    1043      790602 :     RedundancyElimination redundancy_elimination(&graph_reducer, temp_zone);
    1044      790603 :     ValueNumberingReducer value_numbering(temp_zone, data->graph()->zone());
    1045      790604 :     MachineOperatorReducer machine_reducer(data->jsgraph());
    1046             :     CommonOperatorReducer common_reducer(&graph_reducer, data->graph(),
    1047      395303 :                                          data->common(), data->machine());
    1048      395302 :     AddReducer(data, &graph_reducer, &dead_code_elimination);
    1049      395303 :     AddReducer(data, &graph_reducer, &simple_reducer);
    1050      395303 :     AddReducer(data, &graph_reducer, &redundancy_elimination);
    1051      395303 :     AddReducer(data, &graph_reducer, &machine_reducer);
    1052      395303 :     AddReducer(data, &graph_reducer, &common_reducer);
    1053      395303 :     AddReducer(data, &graph_reducer, &value_numbering);
    1054      395303 :     graph_reducer.ReduceGraph();
    1055      395302 :   }
    1056             : };
    1057             : 
    1058             : struct ControlFlowOptimizationPhase {
    1059             :   static const char* phase_name() { return "control flow optimization"; }
    1060             : 
    1061      395303 :   void Run(PipelineData* data, Zone* temp_zone) {
    1062             :     ControlFlowOptimizer optimizer(data->graph(), data->common(),
    1063      395303 :                                    data->machine(), temp_zone);
    1064      395302 :     optimizer.Optimize();
    1065      395302 :   }
    1066             : };
    1067             : 
    1068             : struct EffectControlLinearizationPhase {
    1069             :   static const char* phase_name() { return "effect linearization"; }
    1070             : 
    1071     1976515 :   void Run(PipelineData* data, Zone* temp_zone) {
    1072             :     // The scheduler requires the graphs to be trimmed, so trim now.
    1073             :     // TODO(jarin) Remove the trimming once the scheduler can handle untrimmed
    1074             :     // graphs.
    1075      395303 :     GraphTrimmer trimmer(temp_zone, data->graph());
    1076             :     NodeVector roots(temp_zone);
    1077      395303 :     data->jsgraph()->GetCachedNodes(&roots);
    1078      395303 :     trimmer.TrimGraph(roots.begin(), roots.end());
    1079             : 
    1080             :     // Schedule the graph without node splitting so that we can
    1081             :     // fix the effect and control flow for nodes with low-level side
    1082             :     // effects (such as changing representation to tagged or
    1083             :     // 'floating' allocation regions.)
    1084             :     Schedule* schedule = Scheduler::ComputeSchedule(temp_zone, data->graph(),
    1085      395303 :                                                     Scheduler::kTempSchedule);
    1086      395303 :     if (FLAG_turbo_verify) ScheduleVerifier::Run(schedule);
    1087      395303 :     TraceSchedule(data->info(), schedule);
    1088             : 
    1089             :     // Post-pass for wiring the control/effects
    1090             :     // - connect allocating representation changes into the control&effect
    1091             :     //   chains and lower them,
    1092             :     // - get rid of the region markers,
    1093             :     // - introduce effect phis and rewire effects to get SSA again.
    1094             :     EffectControlLinearizer linearizer(data->jsgraph(), schedule, temp_zone,
    1095      395303 :                                        data->source_positions());
    1096      395301 :     linearizer.Run();
    1097      395296 :   }
    1098             : };
    1099             : 
    1100             : // The store-store elimination greatly benefits from doing a common operator
    1101             : // reducer and dead code elimination just before it, to eliminate conditional
    1102             : // deopts with a constant condition.
    1103             : 
    1104             : struct DeadCodeEliminationPhase {
    1105             :   static const char* phase_name() { return "dead code elimination"; }
    1106             : 
    1107     1185905 :   void Run(PipelineData* data, Zone* temp_zone) {
    1108      395301 :     JSGraphReducer graph_reducer(data->jsgraph(), temp_zone);
    1109             :     DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
    1110      395302 :                                               data->common());
    1111             :     CommonOperatorReducer common_reducer(&graph_reducer, data->graph(),
    1112      395302 :                                          data->common(), data->machine());
    1113      395301 :     AddReducer(data, &graph_reducer, &dead_code_elimination);
    1114      395301 :     AddReducer(data, &graph_reducer, &common_reducer);
    1115      395301 :     graph_reducer.ReduceGraph();
    1116      395303 :   }
    1117             : };
    1118             : 
    1119             : struct StoreStoreEliminationPhase {
    1120             :   static const char* phase_name() { return "store-store elimination"; }
    1121             : 
    1122     1185909 :   void Run(PipelineData* data, Zone* temp_zone) {
    1123      395303 :     GraphTrimmer trimmer(temp_zone, data->graph());
    1124             :     NodeVector roots(temp_zone);
    1125      395303 :     data->jsgraph()->GetCachedNodes(&roots);
    1126      395303 :     trimmer.TrimGraph(roots.begin(), roots.end());
    1127             : 
    1128      395303 :     StoreStoreElimination::Run(data->jsgraph(), temp_zone);
    1129      395300 :   }
    1130             : };
    1131             : 
    1132             : struct LoadEliminationPhase {
    1133             :   static const char* phase_name() { return "load elimination"; }
    1134             : 
    1135     2359050 :   void Run(PipelineData* data, Zone* temp_zone) {
    1136      393175 :     JSGraphReducer graph_reducer(data->jsgraph(), temp_zone);
    1137             :     BranchElimination branch_condition_elimination(&graph_reducer,
    1138      786350 :                                                    data->jsgraph(), temp_zone);
    1139             :     DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
    1140      393175 :                                               data->common());
    1141      786350 :     RedundancyElimination redundancy_elimination(&graph_reducer, temp_zone);
    1142             :     LoadElimination load_elimination(&graph_reducer, data->jsgraph(),
    1143             :                                      temp_zone);
    1144      393175 :     CheckpointElimination checkpoint_elimination(&graph_reducer);
    1145      786350 :     ValueNumberingReducer value_numbering(temp_zone, data->graph()->zone());
    1146             :     CommonOperatorReducer common_reducer(&graph_reducer, data->graph(),
    1147      393175 :                                          data->common(), data->machine());
    1148      393175 :     AddReducer(data, &graph_reducer, &branch_condition_elimination);
    1149      393175 :     AddReducer(data, &graph_reducer, &dead_code_elimination);
    1150      393175 :     AddReducer(data, &graph_reducer, &redundancy_elimination);
    1151      393175 :     AddReducer(data, &graph_reducer, &load_elimination);
    1152      393175 :     AddReducer(data, &graph_reducer, &checkpoint_elimination);
    1153      393175 :     AddReducer(data, &graph_reducer, &common_reducer);
    1154      393175 :     AddReducer(data, &graph_reducer, &value_numbering);
    1155      393175 :     graph_reducer.ReduceGraph();
    1156      393175 :   }
    1157             : };
    1158             : 
    1159             : struct MemoryOptimizationPhase {
    1160             :   static const char* phase_name() { return "memory optimization"; }
    1161             : 
    1162     1185909 :   void Run(PipelineData* data, Zone* temp_zone) {
    1163             :     // The memory optimizer requires the graphs to be trimmed, so trim now.
    1164      395303 :     GraphTrimmer trimmer(temp_zone, data->graph());
    1165             :     NodeVector roots(temp_zone);
    1166      395303 :     data->jsgraph()->GetCachedNodes(&roots);
    1167      395303 :     trimmer.TrimGraph(roots.begin(), roots.end());
    1168             : 
    1169             :     // Optimize allocations and load/store operations.
    1170      395303 :     MemoryOptimizer optimizer(data->jsgraph(), temp_zone);
    1171      790603 :     optimizer.Optimize();
    1172      395300 :   }
    1173             : };
    1174             : 
    1175             : struct LateOptimizationPhase {
    1176             :   static const char* phase_name() { return "late optimization"; }
    1177             : 
    1178     3162419 :   void Run(PipelineData* data, Zone* temp_zone) {
    1179      395303 :     JSGraphReducer graph_reducer(data->jsgraph(), temp_zone);
    1180             :     BranchElimination branch_condition_elimination(&graph_reducer,
    1181      790601 :                                                    data->jsgraph(), temp_zone);
    1182             :     DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
    1183      395303 :                                               data->common());
    1184      790601 :     ValueNumberingReducer value_numbering(temp_zone, data->graph()->zone());
    1185      790597 :     MachineOperatorReducer machine_reducer(data->jsgraph());
    1186             :     CommonOperatorReducer common_reducer(&graph_reducer, data->graph(),
    1187      395302 :                                          data->common(), data->machine());
    1188             :     SelectLowering select_lowering(data->jsgraph()->graph(),
    1189      790604 :                                    data->jsgraph()->common());
    1190             :     TailCallOptimization tco(data->common(), data->graph());
    1191      395302 :     AddReducer(data, &graph_reducer, &branch_condition_elimination);
    1192      395302 :     AddReducer(data, &graph_reducer, &dead_code_elimination);
    1193      395303 :     AddReducer(data, &graph_reducer, &machine_reducer);
    1194      395303 :     AddReducer(data, &graph_reducer, &common_reducer);
    1195      395303 :     AddReducer(data, &graph_reducer, &select_lowering);
    1196      395303 :     AddReducer(data, &graph_reducer, &tco);
    1197      395303 :     AddReducer(data, &graph_reducer, &value_numbering);
    1198      395303 :     graph_reducer.ReduceGraph();
    1199      395301 :   }
    1200             : };
    1201             : 
    1202             : struct EarlyGraphTrimmingPhase {
    1203             :   static const char* phase_name() { return "early graph trimming"; }
    1204      790686 :   void Run(PipelineData* data, Zone* temp_zone) {
    1205      395343 :     GraphTrimmer trimmer(temp_zone, data->graph());
    1206             :     NodeVector roots(temp_zone);
    1207      395343 :     data->jsgraph()->GetCachedNodes(&roots);
    1208      395343 :     trimmer.TrimGraph(roots.begin(), roots.end());
    1209      395343 :   }
    1210             : };
    1211             : 
    1212             : 
    1213             : struct LateGraphTrimmingPhase {
    1214             :   static const char* phase_name() { return "late graph trimming"; }
    1215      931748 :   void Run(PipelineData* data, Zone* temp_zone) {
    1216      465861 :     GraphTrimmer trimmer(temp_zone, data->graph());
    1217             :     NodeVector roots(temp_zone);
    1218      465887 :     if (data->jsgraph()) {
    1219      465888 :       data->jsgraph()->GetCachedNodes(&roots);
    1220             :     }
    1221      465880 :     trimmer.TrimGraph(roots.begin(), roots.end());
    1222      465869 :   }
    1223             : };
    1224             : 
    1225             : 
    1226             : struct ComputeSchedulePhase {
    1227             :   static const char* phase_name() { return "scheduling"; }
    1228             : 
    1229     1136518 :   void Run(PipelineData* data, Zone* temp_zone) {
    1230             :     Schedule* schedule = Scheduler::ComputeSchedule(
    1231             :         temp_zone, data->graph(), data->info()->is_splitting_enabled()
    1232             :                                       ? Scheduler::kSplitNodes
    1233     1136518 :                                       : Scheduler::kNoFlags);
    1234      568260 :     if (FLAG_turbo_verify) ScheduleVerifier::Run(schedule);
    1235             :     data->set_schedule(schedule);
    1236      568260 :   }
    1237             : };
    1238             : 
    1239             : 
    1240             : struct InstructionSelectionPhase {
    1241             :   static const char* phase_name() { return "select instructions"; }
    1242             : 
    1243     2747526 :   void Run(PipelineData* data, Zone* temp_zone, Linkage* linkage) {
    1244             :     InstructionSelector selector(
    1245             :         temp_zone, data->graph()->NodeCount(), linkage, data->sequence(),
    1246             :         data->schedule(), data->source_positions(), data->frame(),
    1247             :         data->info()->is_source_positions_enabled()
    1248             :             ? InstructionSelector::kAllSourcePositions
    1249             :             : InstructionSelector::kCallSourcePositions,
    1250             :         InstructionSelector::SupportedFeatures(),
    1251             :         FLAG_turbo_instruction_scheduling
    1252             :             ? InstructionSelector::kEnableScheduling
    1253             :             : InstructionSelector::kDisableScheduling,
    1254             :         data->info()->will_serialize()
    1255             :             ? InstructionSelector::kEnableSerialization
    1256     3663374 :             : InstructionSelector::kDisableSerialization);
    1257      915877 :     if (!selector.SelectInstructions()) {
    1258             :       data->set_compilation_failed();
    1259             :     }
    1260      915847 :   }
    1261             : };
    1262             : 
    1263             : 
    1264             : struct MeetRegisterConstraintsPhase {
    1265             :   static const char* phase_name() { return "meet register constraints"; }
    1266             : 
    1267      915913 :   void Run(PipelineData* data, Zone* temp_zone) {
    1268      915913 :     ConstraintBuilder builder(data->register_allocation_data());
    1269      915909 :     builder.MeetRegisterConstraints();
    1270      915922 :   }
    1271             : };
    1272             : 
    1273             : 
    1274             : struct ResolvePhisPhase {
    1275             :   static const char* phase_name() { return "resolve phis"; }
    1276             : 
    1277      915921 :   void Run(PipelineData* data, Zone* temp_zone) {
    1278      915921 :     ConstraintBuilder builder(data->register_allocation_data());
    1279      915920 :     builder.ResolvePhis();
    1280      915907 :   }
    1281             : };
    1282             : 
    1283             : 
    1284             : struct BuildLiveRangesPhase {
    1285             :   static const char* phase_name() { return "build live ranges"; }
    1286             : 
    1287      915890 :   void Run(PipelineData* data, Zone* temp_zone) {
    1288      915890 :     LiveRangeBuilder builder(data->register_allocation_data(), temp_zone);
    1289      915896 :     builder.BuildLiveRanges();
    1290      915919 :   }
    1291             : };
    1292             : 
    1293             : 
    1294             : struct SplinterLiveRangesPhase {
    1295             :   static const char* phase_name() { return "splinter live ranges"; }
    1296             : 
    1297      915920 :   void Run(PipelineData* data, Zone* temp_zone) {
    1298             :     LiveRangeSeparator live_range_splinterer(data->register_allocation_data(),
    1299             :                                              temp_zone);
    1300      915920 :     live_range_splinterer.Splinter();
    1301             :   }
    1302             : };
    1303             : 
    1304             : 
    1305             : template <typename RegAllocator>
    1306             : struct AllocateGeneralRegistersPhase {
    1307             :   static const char* phase_name() { return "allocate general registers"; }
    1308             : 
    1309      915911 :   void Run(PipelineData* data, Zone* temp_zone) {
    1310             :     RegAllocator allocator(data->register_allocation_data(), GENERAL_REGISTERS,
    1311      915911 :                            temp_zone);
    1312      915922 :     allocator.AllocateRegisters();
    1313      915890 :   }
    1314             : };
    1315             : 
    1316             : template <typename RegAllocator>
    1317             : struct AllocateFPRegistersPhase {
    1318             :   static const char* phase_name() { return "allocate f.p. registers"; }
    1319             : 
    1320      915923 :   void Run(PipelineData* data, Zone* temp_zone) {
    1321             :     RegAllocator allocator(data->register_allocation_data(), FP_REGISTERS,
    1322      915923 :                            temp_zone);
    1323      915928 :     allocator.AllocateRegisters();
    1324      915926 :   }
    1325             : };
    1326             : 
    1327             : 
    1328             : struct MergeSplintersPhase {
    1329             :   static const char* phase_name() { return "merge splintered ranges"; }
    1330      915926 :   void Run(PipelineData* pipeline_data, Zone* temp_zone) {
    1331             :     RegisterAllocationData* data = pipeline_data->register_allocation_data();
    1332             :     LiveRangeMerger live_range_merger(data, temp_zone);
    1333      915926 :     live_range_merger.Merge();
    1334             :   }
    1335             : };
    1336             : 
    1337             : 
    1338             : struct LocateSpillSlotsPhase {
    1339             :   static const char* phase_name() { return "locate spill slots"; }
    1340             : 
    1341      915927 :   void Run(PipelineData* data, Zone* temp_zone) {
    1342      915927 :     SpillSlotLocator locator(data->register_allocation_data());
    1343      915924 :     locator.LocateSpillSlots();
    1344      915927 :   }
    1345             : };
    1346             : 
    1347             : 
    1348             : struct AssignSpillSlotsPhase {
    1349             :   static const char* phase_name() { return "assign spill slots"; }
    1350             : 
    1351      915924 :   void Run(PipelineData* data, Zone* temp_zone) {
    1352      915924 :     OperandAssigner assigner(data->register_allocation_data());
    1353      915918 :     assigner.AssignSpillSlots();
    1354      915883 :   }
    1355             : };
    1356             : 
    1357             : 
    1358             : struct CommitAssignmentPhase {
    1359             :   static const char* phase_name() { return "commit assignment"; }
    1360             : 
    1361      915923 :   void Run(PipelineData* data, Zone* temp_zone) {
    1362      915923 :     OperandAssigner assigner(data->register_allocation_data());
    1363      915923 :     assigner.CommitAssignment();
    1364      915919 :   }
    1365             : };
    1366             : 
    1367             : 
    1368             : struct PopulateReferenceMapsPhase {
    1369             :   static const char* phase_name() { return "populate pointer maps"; }
    1370             : 
    1371      915922 :   void Run(PipelineData* data, Zone* temp_zone) {
    1372      915922 :     ReferenceMapPopulator populator(data->register_allocation_data());
    1373      915922 :     populator.PopulateReferenceMaps();
    1374      915890 :   }
    1375             : };
    1376             : 
    1377             : 
    1378             : struct ConnectRangesPhase {
    1379             :   static const char* phase_name() { return "connect ranges"; }
    1380             : 
    1381      915919 :   void Run(PipelineData* data, Zone* temp_zone) {
    1382      915919 :     LiveRangeConnector connector(data->register_allocation_data());
    1383      915913 :     connector.ConnectRanges(temp_zone);
    1384      915899 :   }
    1385             : };
    1386             : 
    1387             : 
    1388             : struct ResolveControlFlowPhase {
    1389             :   static const char* phase_name() { return "resolve control flow"; }
    1390             : 
    1391      915923 :   void Run(PipelineData* data, Zone* temp_zone) {
    1392      915923 :     LiveRangeConnector connector(data->register_allocation_data());
    1393      915923 :     connector.ResolveControlFlow(temp_zone);
    1394      915901 :   }
    1395             : };
    1396             : 
    1397             : 
    1398             : struct OptimizeMovesPhase {
    1399             :   static const char* phase_name() { return "optimize moves"; }
    1400             : 
    1401      915928 :   void Run(PipelineData* data, Zone* temp_zone) {
    1402      915928 :     MoveOptimizer move_optimizer(temp_zone, data->sequence());
    1403      915914 :     move_optimizer.Run();
    1404      915899 :   }
    1405             : };
    1406             : 
    1407             : 
    1408             : struct FrameElisionPhase {
    1409             :   static const char* phase_name() { return "frame elision"; }
    1410             : 
    1411      915884 :   void Run(PipelineData* data, Zone* temp_zone) {
    1412      915884 :     FrameElider(data->sequence()).Run();
    1413      915838 :   }
    1414             : };
    1415             : 
    1416             : 
    1417             : struct JumpThreadingPhase {
    1418             :   static const char* phase_name() { return "jump threading"; }
    1419             : 
    1420     2389016 :   void Run(PipelineData* data, Zone* temp_zone, bool frame_at_start) {
    1421             :     ZoneVector<RpoNumber> result(temp_zone);
    1422      915866 :     if (JumpThreading::ComputeForwarding(temp_zone, result, data->sequence(),
    1423      915866 :                                          frame_at_start)) {
    1424      557284 :       JumpThreading::ApplyForwarding(result, data->sequence());
    1425             :     }
    1426      915882 :   }
    1427             : };
    1428             : 
    1429             : 
    1430             : struct GenerateCodePhase {
    1431             :   static const char* phase_name() { return "generate code"; }
    1432             : 
    1433      912392 :   void Run(PipelineData* data, Zone* temp_zone, Linkage* linkage) {
    1434             :     CodeGenerator generator(data->frame(), linkage, data->sequence(),
    1435      912392 :                             data->info());
    1436     1824784 :     data->set_code(generator.GenerateCode());
    1437      912392 :   }
    1438             : };
    1439             : 
    1440             : 
    1441             : struct PrintGraphPhase {
    1442             :   static const char* phase_name() { return nullptr; }
    1443             : 
    1444           0 :   void Run(PipelineData* data, Zone* temp_zone, const char* phase) {
    1445           0 :     CompilationInfo* info = data->info();
    1446             :     Graph* graph = data->graph();
    1447             : 
    1448             :     {  // Print JSON.
    1449             :       AllowHandleDereference allow_deref;
    1450           0 :       TurboJsonFile json_of(info, std::ios_base::app);
    1451           0 :       json_of << "{\"name\":\"" << phase << "\",\"type\":\"graph\",\"data\":"
    1452           0 :               << AsJSON(*graph, data->source_positions()) << "},\n";
    1453             :     }
    1454             : 
    1455           0 :     if (FLAG_trace_turbo_graph) {  // Simple textual RPO.
    1456             :       AllowHandleDereference allow_deref;
    1457           0 :       CodeTracer::Scope tracing_scope(info->isolate()->GetCodeTracer());
    1458           0 :       OFStream os(tracing_scope.file());
    1459           0 :       os << "-- Graph after " << phase << " -- " << std::endl;
    1460           0 :       os << AsRPO(*graph);
    1461             :     }
    1462           0 :   }
    1463             : };
    1464             : 
    1465             : 
    1466             : struct VerifyGraphPhase {
    1467             :   static const char* phase_name() { return nullptr; }
    1468             : 
    1469      111827 :   void Run(PipelineData* data, Zone* temp_zone, const bool untyped,
    1470             :            bool values_only = false) {
    1471             :     Verifier::Run(data->graph(), !untyped ? Verifier::TYPED : Verifier::UNTYPED,
    1472      223654 :                   values_only ? Verifier::kValuesOnly : Verifier::kAll);
    1473             :   }
    1474             : };
    1475             : 
    1476     7666982 : void PipelineImpl::RunPrintAndVerify(const char* phase, bool untyped) {
    1477     7666982 :   if (FLAG_trace_turbo) {
    1478           0 :     Run<PrintGraphPhase>(phase);
    1479             :   }
    1480     7667033 :   if (FLAG_turbo_verify) {
    1481           0 :     Run<VerifyGraphPhase>(untyped);
    1482             :   }
    1483     7667033 : }
    1484             : 
    1485      395343 : bool PipelineImpl::CreateGraph() {
    1486     1581372 :   PipelineData* data = this->data_;
    1487             : 
    1488             :   data->BeginPhaseKind("graph creation");
    1489             : 
    1490      395343 :   if (FLAG_trace_turbo) {
    1491           0 :     CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer());
    1492           0 :     OFStream os(tracing_scope.file());
    1493           0 :     os << "---------------------------------------------------\n"
    1494           0 :        << "Begin compiling method " << info()->GetDebugName().get()
    1495           0 :        << " using Turbofan" << std::endl;
    1496           0 :     TurboCfgFile tcf(isolate());
    1497           0 :     tcf << AsC1VCompilation(info());
    1498             :   }
    1499             : 
    1500      395343 :   data->source_positions()->AddDecorator();
    1501             : 
    1502      395343 :   if (FLAG_loop_assignment_analysis) {
    1503      392123 :     Run<LoopAssignmentAnalysisPhase>();
    1504             :   }
    1505             : 
    1506      395343 :   Run<GraphBuilderPhase>();
    1507      395343 :   if (data->compilation_failed()) {
    1508             :     data->EndPhaseKind();
    1509             :     return false;
    1510             :   }
    1511      395343 :   RunPrintAndVerify("Initial untyped", true);
    1512             : 
    1513             :   // Perform OSR deconstruction.
    1514      395343 :   if (info()->is_osr()) {
    1515        5813 :     Run<OsrDeconstructionPhase>();
    1516        5813 :     RunPrintAndVerify("OSR deconstruction", true);
    1517             :   }
    1518             : 
    1519             :   // Perform function context specialization and inlining (if enabled).
    1520      395343 :   Run<InliningPhase>();
    1521      395343 :   RunPrintAndVerify("Inlined", true);
    1522             : 
    1523             :   // Remove dead->live edges from the graph.
    1524      395343 :   Run<EarlyGraphTrimmingPhase>();
    1525      395343 :   RunPrintAndVerify("Early trimmed", true);
    1526             : 
    1527             :   // Run the type-sensitive lowerings and optimizations on the graph.
    1528             :   {
    1529             :     // Determine the Typer operation flags.
    1530             :     Typer::Flags flags = Typer::kNoFlags;
    1531     1495924 :     if (is_sloppy(info()->shared_info()->language_mode()) &&
    1532     1015133 :         info()->shared_info()->IsUserJavaScript()) {
    1533             :       // Sloppy mode functions always have an Object for this.
    1534             :       flags |= Typer::kThisIsReceiver;
    1535             :     }
    1536      790686 :     if (IsClassConstructor(info()->shared_info()->kind())) {
    1537             :       // Class constructors cannot be [[Call]]ed.
    1538             :       flags |= Typer::kNewTargetIsReceiver;
    1539             :     }
    1540             : 
    1541             :     // Type the graph and keep the Typer running on newly created nodes within
    1542             :     // this scope; the Typer is automatically unlinked from the Graph once we
    1543             :     // leave this scope below.
    1544      395343 :     Typer typer(isolate(), flags, data->graph());
    1545      395343 :     Run<TyperPhase>(&typer);
    1546      395343 :     RunPrintAndVerify("Typed");
    1547             : 
    1548             :     // Lower JSOperators where we can determine types.
    1549      395343 :     Run<TypedLoweringPhase>();
    1550      395343 :     RunPrintAndVerify("Lowered typed");
    1551             :   }
    1552             : 
    1553             :   // Do some hacky things to prepare for the optimization phase.
    1554             :   // (caching handles, etc.).
    1555      395343 :   Run<ConcurrentOptimizationPrepPhase>();
    1556             : 
    1557             :   data->EndPhaseKind();
    1558             : 
    1559             :   return true;
    1560             : }
    1561             : 
    1562      395303 : bool PipelineImpl::OptimizeGraph(Linkage* linkage) {
    1563     1974405 :   PipelineData* data = this->data_;
    1564             : 
    1565             :   data->BeginPhaseKind("lowering");
    1566             : 
    1567      395303 :   if (data->info()->is_loop_peeling_enabled()) {
    1568      388307 :     Run<LoopPeelingPhase>();
    1569      388307 :     RunPrintAndVerify("Loops peeled", true);
    1570             :   } else {
    1571        6996 :     Run<LoopExitEliminationPhase>();
    1572        6996 :     RunPrintAndVerify("Loop exits eliminated", true);
    1573             :   }
    1574             : 
    1575      395303 :   if (!data->is_asm()) {
    1576      393193 :     if (FLAG_turbo_load_elimination) {
    1577      393175 :       Run<LoadEliminationPhase>();
    1578      393175 :       RunPrintAndVerify("Load eliminated");
    1579             :     }
    1580             : 
    1581      393193 :     if (FLAG_turbo_escape) {
    1582      393193 :       Run<EscapeAnalysisPhase>();
    1583      393193 :       if (data->compilation_failed()) {
    1584             :         info()->AbortOptimization(kCyclicObjectStateDetectedInEscapeAnalysis);
    1585             :         data->EndPhaseKind();
    1586             :         return false;
    1587             :       }
    1588      393193 :       RunPrintAndVerify("Escape Analysed");
    1589             :     }
    1590             :   }
    1591             : 
    1592             :   // Perform simplified lowering. This has to run w/o the Typer decorator,
    1593             :   // because we cannot compute meaningful types anyways, and the computed types
    1594             :   // might even conflict with the representation/truncation logic.
    1595      395303 :   Run<SimplifiedLoweringPhase>();
    1596      395303 :   RunPrintAndVerify("Simplified lowering", true);
    1597             : 
    1598             : #ifdef DEBUG
    1599             :   // From now on it is invalid to look at types on the nodes, because:
    1600             :   //
    1601             :   //  (a) The remaining passes (might) run concurrent to the main thread and
    1602             :   //      therefore must not access the Heap or the Isolate in an uncontrolled
    1603             :   //      way (as done by the type system), and
    1604             :   //  (b) the types on the nodes might not make sense after representation
    1605             :   //      selection due to the way we handle truncations; if we'd want to look
    1606             :   //      at types afterwards we'd essentially need to re-type (large portions
    1607             :   //      of) the graph.
    1608             :   //
    1609             :   // In order to catch bugs related to type access after this point we remove
    1610             :   // the types from the nodes at this point (currently only in Debug builds).
    1611             :   Run<UntyperPhase>();
    1612             :   RunPrintAndVerify("Untyped", true);
    1613             : #endif
    1614             : 
    1615             :   // Run generic lowering pass.
    1616      395303 :   Run<GenericLoweringPhase>();
    1617      395303 :   RunPrintAndVerify("Generic lowering", true);
    1618             : 
    1619             :   data->BeginPhaseKind("block building");
    1620             : 
    1621             :   // Run early optimization pass.
    1622      395303 :   Run<EarlyOptimizationPhase>();
    1623      395303 :   RunPrintAndVerify("Early optimized", true);
    1624             : 
    1625      395303 :   Run<EffectControlLinearizationPhase>();
    1626      395302 :   RunPrintAndVerify("Effect and control linearized", true);
    1627             : 
    1628      395302 :   Run<DeadCodeEliminationPhase>();
    1629      395303 :   RunPrintAndVerify("Dead code elimination", true);
    1630             : 
    1631      395303 :   if (FLAG_turbo_store_elimination) {
    1632      395303 :     Run<StoreStoreEliminationPhase>();
    1633      395303 :     RunPrintAndVerify("Store-store elimination", true);
    1634             :   }
    1635             : 
    1636             :   // Optimize control flow.
    1637      395303 :   if (FLAG_turbo_cf_optimization) {
    1638      395303 :     Run<ControlFlowOptimizationPhase>();
    1639      395303 :     RunPrintAndVerify("Control flow optimized", true);
    1640             :   }
    1641             : 
    1642             :   // Optimize memory access and allocation operations.
    1643      395302 :   Run<MemoryOptimizationPhase>();
    1644             :   // TODO(jarin, rossberg): Remove UNTYPED once machine typing works.
    1645      395303 :   RunPrintAndVerify("Memory optimized", true);
    1646             : 
    1647             :   // Lower changes that have been inserted before.
    1648      395303 :   Run<LateOptimizationPhase>();
    1649             :   // TODO(jarin, rossberg): Remove UNTYPED once machine typing works.
    1650      395303 :   RunPrintAndVerify("Late optimized", true);
    1651             : 
    1652      395303 :   data->source_positions()->RemoveDecorator();
    1653             : 
    1654      395302 :   return ScheduleAndSelectInstructions(linkage, true);
    1655             : }
    1656             : 
    1657      335479 : Handle<Code> Pipeline::GenerateCodeForCodeStub(Isolate* isolate,
    1658             :                                                CallDescriptor* call_descriptor,
    1659      111827 :                                                Graph* graph, Schedule* schedule,
    1660             :                                                Code::Flags flags,
    1661             :                                                const char* debug_name) {
    1662      111827 :   CompilationInfo info(CStrVector(debug_name), isolate, graph->zone(), flags);
    1663      111826 :   if (isolate->serializer_enabled()) info.PrepareForSerializing();
    1664             : 
    1665             :   // Construct a pipeline for scheduling and code generation.
    1666      223653 :   ZoneStats zone_stats(isolate->allocator());
    1667      111827 :   SourcePositionTable source_positions(graph);
    1668      223654 :   PipelineData data(&zone_stats, &info, graph, schedule, &source_positions);
    1669             :   data.set_verify_graph(FLAG_verify_csa);
    1670             :   std::unique_ptr<PipelineStatistics> pipeline_statistics;
    1671      111827 :   if (FLAG_turbo_stats || FLAG_turbo_stats_nvp) {
    1672           0 :     pipeline_statistics.reset(new PipelineStatistics(&info, &zone_stats));
    1673           0 :     pipeline_statistics->BeginPhaseKind("stub codegen");
    1674             :   }
    1675             : 
    1676             :   PipelineImpl pipeline(&data);
    1677             :   DCHECK_NOT_NULL(data.schedule());
    1678             : 
    1679      111826 :   if (FLAG_trace_turbo) {
    1680             :     {
    1681           0 :       CodeTracer::Scope tracing_scope(isolate->GetCodeTracer());
    1682           0 :       OFStream os(tracing_scope.file());
    1683           0 :       os << "---------------------------------------------------\n"
    1684           0 :          << "Begin compiling " << debug_name << " using Turbofan" << std::endl;
    1685             :     }
    1686             :     {
    1687           0 :       TurboJsonFile json_of(&info, std::ios_base::trunc);
    1688           0 :       json_of << "{\"function\":\"" << info.GetDebugName().get()
    1689           0 :               << "\", \"source\":\"\",\n\"phases\":[";
    1690             :     }
    1691           0 :     pipeline.Run<PrintGraphPhase>("Machine");
    1692             :   }
    1693             : 
    1694      111826 :   pipeline.Run<VerifyGraphPhase>(false, true);
    1695      223654 :   return pipeline.ScheduleAndGenerateCode(call_descriptor);
    1696             : }
    1697             : 
    1698             : // static
    1699        4886 : Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info) {
    1700        4886 :   ZoneStats zone_stats(info->isolate()->allocator());
    1701             :   std::unique_ptr<PipelineStatistics> pipeline_statistics(
    1702        4886 :       CreatePipelineStatistics(info, &zone_stats));
    1703        9772 :   PipelineData data(&zone_stats, info, pipeline_statistics.get());
    1704             :   PipelineImpl pipeline(&data);
    1705             : 
    1706        4886 :   Linkage linkage(Linkage::ComputeIncoming(data.instruction_zone(), info));
    1707             : 
    1708        4886 :   if (!pipeline.CreateGraph()) return Handle<Code>::null();
    1709        4886 :   if (!pipeline.OptimizeGraph(&linkage)) return Handle<Code>::null();
    1710        9772 :   return pipeline.GenerateCode(&linkage);
    1711             : }
    1712             : 
    1713             : // static
    1714           7 : Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info,
    1715             :                                               Graph* graph,
    1716             :                                               Schedule* schedule) {
    1717             :   CallDescriptor* call_descriptor =
    1718           7 :       Linkage::ComputeIncoming(info->zone(), info);
    1719           7 :   return GenerateCodeForTesting(info, call_descriptor, graph, schedule);
    1720             : }
    1721             : 
    1722             : // static
    1723      338167 : Handle<Code> Pipeline::GenerateCodeForTesting(
    1724      674065 :     CompilationInfo* info, CallDescriptor* call_descriptor, Graph* graph,
    1725             :     Schedule* schedule, SourcePositionTable* source_positions) {
    1726             :   // Construct a pipeline for scheduling and code generation.
    1727      338167 :   ZoneStats zone_stats(info->isolate()->allocator());
    1728             :   // TODO(wasm): Refactor code generation to check for non-existing source
    1729             :   // table, then remove this conditional allocation.
    1730      338167 :   if (!source_positions)
    1731      335898 :     source_positions = new (info->zone()) SourcePositionTable(graph);
    1732      676334 :   PipelineData data(&zone_stats, info, graph, schedule, source_positions);
    1733             :   std::unique_ptr<PipelineStatistics> pipeline_statistics;
    1734      338167 :   if (FLAG_turbo_stats || FLAG_turbo_stats_nvp) {
    1735           0 :     pipeline_statistics.reset(new PipelineStatistics(info, &zone_stats));
    1736           0 :     pipeline_statistics->BeginPhaseKind("test codegen");
    1737             :   }
    1738             : 
    1739             :   PipelineImpl pipeline(&data);
    1740             : 
    1741      338167 :   if (FLAG_trace_turbo) {
    1742           0 :     TurboJsonFile json_of(info, std::ios_base::trunc);
    1743           0 :     json_of << "{\"function\":\"" << info->GetDebugName().get()
    1744           0 :             << "\", \"source\":\"\",\n\"phases\":[";
    1745             :   }
    1746             :   // TODO(rossberg): Should this really be untyped?
    1747      338167 :   pipeline.RunPrintAndVerify("Machine", true);
    1748             : 
    1749      676334 :   return pipeline.ScheduleAndGenerateCode(call_descriptor);
    1750             : }
    1751             : 
    1752             : // static
    1753      418335 : CompilationJob* Pipeline::NewCompilationJob(Handle<JSFunction> function,
    1754             :                                             bool has_script) {
    1755             :   Handle<SharedFunctionInfo> shared = handle(function->shared());
    1756             :   ParseInfo* parse_info;
    1757      418335 :   if (!has_script) {
    1758           0 :     parse_info = ParseInfo::AllocateWithoutScript(shared);
    1759             :   } else {
    1760      418335 :     parse_info = new ParseInfo(shared);
    1761             :   }
    1762      418336 :   return new PipelineCompilationJob(parse_info, function);
    1763             : }
    1764             : 
    1765             : // static
    1766       70580 : CompilationJob* Pipeline::NewWasmCompilationJob(
    1767             :     CompilationInfo* info, JSGraph* jsgraph, CallDescriptor* descriptor,
    1768             :     SourcePositionTable* source_positions,
    1769             :     ZoneVector<trap_handler::ProtectedInstructionData>* protected_instructions,
    1770             :     bool allow_signalling_nan) {
    1771             :   return new PipelineWasmCompilationJob(
    1772             :       info, jsgraph, descriptor, source_positions, protected_instructions,
    1773       70580 :       allow_signalling_nan);
    1774             : }
    1775             : 
    1776          42 : bool Pipeline::AllocateRegistersForTesting(const RegisterConfiguration* config,
    1777          84 :                                            InstructionSequence* sequence,
    1778             :                                            bool run_verifier) {
    1779             :   CompilationInfo info(ArrayVector("testing"), sequence->isolate(),
    1780          42 :                        sequence->zone(), Code::ComputeFlags(Code::STUB));
    1781          84 :   ZoneStats zone_stats(sequence->isolate()->allocator());
    1782          84 :   PipelineData data(&zone_stats, &info, sequence);
    1783             :   PipelineImpl pipeline(&data);
    1784          42 :   pipeline.data_->InitializeFrameData(nullptr);
    1785          42 :   pipeline.AllocateRegisters(config, nullptr, run_verifier);
    1786          84 :   return !data.compilation_failed();
    1787             : }
    1788             : 
    1789      915874 : bool PipelineImpl::ScheduleAndSelectInstructions(Linkage* linkage,
    1790             :                                                  bool trim_graph) {
    1791             :   CallDescriptor* call_descriptor = linkage->GetIncomingDescriptor();
    1792     5495284 :   PipelineData* data = this->data_;
    1793             : 
    1794             :   DCHECK_NOT_NULL(data->graph());
    1795             : 
    1796      915874 :   if (trim_graph) {
    1797      465878 :     Run<LateGraphTrimmingPhase>();
    1798      465891 :     RunPrintAndVerify("Late trimmed", true);
    1799             :   }
    1800      915878 :   if (data->schedule() == nullptr) Run<ComputeSchedulePhase>();
    1801      915886 :   TraceSchedule(data->info(), data->schedule());
    1802             : 
    1803      915871 :   if (FLAG_turbo_profiling) {
    1804             :     data->set_profiler_data(BasicBlockInstrumentor::Instrument(
    1805          14 :         info(), data->graph(), data->schedule()));
    1806             :   }
    1807             : 
    1808             :   bool verify_stub_graph = data->verify_graph();
    1809     2747605 :   if (verify_stub_graph ||
    1810      915863 :       (FLAG_turbo_verify_machine_graph != nullptr &&
    1811           0 :        (!strcmp(FLAG_turbo_verify_machine_graph, "*") ||
    1812           0 :         !strcmp(FLAG_turbo_verify_machine_graph, data->debug_name())))) {
    1813           0 :     if (FLAG_trace_verify_csa) {
    1814             :       AllowHandleDereference allow_deref;
    1815           0 :       CompilationInfo* info = data->info();
    1816           0 :       CodeTracer::Scope tracing_scope(info->isolate()->GetCodeTracer());
    1817           0 :       OFStream os(tracing_scope.file());
    1818           0 :       os << "--------------------------------------------------\n"
    1819           0 :          << "--- Verifying " << data->debug_name() << " generated by TurboFan\n"
    1820           0 :          << "--------------------------------------------------\n"
    1821           0 :          << *data->schedule()
    1822           0 :          << "--------------------------------------------------\n"
    1823           0 :          << "--- End of " << data->debug_name() << " generated by TurboFan\n"
    1824           0 :          << "--------------------------------------------------\n";
    1825             :     }
    1826           0 :     Zone temp_zone(data->isolate()->allocator(), ZONE_NAME);
    1827             :     MachineGraphVerifier::Run(data->graph(), data->schedule(), linkage,
    1828           0 :                               data->info()->IsStub(), data->debug_name(),
    1829           0 :                               &temp_zone);
    1830             :   }
    1831             : 
    1832      915871 :   data->InitializeInstructionSequence(call_descriptor);
    1833             : 
    1834      915863 :   data->InitializeFrameData(call_descriptor);
    1835             :   // Select and schedule instructions covering the scheduled graph.
    1836      915833 :   Run<InstructionSelectionPhase>(linkage);
    1837      915888 :   if (data->compilation_failed()) {
    1838             :     info()->AbortOptimization(kCodeGenerationFailed);
    1839             :     data->EndPhaseKind();
    1840             :     return false;
    1841             :   }
    1842             : 
    1843      915888 :   if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) {
    1844             :     AllowHandleDereference allow_deref;
    1845           0 :     TurboCfgFile tcf(isolate());
    1846             :     tcf << AsC1V("CodeGen", data->schedule(), data->source_positions(),
    1847           0 :                  data->sequence());
    1848             :   }
    1849             : 
    1850      915888 :   if (FLAG_trace_turbo) {
    1851           0 :     std::ostringstream source_position_output;
    1852             :     // Output source position information before the graph is deleted.
    1853      915873 :     data_->source_positions()->Print(source_position_output);
    1854           0 :     data_->set_source_position_output(source_position_output.str());
    1855             :   }
    1856             : 
    1857      915888 :   data->DeleteGraphZone();
    1858             : 
    1859             :   data->BeginPhaseKind("register allocation");
    1860             : 
    1861      915880 :   bool run_verifier = FLAG_turbo_verify_allocation;
    1862             : 
    1863             :   // Allocate registers.
    1864             :   AllocateRegisters(RegisterConfiguration::Turbofan(), call_descriptor,
    1865      915880 :                     run_verifier);
    1866      915878 :   Run<FrameElisionPhase>();
    1867      915873 :   if (data->compilation_failed()) {
    1868             :     info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc);
    1869             :     data->EndPhaseKind();
    1870             :     return false;
    1871             :   }
    1872             : 
    1873             :   // TODO(mtrofin): move this off to the register allocator.
    1874             :   bool generate_frame_at_start =
    1875     2747619 :       data_->sequence()->instruction_blocks().front()->must_construct_frame();
    1876             :   // Optimimize jumps.
    1877      915873 :   if (FLAG_turbo_jt) {
    1878      915832 :     Run<JumpThreadingPhase>(generate_frame_at_start);
    1879             :   }
    1880             : 
    1881             :   data->EndPhaseKind();
    1882             : 
    1883             :   return true;
    1884             : }
    1885             : 
    1886      912390 : Handle<Code> PipelineImpl::GenerateCode(Linkage* linkage) {
    1887      912390 :   PipelineData* data = this->data_;
    1888             : 
    1889             :   data->BeginPhaseKind("code generation");
    1890             : 
    1891             :   // Generate final machine code.
    1892      912390 :   Run<GenerateCodePhase>(linkage);
    1893             : 
    1894             :   Handle<Code> code = data->code();
    1895             :   if (data->profiler_data()) {
    1896             : #if ENABLE_DISASSEMBLER
    1897             :     std::ostringstream os;
    1898             :     code->Disassemble(nullptr, os);
    1899             :     data->profiler_data()->SetCode(&os);
    1900             : #endif
    1901             :   }
    1902             : 
    1903             :   info()->SetCode(code);
    1904      912392 :   v8::internal::CodeGenerator::PrintCode(code, info());
    1905             : 
    1906      912391 :   if (FLAG_trace_turbo) {
    1907           0 :     TurboJsonFile json_of(info(), std::ios_base::app);
    1908           0 :     json_of << "{\"name\":\"disassembly\",\"type\":\"disassembly\",\"data\":\"";
    1909             : #if ENABLE_DISASSEMBLER
    1910             :     std::stringstream disassembly_stream;
    1911             :     code->Disassemble(nullptr, disassembly_stream);
    1912             :     std::string disassembly_string(disassembly_stream.str());
    1913             :     for (const auto& c : disassembly_string) {
    1914             :       json_of << AsEscapedUC16ForJSON(c);
    1915             :     }
    1916             : #endif  // ENABLE_DISASSEMBLER
    1917           0 :     json_of << "\"}\n],\n";
    1918           0 :     json_of << "\"nodePositions\":";
    1919             :     json_of << data->source_position_output();
    1920           0 :     json_of << "}";
    1921             : 
    1922           0 :     CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer());
    1923           0 :     OFStream os(tracing_scope.file());
    1924           0 :     os << "---------------------------------------------------\n"
    1925           0 :        << "Finished compiling method " << info()->GetDebugName().get()
    1926           0 :        << " using Turbofan" << std::endl;
    1927             :   }
    1928             : 
    1929      912391 :   return code;
    1930             : }
    1931             : 
    1932      449994 : Handle<Code> PipelineImpl::ScheduleAndGenerateCode(
    1933             :     CallDescriptor* call_descriptor) {
    1934             :   Linkage linkage(call_descriptor);
    1935             : 
    1936             :   // Schedule the graph, perform instruction selection and register allocation.
    1937      449994 :   if (!ScheduleAndSelectInstructions(&linkage, false)) return Handle<Code>();
    1938             : 
    1939             :   // Generate the final machine code.
    1940      449994 :   return GenerateCode(&linkage);
    1941             : }
    1942             : 
    1943      915904 : void PipelineImpl::AllocateRegisters(const RegisterConfiguration* config,
    1944             :                                      CallDescriptor* descriptor,
    1945             :                                      bool run_verifier) {
    1946      921843 :   PipelineData* data = this->data_;
    1947             :   // Don't track usage for this zone in compiler stats.
    1948             :   std::unique_ptr<Zone> verifier_zone;
    1949             :   RegisterAllocatorVerifier* verifier = nullptr;
    1950      915904 :   if (run_verifier) {
    1951          42 :     verifier_zone.reset(new Zone(isolate()->allocator(), ZONE_NAME));
    1952             :     verifier = new (verifier_zone.get()) RegisterAllocatorVerifier(
    1953          42 :         verifier_zone.get(), config, data->sequence());
    1954             :   }
    1955             : 
    1956             : #ifdef DEBUG
    1957             :   data_->sequence()->ValidateEdgeSplitForm();
    1958             :   data_->sequence()->ValidateDeferredBlockEntryPaths();
    1959             :   data_->sequence()->ValidateDeferredBlockExitPaths();
    1960             : #endif
    1961             : 
    1962      915904 :   data->InitializeRegisterAllocationData(config, descriptor);
    1963      915905 :   if (info()->is_osr()) {
    1964             :     AllowHandleDereference allow_deref;
    1965        5813 :     OsrHelper osr_helper(info());
    1966        5813 :     osr_helper.SetupFrame(data->frame());
    1967             :   }
    1968             : 
    1969      915905 :   Run<MeetRegisterConstraintsPhase>();
    1970      915927 :   Run<ResolvePhisPhase>();
    1971      915924 :   Run<BuildLiveRangesPhase>();
    1972      915921 :   if (FLAG_trace_turbo_graph) {
    1973             :     AllowHandleDereference allow_deref;
    1974           0 :     CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer());
    1975           0 :     OFStream os(tracing_scope.file());
    1976           0 :     os << "----- Instruction sequence before register allocation -----\n"
    1977           0 :        << PrintableInstructionSequence({config, data->sequence()});
    1978             :   }
    1979      915921 :   if (verifier != nullptr) {
    1980          42 :     CHECK(!data->register_allocation_data()->ExistsUseWithoutDefinition());
    1981          42 :     CHECK(data->register_allocation_data()
    1982             :               ->RangesDefinedInDeferredStayInDeferred());
    1983             :   }
    1984             : 
    1985      915921 :   if (FLAG_turbo_preprocess_ranges) {
    1986      915908 :     Run<SplinterLiveRangesPhase>();
    1987             :   }
    1988             : 
    1989      915939 :   Run<AllocateGeneralRegistersPhase<LinearScanAllocator>>();
    1990      915927 :   Run<AllocateFPRegistersPhase<LinearScanAllocator>>();
    1991             : 
    1992      915930 :   if (FLAG_turbo_preprocess_ranges) {
    1993      915929 :     Run<MergeSplintersPhase>();
    1994             :   }
    1995             : 
    1996      915927 :   Run<AssignSpillSlotsPhase>();
    1997             : 
    1998      915929 :   Run<CommitAssignmentPhase>();
    1999      915928 :   Run<PopulateReferenceMapsPhase>();
    2000      915926 :   Run<ConnectRangesPhase>();
    2001      915928 :   Run<ResolveControlFlowPhase>();
    2002      915927 :   if (FLAG_turbo_move_optimization) {
    2003      915927 :     Run<OptimizeMovesPhase>();
    2004             :   }
    2005             : 
    2006      915929 :   Run<LocateSpillSlotsPhase>();
    2007             : 
    2008      915930 :   if (FLAG_trace_turbo_graph) {
    2009             :     AllowHandleDereference allow_deref;
    2010           0 :     CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer());
    2011           0 :     OFStream os(tracing_scope.file());
    2012           0 :     os << "----- Instruction sequence after register allocation -----\n"
    2013           0 :        << PrintableInstructionSequence({config, data->sequence()});
    2014             :   }
    2015             : 
    2016      915930 :   if (verifier != nullptr) {
    2017          42 :     verifier->VerifyAssignment();
    2018          42 :     verifier->VerifyGapMoves();
    2019             :   }
    2020             : 
    2021      915912 :   if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) {
    2022           0 :     TurboCfgFile tcf(data->isolate());
    2023             :     tcf << AsC1VRegisterAllocationData("CodeGen",
    2024           0 :                                        data->register_allocation_data());
    2025             :   }
    2026             : 
    2027      915912 :   data->DeleteRegisterAllocationZone();
    2028      915929 : }
    2029             : 
    2030     4632012 : CompilationInfo* PipelineImpl::info() const { return data_->info(); }
    2031             : 
    2032      395385 : Isolate* PipelineImpl::isolate() const { return info()->isolate(); }
    2033             : 
    2034             : }  // namespace compiler
    2035             : }  // namespace internal
    2036             : }  // namespace v8

Generated by: LCOV version 1.10