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

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

Issue 10592028: Improve inlining of bit_and operation for Mint and Smi in new compilers. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 6 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
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 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 } 375 }
376 __ jmp(&done); 376 __ jmp(&done);
377 __ Bind(&next_test); 377 __ Bind(&next_test);
378 } 378 }
379 // Fall through leads to deoptimization 379 // Fall through leads to deoptimization
380 __ jmp(deopt); 380 __ jmp(deopt);
381 __ Bind(&done); 381 __ Bind(&done);
382 } 382 }
383 383
384 384
385
386 // First test if receiver is NULL, in which case === is applied. 385 // First test if receiver is NULL, in which case === is applied.
387 // If type feedback was provided (lists of <class-id, target>), do a 386 // If type feedback was provided (lists of <class-id, target>), do a
388 // type by type check (either === or static call to the operator. 387 // type by type check (either === or static call to the operator.
389 static void EmitGenericEqualityCompare(FlowGraphCompiler* compiler, 388 static void EmitGenericEqualityCompare(FlowGraphCompiler* compiler,
390 EqualityCompareComp* comp) { 389 EqualityCompareComp* comp) {
391 const Immediate raw_null = 390 const Immediate raw_null =
392 Immediate(reinterpret_cast<intptr_t>(Object::null())); 391 Immediate(reinterpret_cast<intptr_t>(Object::null()));
393 Register left = comp->locs()->in(0).reg(); 392 Register left = comp->locs()->in(0).reg();
394 Register right = comp->locs()->in(1).reg(); 393 Register right = comp->locs()->in(1).reg();
395 Label done, non_null_compare; 394 Label done, non_null_compare;
(...skipping 1100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1496 UNREACHABLE(); 1495 UNREACHABLE();
1497 break; 1496 break;
1498 } 1497 }
1499 default: 1498 default:
1500 UNREACHABLE(); 1499 UNREACHABLE();
1501 break; 1500 break;
1502 } 1501 }
1503 } 1502 }
1504 1503
1505 1504
1505 static RawFunction* GetTargetForReceiverClassId(const ICData& ic_data,
1506 intptr_t receiver_class_id) {
srdjan 2012/06/21 16:02:37 I could imagine that this could also live inside c
regis 2012/06/21 18:26:42 Good point. Done.
1507 Function& target = Function::Handle();
1508 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) {
1509 GrowableArray<intptr_t> class_ids;
1510 ic_data.GetCheckAt(i, &class_ids, &target);
1511 if (class_ids[0] == receiver_class_id) {
1512 return target.raw();
1513 }
1514 }
1515 UNREACHABLE();
1516 return Function::null();
1517 }
1518
1519
1506 static void EmitMintBinaryOp(FlowGraphCompiler* compiler, BinaryOpComp* comp) { 1520 static void EmitMintBinaryOp(FlowGraphCompiler* compiler, BinaryOpComp* comp) {
1507 // TODO(regis): For now, we only support Token::kBIT_AND for a Mint or Smi 1521 // TODO(regis): For now, we only support Token::kBIT_AND for a Mint or Smi
1508 // receiver and a Smi argument. 1522 // receiver and a Mint or Smi argument. We fall back to the run time call if
1523 // both receiver and argument are Mint or if one of them is Mint and the other
1524 // is a negative Smi.
1509 Register left = comp->locs()->in(0).reg(); 1525 Register left = comp->locs()->in(0).reg();
1510 Register right = comp->locs()->in(1).reg(); 1526 Register right = comp->locs()->in(1).reg();
1511 Register result = comp->locs()->out().reg(); 1527 Register result = comp->locs()->out().reg();
1512 Register temp = comp->locs()->temp(0).reg(); 1528 Register temp = comp->locs()->temp(0).reg();
1513 ASSERT(left == result); 1529 ASSERT(left == result);
1530 ASSERT(comp->op_kind() == Token::kBIT_AND);
1514 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->cid(), 1531 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->cid(),
1515 comp->instance_call()->token_index(), 1532 comp->instance_call()->token_index(),
1516 comp->instance_call()->try_index(), 1533 comp->instance_call()->try_index(),
1517 kDeoptMintBinaryOp, 1534 kDeoptMintBinaryOp,
1518 temp, 1535 temp,
1519 right); 1536 right);
1520 __ testq(right, Immediate(kSmiTagMask)); // Argument must be Smi. 1537 Label mint_static_call, smi_static_call, non_smi, smi_smi, done;
1521 __ j(NOT_ZERO, deopt); 1538 __ testq(left, Immediate(kSmiTagMask)); // Is receiver Smi?
1522 __ testq(left, Immediate(kSmiTagMask)); // Receiver can be Smi. 1539 __ j(NOT_ZERO, &non_smi);
1523 Label two_smi; 1540 __ testq(right, Immediate(kSmiTagMask)); // Is argument Smi?
1524 __ j(ZERO, &two_smi); 1541 __ j(ZERO, &smi_smi);
1525 __ CompareClassId(left, kMint); // Receiver must be Mint. 1542 __ CompareClassId(right, kMint); // Is argument Mint?
1526 __ j(NOT_EQUAL, deopt); 1543 __ j(NOT_EQUAL, deopt); // Argument neither Smi nor Mint.
1544 __ cmpq(left, Immediate(0));
1545 __ j(LESS, &smi_static_call); // Negative Smi receiver, Mint argument.
1527 1546
1528 ASSERT(comp->op_kind() == Token::kBIT_AND); 1547 // Positive Smi receiver, Mint argument.
1548 // Load lower argument Mint word, convert to Smi. It is OK to loose bits.
1549 __ movq(right, FieldAddress(right, Mint::value_offset()));
1550 __ SmiTag(right);
1551 __ andq(result, right);
1552 __ jmp(&done);
1529 1553
1530 // Load lower Mint word, convert to Smi. It is OK to loose bits. 1554 __ Bind(&non_smi); // Receiver is non-Smi.
1531 ASSERT(result == left); 1555 __ CompareClassId(left, kMint); // Is receiver Mint?
1556 __ j(NOT_EQUAL, deopt); // Receiver neither Smi nor Mint.
1557 __ testq(right, Immediate(kSmiTagMask)); // Is argument Smi?
1558 __ j(NOT_ZERO, &mint_static_call); // Mint receiver, non-Smi argument.
1559 __ cmpq(right, Immediate(0));
1560 __ j(LESS, &mint_static_call); // Mint receiver, negative Smi argument.
1561
1562 // Mint receiver, positive Smi argument.
1563 // Load lower receiver Mint word, convert to Smi. It is OK to loose bits.
1532 __ movq(result, FieldAddress(left, Mint::value_offset())); 1564 __ movq(result, FieldAddress(left, Mint::value_offset()));
1533 __ SmiTag(result); 1565 __ SmiTag(result);
1534 __ Bind(&two_smi); 1566 __ Bind(&smi_smi);
1535 __ andq(result, right); 1567 __ andq(result, right);
1568 __ jmp(&done);
1569
1570 __ Bind(&smi_static_call);
1571 {
1572 Function& target = Function::ZoneHandle(
1573 GetTargetForReceiverClassId(*comp->ic_data(), kSmi));
1574 compiler->GenerateStaticCall(comp->instance_call()->cid(),
1575 comp->instance_call()->token_index(),
1576 comp->instance_call()->try_index(),
1577 target,
1578 comp->instance_call()->ArgumentCount(),
1579 comp->instance_call()->argument_names());
1580 }
1581 __ jmp(&done);
1582
1583 __ Bind(&mint_static_call);
1584 {
1585 Function& target = Function::ZoneHandle(
1586 GetTargetForReceiverClassId(*comp->ic_data(), kMint));
1587 compiler->GenerateStaticCall(comp->instance_call()->cid(),
1588 comp->instance_call()->token_index(),
1589 comp->instance_call()->try_index(),
1590 target,
1591 comp->instance_call()->ArgumentCount(),
1592 comp->instance_call()->argument_names());
1593 }
1594 __ Bind(&done);
1536 } 1595 }
1537 1596
1538 1597
1539 static void EmitDoubleBinaryOp(FlowGraphCompiler* compiler, 1598 static void EmitDoubleBinaryOp(FlowGraphCompiler* compiler,
1540 BinaryOpComp* comp) { 1599 BinaryOpComp* comp) {
1541 Register left = RBX; 1600 Register left = RBX;
1542 Register right = RCX; 1601 Register right = RCX;
1543 Register temp = RDX; 1602 Register temp = RDX;
1544 Register result = comp->locs()->out().reg(); 1603 Register result = comp->locs()->out().reg();
1545 1604
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
1817 instance_call()->argument_names()); 1876 instance_call()->argument_names());
1818 } 1877 }
1819 __ Bind(&done); 1878 __ Bind(&done);
1820 } 1879 }
1821 1880
1822 } // namespace dart 1881 } // namespace dart
1823 1882
1824 #undef __ 1883 #undef __
1825 1884
1826 #endif // defined TARGET_ARCH_X64 1885 #endif // defined TARGET_ARCH_X64
OLDNEW
« runtime/vm/flow_graph_optimizer.cc ('K') | « runtime/vm/intermediate_language_ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698