5#ifndef V8_COMPILER_TURBOSHAFT_PIPELINES_H_
6#define V8_COMPILER_TURBOSHAFT_PIPELINES_H_
34#if V8_ENABLE_WEBASSEMBLY
42#define RUN_MAYBE_ABORT(phase, ...) \
43 if (V8_UNLIKELY(!Run<phase>(__VA_ARGS__))) return {};
57 if (
auto statistics =
data()->pipeline_statistics()) {
58 statistics->BeginPhaseKind(phase_kind_name);
62 if (
auto statistics =
data()->pipeline_statistics()) {
63 statistics->EndPhaseKind();
70 PhaseScope phase_scope(
data_->pipeline_statistics(), Phase::phase_name());
75#ifdef V8_RUNTIME_CALL_STATS
76 RuntimeCallTimerScope runtime_call_timer_scope(
data_->runtime_call_stats(),
77 Phase::kRuntimeCallCounterId,
83 decltype(phase.Run(
data_, temp_zone, std::forward<Args>(
args)...));
84 if constexpr (std::is_same_v<result_t, void>) {
85 phase.Run(
data_, temp_zone, std::forward<Args>(
args)...);
87 PrintGraph(temp_zone, Phase::phase_name());
89 return !
data_->info()->was_cancelled();
93 PrintGraph(temp_zone, Phase::phase_name());
95 return !
data_->info()->was_cancelled() ?
result : std::nullopt;
102 if (
data_->info()->trace_turbo_graph()) {
106 code_tracer =
data_->GetCodeTracer();
113 if (
info()->trace_turbo_json()) {
118 <<
"{\"name\":\"" << phase_name <<
"\",\"type\":\"sequence\""
120 <<
",\"register_allocation\":{"
122 *(
data()->sequence())}
125 if (
info()->trace_turbo_graph()) {
130 <<
"----- Instruction sequence " << phase_name <<
" -----\n"
131 << *
data()->sequence();
138 BeginPhaseKind(
"V8.TFGraphCreation");
140 std::optional<BailoutReason> bailout =
141 Run<turboshaft::MaglevGraphBuildingPhase>(
linkage);
144 if (bailout.has_value()) {
145 data_->info()->AbortOptimization(bailout.value());
157 v8_flags.turboshaft_trace_reduction ||
162 if (std::optional<BailoutReason> bailout =
163 Run<turboshaft::BuildGraphPhase>(turbofan_data,
linkage)) {
164 info()->AbortOptimization(*bailout);
173 v8_flags.turboshaft_trace_reduction ||
178 BeginPhaseKind(
"V8.TurboshaftOptimize");
180#ifdef V8_ENABLE_WEBASSEMBLY
185 if (
v8_flags.turboshaft_wasm_in_js_inlining) {
192 if (
v8_flags.turboshaft_loop_unrolling) {
196 if (
v8_flags.turbo_store_elimination) {
202 if (
v8_flags.turboshaft_typed_optimizations) {
206 if (
v8_flags.turboshaft_assert_types) {
214#ifdef V8_ENABLE_DEBUG_CODE
234 TurboshaftPipelineKind::kTSABuiltin)) {
240 Builtins::IsBuiltinId(info()->
builtin())) {
242 BasicBlockCallGraphProfiler::StoreCallGraph(
info(),
data()->
graph());
251 const size_t block_count =
data()->graph().block_count();
253 BasicBlockProfiler::Get()->NewData(block_count);
258 if (
v8_flags.turbo_profiling_verbose) {
259 std::ostringstream os;
260 os <<
data()->graph();
264 info()->set_profiler_data(profiler_data);
281 return Run<SpecialRPOSchedulingPhase>();
285 auto call_descriptor =
linkage->GetIncomingDescriptor();
289 if (!
data_->frame()) {
290 data_->InitializeFrameData(call_descriptor);
295 if (
info()->trace_turbo_graph()) {
299 code_tracer =
data_->GetCodeTracer();
302 if (std::optional<BailoutReason> bailout = Run<InstructionSelectionPhase>(
303 call_descriptor,
linkage, code_tracer)) {
304 data_->info()->AbortOptimization(*bailout);
335 BeginPhaseKind(
"V8.TFRegisterAllocation");
337 bool run_verifier =
v8_flags.turbo_verify_allocation;
341 std::unique_ptr<const RegisterConfiguration> restricted_config;
345 restricted_config.reset(
346 RegisterConfiguration::RestrictGeneralRegisters(
registers));
347 config = restricted_config.get();
349 if (!AllocateRegisters(config, call_descriptor, run_verifier))
return false;
352 VerifyGeneratedCodeIsIdempotent();
357 bool generate_frame_at_start =
358 data_->sequence()->instruction_blocks().front()->must_construct_frame();
366 return !
info()->was_cancelled();
376 if (jump_opt ==
nullptr)
return;
380 int virtual_registers = code->VirtualRegisterCount();
382 base::hash_combine(instruction_blocks, virtual_registers);
384 hash_code = base::hash_combine(hash_code,
instr->opcode(),
387 for (
int i = 0;
i < virtual_registers;
i++) {
388 hash_code = base::hash_combine(hash_code, code->GetRepresentation(
i));
402 BeginPhaseKind(
"V8.TFCodeGeneration");
408 if (
info()->trace_turbo_json()) {
411 <<
"{\"name\":\"code generation\"" <<
", \"type\":\"instructions\""
414 &
data()->code_generator()->offsets_info()};
418 data()->ClearInstructionComponent();
420 return !
info()->was_cancelled();
425 if (!PrepareForInstructionSelection())
return {};
426 if (!SelectInstructions(&
linkage)) {
429 if (!AllocateRegisters(
linkage.GetIncomingDescriptor()))
return {};
430 if (!AssembleCode(&
linkage))
return {};
431 return FinalizeCode();
434 [[nodiscard]]
bool GenerateCode(
442 BeginPhaseKind(
"V8.TFFinalizeCode");
443 if (
data_->broker() && retire_broker) {
444 data_->broker()->Retire();
454 data_->info()->SetCode(code);
459 if (
v8_flags.profile_guided_optimization &&
460 info()->could_not_inline_all_candidates() &&
461 info()->shared_info()->cached_tiering_decision() !=
462 CachedTieringDecision::kDelayMaglev) {
463 info()->shared_info()->set_cached_tiering_decision(
464 CachedTieringDecision::kNormal);
467 if (
info()->trace_turbo_json()) {
470 json_of <<
"{\"name\":\"disassembly\",\"type\":\"disassembly\""
473#ifdef ENABLE_DISASSEMBLER
474 std::stringstream disassembly_stream;
475 code->Disassemble(
nullptr, disassembly_stream,
data_->isolate());
476 std::string disassembly_string(disassembly_stream.str());
477 for (
const auto& c : disassembly_string) {
481 json_of <<
"\"}\n],\n";
482 json_of <<
"\"nodePositions\":";
484 json_of << (
data_->source_position_output().empty()
486 :
data_->source_position_output())
489 if (
info()->has_bytecode_array()) {
495 if (
info()->trace_turbo_json() ||
info()->trace_turbo_graph()) {
498 <<
"---------------------------------------------------\n"
499 <<
"Finished compiling method " <<
info()->GetDebugName().get()
500 <<
" using TurboFan" << std::endl;
507 return data_->depedencies() ==
nullptr ||
508 data_->depedencies()->Commit(code);
513 virtual bool IsBuiltinPipeline()
const {
return false; }
526 bool IsBuiltinPipeline()
const override {
return true; }
530#undef RUN_MAYBE_ABORT
uint8_t data_[MAX_STACK_LENGTH]
union v8::internal::@341::BuiltinMetadata::KindSpecificData data
void SetFunctionName(std::unique_ptr< char[]> name)
void SetSchedule(const std::ostringstream &os)
V8_WARN_UNUSED_RESULT V8_INLINE bool ToHandle(Handle< S > *out) const
bool HasRestrictedAllocatableRegisters() const
RegList AllocatableRegisters() const
int InstructionBlockCount() const
BuiltinPipeline(PipelineData *data)
V8_WARN_UNUSED_RESULT bool RunSimplificationAndNormalizationPhase()
bool CreateGraphFromTurbofan(compiler::TFPipelineData *turbofan_data, Linkage *linkage)
bool MayHaveUnverifiableGraph() const
Pipeline(PipelineData *data)
PipelineData * data() const
void PrintGraph(Zone *zone, const char *phase_name)
bool SelectInstructions(Linkage *linkage)
bool CommitDependencies(Handle< Code > code)
V8_WARN_UNUSED_RESULT bool PrepareForInstructionSelection(const ProfileDataFromFile *profile=nullptr)
void BeginPhaseKind(const char *phase_kind_name)
MaybeHandle< Code > GenerateCode(CallDescriptor *call_descriptor)
MaybeIndirectHandle< Code > FinalizeCode(bool retire_broker=true)
V8_WARN_UNUSED_RESULT bool AssembleCode(Linkage *linkage)
bool CreateGraphWithMaglev(Linkage *linkage)
bool OptimizeTurboshaftGraph(Linkage *linkage)
void VerifyGeneratedCodeIsIdempotent()
OptimizedCompilationInfo * info()
void TraceSequence(const char *phase_name)
V8_WARN_UNUSED_RESULT bool AllocateRegisters(CallDescriptor *call_descriptor)
V8_WARN_UNUSED_RESULT auto Run(Args &&... args)
Handle< SharedFunctionInfo > info
base::Vector< const DirectHandle< Object > > args
TurboshaftPipelineKind pipeline_kind
ZoneVector< RpoNumber > & result
RegListBase< RegisterT > registers
void PrintTurboshaftGraph(PipelineData *data, Zone *temp_zone, CodeTracer *code_tracer, const char *phase_name)
constexpr char kTempZoneName[]
base::Vector< const char > GetDebugName(Zone *zone, const wasm::WasmModule *module, const wasm::WireBytesStorage *wire_bytes, int index)
void PrintCode(Isolate *isolate, DirectHandle< Code > code, OptimizedCompilationInfo *info)
void JsonPrintAllBytecodeSources(std::ostream &os, OptimizedCompilationInfo *info)
void JsonPrintAllSourceWithPositions(std::ostream &os, OptimizedCompilationInfo *info, Isolate *isolate)
V8_EXPORT_PRIVATE FlagValues v8_flags
#define RUN_MAYBE_ABORT(phase,...)
#define CHECK_IMPLIES(lhs, rhs)
#define DCHECK_NOT_NULL(val)
#define CHECK_EQ(lhs, rhs)
#define DCHECK_LT(v1, v2)
#define V8_EXPORT_PRIVATE
bool is_collecting() const
void Run(PipelineData *data, Zone *temp_zone)
#define DECL_TURBOSHAFT_PHASE_CONSTANTS(Name)
#define V8_WARN_UNUSED_RESULT
#define V8_UNLIKELY(condition)