#include "src/maglev/maglev-graph-optimizer.h"
#include <optional>
#include "src/base/logging.h"
#include "src/codegen/bailout-reason.h"
#include "src/common/operation.h"
#include "src/deoptimizer/deoptimize-reason.h"
#include "src/maglev/maglev-basic-block.h"
#include "src/maglev/maglev-graph-processor.h"
#include "src/maglev/maglev-ir-inl.h"
#include "src/maglev/maglev-ir.h"
#include "src/maglev/maglev-known-node-aspects.h"
#include "src/maglev/maglev-reducer-inl.h"
#include "src/maglev/maglev-reducer.h"
#include "src/objects/objects-inl.h"
namespace v8 {
namespace internal {
namespace maglev {
#define RETURN_IF_SUCCESS(res) \
do { \
auto _res = (res); \
if (_res) return *_res; \
} while (false)
namespace {
bool IsDoneWithValue(MaybeReduceResult result) {
return result.IsDoneWithValue();
}
bool IsDoneWithValue(ValueNode* node) { return node != nullptr; }
bool IsDoneWithAbort(MaybeReduceResult result) {
return result.IsDoneWithAbort();
}
bool IsDoneWithAbort(ValueNode* node) { return false; }
#ifdef DEBUG
bool IsFail(MaybeReduceResult result) { return result.IsFail(); }
bool IsFail(ValueNode* node) { return node == nullptr; }
#endif
ValueNode* Value(MaybeReduceResult result) { return result.value(); }
ValueNode* Value(ValueNode* node) { return node; }
}
#define REPLACE_AND_RETURN_IF_DONE(result) \
do { \
auto res = (result); \
if (IsDoneWithValue(res)) { \
return ReplaceWith(Value(res)); \
} else if (IsDoneWithAbort(res)) { \
return ProcessResult::kTruncateBlock; \
} \
DCHECK(IsFail(result)); \
} while (false)
namespace {
constexpr ValueRepresentation ValueRepresentationFromUse(
UseRepresentation repr) {
switch (repr) {
case UseRepresentation::kTagged:
case UseRepresentation::kTaggedForNumberToString:
return ValueRepresentation::kTagged;
case UseRepresentation::kInt32:
case UseRepresentation::kTruncatedInt32:
return ValueRepresentation::kInt32;
case UseRepresentation::kUint32:
return ValueRepresentation::kUint32;
case UseRepresentation::kShiftedInt53:
return ValueRepresentation::kShiftedInt53;
case UseRepresentation::kFloat64:
return ValueRepresentation::kFloat64;
case UseRepresentation::kHoleyFloat64:
return ValueRepresentation::kHoleyFloat64;
}
UNREACHABLE();
}
}
MaglevGraphOptimizer::MaglevGraphOptimizer(
Graph* graph, RecomputeKnownNodeAspectsProcessor& kna_processor,
NodeRanges* ranges)
: reducer_(this, graph), kna_processor_(kna_processor), ranges_(ranges) {}
BlockProcessResult MaglevGraphOptimizer::PreProcessBasicBlock(
BasicBlock* block) {
reducer_.set_current_block(block);
return BlockProcessResult::kContinue;
}
void MaglevGraphOptimizer::PostProcessBasicBlock(BasicBlock* block) {
reducer_.FlushNodesToBlock();
}
void MaglevGraphOptimizer::PreProcessNode(Node*, const ProcessingState& state) {
#ifdef DEBUG
reducer_.StartNewPeriod();
#endif
if (reducer_.has_graph_labeller()) {
reducer_.SetCurrentProvenance(
reducer_.graph_labeller()->GetNodeProvenance(current_node()));
}
reducer_.SetNewNodePosition(BasicBlockPosition::At(state.node_index()));
}
void MaglevGraphOptimizer::PostProcessNode(Node*) {
#ifdef DEBUG
reducer_.SetCurrentProvenance(MaglevGraphLabeller::Provenance{});
reducer_.SetNewNodePosition(BasicBlockPosition::End());
#endif
}
void MaglevGraphOptimizer::PreProcessNode(Phi*, const ProcessingState&) {}
void MaglevGraphOptimizer::PostProcessNode(Phi*) {}
void MaglevGraphOptimizer::PreProcessNode(ControlNode*,
const ProcessingState&) {
reducer_.SetNewNodePosition(BasicBlockPosition::End());
}
void MaglevGraphOptimizer::PostProcessNode(ControlNode*) {}
compiler::JSHeapBroker* MaglevGraphOptimizer::broker() const {
return reducer_.broker();
}
std::optional<Range> MaglevGraphOptimizer::GetRange(ValueNode* node) {
if (!ranges_) return {};
return ranges_->Get(reducer_.current_block(), node);
}
bool MaglevGraphOptimizer::IsRangeLessEqual(ValueNode* lhs, ValueNode* rhs) {
if (!ranges_) return false;
return ranges_->IsLessEqualConstraint(reducer_.current_block(), lhs, rhs);
}
ProcessResult MaglevGraphOptimizer::ReplaceWith(ValueNode* node) {
CHECK(current_node()->Cast<ValueNode>());
DCHECK(!node->Is<Identity>());
ValueNode* current_value = current_node()->Cast<ValueNode>();
ReduceResult result = reducer_.ConvertInputTo(
node, current_value->properties().value_representation());
if (result.IsDoneWithAbort()) {
return ProcessResult::kTruncateBlock;
}
current_value->OverwriteWithIdentityTo(result.value());
return ProcessResult::kRemove;
}
template <typename NodeT, typename... Args>
ProcessResult MaglevGraphOptimizer::ReplaceWith(
std::initializer_list<ValueNode*> inputs, Args&&... args) {
CHECK(current_node()->Cast<ValueNode>());
ValueNode* current_value = current_node()->Cast<ValueNode>();
current_value->ClearInputs();
current_value->UnwrapDeoptFrames();
NodeT* new_node =
current_value->OverwriteWith<NodeT>(std::forward<Args>(args)...);
ReduceResult result = reducer_.SetNodeInputs(new_node, inputs);
DCHECK(result.IsDone());
if (result.IsDoneWithAbort()) {
ReduceResult deopt = EmitUnconditionalDeopt(DeoptimizeReason::kUnknown);
USE(deopt);
return ProcessResult::kTruncateBlock;
}
return ProcessResult::kContinue;
}
void MaglevGraphOptimizer::UnwrapInputs() {
for (int i = 0; i < current_node()->input_count(); i++) {
ValueNode* input = current_node()->input(i).node();
if (!input) continue;
current_node()->change_input(i, input->UnwrapIdentities());
}
}
ValueNode* MaglevGraphOptimizer::GetConstantWithRepresentation(
ValueNode* node, UseRepresentation use_repr,
std::optional<TaggedToFloat64ConversionType> conversion_type) {
switch (use_repr) {
case UseRepresentation::kInt32:
case UseRepresentation::kTruncatedInt32: {
auto cst = reducer_.TryGetInt32Constant(node);
if (cst.has_value()) {
return reducer_.GetInt32Constant(cst.value());
}
return nullptr;
}
case UseRepresentation::kShiftedInt53: {
auto cst = reducer_.TryGetShiftedInt53Constant(node);
if (cst.has_value()) {
return reducer_.GetShiftedInt53Constant(cst.value());
}
return nullptr;
}
case UseRepresentation::kFloat64:
case UseRepresentation::kHoleyFloat64: {
DCHECK(conversion_type.has_value());
auto cst = reducer_.TryGetFloat64OrHoleyFloat64Constant(use_repr, node,
*conversion_type);
if (cst.has_value()) {
if (use_repr == UseRepresentation::kHoleyFloat64) {
return reducer_.GetHoleyFloat64Constant(cst.value());
}
return reducer_.GetFloat64Constant(cst.value());
}
return nullptr;
}
default:
return nullptr;
}
}
MaybeReduceResult MaglevGraphOptimizer::GetUntaggedValueWithRepresentation(
ValueNode* node, UseRepresentation use_repr,
std::optional<TaggedToFloat64ConversionType> conversion_type) {
DCHECK_NE(use_repr, UseRepresentation::kTagged);
if (node->value_representation() == ValueRepresentationFromUse(use_repr)) {
return node;
}
if (node->Is<ReturnedValue>()) {
ValueNode* input = node->input_node(0);
return GetUntaggedValueWithRepresentation(input, use_repr, conversion_type);
}
if (ValueNode* cst =
GetConstantWithRepresentation(node, use_repr, conversion_type)) {
return cst;
}
if (node->is_tagged()) {
if (use_repr == UseRepresentation::kShiftedInt53) return {};
NodeInfo* node_info =
known_node_aspects().GetOrCreateInfoFor(broker(), node);
auto& alternative = node_info->alternative();
if (ValueNode* alt = alternative.get(use_repr)) return alt;
return {};
}
if (!current_node_->properties().can_eager_deopt() &&
!current_node_->properties().is_deopt_checkpoint()) {
return {};
}
switch (use_repr) {
case UseRepresentation::kInt32:
return reducer_.GetInt32(node);
case UseRepresentation::kTruncatedInt32:
DCHECK(conversion_type.has_value());
return reducer_.GetTruncatedInt32ForToNumber(
node, GetAllowedTypeFromConversionType(*conversion_type));
case UseRepresentation::kShiftedInt53:
return reducer_.GetShiftedInt53(node);
case UseRepresentation::kFloat64:
DCHECK(conversion_type.has_value());
return reducer_.GetFloat64ForToNumber(
node, GetAllowedTypeFromConversionType(*conversion_type));
case UseRepresentation::kHoleyFloat64:
DCHECK(conversion_type.has_value());
return reducer_.GetHoleyFloat64ForToNumber(
node, GetAllowedTypeFromConversionType(*conversion_type));
default:
return {};
}
UNREACHABLE();
}
template <typename NodeT>
ValueNode* MaglevGraphOptimizer::TrySmiTag(Input input) {
auto cst = reducer_.TryGetInt32Constant(input.node());
if (cst.has_value() && Smi::IsValid(cst.value())) {
return reducer_.GetSmiConstant(cst.value());
}
if (auto range = GetRange(input.node())) {
if (range->IsSmi()) {
return reducer_.AddNewNodeNoInputConversion<NodeT>({input.node()});
}
}
return nullptr;
}
template <Operation kOperation>
std::optional<ProcessResult> MaglevGraphOptimizer::TryFoldInt32Operation(
ValueNode* node) {
MaybeReduceResult result;
if constexpr (IsUnaryOperation(kOperation)) {
result =
reducer_.TryFoldInt32UnaryOperation<kOperation>(node->input_node(0));
} else {
static_assert(IsBinaryOperation(kOperation));
result = reducer_.TryFoldInt32BinaryOperation<kOperation>(
node->input_node(0), node->input_node(1));
}
if (!result.IsDone()) return {};
DCHECK(result.IsDoneWithValue());
if constexpr (kOperation == Operation::kShiftRightLogical) {
CHECK(result.value()->Is<Uint32Constant>());
return ReplaceWith(result.value());
}
return ReplaceWith(reducer_.GetInt32(result.value()));
}
template <Operation kOperation>
std::optional<ProcessResult> MaglevGraphOptimizer::TryFoldFloat64Operation(
ValueNode* node) {
MaybeReduceResult result;
if constexpr (IsUnaryOperation(kOperation)) {
result = reducer_.TryFoldFloat64UnaryOperationForToNumber<kOperation>(
TaggedToFloat64ConversionType::kOnlyNumber, node->input_node(0));
} else {
static_assert(IsBinaryOperation(kOperation));
result = reducer_.TryFoldFloat64BinaryOperationForToNumber<kOperation>(
TaggedToFloat64ConversionType::kOnlyNumber, node->input_node(0),
node->input_node(1));
}
if (!result.IsDone()) return {};
if (result.IsDoneWithAbort()) {
return ProcessResult::kTruncateBlock;
}
DCHECK(result.IsDoneWithValue());
ReduceResult float64_result = reducer_.GetFloat64(result.value());
if (float64_result.IsDoneWithAbort()) {
return ProcessResult::kTruncateBlock;
}
DCHECK(float64_result.IsDoneWithValue());
return ReplaceWith(float64_result.value());
}
Jump* MaglevGraphOptimizer::FoldBranch(BasicBlock* current,
BranchControlNode* branch_node,
bool if_true) {
BasicBlock* target =
if_true ? branch_node->if_true() : branch_node->if_false();
BasicBlock* unreachable_block =
if_true ? branch_node->if_false() : branch_node->if_true();
if (!unreachable_block->has_state()) {
unreachable_block->set_predecessor(nullptr);
} else {
for (int i = unreachable_block->predecessor_count() - 1; i >= 0; i--) {
if (unreachable_block->predecessor_at(i) == current) {
unreachable_block->state()->RemovePredecessorAt(i);
}
}
}
Jump* new_control_node = branch_node->OverwriteWith<Jump>();
new_control_node->set_target(target);
int predecessor_id;
if (!target->has_state()) {
predecessor_id = 0;
} else {
for (int i = target->predecessor_count() - 1; i >= 0; i--) {
if (target->predecessor_at(i) == current) {
predecessor_id = i;
}
}
}
new_control_node->set_predecessor_id(predecessor_id);
reducer_.graph()->set_may_have_unreachable_blocks(true);
return new_control_node;
}
ReduceResult MaglevGraphOptimizer::EmitUnconditionalDeopt(
DeoptimizeReason reason) {
BasicBlock* block = reducer_.current_block();
ControlNode* control = block->reset_control_node();
block->set_deferred(true);
block->RemovePredecessorFollowing(control);
reducer_.AddNewControlNode<Deopt>({}, reason);
return ReduceResult::DoneWithAbort();
}
ProcessResult MaglevGraphOptimizer::EmitAbort(AbortReason reason) {
BasicBlock* block = reducer_.current_block();
ControlNode* control = block->reset_control_node();
block->RemovePredecessorFollowing(control);
reducer_.AddNewControlNode<Abort>({}, reason);
return ProcessResult::kTruncateBlock;
}
template <typename NodeT>
ProcessResult MaglevGraphOptimizer::ProcessLoadContextSlot(NodeT* node) {
REPLACE_AND_RETURN_IF_DONE(known_node_aspects().TryGetContextCachedValue(
node->input_node(0), node->offset(),
node->is_const() ? ContextSlotMutability::kImmutable
: ContextSlotMutability::kMutable));
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitAssertInt32(
AssertInt32* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckDynamicValue(
CheckDynamicValue* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckInt32IsSmi(
CheckInt32IsSmi* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckUint32IsSmi(
CheckUint32IsSmi* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckIntPtrIsSmi(
CheckIntPtrIsSmi* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckFloat64IsSmi(
CheckFloat64IsSmi* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckHoleyFloat64IsSmi(
CheckHoleyFloat64IsSmi* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckHeapObject(
CheckHeapObject* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckInt32Condition(
CheckInt32Condition* node, const ProcessingState& state) {
if (node->condition() == AssertCondition::kUnsignedLessThan) {
ValueNode* lhs = node->input_node(0);
ValueNode* rhs = node->input_node(1);
auto r1 = GetRange(lhs);
auto r2 = GetRange(rhs);
if (r1 && r2 && r1->IsUint32()) {
if (*r1 < *r2 || IsRangeLessEqual(lhs, rhs)) {
return ProcessResult::kRemove;
}
}
}
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckCacheIndicesNotCleared(
CheckCacheIndicesNotCleared* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckJSDataViewBounds(
CheckJSDataViewBounds* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckTypedArrayBounds(
CheckTypedArrayBounds* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckTypedArrayNotDetached(
CheckTypedArrayNotDetached* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
template <typename NodeT>
ProcessResult MaglevGraphOptimizer::ProcessCheckMaps(NodeT* node,
ValueNode* object_map) {
ValueNode* object = node->input_node(0);
KnownMapsMerger<compiler::ZoneRefSet<Map>> merger(broker(), reducer_.zone(),
node->maps());
MaybeReduceResult result =
reducer_.TryFoldCheckMaps(object, object_map, node->maps(), merger);
if (result.IsDoneWithAbort()) {
return ProcessResult::kTruncateBlock;
}
if (result.IsDone()) {
if (merger.emit_check_with_migration()) {
return ProcessResult::kContinue;
}
return ProcessResult::kRemove;
}
merger.UpdateKnownNodeAspects(object, known_node_aspects());
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckMaps(
CheckMaps* node, const ProcessingState& state) {
return ProcessCheckMaps(node);
}
ProcessResult MaglevGraphOptimizer::VisitCheckMapsWithMigrationAndDeopt(
CheckMapsWithMigrationAndDeopt* node, const ProcessingState& state) {
return ProcessCheckMaps(node);
}
ProcessResult MaglevGraphOptimizer::VisitCheckMapsWithMigration(
CheckMapsWithMigration* node, const ProcessingState& state) {
return ProcessCheckMaps(node);
}
ProcessResult MaglevGraphOptimizer::VisitCheckMapsWithAlreadyLoadedMap(
CheckMapsWithAlreadyLoadedMap* node, const ProcessingState& state) {
return ProcessCheckMaps(node, node->MapInput().node());
}
ProcessResult MaglevGraphOptimizer::VisitCheckDetectableCallable(
CheckDetectableCallable* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckJSReceiverOrNullOrUndefined(
CheckJSReceiverOrNullOrUndefined* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckNotHole(
CheckNotHole* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckHoleyFloat64NotHoleOrUndefined(
CheckHoleyFloat64NotHoleOrUndefined* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
#define VISIT_CHECK(Type) \
ProcessResult MaglevGraphOptimizer::VisitCheck##Type( \
Check##Type* node, const ProcessingState& state) { \
if (NodeTypeIs(reducer_.GetType(node->input_node(0)), \
NodeType::k##Type)) { \
return ProcessResult::kRemove; \
} \
return ProcessResult::kContinue; \
}
VISIT_CHECK(Smi)
VISIT_CHECK(Number)
VISIT_CHECK(String)
VISIT_CHECK(SeqOneByteString)
VISIT_CHECK(StringOrStringWrapper)
VISIT_CHECK(StringOrOddball)
VISIT_CHECK(Symbol)
#undef PROCESS_CHECK
ProcessResult MaglevGraphOptimizer::VisitCheckValue(
CheckValue* node, const ProcessingState& state) {
ValueNode* input = node->input_node(0);
if (Constant* constant = input->TryCast<Constant>()) {
if (constant->object() == node->value()) {
return ProcessResult::kRemove;
}
}
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckValueEqualsInt32(
CheckValueEqualsInt32* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckFloat64SameValue(
CheckFloat64SameValue* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckValueEqualsString(
CheckValueEqualsString* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckInstanceType(
CheckInstanceType* node, const ProcessingState& state) {
ValueNode* input = node->input_node(0);
if (input->Is<FastCreateClosure>()) {
if (node->first_instance_type() == FIRST_JS_FUNCTION_TYPE &&
node->last_instance_type() == LAST_JS_FUNCTION_TYPE) {
return ProcessResult::kRemove;
}
}
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitDead(Dead* node,
const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitMajorGCForCompilerTesting(
MajorGCForCompilerTesting*, const ProcessingState&) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitDebugBreak(
DebugBreak* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitFunctionEntryStackCheck(
FunctionEntryStackCheck* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitGeneratorStore(
GeneratorStore* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitTryOnStackReplacement(
TryOnStackReplacement* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitStoreMap(
StoreMap* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitStoreFixedArrayElementWithWriteBarrier(
StoreFixedArrayElementWithWriteBarrier* node,
const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitStoreFixedArrayElementNoWriteBarrier(
StoreFixedArrayElementNoWriteBarrier* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitStoreFixedHoleyDoubleArrayElement(
StoreFixedHoleyDoubleArrayElement* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitStoreFixedDoubleArrayElement(
StoreFixedDoubleArrayElement* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitStoreInt32(
StoreInt32* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitStoreFloat64(
StoreFloat64* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitStoreIntTypedArrayElement(
StoreIntTypedArrayElement* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitStoreDoubleTypedArrayElement(
StoreDoubleTypedArrayElement* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitStoreIntConstantTypedArrayElement(
StoreIntConstantTypedArrayElement* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitStoreDoubleConstantTypedArrayElement(
StoreDoubleConstantTypedArrayElement* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitStoreSignedIntDataViewElement(
StoreSignedIntDataViewElement* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitStoreDoubleDataViewElement(
StoreDoubleDataViewElement* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitStoreTaggedFieldNoWriteBarrier(
StoreTaggedFieldNoWriteBarrier* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitStoreTaggedFieldWithWriteBarrier(
StoreTaggedFieldWithWriteBarrier* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitStoreContextSlotWithWriteBarrier(
StoreContextSlotWithWriteBarrier* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitStoreSmiContextCell(
StoreSmiContextCell* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitStoreInt32ContextCell(
StoreInt32ContextCell* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitStoreFloat64ContextCell(
StoreFloat64ContextCell* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult
MaglevGraphOptimizer::VisitStoreTrustedPointerFieldWithWriteBarrier(
StoreTrustedPointerFieldWithWriteBarrier* node,
const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitHandleNoHeapWritesInterrupt(
HandleNoHeapWritesInterrupt* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitReduceInterruptBudgetForLoop(
ReduceInterruptBudgetForLoop* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitReduceInterruptBudgetForReturn(
ReduceInterruptBudgetForReturn* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitDeoptIfHole(DeoptIfHole* node,
const ProcessingState&) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitThrowReferenceErrorIfHole(
ThrowReferenceErrorIfHole* node, const ProcessingState& state) {
switch (node->ValueInput().node()->IsTheHole()) {
case Tribool::kTrue: {
ValueNode* throw_input = reducer_.GetConstant(node->name());
Throw* throw_node = node->OverwriteWith<Throw>();
throw_node->UpdateBitfield(Throw::kThrowAccessedUninitializedVariable,
true);
throw_node->change_input(0, throw_input);
return ProcessResult::kContinue;
}
case Tribool::kFalse:
return ProcessResult::kRemove;
case Tribool::kMaybe:
return ProcessResult::kContinue;
}
}
ProcessResult MaglevGraphOptimizer::VisitThrowSuperNotCalledIfHole(
ThrowSuperNotCalledIfHole* node, const ProcessingState& state) {
switch (node->ValueInput().node()->IsTheHole()) {
case Tribool::kTrue: {
Throw* throw_node = node->OverwriteWith<Throw>();
throw_node->UpdateBitfield(Throw::kThrowSuperNotCalled,
false);
return ProcessResult::kContinue;
}
case Tribool::kFalse:
return ProcessResult::kRemove;
case Tribool::kMaybe:
return ProcessResult::kContinue;
}
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitThrowSuperAlreadyCalledIfNotHole(
ThrowSuperAlreadyCalledIfNotHole* node, const ProcessingState& state) {
switch (node->ValueInput().node()->IsTheHole()) {
case Tribool::kTrue:
return ProcessResult::kRemove;
case Tribool::kFalse: {
Throw* throw_node = node->OverwriteWith<Throw>();
throw_node->UpdateBitfield(Throw::kThrowSuperAlreadyCalledError,
false);
return ProcessResult::kContinue;
}
case Tribool::kMaybe:
return ProcessResult::kContinue;
}
}
ProcessResult MaglevGraphOptimizer::VisitThrowIfNotCallable(
ThrowIfNotCallable* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitThrowIfNotSuperConstructor(
ThrowIfNotSuperConstructor* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitTransitionElementsKindOrCheckMap(
TransitionElementsKindOrCheckMap* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitSetContinuationPreservedEmbedderData(
SetContinuationPreservedEmbedderData* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitTransitionAndStoreArrayElement(
TransitionAndStoreArrayElement* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitIdentity(
Identity* node, const ProcessingState& state) {
return ProcessResult::kRemove;
}
ProcessResult MaglevGraphOptimizer::VisitAllocationBlock(
AllocationBlock* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitArgumentsElements(
ArgumentsElements* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitArgumentsLength(
ArgumentsLength* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitRestLength(
RestLength* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCall(Call* node,
const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCallBuiltin(
CallBuiltin* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCallForwardVarargs(
CallForwardVarargs* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitConstructForwardVarargs(
ConstructForwardVarargs* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCallRuntime(
CallRuntime* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCallWithArrayLike(
CallWithArrayLike* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCallWithSpread(
CallWithSpread* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCallKnownApiFunction(
CallKnownApiFunction* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCallKnownJSFunction(
CallKnownJSFunction* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitReturnedValue(
ReturnedValue* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCallSelf(
CallSelf* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitConstruct(
Construct* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckConstructResult(
CheckConstructResult* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckDerivedConstructResult(
CheckDerivedConstructResult* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitConstructWithSpread(
ConstructWithSpread* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitConvertReceiver(
ConvertReceiver* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitConvertHoleToUndefined(
ConvertHoleToUndefined* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCreateArrayLiteral(
CreateArrayLiteral* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCreateShallowArrayLiteral(
CreateShallowArrayLiteral* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCreateObjectLiteral(
CreateObjectLiteral* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCreateShallowObjectLiteral(
CreateShallowObjectLiteral* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCreateFunctionContext(
CreateFunctionContext* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCreateClosure(
CreateClosure* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitFastCreateClosure(
FastCreateClosure* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCreateRegExpLiteral(
CreateRegExpLiteral* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitDeleteProperty(
DeleteProperty* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitEnsureWritableFastElements(
EnsureWritableFastElements* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitExtendPropertiesBackingStore(
ExtendPropertiesBackingStore* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitInlinedAllocation(
InlinedAllocation* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitForInPrepare(
ForInPrepare* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitForInNext(
ForInNext* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitGeneratorRestoreRegister(
GeneratorRestoreRegister* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitGetIterator(
GetIterator* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitGetSecondReturnedValue(
GetSecondReturnedValue* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitGetTemplateObject(
GetTemplateObject* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitHasInPrototypeChain(
HasInPrototypeChain* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitInitialValue(
InitialValue* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitLoadTaggedField(
LoadTaggedField* node, const ProcessingState& state) {
if (node->offset() == HeapObject::kMapOffset) {
if (auto constant =
reducer_.TryGetConstant<HeapObject>(node->input_node(0))) {
compiler::MapRef map = constant->map(broker());
if (map.is_stable()) {
broker()->dependencies()->DependOnStableMap(map);
return ReplaceWith(reducer_.GetConstant(map));
}
}
}
if (node->offset() == JSFunction::kFeedbackCellOffset) {
if (auto input = node->input_node(0)->TryCast<FastCreateClosure>()) {
return ReplaceWith(reducer_.GetConstant(input->feedback_cell()));
}
}
if (!node->property_key().is_none()) {
REPLACE_AND_RETURN_IF_DONE(known_node_aspects().TryFindLoadedProperty(
node->ValueInput().node(), node->property_key(), node->is_const()));
}
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitLoadContextSlotNoCells(
LoadContextSlotNoCells* node, const ProcessingState& state) {
return ProcessLoadContextSlot(node);
}
ProcessResult MaglevGraphOptimizer::VisitLoadContextSlot(
LoadContextSlot* node, const ProcessingState& state) {
return ProcessLoadContextSlot(node);
}
ProcessResult MaglevGraphOptimizer::VisitLoadFloat64(
LoadFloat64* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitLoadInt32(
LoadInt32* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitLoadTaggedFieldByFieldIndex(
LoadTaggedFieldByFieldIndex* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitLoadFixedArrayElement(
LoadFixedArrayElement* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitLoadFixedDoubleArrayElement(
LoadFixedDoubleArrayElement* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitLoadHoleyFixedDoubleArrayElement(
LoadHoleyFixedDoubleArrayElement* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult
MaglevGraphOptimizer::VisitLoadHoleyFixedDoubleArrayElementCheckedNotHole(
LoadHoleyFixedDoubleArrayElementCheckedNotHole* node,
const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitLoadSignedIntDataViewElement(
LoadSignedIntDataViewElement* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitLoadDoubleDataViewElement(
LoadDoubleDataViewElement* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitLoadTypedArrayLength(
LoadTypedArrayLength* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitLoadDataViewByteLength(
LoadDataViewByteLength* node, const ProcessingState& state) {
REPLACE_AND_RETURN_IF_DONE(known_node_aspects().TryFindLoadedConstantProperty(
node->ValueInput().node(), PropertyKey::ArrayBufferViewByteLength()));
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitLoadDataViewDataPointer(
LoadDataViewDataPointer* node, const ProcessingState& state) {
REPLACE_AND_RETURN_IF_DONE(known_node_aspects().TryFindLoadedConstantProperty(
node->ValueInput().node(), PropertyKey::ArrayBufferViewDataPointer()));
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitLoadSignedIntTypedArrayElement(
LoadSignedIntTypedArrayElement* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitLoadUnsignedIntTypedArrayElement(
LoadUnsignedIntTypedArrayElement* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitLoadDoubleTypedArrayElement(
LoadDoubleTypedArrayElement* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitLoadSignedIntConstantTypedArrayElement(
LoadSignedIntConstantTypedArrayElement* node,
const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult
MaglevGraphOptimizer::VisitLoadUnsignedIntConstantTypedArrayElement(
LoadUnsignedIntConstantTypedArrayElement* node,
const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitLoadDoubleConstantTypedArrayElement(
LoadDoubleConstantTypedArrayElement* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitLoadEnumCacheLength(
LoadEnumCacheLength* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitLoadGlobal(
LoadGlobal* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitLoadNamedGeneric(
LoadNamedGeneric* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitLoadNamedFromSuperGeneric(
LoadNamedFromSuperGeneric* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitMaybeGrowFastElements(
MaybeGrowFastElements* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitMigrateMapIfNeeded(
MigrateMapIfNeeded* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitSetNamedGeneric(
SetNamedGeneric* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitDefineNamedOwnGeneric(
DefineNamedOwnGeneric* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitStoreInArrayLiteralGeneric(
StoreInArrayLiteralGeneric* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitStoreGlobal(
StoreGlobal* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitGetKeyedGeneric(
GetKeyedGeneric* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitSetKeyedGeneric(
SetKeyedGeneric* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitDefineKeyedOwnGeneric(
DefineKeyedOwnGeneric* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitPhi(Phi* node,
const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitRegisterInput(
RegisterInput* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckedSmiSizedInt32(
CheckedSmiSizedInt32* node, const ProcessingState& state) {
if (auto cst = reducer_.TryGetInt32Constant(node->input_node(0))) {
if (Smi::IsValid(cst.value())) {
return ReplaceWith(reducer_.GetInt32Constant(cst.value()));
}
}
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckedSmiTagInt32(
CheckedSmiTagInt32* node, const ProcessingState& state) {
if (auto range = GetRange(node->input_node(0))) {
if (Range::Smi().contains(*range)) {
return ReplaceWith<UnsafeSmiTagInt32>({node->input_node(0)});
}
}
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckedSmiTagUint32(
CheckedSmiTagUint32* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckedSmiTagIntPtr(
CheckedSmiTagIntPtr* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitUnsafeSmiTagInt32(
UnsafeSmiTagInt32* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitUnsafeSmiTagUint32(
UnsafeSmiTagUint32* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitUnsafeSmiTagIntPtr(
UnsafeSmiTagIntPtr* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckedInternalizedString(
CheckedInternalizedString* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckedObjectToIndex(
CheckedObjectToIndex* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckedInt32ToUint32(
CheckedInt32ToUint32* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitUnsafeInt32ToUint32(
UnsafeInt32ToUint32* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckedUint32ToInt32(
CheckedUint32ToInt32* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckedIntPtrToInt32(
CheckedIntPtrToInt32* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitChangeInt32ToFloat64(
ChangeInt32ToFloat64* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitChangeInt32ToHoleyFloat64(
ChangeInt32ToHoleyFloat64* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitChangeUint32ToFloat64(
ChangeUint32ToFloat64* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitChangeUint32ToHoleyFloat64(
ChangeUint32ToHoleyFloat64* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitChangeIntPtrToFloat64(
ChangeIntPtrToFloat64* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckedFloat64ToInt32(
CheckedFloat64ToInt32* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckedHoleyFloat64ToInt32(
CheckedHoleyFloat64ToInt32* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitTruncateUint32ToInt32(
TruncateUint32ToInt32* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitTruncateFloat64ToInt32(
TruncateFloat64ToInt32* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitTruncateHoleyFloat64ToInt32(
TruncateHoleyFloat64ToInt32* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitUnsafeFloat64ToInt32(
UnsafeFloat64ToInt32* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitUnsafeHoleyFloat64ToInt32(
UnsafeHoleyFloat64ToInt32* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitInt32ToUint8Clamped(
Int32ToUint8Clamped* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitUint32ToUint8Clamped(
Uint32ToUint8Clamped* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitFloat64ToUint8Clamped(
Float64ToUint8Clamped* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckedNumberToUint8Clamped(
CheckedNumberToUint8Clamped* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitInt32ToNumber(
Int32ToNumber* node, const ProcessingState& state) {
REPLACE_AND_RETURN_IF_DONE(TrySmiTag<UnsafeSmiTagInt32>(node->ValueInput()));
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitUint32ToNumber(
Uint32ToNumber* node, const ProcessingState& state) {
REPLACE_AND_RETURN_IF_DONE(TrySmiTag<UnsafeSmiTagUint32>(node->ValueInput()));
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitIntPtrToNumber(
IntPtrToNumber* node, const ProcessingState& state) {
REPLACE_AND_RETURN_IF_DONE(TrySmiTag<UnsafeSmiTagIntPtr>(node->ValueInput()));
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitShiftedInt53ToNumber(
ShiftedInt53ToNumber* node, const ProcessingState& state) {
REPLACE_AND_RETURN_IF_DONE(
TrySmiTag<UnsafeSmiTagShiftedInt53>(node->ValueInput()));
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitInt32CountLeadingZeros(
Int32CountLeadingZeros* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitTaggedCountLeadingZeros(
TaggedCountLeadingZeros* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitFloat64CountLeadingZeros(
Float64CountLeadingZeros* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitIntPtrToBoolean(
IntPtrToBoolean* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitFloat64ToTagged(
Float64ToTagged* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitFloat64ToHeapNumberForField(
Float64ToHeapNumberForField* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitHoleyFloat64ToTagged(
HoleyFloat64ToTagged* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckedSmiTagFloat64(
CheckedSmiTagFloat64* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckedSmiTagHoleyFloat64(
CheckedSmiTagHoleyFloat64* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckedNumberOrOddballToHoleyFloat64(
CheckedNumberOrOddballToHoleyFloat64* node, const ProcessingState& state) {
REPLACE_AND_RETURN_IF_DONE(GetUntaggedValueWithRepresentation(
node->input_node(0), UseRepresentation::kHoleyFloat64,
node->conversion_type()));
return ProcessResult::kContinue;
}
#define UNTAGGING_CASE(Node, Repr, ConvType) \
ProcessResult MaglevGraphOptimizer::Visit##Node( \
Node* node, const ProcessingState& state) { \
REPLACE_AND_RETURN_IF_DONE(GetUntaggedValueWithRepresentation( \
node->input_node(0), UseRepresentation::k##Repr, ConvType)); \
return ProcessResult::kContinue; \
}
UNTAGGING_CASE(UnsafeSmiUntag, Int32, {})
UNTAGGING_CASE(CheckedNumberToInt32, Int32, {})
UNTAGGING_CASE(TruncateCheckedNumberOrOddballToInt32, TruncatedInt32,
node->conversion_type())
UNTAGGING_CASE(TruncateUnsafeNumberOrOddballToInt32, TruncatedInt32,
node->conversion_type())
UNTAGGING_CASE(CheckedNumberToShiftedInt53, ShiftedInt53, {})
UNTAGGING_CASE(CheckedNumberOrOddballToFloat64, Float64,
node->conversion_type())
UNTAGGING_CASE(UnsafeNumberOrOddballToFloat64, Float64, node->conversion_type())
UNTAGGING_CASE(UnsafeNumberToFloat64, Float64,
TaggedToFloat64ConversionType::kOnlyNumber)
UNTAGGING_CASE(UnsafeNumberOrOddballToHoleyFloat64, HoleyFloat64,
node->conversion_type())
#undef UNTAGGING_CASE
ProcessResult MaglevGraphOptimizer::VisitCheckedSmiUntag(
CheckedSmiUntag* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckedNumberToFloat64(
CheckedNumberToFloat64* node, const ProcessingState& state) {
MaybeReduceResult maybe_alt = GetUntaggedValueWithRepresentation(
node->input_node(0), UseRepresentation::kFloat64,
TaggedToFloat64ConversionType::kOnlyNumber);
if (maybe_alt.IsDoneWithValue()) {
ValueNode* alt = maybe_alt.value();
if (alt->Is<CheckedNumberOrOddballToFloat64>() ||
alt->Is<UnsafeNumberOrOddballToFloat64>()) {
return ProcessResult::kContinue;
}
return ReplaceWith(alt);
} else if (maybe_alt.IsDoneWithAbort()) {
return ProcessResult::kTruncateBlock;
}
DCHECK(maybe_alt.IsFail());
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckedHoleyFloat64ToFloat64(
CheckedHoleyFloat64ToFloat64* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitUnsafeHoleyFloat64ToFloat64(
UnsafeHoleyFloat64ToFloat64* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitUnsafeFloat64ToHoleyFloat64(
UnsafeFloat64ToHoleyFloat64* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitFloat64ToSilencedFloat64(
Float64ToSilencedFloat64* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitHoleyFloat64ToSilencedFloat64(
HoleyFloat64ToSilencedFloat64* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitChangeFloat64ToHoleyFloat64(
ChangeFloat64ToHoleyFloat64* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
#ifdef V8_ENABLE_UNDEFINED_DOUBLE
ProcessResult MaglevGraphOptimizer::VisitHoleyFloat64ConvertHoleToUndefined(
HoleyFloat64ConvertHoleToUndefined* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitHoleyFloat64IsUndefinedOrHole(
HoleyFloat64IsUndefinedOrHole* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::
VisitLoadHoleyFixedDoubleArrayElementCheckedNotUndefinedOrHole(
LoadHoleyFixedDoubleArrayElementCheckedNotUndefinedOrHole* node,
const ProcessingState& state) {
return ProcessResult::kContinue;
}
#else
ProcessResult MaglevGraphOptimizer::VisitHoleyFloat64IsHole(
HoleyFloat64IsHole* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
#endif
ProcessResult MaglevGraphOptimizer::VisitLogicalNot(
LogicalNot* node, const ProcessingState& state) {
REPLACE_AND_RETURN_IF_DONE(reducer_.TryFoldLogicalNot(node->input_node(0)));
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitSetPendingMessage(
SetPendingMessage* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitStringAt(
StringAt* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitStringEqual(
StringEqual* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitStringLength(
StringLength* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitStringConcat(
StringConcat* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitSeqOneByteStringAt(
SeqOneByteStringAt* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitConsStringMap(
ConsStringMap* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitUnwrapStringWrapper(
UnwrapStringWrapper* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitToBoolean(
ToBoolean* node, const ProcessingState& state) {
if (IsConstantNode(node->input_node(0)->opcode())) {
return ReplaceWith(reducer_.GetBooleanConstant(
FromConstantToBool(reducer_.local_isolate(), node->input_node(0))));
}
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitToBooleanLogicalNot(
ToBooleanLogicalNot* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitAllocateElementsArray(
AllocateElementsArray* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitTaggedEqual(
TaggedEqual* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitTaggedNotEqual(
TaggedNotEqual* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitTestInstanceOf(
TestInstanceOf* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitTestUndetectable(
TestUndetectable* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitTestTypeOf(
TestTypeOf* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitToName(ToName* node,
const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitToNumberOrNumeric(
ToNumberOrNumeric* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitToObject(
ToObject* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitToString(
ToString* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitTransitionElementsKind(
TransitionElementsKind* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitInt32ToString(
Int32ToString* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitFloat64ToString(
Float64ToString* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitSmiToString(
SmiToString* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitNumberToString(
NumberToString* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitUpdateJSArrayLength(
UpdateJSArrayLength* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitGetContinuationPreservedEmbedderData(
GetContinuationPreservedEmbedderData* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
#define CONSTANT_CASE(Node) \
ProcessResult MaglevGraphOptimizer::Visit##Node( \
Node* node, const ProcessingState& state) { \
return ProcessResult::kContinue; \
}
CONSTANT_VALUE_NODE_LIST(CONSTANT_CASE)
#undef CONSTANT_CASE
ProcessResult MaglevGraphOptimizer::VisitInt32AbsWithOverflow(
Int32AbsWithOverflow* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitInt32Increment(
Int32Increment* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitInt32Decrement(
Int32Decrement* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitInt32Add(
Int32Add* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitInt32Subtract(
Int32Subtract* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitInt32Multiply(
Int32Multiply* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitInt32MultiplyOverflownBits(
Int32MultiplyOverflownBits* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitInt32Divide(
Int32Divide* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitInt32AddWithOverflow(
Int32AddWithOverflow* node, const ProcessingState& state) {
RETURN_IF_SUCCESS(TryFoldInt32Operation<Operation::kAdd>(node));
if (auto lhs_range = GetRange(node->input_node(0))) {
if (auto rhs_range = GetRange(node->input_node(1))) {
if (Range::Add(*lhs_range, *rhs_range).IsInt32()) {
return ReplaceWith<Int32Add>(
{node->input_node(0), node->input_node(1)});
}
}
}
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitInt32SubtractWithOverflow(
Int32SubtractWithOverflow* node, const ProcessingState& state) {
RETURN_IF_SUCCESS(TryFoldInt32Operation<Operation::kSubtract>(node));
if (auto lhs_range = GetRange(node->input_node(0))) {
if (auto rhs_range = GetRange(node->input_node(1))) {
if (Range::Sub(*lhs_range, *rhs_range).IsInt32()) {
return ReplaceWith<Int32Subtract>(
{node->input_node(0), node->input_node(1)});
}
}
}
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitInt32MultiplyWithOverflow(
Int32MultiplyWithOverflow* node, const ProcessingState& state) {
RETURN_IF_SUCCESS(TryFoldInt32Operation<Operation::kMultiply>(node));
if (auto lhs_range = GetRange(node->input_node(0))) {
if (auto rhs_range = GetRange(node->input_node(1))) {
if (Range::Mul(*lhs_range, *rhs_range).IsInt32()) {
return ReplaceWith<Int32Multiply>(
{node->input_node(0), node->input_node(1)});
}
}
}
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitInt32DivideWithOverflow(
Int32DivideWithOverflow* node, const ProcessingState& state) {
RETURN_IF_SUCCESS(TryFoldInt32Operation<Operation::kDivide>(node));
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitInt32ModulusWithOverflow(
Int32ModulusWithOverflow* node, const ProcessingState& state) {
RETURN_IF_SUCCESS(TryFoldInt32Operation<Operation::kModulus>(node));
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitInt32BitwiseAnd(
Int32BitwiseAnd* node, const ProcessingState& state) {
RETURN_IF_SUCCESS(TryFoldInt32Operation<Operation::kBitwiseAnd>(node));
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitInt32BitwiseOr(
Int32BitwiseOr* node, const ProcessingState& state) {
RETURN_IF_SUCCESS(TryFoldInt32Operation<Operation::kBitwiseOr>(node));
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitInt32BitwiseXor(
Int32BitwiseXor* node, const ProcessingState& state) {
RETURN_IF_SUCCESS(TryFoldInt32Operation<Operation::kBitwiseXor>(node));
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitInt32ShiftLeft(
Int32ShiftLeft* node, const ProcessingState& state) {
RETURN_IF_SUCCESS(TryFoldInt32Operation<Operation::kShiftLeft>(node));
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitInt32ShiftRight(
Int32ShiftRight* node, const ProcessingState& state) {
RETURN_IF_SUCCESS(TryFoldInt32Operation<Operation::kShiftRight>(node));
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitInt32ShiftRightLogical(
Int32ShiftRightLogical* node, const ProcessingState& state) {
RETURN_IF_SUCCESS(TryFoldInt32Operation<Operation::kShiftRightLogical>(node));
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitInt32BitwiseNot(
Int32BitwiseNot* node, const ProcessingState& state) {
RETURN_IF_SUCCESS(TryFoldInt32Operation<Operation::kBitwiseNot>(node));
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitInt32NegateWithOverflow(
Int32NegateWithOverflow* node, const ProcessingState& state) {
RETURN_IF_SUCCESS(TryFoldInt32Operation<Operation::kNegate>(node));
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitInt32IncrementWithOverflow(
Int32IncrementWithOverflow* node, const ProcessingState& state) {
RETURN_IF_SUCCESS(TryFoldInt32Operation<Operation::kIncrement>(node));
if (auto range = GetRange(node->input_node(0))) {
if (range->IsInt32() && *range->max() != INT32_MAX) {
return ReplaceWith<Int32Increment>({node->input_node(0)});
}
}
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitInt32DecrementWithOverflow(
Int32DecrementWithOverflow* node, const ProcessingState& state) {
RETURN_IF_SUCCESS(TryFoldInt32Operation<Operation::kDecrement>(node));
if (auto range = GetRange(node->input_node(0))) {
if (range->IsInt32() && *range->min() != INT32_MIN) {
return ReplaceWith<Int32Decrement>({node->input_node(0)});
}
}
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitInt32Compare(
Int32Compare* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitInt32ToBoolean(
Int32ToBoolean* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitShiftedInt53AddWithOverflow(
ShiftedInt53AddWithOverflow* node, const ProcessingState& state) {
REPLACE_AND_RETURN_IF_DONE(reducer_.TryFoldShiftedInt53Add(
node->input_node(0), node->input_node(1)));
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitFloat64Abs(
Float64Abs* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitFloat64Add(
Float64Add* node, const ProcessingState& state) {
RETURN_IF_SUCCESS(TryFoldFloat64Operation<Operation::kAdd>(node));
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitFloat64Subtract(
Float64Subtract* node, const ProcessingState& state) {
RETURN_IF_SUCCESS(TryFoldFloat64Operation<Operation::kSubtract>(node));
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitFloat64Multiply(
Float64Multiply* node, const ProcessingState& state) {
RETURN_IF_SUCCESS(TryFoldFloat64Operation<Operation::kMultiply>(node));
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitFloat64Divide(
Float64Divide* node, const ProcessingState& state) {
RETURN_IF_SUCCESS(TryFoldFloat64Operation<Operation::kDivide>(node));
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitFloat64Exponentiate(
Float64Exponentiate* node, const ProcessingState& state) {
RETURN_IF_SUCCESS(TryFoldFloat64Operation<Operation::kExponentiate>(node));
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitFloat64Modulus(
Float64Modulus* node, const ProcessingState& state) {
RETURN_IF_SUCCESS(TryFoldFloat64Operation<Operation::kModulus>(node));
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitFloat64Negate(
Float64Negate* node, const ProcessingState& state) {
RETURN_IF_SUCCESS(TryFoldFloat64Operation<Operation::kNegate>(node));
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitFloat64Round(
Float64Round* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitFloat64Compare(
Float64Compare* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitFloat64ToBoolean(
Float64ToBoolean* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitFloat64Min(
Float64Min* node, const ProcessingState& state) {
REPLACE_AND_RETURN_IF_DONE(reducer_.TryFoldFloat64Min(
node->LeftInput().node(), node->RightInput().node()));
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitFloat64Max(
Float64Max* node, const ProcessingState& state) {
REPLACE_AND_RETURN_IF_DONE(reducer_.TryFoldFloat64Max(
node->LeftInput().node(), node->RightInput().node()));
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitFloat64Ieee754Unary(
Float64Ieee754Unary* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitFloat64Ieee754Binary(
Float64Ieee754Binary* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitFloat64Sqrt(
Float64Sqrt* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckedSmiIncrement(
CheckedSmiIncrement* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckedSmiDecrement(
CheckedSmiDecrement* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitGenericAdd(
GenericAdd* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitGenericSubtract(
GenericSubtract* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitGenericMultiply(
GenericMultiply* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitGenericDivide(
GenericDivide* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitGenericModulus(
GenericModulus* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitGenericExponentiate(
GenericExponentiate* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitGenericBitwiseAnd(
GenericBitwiseAnd* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitGenericBitwiseOr(
GenericBitwiseOr* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitGenericBitwiseXor(
GenericBitwiseXor* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitGenericShiftLeft(
GenericShiftLeft* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitGenericShiftRight(
GenericShiftRight* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitGenericShiftRightLogical(
GenericShiftRightLogical* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitGenericBitwiseNot(
GenericBitwiseNot* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitGenericNegate(
GenericNegate* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitGenericIncrement(
GenericIncrement* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitGenericDecrement(
GenericDecrement* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitGenericEqual(
GenericEqual* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitGenericStrictEqual(
GenericStrictEqual* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitGenericLessThan(
GenericLessThan* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitGenericLessThanOrEqual(
GenericLessThanOrEqual* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitGenericGreaterThan(
GenericGreaterThan* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitGenericGreaterThanOrEqual(
GenericGreaterThanOrEqual* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitBuiltinStringFromCharCode(
BuiltinStringFromCharCode* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult
MaglevGraphOptimizer::VisitBuiltinStringPrototypeCharCodeOrCodePointAt(
BuiltinStringPrototypeCharCodeOrCodePointAt* node,
const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitBuiltinSeqOneByteStringCharCodeAt(
BuiltinSeqOneByteStringCharCodeAt* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCreateFastArrayElements(
CreateFastArrayElements* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitNewConsString(
NewConsString* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitMapPrototypeGet(
MapPrototypeGet* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitMapPrototypeGetInt32Key(
MapPrototypeGetInt32Key* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitSetPrototypeHas(
SetPrototypeHas* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitStringSlice(
StringSlice* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitAbort(Abort* node,
const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitReturn(Return* node,
const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitDeopt(Deopt* node,
const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitThrow(Throw* node,
const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitSwitch(Switch* node,
const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitBranchIfSmi(
BranchIfSmi* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitBranchIfRootConstant(
BranchIfRootConstant* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitBranchIfToBooleanTrue(
BranchIfToBooleanTrue* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitBranchIfInt32ToBooleanTrue(
BranchIfInt32ToBooleanTrue* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitBranchIfIntPtrToBooleanTrue(
BranchIfIntPtrToBooleanTrue* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitBranchIfFloat64ToBooleanTrue(
BranchIfFloat64ToBooleanTrue* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitBranchIfHoleyFloat64ToBooleanTrue(
BranchIfHoleyFloat64ToBooleanTrue* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
#ifdef V8_ENABLE_UNDEFINED_DOUBLE
ProcessResult MaglevGraphOptimizer::VisitBranchIfFloat64IsUndefinedOrHole(
BranchIfFloat64IsUndefinedOrHole* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
#endif
ProcessResult MaglevGraphOptimizer::VisitBranchIfFloat64IsHole(
BranchIfFloat64IsHole* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitBranchIfReferenceEqual(
BranchIfReferenceEqual* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitBranchIfInt32Compare(
BranchIfInt32Compare* node, const ProcessingState& state) {
if (auto result = reducer_.TryFoldInt32CompareOperation(
node->operation(), node->input_node(0), node->input_node(1))) {
FoldBranch(state.block(), node, result.value());
return ProcessResult::kRevisit;
}
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitBranchIfUint32Compare(
BranchIfUint32Compare* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitBranchIfFloat64Compare(
BranchIfFloat64Compare* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitBranchIfUndefinedOrNull(
BranchIfUndefinedOrNull* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitBranchIfUndetectable(
BranchIfUndetectable* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitBranchIfJSReceiver(
BranchIfJSReceiver* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitJump(Jump* node,
const ProcessingState& state) {
return ProcessResult::kContinue;
}
ProcessResult MaglevGraphOptimizer::VisitCheckpointedJump(
CheckpointedJump* node, const ProcessingState& state) {
return ProcessResult::kContinue;
}
#define UNIMPLEMENTED_NODE(name) \
ProcessResult MaglevGraphOptimizer::Visit##name(name*, \
const ProcessingState&) { \
return ProcessResult::kContinue; \
}
UNIMPLEMENTED_NODE(CheckedShiftedInt53ToInt32)
UNIMPLEMENTED_NODE(CheckedShiftedInt53ToUint32)
UNIMPLEMENTED_NODE(CheckedIntPtrToShiftedInt53)
UNIMPLEMENTED_NODE(CheckedHoleyFloat64ToShiftedInt53)
UNIMPLEMENTED_NODE(UnsafeSmiTagShiftedInt53)
UNIMPLEMENTED_NODE(ChangeInt32ToShiftedInt53)
UNIMPLEMENTED_NODE(ChangeUint32ToShiftedInt53)
UNIMPLEMENTED_NODE(ChangeShiftedInt53ToFloat64)
UNIMPLEMENTED_NODE(ChangeShiftedInt53ToHoleyFloat64)
UNIMPLEMENTED_NODE(TruncateShiftedInt53ToInt32)
UNIMPLEMENTED_NODE(CheckedSmiTagShiftedInt53)
UNIMPLEMENTED_NODE(ShiftedInt53ToBoolean)
UNIMPLEMENTED_NODE(AssertRangeInt32)
UNIMPLEMENTED_NODE(AssertRangeFloat64)
ProcessResult MaglevGraphOptimizer::VisitJumpLoop(
JumpLoop* node, const ProcessingState& state) {
BasicBlock* loop_header = node->target();
if (!loop_header->has_phi()) return ProcessResult::kContinue;
for (Phi* phi : *loop_header->phis()) {
for (int i = 0; i < phi->input_count(); i++) {
ValueNode* input = phi->input(i).node();
if (!input) continue;
phi->change_input(i, input->UnwrapIdentities());
}
}
return ProcessResult::kContinue;
}
#define UNREACHABLE_NODES(X) \
X(ConstantGapMove) \
X(GapMove) \
X(VirtualObject)
#define UNREACHEABLE_VISITOR(Node) \
ProcessResult MaglevGraphOptimizer::Visit##Node(Node* node, \
const ProcessingState&) { \
UNREACHABLE(); \
}
UNREACHABLE_NODES(UNREACHEABLE_VISITOR)
}
}
}