39#if V8_ENABLE_WEBASSEMBLY
50 if (v8_flags.trace_representation) PrintF(__VA_ARGS__); \
112UseInfo CheckedUseInfoAsWord32FromHint(
114 const FeedbackSource& feedback = FeedbackSource()) {
133UseInfo CheckedUseInfoAsFloat64FromHint(
187UseInfo UseInfoForBasePointer(
const FieldAccess& access) {
191UseInfo UseInfoForBasePointer(
const ElementAccess& access) {
195void ReplaceEffectControlUses(Node* node, Node* effect, Node* control) {
196 for (Edge edge : node->use_edges()) {
198 edge.UpdateTo(control);
200 edge.UpdateTo(effect);
208bool CanOverflowSigned32(
const Operator* op, Type left, Type right,
209 TypeCache
const* type_cache,
Zone* type_zone) {
213 if (left.Maybe(Type::MinusZero())) {
214 left =
Type::Union(left, type_cache->kSingletonZero, type_zone);
216 if (right.Maybe(Type::MinusZero())) {
217 right =
Type::Union(right, type_cache->kSingletonZero, type_zone);
221 if (left.IsNone() || right.IsNone())
return false;
222 switch (op->opcode()) {
223 case IrOpcode::kSpeculativeSmallIntegerAdd:
224 return (left.Max() + right.Max() >
kMaxInt) ||
225 (left.Min() + right.Min() <
kMinInt);
227 case IrOpcode::kSpeculativeSmallIntegerSubtract:
228 return (left.Max() - right.Min() >
kMaxInt) ||
229 (left.Min() - right.Max() <
kMinInt);
236bool IsSomePositiveOrderedNumber(Type type) {
237 return type.Is(Type::OrderedNumber()) && (type.IsNone() || type.Min() > 0);
240inline bool IsLargeBigInt(Type type) {
241 return type.Is(Type::BigInt()) && !type.Is(Type::SignedBigInt64()) &&
242 !type.Is(Type::UnsignedBigInt64());
245class JSONGraphWriterWithVerifierTypes :
public JSONGraphWriter {
247 JSONGraphWriterWithVerifierTypes(std::ostream& os,
const TFGraph* graph,
248 const SourcePositionTable* positions,
249 const NodeOriginTable*
origins,
250 SimplifiedLoweringVerifier* verifier)
254 std::optional<Type> GetType(Node* node)
override {
262bool IsLoadFloat16ArrayElement(Node* node) {
264 return (opcode == IrOpcode::kLoadTypedElement ||
265 opcode == IrOpcode::kLoadDataViewElement) &&
275 explicit InputUseInfos(
Zone* zone) : input_use_infos_(zone) {}
277 void SetAndCheckInput(Node* node,
int index, UseInfo use_info) {
278 if (input_use_infos_.empty()) {
279 input_use_infos_.resize(node->InputCount(), UseInfo::None());
283 DCHECK(IsUseLessGeneral(input_use_infos_[index], use_info));
284 input_use_infos_[
index] = use_info;
288 ZoneVector<UseInfo> input_use_infos_;
290 static bool IsUseLessGeneral(UseInfo use1, UseInfo use2) {
291 return use1.truncation().IsLessGeneralThan(use2.truncation());
409 int arity = node->op()->ValueInputCount();
411 for (
int i = 1;
i < arity; ++
i) {
423 if (node->op()->ValueOutputCount() == 0)
return false;
426 node->opcode() != IrOpcode::kLoadFramePointer) {
433 if (node->opcode() != IrOpcode::kPhi) {
434 for (
int i = 0;
i < node->op()->ValueInputCount();
i++) {
442 Type type = info->feedback_type();
448 if (node->InputCount() > 0) input0_type =
FeedbackTypeOf(node->InputAt(0));
450 if (node->InputCount() > 1) input1_type =
FeedbackTypeOf(node->InputAt(1));
452 switch (node->opcode()) {
453#define DECLARE_CASE(Name) \
454 case IrOpcode::k##Name: { \
455 new_type = op_typer_.Name(input0_type, input1_type); \
462#define DECLARE_CASE(Name) \
463 case IrOpcode::k##Name: { \
464 new_type = Type::Intersect(op_typer_.Name(input0_type, input1_type), \
465 info->restriction_type(), graph_zone()); \
472#define DECLARE_CASE(Name) \
473 case IrOpcode::k##Name: { \
474 new_type = op_typer_.Name(input0_type); \
480#define DECLARE_CASE(Name) \
481 case IrOpcode::k##Name: { \
482 new_type = Type::Intersect(op_typer_.Name(input0_type), \
483 info->restriction_type(), graph_zone()); \
489 case IrOpcode::kConvertReceiver:
490 new_type =
op_typer_.ConvertReceiver(input0_type);
493 case IrOpcode::kPlainPrimitiveToNumber:
497 case IrOpcode::kCheckBounds:
503 case IrOpcode::kCheckFloat64Hole:
508 case IrOpcode::kCheckNumber:
513 case IrOpcode::kCheckNumberFitsInt32:
518 case IrOpcode::kPhi: {
520 if (!type.IsInvalid()) {
521 new_type =
Weaken(node, type, new_type);
526 case IrOpcode::kConvertTaggedHoleToUndefined:
531 case IrOpcode::kTypeGuard: {
537 case IrOpcode::kSelect: {
540 if (type.IsInvalid()) {
552 if (type.IsInvalid()) {
564 if (!type.IsInvalid() && new_type.
Is(type))
return false;
566 if (
v8_flags.trace_representation) {
574 os <<
"#" << n->id() <<
":" << *n->op() <<
"(";
576 for (
Node*
const i : n->inputs()) {
577 if (j++ > 0) os <<
", ";
578 os <<
"#" <<
i->
id() <<
":" <<
i->op()->mnemonic();
583 os <<
" [Static type: " << static_type;
585 if (!feedback_type.
IsInvalid() && feedback_type != static_type) {
586 os <<
", Feedback type: " << feedback_type;
596 if (!previous_type.
Maybe(integer)) {
603 Type previous_integer =
608 if (!
GetInfo(node)->weakened()) {
614 if (current.IsInvalid() ||
previous.IsInvalid()) {
638 while (!stack.empty()) {
640 Node* node = current.node;
642 bool pushed_unvisited =
false;
643 while (current.input_index < node->InputCount()) {
646 current.input_index++;
649 stack.push({input, 0});
650 pushed_unvisited =
true;
652 }
else if (input_info->
pushed()) {
662 if (pushed_unvisited)
continue;
675 if (info->visited()) {
676 TRACE(
" QUEUEING #%d: %s\n", node->id(), node->op()->mnemonic());
689 TRACE(
" visit #%d: %s\n", node->id(), node->op()->mnemonic());
702 TRACE(
" visit #%d: %s (trunc: %s)\n", node->id(), node->op()->mnemonic(),
703 info->truncation().description());
709 TRACE(
"--{Propagate phase}--\n");
728 TRACE(
"--{Retype phase}--\n");
740 for (
Node*
const user : revisit_it->second) {
752 for (
Node*
const user : revisit_node->
uses()) {
761 TRACE(
"--{Lower phase}--\n");
766 TRACE(
" visit #%d: %s\n", node->id(), node->op()->mnemonic());
779 Node* replacement = *(++
i);
785 if (*j == node) *j = replacement;
793 TRACE(
"--{Verify Phase}--\n");
796 for (
const auto& [constant, uses] :
798 Node* typed_constant =
800 for (
auto use : uses) {
801 for (
int i = 0;
i < use->InputCount(); ++
i) {
802 if (use->InputAt(
i) == constant) {
803 use->ReplaceInput(
i, typed_constant);
816 if (!info->feedback_type().IsInvalid()) {
822 if (compilation_info !=
nullptr && compilation_info->trace_turbo_json()) {
829 writer.
PrintPhase(
"V8.TFSimplifiedLowering [after lower]");
838 if (compilation_info !=
nullptr && compilation_info->trace_turbo_json()) {
843 JSONGraphWriterWithVerifierTypes writer(
845 writer.PrintPhase(
"V8.TFSimplifiedLowering [after verify]");
871 "This version of EnqueueInput has to be called in "
872 "the Retype or Lower phase.");
897 DCHECK_EQ(1, node->op()->ValueInputCount());
902 DCHECK_EQ(1, node->op()->ValueInputCount());
915 DCHECK_EQ(2, node->op()->ValueInputCount());
926 DCHECK_EQ(2, node->op()->ValueInputCount());
937 Node* unreachable = effect =
941 node->ReplaceInput(0, unreachable);
943 ReplaceEffectControlUses(node, effect, control);
951 if (node->op()->EffectInputCount() > 0) {
952 DCHECK_LT(0, node->op()->ControlInputCount());
960 ReplaceEffectControlUses(node, effect, control);
962 DCHECK_EQ(0, node->op()->ControlInputCount());
970 if (node->op()->EffectInputCount() > 0) {
971 DCHECK_LT(0, node->op()->ControlInputCount());
980 ReplaceEffectControlUses(node, effect, control);
982 DCHECK_EQ(0, node->op()->ControlInputCount());
988 int new_input_index,
Node* new_input) {
991 DCHECK_EQ(node->op()->ValueInputCount(), 1);
994 if (node->op()->EffectInputCount() > 0) {
995 DCHECK_LT(0, node->op()->ControlInputCount());
1002 node->TrimInputCount(node->op()->ValueInputCount());
1003 ReplaceEffectControlUses(node, effect, control);
1005 DCHECK_EQ(0, node->op()->ControlInputCount());
1007 if (new_input_index == 0) {
1029 if (input_rep != use.representation() ||
1032 TRACE(
" change: #%d:%s(@%d #%d:%s) ", node->id(), node->op()->mnemonic(),
1033 index, input->id(), input->op()->mnemonic());
1034 TRACE(
"from %s to %s:%s\n",
1037 use.truncation().description());
1038 if (input_type.IsInvalid()) {
1039 input_type =
TypeOf(input);
1045 DCHECK_EQ(node->opcode(), IrOpcode::kTypeGuard);
1061 "This version of ProcessRemainingInputs has to be called in "
1062 "the Retype or Lower phase.");
1074 it->second.push_back(node);
1075 TRACE(
" Marking #%d: %s as needing revisit due to #%d: %s\n", node->id(),
1076 node->op()->mnemonic(), input->id(), input->op()->mnemonic());
1084 "This version of VisitInputs has to be called in the Retype phase.");
1094 for (
int i = 1;
i < first_effect_index;
i++) {
1098 for (
int i = first_effect_index;
i < node->InputCount();
i++) {
1107 for (
int i = 0;
i < first_effect_index;
i++) {
1113 TRACE(
"disconnecting unused #%d:%s\n", node->id(),
1114 node->op()->mnemonic());
1116 node->NullAllInputs();
1136 DCHECK_EQ(2, node->op()->ValueInputCount());
1139 for (
int i = 2;
i < node->InputCount();
i++) {
1149 VisitBinop<T>(node, input_use, input_use, output, restriction_type);
1154 DCHECK_EQ(2, node->op()->ValueInputCount());
1169 DCHECK_EQ(1, node->op()->ValueInputCount());
1206 }
else if (type.Is(Type::Signed32()) || type.Is(Type::Unsigned32())) {
1208 }
else if (type.Is(Type::NumberOrOddball()) && use.IsUsedAsWord32()) {
1210 }
else if (type.Is(Type::Boolean())) {
1212 }
else if (type.Is(Type::NumberOrOddball()) &&
1213 use.TruncatesOddballAndBigIntToNumber()) {
1221 }
else if (type.Is(Type::Number())) {
1223 }
else if (type.Is(Type::BigInt()) &&
Is64() && use.IsUsedAsWord64()) {
1225 }
else if (type.Is(Type::ExternalPointer()) ||
1226 type.Is(Type::SandboxedPointer())) {
1247 ChangeOp(node, lowering->common()->Select(output, p.
hint()));
1252 UseInfo input_use(output, truncation);
1272 int values = node->op()->ValueInputCount();
1276 ChangeOp(node, lowering->common()->Phi(output, values));
1282 UseInfo input_use(output, truncation);
1283 for (
int i = 0;
i < node->InputCount();
i++) {
1290 Type const input_type =
TypeOf(node->InputAt(0));
1291 if (input_type.
Is(type)) {
1296 true_type(), lowering->jsgraph()->Int32Constant(1)));
1303 false_type(), lowering->jsgraph()->Int32Constant(0)));
1324 int params =
static_cast<int>(call_descriptor->ParameterCount());
1325 int value_input_count = node->op()->ValueInputCount();
1335 for (
int i = 1;
i <= params;
i++) {
1337 TruncatingUseInfoFromRepresentation(
1338 call_descriptor->GetInputType(
i).representation()));
1342 for (
int i = params + 1;
i < value_input_count;
i++) {
1349 if (call_descriptor->ReturnCount() > 0) {
1350 SetOutput<T>(node, call_descriptor->GetReturnType(0).representation());
1359 node->ReplaceInput(1,
1367 if (type.Is(Type::Signed32())) {
1369 }
else if (type.Is(Type::Unsigned32())) {
1377 if (type.IsNone()) {
1385 if (type.Is(Type::SignedBigInt64())) {
1389 if (type.Is(Type::UnsignedBigInt64())) {
1393 if (type.Is(Type::BigInt())) {
1406 type.Is(Type::Boolean()));
1407 return machine_type;
1413 for (
int i = 0;
i < node->InputCount();
i++) {
1414 if (IsLargeBigInt(
TypeOf(node->InputAt(
i)))) {
1420 }
else if (IsLoadFloat16ArrayElement(node->InputAt(
i))) {
1433 for (
int i = 0;
i < node->InputCount();
i++) {
1436 if (IsLargeBigInt(
TypeOf(input))) {
1438 }
else if (IsLoadFloat16ArrayElement(input)) {
1452 DCHECK_EQ(5, node->op()->ValueInputCount());
1464 Node* accumulator = node.stack();
1466 if (IsLargeBigInt(
TypeOf(accumulator))) {
1469 }
else if (IsLoadFloat16ArrayElement(accumulator)) {
1480 if (IsLargeBigInt(accumulator_type)) {
1483 accumulator = node.stack();
1484 }
else if (IsLoadFloat16ArrayElement(accumulator)) {
1487 accumulator = node.stack();
1491 if (accumulator ==
jsgraph_->OptimizedOutConstant()) {
1493 jsgraph_->SingleDeadTypedStateValues());
1519 for (
int i = 0;
i < node->InputCount();
i++) {
1520 if (IsLargeBigInt(
TypeOf(node->InputAt(
i)))) {
1522 }
else if (IsLoadFloat16ArrayElement(node->InputAt(
i))) {
1532 for (
int i = 0;
i < node->InputCount();
i++) {
1535 if (IsLargeBigInt(
TypeOf(input))) {
1537 }
else if (IsLoadFloat16ArrayElement(input)) {
1595 if (field_type.
Is(Type::BooleanOrNullOrUndefined()) ||
1596 value_type.
Is(Type::BooleanOrNullOrUndefined())) {
1618 if (
m.HasResolvedValue()) {
1638 value_representation, value);
1645 return write_barrier_kind;
1656 Type input0_type,
Type input1_type,
1658 DCHECK_EQ(node->opcode(), IrOpcode::kSpeculativeNumberMultiply);
1665 if (IsSomePositiveOrderedNumber(input0_type) ||
1666 IsSomePositiveOrderedNumber(input1_type)) {
1668 restriction = Type::Signed32();
1671 restriction = Type::Signed32OrMinusZero();
1674 restriction = Type::Signed32();
1718 Type left_feedback_type =
TypeOf(node->InputAt(0));
1719 Type right_feedback_type =
TypeOf(node->InputAt(1));
1725 Type const restriction =
1729 ? Type::Signed32OrMinusZero()
1737 Type left_constraint_type =
1738 node->opcode() == IrOpcode::kSpeculativeSmallIntegerAdd
1739 ? Type::Signed32OrMinusZero()
1741 if (left_upper.
Is(left_constraint_type) &&
1742 right_upper.
Is(Type::Signed32OrMinusZero()) &&
1743 (left_upper.
Is(Type::Signed32()) || right_upper.
Is(Type::Signed32()))) {
1752 if (node->opcode() == IrOpcode::kSpeculativeSmallIntegerAdd &&
1753 !right_feedback_type.
Maybe(Type::MinusZero())) {
1757 CheckedUseInfoAsWord32FromHint(hint, left_identify_zeros);
1769 !CanOverflowSigned32(node->op(), left_feedback_type,
1780 if (!
v8_flags.additive_safe_int_feedback)
return false;
1785 DCHECK_EQ(2, node->op()->ValueInputCount());
1849 if (
BothInputsAre(node, Type::Unsigned32OrMinusZeroOrNaN()) &&
1857 if (
BothInputsAre(node, Type::Signed32OrMinusZeroOrNaN()) &&
1899 CheckedUseInfoAsWord32FromHint(hint, truncation.
identify_zeros());
1905 }
else if (
BothInputsAre(node, Type::Unsigned32OrMinusZeroOrNaN())) {
1906 Type const restriction =
1909 ? Type::Unsigned32OrMinusZero()
1910 : Type::Unsigned32();
1915 Type const restriction =
1918 ? Type::Signed32OrMinusZero()
1927 if (
TypeOf(node->InputAt(0)).
Is(Type::Unsigned32()) &&
1928 TypeOf(node->InputAt(1)).
Is(Type::Unsigned32()) &&
1936 if (
TypeOf(node->InputAt(0)).
Is(Type::Signed32()) &&
1937 TypeOf(node->InputAt(1)).
Is(Type::Signed32()) &&
1964 "This version of InsertUnreachableIfNecessary has to be "
1965 "called in the Propagate or Retype phase.");
1972 Type const index_type =
TypeOf(node->InputAt(0));
1973 Type const length_type =
TypeOf(node->InputAt(1));
1980 if (length_type.
Is(Type::Unsigned31())) {
1981 if (index_type.
Is(Type::Integral32()) ||
1982 (index_type.
Is(Type::Integral32OrMinusZero()) &&
1991 (index_type.
Min() >= 0.0 &&
1992 index_type.
Max() < length_type.
Min())) {
1996 if (
v8_flags.turbo_typer_hardening) {
2004 simplified()->CheckedUint32Bounds(feedback, new_flags));
2012 simplified()->CheckedUint64Bounds(feedback, new_flags));
2015 simplified()->CheckedUint32Bounds(feedback, new_flags));
2024 simplified()->CheckedUint32Bounds(feedback, new_flags));
2046 switch (type.GetSequenceType()) {
2047 case CTypeInfo::SequenceType::kScalar: {
2048 uint8_t flags = uint8_t(type.GetFlags());
2059 switch (type.GetType()) {
2092 case CTypeInfo::SequenceType::kIsSequence: {
2119 int slow_arg_count =
static_cast<int>(call_descriptor->
ParameterCount());
2120 const int value_input_count = node->op()->ValueInputCount();
2130 for (
int i = 0;
i < c_arg_count;
i++) {
2137 DCHECK_EQ(n.CallbackDataIndex(), cursor);
2144 for (
int i = 1;
i <= slow_arg_count;
i++) {
2146 TruncatingUseInfoFromRepresentation(
2158 switch (return_type.
GetType()) {
2214 if (!ref.IsBigInt())
return false;
2216 bool lossless =
false;
2217 int64_t shift_amount = bigint.
AsInt64(&lossless);
2219 if (!lossless)
return false;
2222 bool is_shift_left =
2223 node->opcode() == IrOpcode::kSpeculativeBigIntShiftLeft;
2224 if (shift_amount < 0) {
2227 if (shift_amount == std::numeric_limits<int64_t>::min())
return false;
2228 is_shift_left = !is_shift_left;
2229 shift_amount = -shift_amount;
2238 if (is_shift_left) {
2243 if (shift_amount > 63) {
2245 }
else if (shift_amount == 0) {
2251 node,
graph()->NewNode(lowering->machine()->Word64Shl(),
2257 }
else if (input_type.
Is(Type::SignedBigInt64())) {
2262 if (shift_amount > 63) {
2265 graph()->NewNode(lowering->machine()->Word64Sar(),
2267 }
else if (shift_amount == 0) {
2273 node,
graph()->NewNode(lowering->machine()->Word64Sar(),
2279 }
else if (input_type.
Is(Type::UnsignedBigInt64())) {
2284 if (shift_amount > 63) {
2286 }
else if (shift_amount == 0) {
2292 node,
graph()->NewNode(lowering->machine()->Word64Shr(),
2304#if V8_ENABLE_WEBASSEMBLY
2307 switch (type.kind()) {
2317 case wasm::kRefNull:
2324 UseInfo UseInfoForJSWasmCallArgument(Node* input,
2325 wasm::CanonicalValueType type,
2326 FeedbackSource
const& feedback) {
2331 switch (type.kind()) {
2343 case wasm::kRefNull:
2351 void VisitJSWasmCall(Node* node, SimplifiedLowering* lowering) {
2352 DCHECK_EQ(JSWasmCallNode::TargetIndex(), 0);
2353 DCHECK_EQ(JSWasmCallNode::ReceiverIndex(), 1);
2354 DCHECK_EQ(JSWasmCallNode::FirstArgumentIndex(), 2);
2356 JSWasmCallNode
n(node);
2358 JSWasmCallParameters
const& params = n.Parameters();
2359 const wasm::CanonicalSig* wasm_signature = params.signature();
2360 int wasm_arg_count =
static_cast<int>(wasm_signature->parameter_count());
2361 DCHECK_EQ(wasm_arg_count, n.ArgumentCount());
2363 base::SmallVector<UseInfo, kInitialArgumentsCount> arg_use_info(
2371 for (
int i = 0;
i < wasm_arg_count;
i++) {
2372 TNode<Object> input = n.Argument(
i);
2374 arg_use_info[
i] = UseInfoForJSWasmCallArgument(
2375 input, wasm_signature->GetParam(
i), params.feedback());
2381 DCHECK(first_effect_index >
2382 JSWasmCallNode::FirstArgumentIndex() + wasm_arg_count);
2383 for (
int i = JSWasmCallNode::FirstArgumentIndex() + wasm_arg_count;
2384 i < first_effect_index;
i++) {
2391 if (wasm_signature->return_count() == 1) {
2392 MachineType return_type =
2393 MachineTypeForWasmReturnType(wasm_signature->GetReturn());
2395 node, return_type.representation(),
2396 JSWasmCallNode::TypeForWasmReturnType(wasm_signature->GetReturn()));
2398 DCHECK_EQ(wasm_signature->return_count(), 0);
2420 if (node->op()->EffectOutputCount() == 0 &&
2421 node->op()->ControlOutputCount() == 0 &&
2422 node->opcode() != IrOpcode::kDeadValue &&
2423 node->opcode() != IrOpcode::kStateValues &&
2424 node->opcode() != IrOpcode::kFrameState &&
2425 node->opcode() != IrOpcode::kPhi) {
2426 for (
int i = 0;
i < node->op()->ValueInputCount();
i++) {
2429 node->ReplaceInput(0, input);
2430 node->TrimInputCount(1);
2449 if (node->op()->ValueInputCount() > 0 &&
2454 switch (node->opcode()) {
2458 case IrOpcode::kStart:
2463 case IrOpcode::kParameter:
2468 case IrOpcode::kInt32Constant:
2483 case IrOpcode::kInt64Constant:
2485 case IrOpcode::kExternalConstant:
2487 case IrOpcode::kNumberConstant: {
2496 lowering->jsgraph()->IntPtrConstant(smi));
2504 case IrOpcode::kHeapConstant:
2506 case IrOpcode::kTrustedHeapConstant:
2508 case IrOpcode::kPointerConstant: {
2517 case IrOpcode::kBranch: {
2534 case IrOpcode::kSwitch:
2538 case IrOpcode::kSelect: {
2551 case IrOpcode::kPhi:
2553 case IrOpcode::kCall:
2555 case IrOpcode::kAssert: {
2566 p.condition_string(), p.file(),
2577 case IrOpcode::kJSToNumber:
2578 case IrOpcode::kJSToNumberConvertBigInt:
2579 case IrOpcode::kJSToNumeric: {
2581 Type::BigInt(), Type::NumberOrOddball(),
graph()->
zone())));
2587 lowering->DoJSToNumberOrNumericTruncatesToWord32(node,
this);
2591 lowering->DoJSToNumberOrNumericTruncatesToFloat64(node,
this);
2597 case IrOpcode::kJSToBigInt:
2598 case IrOpcode::kJSToBigIntConvertNumber: {
2607 case IrOpcode::kToBoolean: {
2618 case IrOpcode::kBooleanNot: {
2624 ChangeOp(node, lowering->machine()->Word32Equal());
2628 ChangeOp(node, lowering->machine()->TaggedEqual());
2640 case IrOpcode::kNumberEqual: {
2641 Type const lhs_type =
TypeOf(node->InputAt(0));
2642 Type const rhs_type =
TypeOf(node->InputAt(1));
2648 if ((lhs_type.
Is(Type::Unsigned32OrMinusZero()) &&
2649 rhs_type.
Is(Type::Unsigned32OrMinusZero())) ||
2650 (lhs_type.
Is(Type::Unsigned32OrMinusZeroOrNaN()) &&
2651 rhs_type.
Is(Type::Unsigned32OrMinusZeroOrNaN()) &&
2659 if ((lhs_type.
Is(Type::Signed32OrMinusZero()) &&
2660 rhs_type.
Is(Type::Signed32OrMinusZero())) ||
2661 (lhs_type.
Is(Type::Signed32OrMinusZeroOrNaN()) &&
2662 rhs_type.
Is(Type::Signed32OrMinusZeroOrNaN()) &&
2670 if (lhs_type.
Is(Type::Boolean()) && rhs_type.
Is(Type::Boolean())) {
2681 case IrOpcode::kNumberLessThan:
2682 case IrOpcode::kNumberLessThanOrEqual: {
2683 Type const lhs_type =
TypeOf(node->InputAt(0));
2684 Type const rhs_type =
TypeOf(node->InputAt(1));
2688 if (lhs_type.
Is(Type::Unsigned32OrMinusZero()) &&
2689 rhs_type.
Is(Type::Unsigned32OrMinusZero())) {
2694 }
else if (lhs_type.
Is(Type::Signed32OrMinusZero()) &&
2695 rhs_type.
Is(Type::Signed32OrMinusZero())) {
2709 case IrOpcode::kSpeculativeSmallIntegerAdd:
2710 case IrOpcode::kSpeculativeSmallIntegerSubtract:
2714 case IrOpcode::kSpeculativeAdditiveSafeIntegerAdd:
2715 case IrOpcode::kSpeculativeAdditiveSafeIntegerSubtract:
2716 case IrOpcode::kSpeculativeNumberAdd:
2717 case IrOpcode::kSpeculativeNumberSubtract:
2720 case IrOpcode::kSpeculativeNumberLessThan:
2721 case IrOpcode::kSpeculativeNumberLessThanOrEqual:
2722 case IrOpcode::kSpeculativeNumberEqual: {
2723 Type const lhs_type =
TypeOf(node->InputAt(0));
2724 Type const rhs_type =
TypeOf(node->InputAt(1));
2728 if (lhs_type.
Is(Type::Unsigned32OrMinusZero()) &&
2729 rhs_type.
Is(Type::Unsigned32OrMinusZero())) {
2735 }
else if (lhs_type.
Is(Type::Signed32OrMinusZero()) &&
2736 rhs_type.
Is(Type::Signed32OrMinusZero())) {
2742 }
else if (lhs_type.
Is(Type::Boolean()) &&
2743 rhs_type.
Is(Type::Boolean())) {
2788 DCHECK_NE(IrOpcode::kSpeculativeNumberEqual, node->opcode());
2793 CheckedUseInfoAsFloat64FromHint(
2803 case IrOpcode::kNumberAdd:
2804 case IrOpcode::kNumberSubtract: {
2805 if (
TypeOf(node->InputAt(0))
2809 (
TypeOf(node).
Is(Type::Signed32()) ||
2810 TypeOf(node).
Is(Type::Unsigned32()) ||
2828 case IrOpcode::kSpeculativeNumberMultiply: {
2863 CheckedUseInfoAsWord32FromHint(hint));
2875 case IrOpcode::kNumberMultiply: {
2876 if (
TypeOf(node->InputAt(0)).
Is(Type::Integral32()) &&
2877 TypeOf(node->InputAt(1)).
Is(Type::Integral32()) &&
2878 (
TypeOf(node).
Is(Type::Signed32()) ||
2879 TypeOf(node).
Is(Type::Unsigned32()) ||
2896 case IrOpcode::kSpeculativeNumberDivide: {
2968 case IrOpcode::kNumberDivide: {
2969 if (
TypeOf(node->InputAt(0)).
Is(Type::Unsigned32()) &&
2970 TypeOf(node->InputAt(1)).
Is(Type::Unsigned32()) &&
2972 TypeOf(node).
Is(Type::Unsigned32()))) {
2978 if (
TypeOf(node->InputAt(0)).
Is(Type::Signed32()) &&
2979 TypeOf(node->InputAt(1)).
Is(Type::Signed32()) &&
2981 TypeOf(node).
Is(Type::Signed32()))) {
2992 case IrOpcode::kUnsigned32Divide: {
3000 case IrOpcode::kSpeculativeNumberModulus:
3002 case IrOpcode::kNumberModulus: {
3003 Type const lhs_type =
TypeOf(node->InputAt(0));
3004 Type const rhs_type =
TypeOf(node->InputAt(1));
3005 if ((lhs_type.
Is(Type::Unsigned32OrMinusZeroOrNaN()) &&
3006 rhs_type.
Is(Type::Unsigned32OrMinusZeroOrNaN())) &&
3008 TypeOf(node).
Is(Type::Unsigned32()))) {
3014 if ((lhs_type.
Is(Type::Signed32OrMinusZeroOrNaN()) &&
3015 rhs_type.
Is(Type::Signed32OrMinusZeroOrNaN())) &&
3018 TypeOf(node).
Is(Type::Signed32OrMinusZero())))) {
3036 case IrOpcode::kNumberBitwiseOr:
3037 case IrOpcode::kNumberBitwiseXor:
3038 case IrOpcode::kNumberBitwiseAnd: {
3043 case IrOpcode::kSpeculativeNumberBitwiseOr:
3044 case IrOpcode::kSpeculativeNumberBitwiseXor:
3045 case IrOpcode::kSpeculativeNumberBitwiseAnd:
3051 case IrOpcode::kNumberShiftLeft: {
3062 case IrOpcode::kSpeculativeNumberShiftLeft: {
3085 case IrOpcode::kNumberShiftRight: {
3096 case IrOpcode::kSpeculativeNumberShiftRight: {
3119 case IrOpcode::kNumberShiftRightLogical: {
3130 case IrOpcode::kSpeculativeNumberShiftRightLogical: {
3144 node->RemoveInput(1);
3169 case IrOpcode::kNumberAbs: {
3173 Type const input_type =
TypeOf(node->InputAt(0));
3174 if (input_type.
Is(Type::Unsigned32OrMinusZero())) {
3184 }
else if (input_type.
Is(Type::Signed32OrMinusZero())) {
3192 lowering->Int32Abs(node)));
3205 case IrOpcode::kNumberClz32: {
3211 case IrOpcode::kNumberImul: {
3218 case IrOpcode::kNumberFround: {
3224 case IrOpcode::kNumberMax: {
3231 Type const lhs_type =
TypeOf(node->InputAt(0));
3232 Type const rhs_type =
TypeOf(node->InputAt(1));
3233 if ((lhs_type.
Is(Type::Unsigned32()) &&
3234 rhs_type.
Is(Type::Unsigned32())) ||
3235 (lhs_type.
Is(Type::Unsigned32OrMinusZero()) &&
3236 rhs_type.
Is(Type::Unsigned32OrMinusZero()) &&
3240 lowering->DoMax(node, lowering->machine()->Uint32LessThan(),
3243 }
else if ((lhs_type.
Is(Type::Signed32()) &&
3244 rhs_type.
Is(Type::Signed32())) ||
3245 (lhs_type.
Is(Type::Signed32OrMinusZero()) &&
3246 rhs_type.
Is(Type::Signed32OrMinusZero()) &&
3250 lowering->DoMax(node, lowering->machine()->Int32LessThan(),
3258 lowering->DoMax(node, lowering->machine()->Int64LessThan(),
3270 ? Type::OrderedNumber()
3271 : Type::PlainNumber()) &&
3272 rhs_type.
Is(Type::OrderedNumber())) {
3273 lowering->DoMax(node, lowering->machine()->Float64LessThan(),
3282 case IrOpcode::kNumberMin: {
3289 Type const lhs_type =
TypeOf(node->InputAt(0));
3290 Type const rhs_type =
TypeOf(node->InputAt(1));
3291 if ((lhs_type.
Is(Type::Unsigned32()) &&
3292 rhs_type.
Is(Type::Unsigned32())) ||
3293 (lhs_type.
Is(Type::Unsigned32OrMinusZero()) &&
3294 rhs_type.
Is(Type::Unsigned32OrMinusZero()) &&
3298 lowering->DoMin(node, lowering->machine()->Uint32LessThan(),
3301 }
else if ((lhs_type.
Is(Type::Signed32()) &&
3302 rhs_type.
Is(Type::Signed32())) ||
3303 (lhs_type.
Is(Type::Signed32OrMinusZero()) &&
3304 rhs_type.
Is(Type::Signed32OrMinusZero()) &&
3308 lowering->DoMin(node, lowering->machine()->Int32LessThan(),
3316 lowering->DoMin(node, lowering->machine()->Int64LessThan(),
3327 if (lhs_type.
Is(Type::OrderedNumber()) &&
3329 ? Type::OrderedNumber()
3330 : Type::PlainNumber())) {
3331 lowering->DoMin(node,
3332 lowering->machine()->Float64LessThanOrEqual(),
3341 case IrOpcode::kSpeculativeNumberPow: {
3350 case IrOpcode::kNumberAtan2:
3351 case IrOpcode::kNumberPow: {
3357 case IrOpcode::kNumberCeil:
3358 case IrOpcode::kNumberFloor:
3359 case IrOpcode::kNumberRound:
3360 case IrOpcode::kNumberTrunc: {
3365 Type const input_type =
TypeOf(node->InputAt(0));
3372 }
else if (node->opcode() == IrOpcode::kNumberRound) {
3380 case IrOpcode::kSpeculativeBigIntAsIntN:
3381 case IrOpcode::kSpeculativeBigIntAsUintN: {
3382 const bool is_asuintn =
3383 node->opcode() == IrOpcode::kSpeculativeBigIntAsUintN;
3392 is_asuintn ? Type::UnsignedBigInt64() : Type::SignedBigInt64());
3394 if (p.bits() == 0) {
3396 Type::UnsignedBigInt63(),
3398 }
else if (p.bits() == 64) {
3400 is_asuintn ? Type::UnsignedBigInt64()
3401 : Type::SignedBigInt64(),
3405 const uint64_t
mask = (1ULL << p.bits()) - 1ULL;
3418 const uint64_t shift = 64 - p.bits();
3421 graph()->
NewNode(lowering->machine()->Word64Shl(), value,
3424 graph()->
NewNode(lowering->machine()->Word64Sar(), shifted,
3433 case IrOpcode::kNumberAcos:
3434 case IrOpcode::kNumberAcosh:
3435 case IrOpcode::kNumberAsin:
3436 case IrOpcode::kNumberAsinh:
3437 case IrOpcode::kNumberAtan:
3438 case IrOpcode::kNumberAtanh:
3439 case IrOpcode::kNumberCos:
3440 case IrOpcode::kNumberCosh:
3441 case IrOpcode::kNumberExp:
3442 case IrOpcode::kNumberExpm1:
3443 case IrOpcode::kNumberLog:
3444 case IrOpcode::kNumberLog1p:
3445 case IrOpcode::kNumberLog2:
3446 case IrOpcode::kNumberLog10:
3447 case IrOpcode::kNumberCbrt:
3448 case IrOpcode::kNumberSin:
3449 case IrOpcode::kNumberSinh:
3450 case IrOpcode::kNumberTan:
3451 case IrOpcode::kNumberTanh: {
3457 case IrOpcode::kNumberSign: {
3458 if (
InputIs(node, Type::Signed32())) {
3469 case IrOpcode::kNumberSilenceNaN: {
3470 Type const input_type =
TypeOf(node->InputAt(0));
3471 if (input_type.
Is(Type::OrderedNumber())) {
3483 case IrOpcode::kNumberSqrt: {
3489 case IrOpcode::kNumberToBoolean: {
3493 Type const input_type =
TypeOf(node->InputAt(0));
3494 if (input_type.
Is(Type::Integral32OrMinusZeroOrNaN())) {
3499 if (
lower<T>()) lowering->DoIntegral32ToBit(node);
3500 }
else if (input_type.
Is(Type::OrderedNumber())) {
3503 if (
lower<T>()) lowering->DoOrderedNumberToBit(node);
3507 if (
lower<T>()) lowering->DoNumberToBit(node);
3511 case IrOpcode::kNumberToInt32: {
3518 case IrOpcode::kNumberToString: {
3523 case IrOpcode::kNumberToUint32: {
3530 case IrOpcode::kNumberToUint8Clamped: {
3531 Type const input_type =
TypeOf(node->InputAt(0));
3536 }
else if (input_type.
Is(Type::Unsigned32OrMinusZeroOrNaN())) {
3539 if (
lower<T>()) lowering->DoUnsigned32ToUint8Clamped(node);
3540 }
else if (input_type.
Is(Type::Signed32OrMinusZeroOrNaN())) {
3543 if (
lower<T>()) lowering->DoSigned32ToUint8Clamped(node);
3547 if (
lower<T>()) lowering->DoIntegerToUint8Clamped(node);
3551 if (
lower<T>()) lowering->DoNumberToUint8Clamped(node);
3555 case IrOpcode::kIntegral32OrMinusZeroToBigInt: {
3565 case IrOpcode::kReferenceEqual: {
3569 ChangeOp(node, lowering->machine()->Word32Equal());
3571 ChangeOp(node, lowering->machine()->WordEqual());
3576 case IrOpcode::kSameValueNumbersOnly: {
3581 case IrOpcode::kSameValue: {
3587 ChangeOp(node, lowering->simplified()->NumberSameValue());
3595 case IrOpcode::kTypeOf: {
3599 case IrOpcode::kNewConsString: {
3606 case IrOpcode::kSpeculativeBigIntAdd:
3607 case IrOpcode::kSpeculativeBigIntSubtract:
3608 case IrOpcode::kSpeculativeBigIntMultiply: {
3644 case IrOpcode::kSpeculativeBigIntDivide:
3645 case IrOpcode::kSpeculativeBigIntModulus: {
3672 case IrOpcode::kSpeculativeBigIntBitwiseAnd:
3673 case IrOpcode::kSpeculativeBigIntBitwiseOr:
3674 case IrOpcode::kSpeculativeBigIntBitwiseXor: {
3710 case IrOpcode::kSpeculativeBigIntShiftLeft:
3711 case IrOpcode::kSpeculativeBigIntShiftRight: {
3729 case IrOpcode::kSpeculativeBigIntEqual:
3730 case IrOpcode::kSpeculativeBigIntLessThan:
3731 case IrOpcode::kSpeculativeBigIntLessThanOrEqual: {
3760 case IrOpcode::kSpeculativeBigIntNegate: {
3784 case IrOpcode::kStringConcat: {
3796 case IrOpcode::kStringEqual:
3797 case IrOpcode::kStringLessThan:
3798 case IrOpcode::kStringLessThanOrEqual: {
3802 case IrOpcode::kStringCharCodeAt: {
3806 case IrOpcode::kStringCodePointAt: {
3810 case IrOpcode::kStringFromSingleCharCode: {
3815 case IrOpcode::kStringFromSingleCodePoint: {
3820 case IrOpcode::kStringFromCodePointAt: {
3824 case IrOpcode::kStringIndexOf: {
3831 case IrOpcode::kStringLength:
3832 case IrOpcode::kStringWrapperLength: {
3840 case IrOpcode::kTypedArrayLength: {
3845 case IrOpcode::kStringSubstring: {
3853 case IrOpcode::kStringToLowerCaseIntl:
3854 case IrOpcode::kStringToUpperCaseIntl: {
3859 case IrOpcode::kCheckBounds:
3861 case IrOpcode::kCheckHeapObject: {
3873 case IrOpcode::kCheckIf: {
3879 case IrOpcode::kCheckInternalizedString: {
3883 case IrOpcode::kCheckNumber: {
3884 Type const input_type =
TypeOf(node->InputAt(0));
3885 if (input_type.
Is(Type::Number())) {
3893 case IrOpcode::kCheckNumberFitsInt32: {
3894 Type const input_type =
TypeOf(node->InputAt(0));
3895 if (input_type.
Is(Type::Signed32())) {
3903 case IrOpcode::kCheckReceiver: {
3907 case IrOpcode::kCheckReceiverOrNullOrUndefined: {
3908 VisitCheck<T>(node, Type::ReceiverOrNullOrUndefined(), lowering);
3911 case IrOpcode::kCheckSmi: {
3927 case IrOpcode::kCheckString: {
3929 if (
InputIs(node, Type::String())) {
3941 case IrOpcode::kCheckStringOrStringWrapper: {
3943 if (
InputIs(node, Type::StringOrStringWrapper())) {
3955 case IrOpcode::kCheckSymbol: {
3960 case IrOpcode::kAllocate: {
3966 case IrOpcode::kLoadFramePointer: {
3970#if V8_ENABLE_WEBASSEMBLY
3971 case IrOpcode::kLoadStackPointer: {
3975 case IrOpcode::kSetStackPointer: {
3980 case IrOpcode::kLoadMessage: {
3985 case IrOpcode::kStoreMessage: {
3992 case IrOpcode::kLoadFieldByIndex: {
3998 case IrOpcode::kLoadField: {
4002 access.machine_type.representation();
4003 VisitUnop<T>(node, UseInfoForBasePointer(access), representation);
4006 case IrOpcode::kStoreField: {
4011 access.machine_type.representation();
4019 access.base_is_tagged, field_representation, access.offset,
4024 node, 1, TruncatingUseInfoFromRepresentation(field_representation));
4028 if (write_barrier_kind < access.write_barrier_kind) {
4029 access.write_barrier_kind = write_barrier_kind;
4035 case IrOpcode::kLoadElement: {
4042 case IrOpcode::kLoadStackArgument: {
4047 case IrOpcode::kStoreElement: {
4052 access.machine_type.representation();
4060 access.base_is_tagged, element_representation, access.type,
4065 TruncatingUseInfoFromRepresentation(
4066 element_representation));
4070 if (write_barrier_kind < access.write_barrier_kind) {
4071 access.write_barrier_kind = write_barrier_kind;
4077 case IrOpcode::kNumberIsFloat64Hole: {
4082 case IrOpcode::kTransitionAndStoreElement: {
4093 }
else if (value_type.
Is(Type::Number())) {
4098 simplified()->TransitionAndStoreNumberElement(double_map));
4100 }
else if (value_type.
Is(Type::NonNumber())) {
4105 fast_map, value_type));
4115 case IrOpcode::kLoadTypedElement: {
4126 case IrOpcode::kLoadDataViewElement: {
4137 case IrOpcode::kStoreTypedElement: {
4145 TruncatingUseInfoFromRepresentation(rep));
4150 case IrOpcode::kStoreDataViewElement: {
4157 TruncatingUseInfoFromRepresentation(rep));
4163 case IrOpcode::kConvertReceiver: {
4172 if (input_type.
Is(Type::Receiver())) {
4174 }
else if (input_type.
Is(Type::NullOrUndefined())) {
4176 }
else if (!input_type.
Maybe(Type::NullOrUndefined())) {
4177 ChangeOp(node, lowering->simplified()->ConvertReceiver(
4183 case IrOpcode::kPlainPrimitiveToNumber: {
4184 if (
InputIs(node, Type::Boolean())) {
4188 node->op(), node->InputAt(0)));
4190 }
else if (
InputIs(node, Type::String())) {
4197 if (
InputIs(node, Type::NumberOrOddball())) {
4202 node->op(), node->InputAt(0)));
4212 if (
InputIs(node, Type::NumberOrOddball())) {
4217 node->op(), node->InputAt(0)));
4232 case IrOpcode::kSpeculativeToNumber: {
4239 CheckedUseInfoAsWord32FromHint(
4248 node, CheckedUseInfoAsFloat64FromHint(p.
hint(), p.
feedback()),
4255 case IrOpcode::kSpeculativeToBigInt: {
4283 case IrOpcode::kObjectIsArrayBufferView: {
4288 case IrOpcode::kObjectIsBigInt: {
4292 case IrOpcode::kObjectIsCallable: {
4296 case IrOpcode::kObjectIsConstructor: {
4301 case IrOpcode::kObjectIsDetectableCallable: {
4305 case IrOpcode::kObjectIsFiniteNumber: {
4312 true_type(), lowering->jsgraph()->Int32Constant(1)));
4314 }
else if (!input_type.
Maybe(Type::Number())) {
4319 false_type(), lowering->jsgraph()->Int32Constant(0)));
4321 }
else if (input_type.
Is(Type::Number())) {
4325 ChangeOp(node, lowering->simplified()->NumberIsFinite());
4332 case IrOpcode::kNumberIsFinite: {
4337 case IrOpcode::kObjectIsSafeInteger: {
4344 true_type(), lowering->jsgraph()->Int32Constant(1)));
4346 }
else if (!input_type.
Maybe(Type::Number())) {
4351 false_type(), lowering->jsgraph()->Int32Constant(0)));
4353 }
else if (input_type.
Is(Type::Number())) {
4357 ChangeOp(node, lowering->simplified()->NumberIsSafeInteger());
4364 case IrOpcode::kNumberIsSafeInteger: {
4367 case IrOpcode::kObjectIsInteger: {
4374 true_type(), lowering->jsgraph()->Int32Constant(1)));
4376 }
else if (!input_type.
Maybe(Type::Number())) {
4381 false_type(), lowering->jsgraph()->Int32Constant(0)));
4383 }
else if (input_type.
Is(Type::Number())) {
4387 ChangeOp(node, lowering->simplified()->NumberIsInteger());
4394 case IrOpcode::kNumberIsInteger: {
4399 case IrOpcode::kObjectIsMinusZero: {
4401 if (input_type.
Is(Type::MinusZero())) {
4406 true_type(), lowering->jsgraph()->Int32Constant(1)));
4408 }
else if (!input_type.
Maybe(Type::MinusZero())) {
4413 false_type(), lowering->jsgraph()->Int32Constant(0)));
4415 }
else if (input_type.
Is(Type::Number())) {
4426 case IrOpcode::kObjectIsNaN: {
4428 if (input_type.
Is(Type::NaN())) {
4433 true_type(), lowering->jsgraph()->Int32Constant(1)));
4435 }
else if (!input_type.
Maybe(Type::NaN())) {
4440 false_type(), lowering->jsgraph()->Int32Constant(0)));
4442 }
else if (input_type.
Is(Type::Number())) {
4453 case IrOpcode::kNumberIsNaN: {
4458 case IrOpcode::kObjectIsNonCallable: {
4462 case IrOpcode::kObjectIsNumber: {
4466 case IrOpcode::kObjectIsReceiver: {
4470 case IrOpcode::kObjectIsSmi: {
4475 case IrOpcode::kObjectIsString: {
4479 case IrOpcode::kObjectIsSymbol: {
4483 case IrOpcode::kObjectIsUndetectable: {
4487 case IrOpcode::kArgumentsLength:
4488 case IrOpcode::kRestLength: {
4492 case IrOpcode::kNewDoubleElements:
4493 case IrOpcode::kNewSmiOrObjectElements: {
4498 case IrOpcode::kNewArgumentsElements: {
4503 case IrOpcode::kCheckFloat64Hole: {
4504 Type const input_type =
TypeOf(node->InputAt(0));
4522 if (
lower<T>() && input_type.
Is(Type::Number())) {
4527 case IrOpcode::kChangeFloat64HoleToTagged: {
4542 case IrOpcode::kCheckNotTaggedHole: {
4547 case IrOpcode::kCheckClosure: {
4553 case IrOpcode::kConvertTaggedHoleToUndefined: {
4554 if (
InputIs(node, Type::NumberOrHole()) &&
4560 }
else if (
InputIs(node, Type::NumberOrHole()) &&
4566 }
else if (
InputIs(node, Type::NonInternal())) {
4578 case IrOpcode::kCheckEqualsSymbol:
4579 case IrOpcode::kCheckEqualsInternalizedString:
4582 case IrOpcode::kMapGuard:
4585 case IrOpcode::kCheckMaps: {
4591 case IrOpcode::kTransitionElementsKind: {
4596 case IrOpcode::kTransitionElementsKindOrCheckMap: {
4601 case IrOpcode::kCompareMaps:
4605 case IrOpcode::kEnsureWritableFastElements:
4608 case IrOpcode::kMaybeGrowFastElements: {
4618 case IrOpcode::kDateNow:
4621 case IrOpcode::kDoubleArrayMax: {
4625 case IrOpcode::kDoubleArrayMin: {
4629 case IrOpcode::kFrameState:
4631 case IrOpcode::kStateValues:
4633 case IrOpcode::kObjectState:
4635 case IrOpcode::kObjectId:
4638 case IrOpcode::kTypeGuard: {
4660 case IrOpcode::kFinishRegion:
4665 case IrOpcode::kReturn:
4670 case IrOpcode::kFindOrderedHashMapEntry: {
4671 Type const key_type =
TypeOf(node->InputAt(1));
4672 if (key_type.
Is(Type::Signed32OrMinusZero())) {
4678 lowering->simplified()->FindOrderedHashMapEntryForInt32Key());
4687 case IrOpcode::kFindOrderedHashSetEntry:
4692 case IrOpcode::kFastApiCall: {
4699 case IrOpcode::kEnd:
4700 case IrOpcode::kIfSuccess:
4701 case IrOpcode::kIfException:
4702 case IrOpcode::kIfTrue:
4703 case IrOpcode::kIfFalse:
4704 case IrOpcode::kIfValue:
4705 case IrOpcode::kIfDefault:
4706 case IrOpcode::kDeoptimize:
4707 case IrOpcode::kEffectPhi:
4708 case IrOpcode::kTerminate:
4709 case IrOpcode::kCheckpoint:
4710 case IrOpcode::kLoop:
4711 case IrOpcode::kMerge:
4712 case IrOpcode::kThrow:
4713 case IrOpcode::kBeginRegion:
4714 case IrOpcode::kProjection:
4715 case IrOpcode::kOsrValue:
4716 case IrOpcode::kArgumentsElementsState:
4717 case IrOpcode::kArgumentsLengthState:
4718 case IrOpcode::kUnreachable:
4719 case IrOpcode::kRuntimeAbort:
4722#define OPCODE_CASE(name, ...) case IrOpcode::k##name:
4728 case IrOpcode::kJSBitwiseNot:
4729 case IrOpcode::kJSDecrement:
4730 case IrOpcode::kJSIncrement:
4731 case IrOpcode::kJSNegate:
4732 case IrOpcode::kJSToLength:
4733 case IrOpcode::kJSToName:
4734 case IrOpcode::kJSToObject:
4735 case IrOpcode::kJSToString:
4736 case IrOpcode::kJSParseInt:
4737#if V8_ENABLE_WEBASSEMBLY
4738 if (node->opcode() == IrOpcode::kJSWasmCall) {
4739 return VisitJSWasmCall<T>(node, lowering);
4745 case IrOpcode::kDeadValue:
4748 case IrOpcode::kStaticAssert:
4752 case IrOpcode::kAssertType:
4755 case IrOpcode::kVerifyType: {
4767 FATAL(
"%%VerifyType: unsupported type");
4774 case IrOpcode::kCheckTurboshaftTypeOf: {
4782 case IrOpcode::kDebugBreak:
4786 case IrOpcode::kEnterMachineGraph: {
4787 DCHECK_EQ(1, node->op()->ValueInputCount());
4793 Type::Machine(), node->InputAt(0)));
4797 case IrOpcode::kExitMachineGraph: {
4798 DCHECK_EQ(1, node->op()->ValueInputCount());
4801 SetOutput<T>(node, p.output_representation(), p.output_type());
4804 p.output_type(), node->InputAt(0)));
4808 case IrOpcode::kInt32Add:
4809 case IrOpcode::kInt32LessThanOrEqual:
4810 case IrOpcode::kInt32Sub:
4811 case IrOpcode::kUint32LessThan:
4812 case IrOpcode::kUint32LessThanOrEqual:
4813 case IrOpcode::kUint64LessThan:
4814 case IrOpcode::kUint64LessThanOrEqual:
4815 case IrOpcode::kUint32Div:
4816 case IrOpcode::kWord32And:
4817 case IrOpcode::kWord32Equal:
4818 case IrOpcode::kWord32Or:
4819 case IrOpcode::kWord32Shl:
4820 case IrOpcode::kWord32Shr:
4821 for (
int i = 0;
i < node->InputCount(); ++
i) {
4826 case IrOpcode::kInt64Add:
4827 case IrOpcode::kInt64Sub:
4828 case IrOpcode::kUint64Div:
4829 case IrOpcode::kWord64And:
4830 case IrOpcode::kWord64Shl:
4831 case IrOpcode::kWord64Shr:
4832 case IrOpcode::kChangeUint32ToUint64:
4833 for (
int i = 0;
i < node->InputCount(); ++
i) {
4838 case IrOpcode::kLoad:
4839 for (
int i = 0;
i < node->InputCount(); ++
i) {
4845#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
4846 case IrOpcode::kGetContinuationPreservedEmbedderData:
4850 case IrOpcode::kSetContinuationPreservedEmbedderData:
4858 "Representation inference: unsupported opcode %i (%s), node #%i\n.",
4859 node->opcode(), node->op()->mnemonic(), node->id());
4866 if (node->op()->EffectInputCount() == 1) {
4868 if (node->op()->ControlInputCount() == 1) {
4871 DCHECK_EQ(node->op()->ControlInputCount(), 0);
4875 ReplaceEffectControlUses(node, effect, control);
4877 DCHECK_EQ(0, node->op()->EffectInputCount());
4878 DCHECK_EQ(0, node->op()->ControlOutputCount());
4879 DCHECK_EQ(0, node->op()->EffectOutputCount());
4884 TRACE(
"defer replacement #%d:%s with #%d:%s\n", node->id(),
4885 node->op()->mnemonic(), replacement->
id(),
4886 replacement->
op()->mnemonic());
4889 node->NullAllInputs();
4899 DCHECK(!type.IsInvalid());
4970 return &
info_[node->id()];
4988 node_input_use_infos_[use_node->
id()].SetAndCheckInput(use_node, index,
4991 if (info->unvisited()) {
4992 info->AddUse(use_info);
4993 TRACE(
" initial #%i: %s\n", node->id(), info->truncation().description());
4996 TRACE(
" queue #%i?: %s\n", node->id(), info->truncation().description());
4997 if (info->AddUse(use_info)) {
4999 if (!info->queued()) {
5003 TRACE(
" added: %s\n", info->truncation().description());
5005 TRACE(
" inqueue: %s\n", info->truncation().description());
5014 info->set_restriction_type(restriction_type);
5023 .
Is(info->restriction_type()));
5024 USE(node_static_type);
5025 info->set_output(representation);
5033 DCHECK_EQ(info->representation(), representation);
5035 .
Is(info->restriction_type()));
5036 USE(node_static_type);
5045 node->op()->EffectInputCount() > 0);
5054 node->op()->EffectInputCount() > 0);
5062 node->op()->EffectInputCount() > 0);
5073 i < node->InputCount(); ++
i) {
5086 for (
int i = 0;
i < first_effect_index;
i++) {
5090 for (
int i = first_effect_index;
i < node->InputCount();
i++) {
5099 for (
int i = 0;
i < first_effect_index;
i++) {
5108 if (node->op()->ValueOutputCount() > 0 &&
5109 node->op()->EffectOutputCount() > 0 &&
5110 node->opcode() != IrOpcode::kUnreachable &&
TypeOf(node).
IsNone()) {
5111 Node* control = (node->op()->ControlOutputCount() == 0)
5120 for (
Edge edge : node->use_edges()) {
5124 if (edge.from() == unreachable)
continue;
5126 if (edge.from()->opcode() == IrOpcode::kIfException) {
5132 edge.UpdateTo(unreachable);
5147 node_origins_(node_origins),
5148 tick_counter_(tick_counter),
5151 observe_node_manager_(observe_node_manager) {}
5155 if (
v8_flags.verify_simplified_lowering) {
5167 DCHECK(node->opcode() == IrOpcode::kJSToNumber ||
5168 node->opcode() == IrOpcode::kJSToNumberConvertBigInt ||
5169 node->opcode() == IrOpcode::kJSToNumeric);
5182 Node* etrue0 = effect;
5190 Node* efalse0 = effect;
5194 node->
opcode() == IrOpcode::kJSToNumber
5195 ? (node->opcode() == IrOpcode::kJSToNumberConvertBigInt
5199 Node* code = node->
opcode() == IrOpcode::kJSToNumber
5201 : (node->opcode() == IrOpcode::kJSToNumberConvertBigInt
5205 op, code, value, context, frame_state, efalse0, if_false0);
5209 Node* on_exception =
nullptr;
5222 Node* etrue1 = efalse0;
5231 Node* efalse1 = efalse0;
5236 efalse1, if_false1);
5244 vtrue1, vfalse1, if_false0);
5250 vtrue0, vfalse0, control);
5253 for (
Edge edge : node->use_edges()) {
5255 if (edge.from()->opcode() == IrOpcode::kIfSuccess) {
5256 edge.from()->ReplaceUses(control);
5257 edge.from()->Kill();
5259 DCHECK_NE(IrOpcode::kIfException, edge.from()->opcode());
5260 edge.UpdateTo(control);
5263 edge.UpdateTo(effect);
5272 DCHECK(node->opcode() == IrOpcode::kJSToNumber ||
5273 node->opcode() == IrOpcode::kJSToNumberConvertBigInt ||
5274 node->opcode() == IrOpcode::kJSToNumeric);
5287 Node* etrue0 = effect;
5292 Node* efalse0 = effect;
5296 node->
opcode() == IrOpcode::kJSToNumber
5297 ? (node->opcode() == IrOpcode::kJSToNumberConvertBigInt
5301 Node* code = node->
opcode() == IrOpcode::kJSToNumber
5303 : (node->opcode() == IrOpcode::kJSToNumberConvertBigInt
5307 op, code, value, context, frame_state, efalse0, if_false0);
5311 Node* on_exception =
nullptr;
5324 Node* etrue1 = efalse0;
5329 Node* efalse1 = efalse0;
5334 efalse1, if_false1);
5342 vtrue1, vfalse1, if_false0);
5348 vtrue0, vfalse0, control);
5351 for (
Edge edge : node->use_edges()) {
5353 if (edge.from()->opcode() == IrOpcode::kIfSuccess) {
5354 edge.from()->ReplaceUses(control);
5355 edge.from()->Kill();
5357 DCHECK_NE(IrOpcode::kIfException, edge.from()->opcode());
5358 edge.UpdateTo(control);
5361 edge.UpdateTo(effect);
5379 machine()->Float64LessThanOrEqual(),
5393 graph()->NewNode(
machine()->Float64LessThan(), input, zero), minus_one,
5409 jsgraph()->Int32Constant(31));
5419 Node*
const lhs =
m.left().node();
5420 Node*
const rhs =
m.right().node();
5422 if (
m.right().Is(-1)) {
5424 }
else if (
m.right().Is(0)) {
5426 }
else if (
machine()->Int32DivIsSafe() ||
m.right().HasResolvedValue()) {
5481 if_false1 =
graph()->
NewNode(merge_op, if_true2, if_false2);
5482 false1 =
graph()->
NewNode(phi_op, true2, false2, if_false1);
5485 if_false0 =
graph()->
NewNode(merge_op, if_true1, if_false1);
5486 false0 =
graph()->
NewNode(phi_op, true1, false1, if_false0);
5490 return graph()->
NewNode(phi_op, true0, false0, merge0);
5497 Node*
const lhs =
m.left().node();
5498 Node*
const rhs =
m.right().node();
5500 if (
m.right().Is(-1) ||
m.right().Is(0)) {
5502 }
else if (
m.right().HasResolvedValue()) {
5566 if_false1 =
graph()->
NewNode(merge_op, if_true2, if_false2);
5567 false1 =
graph()->
NewNode(phi_op, true2, false2, if_false1);
5570 if_true0 =
graph()->
NewNode(merge_op, if_true1, if_false1);
5571 true0 =
graph()->
NewNode(phi_op, true1, false1, if_true0);
5588 if_false0 =
graph()->
NewNode(merge_op, if_true1, if_false1);
5589 false0 =
graph()->
NewNode(phi_op, true1, false1, if_false0);
5593 return graph()->
NewNode(phi_op, true0, false0, merge0);
5605 graph()->NewNode(
machine()->Int32LessThan(), input, zero), minus_one,
5615 Node*
const lhs =
m.left().node();
5616 Node*
const rhs =
m.right().node();
5618 if (
m.right().Is(0)) {
5620 }
else if (
machine()->Uint32DivIsSafe() ||
m.right().HasResolvedValue()) {
5635 Node*
const lhs =
m.left().node();
5636 Node*
const rhs =
m.right().node();
5638 if (
m.right().Is(0)) {
5640 }
else if (
m.right().HasResolvedValue()) {
5686 if_false0 =
graph()->
NewNode(merge_op, if_true1, if_false1);
5687 false0 =
graph()->
NewNode(phi_op, true1, false1, if_false0);
5691 return graph()->
NewNode(phi_op, true0, false0, merge0);
5701 node->AppendInput(
graph()->
zone(), lhs);
5721 node->ReplaceInput(0,
graph()->NewNode(op, input, zero));
5722 node->AppendInput(
graph()->
zone(), zero);
5730 jsgraph()->Float64Constant(0.0)));
5750 0,
graph()->NewNode(
machine()->Float64LessThan(), min, input));
5755 graph()->NewNode(
machine()->Float64LessThan(), input, max), input,
5757 node->AppendInput(
graph()->
zone(), min);
5767 0,
graph()->NewNode(
5769 graph()->NewNode(
machine()->Float64LessThan(), min, input),
5772 graph()->NewNode(
machine()->Float64LessThan(), input, max),
5784 0,
graph()->NewNode(
machine()->Int32LessThanOrEqual(), input, max));
5788 graph()->NewNode(
machine()->Int32LessThan(), input, min),
5790 node->AppendInput(
graph()->
zone(), max);
5799 0,
graph()->NewNode(
machine()->Uint32LessThanOrEqual(), input, max));
5800 node->AppendInput(
graph()->
zone(), input);
5801 node->AppendInput(
graph()->
zone(), max);
#define Assert(condition)
Int64Representation GetInt64Representation() const
const CTypeInfo & ArgumentInfo(unsigned int index) const
unsigned int ArgumentCount() const
constexpr Type GetType() const
Flags without(flag_type flag) const
static V8_EXPORT_PRIVATE Callable CallableFor(Isolate *isolate, Builtin builtin)
int GetStackParameterCount() const
Handle< Code > code() const
CallInterfaceDescriptor descriptor() const
static constexpr int kMapOffset
RootsTable & roots_table()
constexpr MachineSemantic semantic() const
static constexpr MachineType Float64()
static constexpr MachineType SignedBigInt64()
constexpr MachineRepresentation representation() const
static constexpr MachineType Int32()
static constexpr MachineType AnyTagged()
static constexpr MachineType UnsignedBigInt64()
static constexpr MachineType Float32()
static constexpr MachineType Int64()
static constexpr MachineType None()
static constexpr MachineRepresentation PointerRepresentation()
bool IsRootHandle(IndirectHandle< T > handle, RootIndex *index) const
static constexpr bool IsImmortalImmovable(RootIndex root_index)
static constexpr Tagged< Smi > FromInt(int value)
void TickAndMaybeEnterSafepoint()
const T * cbegin() const V8_NOEXCEPT
const_reverse_iterator crbegin() const V8_NOEXCEPT
const T * cend() const V8_NOEXCEPT
const_reverse_iterator crend() const V8_NOEXCEPT
void push_back(const T &value)
static FieldAccess ForHeapNumberValue()
const FeedbackSource & feedback() const
BigIntOperationHint hint() const
int64_t AsInt64(bool *lossless) const
MachineType GetInputType(size_t index) const
size_t ParameterCount() const
CheckBoundsFlags flags() const
const CheckParameters & check_parameters() const
CheckFloat64HoleMode mode() const
FeedbackSource const & feedback() const
const Operator * Phi(MachineRepresentation representation, int value_input_count)
const Operator * DeadValue(MachineRepresentation rep)
const Operator * Merge(int control_input_count)
static constexpr int ArityForArgc(int c_arg_count, int slow_arg_count)
FastApiCallFunction c_function() const
CallDescriptor * descriptor() const
FeedbackSource const & feedback() const
static constexpr int kFrameStateLocalsInput
static constexpr int kFrameStateInputCount
static constexpr int kFrameStateContextInput
static constexpr int kFrameStateParametersInput
static constexpr int kFrameStateFunctionInput
static constexpr int kFrameStateOuterStateInput
static constexpr int kFrameStateStackInput
static bool IsMachineOpcode(Value value)
static bool IsMachineConstantOpcode(Value value)
SimplifiedOperatorBuilder * simplified() const
Isolate * isolate() const
void PrintPhase(const char *phase_name)
static CallDescriptor * GetStubCallDescriptor(Zone *zone, const CallInterfaceDescriptor &descriptor, int stack_parameter_count, CallDescriptor::Flags flags, Operator::Properties properties=Operator::kNoProperties, StubCallMode stub_mode=StubCallMode::kCallCodeObject)
Node * Int64Constant(int64_t value)
Node * Float64Constant(double value)
Node * Uint64Constant(uint64_t value)
CommonOperatorBuilder * common() const
MachineOperatorBuilder * machine() const
Node * Uint32Constant(uint32_t value)
Node * Int32Constant(int32_t value)
const Operator * Word32Equal()
const Operator * Word32And()
static int FirstEffectIndex(Node *node)
static void ChangeOp(Node *node, const Operator *new_op)
static void ReplaceEffectInput(Node *node, Node *effect, int index=0)
static Type GetType(const Node *node)
static bool IsControlEdge(Edge edge)
static void ReplaceControlInput(Node *node, Node *control, int index=0)
static bool IsTyped(const Node *node)
static Type GetTypeOrAny(const Node *node)
static Node * GetEffectInput(Node *node, int index=0)
static int PastValueIndex(Node *node)
static bool IsValueEdge(Edge edge)
static bool IsContextEdge(Edge edge)
static Node * GetValueInput(Node *node, int index)
static bool IsEffectEdge(Edge edge)
static void SetType(Node *node, Type type)
static int FirstControlIndex(Node *node)
static bool IsExceptionalCall(Node *node, Node **out_exception=nullptr)
static Node * GetControlInput(Node *node, int index=0)
static int PastContextIndex(Node *node)
static Node * FindSuccessfulControlProjection(Node *node)
constexpr IrOpcode::Value opcode() const
const Operator * op() const
void ReplaceInput(int index, Node *new_to)
Node * InputAt(int index) const
void ReplaceUses(Node *replace_to)
void InsertInput(Zone *zone, int index, Node *new_to)
NumberOperationHint hint() const
const FeedbackSource & feedback() const
void OnNodeChanged(const char *reducer_name, const Node *old_node, const Node *new_node)
Type TypeTypeGuard(const Operator *sigma_op, Type input)
Type CheckFloat64Hole(Type type)
Type CheckNumber(Type type)
Type Merge(Type left, Type right)
Type WeakenRange(Type current_range, Type previous_range)
Type ConvertTaggedHoleToUndefined(Type type)
Type CheckBounds(Type index, Type length)
Type CheckNumberFitsInt32(Type type)
static int GetFrameStateInputCount(const Operator *op)
int ValueInputCount() const
bool HasProperty(Property property) const
constexpr Opcode opcode() const
const Operator * Int32OperatorFor(IrOpcode::Value opcode)
const Operator * Int32OverflowOperatorFor(IrOpcode::Value opcode)
const Operator * AdditiveSafeIntegerOverflowOperatorFor(IrOpcode::Value opcode)
const Operator * Uint32OperatorFor(IrOpcode::Value opcode)
const Operator * Uint32OverflowOperatorFor(IrOpcode::Value opcode)
Node * GetRepresentationFor(Node *node, MachineRepresentation output_rep, Type output_type, Node *use_node, UseInfo use_info)
const Operator * TaggedSignedOperatorFor(IrOpcode::Value opcode)
const Operator * Int64OverflowOperatorFor(IrOpcode::Value opcode)
const Operator * BigIntOperatorFor(IrOpcode::Value opcode)
const Operator * Int64OperatorFor(IrOpcode::Value opcode)
const Operator * Float64OperatorFor(IrOpcode::Value opcode)
Type feedback_type() const
bool AddUse(UseInfo info)
void set_feedback_type(Type type)
Truncation truncation() const
void set_output(MachineRepresentation output)
void set_restriction_type(Type type)
MachineRepresentation representation_
MachineRepresentation representation() const
Type restriction_type() const
static void ChangeOp(Node *node, const Operator *new_op)
void VisitInt64Binop(Node *node)
NodeInfo * GetInfo(Node *node)
void ChangeUnaryToPureBinaryOp(Node *node, const Operator *new_op, int new_input_index, Node *new_input)
ZoneVector< NodeInfo > info_
bool InputIs(Node *node, Type type)
CommonOperatorBuilder * common() const
const Operator * AdditiveSafeIntegerOverflowOp(Node *node)
void VisitStateValues(Node *node)
void VisitSpeculativeNumberModulus(Node *node, Truncation truncation, SimplifiedLowering *lowering)
void ReplaceWithPureNode(Node *node, Node *pure_node)
void ChangeToDeadValue(Node *node, Node *effect, Node *control)
bool CanSpeculateAdditiveSafeInteger(Node *node)
void VisitWord32TruncatingBinop(Node *node)
void ChangeToInt32OverflowOp(Node *node)
void PrintNodeFeedbackType(Node *n)
void ConvertInput(Node *node, int index, UseInfo use, Type input_type=Type::Invalid())
bool BothInputsAreUnsigned32(Node *node)
bool IsNodeRepresentationTagged(Node *node)
void VisitSpeculativeInt32Binop(Node *node)
bool BothInputsAre(Node *node, Type type)
void VisitSpeculativeSmallIntegerAdditiveOp(Node *node, Truncation truncation, SimplifiedLowering *lowering)
void MarkAsPossibleRevisit(Node *node, Node *input)
RepresentationChanger * changer_
void VisitFloat64Binop(Node *node)
ZoneMap< Node *, ZoneVector< Node * > > might_need_revisit_
NodeVector traversal_nodes_
Type GetUpperBound(Node *node)
void VisitInputs(Node *node)
void VisitSelect(Node *node, Truncation truncation, SimplifiedLowering *lowering)
SimplifiedOperatorBuilder * simplified() const
void VisitCall(Node *node, SimplifiedLowering *lowering)
UseInfo UseInfoForFastApiCallArgument(CTypeInfo type, CFunctionInfo::Int64Representation repr, FeedbackSource const &feedback)
const Operator * Int64Op(Node *node)
void InsertUnreachableIfNecessary(Node *node)
void VisitLeaf(Node *node, MachineRepresentation output)
bool InputCannotBe(Node *node, Type type)
void ChangeOp(Node *node, const Operator *new_op)
const Operator * Uint32OverflowOp(Node *node)
void VisitReturn(Node *node)
static MachineType DeoptMachineTypeOf(MachineRepresentation rep, Type type)
void DeferReplacement(Node *node, Node *replacement)
NodeOriginTable * node_origins_
TickCounter *const tick_counter_
static constexpr bool propagate()
static MachineSemantic DeoptValueSemanticOf(Type type)
const Operator * Int32Op(Node *node)
void DisconnectFromEffectAndControl(Node *node)
bool TryOptimizeBigInt64Shift(Node *node, const Truncation &truncation, SimplifiedLowering *lowering)
bool BothInputsAreSigned32(Node *node)
WriteBarrierKind WriteBarrierKindFor(BaseTaggedness base_taggedness, MachineRepresentation field_representation, int field_offset, Type field_type, MachineRepresentation value_representation, Node *value)
void VisitBinop(Node *node, UseInfo input_use, MachineRepresentation output, Type restriction_type=Type::Any())
void VisitNode(Node *node, Truncation truncation, SimplifiedLowering *lowering)
bool UpdateFeedbackType(Node *node)
void ChangeToUint32OverflowOp(Node *node)
Node * InsertTypeOverrideForVerifier(const Type &type, Node *node)
static constexpr bool retype()
WriteBarrierKind WriteBarrierKindFor(BaseTaggedness base_taggedness, MachineRepresentation field_representation, Type field_type, MachineRepresentation value_representation, Node *value)
ObserveNodeManager *const observe_node_manager_
const Operator * Int32OverflowOp(Node *node)
void MaskShiftOperand(Node *node, Type rhs_type)
const Operator * BigIntOp(Node *node)
void ChangeToPureOp(Node *node, const Operator *new_op)
void VisitForCheckedInt32Mul(Node *node, Truncation truncation, Type input0_type, Type input1_type, UseInfo input_use)
const Operator * Uint32Op(Node *node)
void PropagateTruncation(Node *node)
TypeCache const * type_cache_
SimplifiedLoweringVerifier * verifier_
void VisitFastApiCall(Node *node, SimplifiedLowering *lowering)
void RunVerifyPhase(OptimizedCompilationInfo *compilation_info)
RepresentationSelector(JSGraph *jsgraph, JSHeapBroker *broker, Zone *zone, RepresentationChanger *changer, SourcePositionTable *source_positions, NodeOriginTable *node_origins, TickCounter *tick_counter, Linkage *linkage, ObserveNodeManager *observe_node_manager, SimplifiedLoweringVerifier *verifier)
const Operator * Int64OverflowOp(Node *node)
void VisitUnop(Node *node, UseInfo input_use, MachineRepresentation output, Type restriction_type=Type::Any())
void VisitSpeculativeAdditiveOp(Node *node, Truncation truncation, SimplifiedLowering *lowering)
void ProcessRemainingInputs(Node *node, int index)
void Run(SimplifiedLowering *lowering)
void ResetNodeInfoState()
void VisitCheckBounds(Node *node, SimplifiedLowering *lowering)
SourcePositionTable * source_positions_
Type TypeSelect(Node *node)
void VisitCheck(Node *node, Type type, SimplifiedLowering *lowering)
void SetOutput(Node *node, MachineRepresentation representation, Type restriction_type=Type::Any())
void PushNodeToRevisitIfVisited(Node *node)
Type Weaken(Node *node, Type previous_type, Type current_type)
ZoneQueue< Node * > revisit_queue_
static constexpr int kInitialArgumentsCount
void VisitObjectState(Node *node)
void NotifyNodeReplaced(Node *node, Node *replacement)
void VisitPhi(Node *node, Truncation truncation, SimplifiedLowering *lowering)
bool verification_enabled() const
MachineRepresentation GetOutputInfoForPhi(Type type, Truncation use)
void VisitNoop(Node *node, Truncation truncation)
void ProcessInput(Node *node, int index, UseInfo use)
Type FeedbackTypeOf(Node *node)
void VisitUnused(Node *node)
Node * InsertSemanticsHintForVerifier(const Operator *semantics, Node *node)
void VisitFrameState(FrameState node)
void RunLowerPhase(SimplifiedLowering *lowering)
void VisitBinop(Node *node, UseInfo left_use, UseInfo right_use, MachineRepresentation output, Type restriction_type=Type::Any())
bool RetypeNode(Node *node)
void EnqueueInput(Node *use_node, int index, UseInfo use_info=UseInfo::None())
bool OneInputCannotBe(Node *node, Type type)
const Operator * Float64Op(Node *node)
static constexpr bool lower()
void VisitObjectIs(Node *node, Type type, SimplifiedLowering *lowering)
MachineRepresentation representation() const
const ZoneUnorderedMap< Node *, ZoneVector< Node * > > & machine_uses_of_constants() const
void RecordHint(Node *node)
void RecordMachineUsesOfConstant(Node *constant, Node::Uses uses)
const ZoneVector< Node * > & inserted_hints() const
void VisitNode(Node *node, OperationTyper &op_typer)
Operator const * ToNumberConvertBigIntOperator()
SetOncePointer< Node > to_number_convert_big_int_code_
void DoNumberToUint8Clamped(Node *node)
Node * Uint32Div(Node *const node)
void DoIntegerToUint8Clamped(Node *node)
Node * Int32Sign(Node *const node)
Node * Int32Div(Node *const node)
void DoUnsigned32ToUint8Clamped(Node *node)
SetOncePointer< Operator const > to_number_operator_
CommonOperatorBuilder * common()
void DoIntegral32ToBit(Node *node)
TickCounter *const tick_counter_
SetOncePointer< Node > to_numeric_code_
SetOncePointer< Operator const > to_number_convert_big_int_operator_
void DoMin(Node *node, Operator const *op, MachineRepresentation rep)
Operator const * ToNumberOperator()
MachineOperatorBuilder * machine()
SourcePositionTable * source_positions_
Node * Float64Round(Node *const node)
Operator const * ToNumericOperator()
Node * Int32Abs(Node *const node)
void DoMax(Node *node, Operator const *op, MachineRepresentation rep)
ObserveNodeManager *const observe_node_manager_
Node * Float64Sign(Node *const node)
void DoSigned32ToUint8Clamped(Node *node)
void DoJSToNumberOrNumericTruncatesToWord32(Node *node, RepresentationSelector *selector)
void DoJSToNumberOrNumericTruncatesToFloat64(Node *node, RepresentationSelector *selector)
NodeOriginTable * node_origins_
void DoNumberToBit(Node *node)
void ChangeOp(Node *node, const Operator *new_op)
SetOncePointer< Node > to_number_code_
SimplifiedOperatorBuilder * simplified()
Node * Uint32Mod(Node *const node)
SimplifiedLowering(JSGraph *jsgraph, JSHeapBroker *broker, Zone *zone, SourcePositionTable *source_position, NodeOriginTable *node_origins, TickCounter *tick_counter, Linkage *linkage, OptimizedCompilationInfo *info, ObserveNodeManager *observe_node_manager=nullptr)
void DoOrderedNumberToBit(Node *node)
SetOncePointer< Operator const > to_numeric_operator_
Node * Int32Mod(Node *const node)
Node * ToNumberConvertBigIntCode()
const Operator * StoreField(FieldAccess const &, bool maybe_initializing_or_transitioning=true)
const Operator * StoreElement(ElementAccess const &)
SourcePosition GetSourcePosition(Node *node) const
Node * NewNode(const Operator *op, int input_count, Node *const *inputs, bool incomplete=false)
static Truncation Any(IdentifyZeros identify_zeros=kDistinguishZeros)
bool TruncatesOddballAndBigIntToNumber() const
IdentifyZeros identify_zeros() const
bool IsUsedAsBool() const
bool IdentifiesZeroAndMinusZero() const
static Truncation Generalize(Truncation t1, Truncation t2)
bool IsUsedAsWord64() const
bool IsUsedAsWord32() const
Type const kSafeIntegerOrMinusZero
Type const kAdditiveSafeInteger
Type const kIntegerOrMinusZeroOrNaN
Type const kAdditiveSafeIntegerOrMinusZero
Type const kZeroToThirtyOne
Type const kUint8OrMinusZeroOrNaN
static TypeCache const * Get()
Type const kPositiveSafeInteger
Type const kPositiveIntegerOrNaN
static Type Union(Type type1, Type type2, Zone *zone)
bool CanBeAsserted() const
bool Maybe(Type that) const
bool IsHeapConstant() const
const HeapConstantType * AsHeapConstant() const
static Type Constant(JSHeapBroker *broker, Handle< i::Object > value, Zone *zone)
static Type SignedSmall()
static Type Intersect(Type type1, Type type2, Zone *zone)
static UseInfo CheckedSignedSmallAsTaggedSigned(const FeedbackSource &feedback, IdentifyZeros identify_zeros=kDistinguishZeros)
static UseInfo CheckedSignedSmallAsWord32(IdentifyZeros identify_zeros, const FeedbackSource &feedback)
Truncation truncation() const
static UseInfo TruncatingFloat64(IdentifyZeros identify_zeros=kDistinguishZeros)
static UseInfo CheckedBigIntAsTaggedPointer(const FeedbackSource &feedback)
static UseInfo CheckedNumberOrOddballAsFloat64(IdentifyZeros identify_zeros, const FeedbackSource &feedback)
static UseInfo CheckedNumberAsFloat64(IdentifyZeros identify_zeros, const FeedbackSource &feedback)
static UseInfo Float16RawBits()
static UseInfo AnyTruncatingToBool()
static UseInfo CheckedSafeIntAsWord64(const FeedbackSource &feedback)
static UseInfo CheckedSigned32AsWord32(IdentifyZeros identify_zeros, const FeedbackSource &feedback)
static UseInfo TruncatingWord64()
static UseInfo TaggedSigned()
static UseInfo Word64(IdentifyZeros identify_zeros=kDistinguishZeros)
static UseInfo CheckedNumberAsWord32(const FeedbackSource &feedback)
static UseInfo AnyTagged()
static UseInfo TruncatingWord32()
static UseInfo CheckedBigIntTruncatingWord64(const FeedbackSource &feedback)
static UseInfo CheckedBigInt64AsWord64(const FeedbackSource &feedback)
static UseInfo CheckedSigned64AsWord64(IdentifyZeros identify_zeros, const FeedbackSource &feedback)
static UseInfo CheckedNumberOrBooleanAsFloat64(IdentifyZeros identify_zeros, const FeedbackSource &feedback)
static UseInfo CheckedHeapObjectAsTaggedPointer(const FeedbackSource &feedback)
MachineRepresentation representation() const
static UseInfo CheckedNumberOrOddballAsWord32(const FeedbackSource &feedback)
static UseInfo CheckedSafeIntTruncatingWord32(const FeedbackSource &feedback)
static UseInfo CheckedTaggedAsArrayIndex(const FeedbackSource &feedback)
#define COMPRESS_POINTERS_BOOL
JSHeapBroker *const broker_
NodeOriginTable * origins
SourcePositionTable * source_positions
#define DECLARE_CASE(x,...)
ZoneVector< RpoNumber > & result
ZoneStack< RpoNumber > & stack
Linkage const *const linkage_
V8_INLINE Dest bit_cast(Source const &source)
V8_INLINE const Operation & Get(const Graph &graph, OpIndex index)
UntaggedUnion< Word32, Word64 > Word
const char * kSimplifiedLoweringReducerName
uint32_t ObjectIdOf(Operator const *op)
const BranchParameters & BranchParametersOf(const Operator *const op)
NumberOperationParameters const & NumberOperationParametersOf(Operator const *op)
FastApiCallParameters const & FastApiCallParametersOf(const Operator *op)
CheckParameters const & CheckParametersOf(Operator const *op)
@ kConvertStringAndMinusZero
CheckMapsParameters const & CheckMapsParametersOf(Operator const *op)
const AssertParameters & AssertParametersOf(const Operator *const op)
CheckFloat64HoleParameters const & CheckFloat64HoleParametersOf(Operator const *op)
CallDescriptor const * CallDescriptorOf(const Operator *const op)
int ParameterIndexOf(const Operator *const op)
NumberOperationHint NumberOperationHintOf(const Operator *op)
const FieldAccess & FieldAccessOf(const Operator *op)
const ElementAccess & ElementAccessOf(const Operator *op)
CheckBoundsParameters const & CheckBoundsParametersOf(Operator const *op)
MapRef FastMapParameterOf(const Operator *op)
SelectParameters const & SelectParametersOf(const Operator *const op)
LoadRepresentation LoadRepresentationOf(Operator const *op)
HeapConstantNoHole(BUILTIN_CODE(isolate(), AllocateInOldGeneration))) DEFINE_GETTER(ArrayConstructorStubConstant
ExternalArrayType ExternalArrayTypeOf(const Operator *op)
T const & OpParameter(const Operator *op)
const ExitMachineGraphParameters & ExitMachineGraphParametersOf(const Operator *op)
BigIntOperationParameters const & BigIntOperationParametersOf(Operator const *op)
SparseInputMask SparseInputMaskOf(Operator const *op)
SpeculativeBigIntAsNParameters const & SpeculativeBigIntAsNParametersOf(Operator const *op)
MachineRepresentation PhiRepresentationOf(const Operator *const op)
BigIntOperationHint BigIntOperationHintOf(const Operator *op)
MapRef DoubleMapParameterOf(const Operator *op)
bool IsNone(Tagged< FieldType > obj)
bool Is(IndirectHandle< U > value)
bool DoubleToSmiInteger(double value, int *smi_int_value)
bool IsSmiDouble(double value)
constexpr bool IsAnyTagged(MachineRepresentation rep)
constexpr bool CanBeTaggedPointer(MachineRepresentation rep)
const char * MachineReprToString(MachineRepresentation rep)
V8_EXPORT_PRIVATE FlagValues v8_flags
other heap size generate builtins concurrently on separate threads in mksnapshot track concurrent recompilation artificial compilation delay in ms max number of threads that concurrent Turbofan can use(0 for unbounded)") DEFINE_BOOL( stress_concurrent_inlining
constexpr bool SmiValuesAre32Bits()
@ kExternalUint8ClampedArray
@ kExternalBigUint64Array
#define JS_CONTEXT_OP_LIST(V)
#define JS_OTHER_OP_LIST(V)
#define SIMPLIFIED_NUMBER_UNOP_LIST(V)
#define JS_OBJECT_OP_LIST(V)
#define SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(V)
#define JS_SIMPLE_BINOP_LIST(V)
#define SIMPLIFIED_SPECULATIVE_BIGINT_BINOP_LIST(V)
#define SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(V)
#define SIMPLIFIED_NUMBER_BINOP_LIST(V)
OptimizedCompilationInfo * info_
SimplifiedLoweringVerifier * verifier_
#define OPCODE_CASE(name,...)
#define DCHECK_LE(v1, v2)
#define DCHECK_NOT_NULL(val)
#define DCHECK_IMPLIES(v1, v2)
#define DCHECK_NE(v1, v2)
#define DCHECK_GE(v1, v2)
#define CHECK_EQ(lhs, rhs)
#define DCHECK(condition)
#define DCHECK_LT(v1, v2)
#define DCHECK_EQ(v1, v2)
#define DCHECK_GT(v1, v2)
const CFunctionInfo * signature
#define END_ALLOW_USE_DEPRECATED()
#define V8_UNLIKELY(condition)
#define START_ALLOW_USE_DEPRECATED()