11cb0ef41Sopenharmony_ci// Copyright 2014 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include "src/compiler/pipeline.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include <fstream>
81cb0ef41Sopenharmony_ci#include <iostream>
91cb0ef41Sopenharmony_ci#include <memory>
101cb0ef41Sopenharmony_ci#include <sstream>
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ci#include "src/base/optional.h"
131cb0ef41Sopenharmony_ci#include "src/base/platform/elapsed-timer.h"
141cb0ef41Sopenharmony_ci#include "src/builtins/profile-data-reader.h"
151cb0ef41Sopenharmony_ci#include "src/codegen/assembler-inl.h"
161cb0ef41Sopenharmony_ci#include "src/codegen/compiler.h"
171cb0ef41Sopenharmony_ci#include "src/codegen/optimized-compilation-info.h"
181cb0ef41Sopenharmony_ci#include "src/codegen/register-configuration.h"
191cb0ef41Sopenharmony_ci#include "src/common/high-allocation-throughput-scope.h"
201cb0ef41Sopenharmony_ci#include "src/compiler/add-type-assertions-reducer.h"
211cb0ef41Sopenharmony_ci#include "src/compiler/backend/code-generator.h"
221cb0ef41Sopenharmony_ci#include "src/compiler/backend/frame-elider.h"
231cb0ef41Sopenharmony_ci#include "src/compiler/backend/instruction-selector.h"
241cb0ef41Sopenharmony_ci#include "src/compiler/backend/instruction.h"
251cb0ef41Sopenharmony_ci#include "src/compiler/backend/jump-threading.h"
261cb0ef41Sopenharmony_ci#include "src/compiler/backend/mid-tier-register-allocator.h"
271cb0ef41Sopenharmony_ci#include "src/compiler/backend/move-optimizer.h"
281cb0ef41Sopenharmony_ci#include "src/compiler/backend/register-allocator-verifier.h"
291cb0ef41Sopenharmony_ci#include "src/compiler/backend/register-allocator.h"
301cb0ef41Sopenharmony_ci#include "src/compiler/basic-block-instrumentor.h"
311cb0ef41Sopenharmony_ci#include "src/compiler/branch-condition-duplicator.h"
321cb0ef41Sopenharmony_ci#include "src/compiler/branch-elimination.h"
331cb0ef41Sopenharmony_ci#include "src/compiler/bytecode-graph-builder.h"
341cb0ef41Sopenharmony_ci#include "src/compiler/checkpoint-elimination.h"
351cb0ef41Sopenharmony_ci#include "src/compiler/common-operator-reducer.h"
361cb0ef41Sopenharmony_ci#include "src/compiler/common-operator.h"
371cb0ef41Sopenharmony_ci#include "src/compiler/compilation-dependencies.h"
381cb0ef41Sopenharmony_ci#include "src/compiler/compiler-source-position-table.h"
391cb0ef41Sopenharmony_ci#include "src/compiler/constant-folding-reducer.h"
401cb0ef41Sopenharmony_ci#include "src/compiler/control-flow-optimizer.h"
411cb0ef41Sopenharmony_ci#include "src/compiler/csa-load-elimination.h"
421cb0ef41Sopenharmony_ci#include "src/compiler/dead-code-elimination.h"
431cb0ef41Sopenharmony_ci#include "src/compiler/decompression-optimizer.h"
441cb0ef41Sopenharmony_ci#include "src/compiler/effect-control-linearizer.h"
451cb0ef41Sopenharmony_ci#include "src/compiler/escape-analysis-reducer.h"
461cb0ef41Sopenharmony_ci#include "src/compiler/escape-analysis.h"
471cb0ef41Sopenharmony_ci#include "src/compiler/graph-trimmer.h"
481cb0ef41Sopenharmony_ci#include "src/compiler/graph-visualizer.h"
491cb0ef41Sopenharmony_ci#include "src/compiler/js-call-reducer.h"
501cb0ef41Sopenharmony_ci#include "src/compiler/js-context-specialization.h"
511cb0ef41Sopenharmony_ci#include "src/compiler/js-create-lowering.h"
521cb0ef41Sopenharmony_ci#include "src/compiler/js-generic-lowering.h"
531cb0ef41Sopenharmony_ci#include "src/compiler/js-heap-broker.h"
541cb0ef41Sopenharmony_ci#include "src/compiler/js-inlining-heuristic.h"
551cb0ef41Sopenharmony_ci#include "src/compiler/js-intrinsic-lowering.h"
561cb0ef41Sopenharmony_ci#include "src/compiler/js-native-context-specialization.h"
571cb0ef41Sopenharmony_ci#include "src/compiler/js-typed-lowering.h"
581cb0ef41Sopenharmony_ci#include "src/compiler/load-elimination.h"
591cb0ef41Sopenharmony_ci#include "src/compiler/loop-analysis.h"
601cb0ef41Sopenharmony_ci#include "src/compiler/loop-peeling.h"
611cb0ef41Sopenharmony_ci#include "src/compiler/loop-unrolling.h"
621cb0ef41Sopenharmony_ci#include "src/compiler/loop-variable-optimizer.h"
631cb0ef41Sopenharmony_ci#include "src/compiler/machine-graph-verifier.h"
641cb0ef41Sopenharmony_ci#include "src/compiler/machine-operator-reducer.h"
651cb0ef41Sopenharmony_ci#include "src/compiler/memory-optimizer.h"
661cb0ef41Sopenharmony_ci#include "src/compiler/node-observer.h"
671cb0ef41Sopenharmony_ci#include "src/compiler/node-origin-table.h"
681cb0ef41Sopenharmony_ci#include "src/compiler/osr.h"
691cb0ef41Sopenharmony_ci#include "src/compiler/pipeline-statistics.h"
701cb0ef41Sopenharmony_ci#include "src/compiler/redundancy-elimination.h"
711cb0ef41Sopenharmony_ci#include "src/compiler/schedule.h"
721cb0ef41Sopenharmony_ci#include "src/compiler/scheduler.h"
731cb0ef41Sopenharmony_ci#include "src/compiler/select-lowering.h"
741cb0ef41Sopenharmony_ci#include "src/compiler/simplified-lowering.h"
751cb0ef41Sopenharmony_ci#include "src/compiler/simplified-operator-reducer.h"
761cb0ef41Sopenharmony_ci#include "src/compiler/simplified-operator.h"
771cb0ef41Sopenharmony_ci#include "src/compiler/store-store-elimination.h"
781cb0ef41Sopenharmony_ci#include "src/compiler/type-narrowing-reducer.h"
791cb0ef41Sopenharmony_ci#include "src/compiler/typed-optimization.h"
801cb0ef41Sopenharmony_ci#include "src/compiler/typer.h"
811cb0ef41Sopenharmony_ci#include "src/compiler/value-numbering-reducer.h"
821cb0ef41Sopenharmony_ci#include "src/compiler/verifier.h"
831cb0ef41Sopenharmony_ci#include "src/compiler/zone-stats.h"
841cb0ef41Sopenharmony_ci#include "src/diagnostics/code-tracer.h"
851cb0ef41Sopenharmony_ci#include "src/diagnostics/disassembler.h"
861cb0ef41Sopenharmony_ci#include "src/execution/isolate-inl.h"
871cb0ef41Sopenharmony_ci#include "src/heap/local-heap.h"
881cb0ef41Sopenharmony_ci#include "src/init/bootstrapper.h"
891cb0ef41Sopenharmony_ci#include "src/logging/code-events.h"
901cb0ef41Sopenharmony_ci#include "src/logging/counters.h"
911cb0ef41Sopenharmony_ci#include "src/logging/runtime-call-stats-scope.h"
921cb0ef41Sopenharmony_ci#include "src/objects/shared-function-info.h"
931cb0ef41Sopenharmony_ci#include "src/parsing/parse-info.h"
941cb0ef41Sopenharmony_ci#include "src/tracing/trace-event.h"
951cb0ef41Sopenharmony_ci#include "src/tracing/traced-value.h"
961cb0ef41Sopenharmony_ci#include "src/utils/ostreams.h"
971cb0ef41Sopenharmony_ci#include "src/utils/utils.h"
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
1001cb0ef41Sopenharmony_ci#include "src/compiler/wasm-compiler.h"
1011cb0ef41Sopenharmony_ci#include "src/compiler/wasm-escape-analysis.h"
1021cb0ef41Sopenharmony_ci#include "src/compiler/wasm-inlining.h"
1031cb0ef41Sopenharmony_ci#include "src/compiler/wasm-loop-peeling.h"
1041cb0ef41Sopenharmony_ci#include "src/wasm/function-body-decoder.h"
1051cb0ef41Sopenharmony_ci#include "src/wasm/function-compiler.h"
1061cb0ef41Sopenharmony_ci#include "src/wasm/wasm-engine.h"
1071cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
1081cb0ef41Sopenharmony_ci
1091cb0ef41Sopenharmony_cinamespace v8 {
1101cb0ef41Sopenharmony_cinamespace internal {
1111cb0ef41Sopenharmony_cinamespace compiler {
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_cistatic constexpr char kCodegenZoneName[] = "codegen-zone";
1141cb0ef41Sopenharmony_cistatic constexpr char kGraphZoneName[] = "graph-zone";
1151cb0ef41Sopenharmony_cistatic constexpr char kInstructionZoneName[] = "instruction-zone";
1161cb0ef41Sopenharmony_cistatic constexpr char kMachineGraphVerifierZoneName[] =
1171cb0ef41Sopenharmony_ci    "machine-graph-verifier-zone";
1181cb0ef41Sopenharmony_cistatic constexpr char kPipelineCompilationJobZoneName[] =
1191cb0ef41Sopenharmony_ci    "pipeline-compilation-job-zone";
1201cb0ef41Sopenharmony_cistatic constexpr char kRegisterAllocationZoneName[] =
1211cb0ef41Sopenharmony_ci    "register-allocation-zone";
1221cb0ef41Sopenharmony_cistatic constexpr char kRegisterAllocatorVerifierZoneName[] =
1231cb0ef41Sopenharmony_ci    "register-allocator-verifier-zone";
1241cb0ef41Sopenharmony_ci
1251cb0ef41Sopenharmony_cinamespace {
1261cb0ef41Sopenharmony_ci
1271cb0ef41Sopenharmony_ciMaybe<OuterContext> GetModuleContext(Handle<JSFunction> closure) {
1281cb0ef41Sopenharmony_ci  Context current = closure->context();
1291cb0ef41Sopenharmony_ci  size_t distance = 0;
1301cb0ef41Sopenharmony_ci  while (!current.IsNativeContext()) {
1311cb0ef41Sopenharmony_ci    if (current.IsModuleContext()) {
1321cb0ef41Sopenharmony_ci      return Just(
1331cb0ef41Sopenharmony_ci          OuterContext(handle(current, current.GetIsolate()), distance));
1341cb0ef41Sopenharmony_ci    }
1351cb0ef41Sopenharmony_ci    current = current.previous();
1361cb0ef41Sopenharmony_ci    distance++;
1371cb0ef41Sopenharmony_ci  }
1381cb0ef41Sopenharmony_ci  return Nothing<OuterContext>();
1391cb0ef41Sopenharmony_ci}
1401cb0ef41Sopenharmony_ci
1411cb0ef41Sopenharmony_ci}  // anonymous namespace
1421cb0ef41Sopenharmony_ci
1431cb0ef41Sopenharmony_ciclass PipelineData {
1441cb0ef41Sopenharmony_ci public:
1451cb0ef41Sopenharmony_ci  // For main entry point.
1461cb0ef41Sopenharmony_ci  PipelineData(ZoneStats* zone_stats, Isolate* isolate,
1471cb0ef41Sopenharmony_ci               OptimizedCompilationInfo* info,
1481cb0ef41Sopenharmony_ci               PipelineStatistics* pipeline_statistics)
1491cb0ef41Sopenharmony_ci      : isolate_(isolate),
1501cb0ef41Sopenharmony_ci        allocator_(isolate->allocator()),
1511cb0ef41Sopenharmony_ci        info_(info),
1521cb0ef41Sopenharmony_ci        debug_name_(info_->GetDebugName()),
1531cb0ef41Sopenharmony_ci        may_have_unverifiable_graph_(false),
1541cb0ef41Sopenharmony_ci        zone_stats_(zone_stats),
1551cb0ef41Sopenharmony_ci        pipeline_statistics_(pipeline_statistics),
1561cb0ef41Sopenharmony_ci        graph_zone_scope_(zone_stats_, kGraphZoneName, kCompressGraphZone),
1571cb0ef41Sopenharmony_ci        graph_zone_(graph_zone_scope_.zone()),
1581cb0ef41Sopenharmony_ci        instruction_zone_scope_(zone_stats_, kInstructionZoneName),
1591cb0ef41Sopenharmony_ci        instruction_zone_(instruction_zone_scope_.zone()),
1601cb0ef41Sopenharmony_ci        codegen_zone_scope_(zone_stats_, kCodegenZoneName),
1611cb0ef41Sopenharmony_ci        codegen_zone_(codegen_zone_scope_.zone()),
1621cb0ef41Sopenharmony_ci        broker_(new JSHeapBroker(isolate_, info_->zone(),
1631cb0ef41Sopenharmony_ci                                 info_->trace_heap_broker(),
1641cb0ef41Sopenharmony_ci                                 info->code_kind())),
1651cb0ef41Sopenharmony_ci        register_allocation_zone_scope_(zone_stats_,
1661cb0ef41Sopenharmony_ci                                        kRegisterAllocationZoneName),
1671cb0ef41Sopenharmony_ci        register_allocation_zone_(register_allocation_zone_scope_.zone()),
1681cb0ef41Sopenharmony_ci        assembler_options_(AssemblerOptions::Default(isolate)) {
1691cb0ef41Sopenharmony_ci    PhaseScope scope(pipeline_statistics, "V8.TFInitPipelineData");
1701cb0ef41Sopenharmony_ci    graph_ = graph_zone_->New<Graph>(graph_zone_);
1711cb0ef41Sopenharmony_ci    source_positions_ = graph_zone_->New<SourcePositionTable>(graph_);
1721cb0ef41Sopenharmony_ci    node_origins_ = info->trace_turbo_json()
1731cb0ef41Sopenharmony_ci                        ? graph_zone_->New<NodeOriginTable>(graph_)
1741cb0ef41Sopenharmony_ci                        : nullptr;
1751cb0ef41Sopenharmony_ci    simplified_ = graph_zone_->New<SimplifiedOperatorBuilder>(graph_zone_);
1761cb0ef41Sopenharmony_ci    machine_ = graph_zone_->New<MachineOperatorBuilder>(
1771cb0ef41Sopenharmony_ci        graph_zone_, MachineType::PointerRepresentation(),
1781cb0ef41Sopenharmony_ci        InstructionSelector::SupportedMachineOperatorFlags(),
1791cb0ef41Sopenharmony_ci        InstructionSelector::AlignmentRequirements());
1801cb0ef41Sopenharmony_ci    common_ = graph_zone_->New<CommonOperatorBuilder>(graph_zone_);
1811cb0ef41Sopenharmony_ci    javascript_ = graph_zone_->New<JSOperatorBuilder>(graph_zone_);
1821cb0ef41Sopenharmony_ci    jsgraph_ = graph_zone_->New<JSGraph>(isolate_, graph_, common_, javascript_,
1831cb0ef41Sopenharmony_ci                                         simplified_, machine_);
1841cb0ef41Sopenharmony_ci    observe_node_manager_ =
1851cb0ef41Sopenharmony_ci        info->node_observer()
1861cb0ef41Sopenharmony_ci            ? graph_zone_->New<ObserveNodeManager>(graph_zone_)
1871cb0ef41Sopenharmony_ci            : nullptr;
1881cb0ef41Sopenharmony_ci    dependencies_ =
1891cb0ef41Sopenharmony_ci        info_->zone()->New<CompilationDependencies>(broker_, info_->zone());
1901cb0ef41Sopenharmony_ci  }
1911cb0ef41Sopenharmony_ci
1921cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
1931cb0ef41Sopenharmony_ci  // For WebAssembly compile entry point.
1941cb0ef41Sopenharmony_ci  PipelineData(ZoneStats* zone_stats, wasm::WasmEngine* wasm_engine,
1951cb0ef41Sopenharmony_ci               OptimizedCompilationInfo* info, MachineGraph* mcgraph,
1961cb0ef41Sopenharmony_ci               PipelineStatistics* pipeline_statistics,
1971cb0ef41Sopenharmony_ci               SourcePositionTable* source_positions,
1981cb0ef41Sopenharmony_ci               NodeOriginTable* node_origins,
1991cb0ef41Sopenharmony_ci               const AssemblerOptions& assembler_options)
2001cb0ef41Sopenharmony_ci      : isolate_(nullptr),
2011cb0ef41Sopenharmony_ci        wasm_engine_(wasm_engine),
2021cb0ef41Sopenharmony_ci        allocator_(wasm_engine->allocator()),
2031cb0ef41Sopenharmony_ci        info_(info),
2041cb0ef41Sopenharmony_ci        debug_name_(info_->GetDebugName()),
2051cb0ef41Sopenharmony_ci        may_have_unverifiable_graph_(false),
2061cb0ef41Sopenharmony_ci        zone_stats_(zone_stats),
2071cb0ef41Sopenharmony_ci        pipeline_statistics_(pipeline_statistics),
2081cb0ef41Sopenharmony_ci        graph_zone_scope_(zone_stats_, kGraphZoneName, kCompressGraphZone),
2091cb0ef41Sopenharmony_ci        graph_zone_(graph_zone_scope_.zone()),
2101cb0ef41Sopenharmony_ci        graph_(mcgraph->graph()),
2111cb0ef41Sopenharmony_ci        source_positions_(source_positions),
2121cb0ef41Sopenharmony_ci        node_origins_(node_origins),
2131cb0ef41Sopenharmony_ci        machine_(mcgraph->machine()),
2141cb0ef41Sopenharmony_ci        common_(mcgraph->common()),
2151cb0ef41Sopenharmony_ci        mcgraph_(mcgraph),
2161cb0ef41Sopenharmony_ci        instruction_zone_scope_(zone_stats_, kInstructionZoneName),
2171cb0ef41Sopenharmony_ci        instruction_zone_(instruction_zone_scope_.zone()),
2181cb0ef41Sopenharmony_ci        codegen_zone_scope_(zone_stats_, kCodegenZoneName),
2191cb0ef41Sopenharmony_ci        codegen_zone_(codegen_zone_scope_.zone()),
2201cb0ef41Sopenharmony_ci        register_allocation_zone_scope_(zone_stats_,
2211cb0ef41Sopenharmony_ci                                        kRegisterAllocationZoneName),
2221cb0ef41Sopenharmony_ci        register_allocation_zone_(register_allocation_zone_scope_.zone()),
2231cb0ef41Sopenharmony_ci        assembler_options_(assembler_options) {
2241cb0ef41Sopenharmony_ci    simplified_ = graph_zone_->New<SimplifiedOperatorBuilder>(graph_zone_);
2251cb0ef41Sopenharmony_ci    javascript_ = graph_zone_->New<JSOperatorBuilder>(graph_zone_);
2261cb0ef41Sopenharmony_ci    jsgraph_ = graph_zone_->New<JSGraph>(isolate_, graph_, common_, javascript_,
2271cb0ef41Sopenharmony_ci                                         simplified_, machine_);
2281cb0ef41Sopenharmony_ci  }
2291cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
2301cb0ef41Sopenharmony_ci
2311cb0ef41Sopenharmony_ci  // For CodeStubAssembler and machine graph testing entry point.
2321cb0ef41Sopenharmony_ci  PipelineData(ZoneStats* zone_stats, OptimizedCompilationInfo* info,
2331cb0ef41Sopenharmony_ci               Isolate* isolate, AccountingAllocator* allocator, Graph* graph,
2341cb0ef41Sopenharmony_ci               JSGraph* jsgraph, Schedule* schedule,
2351cb0ef41Sopenharmony_ci               SourcePositionTable* source_positions,
2361cb0ef41Sopenharmony_ci               NodeOriginTable* node_origins, JumpOptimizationInfo* jump_opt,
2371cb0ef41Sopenharmony_ci               const AssemblerOptions& assembler_options,
2381cb0ef41Sopenharmony_ci               const ProfileDataFromFile* profile_data)
2391cb0ef41Sopenharmony_ci      : isolate_(isolate),
2401cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
2411cb0ef41Sopenharmony_ci        // TODO(clemensb): Remove this field, use GetWasmEngine directly
2421cb0ef41Sopenharmony_ci        // instead.
2431cb0ef41Sopenharmony_ci        wasm_engine_(wasm::GetWasmEngine()),
2441cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
2451cb0ef41Sopenharmony_ci        allocator_(allocator),
2461cb0ef41Sopenharmony_ci        info_(info),
2471cb0ef41Sopenharmony_ci        debug_name_(info_->GetDebugName()),
2481cb0ef41Sopenharmony_ci        zone_stats_(zone_stats),
2491cb0ef41Sopenharmony_ci        graph_zone_scope_(zone_stats_, kGraphZoneName, kCompressGraphZone),
2501cb0ef41Sopenharmony_ci        graph_zone_(graph_zone_scope_.zone()),
2511cb0ef41Sopenharmony_ci        graph_(graph),
2521cb0ef41Sopenharmony_ci        source_positions_(source_positions),
2531cb0ef41Sopenharmony_ci        node_origins_(node_origins),
2541cb0ef41Sopenharmony_ci        schedule_(schedule),
2551cb0ef41Sopenharmony_ci        instruction_zone_scope_(zone_stats_, kInstructionZoneName),
2561cb0ef41Sopenharmony_ci        instruction_zone_(instruction_zone_scope_.zone()),
2571cb0ef41Sopenharmony_ci        codegen_zone_scope_(zone_stats_, kCodegenZoneName),
2581cb0ef41Sopenharmony_ci        codegen_zone_(codegen_zone_scope_.zone()),
2591cb0ef41Sopenharmony_ci        register_allocation_zone_scope_(zone_stats_,
2601cb0ef41Sopenharmony_ci                                        kRegisterAllocationZoneName),
2611cb0ef41Sopenharmony_ci        register_allocation_zone_(register_allocation_zone_scope_.zone()),
2621cb0ef41Sopenharmony_ci        jump_optimization_info_(jump_opt),
2631cb0ef41Sopenharmony_ci        assembler_options_(assembler_options),
2641cb0ef41Sopenharmony_ci        profile_data_(profile_data) {
2651cb0ef41Sopenharmony_ci    if (jsgraph) {
2661cb0ef41Sopenharmony_ci      jsgraph_ = jsgraph;
2671cb0ef41Sopenharmony_ci      simplified_ = jsgraph->simplified();
2681cb0ef41Sopenharmony_ci      machine_ = jsgraph->machine();
2691cb0ef41Sopenharmony_ci      common_ = jsgraph->common();
2701cb0ef41Sopenharmony_ci      javascript_ = jsgraph->javascript();
2711cb0ef41Sopenharmony_ci    } else {
2721cb0ef41Sopenharmony_ci      simplified_ = graph_zone_->New<SimplifiedOperatorBuilder>(graph_zone_);
2731cb0ef41Sopenharmony_ci      machine_ = graph_zone_->New<MachineOperatorBuilder>(
2741cb0ef41Sopenharmony_ci          graph_zone_, MachineType::PointerRepresentation(),
2751cb0ef41Sopenharmony_ci          InstructionSelector::SupportedMachineOperatorFlags(),
2761cb0ef41Sopenharmony_ci          InstructionSelector::AlignmentRequirements());
2771cb0ef41Sopenharmony_ci      common_ = graph_zone_->New<CommonOperatorBuilder>(graph_zone_);
2781cb0ef41Sopenharmony_ci      javascript_ = graph_zone_->New<JSOperatorBuilder>(graph_zone_);
2791cb0ef41Sopenharmony_ci      jsgraph_ = graph_zone_->New<JSGraph>(isolate_, graph_, common_,
2801cb0ef41Sopenharmony_ci                                           javascript_, simplified_, machine_);
2811cb0ef41Sopenharmony_ci    }
2821cb0ef41Sopenharmony_ci  }
2831cb0ef41Sopenharmony_ci
2841cb0ef41Sopenharmony_ci  // For register allocation testing entry point.
2851cb0ef41Sopenharmony_ci  PipelineData(ZoneStats* zone_stats, OptimizedCompilationInfo* info,
2861cb0ef41Sopenharmony_ci               Isolate* isolate, InstructionSequence* sequence)
2871cb0ef41Sopenharmony_ci      : isolate_(isolate),
2881cb0ef41Sopenharmony_ci        allocator_(isolate->allocator()),
2891cb0ef41Sopenharmony_ci        info_(info),
2901cb0ef41Sopenharmony_ci        debug_name_(info_->GetDebugName()),
2911cb0ef41Sopenharmony_ci        zone_stats_(zone_stats),
2921cb0ef41Sopenharmony_ci        graph_zone_scope_(zone_stats_, kGraphZoneName, kCompressGraphZone),
2931cb0ef41Sopenharmony_ci        instruction_zone_scope_(zone_stats_, kInstructionZoneName),
2941cb0ef41Sopenharmony_ci        instruction_zone_(sequence->zone()),
2951cb0ef41Sopenharmony_ci        sequence_(sequence),
2961cb0ef41Sopenharmony_ci        codegen_zone_scope_(zone_stats_, kCodegenZoneName),
2971cb0ef41Sopenharmony_ci        codegen_zone_(codegen_zone_scope_.zone()),
2981cb0ef41Sopenharmony_ci        register_allocation_zone_scope_(zone_stats_,
2991cb0ef41Sopenharmony_ci                                        kRegisterAllocationZoneName),
3001cb0ef41Sopenharmony_ci        register_allocation_zone_(register_allocation_zone_scope_.zone()),
3011cb0ef41Sopenharmony_ci        assembler_options_(AssemblerOptions::Default(isolate)) {}
3021cb0ef41Sopenharmony_ci
3031cb0ef41Sopenharmony_ci  ~PipelineData() {
3041cb0ef41Sopenharmony_ci    // Must happen before zones are destroyed.
3051cb0ef41Sopenharmony_ci    delete code_generator_;
3061cb0ef41Sopenharmony_ci    code_generator_ = nullptr;
3071cb0ef41Sopenharmony_ci    DeleteTyper();
3081cb0ef41Sopenharmony_ci    DeleteRegisterAllocationZone();
3091cb0ef41Sopenharmony_ci    DeleteInstructionZone();
3101cb0ef41Sopenharmony_ci    DeleteCodegenZone();
3111cb0ef41Sopenharmony_ci    DeleteGraphZone();
3121cb0ef41Sopenharmony_ci  }
3131cb0ef41Sopenharmony_ci
3141cb0ef41Sopenharmony_ci  PipelineData(const PipelineData&) = delete;
3151cb0ef41Sopenharmony_ci  PipelineData& operator=(const PipelineData&) = delete;
3161cb0ef41Sopenharmony_ci
3171cb0ef41Sopenharmony_ci  Isolate* isolate() const { return isolate_; }
3181cb0ef41Sopenharmony_ci  AccountingAllocator* allocator() const { return allocator_; }
3191cb0ef41Sopenharmony_ci  OptimizedCompilationInfo* info() const { return info_; }
3201cb0ef41Sopenharmony_ci  ZoneStats* zone_stats() const { return zone_stats_; }
3211cb0ef41Sopenharmony_ci  CompilationDependencies* dependencies() const { return dependencies_; }
3221cb0ef41Sopenharmony_ci  PipelineStatistics* pipeline_statistics() { return pipeline_statistics_; }
3231cb0ef41Sopenharmony_ci  OsrHelper* osr_helper() { return &(*osr_helper_); }
3241cb0ef41Sopenharmony_ci  bool compilation_failed() const { return compilation_failed_; }
3251cb0ef41Sopenharmony_ci  void set_compilation_failed() { compilation_failed_ = true; }
3261cb0ef41Sopenharmony_ci
3271cb0ef41Sopenharmony_ci  bool verify_graph() const { return verify_graph_; }
3281cb0ef41Sopenharmony_ci  void set_verify_graph(bool value) { verify_graph_ = value; }
3291cb0ef41Sopenharmony_ci
3301cb0ef41Sopenharmony_ci  MaybeHandle<Code> code() { return code_; }
3311cb0ef41Sopenharmony_ci  void set_code(MaybeHandle<Code> code) {
3321cb0ef41Sopenharmony_ci    DCHECK(code_.is_null());
3331cb0ef41Sopenharmony_ci    code_ = code;
3341cb0ef41Sopenharmony_ci  }
3351cb0ef41Sopenharmony_ci
3361cb0ef41Sopenharmony_ci  CodeGenerator* code_generator() const { return code_generator_; }
3371cb0ef41Sopenharmony_ci
3381cb0ef41Sopenharmony_ci  // RawMachineAssembler generally produces graphs which cannot be verified.
3391cb0ef41Sopenharmony_ci  bool MayHaveUnverifiableGraph() const { return may_have_unverifiable_graph_; }
3401cb0ef41Sopenharmony_ci
3411cb0ef41Sopenharmony_ci  Zone* graph_zone() const { return graph_zone_; }
3421cb0ef41Sopenharmony_ci  Graph* graph() const { return graph_; }
3431cb0ef41Sopenharmony_ci  SourcePositionTable* source_positions() const { return source_positions_; }
3441cb0ef41Sopenharmony_ci  NodeOriginTable* node_origins() const { return node_origins_; }
3451cb0ef41Sopenharmony_ci  MachineOperatorBuilder* machine() const { return machine_; }
3461cb0ef41Sopenharmony_ci  CommonOperatorBuilder* common() const { return common_; }
3471cb0ef41Sopenharmony_ci  JSOperatorBuilder* javascript() const { return javascript_; }
3481cb0ef41Sopenharmony_ci  JSGraph* jsgraph() const { return jsgraph_; }
3491cb0ef41Sopenharmony_ci  MachineGraph* mcgraph() const { return mcgraph_; }
3501cb0ef41Sopenharmony_ci  Handle<NativeContext> native_context() const {
3511cb0ef41Sopenharmony_ci    return handle(info()->native_context(), isolate());
3521cb0ef41Sopenharmony_ci  }
3531cb0ef41Sopenharmony_ci  Handle<JSGlobalObject> global_object() const {
3541cb0ef41Sopenharmony_ci    return handle(info()->global_object(), isolate());
3551cb0ef41Sopenharmony_ci  }
3561cb0ef41Sopenharmony_ci
3571cb0ef41Sopenharmony_ci  JSHeapBroker* broker() const { return broker_; }
3581cb0ef41Sopenharmony_ci  std::unique_ptr<JSHeapBroker> ReleaseBroker() {
3591cb0ef41Sopenharmony_ci    std::unique_ptr<JSHeapBroker> broker(broker_);
3601cb0ef41Sopenharmony_ci    broker_ = nullptr;
3611cb0ef41Sopenharmony_ci    return broker;
3621cb0ef41Sopenharmony_ci  }
3631cb0ef41Sopenharmony_ci
3641cb0ef41Sopenharmony_ci  Schedule* schedule() const { return schedule_; }
3651cb0ef41Sopenharmony_ci  void set_schedule(Schedule* schedule) {
3661cb0ef41Sopenharmony_ci    DCHECK(!schedule_);
3671cb0ef41Sopenharmony_ci    schedule_ = schedule;
3681cb0ef41Sopenharmony_ci  }
3691cb0ef41Sopenharmony_ci  void reset_schedule() { schedule_ = nullptr; }
3701cb0ef41Sopenharmony_ci
3711cb0ef41Sopenharmony_ci  ObserveNodeManager* observe_node_manager() const {
3721cb0ef41Sopenharmony_ci    return observe_node_manager_;
3731cb0ef41Sopenharmony_ci  }
3741cb0ef41Sopenharmony_ci
3751cb0ef41Sopenharmony_ci  Zone* instruction_zone() const { return instruction_zone_; }
3761cb0ef41Sopenharmony_ci  Zone* codegen_zone() const { return codegen_zone_; }
3771cb0ef41Sopenharmony_ci  InstructionSequence* sequence() const { return sequence_; }
3781cb0ef41Sopenharmony_ci  Frame* frame() const { return frame_; }
3791cb0ef41Sopenharmony_ci
3801cb0ef41Sopenharmony_ci  Zone* register_allocation_zone() const { return register_allocation_zone_; }
3811cb0ef41Sopenharmony_ci
3821cb0ef41Sopenharmony_ci  RegisterAllocationData* register_allocation_data() const {
3831cb0ef41Sopenharmony_ci    return register_allocation_data_;
3841cb0ef41Sopenharmony_ci  }
3851cb0ef41Sopenharmony_ci  TopTierRegisterAllocationData* top_tier_register_allocation_data() const {
3861cb0ef41Sopenharmony_ci    return TopTierRegisterAllocationData::cast(register_allocation_data_);
3871cb0ef41Sopenharmony_ci  }
3881cb0ef41Sopenharmony_ci  MidTierRegisterAllocationData* mid_tier_register_allocator_data() const {
3891cb0ef41Sopenharmony_ci    return MidTierRegisterAllocationData::cast(register_allocation_data_);
3901cb0ef41Sopenharmony_ci  }
3911cb0ef41Sopenharmony_ci
3921cb0ef41Sopenharmony_ci  std::string const& source_position_output() const {
3931cb0ef41Sopenharmony_ci    return source_position_output_;
3941cb0ef41Sopenharmony_ci  }
3951cb0ef41Sopenharmony_ci  void set_source_position_output(std::string const& source_position_output) {
3961cb0ef41Sopenharmony_ci    source_position_output_ = source_position_output;
3971cb0ef41Sopenharmony_ci  }
3981cb0ef41Sopenharmony_ci
3991cb0ef41Sopenharmony_ci  JumpOptimizationInfo* jump_optimization_info() const {
4001cb0ef41Sopenharmony_ci    return jump_optimization_info_;
4011cb0ef41Sopenharmony_ci  }
4021cb0ef41Sopenharmony_ci
4031cb0ef41Sopenharmony_ci  const AssemblerOptions& assembler_options() const {
4041cb0ef41Sopenharmony_ci    return assembler_options_;
4051cb0ef41Sopenharmony_ci  }
4061cb0ef41Sopenharmony_ci
4071cb0ef41Sopenharmony_ci  void ChooseSpecializationContext() {
4081cb0ef41Sopenharmony_ci    if (info()->function_context_specializing()) {
4091cb0ef41Sopenharmony_ci      DCHECK(info()->has_context());
4101cb0ef41Sopenharmony_ci      specialization_context_ =
4111cb0ef41Sopenharmony_ci          Just(OuterContext(handle(info()->context(), isolate()), 0));
4121cb0ef41Sopenharmony_ci    } else {
4131cb0ef41Sopenharmony_ci      specialization_context_ = GetModuleContext(info()->closure());
4141cb0ef41Sopenharmony_ci    }
4151cb0ef41Sopenharmony_ci  }
4161cb0ef41Sopenharmony_ci
4171cb0ef41Sopenharmony_ci  Maybe<OuterContext> specialization_context() const {
4181cb0ef41Sopenharmony_ci    return specialization_context_;
4191cb0ef41Sopenharmony_ci  }
4201cb0ef41Sopenharmony_ci
4211cb0ef41Sopenharmony_ci  size_t* address_of_max_unoptimized_frame_height() {
4221cb0ef41Sopenharmony_ci    return &max_unoptimized_frame_height_;
4231cb0ef41Sopenharmony_ci  }
4241cb0ef41Sopenharmony_ci  size_t max_unoptimized_frame_height() const {
4251cb0ef41Sopenharmony_ci    return max_unoptimized_frame_height_;
4261cb0ef41Sopenharmony_ci  }
4271cb0ef41Sopenharmony_ci  size_t* address_of_max_pushed_argument_count() {
4281cb0ef41Sopenharmony_ci    return &max_pushed_argument_count_;
4291cb0ef41Sopenharmony_ci  }
4301cb0ef41Sopenharmony_ci  size_t max_pushed_argument_count() const {
4311cb0ef41Sopenharmony_ci    return max_pushed_argument_count_;
4321cb0ef41Sopenharmony_ci  }
4331cb0ef41Sopenharmony_ci
4341cb0ef41Sopenharmony_ci  CodeTracer* GetCodeTracer() const {
4351cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
4361cb0ef41Sopenharmony_ci    if (wasm_engine_) return wasm_engine_->GetCodeTracer();
4371cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
4381cb0ef41Sopenharmony_ci    return isolate_->GetCodeTracer();
4391cb0ef41Sopenharmony_ci  }
4401cb0ef41Sopenharmony_ci
4411cb0ef41Sopenharmony_ci  Typer* CreateTyper() {
4421cb0ef41Sopenharmony_ci    DCHECK_NULL(typer_);
4431cb0ef41Sopenharmony_ci    typer_ =
4441cb0ef41Sopenharmony_ci        new Typer(broker(), typer_flags_, graph(), &info()->tick_counter());
4451cb0ef41Sopenharmony_ci    return typer_;
4461cb0ef41Sopenharmony_ci  }
4471cb0ef41Sopenharmony_ci
4481cb0ef41Sopenharmony_ci  void AddTyperFlag(Typer::Flag flag) {
4491cb0ef41Sopenharmony_ci    DCHECK_NULL(typer_);
4501cb0ef41Sopenharmony_ci    typer_flags_ |= flag;
4511cb0ef41Sopenharmony_ci  }
4521cb0ef41Sopenharmony_ci
4531cb0ef41Sopenharmony_ci  void DeleteTyper() {
4541cb0ef41Sopenharmony_ci    delete typer_;
4551cb0ef41Sopenharmony_ci    typer_ = nullptr;
4561cb0ef41Sopenharmony_ci  }
4571cb0ef41Sopenharmony_ci
4581cb0ef41Sopenharmony_ci  void DeleteGraphZone() {
4591cb0ef41Sopenharmony_ci    if (graph_zone_ == nullptr) return;
4601cb0ef41Sopenharmony_ci    graph_zone_scope_.Destroy();
4611cb0ef41Sopenharmony_ci    graph_zone_ = nullptr;
4621cb0ef41Sopenharmony_ci    graph_ = nullptr;
4631cb0ef41Sopenharmony_ci    source_positions_ = nullptr;
4641cb0ef41Sopenharmony_ci    node_origins_ = nullptr;
4651cb0ef41Sopenharmony_ci    simplified_ = nullptr;
4661cb0ef41Sopenharmony_ci    machine_ = nullptr;
4671cb0ef41Sopenharmony_ci    common_ = nullptr;
4681cb0ef41Sopenharmony_ci    javascript_ = nullptr;
4691cb0ef41Sopenharmony_ci    jsgraph_ = nullptr;
4701cb0ef41Sopenharmony_ci    mcgraph_ = nullptr;
4711cb0ef41Sopenharmony_ci    schedule_ = nullptr;
4721cb0ef41Sopenharmony_ci  }
4731cb0ef41Sopenharmony_ci
4741cb0ef41Sopenharmony_ci  void DeleteInstructionZone() {
4751cb0ef41Sopenharmony_ci    if (instruction_zone_ == nullptr) return;
4761cb0ef41Sopenharmony_ci    instruction_zone_scope_.Destroy();
4771cb0ef41Sopenharmony_ci    instruction_zone_ = nullptr;
4781cb0ef41Sopenharmony_ci    sequence_ = nullptr;
4791cb0ef41Sopenharmony_ci  }
4801cb0ef41Sopenharmony_ci
4811cb0ef41Sopenharmony_ci  void DeleteCodegenZone() {
4821cb0ef41Sopenharmony_ci    if (codegen_zone_ == nullptr) return;
4831cb0ef41Sopenharmony_ci    codegen_zone_scope_.Destroy();
4841cb0ef41Sopenharmony_ci    codegen_zone_ = nullptr;
4851cb0ef41Sopenharmony_ci    dependencies_ = nullptr;
4861cb0ef41Sopenharmony_ci    delete broker_;
4871cb0ef41Sopenharmony_ci    broker_ = nullptr;
4881cb0ef41Sopenharmony_ci    frame_ = nullptr;
4891cb0ef41Sopenharmony_ci  }
4901cb0ef41Sopenharmony_ci
4911cb0ef41Sopenharmony_ci  void DeleteRegisterAllocationZone() {
4921cb0ef41Sopenharmony_ci    if (register_allocation_zone_ == nullptr) return;
4931cb0ef41Sopenharmony_ci    register_allocation_zone_scope_.Destroy();
4941cb0ef41Sopenharmony_ci    register_allocation_zone_ = nullptr;
4951cb0ef41Sopenharmony_ci    register_allocation_data_ = nullptr;
4961cb0ef41Sopenharmony_ci  }
4971cb0ef41Sopenharmony_ci
4981cb0ef41Sopenharmony_ci  void InitializeInstructionSequence(const CallDescriptor* call_descriptor) {
4991cb0ef41Sopenharmony_ci    DCHECK_NULL(sequence_);
5001cb0ef41Sopenharmony_ci    InstructionBlocks* instruction_blocks =
5011cb0ef41Sopenharmony_ci        InstructionSequence::InstructionBlocksFor(instruction_zone(),
5021cb0ef41Sopenharmony_ci                                                  schedule());
5031cb0ef41Sopenharmony_ci    sequence_ = instruction_zone()->New<InstructionSequence>(
5041cb0ef41Sopenharmony_ci        isolate(), instruction_zone(), instruction_blocks);
5051cb0ef41Sopenharmony_ci    if (call_descriptor && call_descriptor->RequiresFrameAsIncoming()) {
5061cb0ef41Sopenharmony_ci      sequence_->instruction_blocks()[0]->mark_needs_frame();
5071cb0ef41Sopenharmony_ci    } else {
5081cb0ef41Sopenharmony_ci      DCHECK(call_descriptor->CalleeSavedFPRegisters().is_empty());
5091cb0ef41Sopenharmony_ci    }
5101cb0ef41Sopenharmony_ci  }
5111cb0ef41Sopenharmony_ci
5121cb0ef41Sopenharmony_ci  void InitializeFrameData(CallDescriptor* call_descriptor) {
5131cb0ef41Sopenharmony_ci    DCHECK_NULL(frame_);
5141cb0ef41Sopenharmony_ci    int fixed_frame_size = 0;
5151cb0ef41Sopenharmony_ci    if (call_descriptor != nullptr) {
5161cb0ef41Sopenharmony_ci      fixed_frame_size =
5171cb0ef41Sopenharmony_ci          call_descriptor->CalculateFixedFrameSize(info()->code_kind());
5181cb0ef41Sopenharmony_ci    }
5191cb0ef41Sopenharmony_ci    frame_ = codegen_zone()->New<Frame>(fixed_frame_size);
5201cb0ef41Sopenharmony_ci    if (osr_helper_.has_value()) osr_helper()->SetupFrame(frame());
5211cb0ef41Sopenharmony_ci  }
5221cb0ef41Sopenharmony_ci
5231cb0ef41Sopenharmony_ci  void InitializeTopTierRegisterAllocationData(
5241cb0ef41Sopenharmony_ci      const RegisterConfiguration* config, CallDescriptor* call_descriptor,
5251cb0ef41Sopenharmony_ci      RegisterAllocationFlags flags) {
5261cb0ef41Sopenharmony_ci    DCHECK_NULL(register_allocation_data_);
5271cb0ef41Sopenharmony_ci    register_allocation_data_ =
5281cb0ef41Sopenharmony_ci        register_allocation_zone()->New<TopTierRegisterAllocationData>(
5291cb0ef41Sopenharmony_ci            config, register_allocation_zone(), frame(), sequence(), flags,
5301cb0ef41Sopenharmony_ci            &info()->tick_counter(), debug_name());
5311cb0ef41Sopenharmony_ci  }
5321cb0ef41Sopenharmony_ci
5331cb0ef41Sopenharmony_ci  void InitializeMidTierRegisterAllocationData(
5341cb0ef41Sopenharmony_ci      const RegisterConfiguration* config, CallDescriptor* call_descriptor) {
5351cb0ef41Sopenharmony_ci    DCHECK_NULL(register_allocation_data_);
5361cb0ef41Sopenharmony_ci    register_allocation_data_ =
5371cb0ef41Sopenharmony_ci        register_allocation_zone()->New<MidTierRegisterAllocationData>(
5381cb0ef41Sopenharmony_ci            config, register_allocation_zone(), frame(), sequence(),
5391cb0ef41Sopenharmony_ci            &info()->tick_counter(), debug_name());
5401cb0ef41Sopenharmony_ci  }
5411cb0ef41Sopenharmony_ci
5421cb0ef41Sopenharmony_ci  void InitializeOsrHelper() {
5431cb0ef41Sopenharmony_ci    DCHECK(!osr_helper_.has_value());
5441cb0ef41Sopenharmony_ci    osr_helper_.emplace(info());
5451cb0ef41Sopenharmony_ci  }
5461cb0ef41Sopenharmony_ci
5471cb0ef41Sopenharmony_ci  void set_start_source_position(int position) {
5481cb0ef41Sopenharmony_ci    DCHECK_EQ(start_source_position_, kNoSourcePosition);
5491cb0ef41Sopenharmony_ci    start_source_position_ = position;
5501cb0ef41Sopenharmony_ci  }
5511cb0ef41Sopenharmony_ci
5521cb0ef41Sopenharmony_ci  void InitializeCodeGenerator(Linkage* linkage) {
5531cb0ef41Sopenharmony_ci    DCHECK_NULL(code_generator_);
5541cb0ef41Sopenharmony_ci    code_generator_ = new CodeGenerator(
5551cb0ef41Sopenharmony_ci        codegen_zone(), frame(), linkage, sequence(), info(), isolate(),
5561cb0ef41Sopenharmony_ci        osr_helper_, start_source_position_, jump_optimization_info_,
5571cb0ef41Sopenharmony_ci        assembler_options(), info_->builtin(), max_unoptimized_frame_height(),
5581cb0ef41Sopenharmony_ci        max_pushed_argument_count(),
5591cb0ef41Sopenharmony_ci        FLAG_trace_turbo_stack_accesses ? debug_name_.get() : nullptr);
5601cb0ef41Sopenharmony_ci  }
5611cb0ef41Sopenharmony_ci
5621cb0ef41Sopenharmony_ci  void BeginPhaseKind(const char* phase_kind_name) {
5631cb0ef41Sopenharmony_ci    if (pipeline_statistics() != nullptr) {
5641cb0ef41Sopenharmony_ci      pipeline_statistics()->BeginPhaseKind(phase_kind_name);
5651cb0ef41Sopenharmony_ci    }
5661cb0ef41Sopenharmony_ci  }
5671cb0ef41Sopenharmony_ci
5681cb0ef41Sopenharmony_ci  void EndPhaseKind() {
5691cb0ef41Sopenharmony_ci    if (pipeline_statistics() != nullptr) {
5701cb0ef41Sopenharmony_ci      pipeline_statistics()->EndPhaseKind();
5711cb0ef41Sopenharmony_ci    }
5721cb0ef41Sopenharmony_ci  }
5731cb0ef41Sopenharmony_ci
5741cb0ef41Sopenharmony_ci  const char* debug_name() const { return debug_name_.get(); }
5751cb0ef41Sopenharmony_ci
5761cb0ef41Sopenharmony_ci  const ProfileDataFromFile* profile_data() const { return profile_data_; }
5771cb0ef41Sopenharmony_ci  void set_profile_data(const ProfileDataFromFile* profile_data) {
5781cb0ef41Sopenharmony_ci    profile_data_ = profile_data;
5791cb0ef41Sopenharmony_ci  }
5801cb0ef41Sopenharmony_ci
5811cb0ef41Sopenharmony_ci  // RuntimeCallStats that is only available during job execution but not
5821cb0ef41Sopenharmony_ci  // finalization.
5831cb0ef41Sopenharmony_ci  // TODO(delphick): Currently even during execution this can be nullptr, due to
5841cb0ef41Sopenharmony_ci  // JSToWasmWrapperCompilationUnit::Execute. Once a table can be extracted
5851cb0ef41Sopenharmony_ci  // there, this method can DCHECK that it is never nullptr.
5861cb0ef41Sopenharmony_ci  RuntimeCallStats* runtime_call_stats() const { return runtime_call_stats_; }
5871cb0ef41Sopenharmony_ci  void set_runtime_call_stats(RuntimeCallStats* stats) {
5881cb0ef41Sopenharmony_ci    runtime_call_stats_ = stats;
5891cb0ef41Sopenharmony_ci  }
5901cb0ef41Sopenharmony_ci
5911cb0ef41Sopenharmony_ci  // Used to skip the "wasm-inlining" phase when there are no JS-to-Wasm calls.
5921cb0ef41Sopenharmony_ci  bool has_js_wasm_calls() const { return has_js_wasm_calls_; }
5931cb0ef41Sopenharmony_ci  void set_has_js_wasm_calls(bool has_js_wasm_calls) {
5941cb0ef41Sopenharmony_ci    has_js_wasm_calls_ = has_js_wasm_calls;
5951cb0ef41Sopenharmony_ci  }
5961cb0ef41Sopenharmony_ci
5971cb0ef41Sopenharmony_ci private:
5981cb0ef41Sopenharmony_ci  Isolate* const isolate_;
5991cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
6001cb0ef41Sopenharmony_ci  wasm::WasmEngine* const wasm_engine_ = nullptr;
6011cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
6021cb0ef41Sopenharmony_ci  AccountingAllocator* const allocator_;
6031cb0ef41Sopenharmony_ci  OptimizedCompilationInfo* const info_;
6041cb0ef41Sopenharmony_ci  std::unique_ptr<char[]> debug_name_;
6051cb0ef41Sopenharmony_ci  bool may_have_unverifiable_graph_ = true;
6061cb0ef41Sopenharmony_ci  ZoneStats* const zone_stats_;
6071cb0ef41Sopenharmony_ci  PipelineStatistics* pipeline_statistics_ = nullptr;
6081cb0ef41Sopenharmony_ci  bool compilation_failed_ = false;
6091cb0ef41Sopenharmony_ci  bool verify_graph_ = false;
6101cb0ef41Sopenharmony_ci  int start_source_position_ = kNoSourcePosition;
6111cb0ef41Sopenharmony_ci  base::Optional<OsrHelper> osr_helper_;
6121cb0ef41Sopenharmony_ci  MaybeHandle<Code> code_;
6131cb0ef41Sopenharmony_ci  CodeGenerator* code_generator_ = nullptr;
6141cb0ef41Sopenharmony_ci  Typer* typer_ = nullptr;
6151cb0ef41Sopenharmony_ci  Typer::Flags typer_flags_ = Typer::kNoFlags;
6161cb0ef41Sopenharmony_ci
6171cb0ef41Sopenharmony_ci  // All objects in the following group of fields are allocated in graph_zone_.
6181cb0ef41Sopenharmony_ci  // They are all set to nullptr when the graph_zone_ is destroyed.
6191cb0ef41Sopenharmony_ci  ZoneStats::Scope graph_zone_scope_;
6201cb0ef41Sopenharmony_ci  Zone* graph_zone_ = nullptr;
6211cb0ef41Sopenharmony_ci  Graph* graph_ = nullptr;
6221cb0ef41Sopenharmony_ci  SourcePositionTable* source_positions_ = nullptr;
6231cb0ef41Sopenharmony_ci  NodeOriginTable* node_origins_ = nullptr;
6241cb0ef41Sopenharmony_ci  SimplifiedOperatorBuilder* simplified_ = nullptr;
6251cb0ef41Sopenharmony_ci  MachineOperatorBuilder* machine_ = nullptr;
6261cb0ef41Sopenharmony_ci  CommonOperatorBuilder* common_ = nullptr;
6271cb0ef41Sopenharmony_ci  JSOperatorBuilder* javascript_ = nullptr;
6281cb0ef41Sopenharmony_ci  JSGraph* jsgraph_ = nullptr;
6291cb0ef41Sopenharmony_ci  MachineGraph* mcgraph_ = nullptr;
6301cb0ef41Sopenharmony_ci  Schedule* schedule_ = nullptr;
6311cb0ef41Sopenharmony_ci  ObserveNodeManager* observe_node_manager_ = nullptr;
6321cb0ef41Sopenharmony_ci
6331cb0ef41Sopenharmony_ci  // All objects in the following group of fields are allocated in
6341cb0ef41Sopenharmony_ci  // instruction_zone_. They are all set to nullptr when the instruction_zone_
6351cb0ef41Sopenharmony_ci  // is destroyed.
6361cb0ef41Sopenharmony_ci  ZoneStats::Scope instruction_zone_scope_;
6371cb0ef41Sopenharmony_ci  Zone* instruction_zone_;
6381cb0ef41Sopenharmony_ci  InstructionSequence* sequence_ = nullptr;
6391cb0ef41Sopenharmony_ci
6401cb0ef41Sopenharmony_ci  // All objects in the following group of fields are allocated in
6411cb0ef41Sopenharmony_ci  // codegen_zone_. They are all set to nullptr when the codegen_zone_
6421cb0ef41Sopenharmony_ci  // is destroyed.
6431cb0ef41Sopenharmony_ci  ZoneStats::Scope codegen_zone_scope_;
6441cb0ef41Sopenharmony_ci  Zone* codegen_zone_;
6451cb0ef41Sopenharmony_ci  CompilationDependencies* dependencies_ = nullptr;
6461cb0ef41Sopenharmony_ci  JSHeapBroker* broker_ = nullptr;
6471cb0ef41Sopenharmony_ci  Frame* frame_ = nullptr;
6481cb0ef41Sopenharmony_ci
6491cb0ef41Sopenharmony_ci  // All objects in the following group of fields are allocated in
6501cb0ef41Sopenharmony_ci  // register_allocation_zone_. They are all set to nullptr when the zone is
6511cb0ef41Sopenharmony_ci  // destroyed.
6521cb0ef41Sopenharmony_ci  ZoneStats::Scope register_allocation_zone_scope_;
6531cb0ef41Sopenharmony_ci  Zone* register_allocation_zone_;
6541cb0ef41Sopenharmony_ci  RegisterAllocationData* register_allocation_data_ = nullptr;
6551cb0ef41Sopenharmony_ci
6561cb0ef41Sopenharmony_ci  // Source position output for --trace-turbo.
6571cb0ef41Sopenharmony_ci  std::string source_position_output_;
6581cb0ef41Sopenharmony_ci
6591cb0ef41Sopenharmony_ci  JumpOptimizationInfo* jump_optimization_info_ = nullptr;
6601cb0ef41Sopenharmony_ci  AssemblerOptions assembler_options_;
6611cb0ef41Sopenharmony_ci  Maybe<OuterContext> specialization_context_ = Nothing<OuterContext>();
6621cb0ef41Sopenharmony_ci
6631cb0ef41Sopenharmony_ci  // The maximal combined height of all inlined frames in their unoptimized
6641cb0ef41Sopenharmony_ci  // state, and the maximal number of arguments pushed during function calls.
6651cb0ef41Sopenharmony_ci  // Calculated during instruction selection, applied during code generation.
6661cb0ef41Sopenharmony_ci  size_t max_unoptimized_frame_height_ = 0;
6671cb0ef41Sopenharmony_ci  size_t max_pushed_argument_count_ = 0;
6681cb0ef41Sopenharmony_ci
6691cb0ef41Sopenharmony_ci  RuntimeCallStats* runtime_call_stats_ = nullptr;
6701cb0ef41Sopenharmony_ci  const ProfileDataFromFile* profile_data_ = nullptr;
6711cb0ef41Sopenharmony_ci
6721cb0ef41Sopenharmony_ci  bool has_js_wasm_calls_ = false;
6731cb0ef41Sopenharmony_ci};
6741cb0ef41Sopenharmony_ci
6751cb0ef41Sopenharmony_ciclass PipelineImpl final {
6761cb0ef41Sopenharmony_ci public:
6771cb0ef41Sopenharmony_ci  explicit PipelineImpl(PipelineData* data) : data_(data) {}
6781cb0ef41Sopenharmony_ci
6791cb0ef41Sopenharmony_ci  // Helpers for executing pipeline phases.
6801cb0ef41Sopenharmony_ci  template <typename Phase, typename... Args>
6811cb0ef41Sopenharmony_ci  void Run(Args&&... args);
6821cb0ef41Sopenharmony_ci
6831cb0ef41Sopenharmony_ci  // Step A.1. Initialize the heap broker.
6841cb0ef41Sopenharmony_ci  void InitializeHeapBroker();
6851cb0ef41Sopenharmony_ci
6861cb0ef41Sopenharmony_ci  // Step A.2. Run the graph creation and initial optimization passes.
6871cb0ef41Sopenharmony_ci  bool CreateGraph();
6881cb0ef41Sopenharmony_ci
6891cb0ef41Sopenharmony_ci  // Step B. Run the concurrent optimization passes.
6901cb0ef41Sopenharmony_ci  bool OptimizeGraph(Linkage* linkage);
6911cb0ef41Sopenharmony_ci
6921cb0ef41Sopenharmony_ci  // Substep B.1. Produce a scheduled graph.
6931cb0ef41Sopenharmony_ci  void ComputeScheduledGraph();
6941cb0ef41Sopenharmony_ci
6951cb0ef41Sopenharmony_ci  // Substep B.2. Select instructions from a scheduled graph.
6961cb0ef41Sopenharmony_ci  bool SelectInstructions(Linkage* linkage);
6971cb0ef41Sopenharmony_ci
6981cb0ef41Sopenharmony_ci  // Step C. Run the code assembly pass.
6991cb0ef41Sopenharmony_ci  void AssembleCode(Linkage* linkage);
7001cb0ef41Sopenharmony_ci
7011cb0ef41Sopenharmony_ci  // Step D. Run the code finalization pass.
7021cb0ef41Sopenharmony_ci  MaybeHandle<Code> FinalizeCode(bool retire_broker = true);
7031cb0ef41Sopenharmony_ci
7041cb0ef41Sopenharmony_ci  // Step E. Install any code dependencies.
7051cb0ef41Sopenharmony_ci  bool CommitDependencies(Handle<Code> code);
7061cb0ef41Sopenharmony_ci
7071cb0ef41Sopenharmony_ci  void VerifyGeneratedCodeIsIdempotent();
7081cb0ef41Sopenharmony_ci  void RunPrintAndVerify(const char* phase, bool untyped = false);
7091cb0ef41Sopenharmony_ci  bool SelectInstructionsAndAssemble(CallDescriptor* call_descriptor);
7101cb0ef41Sopenharmony_ci  MaybeHandle<Code> GenerateCode(CallDescriptor* call_descriptor);
7111cb0ef41Sopenharmony_ci  void AllocateRegistersForTopTier(const RegisterConfiguration* config,
7121cb0ef41Sopenharmony_ci                                   CallDescriptor* call_descriptor,
7131cb0ef41Sopenharmony_ci                                   bool run_verifier);
7141cb0ef41Sopenharmony_ci  void AllocateRegistersForMidTier(const RegisterConfiguration* config,
7151cb0ef41Sopenharmony_ci                                   CallDescriptor* call_descriptor,
7161cb0ef41Sopenharmony_ci                                   bool run_verifier);
7171cb0ef41Sopenharmony_ci
7181cb0ef41Sopenharmony_ci  OptimizedCompilationInfo* info() const;
7191cb0ef41Sopenharmony_ci  Isolate* isolate() const;
7201cb0ef41Sopenharmony_ci  CodeGenerator* code_generator() const;
7211cb0ef41Sopenharmony_ci
7221cb0ef41Sopenharmony_ci  ObserveNodeManager* observe_node_manager() const;
7231cb0ef41Sopenharmony_ci
7241cb0ef41Sopenharmony_ci private:
7251cb0ef41Sopenharmony_ci  PipelineData* const data_;
7261cb0ef41Sopenharmony_ci};
7271cb0ef41Sopenharmony_ci
7281cb0ef41Sopenharmony_cinamespace {
7291cb0ef41Sopenharmony_ci
7301cb0ef41Sopenharmony_ciclass SourcePositionWrapper final : public Reducer {
7311cb0ef41Sopenharmony_ci public:
7321cb0ef41Sopenharmony_ci  SourcePositionWrapper(Reducer* reducer, SourcePositionTable* table)
7331cb0ef41Sopenharmony_ci      : reducer_(reducer), table_(table) {}
7341cb0ef41Sopenharmony_ci  ~SourcePositionWrapper() final = default;
7351cb0ef41Sopenharmony_ci  SourcePositionWrapper(const SourcePositionWrapper&) = delete;
7361cb0ef41Sopenharmony_ci  SourcePositionWrapper& operator=(const SourcePositionWrapper&) = delete;
7371cb0ef41Sopenharmony_ci
7381cb0ef41Sopenharmony_ci  const char* reducer_name() const override { return reducer_->reducer_name(); }
7391cb0ef41Sopenharmony_ci
7401cb0ef41Sopenharmony_ci  Reduction Reduce(Node* node) final {
7411cb0ef41Sopenharmony_ci    SourcePosition const pos = table_->GetSourcePosition(node);
7421cb0ef41Sopenharmony_ci    SourcePositionTable::Scope position(table_, pos);
7431cb0ef41Sopenharmony_ci    return reducer_->Reduce(node, nullptr);
7441cb0ef41Sopenharmony_ci  }
7451cb0ef41Sopenharmony_ci
7461cb0ef41Sopenharmony_ci  void Finalize() final { reducer_->Finalize(); }
7471cb0ef41Sopenharmony_ci
7481cb0ef41Sopenharmony_ci private:
7491cb0ef41Sopenharmony_ci  Reducer* const reducer_;
7501cb0ef41Sopenharmony_ci  SourcePositionTable* const table_;
7511cb0ef41Sopenharmony_ci};
7521cb0ef41Sopenharmony_ci
7531cb0ef41Sopenharmony_ciclass NodeOriginsWrapper final : public Reducer {
7541cb0ef41Sopenharmony_ci public:
7551cb0ef41Sopenharmony_ci  NodeOriginsWrapper(Reducer* reducer, NodeOriginTable* table)
7561cb0ef41Sopenharmony_ci      : reducer_(reducer), table_(table) {}
7571cb0ef41Sopenharmony_ci  ~NodeOriginsWrapper() final = default;
7581cb0ef41Sopenharmony_ci  NodeOriginsWrapper(const NodeOriginsWrapper&) = delete;
7591cb0ef41Sopenharmony_ci  NodeOriginsWrapper& operator=(const NodeOriginsWrapper&) = delete;
7601cb0ef41Sopenharmony_ci
7611cb0ef41Sopenharmony_ci  const char* reducer_name() const override { return reducer_->reducer_name(); }
7621cb0ef41Sopenharmony_ci
7631cb0ef41Sopenharmony_ci  Reduction Reduce(Node* node) final {
7641cb0ef41Sopenharmony_ci    NodeOriginTable::Scope position(table_, reducer_name(), node);
7651cb0ef41Sopenharmony_ci    return reducer_->Reduce(node, nullptr);
7661cb0ef41Sopenharmony_ci  }
7671cb0ef41Sopenharmony_ci
7681cb0ef41Sopenharmony_ci  void Finalize() final { reducer_->Finalize(); }
7691cb0ef41Sopenharmony_ci
7701cb0ef41Sopenharmony_ci private:
7711cb0ef41Sopenharmony_ci  Reducer* const reducer_;
7721cb0ef41Sopenharmony_ci  NodeOriginTable* const table_;
7731cb0ef41Sopenharmony_ci};
7741cb0ef41Sopenharmony_ci
7751cb0ef41Sopenharmony_ciclass V8_NODISCARD PipelineRunScope {
7761cb0ef41Sopenharmony_ci public:
7771cb0ef41Sopenharmony_ci#ifdef V8_RUNTIME_CALL_STATS
7781cb0ef41Sopenharmony_ci  PipelineRunScope(
7791cb0ef41Sopenharmony_ci      PipelineData* data, const char* phase_name,
7801cb0ef41Sopenharmony_ci      RuntimeCallCounterId runtime_call_counter_id,
7811cb0ef41Sopenharmony_ci      RuntimeCallStats::CounterMode counter_mode = RuntimeCallStats::kExact)
7821cb0ef41Sopenharmony_ci      : phase_scope_(data->pipeline_statistics(), phase_name),
7831cb0ef41Sopenharmony_ci        zone_scope_(data->zone_stats(), phase_name),
7841cb0ef41Sopenharmony_ci        origin_scope_(data->node_origins(), phase_name),
7851cb0ef41Sopenharmony_ci        runtime_call_timer_scope(data->runtime_call_stats(),
7861cb0ef41Sopenharmony_ci                                 runtime_call_counter_id, counter_mode) {
7871cb0ef41Sopenharmony_ci    DCHECK_NOT_NULL(phase_name);
7881cb0ef41Sopenharmony_ci  }
7891cb0ef41Sopenharmony_ci#else   // V8_RUNTIME_CALL_STATS
7901cb0ef41Sopenharmony_ci  PipelineRunScope(PipelineData* data, const char* phase_name)
7911cb0ef41Sopenharmony_ci      : phase_scope_(data->pipeline_statistics(), phase_name),
7921cb0ef41Sopenharmony_ci        zone_scope_(data->zone_stats(), phase_name),
7931cb0ef41Sopenharmony_ci        origin_scope_(data->node_origins(), phase_name) {
7941cb0ef41Sopenharmony_ci    DCHECK_NOT_NULL(phase_name);
7951cb0ef41Sopenharmony_ci  }
7961cb0ef41Sopenharmony_ci#endif  // V8_RUNTIME_CALL_STATS
7971cb0ef41Sopenharmony_ci
7981cb0ef41Sopenharmony_ci  Zone* zone() { return zone_scope_.zone(); }
7991cb0ef41Sopenharmony_ci
8001cb0ef41Sopenharmony_ci private:
8011cb0ef41Sopenharmony_ci  PhaseScope phase_scope_;
8021cb0ef41Sopenharmony_ci  ZoneStats::Scope zone_scope_;
8031cb0ef41Sopenharmony_ci  NodeOriginTable::PhaseScope origin_scope_;
8041cb0ef41Sopenharmony_ci#ifdef V8_RUNTIME_CALL_STATS
8051cb0ef41Sopenharmony_ci  RuntimeCallTimerScope runtime_call_timer_scope;
8061cb0ef41Sopenharmony_ci#endif  // V8_RUNTIME_CALL_STATS
8071cb0ef41Sopenharmony_ci};
8081cb0ef41Sopenharmony_ci
8091cb0ef41Sopenharmony_ci// LocalIsolateScope encapsulates the phase where persistent handles are
8101cb0ef41Sopenharmony_ci// attached to the LocalHeap inside {local_isolate}.
8111cb0ef41Sopenharmony_ciclass V8_NODISCARD LocalIsolateScope {
8121cb0ef41Sopenharmony_ci public:
8131cb0ef41Sopenharmony_ci  explicit LocalIsolateScope(JSHeapBroker* broker,
8141cb0ef41Sopenharmony_ci                             OptimizedCompilationInfo* info,
8151cb0ef41Sopenharmony_ci                             LocalIsolate* local_isolate)
8161cb0ef41Sopenharmony_ci      : broker_(broker), info_(info) {
8171cb0ef41Sopenharmony_ci    broker_->AttachLocalIsolate(info_, local_isolate);
8181cb0ef41Sopenharmony_ci    info_->tick_counter().AttachLocalHeap(local_isolate->heap());
8191cb0ef41Sopenharmony_ci  }
8201cb0ef41Sopenharmony_ci
8211cb0ef41Sopenharmony_ci  ~LocalIsolateScope() {
8221cb0ef41Sopenharmony_ci    info_->tick_counter().DetachLocalHeap();
8231cb0ef41Sopenharmony_ci    broker_->DetachLocalIsolate(info_);
8241cb0ef41Sopenharmony_ci  }
8251cb0ef41Sopenharmony_ci
8261cb0ef41Sopenharmony_ci private:
8271cb0ef41Sopenharmony_ci  JSHeapBroker* broker_;
8281cb0ef41Sopenharmony_ci  OptimizedCompilationInfo* info_;
8291cb0ef41Sopenharmony_ci};
8301cb0ef41Sopenharmony_ci
8311cb0ef41Sopenharmony_civoid PrintFunctionSource(OptimizedCompilationInfo* info, Isolate* isolate,
8321cb0ef41Sopenharmony_ci                         int source_id, Handle<SharedFunctionInfo> shared) {
8331cb0ef41Sopenharmony_ci  if (!shared->script().IsUndefined(isolate)) {
8341cb0ef41Sopenharmony_ci    Handle<Script> script(Script::cast(shared->script()), isolate);
8351cb0ef41Sopenharmony_ci
8361cb0ef41Sopenharmony_ci    if (!script->source().IsUndefined(isolate)) {
8371cb0ef41Sopenharmony_ci      CodeTracer::StreamScope tracing_scope(isolate->GetCodeTracer());
8381cb0ef41Sopenharmony_ci      Object source_name = script->name();
8391cb0ef41Sopenharmony_ci      auto& os = tracing_scope.stream();
8401cb0ef41Sopenharmony_ci      os << "--- FUNCTION SOURCE (";
8411cb0ef41Sopenharmony_ci      if (source_name.IsString()) {
8421cb0ef41Sopenharmony_ci        os << String::cast(source_name).ToCString().get() << ":";
8431cb0ef41Sopenharmony_ci      }
8441cb0ef41Sopenharmony_ci      os << shared->DebugNameCStr().get() << ") id{";
8451cb0ef41Sopenharmony_ci      os << info->optimization_id() << "," << source_id << "} start{";
8461cb0ef41Sopenharmony_ci      os << shared->StartPosition() << "} ---\n";
8471cb0ef41Sopenharmony_ci      {
8481cb0ef41Sopenharmony_ci        DisallowGarbageCollection no_gc;
8491cb0ef41Sopenharmony_ci        int start = shared->StartPosition();
8501cb0ef41Sopenharmony_ci        int len = shared->EndPosition() - start;
8511cb0ef41Sopenharmony_ci        SubStringRange source(String::cast(script->source()), no_gc, start,
8521cb0ef41Sopenharmony_ci                              len);
8531cb0ef41Sopenharmony_ci        for (auto c : source) {
8541cb0ef41Sopenharmony_ci          os << AsReversiblyEscapedUC16(c);
8551cb0ef41Sopenharmony_ci        }
8561cb0ef41Sopenharmony_ci      }
8571cb0ef41Sopenharmony_ci
8581cb0ef41Sopenharmony_ci      os << "\n--- END ---\n";
8591cb0ef41Sopenharmony_ci    }
8601cb0ef41Sopenharmony_ci  }
8611cb0ef41Sopenharmony_ci}
8621cb0ef41Sopenharmony_ci
8631cb0ef41Sopenharmony_ci// Print information for the given inlining: which function was inlined and
8641cb0ef41Sopenharmony_ci// where the inlining occurred.
8651cb0ef41Sopenharmony_civoid PrintInlinedFunctionInfo(
8661cb0ef41Sopenharmony_ci    OptimizedCompilationInfo* info, Isolate* isolate, int source_id,
8671cb0ef41Sopenharmony_ci    int inlining_id, const OptimizedCompilationInfo::InlinedFunctionHolder& h) {
8681cb0ef41Sopenharmony_ci  CodeTracer::StreamScope tracing_scope(isolate->GetCodeTracer());
8691cb0ef41Sopenharmony_ci  auto& os = tracing_scope.stream();
8701cb0ef41Sopenharmony_ci  os << "INLINE (" << h.shared_info->DebugNameCStr().get() << ") id{"
8711cb0ef41Sopenharmony_ci     << info->optimization_id() << "," << source_id << "} AS " << inlining_id
8721cb0ef41Sopenharmony_ci     << " AT ";
8731cb0ef41Sopenharmony_ci  const SourcePosition position = h.position.position;
8741cb0ef41Sopenharmony_ci  if (position.IsKnown()) {
8751cb0ef41Sopenharmony_ci    os << "<" << position.InliningId() << ":" << position.ScriptOffset() << ">";
8761cb0ef41Sopenharmony_ci  } else {
8771cb0ef41Sopenharmony_ci    os << "<?>";
8781cb0ef41Sopenharmony_ci  }
8791cb0ef41Sopenharmony_ci  os << std::endl;
8801cb0ef41Sopenharmony_ci}
8811cb0ef41Sopenharmony_ci
8821cb0ef41Sopenharmony_ci// Print the source of all functions that participated in this optimizing
8831cb0ef41Sopenharmony_ci// compilation. For inlined functions print source position of their inlining.
8841cb0ef41Sopenharmony_civoid PrintParticipatingSource(OptimizedCompilationInfo* info,
8851cb0ef41Sopenharmony_ci                              Isolate* isolate) {
8861cb0ef41Sopenharmony_ci  SourceIdAssigner id_assigner(info->inlined_functions().size());
8871cb0ef41Sopenharmony_ci  PrintFunctionSource(info, isolate, -1, info->shared_info());
8881cb0ef41Sopenharmony_ci  const auto& inlined = info->inlined_functions();
8891cb0ef41Sopenharmony_ci  for (unsigned id = 0; id < inlined.size(); id++) {
8901cb0ef41Sopenharmony_ci    const int source_id = id_assigner.GetIdFor(inlined[id].shared_info);
8911cb0ef41Sopenharmony_ci    PrintFunctionSource(info, isolate, source_id, inlined[id].shared_info);
8921cb0ef41Sopenharmony_ci    PrintInlinedFunctionInfo(info, isolate, source_id, id, inlined[id]);
8931cb0ef41Sopenharmony_ci  }
8941cb0ef41Sopenharmony_ci}
8951cb0ef41Sopenharmony_ci
8961cb0ef41Sopenharmony_ci// Print the code after compiling it.
8971cb0ef41Sopenharmony_civoid PrintCode(Isolate* isolate, Handle<Code> code,
8981cb0ef41Sopenharmony_ci               OptimizedCompilationInfo* info) {
8991cb0ef41Sopenharmony_ci  if (FLAG_print_opt_source && info->IsOptimizing()) {
9001cb0ef41Sopenharmony_ci    PrintParticipatingSource(info, isolate);
9011cb0ef41Sopenharmony_ci  }
9021cb0ef41Sopenharmony_ci
9031cb0ef41Sopenharmony_ci#ifdef ENABLE_DISASSEMBLER
9041cb0ef41Sopenharmony_ci  const bool print_code =
9051cb0ef41Sopenharmony_ci      FLAG_print_code ||
9061cb0ef41Sopenharmony_ci      (info->IsOptimizing() && FLAG_print_opt_code &&
9071cb0ef41Sopenharmony_ci       info->shared_info()->PassesFilter(FLAG_print_opt_code_filter));
9081cb0ef41Sopenharmony_ci  if (print_code) {
9091cb0ef41Sopenharmony_ci    std::unique_ptr<char[]> debug_name = info->GetDebugName();
9101cb0ef41Sopenharmony_ci    CodeTracer::StreamScope tracing_scope(isolate->GetCodeTracer());
9111cb0ef41Sopenharmony_ci    auto& os = tracing_scope.stream();
9121cb0ef41Sopenharmony_ci
9131cb0ef41Sopenharmony_ci    // Print the source code if available.
9141cb0ef41Sopenharmony_ci    const bool print_source = info->IsOptimizing();
9151cb0ef41Sopenharmony_ci    if (print_source) {
9161cb0ef41Sopenharmony_ci      Handle<SharedFunctionInfo> shared = info->shared_info();
9171cb0ef41Sopenharmony_ci      if (shared->script().IsScript() &&
9181cb0ef41Sopenharmony_ci          !Script::cast(shared->script()).source().IsUndefined(isolate)) {
9191cb0ef41Sopenharmony_ci        os << "--- Raw source ---\n";
9201cb0ef41Sopenharmony_ci        StringCharacterStream stream(
9211cb0ef41Sopenharmony_ci            String::cast(Script::cast(shared->script()).source()),
9221cb0ef41Sopenharmony_ci            shared->StartPosition());
9231cb0ef41Sopenharmony_ci        // fun->end_position() points to the last character in the stream. We
9241cb0ef41Sopenharmony_ci        // need to compensate by adding one to calculate the length.
9251cb0ef41Sopenharmony_ci        int source_len = shared->EndPosition() - shared->StartPosition() + 1;
9261cb0ef41Sopenharmony_ci        for (int i = 0; i < source_len; i++) {
9271cb0ef41Sopenharmony_ci          if (stream.HasMore()) {
9281cb0ef41Sopenharmony_ci            os << AsReversiblyEscapedUC16(stream.GetNext());
9291cb0ef41Sopenharmony_ci          }
9301cb0ef41Sopenharmony_ci        }
9311cb0ef41Sopenharmony_ci        os << "\n\n";
9321cb0ef41Sopenharmony_ci      }
9331cb0ef41Sopenharmony_ci    }
9341cb0ef41Sopenharmony_ci    if (info->IsOptimizing()) {
9351cb0ef41Sopenharmony_ci      os << "--- Optimized code ---\n"
9361cb0ef41Sopenharmony_ci         << "optimization_id = " << info->optimization_id() << "\n";
9371cb0ef41Sopenharmony_ci    } else {
9381cb0ef41Sopenharmony_ci      os << "--- Code ---\n";
9391cb0ef41Sopenharmony_ci    }
9401cb0ef41Sopenharmony_ci    if (print_source) {
9411cb0ef41Sopenharmony_ci      Handle<SharedFunctionInfo> shared = info->shared_info();
9421cb0ef41Sopenharmony_ci      os << "source_position = " << shared->StartPosition() << "\n";
9431cb0ef41Sopenharmony_ci    }
9441cb0ef41Sopenharmony_ci    code->Disassemble(debug_name.get(), os, isolate);
9451cb0ef41Sopenharmony_ci    os << "--- End code ---\n";
9461cb0ef41Sopenharmony_ci  }
9471cb0ef41Sopenharmony_ci#endif  // ENABLE_DISASSEMBLER
9481cb0ef41Sopenharmony_ci}
9491cb0ef41Sopenharmony_ci
9501cb0ef41Sopenharmony_civoid TraceScheduleAndVerify(OptimizedCompilationInfo* info, PipelineData* data,
9511cb0ef41Sopenharmony_ci                            Schedule* schedule, const char* phase_name) {
9521cb0ef41Sopenharmony_ci  RCS_SCOPE(data->runtime_call_stats(),
9531cb0ef41Sopenharmony_ci            RuntimeCallCounterId::kOptimizeTraceScheduleAndVerify,
9541cb0ef41Sopenharmony_ci            RuntimeCallStats::kThreadSpecific);
9551cb0ef41Sopenharmony_ci  TRACE_EVENT0(PipelineStatistics::kTraceCategory, "V8.TraceScheduleAndVerify");
9561cb0ef41Sopenharmony_ci  if (info->trace_turbo_json()) {
9571cb0ef41Sopenharmony_ci    UnparkedScopeIfNeeded scope(data->broker());
9581cb0ef41Sopenharmony_ci    AllowHandleDereference allow_deref;
9591cb0ef41Sopenharmony_ci    TurboJsonFile json_of(info, std::ios_base::app);
9601cb0ef41Sopenharmony_ci    json_of << "{\"name\":\"" << phase_name << "\",\"type\":\"schedule\""
9611cb0ef41Sopenharmony_ci            << ",\"data\":\"";
9621cb0ef41Sopenharmony_ci    std::stringstream schedule_stream;
9631cb0ef41Sopenharmony_ci    schedule_stream << *schedule;
9641cb0ef41Sopenharmony_ci    std::string schedule_string(schedule_stream.str());
9651cb0ef41Sopenharmony_ci    for (const auto& c : schedule_string) {
9661cb0ef41Sopenharmony_ci      json_of << AsEscapedUC16ForJSON(c);
9671cb0ef41Sopenharmony_ci    }
9681cb0ef41Sopenharmony_ci    json_of << "\"},\n";
9691cb0ef41Sopenharmony_ci  }
9701cb0ef41Sopenharmony_ci  if (info->trace_turbo_graph() || FLAG_trace_turbo_scheduler) {
9711cb0ef41Sopenharmony_ci    UnparkedScopeIfNeeded scope(data->broker());
9721cb0ef41Sopenharmony_ci    AllowHandleDereference allow_deref;
9731cb0ef41Sopenharmony_ci    CodeTracer::StreamScope tracing_scope(data->GetCodeTracer());
9741cb0ef41Sopenharmony_ci    tracing_scope.stream()
9751cb0ef41Sopenharmony_ci        << "-- Schedule --------------------------------------\n"
9761cb0ef41Sopenharmony_ci        << *schedule;
9771cb0ef41Sopenharmony_ci  }
9781cb0ef41Sopenharmony_ci
9791cb0ef41Sopenharmony_ci  if (FLAG_turbo_verify) ScheduleVerifier::Run(schedule);
9801cb0ef41Sopenharmony_ci}
9811cb0ef41Sopenharmony_ci
9821cb0ef41Sopenharmony_civoid AddReducer(PipelineData* data, GraphReducer* graph_reducer,
9831cb0ef41Sopenharmony_ci                Reducer* reducer) {
9841cb0ef41Sopenharmony_ci  if (data->info()->source_positions()) {
9851cb0ef41Sopenharmony_ci    SourcePositionWrapper* const wrapper =
9861cb0ef41Sopenharmony_ci        data->graph_zone()->New<SourcePositionWrapper>(
9871cb0ef41Sopenharmony_ci            reducer, data->source_positions());
9881cb0ef41Sopenharmony_ci    reducer = wrapper;
9891cb0ef41Sopenharmony_ci  }
9901cb0ef41Sopenharmony_ci  if (data->info()->trace_turbo_json()) {
9911cb0ef41Sopenharmony_ci    NodeOriginsWrapper* const wrapper =
9921cb0ef41Sopenharmony_ci        data->graph_zone()->New<NodeOriginsWrapper>(reducer,
9931cb0ef41Sopenharmony_ci                                                    data->node_origins());
9941cb0ef41Sopenharmony_ci    reducer = wrapper;
9951cb0ef41Sopenharmony_ci  }
9961cb0ef41Sopenharmony_ci
9971cb0ef41Sopenharmony_ci  graph_reducer->AddReducer(reducer);
9981cb0ef41Sopenharmony_ci}
9991cb0ef41Sopenharmony_ci
10001cb0ef41Sopenharmony_ciPipelineStatistics* CreatePipelineStatistics(Handle<Script> script,
10011cb0ef41Sopenharmony_ci                                             OptimizedCompilationInfo* info,
10021cb0ef41Sopenharmony_ci                                             Isolate* isolate,
10031cb0ef41Sopenharmony_ci                                             ZoneStats* zone_stats) {
10041cb0ef41Sopenharmony_ci  PipelineStatistics* pipeline_statistics = nullptr;
10051cb0ef41Sopenharmony_ci
10061cb0ef41Sopenharmony_ci  bool tracing_enabled;
10071cb0ef41Sopenharmony_ci  TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("v8.turbofan"),
10081cb0ef41Sopenharmony_ci                                     &tracing_enabled);
10091cb0ef41Sopenharmony_ci  if (tracing_enabled || FLAG_turbo_stats || FLAG_turbo_stats_nvp) {
10101cb0ef41Sopenharmony_ci    pipeline_statistics =
10111cb0ef41Sopenharmony_ci        new PipelineStatistics(info, isolate->GetTurboStatistics(), zone_stats);
10121cb0ef41Sopenharmony_ci    pipeline_statistics->BeginPhaseKind("V8.TFInitializing");
10131cb0ef41Sopenharmony_ci  }
10141cb0ef41Sopenharmony_ci
10151cb0ef41Sopenharmony_ci  if (info->trace_turbo_json()) {
10161cb0ef41Sopenharmony_ci    TurboJsonFile json_of(info, std::ios_base::trunc);
10171cb0ef41Sopenharmony_ci    json_of << "{\"function\" : ";
10181cb0ef41Sopenharmony_ci    JsonPrintFunctionSource(json_of, -1, info->GetDebugName(), script, isolate,
10191cb0ef41Sopenharmony_ci                            info->shared_info());
10201cb0ef41Sopenharmony_ci    json_of << ",\n\"phases\":[";
10211cb0ef41Sopenharmony_ci  }
10221cb0ef41Sopenharmony_ci
10231cb0ef41Sopenharmony_ci  return pipeline_statistics;
10241cb0ef41Sopenharmony_ci}
10251cb0ef41Sopenharmony_ci
10261cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
10271cb0ef41Sopenharmony_ciPipelineStatistics* CreatePipelineStatistics(
10281cb0ef41Sopenharmony_ci    wasm::FunctionBody function_body, const wasm::WasmModule* wasm_module,
10291cb0ef41Sopenharmony_ci    OptimizedCompilationInfo* info, ZoneStats* zone_stats) {
10301cb0ef41Sopenharmony_ci  PipelineStatistics* pipeline_statistics = nullptr;
10311cb0ef41Sopenharmony_ci
10321cb0ef41Sopenharmony_ci  bool tracing_enabled;
10331cb0ef41Sopenharmony_ci  TRACE_EVENT_CATEGORY_GROUP_ENABLED(
10341cb0ef41Sopenharmony_ci      TRACE_DISABLED_BY_DEFAULT("v8.wasm.turbofan"), &tracing_enabled);
10351cb0ef41Sopenharmony_ci  if (tracing_enabled || FLAG_turbo_stats_wasm) {
10361cb0ef41Sopenharmony_ci    pipeline_statistics = new PipelineStatistics(
10371cb0ef41Sopenharmony_ci        info, wasm::GetWasmEngine()->GetOrCreateTurboStatistics(), zone_stats);
10381cb0ef41Sopenharmony_ci    pipeline_statistics->BeginPhaseKind("V8.WasmInitializing");
10391cb0ef41Sopenharmony_ci  }
10401cb0ef41Sopenharmony_ci
10411cb0ef41Sopenharmony_ci  if (info->trace_turbo_json()) {
10421cb0ef41Sopenharmony_ci    TurboJsonFile json_of(info, std::ios_base::trunc);
10431cb0ef41Sopenharmony_ci    std::unique_ptr<char[]> function_name = info->GetDebugName();
10441cb0ef41Sopenharmony_ci    json_of << "{\"function\":\"" << function_name.get() << "\", \"source\":\"";
10451cb0ef41Sopenharmony_ci    AccountingAllocator allocator;
10461cb0ef41Sopenharmony_ci    std::ostringstream disassembly;
10471cb0ef41Sopenharmony_ci    std::vector<int> source_positions;
10481cb0ef41Sopenharmony_ci    wasm::PrintRawWasmCode(&allocator, function_body, wasm_module,
10491cb0ef41Sopenharmony_ci                           wasm::kPrintLocals, disassembly, &source_positions);
10501cb0ef41Sopenharmony_ci    for (const auto& c : disassembly.str()) {
10511cb0ef41Sopenharmony_ci      json_of << AsEscapedUC16ForJSON(c);
10521cb0ef41Sopenharmony_ci    }
10531cb0ef41Sopenharmony_ci    json_of << "\",\n\"sourceLineToBytecodePosition\" : [";
10541cb0ef41Sopenharmony_ci    bool insert_comma = false;
10551cb0ef41Sopenharmony_ci    for (auto val : source_positions) {
10561cb0ef41Sopenharmony_ci      if (insert_comma) {
10571cb0ef41Sopenharmony_ci        json_of << ", ";
10581cb0ef41Sopenharmony_ci      }
10591cb0ef41Sopenharmony_ci      json_of << val;
10601cb0ef41Sopenharmony_ci      insert_comma = true;
10611cb0ef41Sopenharmony_ci    }
10621cb0ef41Sopenharmony_ci    json_of << "],\n\"phases\":[";
10631cb0ef41Sopenharmony_ci  }
10641cb0ef41Sopenharmony_ci
10651cb0ef41Sopenharmony_ci  return pipeline_statistics;
10661cb0ef41Sopenharmony_ci}
10671cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
10681cb0ef41Sopenharmony_ci
10691cb0ef41Sopenharmony_ci}  // namespace
10701cb0ef41Sopenharmony_ci
10711cb0ef41Sopenharmony_ciclass PipelineCompilationJob final : public TurbofanCompilationJob {
10721cb0ef41Sopenharmony_ci public:
10731cb0ef41Sopenharmony_ci  PipelineCompilationJob(Isolate* isolate,
10741cb0ef41Sopenharmony_ci                         Handle<SharedFunctionInfo> shared_info,
10751cb0ef41Sopenharmony_ci                         Handle<JSFunction> function, BytecodeOffset osr_offset,
10761cb0ef41Sopenharmony_ci                         JavaScriptFrame* osr_frame, CodeKind code_kind);
10771cb0ef41Sopenharmony_ci  ~PipelineCompilationJob() final;
10781cb0ef41Sopenharmony_ci  PipelineCompilationJob(const PipelineCompilationJob&) = delete;
10791cb0ef41Sopenharmony_ci  PipelineCompilationJob& operator=(const PipelineCompilationJob&) = delete;
10801cb0ef41Sopenharmony_ci
10811cb0ef41Sopenharmony_ci protected:
10821cb0ef41Sopenharmony_ci  Status PrepareJobImpl(Isolate* isolate) final;
10831cb0ef41Sopenharmony_ci  Status ExecuteJobImpl(RuntimeCallStats* stats,
10841cb0ef41Sopenharmony_ci                        LocalIsolate* local_isolate) final;
10851cb0ef41Sopenharmony_ci  Status FinalizeJobImpl(Isolate* isolate) final;
10861cb0ef41Sopenharmony_ci
10871cb0ef41Sopenharmony_ci  // Registers weak object to optimized code dependencies.
10881cb0ef41Sopenharmony_ci  void RegisterWeakObjectsInOptimizedCode(Isolate* isolate,
10891cb0ef41Sopenharmony_ci                                          Handle<NativeContext> context,
10901cb0ef41Sopenharmony_ci                                          Handle<Code> code);
10911cb0ef41Sopenharmony_ci
10921cb0ef41Sopenharmony_ci private:
10931cb0ef41Sopenharmony_ci  Zone zone_;
10941cb0ef41Sopenharmony_ci  ZoneStats zone_stats_;
10951cb0ef41Sopenharmony_ci  OptimizedCompilationInfo compilation_info_;
10961cb0ef41Sopenharmony_ci  std::unique_ptr<PipelineStatistics> pipeline_statistics_;
10971cb0ef41Sopenharmony_ci  PipelineData data_;
10981cb0ef41Sopenharmony_ci  PipelineImpl pipeline_;
10991cb0ef41Sopenharmony_ci  Linkage* linkage_;
11001cb0ef41Sopenharmony_ci};
11011cb0ef41Sopenharmony_ci
11021cb0ef41Sopenharmony_ciPipelineCompilationJob::PipelineCompilationJob(
11031cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<SharedFunctionInfo> shared_info,
11041cb0ef41Sopenharmony_ci    Handle<JSFunction> function, BytecodeOffset osr_offset,
11051cb0ef41Sopenharmony_ci    JavaScriptFrame* osr_frame, CodeKind code_kind)
11061cb0ef41Sopenharmony_ci    // Note that the OptimizedCompilationInfo is not initialized at the time
11071cb0ef41Sopenharmony_ci    // we pass it to the CompilationJob constructor, but it is not
11081cb0ef41Sopenharmony_ci    // dereferenced there.
11091cb0ef41Sopenharmony_ci    : TurbofanCompilationJob(&compilation_info_,
11101cb0ef41Sopenharmony_ci                             CompilationJob::State::kReadyToPrepare),
11111cb0ef41Sopenharmony_ci      zone_(isolate->allocator(), kPipelineCompilationJobZoneName),
11121cb0ef41Sopenharmony_ci      zone_stats_(isolate->allocator()),
11131cb0ef41Sopenharmony_ci      compilation_info_(&zone_, isolate, shared_info, function, code_kind,
11141cb0ef41Sopenharmony_ci                        osr_offset, osr_frame),
11151cb0ef41Sopenharmony_ci      pipeline_statistics_(CreatePipelineStatistics(
11161cb0ef41Sopenharmony_ci          handle(Script::cast(shared_info->script()), isolate),
11171cb0ef41Sopenharmony_ci          compilation_info(), isolate, &zone_stats_)),
11181cb0ef41Sopenharmony_ci      data_(&zone_stats_, isolate, compilation_info(),
11191cb0ef41Sopenharmony_ci            pipeline_statistics_.get()),
11201cb0ef41Sopenharmony_ci      pipeline_(&data_),
11211cb0ef41Sopenharmony_ci      linkage_(nullptr) {}
11221cb0ef41Sopenharmony_ci
11231cb0ef41Sopenharmony_ciPipelineCompilationJob::~PipelineCompilationJob() = default;
11241cb0ef41Sopenharmony_ci
11251cb0ef41Sopenharmony_cinamespace {
11261cb0ef41Sopenharmony_ci// Ensure that the RuntimeStats table is set on the PipelineData for
11271cb0ef41Sopenharmony_ci// duration of the job phase and unset immediately afterwards. Each job
11281cb0ef41Sopenharmony_ci// needs to set the correct RuntimeCallStats table depending on whether it
11291cb0ef41Sopenharmony_ci// is running on a background or foreground thread.
11301cb0ef41Sopenharmony_ciclass V8_NODISCARD PipelineJobScope {
11311cb0ef41Sopenharmony_ci public:
11321cb0ef41Sopenharmony_ci  PipelineJobScope(PipelineData* data, RuntimeCallStats* stats) : data_(data) {
11331cb0ef41Sopenharmony_ci    data_->set_runtime_call_stats(stats);
11341cb0ef41Sopenharmony_ci  }
11351cb0ef41Sopenharmony_ci
11361cb0ef41Sopenharmony_ci  ~PipelineJobScope() { data_->set_runtime_call_stats(nullptr); }
11371cb0ef41Sopenharmony_ci
11381cb0ef41Sopenharmony_ci private:
11391cb0ef41Sopenharmony_ci  HighAllocationThroughputScope high_throughput_scope_{
11401cb0ef41Sopenharmony_ci      V8::GetCurrentPlatform()};
11411cb0ef41Sopenharmony_ci  PipelineData* data_;
11421cb0ef41Sopenharmony_ci};
11431cb0ef41Sopenharmony_ci}  // namespace
11441cb0ef41Sopenharmony_ci
11451cb0ef41Sopenharmony_ciPipelineCompilationJob::Status PipelineCompilationJob::PrepareJobImpl(
11461cb0ef41Sopenharmony_ci    Isolate* isolate) {
11471cb0ef41Sopenharmony_ci  // Ensure that the RuntimeCallStats table of main thread is available for
11481cb0ef41Sopenharmony_ci  // phases happening during PrepareJob.
11491cb0ef41Sopenharmony_ci  PipelineJobScope scope(&data_, isolate->counters()->runtime_call_stats());
11501cb0ef41Sopenharmony_ci
11511cb0ef41Sopenharmony_ci  if (compilation_info()->bytecode_array()->length() >
11521cb0ef41Sopenharmony_ci      FLAG_max_optimized_bytecode_size) {
11531cb0ef41Sopenharmony_ci    return AbortOptimization(BailoutReason::kFunctionTooBig);
11541cb0ef41Sopenharmony_ci  }
11551cb0ef41Sopenharmony_ci
11561cb0ef41Sopenharmony_ci  if (!FLAG_always_opt) {
11571cb0ef41Sopenharmony_ci    compilation_info()->set_bailout_on_uninitialized();
11581cb0ef41Sopenharmony_ci  }
11591cb0ef41Sopenharmony_ci  if (FLAG_turbo_loop_peeling) {
11601cb0ef41Sopenharmony_ci    compilation_info()->set_loop_peeling();
11611cb0ef41Sopenharmony_ci  }
11621cb0ef41Sopenharmony_ci  if (FLAG_turbo_inlining) {
11631cb0ef41Sopenharmony_ci    compilation_info()->set_inlining();
11641cb0ef41Sopenharmony_ci  }
11651cb0ef41Sopenharmony_ci  if (FLAG_turbo_allocation_folding) {
11661cb0ef41Sopenharmony_ci    compilation_info()->set_allocation_folding();
11671cb0ef41Sopenharmony_ci  }
11681cb0ef41Sopenharmony_ci
11691cb0ef41Sopenharmony_ci  // Determine whether to specialize the code for the function's context.
11701cb0ef41Sopenharmony_ci  // We can't do this in the case of OSR, because we want to cache the
11711cb0ef41Sopenharmony_ci  // generated code on the native context keyed on SharedFunctionInfo.
11721cb0ef41Sopenharmony_ci  // TODO(mythria): Check if it is better to key the OSR cache on JSFunction and
11731cb0ef41Sopenharmony_ci  // allow context specialization for OSR code.
11741cb0ef41Sopenharmony_ci  if (compilation_info()->closure()->raw_feedback_cell().map() ==
11751cb0ef41Sopenharmony_ci          ReadOnlyRoots(isolate).one_closure_cell_map() &&
11761cb0ef41Sopenharmony_ci      !compilation_info()->is_osr()) {
11771cb0ef41Sopenharmony_ci    compilation_info()->set_function_context_specializing();
11781cb0ef41Sopenharmony_ci    data_.ChooseSpecializationContext();
11791cb0ef41Sopenharmony_ci  }
11801cb0ef41Sopenharmony_ci
11811cb0ef41Sopenharmony_ci  if (compilation_info()->source_positions()) {
11821cb0ef41Sopenharmony_ci    SharedFunctionInfo::EnsureSourcePositionsAvailable(
11831cb0ef41Sopenharmony_ci        isolate, compilation_info()->shared_info());
11841cb0ef41Sopenharmony_ci  }
11851cb0ef41Sopenharmony_ci
11861cb0ef41Sopenharmony_ci  data_.set_start_source_position(
11871cb0ef41Sopenharmony_ci      compilation_info()->shared_info()->StartPosition());
11881cb0ef41Sopenharmony_ci
11891cb0ef41Sopenharmony_ci  linkage_ = compilation_info()->zone()->New<Linkage>(
11901cb0ef41Sopenharmony_ci      Linkage::ComputeIncoming(compilation_info()->zone(), compilation_info()));
11911cb0ef41Sopenharmony_ci
11921cb0ef41Sopenharmony_ci  if (compilation_info()->is_osr()) data_.InitializeOsrHelper();
11931cb0ef41Sopenharmony_ci
11941cb0ef41Sopenharmony_ci  // InitializeHeapBroker() and CreateGraph() may already use
11951cb0ef41Sopenharmony_ci  // IsPendingAllocation.
11961cb0ef41Sopenharmony_ci  isolate->heap()->PublishPendingAllocations();
11971cb0ef41Sopenharmony_ci
11981cb0ef41Sopenharmony_ci  pipeline_.InitializeHeapBroker();
11991cb0ef41Sopenharmony_ci
12001cb0ef41Sopenharmony_ci  // Serialization may have allocated.
12011cb0ef41Sopenharmony_ci  isolate->heap()->PublishPendingAllocations();
12021cb0ef41Sopenharmony_ci
12031cb0ef41Sopenharmony_ci  return SUCCEEDED;
12041cb0ef41Sopenharmony_ci}
12051cb0ef41Sopenharmony_ci
12061cb0ef41Sopenharmony_ciPipelineCompilationJob::Status PipelineCompilationJob::ExecuteJobImpl(
12071cb0ef41Sopenharmony_ci    RuntimeCallStats* stats, LocalIsolate* local_isolate) {
12081cb0ef41Sopenharmony_ci  // Ensure that the RuntimeCallStats table is only available during execution
12091cb0ef41Sopenharmony_ci  // and not during finalization as that might be on a different thread.
12101cb0ef41Sopenharmony_ci  PipelineJobScope scope(&data_, stats);
12111cb0ef41Sopenharmony_ci  LocalIsolateScope local_isolate_scope(data_.broker(), data_.info(),
12121cb0ef41Sopenharmony_ci                                        local_isolate);
12131cb0ef41Sopenharmony_ci
12141cb0ef41Sopenharmony_ci  if (!pipeline_.CreateGraph()) {
12151cb0ef41Sopenharmony_ci    return AbortOptimization(BailoutReason::kGraphBuildingFailed);
12161cb0ef41Sopenharmony_ci  }
12171cb0ef41Sopenharmony_ci
12181cb0ef41Sopenharmony_ci  // We selectively Unpark inside OptimizeGraph.
12191cb0ef41Sopenharmony_ci  if (!pipeline_.OptimizeGraph(linkage_)) return FAILED;
12201cb0ef41Sopenharmony_ci
12211cb0ef41Sopenharmony_ci  pipeline_.AssembleCode(linkage_);
12221cb0ef41Sopenharmony_ci
12231cb0ef41Sopenharmony_ci  return SUCCEEDED;
12241cb0ef41Sopenharmony_ci}
12251cb0ef41Sopenharmony_ci
12261cb0ef41Sopenharmony_ciPipelineCompilationJob::Status PipelineCompilationJob::FinalizeJobImpl(
12271cb0ef41Sopenharmony_ci    Isolate* isolate) {
12281cb0ef41Sopenharmony_ci  // Ensure that the RuntimeCallStats table of main thread is available for
12291cb0ef41Sopenharmony_ci  // phases happening during PrepareJob.
12301cb0ef41Sopenharmony_ci  PipelineJobScope scope(&data_, isolate->counters()->runtime_call_stats());
12311cb0ef41Sopenharmony_ci  RCS_SCOPE(isolate, RuntimeCallCounterId::kOptimizeFinalizePipelineJob);
12321cb0ef41Sopenharmony_ci  MaybeHandle<Code> maybe_code = pipeline_.FinalizeCode();
12331cb0ef41Sopenharmony_ci  Handle<Code> code;
12341cb0ef41Sopenharmony_ci  if (!maybe_code.ToHandle(&code)) {
12351cb0ef41Sopenharmony_ci    if (compilation_info()->bailout_reason() == BailoutReason::kNoReason) {
12361cb0ef41Sopenharmony_ci      return AbortOptimization(BailoutReason::kCodeGenerationFailed);
12371cb0ef41Sopenharmony_ci    }
12381cb0ef41Sopenharmony_ci    return FAILED;
12391cb0ef41Sopenharmony_ci  }
12401cb0ef41Sopenharmony_ci  if (!pipeline_.CommitDependencies(code)) {
12411cb0ef41Sopenharmony_ci    return RetryOptimization(BailoutReason::kBailedOutDueToDependencyChange);
12421cb0ef41Sopenharmony_ci  }
12431cb0ef41Sopenharmony_ci
12441cb0ef41Sopenharmony_ci  compilation_info()->SetCode(code);
12451cb0ef41Sopenharmony_ci  Handle<NativeContext> context(compilation_info()->native_context(), isolate);
12461cb0ef41Sopenharmony_ci  if (CodeKindCanDeoptimize(code->kind())) {
12471cb0ef41Sopenharmony_ci    context->AddOptimizedCode(ToCodeT(*code));
12481cb0ef41Sopenharmony_ci  }
12491cb0ef41Sopenharmony_ci  RegisterWeakObjectsInOptimizedCode(isolate, context, code);
12501cb0ef41Sopenharmony_ci  return SUCCEEDED;
12511cb0ef41Sopenharmony_ci}
12521cb0ef41Sopenharmony_ci
12531cb0ef41Sopenharmony_civoid PipelineCompilationJob::RegisterWeakObjectsInOptimizedCode(
12541cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<NativeContext> context, Handle<Code> code) {
12551cb0ef41Sopenharmony_ci  std::vector<Handle<Map>> maps;
12561cb0ef41Sopenharmony_ci  DCHECK(code->is_optimized_code());
12571cb0ef41Sopenharmony_ci  {
12581cb0ef41Sopenharmony_ci    DisallowGarbageCollection no_gc;
12591cb0ef41Sopenharmony_ci    PtrComprCageBase cage_base(isolate);
12601cb0ef41Sopenharmony_ci    int const mode_mask = RelocInfo::EmbeddedObjectModeMask();
12611cb0ef41Sopenharmony_ci    for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
12621cb0ef41Sopenharmony_ci      DCHECK(RelocInfo::IsEmbeddedObjectMode(it.rinfo()->rmode()));
12631cb0ef41Sopenharmony_ci      HeapObject target_object = it.rinfo()->target_object(cage_base);
12641cb0ef41Sopenharmony_ci      if (code->IsWeakObjectInOptimizedCode(target_object)) {
12651cb0ef41Sopenharmony_ci        if (target_object.IsMap(cage_base)) {
12661cb0ef41Sopenharmony_ci          maps.push_back(handle(Map::cast(target_object), isolate));
12671cb0ef41Sopenharmony_ci        }
12681cb0ef41Sopenharmony_ci      }
12691cb0ef41Sopenharmony_ci    }
12701cb0ef41Sopenharmony_ci  }
12711cb0ef41Sopenharmony_ci  for (Handle<Map> map : maps) {
12721cb0ef41Sopenharmony_ci    isolate->heap()->AddRetainedMap(context, map);
12731cb0ef41Sopenharmony_ci  }
12741cb0ef41Sopenharmony_ci  code->set_can_have_weak_objects(true);
12751cb0ef41Sopenharmony_ci}
12761cb0ef41Sopenharmony_ci
12771cb0ef41Sopenharmony_citemplate <typename Phase, typename... Args>
12781cb0ef41Sopenharmony_civoid PipelineImpl::Run(Args&&... args) {
12791cb0ef41Sopenharmony_ci#ifdef V8_RUNTIME_CALL_STATS
12801cb0ef41Sopenharmony_ci  PipelineRunScope scope(this->data_, Phase::phase_name(),
12811cb0ef41Sopenharmony_ci                         Phase::kRuntimeCallCounterId, Phase::kCounterMode);
12821cb0ef41Sopenharmony_ci#else
12831cb0ef41Sopenharmony_ci  PipelineRunScope scope(this->data_, Phase::phase_name());
12841cb0ef41Sopenharmony_ci#endif
12851cb0ef41Sopenharmony_ci  Phase phase;
12861cb0ef41Sopenharmony_ci  phase.Run(this->data_, scope.zone(), std::forward<Args>(args)...);
12871cb0ef41Sopenharmony_ci}
12881cb0ef41Sopenharmony_ci
12891cb0ef41Sopenharmony_ci#ifdef V8_RUNTIME_CALL_STATS
12901cb0ef41Sopenharmony_ci#define DECL_PIPELINE_PHASE_CONSTANTS_HELPER(Name, Mode)        \
12911cb0ef41Sopenharmony_ci  static const char* phase_name() { return "V8.TF" #Name; }     \
12921cb0ef41Sopenharmony_ci  static constexpr RuntimeCallCounterId kRuntimeCallCounterId = \
12931cb0ef41Sopenharmony_ci      RuntimeCallCounterId::kOptimize##Name;                    \
12941cb0ef41Sopenharmony_ci  static constexpr RuntimeCallStats::CounterMode kCounterMode = Mode;
12951cb0ef41Sopenharmony_ci#else  // V8_RUNTIME_CALL_STATS
12961cb0ef41Sopenharmony_ci#define DECL_PIPELINE_PHASE_CONSTANTS_HELPER(Name, Mode) \
12971cb0ef41Sopenharmony_ci  static const char* phase_name() { return "V8.TF" #Name; }
12981cb0ef41Sopenharmony_ci#endif  // V8_RUNTIME_CALL_STATS
12991cb0ef41Sopenharmony_ci
13001cb0ef41Sopenharmony_ci#define DECL_PIPELINE_PHASE_CONSTANTS(Name) \
13011cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS_HELPER(Name, RuntimeCallStats::kThreadSpecific)
13021cb0ef41Sopenharmony_ci
13031cb0ef41Sopenharmony_ci#define DECL_MAIN_THREAD_PIPELINE_PHASE_CONSTANTS(Name) \
13041cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS_HELPER(Name, RuntimeCallStats::kExact)
13051cb0ef41Sopenharmony_ci
13061cb0ef41Sopenharmony_cistruct GraphBuilderPhase {
13071cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(BytecodeGraphBuilder)
13081cb0ef41Sopenharmony_ci
13091cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
13101cb0ef41Sopenharmony_ci    BytecodeGraphBuilderFlags flags;
13111cb0ef41Sopenharmony_ci    if (data->info()->analyze_environment_liveness()) {
13121cb0ef41Sopenharmony_ci      flags |= BytecodeGraphBuilderFlag::kAnalyzeEnvironmentLiveness;
13131cb0ef41Sopenharmony_ci    }
13141cb0ef41Sopenharmony_ci    if (data->info()->bailout_on_uninitialized()) {
13151cb0ef41Sopenharmony_ci      flags |= BytecodeGraphBuilderFlag::kBailoutOnUninitialized;
13161cb0ef41Sopenharmony_ci    }
13171cb0ef41Sopenharmony_ci
13181cb0ef41Sopenharmony_ci    JSFunctionRef closure = MakeRef(data->broker(), data->info()->closure());
13191cb0ef41Sopenharmony_ci    CallFrequency frequency(1.0f);
13201cb0ef41Sopenharmony_ci    BuildGraphFromBytecode(
13211cb0ef41Sopenharmony_ci        data->broker(), temp_zone, closure.shared(),
13221cb0ef41Sopenharmony_ci        closure.raw_feedback_cell(data->dependencies()),
13231cb0ef41Sopenharmony_ci        data->info()->osr_offset(), data->jsgraph(), frequency,
13241cb0ef41Sopenharmony_ci        data->source_positions(), SourcePosition::kNotInlined,
13251cb0ef41Sopenharmony_ci        data->info()->code_kind(), flags, &data->info()->tick_counter(),
13261cb0ef41Sopenharmony_ci        ObserveNodeInfo{data->observe_node_manager(),
13271cb0ef41Sopenharmony_ci                        data->info()->node_observer()});
13281cb0ef41Sopenharmony_ci  }
13291cb0ef41Sopenharmony_ci};
13301cb0ef41Sopenharmony_ci
13311cb0ef41Sopenharmony_cistruct InliningPhase {
13321cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(Inlining)
13331cb0ef41Sopenharmony_ci
13341cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
13351cb0ef41Sopenharmony_ci    OptimizedCompilationInfo* info = data->info();
13361cb0ef41Sopenharmony_ci    GraphReducer graph_reducer(temp_zone, data->graph(), &info->tick_counter(),
13371cb0ef41Sopenharmony_ci                               data->broker(), data->jsgraph()->Dead(),
13381cb0ef41Sopenharmony_ci                               data->observe_node_manager());
13391cb0ef41Sopenharmony_ci    DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
13401cb0ef41Sopenharmony_ci                                              data->common(), temp_zone);
13411cb0ef41Sopenharmony_ci    CheckpointElimination checkpoint_elimination(&graph_reducer);
13421cb0ef41Sopenharmony_ci    CommonOperatorReducer common_reducer(
13431cb0ef41Sopenharmony_ci        &graph_reducer, data->graph(), data->broker(), data->common(),
13441cb0ef41Sopenharmony_ci        data->machine(), temp_zone, BranchSemantics::kJS);
13451cb0ef41Sopenharmony_ci    JSCallReducer::Flags call_reducer_flags = JSCallReducer::kNoFlags;
13461cb0ef41Sopenharmony_ci    if (data->info()->bailout_on_uninitialized()) {
13471cb0ef41Sopenharmony_ci      call_reducer_flags |= JSCallReducer::kBailoutOnUninitialized;
13481cb0ef41Sopenharmony_ci    }
13491cb0ef41Sopenharmony_ci    if (data->info()->inline_js_wasm_calls() && data->info()->inlining()) {
13501cb0ef41Sopenharmony_ci      call_reducer_flags |= JSCallReducer::kInlineJSToWasmCalls;
13511cb0ef41Sopenharmony_ci    }
13521cb0ef41Sopenharmony_ci    JSCallReducer call_reducer(&graph_reducer, data->jsgraph(), data->broker(),
13531cb0ef41Sopenharmony_ci                               temp_zone, call_reducer_flags);
13541cb0ef41Sopenharmony_ci    JSContextSpecialization context_specialization(
13551cb0ef41Sopenharmony_ci        &graph_reducer, data->jsgraph(), data->broker(),
13561cb0ef41Sopenharmony_ci        data->specialization_context(),
13571cb0ef41Sopenharmony_ci        data->info()->function_context_specializing()
13581cb0ef41Sopenharmony_ci            ? data->info()->closure()
13591cb0ef41Sopenharmony_ci            : MaybeHandle<JSFunction>());
13601cb0ef41Sopenharmony_ci    JSNativeContextSpecialization::Flags flags =
13611cb0ef41Sopenharmony_ci        JSNativeContextSpecialization::kNoFlags;
13621cb0ef41Sopenharmony_ci    if (data->info()->bailout_on_uninitialized()) {
13631cb0ef41Sopenharmony_ci      flags |= JSNativeContextSpecialization::kBailoutOnUninitialized;
13641cb0ef41Sopenharmony_ci    }
13651cb0ef41Sopenharmony_ci    // Passing the OptimizedCompilationInfo's shared zone here as
13661cb0ef41Sopenharmony_ci    // JSNativeContextSpecialization allocates out-of-heap objects
13671cb0ef41Sopenharmony_ci    // that need to live until code generation.
13681cb0ef41Sopenharmony_ci    JSNativeContextSpecialization native_context_specialization(
13691cb0ef41Sopenharmony_ci        &graph_reducer, data->jsgraph(), data->broker(), flags,
13701cb0ef41Sopenharmony_ci        data->dependencies(), temp_zone, info->zone());
13711cb0ef41Sopenharmony_ci    JSInliningHeuristic inlining(
13721cb0ef41Sopenharmony_ci        &graph_reducer, temp_zone, data->info(), data->jsgraph(),
13731cb0ef41Sopenharmony_ci        data->broker(), data->source_positions(), JSInliningHeuristic::kJSOnly);
13741cb0ef41Sopenharmony_ci
13751cb0ef41Sopenharmony_ci    JSIntrinsicLowering intrinsic_lowering(&graph_reducer, data->jsgraph(),
13761cb0ef41Sopenharmony_ci                                           data->broker());
13771cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &dead_code_elimination);
13781cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &checkpoint_elimination);
13791cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &common_reducer);
13801cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &native_context_specialization);
13811cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &context_specialization);
13821cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &intrinsic_lowering);
13831cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &call_reducer);
13841cb0ef41Sopenharmony_ci    if (data->info()->inlining()) {
13851cb0ef41Sopenharmony_ci      AddReducer(data, &graph_reducer, &inlining);
13861cb0ef41Sopenharmony_ci    }
13871cb0ef41Sopenharmony_ci    graph_reducer.ReduceGraph();
13881cb0ef41Sopenharmony_ci    info->set_inlined_bytecode_size(inlining.total_inlined_bytecode_size());
13891cb0ef41Sopenharmony_ci
13901cb0ef41Sopenharmony_ci    // Skip the "wasm-inlining" phase if there are no Wasm functions calls.
13911cb0ef41Sopenharmony_ci    if (call_reducer.has_wasm_calls()) {
13921cb0ef41Sopenharmony_ci      data->set_has_js_wasm_calls(true);
13931cb0ef41Sopenharmony_ci    }
13941cb0ef41Sopenharmony_ci  }
13951cb0ef41Sopenharmony_ci};
13961cb0ef41Sopenharmony_ci
13971cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
13981cb0ef41Sopenharmony_cistruct JSWasmInliningPhase {
13991cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(JSWasmInlining)
14001cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
14011cb0ef41Sopenharmony_ci    DCHECK(data->has_js_wasm_calls());
14021cb0ef41Sopenharmony_ci
14031cb0ef41Sopenharmony_ci    OptimizedCompilationInfo* info = data->info();
14041cb0ef41Sopenharmony_ci    GraphReducer graph_reducer(temp_zone, data->graph(), &info->tick_counter(),
14051cb0ef41Sopenharmony_ci                               data->broker(), data->jsgraph()->Dead());
14061cb0ef41Sopenharmony_ci    DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
14071cb0ef41Sopenharmony_ci                                              data->common(), temp_zone);
14081cb0ef41Sopenharmony_ci    CommonOperatorReducer common_reducer(
14091cb0ef41Sopenharmony_ci        &graph_reducer, data->graph(), data->broker(), data->common(),
14101cb0ef41Sopenharmony_ci        data->machine(), temp_zone, BranchSemantics::kMachine);
14111cb0ef41Sopenharmony_ci    JSInliningHeuristic inlining(&graph_reducer, temp_zone, data->info(),
14121cb0ef41Sopenharmony_ci                                 data->jsgraph(), data->broker(),
14131cb0ef41Sopenharmony_ci                                 data->source_positions(),
14141cb0ef41Sopenharmony_ci                                 JSInliningHeuristic::kWasmOnly);
14151cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &dead_code_elimination);
14161cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &common_reducer);
14171cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &inlining);
14181cb0ef41Sopenharmony_ci    graph_reducer.ReduceGraph();
14191cb0ef41Sopenharmony_ci  }
14201cb0ef41Sopenharmony_ci};
14211cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
14221cb0ef41Sopenharmony_ci
14231cb0ef41Sopenharmony_cistruct EarlyGraphTrimmingPhase {
14241cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(EarlyGraphTrimming)
14251cb0ef41Sopenharmony_ci
14261cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
14271cb0ef41Sopenharmony_ci    GraphTrimmer trimmer(temp_zone, data->graph());
14281cb0ef41Sopenharmony_ci    NodeVector roots(temp_zone);
14291cb0ef41Sopenharmony_ci    data->jsgraph()->GetCachedNodes(&roots);
14301cb0ef41Sopenharmony_ci    UnparkedScopeIfNeeded scope(data->broker(), FLAG_trace_turbo_trimming);
14311cb0ef41Sopenharmony_ci    trimmer.TrimGraph(roots.begin(), roots.end());
14321cb0ef41Sopenharmony_ci  }
14331cb0ef41Sopenharmony_ci};
14341cb0ef41Sopenharmony_ci
14351cb0ef41Sopenharmony_cistruct TyperPhase {
14361cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(Typer)
14371cb0ef41Sopenharmony_ci
14381cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone, Typer* typer) {
14391cb0ef41Sopenharmony_ci    NodeVector roots(temp_zone);
14401cb0ef41Sopenharmony_ci    data->jsgraph()->GetCachedNodes(&roots);
14411cb0ef41Sopenharmony_ci
14421cb0ef41Sopenharmony_ci    // Make sure we always type True and False. Needed for escape analysis.
14431cb0ef41Sopenharmony_ci    roots.push_back(data->jsgraph()->TrueConstant());
14441cb0ef41Sopenharmony_ci    roots.push_back(data->jsgraph()->FalseConstant());
14451cb0ef41Sopenharmony_ci
14461cb0ef41Sopenharmony_ci    LoopVariableOptimizer induction_vars(data->jsgraph()->graph(),
14471cb0ef41Sopenharmony_ci                                         data->common(), temp_zone);
14481cb0ef41Sopenharmony_ci    if (FLAG_turbo_loop_variable) induction_vars.Run();
14491cb0ef41Sopenharmony_ci
14501cb0ef41Sopenharmony_ci    // The typer inspects heap objects, so we need to unpark the local heap.
14511cb0ef41Sopenharmony_ci    UnparkedScopeIfNeeded scope(data->broker());
14521cb0ef41Sopenharmony_ci    typer->Run(roots, &induction_vars);
14531cb0ef41Sopenharmony_ci  }
14541cb0ef41Sopenharmony_ci};
14551cb0ef41Sopenharmony_ci
14561cb0ef41Sopenharmony_cistruct UntyperPhase {
14571cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(Untyper)
14581cb0ef41Sopenharmony_ci
14591cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
14601cb0ef41Sopenharmony_ci    class RemoveTypeReducer final : public Reducer {
14611cb0ef41Sopenharmony_ci     public:
14621cb0ef41Sopenharmony_ci      const char* reducer_name() const override { return "RemoveTypeReducer"; }
14631cb0ef41Sopenharmony_ci      Reduction Reduce(Node* node) final {
14641cb0ef41Sopenharmony_ci        if (NodeProperties::IsTyped(node)) {
14651cb0ef41Sopenharmony_ci          NodeProperties::RemoveType(node);
14661cb0ef41Sopenharmony_ci          return Changed(node);
14671cb0ef41Sopenharmony_ci        }
14681cb0ef41Sopenharmony_ci        return NoChange();
14691cb0ef41Sopenharmony_ci      }
14701cb0ef41Sopenharmony_ci    };
14711cb0ef41Sopenharmony_ci
14721cb0ef41Sopenharmony_ci    NodeVector roots(temp_zone);
14731cb0ef41Sopenharmony_ci    data->jsgraph()->GetCachedNodes(&roots);
14741cb0ef41Sopenharmony_ci    for (Node* node : roots) {
14751cb0ef41Sopenharmony_ci      NodeProperties::RemoveType(node);
14761cb0ef41Sopenharmony_ci    }
14771cb0ef41Sopenharmony_ci
14781cb0ef41Sopenharmony_ci    GraphReducer graph_reducer(
14791cb0ef41Sopenharmony_ci        temp_zone, data->graph(), &data->info()->tick_counter(), data->broker(),
14801cb0ef41Sopenharmony_ci        data->jsgraph()->Dead(), data->observe_node_manager());
14811cb0ef41Sopenharmony_ci    RemoveTypeReducer remove_type_reducer;
14821cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &remove_type_reducer);
14831cb0ef41Sopenharmony_ci    graph_reducer.ReduceGraph();
14841cb0ef41Sopenharmony_ci  }
14851cb0ef41Sopenharmony_ci};
14861cb0ef41Sopenharmony_ci
14871cb0ef41Sopenharmony_cistruct HeapBrokerInitializationPhase {
14881cb0ef41Sopenharmony_ci  DECL_MAIN_THREAD_PIPELINE_PHASE_CONSTANTS(HeapBrokerInitialization)
14891cb0ef41Sopenharmony_ci
14901cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
14911cb0ef41Sopenharmony_ci    data->broker()->InitializeAndStartSerializing();
14921cb0ef41Sopenharmony_ci  }
14931cb0ef41Sopenharmony_ci};
14941cb0ef41Sopenharmony_ci
14951cb0ef41Sopenharmony_cistruct TypedLoweringPhase {
14961cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(TypedLowering)
14971cb0ef41Sopenharmony_ci
14981cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
14991cb0ef41Sopenharmony_ci    GraphReducer graph_reducer(
15001cb0ef41Sopenharmony_ci        temp_zone, data->graph(), &data->info()->tick_counter(), data->broker(),
15011cb0ef41Sopenharmony_ci        data->jsgraph()->Dead(), data->observe_node_manager());
15021cb0ef41Sopenharmony_ci    DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
15031cb0ef41Sopenharmony_ci                                              data->common(), temp_zone);
15041cb0ef41Sopenharmony_ci    JSCreateLowering create_lowering(&graph_reducer, data->dependencies(),
15051cb0ef41Sopenharmony_ci                                     data->jsgraph(), data->broker(),
15061cb0ef41Sopenharmony_ci                                     temp_zone);
15071cb0ef41Sopenharmony_ci    JSTypedLowering typed_lowering(&graph_reducer, data->jsgraph(),
15081cb0ef41Sopenharmony_ci                                   data->broker(), temp_zone);
15091cb0ef41Sopenharmony_ci    ConstantFoldingReducer constant_folding_reducer(
15101cb0ef41Sopenharmony_ci        &graph_reducer, data->jsgraph(), data->broker());
15111cb0ef41Sopenharmony_ci    TypedOptimization typed_optimization(&graph_reducer, data->dependencies(),
15121cb0ef41Sopenharmony_ci                                         data->jsgraph(), data->broker());
15131cb0ef41Sopenharmony_ci    SimplifiedOperatorReducer simple_reducer(
15141cb0ef41Sopenharmony_ci        &graph_reducer, data->jsgraph(), data->broker(), BranchSemantics::kJS);
15151cb0ef41Sopenharmony_ci    CheckpointElimination checkpoint_elimination(&graph_reducer);
15161cb0ef41Sopenharmony_ci    CommonOperatorReducer common_reducer(
15171cb0ef41Sopenharmony_ci        &graph_reducer, data->graph(), data->broker(), data->common(),
15181cb0ef41Sopenharmony_ci        data->machine(), temp_zone, BranchSemantics::kJS);
15191cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &dead_code_elimination);
15201cb0ef41Sopenharmony_ci
15211cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &create_lowering);
15221cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &constant_folding_reducer);
15231cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &typed_lowering);
15241cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &typed_optimization);
15251cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &simple_reducer);
15261cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &checkpoint_elimination);
15271cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &common_reducer);
15281cb0ef41Sopenharmony_ci
15291cb0ef41Sopenharmony_ci    // ConstantFoldingReducer, JSCreateLowering, JSTypedLowering, and
15301cb0ef41Sopenharmony_ci    // TypedOptimization access the heap.
15311cb0ef41Sopenharmony_ci    UnparkedScopeIfNeeded scope(data->broker());
15321cb0ef41Sopenharmony_ci
15331cb0ef41Sopenharmony_ci    graph_reducer.ReduceGraph();
15341cb0ef41Sopenharmony_ci  }
15351cb0ef41Sopenharmony_ci};
15361cb0ef41Sopenharmony_ci
15371cb0ef41Sopenharmony_ci
15381cb0ef41Sopenharmony_cistruct EscapeAnalysisPhase {
15391cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(EscapeAnalysis)
15401cb0ef41Sopenharmony_ci
15411cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
15421cb0ef41Sopenharmony_ci    EscapeAnalysis escape_analysis(data->jsgraph(),
15431cb0ef41Sopenharmony_ci                                   &data->info()->tick_counter(), temp_zone);
15441cb0ef41Sopenharmony_ci    escape_analysis.ReduceGraph();
15451cb0ef41Sopenharmony_ci
15461cb0ef41Sopenharmony_ci    GraphReducer reducer(temp_zone, data->graph(),
15471cb0ef41Sopenharmony_ci                         &data->info()->tick_counter(), data->broker(),
15481cb0ef41Sopenharmony_ci                         data->jsgraph()->Dead(), data->observe_node_manager());
15491cb0ef41Sopenharmony_ci    EscapeAnalysisReducer escape_reducer(
15501cb0ef41Sopenharmony_ci        &reducer, data->jsgraph(), data->broker(),
15511cb0ef41Sopenharmony_ci        escape_analysis.analysis_result(), temp_zone);
15521cb0ef41Sopenharmony_ci
15531cb0ef41Sopenharmony_ci    AddReducer(data, &reducer, &escape_reducer);
15541cb0ef41Sopenharmony_ci
15551cb0ef41Sopenharmony_ci    // EscapeAnalysisReducer accesses the heap.
15561cb0ef41Sopenharmony_ci    UnparkedScopeIfNeeded scope(data->broker());
15571cb0ef41Sopenharmony_ci
15581cb0ef41Sopenharmony_ci    reducer.ReduceGraph();
15591cb0ef41Sopenharmony_ci    // TODO(turbofan): Turn this into a debug mode check once we have
15601cb0ef41Sopenharmony_ci    // confidence.
15611cb0ef41Sopenharmony_ci    escape_reducer.VerifyReplacement();
15621cb0ef41Sopenharmony_ci  }
15631cb0ef41Sopenharmony_ci};
15641cb0ef41Sopenharmony_ci
15651cb0ef41Sopenharmony_cistruct TypeAssertionsPhase {
15661cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(TypeAssertions)
15671cb0ef41Sopenharmony_ci
15681cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
15691cb0ef41Sopenharmony_ci    GraphReducer graph_reducer(
15701cb0ef41Sopenharmony_ci        temp_zone, data->graph(), &data->info()->tick_counter(), data->broker(),
15711cb0ef41Sopenharmony_ci        data->jsgraph()->Dead(), data->observe_node_manager());
15721cb0ef41Sopenharmony_ci    AddTypeAssertionsReducer type_assertions(&graph_reducer, data->jsgraph(),
15731cb0ef41Sopenharmony_ci                                             temp_zone);
15741cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &type_assertions);
15751cb0ef41Sopenharmony_ci    graph_reducer.ReduceGraph();
15761cb0ef41Sopenharmony_ci  }
15771cb0ef41Sopenharmony_ci};
15781cb0ef41Sopenharmony_ci
15791cb0ef41Sopenharmony_cistruct SimplifiedLoweringPhase {
15801cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(SimplifiedLowering)
15811cb0ef41Sopenharmony_ci
15821cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone, Linkage* linkage) {
15831cb0ef41Sopenharmony_ci    SimplifiedLowering lowering(data->jsgraph(), data->broker(), temp_zone,
15841cb0ef41Sopenharmony_ci                                data->source_positions(), data->node_origins(),
15851cb0ef41Sopenharmony_ci                                &data->info()->tick_counter(), linkage,
15861cb0ef41Sopenharmony_ci                                data->info(), data->observe_node_manager());
15871cb0ef41Sopenharmony_ci
15881cb0ef41Sopenharmony_ci    // RepresentationChanger accesses the heap.
15891cb0ef41Sopenharmony_ci    UnparkedScopeIfNeeded scope(data->broker());
15901cb0ef41Sopenharmony_ci
15911cb0ef41Sopenharmony_ci    lowering.LowerAllNodes();
15921cb0ef41Sopenharmony_ci  }
15931cb0ef41Sopenharmony_ci};
15941cb0ef41Sopenharmony_ci
15951cb0ef41Sopenharmony_cistruct LoopPeelingPhase {
15961cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(LoopPeeling)
15971cb0ef41Sopenharmony_ci
15981cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
15991cb0ef41Sopenharmony_ci    GraphTrimmer trimmer(temp_zone, data->graph());
16001cb0ef41Sopenharmony_ci    NodeVector roots(temp_zone);
16011cb0ef41Sopenharmony_ci    data->jsgraph()->GetCachedNodes(&roots);
16021cb0ef41Sopenharmony_ci    {
16031cb0ef41Sopenharmony_ci      UnparkedScopeIfNeeded scope(data->broker(), FLAG_trace_turbo_trimming);
16041cb0ef41Sopenharmony_ci      trimmer.TrimGraph(roots.begin(), roots.end());
16051cb0ef41Sopenharmony_ci    }
16061cb0ef41Sopenharmony_ci
16071cb0ef41Sopenharmony_ci    LoopTree* loop_tree = LoopFinder::BuildLoopTree(
16081cb0ef41Sopenharmony_ci        data->jsgraph()->graph(), &data->info()->tick_counter(), temp_zone);
16091cb0ef41Sopenharmony_ci    // We call the typer inside of PeelInnerLoopsOfTree which inspects heap
16101cb0ef41Sopenharmony_ci    // objects, so we need to unpark the local heap.
16111cb0ef41Sopenharmony_ci    UnparkedScopeIfNeeded scope(data->broker());
16121cb0ef41Sopenharmony_ci    LoopPeeler(data->graph(), data->common(), loop_tree, temp_zone,
16131cb0ef41Sopenharmony_ci               data->source_positions(), data->node_origins())
16141cb0ef41Sopenharmony_ci        .PeelInnerLoopsOfTree();
16151cb0ef41Sopenharmony_ci  }
16161cb0ef41Sopenharmony_ci};
16171cb0ef41Sopenharmony_ci
16181cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
16191cb0ef41Sopenharmony_cistruct WasmInliningPhase {
16201cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(WasmInlining)
16211cb0ef41Sopenharmony_ci
16221cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone, wasm::CompilationEnv* env,
16231cb0ef41Sopenharmony_ci           uint32_t function_index, const wasm::WireBytesStorage* wire_bytes,
16241cb0ef41Sopenharmony_ci           std::vector<compiler::WasmLoopInfo>* loop_info) {
16251cb0ef41Sopenharmony_ci    if (!WasmInliner::graph_size_allows_inlining(data->graph()->NodeCount())) {
16261cb0ef41Sopenharmony_ci      return;
16271cb0ef41Sopenharmony_ci    }
16281cb0ef41Sopenharmony_ci    GraphReducer graph_reducer(
16291cb0ef41Sopenharmony_ci        temp_zone, data->graph(), &data->info()->tick_counter(), data->broker(),
16301cb0ef41Sopenharmony_ci        data->jsgraph()->Dead(), data->observe_node_manager());
16311cb0ef41Sopenharmony_ci    DeadCodeElimination dead(&graph_reducer, data->graph(), data->common(),
16321cb0ef41Sopenharmony_ci                             temp_zone);
16331cb0ef41Sopenharmony_ci    std::unique_ptr<char[]> debug_name = data->info()->GetDebugName();
16341cb0ef41Sopenharmony_ci    WasmInliner inliner(&graph_reducer, env, function_index,
16351cb0ef41Sopenharmony_ci                        data->source_positions(), data->node_origins(),
16361cb0ef41Sopenharmony_ci                        data->mcgraph(), wire_bytes, loop_info,
16371cb0ef41Sopenharmony_ci                        debug_name.get());
16381cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &dead);
16391cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &inliner);
16401cb0ef41Sopenharmony_ci    graph_reducer.ReduceGraph();
16411cb0ef41Sopenharmony_ci  }
16421cb0ef41Sopenharmony_ci};
16431cb0ef41Sopenharmony_ci
16441cb0ef41Sopenharmony_cinamespace {
16451cb0ef41Sopenharmony_civoid EliminateLoopExits(std::vector<compiler::WasmLoopInfo>* loop_infos) {
16461cb0ef41Sopenharmony_ci  for (WasmLoopInfo& loop_info : *loop_infos) {
16471cb0ef41Sopenharmony_ci    std::unordered_set<Node*> loop_exits;
16481cb0ef41Sopenharmony_ci    // We collect exits into a set first because we are not allowed to mutate
16491cb0ef41Sopenharmony_ci    // them while iterating uses().
16501cb0ef41Sopenharmony_ci    for (Node* use : loop_info.header->uses()) {
16511cb0ef41Sopenharmony_ci      if (use->opcode() == IrOpcode::kLoopExit) {
16521cb0ef41Sopenharmony_ci        loop_exits.insert(use);
16531cb0ef41Sopenharmony_ci      }
16541cb0ef41Sopenharmony_ci    }
16551cb0ef41Sopenharmony_ci    for (Node* use : loop_exits) {
16561cb0ef41Sopenharmony_ci      LoopPeeler::EliminateLoopExit(use);
16571cb0ef41Sopenharmony_ci    }
16581cb0ef41Sopenharmony_ci  }
16591cb0ef41Sopenharmony_ci}
16601cb0ef41Sopenharmony_ci}  // namespace
16611cb0ef41Sopenharmony_ci
16621cb0ef41Sopenharmony_cistruct WasmLoopUnrollingPhase {
16631cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(WasmLoopUnrolling)
16641cb0ef41Sopenharmony_ci
16651cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone,
16661cb0ef41Sopenharmony_ci           std::vector<compiler::WasmLoopInfo>* loop_infos) {
16671cb0ef41Sopenharmony_ci    for (WasmLoopInfo& loop_info : *loop_infos) {
16681cb0ef41Sopenharmony_ci      if (loop_info.can_be_innermost) {
16691cb0ef41Sopenharmony_ci        ZoneUnorderedSet<Node*>* loop =
16701cb0ef41Sopenharmony_ci            LoopFinder::FindSmallInnermostLoopFromHeader(
16711cb0ef41Sopenharmony_ci                loop_info.header, temp_zone,
16721cb0ef41Sopenharmony_ci                // Only discover the loop until its size is the maximum unrolled
16731cb0ef41Sopenharmony_ci                // size for its depth.
16741cb0ef41Sopenharmony_ci                maximum_unrollable_size(loop_info.nesting_depth), true);
16751cb0ef41Sopenharmony_ci        if (loop == nullptr) continue;
16761cb0ef41Sopenharmony_ci        UnrollLoop(loop_info.header, loop, loop_info.nesting_depth,
16771cb0ef41Sopenharmony_ci                   data->graph(), data->common(), temp_zone,
16781cb0ef41Sopenharmony_ci                   data->source_positions(), data->node_origins());
16791cb0ef41Sopenharmony_ci      }
16801cb0ef41Sopenharmony_ci    }
16811cb0ef41Sopenharmony_ci
16821cb0ef41Sopenharmony_ci    EliminateLoopExits(loop_infos);
16831cb0ef41Sopenharmony_ci  }
16841cb0ef41Sopenharmony_ci};
16851cb0ef41Sopenharmony_ci
16861cb0ef41Sopenharmony_cistruct WasmLoopPeelingPhase {
16871cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(WasmLoopPeeling)
16881cb0ef41Sopenharmony_ci
16891cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone,
16901cb0ef41Sopenharmony_ci           std::vector<compiler::WasmLoopInfo>* loop_infos) {
16911cb0ef41Sopenharmony_ci    for (WasmLoopInfo& loop_info : *loop_infos) {
16921cb0ef41Sopenharmony_ci      if (loop_info.can_be_innermost) {
16931cb0ef41Sopenharmony_ci        ZoneUnorderedSet<Node*>* loop =
16941cb0ef41Sopenharmony_ci            LoopFinder::FindSmallInnermostLoopFromHeader(
16951cb0ef41Sopenharmony_ci                loop_info.header, temp_zone, std::numeric_limits<size_t>::max(),
16961cb0ef41Sopenharmony_ci                false);
16971cb0ef41Sopenharmony_ci        if (loop == nullptr) continue;
16981cb0ef41Sopenharmony_ci        PeelWasmLoop(loop_info.header, loop, data->graph(), data->common(),
16991cb0ef41Sopenharmony_ci                     temp_zone, data->source_positions(), data->node_origins());
17001cb0ef41Sopenharmony_ci      }
17011cb0ef41Sopenharmony_ci    }
17021cb0ef41Sopenharmony_ci    // If we are going to unroll later, keep loop exits.
17031cb0ef41Sopenharmony_ci    if (!FLAG_wasm_loop_unrolling) EliminateLoopExits(loop_infos);
17041cb0ef41Sopenharmony_ci  }
17051cb0ef41Sopenharmony_ci};
17061cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
17071cb0ef41Sopenharmony_ci
17081cb0ef41Sopenharmony_cistruct LoopExitEliminationPhase {
17091cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(LoopExitElimination)
17101cb0ef41Sopenharmony_ci
17111cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
17121cb0ef41Sopenharmony_ci    LoopPeeler::EliminateLoopExits(data->graph(), temp_zone);
17131cb0ef41Sopenharmony_ci  }
17141cb0ef41Sopenharmony_ci};
17151cb0ef41Sopenharmony_ci
17161cb0ef41Sopenharmony_cistruct GenericLoweringPhase {
17171cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(GenericLowering)
17181cb0ef41Sopenharmony_ci
17191cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
17201cb0ef41Sopenharmony_ci    GraphReducer graph_reducer(
17211cb0ef41Sopenharmony_ci        temp_zone, data->graph(), &data->info()->tick_counter(), data->broker(),
17221cb0ef41Sopenharmony_ci        data->jsgraph()->Dead(), data->observe_node_manager());
17231cb0ef41Sopenharmony_ci    JSGenericLowering generic_lowering(data->jsgraph(), &graph_reducer,
17241cb0ef41Sopenharmony_ci                                       data->broker());
17251cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &generic_lowering);
17261cb0ef41Sopenharmony_ci
17271cb0ef41Sopenharmony_ci    // JSGEnericLowering accesses the heap due to ObjectRef's type checks.
17281cb0ef41Sopenharmony_ci    UnparkedScopeIfNeeded scope(data->broker());
17291cb0ef41Sopenharmony_ci
17301cb0ef41Sopenharmony_ci    graph_reducer.ReduceGraph();
17311cb0ef41Sopenharmony_ci  }
17321cb0ef41Sopenharmony_ci};
17331cb0ef41Sopenharmony_ci
17341cb0ef41Sopenharmony_cistruct EarlyOptimizationPhase {
17351cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(EarlyOptimization)
17361cb0ef41Sopenharmony_ci
17371cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
17381cb0ef41Sopenharmony_ci    GraphReducer graph_reducer(
17391cb0ef41Sopenharmony_ci        temp_zone, data->graph(), &data->info()->tick_counter(), data->broker(),
17401cb0ef41Sopenharmony_ci        data->jsgraph()->Dead(), data->observe_node_manager());
17411cb0ef41Sopenharmony_ci    DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
17421cb0ef41Sopenharmony_ci                                              data->common(), temp_zone);
17431cb0ef41Sopenharmony_ci    SimplifiedOperatorReducer simple_reducer(&graph_reducer, data->jsgraph(),
17441cb0ef41Sopenharmony_ci                                             data->broker(),
17451cb0ef41Sopenharmony_ci                                             BranchSemantics::kMachine);
17461cb0ef41Sopenharmony_ci    RedundancyElimination redundancy_elimination(&graph_reducer, temp_zone);
17471cb0ef41Sopenharmony_ci    ValueNumberingReducer value_numbering(temp_zone, data->graph()->zone());
17481cb0ef41Sopenharmony_ci    MachineOperatorReducer machine_reducer(&graph_reducer, data->jsgraph());
17491cb0ef41Sopenharmony_ci    CommonOperatorReducer common_reducer(
17501cb0ef41Sopenharmony_ci        &graph_reducer, data->graph(), data->broker(), data->common(),
17511cb0ef41Sopenharmony_ci        data->machine(), temp_zone, BranchSemantics::kMachine);
17521cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &dead_code_elimination);
17531cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &simple_reducer);
17541cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &redundancy_elimination);
17551cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &machine_reducer);
17561cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &common_reducer);
17571cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &value_numbering);
17581cb0ef41Sopenharmony_ci    graph_reducer.ReduceGraph();
17591cb0ef41Sopenharmony_ci  }
17601cb0ef41Sopenharmony_ci};
17611cb0ef41Sopenharmony_ci
17621cb0ef41Sopenharmony_cistruct ControlFlowOptimizationPhase {
17631cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(ControlFlowOptimization)
17641cb0ef41Sopenharmony_ci
17651cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
17661cb0ef41Sopenharmony_ci    ControlFlowOptimizer optimizer(data->graph(), data->common(),
17671cb0ef41Sopenharmony_ci                                   data->machine(),
17681cb0ef41Sopenharmony_ci                                   &data->info()->tick_counter(), temp_zone);
17691cb0ef41Sopenharmony_ci    optimizer.Optimize();
17701cb0ef41Sopenharmony_ci  }
17711cb0ef41Sopenharmony_ci};
17721cb0ef41Sopenharmony_ci
17731cb0ef41Sopenharmony_cistruct EffectControlLinearizationPhase {
17741cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(EffectLinearization)
17751cb0ef41Sopenharmony_ci
17761cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
17771cb0ef41Sopenharmony_ci    {
17781cb0ef41Sopenharmony_ci      // Branch cloning in the effect control linearizer requires the graphs to
17791cb0ef41Sopenharmony_ci      // be trimmed, so trim now before scheduling.
17801cb0ef41Sopenharmony_ci      GraphTrimmer trimmer(temp_zone, data->graph());
17811cb0ef41Sopenharmony_ci      NodeVector roots(temp_zone);
17821cb0ef41Sopenharmony_ci      data->jsgraph()->GetCachedNodes(&roots);
17831cb0ef41Sopenharmony_ci      {
17841cb0ef41Sopenharmony_ci        UnparkedScopeIfNeeded scope(data->broker(), FLAG_trace_turbo_trimming);
17851cb0ef41Sopenharmony_ci        trimmer.TrimGraph(roots.begin(), roots.end());
17861cb0ef41Sopenharmony_ci      }
17871cb0ef41Sopenharmony_ci
17881cb0ef41Sopenharmony_ci      // Schedule the graph without node splitting so that we can
17891cb0ef41Sopenharmony_ci      // fix the effect and control flow for nodes with low-level side
17901cb0ef41Sopenharmony_ci      // effects (such as changing representation to tagged or
17911cb0ef41Sopenharmony_ci      // 'floating' allocation regions.)
17921cb0ef41Sopenharmony_ci      Schedule* schedule = Scheduler::ComputeSchedule(
17931cb0ef41Sopenharmony_ci          temp_zone, data->graph(), Scheduler::kTempSchedule,
17941cb0ef41Sopenharmony_ci          &data->info()->tick_counter(), data->profile_data());
17951cb0ef41Sopenharmony_ci      TraceScheduleAndVerify(data->info(), data, schedule,
17961cb0ef41Sopenharmony_ci                             "effect linearization schedule");
17971cb0ef41Sopenharmony_ci
17981cb0ef41Sopenharmony_ci      // Post-pass for wiring the control/effects
17991cb0ef41Sopenharmony_ci      // - connect allocating representation changes into the control&effect
18001cb0ef41Sopenharmony_ci      //   chains and lower them,
18011cb0ef41Sopenharmony_ci      // - get rid of the region markers,
18021cb0ef41Sopenharmony_ci      // - introduce effect phis and rewire effects to get SSA again.
18031cb0ef41Sopenharmony_ci      LinearizeEffectControl(data->jsgraph(), schedule, temp_zone,
18041cb0ef41Sopenharmony_ci                             data->source_positions(), data->node_origins(),
18051cb0ef41Sopenharmony_ci                             data->broker());
18061cb0ef41Sopenharmony_ci    }
18071cb0ef41Sopenharmony_ci    {
18081cb0ef41Sopenharmony_ci      // The {EffectControlLinearizer} might leave {Dead} nodes behind, so we
18091cb0ef41Sopenharmony_ci      // run {DeadCodeElimination} to prune these parts of the graph.
18101cb0ef41Sopenharmony_ci      // Also, the following store-store elimination phase greatly benefits from
18111cb0ef41Sopenharmony_ci      // doing a common operator reducer and dead code elimination just before
18121cb0ef41Sopenharmony_ci      // it, to eliminate conditional deopts with a constant condition.
18131cb0ef41Sopenharmony_ci      GraphReducer graph_reducer(temp_zone, data->graph(),
18141cb0ef41Sopenharmony_ci                                 &data->info()->tick_counter(), data->broker(),
18151cb0ef41Sopenharmony_ci                                 data->jsgraph()->Dead(),
18161cb0ef41Sopenharmony_ci                                 data->observe_node_manager());
18171cb0ef41Sopenharmony_ci      DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
18181cb0ef41Sopenharmony_ci                                                data->common(), temp_zone);
18191cb0ef41Sopenharmony_ci      CommonOperatorReducer common_reducer(
18201cb0ef41Sopenharmony_ci          &graph_reducer, data->graph(), data->broker(), data->common(),
18211cb0ef41Sopenharmony_ci          data->machine(), temp_zone, BranchSemantics::kMachine);
18221cb0ef41Sopenharmony_ci      AddReducer(data, &graph_reducer, &dead_code_elimination);
18231cb0ef41Sopenharmony_ci      AddReducer(data, &graph_reducer, &common_reducer);
18241cb0ef41Sopenharmony_ci      graph_reducer.ReduceGraph();
18251cb0ef41Sopenharmony_ci    }
18261cb0ef41Sopenharmony_ci  }
18271cb0ef41Sopenharmony_ci};
18281cb0ef41Sopenharmony_ci
18291cb0ef41Sopenharmony_cistruct StoreStoreEliminationPhase {
18301cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(StoreStoreElimination)
18311cb0ef41Sopenharmony_ci
18321cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
18331cb0ef41Sopenharmony_ci    GraphTrimmer trimmer(temp_zone, data->graph());
18341cb0ef41Sopenharmony_ci    NodeVector roots(temp_zone);
18351cb0ef41Sopenharmony_ci    data->jsgraph()->GetCachedNodes(&roots);
18361cb0ef41Sopenharmony_ci    {
18371cb0ef41Sopenharmony_ci      UnparkedScopeIfNeeded scope(data->broker(), FLAG_trace_turbo_trimming);
18381cb0ef41Sopenharmony_ci      trimmer.TrimGraph(roots.begin(), roots.end());
18391cb0ef41Sopenharmony_ci    }
18401cb0ef41Sopenharmony_ci
18411cb0ef41Sopenharmony_ci    StoreStoreElimination::Run(data->jsgraph(), &data->info()->tick_counter(),
18421cb0ef41Sopenharmony_ci                               temp_zone);
18431cb0ef41Sopenharmony_ci  }
18441cb0ef41Sopenharmony_ci};
18451cb0ef41Sopenharmony_ci
18461cb0ef41Sopenharmony_cistruct LoadEliminationPhase {
18471cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(LoadElimination)
18481cb0ef41Sopenharmony_ci
18491cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
18501cb0ef41Sopenharmony_ci    GraphReducer graph_reducer(
18511cb0ef41Sopenharmony_ci        temp_zone, data->graph(), &data->info()->tick_counter(), data->broker(),
18521cb0ef41Sopenharmony_ci        data->jsgraph()->Dead(), data->observe_node_manager());
18531cb0ef41Sopenharmony_ci    BranchElimination branch_condition_elimination(
18541cb0ef41Sopenharmony_ci        &graph_reducer, data->jsgraph(), temp_zone, data->source_positions(),
18551cb0ef41Sopenharmony_ci        BranchElimination::kEARLY);
18561cb0ef41Sopenharmony_ci    DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
18571cb0ef41Sopenharmony_ci                                              data->common(), temp_zone);
18581cb0ef41Sopenharmony_ci    RedundancyElimination redundancy_elimination(&graph_reducer, temp_zone);
18591cb0ef41Sopenharmony_ci    LoadElimination load_elimination(&graph_reducer, data->jsgraph(),
18601cb0ef41Sopenharmony_ci                                     temp_zone);
18611cb0ef41Sopenharmony_ci    CheckpointElimination checkpoint_elimination(&graph_reducer);
18621cb0ef41Sopenharmony_ci    ValueNumberingReducer value_numbering(temp_zone, data->graph()->zone());
18631cb0ef41Sopenharmony_ci    CommonOperatorReducer common_reducer(
18641cb0ef41Sopenharmony_ci        &graph_reducer, data->graph(), data->broker(), data->common(),
18651cb0ef41Sopenharmony_ci        data->machine(), temp_zone, BranchSemantics::kJS);
18661cb0ef41Sopenharmony_ci    TypedOptimization typed_optimization(&graph_reducer, data->dependencies(),
18671cb0ef41Sopenharmony_ci                                         data->jsgraph(), data->broker());
18681cb0ef41Sopenharmony_ci    ConstantFoldingReducer constant_folding_reducer(
18691cb0ef41Sopenharmony_ci        &graph_reducer, data->jsgraph(), data->broker());
18701cb0ef41Sopenharmony_ci    TypeNarrowingReducer type_narrowing_reducer(&graph_reducer, data->jsgraph(),
18711cb0ef41Sopenharmony_ci                                                data->broker());
18721cb0ef41Sopenharmony_ci
18731cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &branch_condition_elimination);
18741cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &dead_code_elimination);
18751cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &redundancy_elimination);
18761cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &load_elimination);
18771cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &type_narrowing_reducer);
18781cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &constant_folding_reducer);
18791cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &typed_optimization);
18801cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &checkpoint_elimination);
18811cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &common_reducer);
18821cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &value_numbering);
18831cb0ef41Sopenharmony_ci
18841cb0ef41Sopenharmony_ci    // ConstantFoldingReducer and TypedOptimization access the heap.
18851cb0ef41Sopenharmony_ci    UnparkedScopeIfNeeded scope(data->broker());
18861cb0ef41Sopenharmony_ci
18871cb0ef41Sopenharmony_ci    graph_reducer.ReduceGraph();
18881cb0ef41Sopenharmony_ci  }
18891cb0ef41Sopenharmony_ci};
18901cb0ef41Sopenharmony_ci
18911cb0ef41Sopenharmony_cistruct MemoryOptimizationPhase {
18921cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(MemoryOptimization)
18931cb0ef41Sopenharmony_ci
18941cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
18951cb0ef41Sopenharmony_ci    // The memory optimizer requires the graphs to be trimmed, so trim now.
18961cb0ef41Sopenharmony_ci    GraphTrimmer trimmer(temp_zone, data->graph());
18971cb0ef41Sopenharmony_ci    NodeVector roots(temp_zone);
18981cb0ef41Sopenharmony_ci    data->jsgraph()->GetCachedNodes(&roots);
18991cb0ef41Sopenharmony_ci    {
19001cb0ef41Sopenharmony_ci      UnparkedScopeIfNeeded scope(data->broker(), FLAG_trace_turbo_trimming);
19011cb0ef41Sopenharmony_ci      trimmer.TrimGraph(roots.begin(), roots.end());
19021cb0ef41Sopenharmony_ci    }
19031cb0ef41Sopenharmony_ci
19041cb0ef41Sopenharmony_ci    // Optimize allocations and load/store operations.
19051cb0ef41Sopenharmony_ci    MemoryOptimizer optimizer(
19061cb0ef41Sopenharmony_ci        data->jsgraph(), temp_zone,
19071cb0ef41Sopenharmony_ci        data->info()->allocation_folding()
19081cb0ef41Sopenharmony_ci            ? MemoryLowering::AllocationFolding::kDoAllocationFolding
19091cb0ef41Sopenharmony_ci            : MemoryLowering::AllocationFolding::kDontAllocationFolding,
19101cb0ef41Sopenharmony_ci        data->debug_name(), &data->info()->tick_counter());
19111cb0ef41Sopenharmony_ci    optimizer.Optimize();
19121cb0ef41Sopenharmony_ci  }
19131cb0ef41Sopenharmony_ci};
19141cb0ef41Sopenharmony_ci
19151cb0ef41Sopenharmony_cistruct LateOptimizationPhase {
19161cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(LateOptimization)
19171cb0ef41Sopenharmony_ci
19181cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
19191cb0ef41Sopenharmony_ci    GraphReducer graph_reducer(
19201cb0ef41Sopenharmony_ci        temp_zone, data->graph(), &data->info()->tick_counter(), data->broker(),
19211cb0ef41Sopenharmony_ci        data->jsgraph()->Dead(), data->observe_node_manager());
19221cb0ef41Sopenharmony_ci    BranchElimination branch_condition_elimination(
19231cb0ef41Sopenharmony_ci        &graph_reducer, data->jsgraph(), temp_zone, data->source_positions());
19241cb0ef41Sopenharmony_ci    DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
19251cb0ef41Sopenharmony_ci                                              data->common(), temp_zone);
19261cb0ef41Sopenharmony_ci    ValueNumberingReducer value_numbering(temp_zone, data->graph()->zone());
19271cb0ef41Sopenharmony_ci    MachineOperatorReducer machine_reducer(&graph_reducer, data->jsgraph());
19281cb0ef41Sopenharmony_ci    CommonOperatorReducer common_reducer(
19291cb0ef41Sopenharmony_ci        &graph_reducer, data->graph(), data->broker(), data->common(),
19301cb0ef41Sopenharmony_ci        data->machine(), temp_zone, BranchSemantics::kMachine);
19311cb0ef41Sopenharmony_ci    JSGraphAssembler graph_assembler(data->jsgraph(), temp_zone);
19321cb0ef41Sopenharmony_ci    SelectLowering select_lowering(&graph_assembler, data->graph());
19331cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &branch_condition_elimination);
19341cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &dead_code_elimination);
19351cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &machine_reducer);
19361cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &common_reducer);
19371cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &select_lowering);
19381cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &value_numbering);
19391cb0ef41Sopenharmony_ci    graph_reducer.ReduceGraph();
19401cb0ef41Sopenharmony_ci  }
19411cb0ef41Sopenharmony_ci};
19421cb0ef41Sopenharmony_ci
19431cb0ef41Sopenharmony_cistruct MachineOperatorOptimizationPhase {
19441cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(MachineOperatorOptimization)
19451cb0ef41Sopenharmony_ci
19461cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
19471cb0ef41Sopenharmony_ci    GraphReducer graph_reducer(
19481cb0ef41Sopenharmony_ci        temp_zone, data->graph(), &data->info()->tick_counter(), data->broker(),
19491cb0ef41Sopenharmony_ci        data->jsgraph()->Dead(), data->observe_node_manager());
19501cb0ef41Sopenharmony_ci    ValueNumberingReducer value_numbering(temp_zone, data->graph()->zone());
19511cb0ef41Sopenharmony_ci    MachineOperatorReducer machine_reducer(&graph_reducer, data->jsgraph());
19521cb0ef41Sopenharmony_ci
19531cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &machine_reducer);
19541cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &value_numbering);
19551cb0ef41Sopenharmony_ci    graph_reducer.ReduceGraph();
19561cb0ef41Sopenharmony_ci  }
19571cb0ef41Sopenharmony_ci};
19581cb0ef41Sopenharmony_ci
19591cb0ef41Sopenharmony_cistruct WasmBaseOptimizationPhase {
19601cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(WasmBaseOptimization)
19611cb0ef41Sopenharmony_ci
19621cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
19631cb0ef41Sopenharmony_ci    GraphReducer graph_reducer(
19641cb0ef41Sopenharmony_ci        temp_zone, data->graph(), &data->info()->tick_counter(), data->broker(),
19651cb0ef41Sopenharmony_ci        data->mcgraph()->Dead(), data->observe_node_manager());
19661cb0ef41Sopenharmony_ci    ValueNumberingReducer value_numbering(temp_zone, data->graph()->zone());
19671cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &value_numbering);
19681cb0ef41Sopenharmony_ci    graph_reducer.ReduceGraph();
19691cb0ef41Sopenharmony_ci  }
19701cb0ef41Sopenharmony_ci};
19711cb0ef41Sopenharmony_ci
19721cb0ef41Sopenharmony_cistruct DecompressionOptimizationPhase {
19731cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(DecompressionOptimization)
19741cb0ef41Sopenharmony_ci
19751cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
19761cb0ef41Sopenharmony_ci    if (COMPRESS_POINTERS_BOOL) {
19771cb0ef41Sopenharmony_ci      DecompressionOptimizer decompression_optimizer(
19781cb0ef41Sopenharmony_ci          temp_zone, data->graph(), data->common(), data->machine());
19791cb0ef41Sopenharmony_ci      decompression_optimizer.Reduce();
19801cb0ef41Sopenharmony_ci    }
19811cb0ef41Sopenharmony_ci  }
19821cb0ef41Sopenharmony_ci};
19831cb0ef41Sopenharmony_ci
19841cb0ef41Sopenharmony_cistruct BranchConditionDuplicationPhase {
19851cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(BranchConditionDuplication)
19861cb0ef41Sopenharmony_ci
19871cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
19881cb0ef41Sopenharmony_ci    BranchConditionDuplicator compare_zero_branch_optimizer(temp_zone,
19891cb0ef41Sopenharmony_ci                                                            data->graph());
19901cb0ef41Sopenharmony_ci    compare_zero_branch_optimizer.Reduce();
19911cb0ef41Sopenharmony_ci  }
19921cb0ef41Sopenharmony_ci};
19931cb0ef41Sopenharmony_ci
19941cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
19951cb0ef41Sopenharmony_cistruct WasmOptimizationPhase {
19961cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(WasmOptimization)
19971cb0ef41Sopenharmony_ci
19981cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone, bool allow_signalling_nan) {
19991cb0ef41Sopenharmony_ci    // Run optimizations in two rounds: First one around load elimination and
20001cb0ef41Sopenharmony_ci    // then one around branch elimination. This is because those two
20011cb0ef41Sopenharmony_ci    // optimizations sometimes display quadratic complexity when run together.
20021cb0ef41Sopenharmony_ci    // We only need load elimination for managed objects.
20031cb0ef41Sopenharmony_ci    if (FLAG_experimental_wasm_gc || FLAG_wasm_inlining) {
20041cb0ef41Sopenharmony_ci      GraphReducer graph_reducer(temp_zone, data->graph(),
20051cb0ef41Sopenharmony_ci                                 &data->info()->tick_counter(), data->broker(),
20061cb0ef41Sopenharmony_ci                                 data->jsgraph()->Dead(),
20071cb0ef41Sopenharmony_ci                                 data->observe_node_manager());
20081cb0ef41Sopenharmony_ci      MachineOperatorReducer machine_reducer(&graph_reducer, data->jsgraph(),
20091cb0ef41Sopenharmony_ci                                             allow_signalling_nan);
20101cb0ef41Sopenharmony_ci      DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
20111cb0ef41Sopenharmony_ci                                                data->common(), temp_zone);
20121cb0ef41Sopenharmony_ci      CommonOperatorReducer common_reducer(
20131cb0ef41Sopenharmony_ci          &graph_reducer, data->graph(), data->broker(), data->common(),
20141cb0ef41Sopenharmony_ci          data->machine(), temp_zone, BranchSemantics::kMachine);
20151cb0ef41Sopenharmony_ci      ValueNumberingReducer value_numbering(temp_zone, data->graph()->zone());
20161cb0ef41Sopenharmony_ci      CsaLoadElimination load_elimination(&graph_reducer, data->jsgraph(),
20171cb0ef41Sopenharmony_ci                                          temp_zone);
20181cb0ef41Sopenharmony_ci      WasmEscapeAnalysis escape(&graph_reducer, data->mcgraph());
20191cb0ef41Sopenharmony_ci      AddReducer(data, &graph_reducer, &machine_reducer);
20201cb0ef41Sopenharmony_ci      AddReducer(data, &graph_reducer, &dead_code_elimination);
20211cb0ef41Sopenharmony_ci      AddReducer(data, &graph_reducer, &common_reducer);
20221cb0ef41Sopenharmony_ci      AddReducer(data, &graph_reducer, &value_numbering);
20231cb0ef41Sopenharmony_ci      if (FLAG_experimental_wasm_gc) {
20241cb0ef41Sopenharmony_ci        AddReducer(data, &graph_reducer, &load_elimination);
20251cb0ef41Sopenharmony_ci        AddReducer(data, &graph_reducer, &escape);
20261cb0ef41Sopenharmony_ci      }
20271cb0ef41Sopenharmony_ci      graph_reducer.ReduceGraph();
20281cb0ef41Sopenharmony_ci    }
20291cb0ef41Sopenharmony_ci    {
20301cb0ef41Sopenharmony_ci      GraphReducer graph_reducer(temp_zone, data->graph(),
20311cb0ef41Sopenharmony_ci                                 &data->info()->tick_counter(), data->broker(),
20321cb0ef41Sopenharmony_ci                                 data->jsgraph()->Dead(),
20331cb0ef41Sopenharmony_ci                                 data->observe_node_manager());
20341cb0ef41Sopenharmony_ci      MachineOperatorReducer machine_reducer(&graph_reducer, data->jsgraph(),
20351cb0ef41Sopenharmony_ci                                             allow_signalling_nan);
20361cb0ef41Sopenharmony_ci      DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
20371cb0ef41Sopenharmony_ci                                                data->common(), temp_zone);
20381cb0ef41Sopenharmony_ci      CommonOperatorReducer common_reducer(
20391cb0ef41Sopenharmony_ci          &graph_reducer, data->graph(), data->broker(), data->common(),
20401cb0ef41Sopenharmony_ci          data->machine(), temp_zone, BranchSemantics::kMachine);
20411cb0ef41Sopenharmony_ci      ValueNumberingReducer value_numbering(temp_zone, data->graph()->zone());
20421cb0ef41Sopenharmony_ci      BranchElimination branch_condition_elimination(
20431cb0ef41Sopenharmony_ci          &graph_reducer, data->jsgraph(), temp_zone, data->source_positions());
20441cb0ef41Sopenharmony_ci      AddReducer(data, &graph_reducer, &machine_reducer);
20451cb0ef41Sopenharmony_ci      AddReducer(data, &graph_reducer, &dead_code_elimination);
20461cb0ef41Sopenharmony_ci      AddReducer(data, &graph_reducer, &common_reducer);
20471cb0ef41Sopenharmony_ci      AddReducer(data, &graph_reducer, &value_numbering);
20481cb0ef41Sopenharmony_ci      AddReducer(data, &graph_reducer, &branch_condition_elimination);
20491cb0ef41Sopenharmony_ci      graph_reducer.ReduceGraph();
20501cb0ef41Sopenharmony_ci    }
20511cb0ef41Sopenharmony_ci  }
20521cb0ef41Sopenharmony_ci};
20531cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
20541cb0ef41Sopenharmony_ci
20551cb0ef41Sopenharmony_cistruct CsaEarlyOptimizationPhase {
20561cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(CSAEarlyOptimization)
20571cb0ef41Sopenharmony_ci
20581cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
20591cb0ef41Sopenharmony_ci    // Run optimizations in two rounds: First one around load elimination and
20601cb0ef41Sopenharmony_ci    // then one around branch elimination. This is because those two
20611cb0ef41Sopenharmony_ci    // optimizations sometimes display quadratic complexity when run together.
20621cb0ef41Sopenharmony_ci    {
20631cb0ef41Sopenharmony_ci      GraphReducer graph_reducer(temp_zone, data->graph(),
20641cb0ef41Sopenharmony_ci                                 &data->info()->tick_counter(), data->broker(),
20651cb0ef41Sopenharmony_ci                                 data->jsgraph()->Dead(),
20661cb0ef41Sopenharmony_ci                                 data->observe_node_manager());
20671cb0ef41Sopenharmony_ci      MachineOperatorReducer machine_reducer(&graph_reducer, data->jsgraph(),
20681cb0ef41Sopenharmony_ci                                             true);
20691cb0ef41Sopenharmony_ci      DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
20701cb0ef41Sopenharmony_ci                                                data->common(), temp_zone);
20711cb0ef41Sopenharmony_ci      CommonOperatorReducer common_reducer(
20721cb0ef41Sopenharmony_ci          &graph_reducer, data->graph(), data->broker(), data->common(),
20731cb0ef41Sopenharmony_ci          data->machine(), temp_zone, BranchSemantics::kMachine);
20741cb0ef41Sopenharmony_ci      ValueNumberingReducer value_numbering(temp_zone, data->graph()->zone());
20751cb0ef41Sopenharmony_ci      CsaLoadElimination load_elimination(&graph_reducer, data->jsgraph(),
20761cb0ef41Sopenharmony_ci                                          temp_zone);
20771cb0ef41Sopenharmony_ci      AddReducer(data, &graph_reducer, &machine_reducer);
20781cb0ef41Sopenharmony_ci      AddReducer(data, &graph_reducer, &dead_code_elimination);
20791cb0ef41Sopenharmony_ci      AddReducer(data, &graph_reducer, &common_reducer);
20801cb0ef41Sopenharmony_ci      AddReducer(data, &graph_reducer, &value_numbering);
20811cb0ef41Sopenharmony_ci      AddReducer(data, &graph_reducer, &load_elimination);
20821cb0ef41Sopenharmony_ci      graph_reducer.ReduceGraph();
20831cb0ef41Sopenharmony_ci    }
20841cb0ef41Sopenharmony_ci    {
20851cb0ef41Sopenharmony_ci      GraphReducer graph_reducer(temp_zone, data->graph(),
20861cb0ef41Sopenharmony_ci                                 &data->info()->tick_counter(), data->broker(),
20871cb0ef41Sopenharmony_ci                                 data->jsgraph()->Dead(),
20881cb0ef41Sopenharmony_ci                                 data->observe_node_manager());
20891cb0ef41Sopenharmony_ci      MachineOperatorReducer machine_reducer(&graph_reducer, data->jsgraph(),
20901cb0ef41Sopenharmony_ci                                             true);
20911cb0ef41Sopenharmony_ci      DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
20921cb0ef41Sopenharmony_ci                                                data->common(), temp_zone);
20931cb0ef41Sopenharmony_ci      CommonOperatorReducer common_reducer(
20941cb0ef41Sopenharmony_ci          &graph_reducer, data->graph(), data->broker(), data->common(),
20951cb0ef41Sopenharmony_ci          data->machine(), temp_zone, BranchSemantics::kMachine);
20961cb0ef41Sopenharmony_ci      ValueNumberingReducer value_numbering(temp_zone, data->graph()->zone());
20971cb0ef41Sopenharmony_ci      BranchElimination branch_condition_elimination(
20981cb0ef41Sopenharmony_ci          &graph_reducer, data->jsgraph(), temp_zone, data->source_positions());
20991cb0ef41Sopenharmony_ci      AddReducer(data, &graph_reducer, &machine_reducer);
21001cb0ef41Sopenharmony_ci      AddReducer(data, &graph_reducer, &dead_code_elimination);
21011cb0ef41Sopenharmony_ci      AddReducer(data, &graph_reducer, &common_reducer);
21021cb0ef41Sopenharmony_ci      AddReducer(data, &graph_reducer, &value_numbering);
21031cb0ef41Sopenharmony_ci      AddReducer(data, &graph_reducer, &branch_condition_elimination);
21041cb0ef41Sopenharmony_ci      graph_reducer.ReduceGraph();
21051cb0ef41Sopenharmony_ci    }
21061cb0ef41Sopenharmony_ci  }
21071cb0ef41Sopenharmony_ci};
21081cb0ef41Sopenharmony_ci
21091cb0ef41Sopenharmony_cistruct CsaOptimizationPhase {
21101cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(CSAOptimization)
21111cb0ef41Sopenharmony_ci
21121cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone, bool allow_signalling_nan) {
21131cb0ef41Sopenharmony_ci    GraphReducer graph_reducer(
21141cb0ef41Sopenharmony_ci        temp_zone, data->graph(), &data->info()->tick_counter(), data->broker(),
21151cb0ef41Sopenharmony_ci        data->jsgraph()->Dead(), data->observe_node_manager());
21161cb0ef41Sopenharmony_ci    BranchElimination branch_condition_elimination(
21171cb0ef41Sopenharmony_ci        &graph_reducer, data->jsgraph(), temp_zone, data->source_positions());
21181cb0ef41Sopenharmony_ci    DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
21191cb0ef41Sopenharmony_ci                                              data->common(), temp_zone);
21201cb0ef41Sopenharmony_ci    MachineOperatorReducer machine_reducer(&graph_reducer, data->jsgraph(),
21211cb0ef41Sopenharmony_ci                                           allow_signalling_nan);
21221cb0ef41Sopenharmony_ci    CommonOperatorReducer common_reducer(
21231cb0ef41Sopenharmony_ci        &graph_reducer, data->graph(), data->broker(), data->common(),
21241cb0ef41Sopenharmony_ci        data->machine(), temp_zone, BranchSemantics::kMachine);
21251cb0ef41Sopenharmony_ci    ValueNumberingReducer value_numbering(temp_zone, data->graph()->zone());
21261cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &branch_condition_elimination);
21271cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &dead_code_elimination);
21281cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &machine_reducer);
21291cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &common_reducer);
21301cb0ef41Sopenharmony_ci    AddReducer(data, &graph_reducer, &value_numbering);
21311cb0ef41Sopenharmony_ci    graph_reducer.ReduceGraph();
21321cb0ef41Sopenharmony_ci  }
21331cb0ef41Sopenharmony_ci};
21341cb0ef41Sopenharmony_ci
21351cb0ef41Sopenharmony_cistruct ComputeSchedulePhase {
21361cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(Scheduling)
21371cb0ef41Sopenharmony_ci
21381cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
21391cb0ef41Sopenharmony_ci    Schedule* schedule = Scheduler::ComputeSchedule(
21401cb0ef41Sopenharmony_ci        temp_zone, data->graph(),
21411cb0ef41Sopenharmony_ci        data->info()->splitting() ? Scheduler::kSplitNodes
21421cb0ef41Sopenharmony_ci                                  : Scheduler::kNoFlags,
21431cb0ef41Sopenharmony_ci        &data->info()->tick_counter(), data->profile_data());
21441cb0ef41Sopenharmony_ci    data->set_schedule(schedule);
21451cb0ef41Sopenharmony_ci  }
21461cb0ef41Sopenharmony_ci};
21471cb0ef41Sopenharmony_ci
21481cb0ef41Sopenharmony_cistruct InstructionRangesAsJSON {
21491cb0ef41Sopenharmony_ci  const InstructionSequence* sequence;
21501cb0ef41Sopenharmony_ci  const ZoneVector<std::pair<int, int>>* instr_origins;
21511cb0ef41Sopenharmony_ci};
21521cb0ef41Sopenharmony_ci
21531cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream& out, const InstructionRangesAsJSON& s) {
21541cb0ef41Sopenharmony_ci  const int max = static_cast<int>(s.sequence->LastInstructionIndex());
21551cb0ef41Sopenharmony_ci
21561cb0ef41Sopenharmony_ci  out << ", \"nodeIdToInstructionRange\": {";
21571cb0ef41Sopenharmony_ci  bool need_comma = false;
21581cb0ef41Sopenharmony_ci  for (size_t i = 0; i < s.instr_origins->size(); ++i) {
21591cb0ef41Sopenharmony_ci    std::pair<int, int> offset = (*s.instr_origins)[i];
21601cb0ef41Sopenharmony_ci    if (offset.first == -1) continue;
21611cb0ef41Sopenharmony_ci    const int first = max - offset.first + 1;
21621cb0ef41Sopenharmony_ci    const int second = max - offset.second + 1;
21631cb0ef41Sopenharmony_ci    if (need_comma) out << ", ";
21641cb0ef41Sopenharmony_ci    out << "\"" << i << "\": [" << first << ", " << second << "]";
21651cb0ef41Sopenharmony_ci    need_comma = true;
21661cb0ef41Sopenharmony_ci  }
21671cb0ef41Sopenharmony_ci  out << "}";
21681cb0ef41Sopenharmony_ci  out << ", \"blockIdtoInstructionRange\": {";
21691cb0ef41Sopenharmony_ci  need_comma = false;
21701cb0ef41Sopenharmony_ci  for (auto block : s.sequence->instruction_blocks()) {
21711cb0ef41Sopenharmony_ci    if (need_comma) out << ", ";
21721cb0ef41Sopenharmony_ci    out << "\"" << block->rpo_number() << "\": [" << block->code_start() << ", "
21731cb0ef41Sopenharmony_ci        << block->code_end() << "]";
21741cb0ef41Sopenharmony_ci    need_comma = true;
21751cb0ef41Sopenharmony_ci  }
21761cb0ef41Sopenharmony_ci  out << "}";
21771cb0ef41Sopenharmony_ci  return out;
21781cb0ef41Sopenharmony_ci}
21791cb0ef41Sopenharmony_ci
21801cb0ef41Sopenharmony_cistruct InstructionSelectionPhase {
21811cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(SelectInstructions)
21821cb0ef41Sopenharmony_ci
21831cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone, Linkage* linkage) {
21841cb0ef41Sopenharmony_ci    InstructionSelector selector(
21851cb0ef41Sopenharmony_ci        temp_zone, data->graph()->NodeCount(), linkage, data->sequence(),
21861cb0ef41Sopenharmony_ci        data->schedule(), data->source_positions(), data->frame(),
21871cb0ef41Sopenharmony_ci        data->info()->switch_jump_table()
21881cb0ef41Sopenharmony_ci            ? InstructionSelector::kEnableSwitchJumpTable
21891cb0ef41Sopenharmony_ci            : InstructionSelector::kDisableSwitchJumpTable,
21901cb0ef41Sopenharmony_ci        &data->info()->tick_counter(), data->broker(),
21911cb0ef41Sopenharmony_ci        data->address_of_max_unoptimized_frame_height(),
21921cb0ef41Sopenharmony_ci        data->address_of_max_pushed_argument_count(),
21931cb0ef41Sopenharmony_ci        data->info()->source_positions()
21941cb0ef41Sopenharmony_ci            ? InstructionSelector::kAllSourcePositions
21951cb0ef41Sopenharmony_ci            : InstructionSelector::kCallSourcePositions,
21961cb0ef41Sopenharmony_ci        InstructionSelector::SupportedFeatures(),
21971cb0ef41Sopenharmony_ci        FLAG_turbo_instruction_scheduling
21981cb0ef41Sopenharmony_ci            ? InstructionSelector::kEnableScheduling
21991cb0ef41Sopenharmony_ci            : InstructionSelector::kDisableScheduling,
22001cb0ef41Sopenharmony_ci        data->assembler_options().enable_root_relative_access
22011cb0ef41Sopenharmony_ci            ? InstructionSelector::kEnableRootsRelativeAddressing
22021cb0ef41Sopenharmony_ci            : InstructionSelector::kDisableRootsRelativeAddressing,
22031cb0ef41Sopenharmony_ci        data->info()->trace_turbo_json()
22041cb0ef41Sopenharmony_ci            ? InstructionSelector::kEnableTraceTurboJson
22051cb0ef41Sopenharmony_ci            : InstructionSelector::kDisableTraceTurboJson);
22061cb0ef41Sopenharmony_ci    if (!selector.SelectInstructions()) {
22071cb0ef41Sopenharmony_ci      data->set_compilation_failed();
22081cb0ef41Sopenharmony_ci    }
22091cb0ef41Sopenharmony_ci    if (data->info()->trace_turbo_json()) {
22101cb0ef41Sopenharmony_ci      TurboJsonFile json_of(data->info(), std::ios_base::app);
22111cb0ef41Sopenharmony_ci      json_of << "{\"name\":\"" << phase_name()
22121cb0ef41Sopenharmony_ci              << "\",\"type\":\"instructions\""
22131cb0ef41Sopenharmony_ci              << InstructionRangesAsJSON{data->sequence(),
22141cb0ef41Sopenharmony_ci                                         &selector.instr_origins()}
22151cb0ef41Sopenharmony_ci              << "},\n";
22161cb0ef41Sopenharmony_ci    }
22171cb0ef41Sopenharmony_ci  }
22181cb0ef41Sopenharmony_ci};
22191cb0ef41Sopenharmony_ci
22201cb0ef41Sopenharmony_ci
22211cb0ef41Sopenharmony_cistruct MeetRegisterConstraintsPhase {
22221cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(MeetRegisterConstraints)
22231cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
22241cb0ef41Sopenharmony_ci    ConstraintBuilder builder(data->top_tier_register_allocation_data());
22251cb0ef41Sopenharmony_ci    builder.MeetRegisterConstraints();
22261cb0ef41Sopenharmony_ci  }
22271cb0ef41Sopenharmony_ci};
22281cb0ef41Sopenharmony_ci
22291cb0ef41Sopenharmony_ci
22301cb0ef41Sopenharmony_cistruct ResolvePhisPhase {
22311cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(ResolvePhis)
22321cb0ef41Sopenharmony_ci
22331cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
22341cb0ef41Sopenharmony_ci    ConstraintBuilder builder(data->top_tier_register_allocation_data());
22351cb0ef41Sopenharmony_ci    builder.ResolvePhis();
22361cb0ef41Sopenharmony_ci  }
22371cb0ef41Sopenharmony_ci};
22381cb0ef41Sopenharmony_ci
22391cb0ef41Sopenharmony_ci
22401cb0ef41Sopenharmony_cistruct BuildLiveRangesPhase {
22411cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(BuildLiveRanges)
22421cb0ef41Sopenharmony_ci
22431cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
22441cb0ef41Sopenharmony_ci    LiveRangeBuilder builder(data->top_tier_register_allocation_data(),
22451cb0ef41Sopenharmony_ci                             temp_zone);
22461cb0ef41Sopenharmony_ci    builder.BuildLiveRanges();
22471cb0ef41Sopenharmony_ci  }
22481cb0ef41Sopenharmony_ci};
22491cb0ef41Sopenharmony_ci
22501cb0ef41Sopenharmony_cistruct BuildBundlesPhase {
22511cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(BuildLiveRangeBundles)
22521cb0ef41Sopenharmony_ci
22531cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
22541cb0ef41Sopenharmony_ci    BundleBuilder builder(data->top_tier_register_allocation_data());
22551cb0ef41Sopenharmony_ci    builder.BuildBundles();
22561cb0ef41Sopenharmony_ci  }
22571cb0ef41Sopenharmony_ci};
22581cb0ef41Sopenharmony_ci
22591cb0ef41Sopenharmony_citemplate <typename RegAllocator>
22601cb0ef41Sopenharmony_cistruct AllocateGeneralRegistersPhase {
22611cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(AllocateGeneralRegisters)
22621cb0ef41Sopenharmony_ci
22631cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
22641cb0ef41Sopenharmony_ci    RegAllocator allocator(data->top_tier_register_allocation_data(),
22651cb0ef41Sopenharmony_ci                           RegisterKind::kGeneral, temp_zone);
22661cb0ef41Sopenharmony_ci    allocator.AllocateRegisters();
22671cb0ef41Sopenharmony_ci  }
22681cb0ef41Sopenharmony_ci};
22691cb0ef41Sopenharmony_ci
22701cb0ef41Sopenharmony_citemplate <typename RegAllocator>
22711cb0ef41Sopenharmony_cistruct AllocateFPRegistersPhase {
22721cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(AllocateFPRegisters)
22731cb0ef41Sopenharmony_ci
22741cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
22751cb0ef41Sopenharmony_ci    RegAllocator allocator(data->top_tier_register_allocation_data(),
22761cb0ef41Sopenharmony_ci                           RegisterKind::kDouble, temp_zone);
22771cb0ef41Sopenharmony_ci    allocator.AllocateRegisters();
22781cb0ef41Sopenharmony_ci  }
22791cb0ef41Sopenharmony_ci};
22801cb0ef41Sopenharmony_ci
22811cb0ef41Sopenharmony_citemplate <typename RegAllocator>
22821cb0ef41Sopenharmony_cistruct AllocateSimd128RegistersPhase {
22831cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(AllocateSIMD128Registers)
22841cb0ef41Sopenharmony_ci
22851cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
22861cb0ef41Sopenharmony_ci    RegAllocator allocator(data->top_tier_register_allocation_data(),
22871cb0ef41Sopenharmony_ci                           RegisterKind::kSimd128, temp_zone);
22881cb0ef41Sopenharmony_ci    allocator.AllocateRegisters();
22891cb0ef41Sopenharmony_ci  }
22901cb0ef41Sopenharmony_ci};
22911cb0ef41Sopenharmony_ci
22921cb0ef41Sopenharmony_cistruct DecideSpillingModePhase {
22931cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(DecideSpillingMode)
22941cb0ef41Sopenharmony_ci
22951cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
22961cb0ef41Sopenharmony_ci    OperandAssigner assigner(data->top_tier_register_allocation_data());
22971cb0ef41Sopenharmony_ci    assigner.DecideSpillingMode();
22981cb0ef41Sopenharmony_ci  }
22991cb0ef41Sopenharmony_ci};
23001cb0ef41Sopenharmony_ci
23011cb0ef41Sopenharmony_cistruct AssignSpillSlotsPhase {
23021cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(AssignSpillSlots)
23031cb0ef41Sopenharmony_ci
23041cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
23051cb0ef41Sopenharmony_ci    OperandAssigner assigner(data->top_tier_register_allocation_data());
23061cb0ef41Sopenharmony_ci    assigner.AssignSpillSlots();
23071cb0ef41Sopenharmony_ci  }
23081cb0ef41Sopenharmony_ci};
23091cb0ef41Sopenharmony_ci
23101cb0ef41Sopenharmony_ci
23111cb0ef41Sopenharmony_cistruct CommitAssignmentPhase {
23121cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(CommitAssignment)
23131cb0ef41Sopenharmony_ci
23141cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
23151cb0ef41Sopenharmony_ci    OperandAssigner assigner(data->top_tier_register_allocation_data());
23161cb0ef41Sopenharmony_ci    assigner.CommitAssignment();
23171cb0ef41Sopenharmony_ci  }
23181cb0ef41Sopenharmony_ci};
23191cb0ef41Sopenharmony_ci
23201cb0ef41Sopenharmony_ci
23211cb0ef41Sopenharmony_cistruct PopulateReferenceMapsPhase {
23221cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(PopulatePointerMaps)
23231cb0ef41Sopenharmony_ci
23241cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
23251cb0ef41Sopenharmony_ci    ReferenceMapPopulator populator(data->top_tier_register_allocation_data());
23261cb0ef41Sopenharmony_ci    populator.PopulateReferenceMaps();
23271cb0ef41Sopenharmony_ci  }
23281cb0ef41Sopenharmony_ci};
23291cb0ef41Sopenharmony_ci
23301cb0ef41Sopenharmony_ci
23311cb0ef41Sopenharmony_cistruct ConnectRangesPhase {
23321cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(ConnectRanges)
23331cb0ef41Sopenharmony_ci
23341cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
23351cb0ef41Sopenharmony_ci    LiveRangeConnector connector(data->top_tier_register_allocation_data());
23361cb0ef41Sopenharmony_ci    connector.ConnectRanges(temp_zone);
23371cb0ef41Sopenharmony_ci  }
23381cb0ef41Sopenharmony_ci};
23391cb0ef41Sopenharmony_ci
23401cb0ef41Sopenharmony_ci
23411cb0ef41Sopenharmony_cistruct ResolveControlFlowPhase {
23421cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(ResolveControlFlow)
23431cb0ef41Sopenharmony_ci
23441cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
23451cb0ef41Sopenharmony_ci    LiveRangeConnector connector(data->top_tier_register_allocation_data());
23461cb0ef41Sopenharmony_ci    connector.ResolveControlFlow(temp_zone);
23471cb0ef41Sopenharmony_ci  }
23481cb0ef41Sopenharmony_ci};
23491cb0ef41Sopenharmony_ci
23501cb0ef41Sopenharmony_cistruct MidTierRegisterOutputDefinitionPhase {
23511cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(MidTierRegisterOutputDefinition)
23521cb0ef41Sopenharmony_ci
23531cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
23541cb0ef41Sopenharmony_ci    DefineOutputs(data->mid_tier_register_allocator_data());
23551cb0ef41Sopenharmony_ci  }
23561cb0ef41Sopenharmony_ci};
23571cb0ef41Sopenharmony_ci
23581cb0ef41Sopenharmony_cistruct MidTierRegisterAllocatorPhase {
23591cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(MidTierRegisterAllocator)
23601cb0ef41Sopenharmony_ci
23611cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
23621cb0ef41Sopenharmony_ci    AllocateRegisters(data->mid_tier_register_allocator_data());
23631cb0ef41Sopenharmony_ci  }
23641cb0ef41Sopenharmony_ci};
23651cb0ef41Sopenharmony_ci
23661cb0ef41Sopenharmony_cistruct MidTierSpillSlotAllocatorPhase {
23671cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(MidTierSpillSlotAllocator)
23681cb0ef41Sopenharmony_ci
23691cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
23701cb0ef41Sopenharmony_ci    AllocateSpillSlots(data->mid_tier_register_allocator_data());
23711cb0ef41Sopenharmony_ci  }
23721cb0ef41Sopenharmony_ci};
23731cb0ef41Sopenharmony_ci
23741cb0ef41Sopenharmony_cistruct MidTierPopulateReferenceMapsPhase {
23751cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(MidTierPopulateReferenceMaps)
23761cb0ef41Sopenharmony_ci
23771cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
23781cb0ef41Sopenharmony_ci    PopulateReferenceMaps(data->mid_tier_register_allocator_data());
23791cb0ef41Sopenharmony_ci  }
23801cb0ef41Sopenharmony_ci};
23811cb0ef41Sopenharmony_ci
23821cb0ef41Sopenharmony_cistruct OptimizeMovesPhase {
23831cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(OptimizeMoves)
23841cb0ef41Sopenharmony_ci
23851cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
23861cb0ef41Sopenharmony_ci    MoveOptimizer move_optimizer(temp_zone, data->sequence());
23871cb0ef41Sopenharmony_ci    move_optimizer.Run();
23881cb0ef41Sopenharmony_ci  }
23891cb0ef41Sopenharmony_ci};
23901cb0ef41Sopenharmony_ci
23911cb0ef41Sopenharmony_cistruct FrameElisionPhase {
23921cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(FrameElision)
23931cb0ef41Sopenharmony_ci
23941cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
23951cb0ef41Sopenharmony_ci    FrameElider(data->sequence()).Run();
23961cb0ef41Sopenharmony_ci  }
23971cb0ef41Sopenharmony_ci};
23981cb0ef41Sopenharmony_ci
23991cb0ef41Sopenharmony_cistruct JumpThreadingPhase {
24001cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(JumpThreading)
24011cb0ef41Sopenharmony_ci
24021cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone, bool frame_at_start) {
24031cb0ef41Sopenharmony_ci    ZoneVector<RpoNumber> result(temp_zone);
24041cb0ef41Sopenharmony_ci    if (JumpThreading::ComputeForwarding(temp_zone, &result, data->sequence(),
24051cb0ef41Sopenharmony_ci                                         frame_at_start)) {
24061cb0ef41Sopenharmony_ci      JumpThreading::ApplyForwarding(temp_zone, result, data->sequence());
24071cb0ef41Sopenharmony_ci    }
24081cb0ef41Sopenharmony_ci  }
24091cb0ef41Sopenharmony_ci};
24101cb0ef41Sopenharmony_ci
24111cb0ef41Sopenharmony_cistruct AssembleCodePhase {
24121cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(AssembleCode)
24131cb0ef41Sopenharmony_ci
24141cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
24151cb0ef41Sopenharmony_ci    data->code_generator()->AssembleCode();
24161cb0ef41Sopenharmony_ci  }
24171cb0ef41Sopenharmony_ci};
24181cb0ef41Sopenharmony_ci
24191cb0ef41Sopenharmony_cistruct FinalizeCodePhase {
24201cb0ef41Sopenharmony_ci  DECL_MAIN_THREAD_PIPELINE_PHASE_CONSTANTS(FinalizeCode)
24211cb0ef41Sopenharmony_ci
24221cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone) {
24231cb0ef41Sopenharmony_ci    data->set_code(data->code_generator()->FinalizeCode());
24241cb0ef41Sopenharmony_ci  }
24251cb0ef41Sopenharmony_ci};
24261cb0ef41Sopenharmony_ci
24271cb0ef41Sopenharmony_ci
24281cb0ef41Sopenharmony_cistruct PrintGraphPhase {
24291cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(PrintGraph)
24301cb0ef41Sopenharmony_ci
24311cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone, const char* phase) {
24321cb0ef41Sopenharmony_ci    OptimizedCompilationInfo* info = data->info();
24331cb0ef41Sopenharmony_ci    Graph* graph = data->graph();
24341cb0ef41Sopenharmony_ci
24351cb0ef41Sopenharmony_ci    if (info->trace_turbo_json()) {  // Print JSON.
24361cb0ef41Sopenharmony_ci      UnparkedScopeIfNeeded scope(data->broker());
24371cb0ef41Sopenharmony_ci      AllowHandleDereference allow_deref;
24381cb0ef41Sopenharmony_ci
24391cb0ef41Sopenharmony_ci      TurboJsonFile json_of(info, std::ios_base::app);
24401cb0ef41Sopenharmony_ci      json_of << "{\"name\":\"" << phase << "\",\"type\":\"graph\",\"data\":"
24411cb0ef41Sopenharmony_ci              << AsJSON(*graph, data->source_positions(), data->node_origins())
24421cb0ef41Sopenharmony_ci              << "},\n";
24431cb0ef41Sopenharmony_ci    }
24441cb0ef41Sopenharmony_ci
24451cb0ef41Sopenharmony_ci    if (info->trace_turbo_scheduled()) {
24461cb0ef41Sopenharmony_ci      AccountingAllocator allocator;
24471cb0ef41Sopenharmony_ci      Schedule* schedule = data->schedule();
24481cb0ef41Sopenharmony_ci      if (schedule == nullptr) {
24491cb0ef41Sopenharmony_ci        schedule = Scheduler::ComputeSchedule(
24501cb0ef41Sopenharmony_ci            temp_zone, data->graph(), Scheduler::kNoFlags,
24511cb0ef41Sopenharmony_ci            &info->tick_counter(), data->profile_data());
24521cb0ef41Sopenharmony_ci      }
24531cb0ef41Sopenharmony_ci
24541cb0ef41Sopenharmony_ci      UnparkedScopeIfNeeded scope(data->broker());
24551cb0ef41Sopenharmony_ci      AllowHandleDereference allow_deref;
24561cb0ef41Sopenharmony_ci      CodeTracer::StreamScope tracing_scope(data->GetCodeTracer());
24571cb0ef41Sopenharmony_ci      tracing_scope.stream()
24581cb0ef41Sopenharmony_ci          << "-- Graph after " << phase << " -- " << std::endl
24591cb0ef41Sopenharmony_ci          << AsScheduledGraph(schedule);
24601cb0ef41Sopenharmony_ci    } else if (info->trace_turbo_graph()) {  // Simple textual RPO.
24611cb0ef41Sopenharmony_ci      UnparkedScopeIfNeeded scope(data->broker());
24621cb0ef41Sopenharmony_ci      AllowHandleDereference allow_deref;
24631cb0ef41Sopenharmony_ci      CodeTracer::StreamScope tracing_scope(data->GetCodeTracer());
24641cb0ef41Sopenharmony_ci      tracing_scope.stream()
24651cb0ef41Sopenharmony_ci          << "-- Graph after " << phase << " -- " << std::endl
24661cb0ef41Sopenharmony_ci          << AsRPO(*graph);
24671cb0ef41Sopenharmony_ci    }
24681cb0ef41Sopenharmony_ci  }
24691cb0ef41Sopenharmony_ci};
24701cb0ef41Sopenharmony_ci
24711cb0ef41Sopenharmony_ci
24721cb0ef41Sopenharmony_cistruct VerifyGraphPhase {
24731cb0ef41Sopenharmony_ci  DECL_PIPELINE_PHASE_CONSTANTS(VerifyGraph)
24741cb0ef41Sopenharmony_ci
24751cb0ef41Sopenharmony_ci  void Run(PipelineData* data, Zone* temp_zone, const bool untyped,
24761cb0ef41Sopenharmony_ci           bool values_only = false) {
24771cb0ef41Sopenharmony_ci    Verifier::CodeType code_type;
24781cb0ef41Sopenharmony_ci    switch (data->info()->code_kind()) {
24791cb0ef41Sopenharmony_ci      case CodeKind::WASM_FUNCTION:
24801cb0ef41Sopenharmony_ci      case CodeKind::WASM_TO_CAPI_FUNCTION:
24811cb0ef41Sopenharmony_ci      case CodeKind::WASM_TO_JS_FUNCTION:
24821cb0ef41Sopenharmony_ci      case CodeKind::JS_TO_WASM_FUNCTION:
24831cb0ef41Sopenharmony_ci      case CodeKind::C_WASM_ENTRY:
24841cb0ef41Sopenharmony_ci        code_type = Verifier::kWasm;
24851cb0ef41Sopenharmony_ci        break;
24861cb0ef41Sopenharmony_ci      default:
24871cb0ef41Sopenharmony_ci        code_type = Verifier::kDefault;
24881cb0ef41Sopenharmony_ci    }
24891cb0ef41Sopenharmony_ci    Verifier::Run(data->graph(), !untyped ? Verifier::TYPED : Verifier::UNTYPED,
24901cb0ef41Sopenharmony_ci                  values_only ? Verifier::kValuesOnly : Verifier::kAll,
24911cb0ef41Sopenharmony_ci                  code_type);
24921cb0ef41Sopenharmony_ci  }
24931cb0ef41Sopenharmony_ci};
24941cb0ef41Sopenharmony_ci
24951cb0ef41Sopenharmony_ci#undef DECL_MAIN_THREAD_PIPELINE_PHASE_CONSTANTS
24961cb0ef41Sopenharmony_ci#undef DECL_PIPELINE_PHASE_CONSTANTS
24971cb0ef41Sopenharmony_ci#undef DECL_PIPELINE_PHASE_CONSTANTS_HELPER
24981cb0ef41Sopenharmony_ci
24991cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
25001cb0ef41Sopenharmony_ciclass WasmHeapStubCompilationJob final : public TurbofanCompilationJob {
25011cb0ef41Sopenharmony_ci public:
25021cb0ef41Sopenharmony_ci  WasmHeapStubCompilationJob(Isolate* isolate, CallDescriptor* call_descriptor,
25031cb0ef41Sopenharmony_ci                             std::unique_ptr<Zone> zone, Graph* graph,
25041cb0ef41Sopenharmony_ci                             CodeKind kind, std::unique_ptr<char[]> debug_name,
25051cb0ef41Sopenharmony_ci                             const AssemblerOptions& options,
25061cb0ef41Sopenharmony_ci                             SourcePositionTable* source_positions)
25071cb0ef41Sopenharmony_ci      // Note that the OptimizedCompilationInfo is not initialized at the time
25081cb0ef41Sopenharmony_ci      // we pass it to the CompilationJob constructor, but it is not
25091cb0ef41Sopenharmony_ci      // dereferenced there.
25101cb0ef41Sopenharmony_ci      : TurbofanCompilationJob(&info_, CompilationJob::State::kReadyToExecute),
25111cb0ef41Sopenharmony_ci        debug_name_(std::move(debug_name)),
25121cb0ef41Sopenharmony_ci        info_(base::CStrVector(debug_name_.get()), graph->zone(), kind),
25131cb0ef41Sopenharmony_ci        call_descriptor_(call_descriptor),
25141cb0ef41Sopenharmony_ci        zone_stats_(zone->allocator()),
25151cb0ef41Sopenharmony_ci        zone_(std::move(zone)),
25161cb0ef41Sopenharmony_ci        graph_(graph),
25171cb0ef41Sopenharmony_ci        data_(&zone_stats_, &info_, isolate, wasm::GetWasmEngine()->allocator(),
25181cb0ef41Sopenharmony_ci              graph_, nullptr, nullptr, source_positions,
25191cb0ef41Sopenharmony_ci              zone_->New<NodeOriginTable>(graph_), nullptr, options, nullptr),
25201cb0ef41Sopenharmony_ci        pipeline_(&data_) {}
25211cb0ef41Sopenharmony_ci
25221cb0ef41Sopenharmony_ci  WasmHeapStubCompilationJob(const WasmHeapStubCompilationJob&) = delete;
25231cb0ef41Sopenharmony_ci  WasmHeapStubCompilationJob& operator=(const WasmHeapStubCompilationJob&) =
25241cb0ef41Sopenharmony_ci      delete;
25251cb0ef41Sopenharmony_ci
25261cb0ef41Sopenharmony_ci protected:
25271cb0ef41Sopenharmony_ci  Status PrepareJobImpl(Isolate* isolate) final;
25281cb0ef41Sopenharmony_ci  Status ExecuteJobImpl(RuntimeCallStats* stats,
25291cb0ef41Sopenharmony_ci                        LocalIsolate* local_isolate) final;
25301cb0ef41Sopenharmony_ci  Status FinalizeJobImpl(Isolate* isolate) final;
25311cb0ef41Sopenharmony_ci
25321cb0ef41Sopenharmony_ci private:
25331cb0ef41Sopenharmony_ci  std::unique_ptr<char[]> debug_name_;
25341cb0ef41Sopenharmony_ci  OptimizedCompilationInfo info_;
25351cb0ef41Sopenharmony_ci  CallDescriptor* call_descriptor_;
25361cb0ef41Sopenharmony_ci  ZoneStats zone_stats_;
25371cb0ef41Sopenharmony_ci  std::unique_ptr<Zone> zone_;
25381cb0ef41Sopenharmony_ci  Graph* graph_;
25391cb0ef41Sopenharmony_ci  PipelineData data_;
25401cb0ef41Sopenharmony_ci  PipelineImpl pipeline_;
25411cb0ef41Sopenharmony_ci};
25421cb0ef41Sopenharmony_ci
25431cb0ef41Sopenharmony_ci// static
25441cb0ef41Sopenharmony_cistd::unique_ptr<TurbofanCompilationJob> Pipeline::NewWasmHeapStubCompilationJob(
25451cb0ef41Sopenharmony_ci    Isolate* isolate, CallDescriptor* call_descriptor,
25461cb0ef41Sopenharmony_ci    std::unique_ptr<Zone> zone, Graph* graph, CodeKind kind,
25471cb0ef41Sopenharmony_ci    std::unique_ptr<char[]> debug_name, const AssemblerOptions& options,
25481cb0ef41Sopenharmony_ci    SourcePositionTable* source_positions) {
25491cb0ef41Sopenharmony_ci  return std::make_unique<WasmHeapStubCompilationJob>(
25501cb0ef41Sopenharmony_ci      isolate, call_descriptor, std::move(zone), graph, kind,
25511cb0ef41Sopenharmony_ci      std::move(debug_name), options, source_positions);
25521cb0ef41Sopenharmony_ci}
25531cb0ef41Sopenharmony_ci
25541cb0ef41Sopenharmony_ciCompilationJob::Status WasmHeapStubCompilationJob::PrepareJobImpl(
25551cb0ef41Sopenharmony_ci    Isolate* isolate) {
25561cb0ef41Sopenharmony_ci  UNREACHABLE();
25571cb0ef41Sopenharmony_ci}
25581cb0ef41Sopenharmony_ci
25591cb0ef41Sopenharmony_ciCompilationJob::Status WasmHeapStubCompilationJob::ExecuteJobImpl(
25601cb0ef41Sopenharmony_ci    RuntimeCallStats* stats, LocalIsolate* local_isolate) {
25611cb0ef41Sopenharmony_ci  std::unique_ptr<PipelineStatistics> pipeline_statistics;
25621cb0ef41Sopenharmony_ci  if (FLAG_turbo_stats || FLAG_turbo_stats_nvp) {
25631cb0ef41Sopenharmony_ci    pipeline_statistics.reset(new PipelineStatistics(
25641cb0ef41Sopenharmony_ci        &info_, wasm::GetWasmEngine()->GetOrCreateTurboStatistics(),
25651cb0ef41Sopenharmony_ci        &zone_stats_));
25661cb0ef41Sopenharmony_ci    pipeline_statistics->BeginPhaseKind("V8.WasmStubCodegen");
25671cb0ef41Sopenharmony_ci  }
25681cb0ef41Sopenharmony_ci  if (info_.trace_turbo_json() || info_.trace_turbo_graph()) {
25691cb0ef41Sopenharmony_ci    CodeTracer::StreamScope tracing_scope(data_.GetCodeTracer());
25701cb0ef41Sopenharmony_ci    tracing_scope.stream()
25711cb0ef41Sopenharmony_ci        << "---------------------------------------------------\n"
25721cb0ef41Sopenharmony_ci        << "Begin compiling method " << info_.GetDebugName().get()
25731cb0ef41Sopenharmony_ci        << " using TurboFan" << std::endl;
25741cb0ef41Sopenharmony_ci  }
25751cb0ef41Sopenharmony_ci  if (info_.trace_turbo_graph()) {  // Simple textual RPO.
25761cb0ef41Sopenharmony_ci    StdoutStream{} << "-- wasm stub " << CodeKindToString(info_.code_kind())
25771cb0ef41Sopenharmony_ci                   << " graph -- " << std::endl
25781cb0ef41Sopenharmony_ci                   << AsRPO(*data_.graph());
25791cb0ef41Sopenharmony_ci  }
25801cb0ef41Sopenharmony_ci
25811cb0ef41Sopenharmony_ci  if (info_.trace_turbo_json()) {
25821cb0ef41Sopenharmony_ci    TurboJsonFile json_of(&info_, std::ios_base::trunc);
25831cb0ef41Sopenharmony_ci    json_of << "{\"function\":\"" << info_.GetDebugName().get()
25841cb0ef41Sopenharmony_ci            << "\", \"source\":\"\",\n\"phases\":[";
25851cb0ef41Sopenharmony_ci  }
25861cb0ef41Sopenharmony_ci  pipeline_.RunPrintAndVerify("V8.WasmMachineCode", true);
25871cb0ef41Sopenharmony_ci  pipeline_.Run<MemoryOptimizationPhase>();
25881cb0ef41Sopenharmony_ci  pipeline_.ComputeScheduledGraph();
25891cb0ef41Sopenharmony_ci  if (pipeline_.SelectInstructionsAndAssemble(call_descriptor_)) {
25901cb0ef41Sopenharmony_ci    return CompilationJob::SUCCEEDED;
25911cb0ef41Sopenharmony_ci  }
25921cb0ef41Sopenharmony_ci  return CompilationJob::FAILED;
25931cb0ef41Sopenharmony_ci}
25941cb0ef41Sopenharmony_ci
25951cb0ef41Sopenharmony_ciCompilationJob::Status WasmHeapStubCompilationJob::FinalizeJobImpl(
25961cb0ef41Sopenharmony_ci    Isolate* isolate) {
25971cb0ef41Sopenharmony_ci  Handle<Code> code;
25981cb0ef41Sopenharmony_ci  if (!pipeline_.FinalizeCode(call_descriptor_).ToHandle(&code)) {
25991cb0ef41Sopenharmony_ci    V8::FatalProcessOutOfMemory(isolate,
26001cb0ef41Sopenharmony_ci                                "WasmHeapStubCompilationJob::FinalizeJobImpl");
26011cb0ef41Sopenharmony_ci  }
26021cb0ef41Sopenharmony_ci  if (pipeline_.CommitDependencies(code)) {
26031cb0ef41Sopenharmony_ci    info_.SetCode(code);
26041cb0ef41Sopenharmony_ci#ifdef ENABLE_DISASSEMBLER
26051cb0ef41Sopenharmony_ci    if (FLAG_print_opt_code) {
26061cb0ef41Sopenharmony_ci      CodeTracer::StreamScope tracing_scope(isolate->GetCodeTracer());
26071cb0ef41Sopenharmony_ci      code->Disassemble(compilation_info()->GetDebugName().get(),
26081cb0ef41Sopenharmony_ci                        tracing_scope.stream(), isolate);
26091cb0ef41Sopenharmony_ci    }
26101cb0ef41Sopenharmony_ci#endif
26111cb0ef41Sopenharmony_ci    PROFILE(isolate, CodeCreateEvent(CodeEventListener::STUB_TAG,
26121cb0ef41Sopenharmony_ci                                     Handle<AbstractCode>::cast(code),
26131cb0ef41Sopenharmony_ci                                     compilation_info()->GetDebugName().get()));
26141cb0ef41Sopenharmony_ci    return SUCCEEDED;
26151cb0ef41Sopenharmony_ci  }
26161cb0ef41Sopenharmony_ci  return FAILED;
26171cb0ef41Sopenharmony_ci}
26181cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
26191cb0ef41Sopenharmony_ci
26201cb0ef41Sopenharmony_civoid PipelineImpl::RunPrintAndVerify(const char* phase, bool untyped) {
26211cb0ef41Sopenharmony_ci  if (info()->trace_turbo_json() || info()->trace_turbo_graph()) {
26221cb0ef41Sopenharmony_ci    Run<PrintGraphPhase>(phase);
26231cb0ef41Sopenharmony_ci  }
26241cb0ef41Sopenharmony_ci  if (FLAG_turbo_verify) {
26251cb0ef41Sopenharmony_ci    Run<VerifyGraphPhase>(untyped);
26261cb0ef41Sopenharmony_ci  }
26271cb0ef41Sopenharmony_ci}
26281cb0ef41Sopenharmony_ci
26291cb0ef41Sopenharmony_civoid PipelineImpl::InitializeHeapBroker() {
26301cb0ef41Sopenharmony_ci  PipelineData* data = data_;
26311cb0ef41Sopenharmony_ci
26321cb0ef41Sopenharmony_ci  data->BeginPhaseKind("V8.TFBrokerInitAndSerialization");
26331cb0ef41Sopenharmony_ci
26341cb0ef41Sopenharmony_ci  if (info()->trace_turbo_json() || info()->trace_turbo_graph()) {
26351cb0ef41Sopenharmony_ci    CodeTracer::StreamScope tracing_scope(data->GetCodeTracer());
26361cb0ef41Sopenharmony_ci    tracing_scope.stream()
26371cb0ef41Sopenharmony_ci        << "---------------------------------------------------\n"
26381cb0ef41Sopenharmony_ci        << "Begin compiling method " << info()->GetDebugName().get()
26391cb0ef41Sopenharmony_ci        << " using TurboFan" << std::endl;
26401cb0ef41Sopenharmony_ci  }
26411cb0ef41Sopenharmony_ci  if (info()->trace_turbo_json()) {
26421cb0ef41Sopenharmony_ci    TurboCfgFile tcf(isolate());
26431cb0ef41Sopenharmony_ci    tcf << AsC1VCompilation(info());
26441cb0ef41Sopenharmony_ci  }
26451cb0ef41Sopenharmony_ci
26461cb0ef41Sopenharmony_ci  data->source_positions()->AddDecorator();
26471cb0ef41Sopenharmony_ci  if (data->info()->trace_turbo_json()) {
26481cb0ef41Sopenharmony_ci    data->node_origins()->AddDecorator();
26491cb0ef41Sopenharmony_ci  }
26501cb0ef41Sopenharmony_ci
26511cb0ef41Sopenharmony_ci  data->broker()->SetTargetNativeContextRef(data->native_context());
26521cb0ef41Sopenharmony_ci  Run<HeapBrokerInitializationPhase>();
26531cb0ef41Sopenharmony_ci  data->broker()->StopSerializing();
26541cb0ef41Sopenharmony_ci  data->EndPhaseKind();
26551cb0ef41Sopenharmony_ci}
26561cb0ef41Sopenharmony_ci
26571cb0ef41Sopenharmony_cibool PipelineImpl::CreateGraph() {
26581cb0ef41Sopenharmony_ci  PipelineData* data = this->data_;
26591cb0ef41Sopenharmony_ci  UnparkedScopeIfNeeded unparked_scope(data->broker());
26601cb0ef41Sopenharmony_ci
26611cb0ef41Sopenharmony_ci  data->BeginPhaseKind("V8.TFGraphCreation");
26621cb0ef41Sopenharmony_ci
26631cb0ef41Sopenharmony_ci  Run<GraphBuilderPhase>();
26641cb0ef41Sopenharmony_ci  RunPrintAndVerify(GraphBuilderPhase::phase_name(), true);
26651cb0ef41Sopenharmony_ci
26661cb0ef41Sopenharmony_ci  // Perform function context specialization and inlining (if enabled).
26671cb0ef41Sopenharmony_ci  Run<InliningPhase>();
26681cb0ef41Sopenharmony_ci  RunPrintAndVerify(InliningPhase::phase_name(), true);
26691cb0ef41Sopenharmony_ci
26701cb0ef41Sopenharmony_ci  // Determine the Typer operation flags.
26711cb0ef41Sopenharmony_ci  {
26721cb0ef41Sopenharmony_ci    SharedFunctionInfoRef shared_info =
26731cb0ef41Sopenharmony_ci        MakeRef(data->broker(), info()->shared_info());
26741cb0ef41Sopenharmony_ci    if (is_sloppy(shared_info.language_mode()) &&
26751cb0ef41Sopenharmony_ci        shared_info.IsUserJavaScript()) {
26761cb0ef41Sopenharmony_ci      // Sloppy mode functions always have an Object for this.
26771cb0ef41Sopenharmony_ci      data->AddTyperFlag(Typer::kThisIsReceiver);
26781cb0ef41Sopenharmony_ci    }
26791cb0ef41Sopenharmony_ci    if (IsClassConstructor(shared_info.kind())) {
26801cb0ef41Sopenharmony_ci      // Class constructors cannot be [[Call]]ed.
26811cb0ef41Sopenharmony_ci      data->AddTyperFlag(Typer::kNewTargetIsReceiver);
26821cb0ef41Sopenharmony_ci    }
26831cb0ef41Sopenharmony_ci  }
26841cb0ef41Sopenharmony_ci
26851cb0ef41Sopenharmony_ci  data->EndPhaseKind();
26861cb0ef41Sopenharmony_ci
26871cb0ef41Sopenharmony_ci  return true;
26881cb0ef41Sopenharmony_ci}
26891cb0ef41Sopenharmony_ci
26901cb0ef41Sopenharmony_cibool PipelineImpl::OptimizeGraph(Linkage* linkage) {
26911cb0ef41Sopenharmony_ci  PipelineData* data = this->data_;
26921cb0ef41Sopenharmony_ci
26931cb0ef41Sopenharmony_ci  data->BeginPhaseKind("V8.TFLowering");
26941cb0ef41Sopenharmony_ci
26951cb0ef41Sopenharmony_ci  // Trim the graph before typing to ensure all nodes are typed.
26961cb0ef41Sopenharmony_ci  Run<EarlyGraphTrimmingPhase>();
26971cb0ef41Sopenharmony_ci  RunPrintAndVerify(EarlyGraphTrimmingPhase::phase_name(), true);
26981cb0ef41Sopenharmony_ci
26991cb0ef41Sopenharmony_ci  // Type the graph and keep the Typer running such that new nodes get
27001cb0ef41Sopenharmony_ci  // automatically typed when they are created.
27011cb0ef41Sopenharmony_ci  Run<TyperPhase>(data->CreateTyper());
27021cb0ef41Sopenharmony_ci  RunPrintAndVerify(TyperPhase::phase_name());
27031cb0ef41Sopenharmony_ci
27041cb0ef41Sopenharmony_ci  Run<TypedLoweringPhase>();
27051cb0ef41Sopenharmony_ci  RunPrintAndVerify(TypedLoweringPhase::phase_name());
27061cb0ef41Sopenharmony_ci
27071cb0ef41Sopenharmony_ci  if (data->info()->loop_peeling()) {
27081cb0ef41Sopenharmony_ci    Run<LoopPeelingPhase>();
27091cb0ef41Sopenharmony_ci    RunPrintAndVerify(LoopPeelingPhase::phase_name(), true);
27101cb0ef41Sopenharmony_ci  } else {
27111cb0ef41Sopenharmony_ci    Run<LoopExitEliminationPhase>();
27121cb0ef41Sopenharmony_ci    RunPrintAndVerify(LoopExitEliminationPhase::phase_name(), true);
27131cb0ef41Sopenharmony_ci  }
27141cb0ef41Sopenharmony_ci
27151cb0ef41Sopenharmony_ci  if (FLAG_turbo_load_elimination) {
27161cb0ef41Sopenharmony_ci    Run<LoadEliminationPhase>();
27171cb0ef41Sopenharmony_ci    RunPrintAndVerify(LoadEliminationPhase::phase_name());
27181cb0ef41Sopenharmony_ci  }
27191cb0ef41Sopenharmony_ci  data->DeleteTyper();
27201cb0ef41Sopenharmony_ci
27211cb0ef41Sopenharmony_ci  if (FLAG_turbo_escape) {
27221cb0ef41Sopenharmony_ci    Run<EscapeAnalysisPhase>();
27231cb0ef41Sopenharmony_ci    if (data->compilation_failed()) {
27241cb0ef41Sopenharmony_ci      info()->AbortOptimization(
27251cb0ef41Sopenharmony_ci          BailoutReason::kCyclicObjectStateDetectedInEscapeAnalysis);
27261cb0ef41Sopenharmony_ci      data->EndPhaseKind();
27271cb0ef41Sopenharmony_ci      return false;
27281cb0ef41Sopenharmony_ci    }
27291cb0ef41Sopenharmony_ci    RunPrintAndVerify(EscapeAnalysisPhase::phase_name());
27301cb0ef41Sopenharmony_ci  }
27311cb0ef41Sopenharmony_ci
27321cb0ef41Sopenharmony_ci  if (FLAG_assert_types) {
27331cb0ef41Sopenharmony_ci    Run<TypeAssertionsPhase>();
27341cb0ef41Sopenharmony_ci    RunPrintAndVerify(TypeAssertionsPhase::phase_name());
27351cb0ef41Sopenharmony_ci  }
27361cb0ef41Sopenharmony_ci
27371cb0ef41Sopenharmony_ci  // Perform simplified lowering. This has to run w/o the Typer decorator,
27381cb0ef41Sopenharmony_ci  // because we cannot compute meaningful types anyways, and the computed types
27391cb0ef41Sopenharmony_ci  // might even conflict with the representation/truncation logic.
27401cb0ef41Sopenharmony_ci  Run<SimplifiedLoweringPhase>(linkage);
27411cb0ef41Sopenharmony_ci  RunPrintAndVerify(SimplifiedLoweringPhase::phase_name(), true);
27421cb0ef41Sopenharmony_ci
27431cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
27441cb0ef41Sopenharmony_ci  if (data->has_js_wasm_calls()) {
27451cb0ef41Sopenharmony_ci    DCHECK(data->info()->inline_js_wasm_calls());
27461cb0ef41Sopenharmony_ci    Run<JSWasmInliningPhase>();
27471cb0ef41Sopenharmony_ci    RunPrintAndVerify(JSWasmInliningPhase::phase_name(), true);
27481cb0ef41Sopenharmony_ci  }
27491cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
27501cb0ef41Sopenharmony_ci
27511cb0ef41Sopenharmony_ci  // From now on it is invalid to look at types on the nodes, because the types
27521cb0ef41Sopenharmony_ci  // on the nodes might not make sense after representation selection due to the
27531cb0ef41Sopenharmony_ci  // way we handle truncations; if we'd want to look at types afterwards we'd
27541cb0ef41Sopenharmony_ci  // essentially need to re-type (large portions of) the graph.
27551cb0ef41Sopenharmony_ci
27561cb0ef41Sopenharmony_ci  // In order to catch bugs related to type access after this point, we now
27571cb0ef41Sopenharmony_ci  // remove the types from the nodes (currently only in Debug builds).
27581cb0ef41Sopenharmony_ci#ifdef DEBUG
27591cb0ef41Sopenharmony_ci  Run<UntyperPhase>();
27601cb0ef41Sopenharmony_ci  RunPrintAndVerify(UntyperPhase::phase_name(), true);
27611cb0ef41Sopenharmony_ci#endif
27621cb0ef41Sopenharmony_ci
27631cb0ef41Sopenharmony_ci  // Run generic lowering pass.
27641cb0ef41Sopenharmony_ci  Run<GenericLoweringPhase>();
27651cb0ef41Sopenharmony_ci  RunPrintAndVerify(GenericLoweringPhase::phase_name(), true);
27661cb0ef41Sopenharmony_ci
27671cb0ef41Sopenharmony_ci  data->BeginPhaseKind("V8.TFBlockBuilding");
27681cb0ef41Sopenharmony_ci
27691cb0ef41Sopenharmony_ci  data->InitializeFrameData(linkage->GetIncomingDescriptor());
27701cb0ef41Sopenharmony_ci
27711cb0ef41Sopenharmony_ci  // Run early optimization pass.
27721cb0ef41Sopenharmony_ci  Run<EarlyOptimizationPhase>();
27731cb0ef41Sopenharmony_ci  RunPrintAndVerify(EarlyOptimizationPhase::phase_name(), true);
27741cb0ef41Sopenharmony_ci
27751cb0ef41Sopenharmony_ci  Run<EffectControlLinearizationPhase>();
27761cb0ef41Sopenharmony_ci  RunPrintAndVerify(EffectControlLinearizationPhase::phase_name(), true);
27771cb0ef41Sopenharmony_ci
27781cb0ef41Sopenharmony_ci  if (FLAG_turbo_store_elimination) {
27791cb0ef41Sopenharmony_ci    Run<StoreStoreEliminationPhase>();
27801cb0ef41Sopenharmony_ci    RunPrintAndVerify(StoreStoreEliminationPhase::phase_name(), true);
27811cb0ef41Sopenharmony_ci  }
27821cb0ef41Sopenharmony_ci
27831cb0ef41Sopenharmony_ci  // Optimize control flow.
27841cb0ef41Sopenharmony_ci  if (FLAG_turbo_cf_optimization) {
27851cb0ef41Sopenharmony_ci    Run<ControlFlowOptimizationPhase>();
27861cb0ef41Sopenharmony_ci    RunPrintAndVerify(ControlFlowOptimizationPhase::phase_name(), true);
27871cb0ef41Sopenharmony_ci  }
27881cb0ef41Sopenharmony_ci
27891cb0ef41Sopenharmony_ci  Run<LateOptimizationPhase>();
27901cb0ef41Sopenharmony_ci  RunPrintAndVerify(LateOptimizationPhase::phase_name(), true);
27911cb0ef41Sopenharmony_ci
27921cb0ef41Sopenharmony_ci  // Optimize memory access and allocation operations.
27931cb0ef41Sopenharmony_ci  Run<MemoryOptimizationPhase>();
27941cb0ef41Sopenharmony_ci  RunPrintAndVerify(MemoryOptimizationPhase::phase_name(), true);
27951cb0ef41Sopenharmony_ci
27961cb0ef41Sopenharmony_ci  // Run value numbering and machine operator reducer to optimize load/store
27971cb0ef41Sopenharmony_ci  // address computation (in particular, reuse the address computation whenever
27981cb0ef41Sopenharmony_ci  // possible).
27991cb0ef41Sopenharmony_ci  Run<MachineOperatorOptimizationPhase>();
28001cb0ef41Sopenharmony_ci  RunPrintAndVerify(MachineOperatorOptimizationPhase::phase_name(), true);
28011cb0ef41Sopenharmony_ci
28021cb0ef41Sopenharmony_ci  Run<DecompressionOptimizationPhase>();
28031cb0ef41Sopenharmony_ci  RunPrintAndVerify(DecompressionOptimizationPhase::phase_name(), true);
28041cb0ef41Sopenharmony_ci
28051cb0ef41Sopenharmony_ci  Run<BranchConditionDuplicationPhase>();
28061cb0ef41Sopenharmony_ci  RunPrintAndVerify(BranchConditionDuplicationPhase::phase_name(), true);
28071cb0ef41Sopenharmony_ci
28081cb0ef41Sopenharmony_ci  data->source_positions()->RemoveDecorator();
28091cb0ef41Sopenharmony_ci  if (data->info()->trace_turbo_json()) {
28101cb0ef41Sopenharmony_ci    data->node_origins()->RemoveDecorator();
28111cb0ef41Sopenharmony_ci  }
28121cb0ef41Sopenharmony_ci
28131cb0ef41Sopenharmony_ci  ComputeScheduledGraph();
28141cb0ef41Sopenharmony_ci
28151cb0ef41Sopenharmony_ci  return SelectInstructions(linkage);
28161cb0ef41Sopenharmony_ci}
28171cb0ef41Sopenharmony_ci
28181cb0ef41Sopenharmony_cinamespace {
28191cb0ef41Sopenharmony_ci
28201cb0ef41Sopenharmony_ci// Compute a hash of the given graph, in a way that should provide the same
28211cb0ef41Sopenharmony_ci// result in multiple runs of mksnapshot, meaning the hash cannot depend on any
28221cb0ef41Sopenharmony_ci// external pointer values or uncompressed heap constants. This hash can be used
28231cb0ef41Sopenharmony_ci// to reject profiling data if the builtin's current code doesn't match the
28241cb0ef41Sopenharmony_ci// version that was profiled. Hash collisions are not catastrophic; in the worst
28251cb0ef41Sopenharmony_ci// case, we just defer some blocks that ideally shouldn't be deferred. The
28261cb0ef41Sopenharmony_ci// result value is in the valid Smi range.
28271cb0ef41Sopenharmony_ciint HashGraphForPGO(Graph* graph) {
28281cb0ef41Sopenharmony_ci  AccountingAllocator allocator;
28291cb0ef41Sopenharmony_ci  Zone local_zone(&allocator, ZONE_NAME);
28301cb0ef41Sopenharmony_ci
28311cb0ef41Sopenharmony_ci  constexpr NodeId kUnassigned = static_cast<NodeId>(-1);
28321cb0ef41Sopenharmony_ci
28331cb0ef41Sopenharmony_ci  constexpr byte kUnvisited = 0;
28341cb0ef41Sopenharmony_ci  constexpr byte kOnStack = 1;
28351cb0ef41Sopenharmony_ci  constexpr byte kVisited = 2;
28361cb0ef41Sopenharmony_ci
28371cb0ef41Sopenharmony_ci  // Do a depth-first post-order traversal of the graph. For every node, hash:
28381cb0ef41Sopenharmony_ci  //
28391cb0ef41Sopenharmony_ci  //   - the node's traversal number
28401cb0ef41Sopenharmony_ci  //   - the opcode
28411cb0ef41Sopenharmony_ci  //   - the number of inputs
28421cb0ef41Sopenharmony_ci  //   - each input node's traversal number
28431cb0ef41Sopenharmony_ci  //
28441cb0ef41Sopenharmony_ci  // What's a traversal number? We can't use node IDs because they're not stable
28451cb0ef41Sopenharmony_ci  // build-to-build, so we assign a new number for each node as it is visited.
28461cb0ef41Sopenharmony_ci
28471cb0ef41Sopenharmony_ci  ZoneVector<byte> state(graph->NodeCount(), kUnvisited, &local_zone);
28481cb0ef41Sopenharmony_ci  ZoneVector<NodeId> traversal_numbers(graph->NodeCount(), kUnassigned,
28491cb0ef41Sopenharmony_ci                                       &local_zone);
28501cb0ef41Sopenharmony_ci  ZoneStack<Node*> stack(&local_zone);
28511cb0ef41Sopenharmony_ci
28521cb0ef41Sopenharmony_ci  NodeId visited_count = 0;
28531cb0ef41Sopenharmony_ci  size_t hash = 0;
28541cb0ef41Sopenharmony_ci
28551cb0ef41Sopenharmony_ci  stack.push(graph->end());
28561cb0ef41Sopenharmony_ci  state[graph->end()->id()] = kOnStack;
28571cb0ef41Sopenharmony_ci  traversal_numbers[graph->end()->id()] = visited_count++;
28581cb0ef41Sopenharmony_ci  while (!stack.empty()) {
28591cb0ef41Sopenharmony_ci    Node* n = stack.top();
28601cb0ef41Sopenharmony_ci    bool pop = true;
28611cb0ef41Sopenharmony_ci    for (Node* const i : n->inputs()) {
28621cb0ef41Sopenharmony_ci      if (state[i->id()] == kUnvisited) {
28631cb0ef41Sopenharmony_ci        state[i->id()] = kOnStack;
28641cb0ef41Sopenharmony_ci        traversal_numbers[i->id()] = visited_count++;
28651cb0ef41Sopenharmony_ci        stack.push(i);
28661cb0ef41Sopenharmony_ci        pop = false;
28671cb0ef41Sopenharmony_ci        break;
28681cb0ef41Sopenharmony_ci      }
28691cb0ef41Sopenharmony_ci    }
28701cb0ef41Sopenharmony_ci    if (pop) {
28711cb0ef41Sopenharmony_ci      state[n->id()] = kVisited;
28721cb0ef41Sopenharmony_ci      stack.pop();
28731cb0ef41Sopenharmony_ci      hash = base::hash_combine(hash, traversal_numbers[n->id()], n->opcode(),
28741cb0ef41Sopenharmony_ci                                n->InputCount());
28751cb0ef41Sopenharmony_ci      for (Node* const i : n->inputs()) {
28761cb0ef41Sopenharmony_ci        DCHECK(traversal_numbers[i->id()] != kUnassigned);
28771cb0ef41Sopenharmony_ci        hash = base::hash_combine(hash, traversal_numbers[i->id()]);
28781cb0ef41Sopenharmony_ci      }
28791cb0ef41Sopenharmony_ci    }
28801cb0ef41Sopenharmony_ci  }
28811cb0ef41Sopenharmony_ci  return Smi(IntToSmi(static_cast<int>(hash))).value();
28821cb0ef41Sopenharmony_ci}
28831cb0ef41Sopenharmony_ci
28841cb0ef41Sopenharmony_ci}  // namespace
28851cb0ef41Sopenharmony_ci
28861cb0ef41Sopenharmony_ciMaybeHandle<Code> Pipeline::GenerateCodeForCodeStub(
28871cb0ef41Sopenharmony_ci    Isolate* isolate, CallDescriptor* call_descriptor, Graph* graph,
28881cb0ef41Sopenharmony_ci    JSGraph* jsgraph, SourcePositionTable* source_positions, CodeKind kind,
28891cb0ef41Sopenharmony_ci    const char* debug_name, Builtin builtin, const AssemblerOptions& options,
28901cb0ef41Sopenharmony_ci    const ProfileDataFromFile* profile_data) {
28911cb0ef41Sopenharmony_ci  OptimizedCompilationInfo info(base::CStrVector(debug_name), graph->zone(),
28921cb0ef41Sopenharmony_ci                                kind);
28931cb0ef41Sopenharmony_ci  info.set_builtin(builtin);
28941cb0ef41Sopenharmony_ci
28951cb0ef41Sopenharmony_ci  // Construct a pipeline for scheduling and code generation.
28961cb0ef41Sopenharmony_ci  ZoneStats zone_stats(isolate->allocator());
28971cb0ef41Sopenharmony_ci  NodeOriginTable node_origins(graph);
28981cb0ef41Sopenharmony_ci  JumpOptimizationInfo jump_opt;
28991cb0ef41Sopenharmony_ci  bool should_optimize_jumps = isolate->serializer_enabled() &&
29001cb0ef41Sopenharmony_ci                               FLAG_turbo_rewrite_far_jumps &&
29011cb0ef41Sopenharmony_ci                               !FLAG_turbo_profiling;
29021cb0ef41Sopenharmony_ci  PipelineData data(&zone_stats, &info, isolate, isolate->allocator(), graph,
29031cb0ef41Sopenharmony_ci                    jsgraph, nullptr, source_positions, &node_origins,
29041cb0ef41Sopenharmony_ci                    should_optimize_jumps ? &jump_opt : nullptr, options,
29051cb0ef41Sopenharmony_ci                    profile_data);
29061cb0ef41Sopenharmony_ci  PipelineJobScope scope(&data, isolate->counters()->runtime_call_stats());
29071cb0ef41Sopenharmony_ci  RCS_SCOPE(isolate, RuntimeCallCounterId::kOptimizeCode);
29081cb0ef41Sopenharmony_ci  data.set_verify_graph(FLAG_verify_csa);
29091cb0ef41Sopenharmony_ci  std::unique_ptr<PipelineStatistics> pipeline_statistics;
29101cb0ef41Sopenharmony_ci  if (FLAG_turbo_stats || FLAG_turbo_stats_nvp) {
29111cb0ef41Sopenharmony_ci    pipeline_statistics.reset(new PipelineStatistics(
29121cb0ef41Sopenharmony_ci        &info, isolate->GetTurboStatistics(), &zone_stats));
29131cb0ef41Sopenharmony_ci    pipeline_statistics->BeginPhaseKind("V8.TFStubCodegen");
29141cb0ef41Sopenharmony_ci  }
29151cb0ef41Sopenharmony_ci
29161cb0ef41Sopenharmony_ci  PipelineImpl pipeline(&data);
29171cb0ef41Sopenharmony_ci
29181cb0ef41Sopenharmony_ci  if (info.trace_turbo_json() || info.trace_turbo_graph()) {
29191cb0ef41Sopenharmony_ci    CodeTracer::StreamScope tracing_scope(data.GetCodeTracer());
29201cb0ef41Sopenharmony_ci    tracing_scope.stream()
29211cb0ef41Sopenharmony_ci        << "---------------------------------------------------\n"
29221cb0ef41Sopenharmony_ci        << "Begin compiling " << debug_name << " using TurboFan" << std::endl;
29231cb0ef41Sopenharmony_ci    if (info.trace_turbo_json()) {
29241cb0ef41Sopenharmony_ci      TurboJsonFile json_of(&info, std::ios_base::trunc);
29251cb0ef41Sopenharmony_ci      json_of << "{\"function\" : ";
29261cb0ef41Sopenharmony_ci      JsonPrintFunctionSource(json_of, -1, info.GetDebugName(),
29271cb0ef41Sopenharmony_ci                              Handle<Script>(), isolate,
29281cb0ef41Sopenharmony_ci                              Handle<SharedFunctionInfo>());
29291cb0ef41Sopenharmony_ci      json_of << ",\n\"phases\":[";
29301cb0ef41Sopenharmony_ci    }
29311cb0ef41Sopenharmony_ci    pipeline.Run<PrintGraphPhase>("V8.TFMachineCode");
29321cb0ef41Sopenharmony_ci  }
29331cb0ef41Sopenharmony_ci
29341cb0ef41Sopenharmony_ci  pipeline.Run<CsaEarlyOptimizationPhase>();
29351cb0ef41Sopenharmony_ci  pipeline.RunPrintAndVerify(CsaEarlyOptimizationPhase::phase_name(), true);
29361cb0ef41Sopenharmony_ci
29371cb0ef41Sopenharmony_ci  // Optimize memory access and allocation operations.
29381cb0ef41Sopenharmony_ci  pipeline.Run<MemoryOptimizationPhase>();
29391cb0ef41Sopenharmony_ci  pipeline.RunPrintAndVerify(MemoryOptimizationPhase::phase_name(), true);
29401cb0ef41Sopenharmony_ci
29411cb0ef41Sopenharmony_ci  pipeline.Run<CsaOptimizationPhase>(true);
29421cb0ef41Sopenharmony_ci  pipeline.RunPrintAndVerify(CsaOptimizationPhase::phase_name(), true);
29431cb0ef41Sopenharmony_ci
29441cb0ef41Sopenharmony_ci  pipeline.Run<DecompressionOptimizationPhase>();
29451cb0ef41Sopenharmony_ci  pipeline.RunPrintAndVerify(DecompressionOptimizationPhase::phase_name(),
29461cb0ef41Sopenharmony_ci                             true);
29471cb0ef41Sopenharmony_ci
29481cb0ef41Sopenharmony_ci  pipeline.Run<BranchConditionDuplicationPhase>();
29491cb0ef41Sopenharmony_ci  pipeline.RunPrintAndVerify(BranchConditionDuplicationPhase::phase_name(),
29501cb0ef41Sopenharmony_ci                             true);
29511cb0ef41Sopenharmony_ci
29521cb0ef41Sopenharmony_ci  pipeline.Run<VerifyGraphPhase>(true);
29531cb0ef41Sopenharmony_ci
29541cb0ef41Sopenharmony_ci  int graph_hash_before_scheduling = 0;
29551cb0ef41Sopenharmony_ci  if (FLAG_turbo_profiling || profile_data != nullptr) {
29561cb0ef41Sopenharmony_ci    graph_hash_before_scheduling = HashGraphForPGO(data.graph());
29571cb0ef41Sopenharmony_ci  }
29581cb0ef41Sopenharmony_ci
29591cb0ef41Sopenharmony_ci  if (profile_data != nullptr &&
29601cb0ef41Sopenharmony_ci      profile_data->hash() != graph_hash_before_scheduling) {
29611cb0ef41Sopenharmony_ci    PrintF("Rejected profile data for %s due to function change\n", debug_name);
29621cb0ef41Sopenharmony_ci    profile_data = nullptr;
29631cb0ef41Sopenharmony_ci    data.set_profile_data(profile_data);
29641cb0ef41Sopenharmony_ci  }
29651cb0ef41Sopenharmony_ci
29661cb0ef41Sopenharmony_ci  pipeline.ComputeScheduledGraph();
29671cb0ef41Sopenharmony_ci  DCHECK_NOT_NULL(data.schedule());
29681cb0ef41Sopenharmony_ci
29691cb0ef41Sopenharmony_ci  // First run code generation on a copy of the pipeline, in order to be able to
29701cb0ef41Sopenharmony_ci  // repeat it for jump optimization. The first run has to happen on a temporary
29711cb0ef41Sopenharmony_ci  // pipeline to avoid deletion of zones on the main pipeline.
29721cb0ef41Sopenharmony_ci  PipelineData second_data(&zone_stats, &info, isolate, isolate->allocator(),
29731cb0ef41Sopenharmony_ci                           data.graph(), data.jsgraph(), data.schedule(),
29741cb0ef41Sopenharmony_ci                           data.source_positions(), data.node_origins(),
29751cb0ef41Sopenharmony_ci                           data.jump_optimization_info(), options,
29761cb0ef41Sopenharmony_ci                           profile_data);
29771cb0ef41Sopenharmony_ci  PipelineJobScope second_scope(&second_data,
29781cb0ef41Sopenharmony_ci                                isolate->counters()->runtime_call_stats());
29791cb0ef41Sopenharmony_ci  second_data.set_verify_graph(FLAG_verify_csa);
29801cb0ef41Sopenharmony_ci  PipelineImpl second_pipeline(&second_data);
29811cb0ef41Sopenharmony_ci  second_pipeline.SelectInstructionsAndAssemble(call_descriptor);
29821cb0ef41Sopenharmony_ci
29831cb0ef41Sopenharmony_ci  if (FLAG_turbo_profiling) {
29841cb0ef41Sopenharmony_ci    info.profiler_data()->SetHash(graph_hash_before_scheduling);
29851cb0ef41Sopenharmony_ci  }
29861cb0ef41Sopenharmony_ci
29871cb0ef41Sopenharmony_ci  if (jump_opt.is_optimizable()) {
29881cb0ef41Sopenharmony_ci    jump_opt.set_optimizing();
29891cb0ef41Sopenharmony_ci    return pipeline.GenerateCode(call_descriptor);
29901cb0ef41Sopenharmony_ci  } else {
29911cb0ef41Sopenharmony_ci    return second_pipeline.FinalizeCode();
29921cb0ef41Sopenharmony_ci  }
29931cb0ef41Sopenharmony_ci}
29941cb0ef41Sopenharmony_ci
29951cb0ef41Sopenharmony_cistruct BlockStartsAsJSON {
29961cb0ef41Sopenharmony_ci  const ZoneVector<int>* block_starts;
29971cb0ef41Sopenharmony_ci};
29981cb0ef41Sopenharmony_ci
29991cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream& out, const BlockStartsAsJSON& s) {
30001cb0ef41Sopenharmony_ci  out << ", \"blockIdToOffset\": {";
30011cb0ef41Sopenharmony_ci  bool need_comma = false;
30021cb0ef41Sopenharmony_ci  for (size_t i = 0; i < s.block_starts->size(); ++i) {
30031cb0ef41Sopenharmony_ci    if (need_comma) out << ", ";
30041cb0ef41Sopenharmony_ci    int offset = (*s.block_starts)[i];
30051cb0ef41Sopenharmony_ci    out << "\"" << i << "\":" << offset;
30061cb0ef41Sopenharmony_ci    need_comma = true;
30071cb0ef41Sopenharmony_ci  }
30081cb0ef41Sopenharmony_ci  out << "},";
30091cb0ef41Sopenharmony_ci  return out;
30101cb0ef41Sopenharmony_ci}
30111cb0ef41Sopenharmony_ci
30121cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
30131cb0ef41Sopenharmony_ci// static
30141cb0ef41Sopenharmony_ciwasm::WasmCompilationResult Pipeline::GenerateCodeForWasmNativeStub(
30151cb0ef41Sopenharmony_ci    CallDescriptor* call_descriptor, MachineGraph* mcgraph, CodeKind kind,
30161cb0ef41Sopenharmony_ci    const char* debug_name, const AssemblerOptions& options,
30171cb0ef41Sopenharmony_ci    SourcePositionTable* source_positions) {
30181cb0ef41Sopenharmony_ci  Graph* graph = mcgraph->graph();
30191cb0ef41Sopenharmony_ci  OptimizedCompilationInfo info(base::CStrVector(debug_name), graph->zone(),
30201cb0ef41Sopenharmony_ci                                kind);
30211cb0ef41Sopenharmony_ci  // Construct a pipeline for scheduling and code generation.
30221cb0ef41Sopenharmony_ci  wasm::WasmEngine* wasm_engine = wasm::GetWasmEngine();
30231cb0ef41Sopenharmony_ci  ZoneStats zone_stats(wasm_engine->allocator());
30241cb0ef41Sopenharmony_ci  NodeOriginTable* node_positions = graph->zone()->New<NodeOriginTable>(graph);
30251cb0ef41Sopenharmony_ci  PipelineData data(&zone_stats, wasm_engine, &info, mcgraph, nullptr,
30261cb0ef41Sopenharmony_ci                    source_positions, node_positions, options);
30271cb0ef41Sopenharmony_ci  std::unique_ptr<PipelineStatistics> pipeline_statistics;
30281cb0ef41Sopenharmony_ci  if (FLAG_turbo_stats || FLAG_turbo_stats_nvp) {
30291cb0ef41Sopenharmony_ci    pipeline_statistics.reset(new PipelineStatistics(
30301cb0ef41Sopenharmony_ci        &info, wasm_engine->GetOrCreateTurboStatistics(), &zone_stats));
30311cb0ef41Sopenharmony_ci    pipeline_statistics->BeginPhaseKind("V8.WasmStubCodegen");
30321cb0ef41Sopenharmony_ci  }
30331cb0ef41Sopenharmony_ci
30341cb0ef41Sopenharmony_ci  PipelineImpl pipeline(&data);
30351cb0ef41Sopenharmony_ci
30361cb0ef41Sopenharmony_ci  if (info.trace_turbo_json() || info.trace_turbo_graph()) {
30371cb0ef41Sopenharmony_ci    CodeTracer::StreamScope tracing_scope(data.GetCodeTracer());
30381cb0ef41Sopenharmony_ci    tracing_scope.stream()
30391cb0ef41Sopenharmony_ci        << "---------------------------------------------------\n"
30401cb0ef41Sopenharmony_ci        << "Begin compiling method " << info.GetDebugName().get()
30411cb0ef41Sopenharmony_ci        << " using TurboFan" << std::endl;
30421cb0ef41Sopenharmony_ci  }
30431cb0ef41Sopenharmony_ci
30441cb0ef41Sopenharmony_ci  if (info.trace_turbo_graph()) {  // Simple textual RPO.
30451cb0ef41Sopenharmony_ci    StdoutStream{} << "-- wasm stub " << CodeKindToString(kind) << " graph -- "
30461cb0ef41Sopenharmony_ci                   << std::endl
30471cb0ef41Sopenharmony_ci                   << AsRPO(*graph);
30481cb0ef41Sopenharmony_ci  }
30491cb0ef41Sopenharmony_ci
30501cb0ef41Sopenharmony_ci  if (info.trace_turbo_json()) {
30511cb0ef41Sopenharmony_ci    TurboJsonFile json_of(&info, std::ios_base::trunc);
30521cb0ef41Sopenharmony_ci    json_of << "{\"function\":\"" << info.GetDebugName().get()
30531cb0ef41Sopenharmony_ci            << "\", \"source\":\"\",\n\"phases\":[";
30541cb0ef41Sopenharmony_ci  }
30551cb0ef41Sopenharmony_ci
30561cb0ef41Sopenharmony_ci  pipeline.RunPrintAndVerify("V8.WasmNativeStubMachineCode", true);
30571cb0ef41Sopenharmony_ci
30581cb0ef41Sopenharmony_ci  pipeline.Run<MemoryOptimizationPhase>();
30591cb0ef41Sopenharmony_ci  pipeline.RunPrintAndVerify(MemoryOptimizationPhase::phase_name(), true);
30601cb0ef41Sopenharmony_ci
30611cb0ef41Sopenharmony_ci  pipeline.ComputeScheduledGraph();
30621cb0ef41Sopenharmony_ci
30631cb0ef41Sopenharmony_ci  Linkage linkage(call_descriptor);
30641cb0ef41Sopenharmony_ci  CHECK(pipeline.SelectInstructions(&linkage));
30651cb0ef41Sopenharmony_ci  pipeline.AssembleCode(&linkage);
30661cb0ef41Sopenharmony_ci
30671cb0ef41Sopenharmony_ci  CodeGenerator* code_generator = pipeline.code_generator();
30681cb0ef41Sopenharmony_ci  wasm::WasmCompilationResult result;
30691cb0ef41Sopenharmony_ci  code_generator->tasm()->GetCode(
30701cb0ef41Sopenharmony_ci      nullptr, &result.code_desc, code_generator->safepoint_table_builder(),
30711cb0ef41Sopenharmony_ci      static_cast<int>(code_generator->handler_table_offset()));
30721cb0ef41Sopenharmony_ci  result.instr_buffer = code_generator->tasm()->ReleaseBuffer();
30731cb0ef41Sopenharmony_ci  result.source_positions = code_generator->GetSourcePositionTable();
30741cb0ef41Sopenharmony_ci  result.protected_instructions_data =
30751cb0ef41Sopenharmony_ci      code_generator->GetProtectedInstructionsData();
30761cb0ef41Sopenharmony_ci  result.frame_slot_count = code_generator->frame()->GetTotalFrameSlotCount();
30771cb0ef41Sopenharmony_ci  result.tagged_parameter_slots = call_descriptor->GetTaggedParameterSlots();
30781cb0ef41Sopenharmony_ci  result.result_tier = wasm::ExecutionTier::kTurbofan;
30791cb0ef41Sopenharmony_ci  if (kind == CodeKind::WASM_TO_JS_FUNCTION) {
30801cb0ef41Sopenharmony_ci    result.kind = wasm::WasmCompilationResult::kWasmToJsWrapper;
30811cb0ef41Sopenharmony_ci  }
30821cb0ef41Sopenharmony_ci
30831cb0ef41Sopenharmony_ci  DCHECK(result.succeeded());
30841cb0ef41Sopenharmony_ci
30851cb0ef41Sopenharmony_ci  if (info.trace_turbo_json()) {
30861cb0ef41Sopenharmony_ci    TurboJsonFile json_of(&info, std::ios_base::app);
30871cb0ef41Sopenharmony_ci    json_of << "{\"name\":\"disassembly\",\"type\":\"disassembly\""
30881cb0ef41Sopenharmony_ci            << BlockStartsAsJSON{&code_generator->block_starts()}
30891cb0ef41Sopenharmony_ci            << "\"data\":\"";
30901cb0ef41Sopenharmony_ci#ifdef ENABLE_DISASSEMBLER
30911cb0ef41Sopenharmony_ci    std::stringstream disassembler_stream;
30921cb0ef41Sopenharmony_ci    Disassembler::Decode(
30931cb0ef41Sopenharmony_ci        nullptr, disassembler_stream, result.code_desc.buffer,
30941cb0ef41Sopenharmony_ci        result.code_desc.buffer + result.code_desc.safepoint_table_offset,
30951cb0ef41Sopenharmony_ci        CodeReference(&result.code_desc));
30961cb0ef41Sopenharmony_ci    for (auto const c : disassembler_stream.str()) {
30971cb0ef41Sopenharmony_ci      json_of << AsEscapedUC16ForJSON(c);
30981cb0ef41Sopenharmony_ci    }
30991cb0ef41Sopenharmony_ci#endif  // ENABLE_DISASSEMBLER
31001cb0ef41Sopenharmony_ci    json_of << "\"}\n]";
31011cb0ef41Sopenharmony_ci    json_of << "\n}";
31021cb0ef41Sopenharmony_ci  }
31031cb0ef41Sopenharmony_ci
31041cb0ef41Sopenharmony_ci  if (info.trace_turbo_json() || info.trace_turbo_graph()) {
31051cb0ef41Sopenharmony_ci    CodeTracer::StreamScope tracing_scope(data.GetCodeTracer());
31061cb0ef41Sopenharmony_ci    tracing_scope.stream()
31071cb0ef41Sopenharmony_ci        << "---------------------------------------------------\n"
31081cb0ef41Sopenharmony_ci        << "Finished compiling method " << info.GetDebugName().get()
31091cb0ef41Sopenharmony_ci        << " using TurboFan" << std::endl;
31101cb0ef41Sopenharmony_ci  }
31111cb0ef41Sopenharmony_ci
31121cb0ef41Sopenharmony_ci  return result;
31131cb0ef41Sopenharmony_ci}
31141cb0ef41Sopenharmony_ci
31151cb0ef41Sopenharmony_ci// static
31161cb0ef41Sopenharmony_civoid Pipeline::GenerateCodeForWasmFunction(
31171cb0ef41Sopenharmony_ci    OptimizedCompilationInfo* info, wasm::CompilationEnv* env,
31181cb0ef41Sopenharmony_ci    const wasm::WireBytesStorage* wire_bytes_storage, MachineGraph* mcgraph,
31191cb0ef41Sopenharmony_ci    CallDescriptor* call_descriptor, SourcePositionTable* source_positions,
31201cb0ef41Sopenharmony_ci    NodeOriginTable* node_origins, wasm::FunctionBody function_body,
31211cb0ef41Sopenharmony_ci    const wasm::WasmModule* module, int function_index,
31221cb0ef41Sopenharmony_ci    std::vector<compiler::WasmLoopInfo>* loop_info) {
31231cb0ef41Sopenharmony_ci  auto* wasm_engine = wasm::GetWasmEngine();
31241cb0ef41Sopenharmony_ci  base::TimeTicks start_time;
31251cb0ef41Sopenharmony_ci  if (V8_UNLIKELY(FLAG_trace_wasm_compilation_times)) {
31261cb0ef41Sopenharmony_ci    start_time = base::TimeTicks::Now();
31271cb0ef41Sopenharmony_ci  }
31281cb0ef41Sopenharmony_ci  ZoneStats zone_stats(wasm_engine->allocator());
31291cb0ef41Sopenharmony_ci  std::unique_ptr<PipelineStatistics> pipeline_statistics(
31301cb0ef41Sopenharmony_ci      CreatePipelineStatistics(function_body, module, info, &zone_stats));
31311cb0ef41Sopenharmony_ci  PipelineData data(&zone_stats, wasm_engine, info, mcgraph,
31321cb0ef41Sopenharmony_ci                    pipeline_statistics.get(), source_positions, node_origins,
31331cb0ef41Sopenharmony_ci                    WasmAssemblerOptions());
31341cb0ef41Sopenharmony_ci
31351cb0ef41Sopenharmony_ci  PipelineImpl pipeline(&data);
31361cb0ef41Sopenharmony_ci
31371cb0ef41Sopenharmony_ci  if (data.info()->trace_turbo_json() || data.info()->trace_turbo_graph()) {
31381cb0ef41Sopenharmony_ci    CodeTracer::StreamScope tracing_scope(data.GetCodeTracer());
31391cb0ef41Sopenharmony_ci    tracing_scope.stream()
31401cb0ef41Sopenharmony_ci        << "---------------------------------------------------\n"
31411cb0ef41Sopenharmony_ci        << "Begin compiling method " << data.info()->GetDebugName().get()
31421cb0ef41Sopenharmony_ci        << " using TurboFan" << std::endl;
31431cb0ef41Sopenharmony_ci  }
31441cb0ef41Sopenharmony_ci
31451cb0ef41Sopenharmony_ci  pipeline.RunPrintAndVerify("V8.WasmMachineCode", true);
31461cb0ef41Sopenharmony_ci
31471cb0ef41Sopenharmony_ci  data.BeginPhaseKind("V8.WasmOptimization");
31481cb0ef41Sopenharmony_ci  if (FLAG_wasm_inlining) {
31491cb0ef41Sopenharmony_ci    pipeline.Run<WasmInliningPhase>(env, function_index, wire_bytes_storage,
31501cb0ef41Sopenharmony_ci                                    loop_info);
31511cb0ef41Sopenharmony_ci    pipeline.RunPrintAndVerify(WasmInliningPhase::phase_name(), true);
31521cb0ef41Sopenharmony_ci  }
31531cb0ef41Sopenharmony_ci  if (FLAG_wasm_loop_peeling) {
31541cb0ef41Sopenharmony_ci    pipeline.Run<WasmLoopPeelingPhase>(loop_info);
31551cb0ef41Sopenharmony_ci    pipeline.RunPrintAndVerify(WasmLoopPeelingPhase::phase_name(), true);
31561cb0ef41Sopenharmony_ci  }
31571cb0ef41Sopenharmony_ci  if (FLAG_wasm_loop_unrolling) {
31581cb0ef41Sopenharmony_ci    pipeline.Run<WasmLoopUnrollingPhase>(loop_info);
31591cb0ef41Sopenharmony_ci    pipeline.RunPrintAndVerify(WasmLoopUnrollingPhase::phase_name(), true);
31601cb0ef41Sopenharmony_ci  }
31611cb0ef41Sopenharmony_ci  const bool is_asm_js = is_asmjs_module(module);
31621cb0ef41Sopenharmony_ci
31631cb0ef41Sopenharmony_ci  if (FLAG_wasm_opt || is_asm_js) {
31641cb0ef41Sopenharmony_ci    pipeline.Run<WasmOptimizationPhase>(is_asm_js);
31651cb0ef41Sopenharmony_ci    pipeline.RunPrintAndVerify(WasmOptimizationPhase::phase_name(), true);
31661cb0ef41Sopenharmony_ci  } else {
31671cb0ef41Sopenharmony_ci    pipeline.Run<WasmBaseOptimizationPhase>();
31681cb0ef41Sopenharmony_ci    pipeline.RunPrintAndVerify(WasmBaseOptimizationPhase::phase_name(), true);
31691cb0ef41Sopenharmony_ci  }
31701cb0ef41Sopenharmony_ci
31711cb0ef41Sopenharmony_ci  pipeline.Run<MemoryOptimizationPhase>();
31721cb0ef41Sopenharmony_ci  pipeline.RunPrintAndVerify(MemoryOptimizationPhase::phase_name(), true);
31731cb0ef41Sopenharmony_ci
31741cb0ef41Sopenharmony_ci  if (FLAG_turbo_splitting && !is_asm_js) {
31751cb0ef41Sopenharmony_ci    data.info()->set_splitting();
31761cb0ef41Sopenharmony_ci  }
31771cb0ef41Sopenharmony_ci
31781cb0ef41Sopenharmony_ci  if (data.node_origins()) {
31791cb0ef41Sopenharmony_ci    data.node_origins()->RemoveDecorator();
31801cb0ef41Sopenharmony_ci  }
31811cb0ef41Sopenharmony_ci
31821cb0ef41Sopenharmony_ci  data.BeginPhaseKind("V8.InstructionSelection");
31831cb0ef41Sopenharmony_ci  pipeline.ComputeScheduledGraph();
31841cb0ef41Sopenharmony_ci
31851cb0ef41Sopenharmony_ci  Linkage linkage(call_descriptor);
31861cb0ef41Sopenharmony_ci  if (!pipeline.SelectInstructions(&linkage)) return;
31871cb0ef41Sopenharmony_ci  pipeline.AssembleCode(&linkage);
31881cb0ef41Sopenharmony_ci
31891cb0ef41Sopenharmony_ci  auto result = std::make_unique<wasm::WasmCompilationResult>();
31901cb0ef41Sopenharmony_ci  CodeGenerator* code_generator = pipeline.code_generator();
31911cb0ef41Sopenharmony_ci  code_generator->tasm()->GetCode(
31921cb0ef41Sopenharmony_ci      nullptr, &result->code_desc, code_generator->safepoint_table_builder(),
31931cb0ef41Sopenharmony_ci      static_cast<int>(code_generator->handler_table_offset()));
31941cb0ef41Sopenharmony_ci
31951cb0ef41Sopenharmony_ci  result->instr_buffer = code_generator->tasm()->ReleaseBuffer();
31961cb0ef41Sopenharmony_ci  result->frame_slot_count = code_generator->frame()->GetTotalFrameSlotCount();
31971cb0ef41Sopenharmony_ci  result->tagged_parameter_slots = call_descriptor->GetTaggedParameterSlots();
31981cb0ef41Sopenharmony_ci  result->source_positions = code_generator->GetSourcePositionTable();
31991cb0ef41Sopenharmony_ci  result->protected_instructions_data =
32001cb0ef41Sopenharmony_ci      code_generator->GetProtectedInstructionsData();
32011cb0ef41Sopenharmony_ci  result->result_tier = wasm::ExecutionTier::kTurbofan;
32021cb0ef41Sopenharmony_ci
32031cb0ef41Sopenharmony_ci  if (data.info()->trace_turbo_json()) {
32041cb0ef41Sopenharmony_ci    TurboJsonFile json_of(data.info(), std::ios_base::app);
32051cb0ef41Sopenharmony_ci    json_of << "{\"name\":\"disassembly\",\"type\":\"disassembly\""
32061cb0ef41Sopenharmony_ci            << BlockStartsAsJSON{&code_generator->block_starts()}
32071cb0ef41Sopenharmony_ci            << "\"data\":\"";
32081cb0ef41Sopenharmony_ci#ifdef ENABLE_DISASSEMBLER
32091cb0ef41Sopenharmony_ci    std::stringstream disassembler_stream;
32101cb0ef41Sopenharmony_ci    Disassembler::Decode(
32111cb0ef41Sopenharmony_ci        nullptr, disassembler_stream, result->code_desc.buffer,
32121cb0ef41Sopenharmony_ci        result->code_desc.buffer + result->code_desc.safepoint_table_offset,
32131cb0ef41Sopenharmony_ci        CodeReference(&result->code_desc));
32141cb0ef41Sopenharmony_ci    for (auto const c : disassembler_stream.str()) {
32151cb0ef41Sopenharmony_ci      json_of << AsEscapedUC16ForJSON(c);
32161cb0ef41Sopenharmony_ci    }
32171cb0ef41Sopenharmony_ci#endif  // ENABLE_DISASSEMBLER
32181cb0ef41Sopenharmony_ci    json_of << "\"}\n]";
32191cb0ef41Sopenharmony_ci    json_of << "\n}";
32201cb0ef41Sopenharmony_ci  }
32211cb0ef41Sopenharmony_ci
32221cb0ef41Sopenharmony_ci  if (data.info()->trace_turbo_json() || data.info()->trace_turbo_graph()) {
32231cb0ef41Sopenharmony_ci    CodeTracer::StreamScope tracing_scope(data.GetCodeTracer());
32241cb0ef41Sopenharmony_ci    tracing_scope.stream()
32251cb0ef41Sopenharmony_ci        << "---------------------------------------------------\n"
32261cb0ef41Sopenharmony_ci        << "Finished compiling method " << data.info()->GetDebugName().get()
32271cb0ef41Sopenharmony_ci        << " using TurboFan" << std::endl;
32281cb0ef41Sopenharmony_ci  }
32291cb0ef41Sopenharmony_ci
32301cb0ef41Sopenharmony_ci  if (V8_UNLIKELY(FLAG_trace_wasm_compilation_times)) {
32311cb0ef41Sopenharmony_ci    base::TimeDelta time = base::TimeTicks::Now() - start_time;
32321cb0ef41Sopenharmony_ci    int codesize = result->code_desc.body_size();
32331cb0ef41Sopenharmony_ci    StdoutStream{} << "Compiled function "
32341cb0ef41Sopenharmony_ci                   << reinterpret_cast<const void*>(module) << "#"
32351cb0ef41Sopenharmony_ci                   << function_index << " using TurboFan, took "
32361cb0ef41Sopenharmony_ci                   << time.InMilliseconds() << " ms and "
32371cb0ef41Sopenharmony_ci                   << zone_stats.GetMaxAllocatedBytes() << " / "
32381cb0ef41Sopenharmony_ci                   << zone_stats.GetTotalAllocatedBytes()
32391cb0ef41Sopenharmony_ci                   << " max/total bytes; bodysize "
32401cb0ef41Sopenharmony_ci                   << function_body.end - function_body.start << " codesize "
32411cb0ef41Sopenharmony_ci                   << codesize << " name " << data.info()->GetDebugName().get()
32421cb0ef41Sopenharmony_ci                   << std::endl;
32431cb0ef41Sopenharmony_ci  }
32441cb0ef41Sopenharmony_ci
32451cb0ef41Sopenharmony_ci  DCHECK(result->succeeded());
32461cb0ef41Sopenharmony_ci  info->SetWasmCompilationResult(std::move(result));
32471cb0ef41Sopenharmony_ci}
32481cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
32491cb0ef41Sopenharmony_ci
32501cb0ef41Sopenharmony_ci// static
32511cb0ef41Sopenharmony_ciMaybeHandle<Code> Pipeline::GenerateCodeForTesting(
32521cb0ef41Sopenharmony_ci    OptimizedCompilationInfo* info, Isolate* isolate,
32531cb0ef41Sopenharmony_ci    std::unique_ptr<JSHeapBroker>* out_broker) {
32541cb0ef41Sopenharmony_ci  ZoneStats zone_stats(isolate->allocator());
32551cb0ef41Sopenharmony_ci  std::unique_ptr<PipelineStatistics> pipeline_statistics(
32561cb0ef41Sopenharmony_ci      CreatePipelineStatistics(Handle<Script>::null(), info, isolate,
32571cb0ef41Sopenharmony_ci                               &zone_stats));
32581cb0ef41Sopenharmony_ci
32591cb0ef41Sopenharmony_ci  PipelineData data(&zone_stats, isolate, info, pipeline_statistics.get());
32601cb0ef41Sopenharmony_ci  PipelineImpl pipeline(&data);
32611cb0ef41Sopenharmony_ci
32621cb0ef41Sopenharmony_ci  Linkage linkage(Linkage::ComputeIncoming(data.instruction_zone(), info));
32631cb0ef41Sopenharmony_ci
32641cb0ef41Sopenharmony_ci  {
32651cb0ef41Sopenharmony_ci    CompilationHandleScope compilation_scope(isolate, info);
32661cb0ef41Sopenharmony_ci    CanonicalHandleScopeForTurbofan canonical(isolate, info);
32671cb0ef41Sopenharmony_ci    info->ReopenHandlesInNewHandleScope(isolate);
32681cb0ef41Sopenharmony_ci    pipeline.InitializeHeapBroker();
32691cb0ef41Sopenharmony_ci  }
32701cb0ef41Sopenharmony_ci
32711cb0ef41Sopenharmony_ci  {
32721cb0ef41Sopenharmony_ci    LocalIsolateScope local_isolate_scope(data.broker(), info,
32731cb0ef41Sopenharmony_ci                                          isolate->main_thread_local_isolate());
32741cb0ef41Sopenharmony_ci    if (!pipeline.CreateGraph()) return MaybeHandle<Code>();
32751cb0ef41Sopenharmony_ci    // We selectively Unpark inside OptimizeGraph.
32761cb0ef41Sopenharmony_ci    if (!pipeline.OptimizeGraph(&linkage)) return MaybeHandle<Code>();
32771cb0ef41Sopenharmony_ci
32781cb0ef41Sopenharmony_ci    pipeline.AssembleCode(&linkage);
32791cb0ef41Sopenharmony_ci  }
32801cb0ef41Sopenharmony_ci
32811cb0ef41Sopenharmony_ci  const bool will_retire_broker = out_broker == nullptr;
32821cb0ef41Sopenharmony_ci  if (!will_retire_broker) {
32831cb0ef41Sopenharmony_ci    // If the broker is going to be kept alive, pass the persistent and the
32841cb0ef41Sopenharmony_ci    // canonical handles containers back to the JSHeapBroker since it will
32851cb0ef41Sopenharmony_ci    // outlive the OptimizedCompilationInfo.
32861cb0ef41Sopenharmony_ci    data.broker()->SetPersistentAndCopyCanonicalHandlesForTesting(
32871cb0ef41Sopenharmony_ci        info->DetachPersistentHandles(), info->DetachCanonicalHandles());
32881cb0ef41Sopenharmony_ci  }
32891cb0ef41Sopenharmony_ci
32901cb0ef41Sopenharmony_ci  Handle<Code> code;
32911cb0ef41Sopenharmony_ci  if (pipeline.FinalizeCode(will_retire_broker).ToHandle(&code) &&
32921cb0ef41Sopenharmony_ci      pipeline.CommitDependencies(code)) {
32931cb0ef41Sopenharmony_ci    if (!will_retire_broker) *out_broker = data.ReleaseBroker();
32941cb0ef41Sopenharmony_ci    return code;
32951cb0ef41Sopenharmony_ci  }
32961cb0ef41Sopenharmony_ci  return MaybeHandle<Code>();
32971cb0ef41Sopenharmony_ci}
32981cb0ef41Sopenharmony_ci
32991cb0ef41Sopenharmony_ci// static
33001cb0ef41Sopenharmony_ciMaybeHandle<Code> Pipeline::GenerateCodeForTesting(
33011cb0ef41Sopenharmony_ci    OptimizedCompilationInfo* info, Isolate* isolate,
33021cb0ef41Sopenharmony_ci    CallDescriptor* call_descriptor, Graph* graph,
33031cb0ef41Sopenharmony_ci    const AssemblerOptions& options, Schedule* schedule) {
33041cb0ef41Sopenharmony_ci  // Construct a pipeline for scheduling and code generation.
33051cb0ef41Sopenharmony_ci  ZoneStats zone_stats(isolate->allocator());
33061cb0ef41Sopenharmony_ci  NodeOriginTable* node_positions = info->zone()->New<NodeOriginTable>(graph);
33071cb0ef41Sopenharmony_ci  PipelineData data(&zone_stats, info, isolate, isolate->allocator(), graph,
33081cb0ef41Sopenharmony_ci                    nullptr, schedule, nullptr, node_positions, nullptr,
33091cb0ef41Sopenharmony_ci                    options, nullptr);
33101cb0ef41Sopenharmony_ci  std::unique_ptr<PipelineStatistics> pipeline_statistics;
33111cb0ef41Sopenharmony_ci  if (FLAG_turbo_stats || FLAG_turbo_stats_nvp) {
33121cb0ef41Sopenharmony_ci    pipeline_statistics.reset(new PipelineStatistics(
33131cb0ef41Sopenharmony_ci        info, isolate->GetTurboStatistics(), &zone_stats));
33141cb0ef41Sopenharmony_ci    pipeline_statistics->BeginPhaseKind("V8.TFTestCodegen");
33151cb0ef41Sopenharmony_ci  }
33161cb0ef41Sopenharmony_ci
33171cb0ef41Sopenharmony_ci  PipelineImpl pipeline(&data);
33181cb0ef41Sopenharmony_ci
33191cb0ef41Sopenharmony_ci  if (info->trace_turbo_json()) {
33201cb0ef41Sopenharmony_ci    TurboJsonFile json_of(info, std::ios_base::trunc);
33211cb0ef41Sopenharmony_ci    json_of << "{\"function\":\"" << info->GetDebugName().get()
33221cb0ef41Sopenharmony_ci            << "\", \"source\":\"\",\n\"phases\":[";
33231cb0ef41Sopenharmony_ci  }
33241cb0ef41Sopenharmony_ci  // TODO(rossberg): Should this really be untyped?
33251cb0ef41Sopenharmony_ci  pipeline.RunPrintAndVerify("V8.TFMachineCode", true);
33261cb0ef41Sopenharmony_ci
33271cb0ef41Sopenharmony_ci  // Ensure we have a schedule.
33281cb0ef41Sopenharmony_ci  if (data.schedule() == nullptr) {
33291cb0ef41Sopenharmony_ci    pipeline.ComputeScheduledGraph();
33301cb0ef41Sopenharmony_ci  }
33311cb0ef41Sopenharmony_ci
33321cb0ef41Sopenharmony_ci  Handle<Code> code;
33331cb0ef41Sopenharmony_ci  if (pipeline.GenerateCode(call_descriptor).ToHandle(&code) &&
33341cb0ef41Sopenharmony_ci      pipeline.CommitDependencies(code)) {
33351cb0ef41Sopenharmony_ci    return code;
33361cb0ef41Sopenharmony_ci  }
33371cb0ef41Sopenharmony_ci  return MaybeHandle<Code>();
33381cb0ef41Sopenharmony_ci}
33391cb0ef41Sopenharmony_ci
33401cb0ef41Sopenharmony_ci// static
33411cb0ef41Sopenharmony_cistd::unique_ptr<TurbofanCompilationJob> Pipeline::NewCompilationJob(
33421cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<JSFunction> function, CodeKind code_kind,
33431cb0ef41Sopenharmony_ci    bool has_script, BytecodeOffset osr_offset, JavaScriptFrame* osr_frame) {
33441cb0ef41Sopenharmony_ci  Handle<SharedFunctionInfo> shared(function->shared(), isolate);
33451cb0ef41Sopenharmony_ci  return std::make_unique<PipelineCompilationJob>(
33461cb0ef41Sopenharmony_ci      isolate, shared, function, osr_offset, osr_frame, code_kind);
33471cb0ef41Sopenharmony_ci}
33481cb0ef41Sopenharmony_ci
33491cb0ef41Sopenharmony_cibool Pipeline::AllocateRegistersForTesting(const RegisterConfiguration* config,
33501cb0ef41Sopenharmony_ci                                           InstructionSequence* sequence,
33511cb0ef41Sopenharmony_ci                                           bool use_mid_tier_register_allocator,
33521cb0ef41Sopenharmony_ci                                           bool run_verifier) {
33531cb0ef41Sopenharmony_ci  OptimizedCompilationInfo info(base::ArrayVector("testing"), sequence->zone(),
33541cb0ef41Sopenharmony_ci                                CodeKind::FOR_TESTING);
33551cb0ef41Sopenharmony_ci  ZoneStats zone_stats(sequence->isolate()->allocator());
33561cb0ef41Sopenharmony_ci  PipelineData data(&zone_stats, &info, sequence->isolate(), sequence);
33571cb0ef41Sopenharmony_ci  data.InitializeFrameData(nullptr);
33581cb0ef41Sopenharmony_ci
33591cb0ef41Sopenharmony_ci  if (info.trace_turbo_json()) {
33601cb0ef41Sopenharmony_ci    TurboJsonFile json_of(&info, std::ios_base::trunc);
33611cb0ef41Sopenharmony_ci    json_of << "{\"function\":\"" << info.GetDebugName().get()
33621cb0ef41Sopenharmony_ci            << "\", \"source\":\"\",\n\"phases\":[";
33631cb0ef41Sopenharmony_ci  }
33641cb0ef41Sopenharmony_ci
33651cb0ef41Sopenharmony_ci  PipelineImpl pipeline(&data);
33661cb0ef41Sopenharmony_ci  if (use_mid_tier_register_allocator) {
33671cb0ef41Sopenharmony_ci    pipeline.AllocateRegistersForMidTier(config, nullptr, run_verifier);
33681cb0ef41Sopenharmony_ci  } else {
33691cb0ef41Sopenharmony_ci    pipeline.AllocateRegistersForTopTier(config, nullptr, run_verifier);
33701cb0ef41Sopenharmony_ci  }
33711cb0ef41Sopenharmony_ci
33721cb0ef41Sopenharmony_ci  return !data.compilation_failed();
33731cb0ef41Sopenharmony_ci}
33741cb0ef41Sopenharmony_ci
33751cb0ef41Sopenharmony_civoid PipelineImpl::ComputeScheduledGraph() {
33761cb0ef41Sopenharmony_ci  PipelineData* data = this->data_;
33771cb0ef41Sopenharmony_ci
33781cb0ef41Sopenharmony_ci  // We should only schedule the graph if it is not scheduled yet.
33791cb0ef41Sopenharmony_ci  DCHECK_NULL(data->schedule());
33801cb0ef41Sopenharmony_ci
33811cb0ef41Sopenharmony_ci  Run<ComputeSchedulePhase>();
33821cb0ef41Sopenharmony_ci  TraceScheduleAndVerify(data->info(), data, data->schedule(), "schedule");
33831cb0ef41Sopenharmony_ci}
33841cb0ef41Sopenharmony_ci
33851cb0ef41Sopenharmony_cibool PipelineImpl::SelectInstructions(Linkage* linkage) {
33861cb0ef41Sopenharmony_ci  auto call_descriptor = linkage->GetIncomingDescriptor();
33871cb0ef41Sopenharmony_ci  PipelineData* data = this->data_;
33881cb0ef41Sopenharmony_ci
33891cb0ef41Sopenharmony_ci  // We should have a scheduled graph.
33901cb0ef41Sopenharmony_ci  DCHECK_NOT_NULL(data->graph());
33911cb0ef41Sopenharmony_ci  DCHECK_NOT_NULL(data->schedule());
33921cb0ef41Sopenharmony_ci
33931cb0ef41Sopenharmony_ci  if (FLAG_turbo_profiling) {
33941cb0ef41Sopenharmony_ci    UnparkedScopeIfNeeded unparked_scope(data->broker());
33951cb0ef41Sopenharmony_ci    data->info()->set_profiler_data(BasicBlockInstrumentor::Instrument(
33961cb0ef41Sopenharmony_ci        info(), data->graph(), data->schedule(), data->isolate()));
33971cb0ef41Sopenharmony_ci  }
33981cb0ef41Sopenharmony_ci
33991cb0ef41Sopenharmony_ci  bool verify_stub_graph =
34001cb0ef41Sopenharmony_ci      data->verify_graph() ||
34011cb0ef41Sopenharmony_ci      (FLAG_turbo_verify_machine_graph != nullptr &&
34021cb0ef41Sopenharmony_ci       (!strcmp(FLAG_turbo_verify_machine_graph, "*") ||
34031cb0ef41Sopenharmony_ci        !strcmp(FLAG_turbo_verify_machine_graph, data->debug_name())));
34041cb0ef41Sopenharmony_ci  // Jump optimization runs instruction selection twice, but the instruction
34051cb0ef41Sopenharmony_ci  // selector mutates nodes like swapping the inputs of a load, which can
34061cb0ef41Sopenharmony_ci  // violate the machine graph verification rules. So we skip the second
34071cb0ef41Sopenharmony_ci  // verification on a graph that already verified before.
34081cb0ef41Sopenharmony_ci  auto jump_opt = data->jump_optimization_info();
34091cb0ef41Sopenharmony_ci  if (jump_opt && jump_opt->is_optimizing()) {
34101cb0ef41Sopenharmony_ci    verify_stub_graph = false;
34111cb0ef41Sopenharmony_ci  }
34121cb0ef41Sopenharmony_ci  if (verify_stub_graph) {
34131cb0ef41Sopenharmony_ci    if (FLAG_trace_verify_csa) {
34141cb0ef41Sopenharmony_ci      UnparkedScopeIfNeeded scope(data->broker());
34151cb0ef41Sopenharmony_ci      AllowHandleDereference allow_deref;
34161cb0ef41Sopenharmony_ci      CodeTracer::StreamScope tracing_scope(data->GetCodeTracer());
34171cb0ef41Sopenharmony_ci      tracing_scope.stream()
34181cb0ef41Sopenharmony_ci          << "--------------------------------------------------\n"
34191cb0ef41Sopenharmony_ci          << "--- Verifying " << data->debug_name()
34201cb0ef41Sopenharmony_ci          << " generated by TurboFan\n"
34211cb0ef41Sopenharmony_ci          << "--------------------------------------------------\n"
34221cb0ef41Sopenharmony_ci          << *data->schedule()
34231cb0ef41Sopenharmony_ci          << "--------------------------------------------------\n"
34241cb0ef41Sopenharmony_ci          << "--- End of " << data->debug_name() << " generated by TurboFan\n"
34251cb0ef41Sopenharmony_ci          << "--------------------------------------------------\n";
34261cb0ef41Sopenharmony_ci    }
34271cb0ef41Sopenharmony_ci    // TODO(jgruber): The parameter is called is_stub but actually contains
34281cb0ef41Sopenharmony_ci    // something different. Update either the name or its contents.
34291cb0ef41Sopenharmony_ci    bool is_stub = !data->info()->IsOptimizing();
34301cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
34311cb0ef41Sopenharmony_ci    if (data->info()->IsWasm()) is_stub = false;
34321cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
34331cb0ef41Sopenharmony_ci    Zone temp_zone(data->allocator(), kMachineGraphVerifierZoneName);
34341cb0ef41Sopenharmony_ci    MachineGraphVerifier::Run(data->graph(), data->schedule(), linkage, is_stub,
34351cb0ef41Sopenharmony_ci                              data->debug_name(), &temp_zone);
34361cb0ef41Sopenharmony_ci  }
34371cb0ef41Sopenharmony_ci
34381cb0ef41Sopenharmony_ci  data->InitializeInstructionSequence(call_descriptor);
34391cb0ef41Sopenharmony_ci
34401cb0ef41Sopenharmony_ci  // Depending on which code path led us to this function, the frame may or
34411cb0ef41Sopenharmony_ci  // may not have been initialized. If it hasn't yet, initialize it now.
34421cb0ef41Sopenharmony_ci  if (!data->frame()) {
34431cb0ef41Sopenharmony_ci    data->InitializeFrameData(call_descriptor);
34441cb0ef41Sopenharmony_ci  }
34451cb0ef41Sopenharmony_ci  // Select and schedule instructions covering the scheduled graph.
34461cb0ef41Sopenharmony_ci  Run<InstructionSelectionPhase>(linkage);
34471cb0ef41Sopenharmony_ci  if (data->compilation_failed()) {
34481cb0ef41Sopenharmony_ci    info()->AbortOptimization(BailoutReason::kCodeGenerationFailed);
34491cb0ef41Sopenharmony_ci    data->EndPhaseKind();
34501cb0ef41Sopenharmony_ci    return false;
34511cb0ef41Sopenharmony_ci  }
34521cb0ef41Sopenharmony_ci
34531cb0ef41Sopenharmony_ci  if (info()->trace_turbo_json() && !data->MayHaveUnverifiableGraph()) {
34541cb0ef41Sopenharmony_ci    UnparkedScopeIfNeeded scope(data->broker());
34551cb0ef41Sopenharmony_ci    AllowHandleDereference allow_deref;
34561cb0ef41Sopenharmony_ci    TurboCfgFile tcf(isolate());
34571cb0ef41Sopenharmony_ci    tcf << AsC1V("CodeGen", data->schedule(), data->source_positions(),
34581cb0ef41Sopenharmony_ci                 data->sequence());
34591cb0ef41Sopenharmony_ci  }
34601cb0ef41Sopenharmony_ci
34611cb0ef41Sopenharmony_ci  if (info()->trace_turbo_json()) {
34621cb0ef41Sopenharmony_ci    std::ostringstream source_position_output;
34631cb0ef41Sopenharmony_ci    // Output source position information before the graph is deleted.
34641cb0ef41Sopenharmony_ci    if (data_->source_positions() != nullptr) {
34651cb0ef41Sopenharmony_ci      data_->source_positions()->PrintJson(source_position_output);
34661cb0ef41Sopenharmony_ci    } else {
34671cb0ef41Sopenharmony_ci      source_position_output << "{}";
34681cb0ef41Sopenharmony_ci    }
34691cb0ef41Sopenharmony_ci    source_position_output << ",\n\"NodeOrigins\" : ";
34701cb0ef41Sopenharmony_ci    data_->node_origins()->PrintJson(source_position_output);
34711cb0ef41Sopenharmony_ci    data_->set_source_position_output(source_position_output.str());
34721cb0ef41Sopenharmony_ci  }
34731cb0ef41Sopenharmony_ci
34741cb0ef41Sopenharmony_ci  data->DeleteGraphZone();
34751cb0ef41Sopenharmony_ci
34761cb0ef41Sopenharmony_ci  data->BeginPhaseKind("V8.TFRegisterAllocation");
34771cb0ef41Sopenharmony_ci
34781cb0ef41Sopenharmony_ci  bool run_verifier = FLAG_turbo_verify_allocation;
34791cb0ef41Sopenharmony_ci
34801cb0ef41Sopenharmony_ci  // Allocate registers.
34811cb0ef41Sopenharmony_ci
34821cb0ef41Sopenharmony_ci  // This limit is chosen somewhat arbitrarily, by looking at a few bigger
34831cb0ef41Sopenharmony_ci  // WebAssembly programs, and chosing the limit such that functions that take
34841cb0ef41Sopenharmony_ci  // >100ms in register allocation are switched to mid-tier.
34851cb0ef41Sopenharmony_ci  static int kTopTierVirtualRegistersLimit = 8192;
34861cb0ef41Sopenharmony_ci
34871cb0ef41Sopenharmony_ci  const RegisterConfiguration* config = RegisterConfiguration::Default();
34881cb0ef41Sopenharmony_ci  std::unique_ptr<const RegisterConfiguration> restricted_config;
34891cb0ef41Sopenharmony_ci  // The mid-tier register allocator keeps values in stack slots for too long.
34901cb0ef41Sopenharmony_ci  // This is incompatible with left-trimming, therefore we cannot enable it for
34911cb0ef41Sopenharmony_ci  // JS functions.
34921cb0ef41Sopenharmony_ci  bool use_mid_tier_register_allocator =
34931cb0ef41Sopenharmony_ci      data->info()->code_kind() == CodeKind::WASM_FUNCTION &&
34941cb0ef41Sopenharmony_ci      (FLAG_turbo_force_mid_tier_regalloc ||
34951cb0ef41Sopenharmony_ci       (FLAG_turbo_use_mid_tier_regalloc_for_huge_functions &&
34961cb0ef41Sopenharmony_ci        data->sequence()->VirtualRegisterCount() >
34971cb0ef41Sopenharmony_ci            kTopTierVirtualRegistersLimit));
34981cb0ef41Sopenharmony_ci
34991cb0ef41Sopenharmony_ci  if (call_descriptor->HasRestrictedAllocatableRegisters()) {
35001cb0ef41Sopenharmony_ci    RegList registers = call_descriptor->AllocatableRegisters();
35011cb0ef41Sopenharmony_ci    DCHECK_LT(0, registers.Count());
35021cb0ef41Sopenharmony_ci    restricted_config.reset(
35031cb0ef41Sopenharmony_ci        RegisterConfiguration::RestrictGeneralRegisters(registers));
35041cb0ef41Sopenharmony_ci    config = restricted_config.get();
35051cb0ef41Sopenharmony_ci    use_mid_tier_register_allocator = false;
35061cb0ef41Sopenharmony_ci  }
35071cb0ef41Sopenharmony_ci  if (use_mid_tier_register_allocator) {
35081cb0ef41Sopenharmony_ci    AllocateRegistersForMidTier(config, call_descriptor, run_verifier);
35091cb0ef41Sopenharmony_ci  } else {
35101cb0ef41Sopenharmony_ci    AllocateRegistersForTopTier(config, call_descriptor, run_verifier);
35111cb0ef41Sopenharmony_ci  }
35121cb0ef41Sopenharmony_ci
35131cb0ef41Sopenharmony_ci  // Verify the instruction sequence has the same hash in two stages.
35141cb0ef41Sopenharmony_ci  VerifyGeneratedCodeIsIdempotent();
35151cb0ef41Sopenharmony_ci
35161cb0ef41Sopenharmony_ci  Run<FrameElisionPhase>();
35171cb0ef41Sopenharmony_ci  if (data->compilation_failed()) {
35181cb0ef41Sopenharmony_ci    info()->AbortOptimization(
35191cb0ef41Sopenharmony_ci        BailoutReason::kNotEnoughVirtualRegistersRegalloc);
35201cb0ef41Sopenharmony_ci    data->EndPhaseKind();
35211cb0ef41Sopenharmony_ci    return false;
35221cb0ef41Sopenharmony_ci  }
35231cb0ef41Sopenharmony_ci
35241cb0ef41Sopenharmony_ci  // TODO(mtrofin): move this off to the register allocator.
35251cb0ef41Sopenharmony_ci  bool generate_frame_at_start =
35261cb0ef41Sopenharmony_ci      data_->sequence()->instruction_blocks().front()->must_construct_frame();
35271cb0ef41Sopenharmony_ci  // Optimimize jumps.
35281cb0ef41Sopenharmony_ci  if (FLAG_turbo_jt) {
35291cb0ef41Sopenharmony_ci    Run<JumpThreadingPhase>(generate_frame_at_start);
35301cb0ef41Sopenharmony_ci  }
35311cb0ef41Sopenharmony_ci
35321cb0ef41Sopenharmony_ci  data->EndPhaseKind();
35331cb0ef41Sopenharmony_ci
35341cb0ef41Sopenharmony_ci  return true;
35351cb0ef41Sopenharmony_ci}
35361cb0ef41Sopenharmony_ci
35371cb0ef41Sopenharmony_civoid PipelineImpl::VerifyGeneratedCodeIsIdempotent() {
35381cb0ef41Sopenharmony_ci  PipelineData* data = this->data_;
35391cb0ef41Sopenharmony_ci  JumpOptimizationInfo* jump_opt = data->jump_optimization_info();
35401cb0ef41Sopenharmony_ci  if (jump_opt == nullptr) return;
35411cb0ef41Sopenharmony_ci
35421cb0ef41Sopenharmony_ci  InstructionSequence* code = data->sequence();
35431cb0ef41Sopenharmony_ci  int instruction_blocks = code->InstructionBlockCount();
35441cb0ef41Sopenharmony_ci  int virtual_registers = code->VirtualRegisterCount();
35451cb0ef41Sopenharmony_ci  size_t hash_code = base::hash_combine(instruction_blocks, virtual_registers);
35461cb0ef41Sopenharmony_ci  for (auto instr : *code) {
35471cb0ef41Sopenharmony_ci    hash_code = base::hash_combine(hash_code, instr->opcode(),
35481cb0ef41Sopenharmony_ci                                   instr->InputCount(), instr->OutputCount());
35491cb0ef41Sopenharmony_ci  }
35501cb0ef41Sopenharmony_ci  for (int i = 0; i < virtual_registers; i++) {
35511cb0ef41Sopenharmony_ci    hash_code = base::hash_combine(hash_code, code->GetRepresentation(i));
35521cb0ef41Sopenharmony_ci  }
35531cb0ef41Sopenharmony_ci  if (jump_opt->is_collecting()) {
35541cb0ef41Sopenharmony_ci    jump_opt->set_hash_code(hash_code);
35551cb0ef41Sopenharmony_ci  } else {
35561cb0ef41Sopenharmony_ci    CHECK_EQ(hash_code, jump_opt->hash_code());
35571cb0ef41Sopenharmony_ci  }
35581cb0ef41Sopenharmony_ci}
35591cb0ef41Sopenharmony_ci
35601cb0ef41Sopenharmony_cistruct InstructionStartsAsJSON {
35611cb0ef41Sopenharmony_ci  const ZoneVector<TurbolizerInstructionStartInfo>* instr_starts;
35621cb0ef41Sopenharmony_ci};
35631cb0ef41Sopenharmony_ci
35641cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream& out, const InstructionStartsAsJSON& s) {
35651cb0ef41Sopenharmony_ci  out << ", \"instructionOffsetToPCOffset\": {";
35661cb0ef41Sopenharmony_ci  bool need_comma = false;
35671cb0ef41Sopenharmony_ci  for (size_t i = 0; i < s.instr_starts->size(); ++i) {
35681cb0ef41Sopenharmony_ci    if (need_comma) out << ", ";
35691cb0ef41Sopenharmony_ci    const TurbolizerInstructionStartInfo& info = (*s.instr_starts)[i];
35701cb0ef41Sopenharmony_ci    out << "\"" << i << "\": {";
35711cb0ef41Sopenharmony_ci    out << "\"gap\": " << info.gap_pc_offset;
35721cb0ef41Sopenharmony_ci    out << ", \"arch\": " << info.arch_instr_pc_offset;
35731cb0ef41Sopenharmony_ci    out << ", \"condition\": " << info.condition_pc_offset;
35741cb0ef41Sopenharmony_ci    out << "}";
35751cb0ef41Sopenharmony_ci    need_comma = true;
35761cb0ef41Sopenharmony_ci  }
35771cb0ef41Sopenharmony_ci  out << "}";
35781cb0ef41Sopenharmony_ci  return out;
35791cb0ef41Sopenharmony_ci}
35801cb0ef41Sopenharmony_ci
35811cb0ef41Sopenharmony_cistruct TurbolizerCodeOffsetsInfoAsJSON {
35821cb0ef41Sopenharmony_ci  const TurbolizerCodeOffsetsInfo* offsets_info;
35831cb0ef41Sopenharmony_ci};
35841cb0ef41Sopenharmony_ci
35851cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream& out,
35861cb0ef41Sopenharmony_ci                         const TurbolizerCodeOffsetsInfoAsJSON& s) {
35871cb0ef41Sopenharmony_ci  out << ", \"codeOffsetsInfo\": {";
35881cb0ef41Sopenharmony_ci  out << "\"codeStartRegisterCheck\": "
35891cb0ef41Sopenharmony_ci      << s.offsets_info->code_start_register_check << ", ";
35901cb0ef41Sopenharmony_ci  out << "\"deoptCheck\": " << s.offsets_info->deopt_check << ", ";
35911cb0ef41Sopenharmony_ci  out << "\"blocksStart\": " << s.offsets_info->blocks_start << ", ";
35921cb0ef41Sopenharmony_ci  out << "\"outOfLineCode\": " << s.offsets_info->out_of_line_code << ", ";
35931cb0ef41Sopenharmony_ci  out << "\"deoptimizationExits\": " << s.offsets_info->deoptimization_exits
35941cb0ef41Sopenharmony_ci      << ", ";
35951cb0ef41Sopenharmony_ci  out << "\"pools\": " << s.offsets_info->pools << ", ";
35961cb0ef41Sopenharmony_ci  out << "\"jumpTables\": " << s.offsets_info->jump_tables;
35971cb0ef41Sopenharmony_ci  out << "}";
35981cb0ef41Sopenharmony_ci  return out;
35991cb0ef41Sopenharmony_ci}
36001cb0ef41Sopenharmony_ci
36011cb0ef41Sopenharmony_civoid PipelineImpl::AssembleCode(Linkage* linkage) {
36021cb0ef41Sopenharmony_ci  PipelineData* data = this->data_;
36031cb0ef41Sopenharmony_ci  data->BeginPhaseKind("V8.TFCodeGeneration");
36041cb0ef41Sopenharmony_ci  data->InitializeCodeGenerator(linkage);
36051cb0ef41Sopenharmony_ci
36061cb0ef41Sopenharmony_ci  UnparkedScopeIfNeeded unparked_scope(data->broker());
36071cb0ef41Sopenharmony_ci
36081cb0ef41Sopenharmony_ci  Run<AssembleCodePhase>();
36091cb0ef41Sopenharmony_ci  if (data->info()->trace_turbo_json()) {
36101cb0ef41Sopenharmony_ci    TurboJsonFile json_of(data->info(), std::ios_base::app);
36111cb0ef41Sopenharmony_ci    json_of << "{\"name\":\"code generation\""
36121cb0ef41Sopenharmony_ci            << ", \"type\":\"instructions\""
36131cb0ef41Sopenharmony_ci            << InstructionStartsAsJSON{&data->code_generator()->instr_starts()}
36141cb0ef41Sopenharmony_ci            << TurbolizerCodeOffsetsInfoAsJSON{
36151cb0ef41Sopenharmony_ci                   &data->code_generator()->offsets_info()};
36161cb0ef41Sopenharmony_ci    json_of << "},\n";
36171cb0ef41Sopenharmony_ci  }
36181cb0ef41Sopenharmony_ci  data->DeleteInstructionZone();
36191cb0ef41Sopenharmony_ci  data->EndPhaseKind();
36201cb0ef41Sopenharmony_ci}
36211cb0ef41Sopenharmony_ci
36221cb0ef41Sopenharmony_ciMaybeHandle<Code> PipelineImpl::FinalizeCode(bool retire_broker) {
36231cb0ef41Sopenharmony_ci  PipelineData* data = this->data_;
36241cb0ef41Sopenharmony_ci  data->BeginPhaseKind("V8.TFFinalizeCode");
36251cb0ef41Sopenharmony_ci  if (data->broker() && retire_broker) {
36261cb0ef41Sopenharmony_ci    data->broker()->Retire();
36271cb0ef41Sopenharmony_ci  }
36281cb0ef41Sopenharmony_ci  Run<FinalizeCodePhase>();
36291cb0ef41Sopenharmony_ci
36301cb0ef41Sopenharmony_ci  MaybeHandle<Code> maybe_code = data->code();
36311cb0ef41Sopenharmony_ci  Handle<Code> code;
36321cb0ef41Sopenharmony_ci  if (!maybe_code.ToHandle(&code)) {
36331cb0ef41Sopenharmony_ci    return maybe_code;
36341cb0ef41Sopenharmony_ci  }
36351cb0ef41Sopenharmony_ci
36361cb0ef41Sopenharmony_ci  info()->SetCode(code);
36371cb0ef41Sopenharmony_ci  PrintCode(isolate(), code, info());
36381cb0ef41Sopenharmony_ci
36391cb0ef41Sopenharmony_ci  if (info()->trace_turbo_json()) {
36401cb0ef41Sopenharmony_ci    TurboJsonFile json_of(info(), std::ios_base::app);
36411cb0ef41Sopenharmony_ci
36421cb0ef41Sopenharmony_ci    json_of << "{\"name\":\"disassembly\",\"type\":\"disassembly\""
36431cb0ef41Sopenharmony_ci            << BlockStartsAsJSON{&data->code_generator()->block_starts()}
36441cb0ef41Sopenharmony_ci            << "\"data\":\"";
36451cb0ef41Sopenharmony_ci#ifdef ENABLE_DISASSEMBLER
36461cb0ef41Sopenharmony_ci    std::stringstream disassembly_stream;
36471cb0ef41Sopenharmony_ci    code->Disassemble(nullptr, disassembly_stream, isolate());
36481cb0ef41Sopenharmony_ci    std::string disassembly_string(disassembly_stream.str());
36491cb0ef41Sopenharmony_ci    for (const auto& c : disassembly_string) {
36501cb0ef41Sopenharmony_ci      json_of << AsEscapedUC16ForJSON(c);
36511cb0ef41Sopenharmony_ci    }
36521cb0ef41Sopenharmony_ci#endif  // ENABLE_DISASSEMBLER
36531cb0ef41Sopenharmony_ci    json_of << "\"}\n],\n";
36541cb0ef41Sopenharmony_ci    json_of << "\"nodePositions\":";
36551cb0ef41Sopenharmony_ci    json_of << data->source_position_output() << ",\n";
36561cb0ef41Sopenharmony_ci    JsonPrintAllSourceWithPositions(json_of, data->info(), isolate());
36571cb0ef41Sopenharmony_ci    json_of << "\n}";
36581cb0ef41Sopenharmony_ci  }
36591cb0ef41Sopenharmony_ci  if (info()->trace_turbo_json() || info()->trace_turbo_graph()) {
36601cb0ef41Sopenharmony_ci    CodeTracer::StreamScope tracing_scope(data->GetCodeTracer());
36611cb0ef41Sopenharmony_ci    tracing_scope.stream()
36621cb0ef41Sopenharmony_ci        << "---------------------------------------------------\n"
36631cb0ef41Sopenharmony_ci        << "Finished compiling method " << info()->GetDebugName().get()
36641cb0ef41Sopenharmony_ci        << " using TurboFan" << std::endl;
36651cb0ef41Sopenharmony_ci  }
36661cb0ef41Sopenharmony_ci  data->EndPhaseKind();
36671cb0ef41Sopenharmony_ci  return code;
36681cb0ef41Sopenharmony_ci}
36691cb0ef41Sopenharmony_ci
36701cb0ef41Sopenharmony_cibool PipelineImpl::SelectInstructionsAndAssemble(
36711cb0ef41Sopenharmony_ci    CallDescriptor* call_descriptor) {
36721cb0ef41Sopenharmony_ci  Linkage linkage(call_descriptor);
36731cb0ef41Sopenharmony_ci
36741cb0ef41Sopenharmony_ci  // Perform instruction selection and register allocation.
36751cb0ef41Sopenharmony_ci  if (!SelectInstructions(&linkage)) return false;
36761cb0ef41Sopenharmony_ci
36771cb0ef41Sopenharmony_ci  // Generate the final machine code.
36781cb0ef41Sopenharmony_ci  AssembleCode(&linkage);
36791cb0ef41Sopenharmony_ci  return true;
36801cb0ef41Sopenharmony_ci}
36811cb0ef41Sopenharmony_ci
36821cb0ef41Sopenharmony_ciMaybeHandle<Code> PipelineImpl::GenerateCode(CallDescriptor* call_descriptor) {
36831cb0ef41Sopenharmony_ci  if (!SelectInstructionsAndAssemble(call_descriptor)) {
36841cb0ef41Sopenharmony_ci    return MaybeHandle<Code>();
36851cb0ef41Sopenharmony_ci  }
36861cb0ef41Sopenharmony_ci  return FinalizeCode();
36871cb0ef41Sopenharmony_ci}
36881cb0ef41Sopenharmony_ci
36891cb0ef41Sopenharmony_cibool PipelineImpl::CommitDependencies(Handle<Code> code) {
36901cb0ef41Sopenharmony_ci  return data_->dependencies() == nullptr ||
36911cb0ef41Sopenharmony_ci         data_->dependencies()->Commit(code);
36921cb0ef41Sopenharmony_ci}
36931cb0ef41Sopenharmony_ci
36941cb0ef41Sopenharmony_cinamespace {
36951cb0ef41Sopenharmony_ci
36961cb0ef41Sopenharmony_civoid TraceSequence(OptimizedCompilationInfo* info, PipelineData* data,
36971cb0ef41Sopenharmony_ci                   const char* phase_name) {
36981cb0ef41Sopenharmony_ci  if (info->trace_turbo_json()) {
36991cb0ef41Sopenharmony_ci    UnparkedScopeIfNeeded scope(data->broker());
37001cb0ef41Sopenharmony_ci    AllowHandleDereference allow_deref;
37011cb0ef41Sopenharmony_ci    TurboJsonFile json_of(info, std::ios_base::app);
37021cb0ef41Sopenharmony_ci    json_of << "{\"name\":\"" << phase_name << "\",\"type\":\"sequence\""
37031cb0ef41Sopenharmony_ci            << ",\"blocks\":" << InstructionSequenceAsJSON{data->sequence()}
37041cb0ef41Sopenharmony_ci            << ",\"register_allocation\":{"
37051cb0ef41Sopenharmony_ci            << RegisterAllocationDataAsJSON{*(data->register_allocation_data()),
37061cb0ef41Sopenharmony_ci                                            *(data->sequence())}
37071cb0ef41Sopenharmony_ci            << "}},\n";
37081cb0ef41Sopenharmony_ci  }
37091cb0ef41Sopenharmony_ci  if (info->trace_turbo_graph()) {
37101cb0ef41Sopenharmony_ci    UnparkedScopeIfNeeded scope(data->broker());
37111cb0ef41Sopenharmony_ci    AllowHandleDereference allow_deref;
37121cb0ef41Sopenharmony_ci    CodeTracer::StreamScope tracing_scope(data->GetCodeTracer());
37131cb0ef41Sopenharmony_ci    tracing_scope.stream() << "----- Instruction sequence " << phase_name
37141cb0ef41Sopenharmony_ci                           << " -----\n"
37151cb0ef41Sopenharmony_ci                           << *data->sequence();
37161cb0ef41Sopenharmony_ci  }
37171cb0ef41Sopenharmony_ci}
37181cb0ef41Sopenharmony_ci
37191cb0ef41Sopenharmony_ci}  // namespace
37201cb0ef41Sopenharmony_ci
37211cb0ef41Sopenharmony_civoid PipelineImpl::AllocateRegistersForTopTier(
37221cb0ef41Sopenharmony_ci    const RegisterConfiguration* config, CallDescriptor* call_descriptor,
37231cb0ef41Sopenharmony_ci    bool run_verifier) {
37241cb0ef41Sopenharmony_ci  PipelineData* data = this->data_;
37251cb0ef41Sopenharmony_ci  // Don't track usage for this zone in compiler stats.
37261cb0ef41Sopenharmony_ci  std::unique_ptr<Zone> verifier_zone;
37271cb0ef41Sopenharmony_ci  RegisterAllocatorVerifier* verifier = nullptr;
37281cb0ef41Sopenharmony_ci  if (run_verifier) {
37291cb0ef41Sopenharmony_ci    verifier_zone.reset(
37301cb0ef41Sopenharmony_ci        new Zone(data->allocator(), kRegisterAllocatorVerifierZoneName));
37311cb0ef41Sopenharmony_ci    verifier = verifier_zone->New<RegisterAllocatorVerifier>(
37321cb0ef41Sopenharmony_ci        verifier_zone.get(), config, data->sequence(), data->frame());
37331cb0ef41Sopenharmony_ci  }
37341cb0ef41Sopenharmony_ci
37351cb0ef41Sopenharmony_ci#ifdef DEBUG
37361cb0ef41Sopenharmony_ci  data_->sequence()->ValidateEdgeSplitForm();
37371cb0ef41Sopenharmony_ci  data_->sequence()->ValidateDeferredBlockEntryPaths();
37381cb0ef41Sopenharmony_ci  data_->sequence()->ValidateDeferredBlockExitPaths();
37391cb0ef41Sopenharmony_ci#endif
37401cb0ef41Sopenharmony_ci
37411cb0ef41Sopenharmony_ci  RegisterAllocationFlags flags;
37421cb0ef41Sopenharmony_ci  if (data->info()->trace_turbo_allocation()) {
37431cb0ef41Sopenharmony_ci    flags |= RegisterAllocationFlag::kTraceAllocation;
37441cb0ef41Sopenharmony_ci  }
37451cb0ef41Sopenharmony_ci  data->InitializeTopTierRegisterAllocationData(config, call_descriptor, flags);
37461cb0ef41Sopenharmony_ci
37471cb0ef41Sopenharmony_ci  Run<MeetRegisterConstraintsPhase>();
37481cb0ef41Sopenharmony_ci  Run<ResolvePhisPhase>();
37491cb0ef41Sopenharmony_ci  Run<BuildLiveRangesPhase>();
37501cb0ef41Sopenharmony_ci  Run<BuildBundlesPhase>();
37511cb0ef41Sopenharmony_ci
37521cb0ef41Sopenharmony_ci  TraceSequence(info(), data, "before register allocation");
37531cb0ef41Sopenharmony_ci  if (verifier != nullptr) {
37541cb0ef41Sopenharmony_ci    CHECK(!data->top_tier_register_allocation_data()
37551cb0ef41Sopenharmony_ci               ->ExistsUseWithoutDefinition());
37561cb0ef41Sopenharmony_ci    CHECK(data->top_tier_register_allocation_data()
37571cb0ef41Sopenharmony_ci              ->RangesDefinedInDeferredStayInDeferred());
37581cb0ef41Sopenharmony_ci  }
37591cb0ef41Sopenharmony_ci
37601cb0ef41Sopenharmony_ci  if (info()->trace_turbo_json() && !data->MayHaveUnverifiableGraph()) {
37611cb0ef41Sopenharmony_ci    TurboCfgFile tcf(isolate());
37621cb0ef41Sopenharmony_ci    tcf << AsC1VRegisterAllocationData(
37631cb0ef41Sopenharmony_ci        "PreAllocation", data->top_tier_register_allocation_data());
37641cb0ef41Sopenharmony_ci  }
37651cb0ef41Sopenharmony_ci
37661cb0ef41Sopenharmony_ci  Run<AllocateGeneralRegistersPhase<LinearScanAllocator>>();
37671cb0ef41Sopenharmony_ci
37681cb0ef41Sopenharmony_ci  if (data->sequence()->HasFPVirtualRegisters()) {
37691cb0ef41Sopenharmony_ci    Run<AllocateFPRegistersPhase<LinearScanAllocator>>();
37701cb0ef41Sopenharmony_ci  }
37711cb0ef41Sopenharmony_ci
37721cb0ef41Sopenharmony_ci  if (data->sequence()->HasSimd128VirtualRegisters() &&
37731cb0ef41Sopenharmony_ci      (kFPAliasing == AliasingKind::kIndependent)) {
37741cb0ef41Sopenharmony_ci    Run<AllocateSimd128RegistersPhase<LinearScanAllocator>>();
37751cb0ef41Sopenharmony_ci  }
37761cb0ef41Sopenharmony_ci
37771cb0ef41Sopenharmony_ci  Run<DecideSpillingModePhase>();
37781cb0ef41Sopenharmony_ci  Run<AssignSpillSlotsPhase>();
37791cb0ef41Sopenharmony_ci  Run<CommitAssignmentPhase>();
37801cb0ef41Sopenharmony_ci
37811cb0ef41Sopenharmony_ci  // TODO(chromium:725559): remove this check once
37821cb0ef41Sopenharmony_ci  // we understand the cause of the bug. We keep just the
37831cb0ef41Sopenharmony_ci  // check at the end of the allocation.
37841cb0ef41Sopenharmony_ci  if (verifier != nullptr) {
37851cb0ef41Sopenharmony_ci    verifier->VerifyAssignment("Immediately after CommitAssignmentPhase.");
37861cb0ef41Sopenharmony_ci  }
37871cb0ef41Sopenharmony_ci
37881cb0ef41Sopenharmony_ci
37891cb0ef41Sopenharmony_ci  Run<ConnectRangesPhase>();
37901cb0ef41Sopenharmony_ci
37911cb0ef41Sopenharmony_ci  Run<ResolveControlFlowPhase>();
37921cb0ef41Sopenharmony_ci
37931cb0ef41Sopenharmony_ci  Run<PopulateReferenceMapsPhase>();
37941cb0ef41Sopenharmony_ci
37951cb0ef41Sopenharmony_ci  if (FLAG_turbo_move_optimization) {
37961cb0ef41Sopenharmony_ci    Run<OptimizeMovesPhase>();
37971cb0ef41Sopenharmony_ci  }
37981cb0ef41Sopenharmony_ci
37991cb0ef41Sopenharmony_ci  TraceSequence(info(), data, "after register allocation");
38001cb0ef41Sopenharmony_ci
38011cb0ef41Sopenharmony_ci  if (verifier != nullptr) {
38021cb0ef41Sopenharmony_ci    verifier->VerifyAssignment("End of regalloc pipeline.");
38031cb0ef41Sopenharmony_ci    verifier->VerifyGapMoves();
38041cb0ef41Sopenharmony_ci  }
38051cb0ef41Sopenharmony_ci
38061cb0ef41Sopenharmony_ci  if (info()->trace_turbo_json() && !data->MayHaveUnverifiableGraph()) {
38071cb0ef41Sopenharmony_ci    TurboCfgFile tcf(isolate());
38081cb0ef41Sopenharmony_ci    tcf << AsC1VRegisterAllocationData(
38091cb0ef41Sopenharmony_ci        "CodeGen", data->top_tier_register_allocation_data());
38101cb0ef41Sopenharmony_ci  }
38111cb0ef41Sopenharmony_ci
38121cb0ef41Sopenharmony_ci  data->DeleteRegisterAllocationZone();
38131cb0ef41Sopenharmony_ci}
38141cb0ef41Sopenharmony_ci
38151cb0ef41Sopenharmony_civoid PipelineImpl::AllocateRegistersForMidTier(
38161cb0ef41Sopenharmony_ci    const RegisterConfiguration* config, CallDescriptor* call_descriptor,
38171cb0ef41Sopenharmony_ci    bool run_verifier) {
38181cb0ef41Sopenharmony_ci  PipelineData* data = data_;
38191cb0ef41Sopenharmony_ci  // Don't track usage for this zone in compiler stats.
38201cb0ef41Sopenharmony_ci  std::unique_ptr<Zone> verifier_zone;
38211cb0ef41Sopenharmony_ci  RegisterAllocatorVerifier* verifier = nullptr;
38221cb0ef41Sopenharmony_ci  if (run_verifier) {
38231cb0ef41Sopenharmony_ci    verifier_zone.reset(
38241cb0ef41Sopenharmony_ci        new Zone(data->allocator(), kRegisterAllocatorVerifierZoneName));
38251cb0ef41Sopenharmony_ci    verifier = verifier_zone->New<RegisterAllocatorVerifier>(
38261cb0ef41Sopenharmony_ci        verifier_zone.get(), config, data->sequence(), data->frame());
38271cb0ef41Sopenharmony_ci  }
38281cb0ef41Sopenharmony_ci
38291cb0ef41Sopenharmony_ci#ifdef DEBUG
38301cb0ef41Sopenharmony_ci  data->sequence()->ValidateEdgeSplitForm();
38311cb0ef41Sopenharmony_ci  data->sequence()->ValidateDeferredBlockEntryPaths();
38321cb0ef41Sopenharmony_ci  data->sequence()->ValidateDeferredBlockExitPaths();
38331cb0ef41Sopenharmony_ci#endif
38341cb0ef41Sopenharmony_ci  data->InitializeMidTierRegisterAllocationData(config, call_descriptor);
38351cb0ef41Sopenharmony_ci
38361cb0ef41Sopenharmony_ci  TraceSequence(info(), data, "before register allocation");
38371cb0ef41Sopenharmony_ci
38381cb0ef41Sopenharmony_ci  Run<MidTierRegisterOutputDefinitionPhase>();
38391cb0ef41Sopenharmony_ci
38401cb0ef41Sopenharmony_ci  Run<MidTierRegisterAllocatorPhase>();
38411cb0ef41Sopenharmony_ci
38421cb0ef41Sopenharmony_ci  Run<MidTierSpillSlotAllocatorPhase>();
38431cb0ef41Sopenharmony_ci
38441cb0ef41Sopenharmony_ci  Run<MidTierPopulateReferenceMapsPhase>();
38451cb0ef41Sopenharmony_ci
38461cb0ef41Sopenharmony_ci  TraceSequence(info(), data, "after register allocation");
38471cb0ef41Sopenharmony_ci
38481cb0ef41Sopenharmony_ci  if (verifier != nullptr) {
38491cb0ef41Sopenharmony_ci    verifier->VerifyAssignment("End of regalloc pipeline.");
38501cb0ef41Sopenharmony_ci    verifier->VerifyGapMoves();
38511cb0ef41Sopenharmony_ci  }
38521cb0ef41Sopenharmony_ci
38531cb0ef41Sopenharmony_ci  data->DeleteRegisterAllocationZone();
38541cb0ef41Sopenharmony_ci}
38551cb0ef41Sopenharmony_ci
38561cb0ef41Sopenharmony_ciOptimizedCompilationInfo* PipelineImpl::info() const { return data_->info(); }
38571cb0ef41Sopenharmony_ci
38581cb0ef41Sopenharmony_ciIsolate* PipelineImpl::isolate() const { return data_->isolate(); }
38591cb0ef41Sopenharmony_ci
38601cb0ef41Sopenharmony_ciCodeGenerator* PipelineImpl::code_generator() const {
38611cb0ef41Sopenharmony_ci  return data_->code_generator();
38621cb0ef41Sopenharmony_ci}
38631cb0ef41Sopenharmony_ci
38641cb0ef41Sopenharmony_ciObserveNodeManager* PipelineImpl::observe_node_manager() const {
38651cb0ef41Sopenharmony_ci  return data_->observe_node_manager();
38661cb0ef41Sopenharmony_ci}
38671cb0ef41Sopenharmony_ci
38681cb0ef41Sopenharmony_ci}  // namespace compiler
38691cb0ef41Sopenharmony_ci}  // namespace internal
38701cb0ef41Sopenharmony_ci}  // namespace v8
3871