Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(289)

Side by Side Diff: runtime/vm/intermediate_language_x64.cc

Issue 10823278: Use type propagation for removing Smi checks in binary operations and comparisons. Regis will adapt… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | runtime/vm/object_store.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 __ jmp(&done); 440 __ jmp(&done);
441 __ Bind(&non_null_compare); // Receiver is not null. 441 __ Bind(&non_null_compare); // Receiver is not null.
442 __ pushq(left); 442 __ pushq(left);
443 __ pushq(right); 443 __ pushq(right);
444 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind, 444 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind,
445 deopt_id, token_pos, try_index); 445 deopt_id, token_pos, try_index);
446 __ Bind(&done); 446 __ Bind(&done);
447 } 447 }
448 448
449 449
450 static intptr_t GetCid(const Value& v) {
451 const AbstractType& type = AbstractType::Handle(v.CompileType());
452 return Class::Handle(type.type_class()).id();
453 }
454
455
450 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler, 456 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler,
451 const LocationSummary& locs, 457 const LocationSummary& locs,
452 Token::Kind kind, 458 Token::Kind kind,
453 BranchInstr* branch, 459 BranchInstr* branch,
454 intptr_t deopt_id, 460 intptr_t deopt_id,
455 intptr_t token_pos, 461 intptr_t token_pos,
456 intptr_t try_index) { 462 intptr_t try_index) {
457 Register left = locs.in(0).reg(); 463 Register left = locs.in(0).reg();
458 Register right = locs.in(1).reg(); 464 Register right = locs.in(1).reg();
459 Register temp = locs.temp(0).reg(); 465 const bool left_is_smi = (branch == NULL) ?
460 Label* deopt = compiler->AddDeoptStub(deopt_id, 466 false : (GetCid(*branch->left()) == kSmiCid);
461 try_index, 467 const bool right_is_smi = (branch == NULL) ?
462 kDeoptSmiCompareSmi, 468 false : (GetCid(*branch->right()) == kSmiCid);
463 left, 469 if (!left_is_smi || !right_is_smi) {
464 right); 470 Register temp = locs.temp(0).reg();
465 __ movq(temp, left); 471 Label* deopt = compiler->AddDeoptStub(deopt_id,
466 __ orq(temp, right); 472 try_index,
467 __ testq(temp, Immediate(kSmiTagMask)); 473 kDeoptSmiCompareSmi,
468 __ j(NOT_ZERO, deopt); 474 left,
475 right);
476 __ movq(temp, left);
477 __ orq(temp, right);
478 __ testq(temp, Immediate(kSmiTagMask));
479 __ j(NOT_ZERO, deopt);
480 }
469 481
470 Condition true_condition = TokenKindToSmiCondition(kind); 482 Condition true_condition = TokenKindToSmiCondition(kind);
471 __ cmpq(left, right); 483 __ cmpq(left, right);
472 484
473 if (branch != NULL) { 485 if (branch != NULL) {
474 branch->EmitBranchOnCondition(compiler, true_condition); 486 branch->EmitBranchOnCondition(compiler, true_condition);
475 } else { 487 } else {
476 Register result = locs.out().reg(); 488 Register result = locs.out().reg();
477 Label done, is_true; 489 Label done, is_true;
478 __ j(true_condition, &is_true); 490 __ j(true_condition, &is_true);
(...skipping 954 matching lines...) Expand 10 before | Expand all | Expand 10 after
1433 } 1445 }
1434 } 1446 }
1435 1447
1436 1448
1437 static void EmitSmiBinaryOp(FlowGraphCompiler* compiler, BinaryOpComp* comp) { 1449 static void EmitSmiBinaryOp(FlowGraphCompiler* compiler, BinaryOpComp* comp) {
1438 Register left = comp->locs()->in(0).reg(); 1450 Register left = comp->locs()->in(0).reg();
1439 Register right = comp->locs()->in(1).reg(); 1451 Register right = comp->locs()->in(1).reg();
1440 Register result = comp->locs()->out().reg(); 1452 Register result = comp->locs()->out().reg();
1441 Register temp = comp->locs()->temp(0).reg(); 1453 Register temp = comp->locs()->temp(0).reg();
1442 ASSERT(left == result); 1454 ASSERT(left == result);
1443 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->deopt_id(), 1455 const bool left_is_smi = (GetCid(*comp->left()) == kSmiCid);
1444 comp->instance_call()->try_index(), 1456 const bool right_is_smi = (GetCid(*comp->right()) == kSmiCid);
1445 kDeoptSmiBinaryOp, 1457 bool can_deopt;
1446 temp, 1458 switch (comp->op_kind()) {
1447 right); 1459 case Token::kBIT_AND:
1448 // TODO(vegorov): for many binary operations this pattern can be rearranged 1460 case Token::kBIT_OR:
1449 // to save one move. 1461 case Token::kBIT_XOR:
1450 __ movq(temp, left); 1462 can_deopt = !(right_is_smi && left_is_smi);
1451 __ orq(left, right); 1463 break;
1452 __ testq(left, Immediate(kSmiTagMask)); 1464 default:
1453 __ j(NOT_ZERO, deopt); 1465 can_deopt = true;
1454 __ movq(left, temp); 1466 }
1467 Label* deopt = NULL;
1468 if (can_deopt) {
1469 deopt = compiler->AddDeoptStub(comp->instance_call()->deopt_id(),
1470 comp->instance_call()->try_index(),
1471 kDeoptSmiBinaryOp,
1472 temp,
1473 right);
1474 }
1475 if (left_is_smi && right_is_smi) {
1476 if (can_deopt) {
1477 // Preserve left for deopt.
1478 __ movq(temp, left);
1479 }
1480 } else {
1481 // TODO(vegorov): for many binary operations this pattern can be rearranged
1482 // to save one move.
1483 __ movq(temp, left);
1484 __ orq(left, right);
1485 __ testq(left, Immediate(kSmiTagMask));
1486 __ j(NOT_ZERO, deopt);
1487 __ movq(left, temp);
1488 }
1455 switch (comp->op_kind()) { 1489 switch (comp->op_kind()) {
1456 case Token::kADD: { 1490 case Token::kADD: {
1457 __ addq(left, right); 1491 __ addq(left, right);
1458 __ j(OVERFLOW, deopt); 1492 __ j(OVERFLOW, deopt);
1459 break; 1493 break;
1460 } 1494 }
1461 case Token::kSUB: { 1495 case Token::kSUB: {
1462 __ subq(left, right); 1496 __ subq(left, right);
1463 __ j(OVERFLOW, deopt); 1497 __ j(OVERFLOW, deopt);
1464 break; 1498 break;
(...skipping 604 matching lines...) Expand 10 before | Expand all | Expand 10 after
2069 kNumArgsChecked); 2103 kNumArgsChecked);
2070 __ CompareObject(RAX, compiler->bool_true()); 2104 __ CompareObject(RAX, compiler->bool_true());
2071 EmitBranchOnCondition(compiler, branch_condition); 2105 EmitBranchOnCondition(compiler, branch_condition);
2072 } 2106 }
2073 2107
2074 } // namespace dart 2108 } // namespace dart
2075 2109
2076 #undef __ 2110 #undef __
2077 2111
2078 #endif // defined TARGET_ARCH_X64 2112 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | runtime/vm/object_store.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698