| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler/simplified-lowering.h" | 5 #include "src/compiler/simplified-lowering.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "src/address-map.h" | 9 #include "src/address-map.h" |
| 10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 350 return nullptr; | 350 return nullptr; |
| 351 } | 351 } |
| 352 | 352 |
| 353 bool UpdateFeedbackType(Node* node) { | 353 bool UpdateFeedbackType(Node* node) { |
| 354 if (node->op()->ValueOutputCount() == 0) return false; | 354 if (node->op()->ValueOutputCount() == 0) return false; |
| 355 | 355 |
| 356 NodeInfo* info = GetInfo(node); | 356 NodeInfo* info = GetInfo(node); |
| 357 Type* type = info->feedback_type(); | 357 Type* type = info->feedback_type(); |
| 358 Type* new_type = type; | 358 Type* new_type = type; |
| 359 | 359 |
| 360 // For any non-phi node just wait until we get all inputs typed. We only |
| 361 // allow untyped inputs for phi nodes because phis are the only places |
| 362 // where cycles need to be broken. |
| 363 if (node->opcode() != IrOpcode::kPhi) { |
| 364 for (int i = 0; i < node->op()->ValueInputCount(); i++) { |
| 365 if (GetInfo(node->InputAt(i))->feedback_type() == nullptr) { |
| 366 return false; |
| 367 } |
| 368 } |
| 369 } |
| 370 |
| 360 switch (node->opcode()) { | 371 switch (node->opcode()) { |
| 361 case IrOpcode::kSpeculativeNumberAdd: { | 372 case IrOpcode::kSpeculativeNumberAdd: { |
| 362 Type* lhs = FeedbackTypeOf(node->InputAt(0)); | |
| 363 Type* rhs = FeedbackTypeOf(node->InputAt(1)); | |
| 364 if (lhs->Is(Type::None()) || rhs->Is(Type::None())) return false; | |
| 365 // TODO(jarin) The ToNumber conversion is too conservative here, | 373 // TODO(jarin) The ToNumber conversion is too conservative here, |
| 366 // e.g. it will treat true as 1 even though the number check will | 374 // e.g. it will treat true as 1 even though the number check will |
| 367 // fail on a boolean. OperationTyper should have a function that | 375 // fail on a boolean. OperationTyper should have a function that |
| 368 // computes a more precise type. | 376 // computes a more precise type. |
| 369 lhs = op_typer_.ToNumber(lhs); | 377 Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0))); |
| 370 rhs = op_typer_.ToNumber(rhs); | 378 Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1))); |
| 371 Type* static_type = op_typer_.NumericAdd(lhs, rhs); | 379 Type* static_type = op_typer_.NumericAdd(lhs, rhs); |
| 372 if (info->type_check() == TypeCheckKind::kNone) { | 380 if (info->type_check() == TypeCheckKind::kNone) { |
| 373 new_type = static_type; | 381 new_type = static_type; |
| 374 } else { | 382 } else { |
| 375 Type* feedback_type = TypeOfSpeculativeOp(info->type_check()); | 383 Type* feedback_type = TypeOfSpeculativeOp(info->type_check()); |
| 376 new_type = Type::Intersect(static_type, feedback_type, graph_zone()); | 384 new_type = Type::Intersect(static_type, feedback_type, graph_zone()); |
| 377 } | 385 } |
| 378 break; | 386 break; |
| 379 } | 387 } |
| 380 | 388 |
| 381 case IrOpcode::kSpeculativeNumberSubtract: { | 389 case IrOpcode::kSpeculativeNumberSubtract: { |
| 382 Type* lhs = FeedbackTypeOf(node->InputAt(0)); | |
| 383 Type* rhs = FeedbackTypeOf(node->InputAt(1)); | |
| 384 if (lhs->Is(Type::None()) || rhs->Is(Type::None())) return false; | |
| 385 // TODO(jarin) The ToNumber conversion is too conservative here, | 390 // TODO(jarin) The ToNumber conversion is too conservative here, |
| 386 // e.g. it will treat true as 1 even though the number check will | 391 // e.g. it will treat true as 1 even though the number check will |
| 387 // fail on a boolean. OperationTyper should have a function that | 392 // fail on a boolean. OperationTyper should have a function that |
| 388 // computes a more precise type. | 393 // computes a more precise type. |
| 389 lhs = op_typer_.ToNumber(lhs); | 394 Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0))); |
| 390 rhs = op_typer_.ToNumber(rhs); | 395 Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1))); |
| 391 Type* static_type = op_typer_.NumericSubtract(lhs, rhs); | 396 Type* static_type = op_typer_.NumericSubtract(lhs, rhs); |
| 392 if (info->type_check() == TypeCheckKind::kNone) { | 397 if (info->type_check() == TypeCheckKind::kNone) { |
| 393 new_type = static_type; | 398 new_type = static_type; |
| 394 } else { | 399 } else { |
| 395 Type* feedback_type = TypeOfSpeculativeOp(info->type_check()); | 400 Type* feedback_type = TypeOfSpeculativeOp(info->type_check()); |
| 396 new_type = Type::Intersect(static_type, feedback_type, graph_zone()); | 401 new_type = Type::Intersect(static_type, feedback_type, graph_zone()); |
| 397 } | 402 } |
| 398 break; | 403 break; |
| 399 } | 404 } |
| 400 | 405 |
| 401 case IrOpcode::kSpeculativeNumberMultiply: { | 406 case IrOpcode::kSpeculativeNumberMultiply: { |
| 402 Type* lhs = FeedbackTypeOf(node->InputAt(0)); | |
| 403 Type* rhs = FeedbackTypeOf(node->InputAt(1)); | |
| 404 if (lhs->Is(Type::None()) || rhs->Is(Type::None())) return false; | |
| 405 // TODO(jarin) The ToNumber conversion is too conservative here, | 407 // TODO(jarin) The ToNumber conversion is too conservative here, |
| 406 // e.g. it will treat true as 1 even though the number check will | 408 // e.g. it will treat true as 1 even though the number check will |
| 407 // fail on a boolean. OperationTyper should have a function that | 409 // fail on a boolean. OperationTyper should have a function that |
| 408 // computes a more precise type. | 410 // computes a more precise type. |
| 409 lhs = op_typer_.ToNumber(lhs); | 411 Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0))); |
| 410 rhs = op_typer_.ToNumber(rhs); | 412 Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1))); |
| 411 Type* static_type = op_typer_.NumericMultiply(lhs, rhs); | 413 Type* static_type = op_typer_.NumericMultiply(lhs, rhs); |
| 412 if (info->type_check() == TypeCheckKind::kNone) { | 414 if (info->type_check() == TypeCheckKind::kNone) { |
| 413 new_type = static_type; | 415 new_type = static_type; |
| 414 } else { | 416 } else { |
| 415 Type* feedback_type = TypeOfSpeculativeOp(info->type_check()); | 417 Type* feedback_type = TypeOfSpeculativeOp(info->type_check()); |
| 416 new_type = Type::Intersect(static_type, feedback_type, graph_zone()); | 418 new_type = Type::Intersect(static_type, feedback_type, graph_zone()); |
| 417 } | 419 } |
| 418 break; | 420 break; |
| 419 } | 421 } |
| 420 | 422 |
| 421 case IrOpcode::kSpeculativeNumberDivide: { | 423 case IrOpcode::kSpeculativeNumberDivide: { |
| 422 Type* lhs = FeedbackTypeOf(node->InputAt(0)); | |
| 423 Type* rhs = FeedbackTypeOf(node->InputAt(1)); | |
| 424 if (lhs->Is(Type::None()) || rhs->Is(Type::None())) return false; | |
| 425 // TODO(jarin) The ToNumber conversion is too conservative here, | 424 // TODO(jarin) The ToNumber conversion is too conservative here, |
| 426 // e.g. it will treat true as 1 even though the number check will | 425 // e.g. it will treat true as 1 even though the number check will |
| 427 // fail on a boolean. OperationTyper should have a function that | 426 // fail on a boolean. OperationTyper should have a function that |
| 428 // computes a more precise type. | 427 // computes a more precise type. |
| 429 lhs = op_typer_.ToNumber(lhs); | 428 Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0))); |
| 430 rhs = op_typer_.ToNumber(rhs); | 429 Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1))); |
| 431 Type* static_type = op_typer_.NumericDivide(lhs, rhs); | 430 Type* static_type = op_typer_.NumericDivide(lhs, rhs); |
| 432 if (info->type_check() == TypeCheckKind::kNone) { | 431 if (info->type_check() == TypeCheckKind::kNone) { |
| 433 new_type = static_type; | 432 new_type = static_type; |
| 434 } else { | 433 } else { |
| 435 Type* feedback_type = TypeOfSpeculativeOp(info->type_check()); | 434 Type* feedback_type = TypeOfSpeculativeOp(info->type_check()); |
| 436 new_type = Type::Intersect(static_type, feedback_type, graph_zone()); | 435 new_type = Type::Intersect(static_type, feedback_type, graph_zone()); |
| 437 } | 436 } |
| 438 break; | 437 break; |
| 439 } | 438 } |
| 440 | 439 |
| 441 case IrOpcode::kSpeculativeNumberModulus: { | 440 case IrOpcode::kSpeculativeNumberModulus: { |
| 442 Type* lhs = FeedbackTypeOf(node->InputAt(0)); | |
| 443 Type* rhs = FeedbackTypeOf(node->InputAt(1)); | |
| 444 if (lhs->Is(Type::None()) || rhs->Is(Type::None())) return false; | |
| 445 // TODO(jarin) The ToNumber conversion is too conservative here, | 441 // TODO(jarin) The ToNumber conversion is too conservative here, |
| 446 // e.g. it will treat true as 1 even though the number check will | 442 // e.g. it will treat true as 1 even though the number check will |
| 447 // fail on a boolean. OperationTyper should have a function that | 443 // fail on a boolean. OperationTyper should have a function that |
| 448 // computes a more precise type. | 444 // computes a more precise type. |
| 449 lhs = op_typer_.ToNumber(lhs); | 445 Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0))); |
| 450 rhs = op_typer_.ToNumber(rhs); | 446 Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1))); |
| 451 Type* static_type = op_typer_.NumericModulus(lhs, rhs); | 447 Type* static_type = op_typer_.NumericModulus(lhs, rhs); |
| 452 if (info->type_check() == TypeCheckKind::kNone) { | 448 if (info->type_check() == TypeCheckKind::kNone) { |
| 453 new_type = static_type; | 449 new_type = static_type; |
| 454 } else { | 450 } else { |
| 455 Type* feedback_type = TypeOfSpeculativeOp(info->type_check()); | 451 Type* feedback_type = TypeOfSpeculativeOp(info->type_check()); |
| 456 new_type = Type::Intersect(static_type, feedback_type, graph_zone()); | 452 new_type = Type::Intersect(static_type, feedback_type, graph_zone()); |
| 457 } | 453 } |
| 458 break; | 454 break; |
| 459 } | 455 } |
| 460 | 456 |
| (...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 938 | 934 |
| 939 if (sig->return_count() > 0) { | 935 if (sig->return_count() > 0) { |
| 940 SetOutput(node, | 936 SetOutput(node, |
| 941 desc->GetMachineSignature()->GetReturn().representation()); | 937 desc->GetMachineSignature()->GetReturn().representation()); |
| 942 } else { | 938 } else { |
| 943 SetOutput(node, MachineRepresentation::kTagged); | 939 SetOutput(node, MachineRepresentation::kTagged); |
| 944 } | 940 } |
| 945 } | 941 } |
| 946 | 942 |
| 947 MachineSemantic DeoptValueSemanticOf(Type* type) { | 943 MachineSemantic DeoptValueSemanticOf(Type* type) { |
| 948 CHECK(!type->Is(Type::None())); | |
| 949 // We only need signedness to do deopt correctly. | 944 // We only need signedness to do deopt correctly. |
| 950 if (type->Is(Type::Signed32())) { | 945 if (type->Is(Type::Signed32())) { |
| 951 return MachineSemantic::kInt32; | 946 return MachineSemantic::kInt32; |
| 952 } else if (type->Is(Type::Unsigned32())) { | 947 } else if (type->Is(Type::Unsigned32())) { |
| 953 return MachineSemantic::kUint32; | 948 return MachineSemantic::kUint32; |
| 954 } else { | 949 } else { |
| 955 return MachineSemantic::kAny; | 950 return MachineSemantic::kAny; |
| 956 } | 951 } |
| 957 } | 952 } |
| 958 | 953 |
| (...skipping 2195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3154 isolate(), graph()->zone(), callable.descriptor(), 0, flags, | 3149 isolate(), graph()->zone(), callable.descriptor(), 0, flags, |
| 3155 Operator::kNoProperties); | 3150 Operator::kNoProperties); |
| 3156 to_number_operator_.set(common()->Call(desc)); | 3151 to_number_operator_.set(common()->Call(desc)); |
| 3157 } | 3152 } |
| 3158 return to_number_operator_.get(); | 3153 return to_number_operator_.get(); |
| 3159 } | 3154 } |
| 3160 | 3155 |
| 3161 } // namespace compiler | 3156 } // namespace compiler |
| 3162 } // namespace internal | 3157 } // namespace internal |
| 3163 } // namespace v8 | 3158 } // namespace v8 |
| OLD | NEW |