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

Side by Side Diff: runtime/vm/intermediate_language_ia32.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
« no previous file with comments | « runtime/vm/flow_graph_optimizer.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('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_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
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 534 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 __ Bind(&is_false); 545 __ Bind(&is_false);
546 __ LoadObject(result, compiler->bool_false()); 546 __ LoadObject(result, compiler->bool_false());
547 __ jmp(&done); 547 __ jmp(&done);
548 __ Bind(&is_true); 548 __ Bind(&is_true);
549 __ LoadObject(result, compiler->bool_true()); 549 __ LoadObject(result, compiler->bool_true());
550 __ Bind(&done); 550 __ Bind(&done);
551 } 551 }
552 } 552 }
553 553
554 554
555
556 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { 555 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
557 if (operands_class_id() == kSmi) { 556 if (operands_class_id() == kSmi) {
558 EmitSmiRelationalOp(compiler, this); 557 EmitSmiRelationalOp(compiler, this);
559 return; 558 return;
560 } 559 }
561 if (operands_class_id() == kDouble) { 560 if (operands_class_id() == kDouble) {
562 EmitDoubleRelationalOp(compiler, this); 561 EmitDoubleRelationalOp(compiler, this);
563 return; 562 return;
564 } 563 }
565 const String& function_name = 564 const String& function_name =
(...skipping 804 matching lines...) Expand 10 before | Expand all | Expand 10 after
1370 LocationSummary* BinaryOpComp::MakeLocationSummary() const { 1369 LocationSummary* BinaryOpComp::MakeLocationSummary() const {
1371 const intptr_t kNumInputs = 2; 1370 const intptr_t kNumInputs = 2;
1372 1371
1373 if (operands_type() == kDoubleOperands) { 1372 if (operands_type() == kDoubleOperands) {
1374 return MakeCallSummary(); // Calls into a stub for allocation. 1373 return MakeCallSummary(); // Calls into a stub for allocation.
1375 } 1374 }
1376 1375
1377 if (operands_type() == kMintOperands) { 1376 if (operands_type() == kMintOperands) {
1378 ASSERT(op_kind() == Token::kBIT_AND); 1377 ASSERT(op_kind() == Token::kBIT_AND);
1379 const intptr_t kNumTemps = 1; 1378 const intptr_t kNumTemps = 1;
1380 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); 1379 LocationSummary* summary =
1381 summary->set_in(0, Location::RequiresRegister()); 1380 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1381 summary->set_in(0, Location::RegisterLocation(EAX));
1382 summary->set_in(1, Location::RequiresRegister()); 1382 summary->set_in(1, Location::RequiresRegister());
1383 summary->set_out(Location::SameAsFirstInput()); 1383 summary->set_out(Location::SameAsFirstInput());
1384 summary->set_temp(0, Location::RequiresRegister()); 1384 summary->set_temp(0, Location::RequiresRegister());
1385 return summary; 1385 return summary;
1386 } 1386 }
1387 1387
1388 ASSERT(operands_type() == kSmiOperands); 1388 ASSERT(operands_type() == kSmiOperands);
1389 1389
1390 if (op_kind() == Token::kTRUNCDIV) { 1390 if (op_kind() == Token::kTRUNCDIV) {
1391 const intptr_t kNumTemps = 3; 1391 const intptr_t kNumTemps = 3;
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
1556 } 1556 }
1557 default: 1557 default:
1558 UNREACHABLE(); 1558 UNREACHABLE();
1559 break; 1559 break;
1560 } 1560 }
1561 } 1561 }
1562 1562
1563 1563
1564 static void EmitMintBinaryOp(FlowGraphCompiler* compiler, BinaryOpComp* comp) { 1564 static void EmitMintBinaryOp(FlowGraphCompiler* compiler, BinaryOpComp* comp) {
1565 // TODO(regis): For now, we only support Token::kBIT_AND for a Mint or Smi 1565 // TODO(regis): For now, we only support Token::kBIT_AND for a Mint or Smi
1566 // receiver and a Smi argument. 1566 // receiver and a Mint or Smi argument. We fall back to the run time call if
1567 // both receiver and argument are Mint or if one of them is Mint and the other
1568 // is a negative Smi.
1567 Register left = comp->locs()->in(0).reg(); 1569 Register left = comp->locs()->in(0).reg();
1568 Register right = comp->locs()->in(1).reg(); 1570 Register right = comp->locs()->in(1).reg();
1569 Register result = comp->locs()->out().reg(); 1571 Register result = comp->locs()->out().reg();
1570 Register temp = comp->locs()->temp(0).reg(); 1572 Register temp = comp->locs()->temp(0).reg();
1571 ASSERT(left == result); 1573 ASSERT(left == result);
1574 ASSERT(comp->op_kind() == Token::kBIT_AND);
1572 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->cid(), 1575 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->cid(),
1573 comp->instance_call()->token_index(), 1576 comp->instance_call()->token_index(),
1574 comp->instance_call()->try_index(), 1577 comp->instance_call()->try_index(),
1575 kDeoptMintBinaryOp, 1578 kDeoptMintBinaryOp,
1576 temp, 1579 left,
1577 right); 1580 right);
1578 __ testl(right, Immediate(kSmiTagMask)); // Argument must be Smi. 1581 Label mint_static_call, smi_static_call, non_smi, smi_smi, done;
1579 __ j(NOT_ZERO, deopt); 1582 __ testl(left, Immediate(kSmiTagMask)); // Is receiver Smi?
1580 __ testl(left, Immediate(kSmiTagMask)); // Receiver can be Smi. 1583 __ j(NOT_ZERO, &non_smi);
1581 Label two_smi; 1584 __ testl(right, Immediate(kSmiTagMask)); // Is argument Smi?
1582 __ j(ZERO, &two_smi); 1585 __ j(ZERO, &smi_smi);
1583 __ CompareClassId(left, kMint, temp); // Receiver must be Mint. 1586 __ CompareClassId(right, kMint, temp); // Is argument Mint?
1584 __ j(NOT_EQUAL, deopt); 1587 __ j(NOT_EQUAL, deopt); // Argument neither Smi nor Mint.
1588 __ cmpl(left, Immediate(0));
1589 __ j(LESS, &smi_static_call); // Negative Smi receiver, Mint argument.
1585 1590
1586 ASSERT(comp->op_kind() == Token::kBIT_AND); 1591 // Positive Smi receiver, Mint argument.
1592 // Load lower argument Mint word, convert to Smi. It is OK to loose bits.
1593 __ movl(right, FieldAddress(right, Mint::value_offset()));
1594 __ SmiTag(right);
1595 __ andl(result, right);
1596 __ jmp(&done);
1587 1597
1588 // Load lower Mint word, convert to Smi. It is OK to loose bits. 1598 __ Bind(&non_smi); // Receiver is non-Smi.
1589 ASSERT(result == left); 1599 __ CompareClassId(left, kMint, temp); // Is receiver Mint?
1600 __ j(NOT_EQUAL, deopt); // Receiver neither Smi nor Mint.
1601 __ testl(right, Immediate(kSmiTagMask)); // Is argument Smi?
1602 __ j(NOT_ZERO, &mint_static_call); // Mint receiver, non-Smi argument.
1603 __ cmpl(right, Immediate(0));
1604 __ j(LESS, &mint_static_call); // Mint receiver, negative Smi argument.
1605
1606 // Mint receiver, positive Smi argument.
1607 // Load lower receiver Mint word, convert to Smi. It is OK to loose bits.
1590 __ movl(result, FieldAddress(left, Mint::value_offset())); 1608 __ movl(result, FieldAddress(left, Mint::value_offset()));
1591 __ SmiTag(result); 1609 __ SmiTag(result);
1592 __ Bind(&two_smi); 1610 __ Bind(&smi_smi);
1593 __ andl(result, right); 1611 __ andl(result, right);
1612 __ jmp(&done);
1613
1614 __ Bind(&smi_static_call);
1615 {
1616 Function& target = Function::ZoneHandle(
1617 comp->ic_data()->GetTargetForReceiverClassId(kSmi));
1618 if (target.IsNull()) {
1619 __ jmp(deopt);
1620 } else {
1621 __ pushl(left);
1622 __ pushl(right);
1623 compiler->GenerateStaticCall(comp->instance_call()->cid(),
1624 comp->instance_call()->token_index(),
1625 comp->instance_call()->try_index(),
1626 target,
1627 comp->instance_call()->ArgumentCount(),
1628 comp->instance_call()->argument_names());
1629 ASSERT(result == EAX);
1630 __ jmp(&done);
1631 }
1632 }
1633
1634 __ Bind(&mint_static_call);
1635 {
1636 Function& target = Function::ZoneHandle(
1637 comp->ic_data()->GetTargetForReceiverClassId(kMint));
1638 if (target.IsNull()) {
1639 __ jmp(deopt);
1640 } else {
1641 __ pushl(left);
1642 __ pushl(right);
1643 compiler->GenerateStaticCall(comp->instance_call()->cid(),
1644 comp->instance_call()->token_index(),
1645 comp->instance_call()->try_index(),
1646 target,
1647 comp->instance_call()->ArgumentCount(),
1648 comp->instance_call()->argument_names());
1649 ASSERT(result == EAX);
1650 }
1651 }
1652 __ Bind(&done);
1594 } 1653 }
1595 1654
1596 1655
1597 static void EmitDoubleBinaryOp(FlowGraphCompiler* compiler, 1656 static void EmitDoubleBinaryOp(FlowGraphCompiler* compiler,
1598 BinaryOpComp* comp) { 1657 BinaryOpComp* comp) {
1599 Register left = EBX; 1658 Register left = EBX;
1600 Register right = ECX; 1659 Register right = ECX;
1601 Register temp = EDX; 1660 Register temp = EDX;
1602 Register result = comp->locs()->out().reg(); 1661 Register result = comp->locs()->out().reg();
1603 1662
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
1871 compiler->GenerateStaticCall(instance_call()->cid(), 1930 compiler->GenerateStaticCall(instance_call()->cid(),
1872 instance_call()->token_index(), 1931 instance_call()->token_index(),
1873 instance_call()->try_index(), 1932 instance_call()->try_index(),
1874 target, 1933 target,
1875 instance_call()->ArgumentCount(), 1934 instance_call()->ArgumentCount(),
1876 instance_call()->argument_names()); 1935 instance_call()->argument_names());
1877 } 1936 }
1878 __ Bind(&done); 1937 __ Bind(&done);
1879 } 1938 }
1880 1939
1881
1882 } // namespace dart 1940 } // namespace dart
1883 1941
1884 #undef __ 1942 #undef __
1885 1943
1886 #endif // defined TARGET_ARCH_X64 1944 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_optimizer.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698