// Copyright 2022 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. #ifndef V8_COMPILER_TURBOSHAFT_VARIABLE_REDUCER_H_ #define V8_COMPILER_TURBOSHAFT_VARIABLE_REDUCER_H_ #include <algorithm> #include <optional> #include "src/base/logging.h" #include "src/codegen/machine-type.h" #include "src/compiler/turboshaft/assembler.h" #include "src/compiler/turboshaft/graph.h" #include "src/compiler/turboshaft/operations.h" #include "src/compiler/turboshaft/representations.h" #include "src/compiler/turboshaft/required-optimization-reducer.h" #include "src/compiler/turboshaft/snapshot-table.h" #include "src/zone/zone-containers.h" namespace v8::internal::compiler::turboshaft { #include "src/compiler/turboshaft/define-assembler-macros.inc" // When cloning a Block or duplicating an Operation, we end up with some // Operations of the old graph mapping to multiple Operations in the new graph. // When using those Operations in subsequent Operations, we need to know which // of the new-Operation to use, and, in particular, if a Block has 2 // predecessors that have a mapping for the same old-Operation, we need to // merge them in a Phi node. All of this is handled by the VariableAssembler. // // The typical workflow when working with the VariableAssembler would be: // - At some point, you need to introduce a Variable (for instance // because you cloned a block or an Operation) and call NewVariable or // NewLoopInvariantVariable to get a fresh Variable. A loop invariant // variable must not need loop phis, that is, not change its value // depending on loop iteration while being visible across loop iterations. // - You can then Set the new-OpIndex associated with this Variable in the // current Block with the Set method. // - If you later need to set an OpIndex for this Variable in another Block, // call Set again. // - At any time, you can call Get to get the new-Operation associated to // this Variable. Get will return: // * if the current block is dominated by a block who did a Set on the // Variable, then the Operation that was Set then. // * otherwise, the current block must be dominated by a Merge whose // predecessors have all Set this Variable. In that case, the // VariableAssembler introduced a Phi in this merge, and will return // this Phi. // // Note that the VariableAssembler does not do "old-OpIndex => Variable" // book-keeping: the users of the Variable should do that themselves (which // is what CopyingPhase does for instance). // VariableReducer always adds a RequiredOptimizationReducer, because phis // with constant inputs introduced by `VariableReducer` need to be eliminated. template <class AfterNext> class VariableReducer : public RequiredOptimizationReducer<AfterNext> { … }; #include "src/compiler/turboshaft/undef-assembler-macros.inc" } // namespace v8::internal::compiler::turboshaft #endif // V8_COMPILER_TURBOSHAFT_VARIABLE_REDUCER_H_