chromium/v8/src/compiler/turboshaft/maglev-graph-building-phase.cc

// Copyright 2023 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/compiler/turboshaft/maglev-graph-building-phase.h"

#include <limits>
#include <memory>
#include <optional>
#include <type_traits>

#include "src/base/logging.h"
#include "src/base/small-vector.h"
#include "src/base/vector.h"
#include "src/codegen/bailout-reason.h"
#include "src/codegen/optimized-compilation-info.h"
#include "src/common/globals.h"
#include "src/compiler/access-builder.h"
#include "src/compiler/bytecode-analysis.h"
#include "src/compiler/bytecode-liveness-map.h"
#include "src/compiler/frame-states.h"
#include "src/compiler/globals.h"
#include "src/compiler/js-heap-broker.h"
#include "src/compiler/turboshaft/assembler.h"
#include "src/compiler/turboshaft/graph.h"
#include "src/compiler/turboshaft/index.h"
#include "src/compiler/turboshaft/machine-optimization-reducer.h"
#include "src/compiler/turboshaft/maglev-early-lowering-reducer-inl.h"
#include "src/compiler/turboshaft/operations.h"
#include "src/compiler/turboshaft/phase.h"
#include "src/compiler/turboshaft/representations.h"
#include "src/compiler/turboshaft/required-optimization-reducer.h"
#include "src/compiler/turboshaft/sidetable.h"
#include "src/compiler/turboshaft/utils.h"
#include "src/compiler/turboshaft/value-numbering-reducer.h"
#include "src/compiler/turboshaft/variable-reducer.h"
#include "src/compiler/write-barrier-kind.h"
#include "src/deoptimizer/deoptimize-reason.h"
#include "src/handles/global-handles-inl.h"
#include "src/handles/handles.h"
#include "src/interpreter/bytecode-register.h"
#include "src/maglev/maglev-basic-block.h"
#include "src/maglev/maglev-compilation-info.h"
#include "src/maglev/maglev-compilation-unit.h"
#include "src/maglev/maglev-graph-builder.h"
#include "src/maglev/maglev-graph-labeller.h"
#include "src/maglev/maglev-graph-processor.h"
#include "src/maglev/maglev-graph-verifier.h"
#include "src/maglev/maglev-ir-inl.h"
#include "src/maglev/maglev-ir.h"
#include "src/maglev/maglev-phi-representation-selector.h"
#include "src/maglev/maglev-post-hoc-optimizations-processors.h"
#include "src/objects/elements-kind.h"
#include "src/objects/heap-object.h"
#include "src/objects/js-array-buffer.h"
#include "src/objects/objects.h"
#include "src/zone/zone-containers.h"

namespace v8::internal::compiler::turboshaft {

#include "src/compiler/turboshaft/define-assembler-macros.inc"

namespace {

MachineType MachineTypeFor(maglev::ValueRepresentation repr) {}

// TODO(dmercadier): use simply .contains once we have access to C++20.
template <typename K, typename V>
bool MapContains(ZoneUnorderedMap<K, V> map, K key) {}

int ElementsKindSize(ElementsKind element_kind) {}

}  // namespace

// This reducer tracks the Maglev origin of the Turboshaft blocks that we build
// during the translation. This is then used when reordering Phi inputs.
template <class Next>
class BlockOriginTrackingReducer : public Next {};

class GeneratorAnalyzer {};

#define GET_FRAME_STATE_MAYBE_ABORT(name, deopt_info)

// Turboshaft's MachineOptimizationReducer will sometimes detect that the
// condition for a DeoptimizeIf is always true, and replace it with an
// unconditional Deoptimize. When this happens, the assembler doesn't emit
// anything until the next reachable block is bound, which can lead to some
// Variable or OpIndex being Invalid, which can break some assumptions. To avoid
// this, the RETURN_IF_UNREACHABLE macro can be used to early-return.
#define RETURN_IF_UNREACHABLE()

// TODO(dmercadier): LazyDeoptOnThrow is currently not very cleanly dealt with.
// In Maglev, it is a property of the ExceptionHandlerInfo, which is use by all
// throwing nodes and is created in a single place
// (MaglevGraphBuilder::AttachExceptionHandlerInfo). However, during the
// translation, we create different kind of calls from different places (Call,
// CallBuiltin_XXX, CallRuntime_XXX), and non-call nodes can also
// LazyDeoptOnThrow (such as GenericBinop) and we always have to manually
// remember to pass ShouldLazyDeoptOnThrow, which is easy to forget, which can
// then easily lead to bugs. A few ideas come to mind:
//
//  - Make ShouldLazyDeoptOnThrow non-optional on all throwing nodes. This is a
//    bit verbose, but at least we won't forget it.
//
//  - Make ThrowingScope automatically annotate all throwing nodes that are
//    emitted while the scope is active. The Assembler would be doing most of
//    the work: it would have a "LazyDeoptOnThrowScope" or something similar,
//    and any throwing node emitted during this scope would have the
//    LazyDeoptOnThrow property added as needed. All throwing nodes have a
//    {lazy_deopt_on_throw} field defined by THROWING_OP_BOILERPLATE (except
//    calls, but we could add it), so it shouldn't be very hard for the
//    Assembler to deal with this in a unified way.
//    The downside of this approach is that the interaction between this and
//    {current_catch_block} (in particular with nested scopes) might introduce
//    even more complexity and magic in the assembler.

class GraphBuilder {};

// A NodeProcessor wrapper around GraphBuilder that takes care of
//  - skipping nodes when we are in Unreachable code.
//  - recording source positions.
class NodeProcessorBase : public GraphBuilder {};

void PrintBytecode(PipelineData& data,
                   maglev::MaglevCompilationInfo* compilation_info) {}

void PrintMaglevGraph(PipelineData& data,
                      maglev::MaglevCompilationInfo* compilation_info,
                      maglev::Graph* maglev_graph, const char* msg) {}

// TODO(dmercadier, nicohartmann): consider doing some of these optimizations on
// the Turboshaft graph after the Maglev->Turboshaft translation. For instance,
// MaglevPhiRepresentationSelector is the Maglev equivalent of Turbofan's
// SimplifiedLowering, but is much less powerful (doesn't take truncations into
// account, doesn't do proper range analysis, doesn't run a fixpoint
// analysis...).
void RunMaglevOptimizations(PipelineData* data,
                            maglev::MaglevCompilationInfo* compilation_info,
                            maglev::MaglevGraphBuilder& maglev_graph_builder,
                            maglev::Graph* maglev_graph) {}

std::optional<BailoutReason> MaglevGraphBuildingPhase::Run(PipelineData* data,
                                                           Zone* temp_zone) {}

#include "src/compiler/turboshaft/undef-assembler-macros.inc"

}  // namespace v8::internal::compiler::turboshaft