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