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 |