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

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

Issue 10916082: Make register allocator to disregard constant computation with no uses. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 3 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') | no next file » | 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 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 167
168 168
169 LocationSummary* ConstantComp::MakeLocationSummary() const { 169 LocationSummary* ConstantComp::MakeLocationSummary() const {
170 return LocationSummary::Make(0, 170 return LocationSummary::Make(0,
171 Location::RequiresRegister(), 171 Location::RequiresRegister(),
172 LocationSummary::kNoCall); 172 LocationSummary::kNoCall);
173 } 173 }
174 174
175 175
176 void ConstantComp::EmitNativeCode(FlowGraphCompiler* compiler) { 176 void ConstantComp::EmitNativeCode(FlowGraphCompiler* compiler) {
177 Register result = locs()->out().reg(); 177 // Register allocator drops constant definitions that have no uses.
178 __ LoadObject(result, value()); 178 if (!locs()->out().IsInvalid()) {
179 Register result = locs()->out().reg();
180 __ LoadObject(result, value());
181 }
179 } 182 }
180 183
181 184
182 LocationSummary* AssertAssignableComp::MakeLocationSummary() const { 185 LocationSummary* AssertAssignableComp::MakeLocationSummary() const {
183 const intptr_t kNumInputs = 3; 186 const intptr_t kNumInputs = 3;
184 const intptr_t kNumTemps = 0; 187 const intptr_t kNumTemps = 0;
185 LocationSummary* summary = 188 LocationSummary* summary =
186 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 189 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
187 summary->set_in(0, Location::RegisterLocation(RAX)); // Value. 190 summary->set_in(0, Location::RegisterLocation(RAX)); // Value.
188 summary->set_in(1, Location::RegisterLocation(RCX)); // Instantiator. 191 summary->set_in(1, Location::RegisterLocation(RCX)); // Instantiator.
(...skipping 1253 matching lines...) Expand 10 before | Expand all | Expand 10 after
1442 1445
1443 Register temp = locs()->temp(0).reg(); 1446 Register temp = locs()->temp(0).reg();
1444 // Generate stack overflow check. 1447 // Generate stack overflow check.
1445 __ movq(temp, Immediate(Isolate::Current()->stack_limit_address())); 1448 __ movq(temp, Immediate(Isolate::Current()->stack_limit_address()));
1446 __ cmpq(RSP, Address(temp, 0)); 1449 __ cmpq(RSP, Address(temp, 0));
1447 __ j(BELOW_EQUAL, slow_path->entry_label()); 1450 __ j(BELOW_EQUAL, slow_path->entry_label());
1448 __ Bind(slow_path->exit_label()); 1451 __ Bind(slow_path->exit_label());
1449 } 1452 }
1450 1453
1451 1454
1455 static bool CanBeImmediate(const Object& constant) {
1456 return constant.IsSmi() &&
1457 Immediate(reinterpret_cast<int64_t>(constant.raw())).is_int32();
1458 }
1459
1452 LocationSummary* BinarySmiOpComp::MakeLocationSummary() const { 1460 LocationSummary* BinarySmiOpComp::MakeLocationSummary() const {
1453 const intptr_t kNumInputs = 2; 1461 const intptr_t kNumInputs = 2;
1462
1463 ConstantComp* right_constant = right()->definition()->AsConstant();
1464 if ((right_constant != NULL) &&
1465 (op_kind() != Token::kTRUNCDIV) &&
1466 (op_kind() != Token::kSHL) &&
1467 (op_kind() != Token::kMUL) &&
1468 CanBeImmediate(right_constant->value())) {
1469 const intptr_t kNumTemps = 0;
1470 LocationSummary* summary =
1471 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1472 summary->set_in(0, Location::RequiresRegister());
1473 summary->set_in(1, Location::Constant(right_constant->value()));
1474 summary->set_out(Location::SameAsFirstInput());
1475 return summary;
1476 }
1477
1454 if (op_kind() == Token::kTRUNCDIV) { 1478 if (op_kind() == Token::kTRUNCDIV) {
1455 const intptr_t kNumTemps = 3; 1479 const intptr_t kNumTemps = 3;
1456 LocationSummary* summary = 1480 LocationSummary* summary =
1457 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1481 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1458 summary->set_in(0, Location::RegisterLocation(RAX)); 1482 summary->set_in(0, Location::RegisterLocation(RAX));
1459 summary->set_in(1, Location::RegisterLocation(RCX)); 1483 summary->set_in(1, Location::RegisterLocation(RCX));
1460 summary->set_out(Location::SameAsFirstInput()); 1484 summary->set_out(Location::SameAsFirstInput());
1461 summary->set_temp(0, Location::RegisterLocation(RBX)); 1485 summary->set_temp(0, Location::RegisterLocation(RBX));
1462 // Will be used for for sign extension. 1486 // Will be used for for sign extension.
1463 summary->set_temp(1, Location::RegisterLocation(RDX)); 1487 summary->set_temp(1, Location::RegisterLocation(RDX));
(...skipping 25 matching lines...) Expand all
1489 summary->set_in(0, Location::RequiresRegister()); 1513 summary->set_in(0, Location::RequiresRegister());
1490 summary->set_in(1, Location::RequiresRegister()); 1514 summary->set_in(1, Location::RequiresRegister());
1491 summary->set_out(Location::SameAsFirstInput()); 1515 summary->set_out(Location::SameAsFirstInput());
1492 return summary; 1516 return summary;
1493 } 1517 }
1494 } 1518 }
1495 1519
1496 1520
1497 void BinarySmiOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1521 void BinarySmiOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1498 Register left = locs()->in(0).reg(); 1522 Register left = locs()->in(0).reg();
1499 Register right = locs()->in(1).reg();
1500 Register result = locs()->out().reg(); 1523 Register result = locs()->out().reg();
1501 ASSERT(left == result); 1524 ASSERT(left == result);
1502 Label* deopt = NULL; 1525 Label* deopt = NULL;
1503 switch (op_kind()) { 1526 switch (op_kind()) {
1504 case Token::kBIT_AND: 1527 case Token::kBIT_AND:
1505 case Token::kBIT_OR: 1528 case Token::kBIT_OR:
1506 case Token::kBIT_XOR: 1529 case Token::kBIT_XOR:
1507 // Can't deoptimize. Arguments are already checked for smi. 1530 // Can't deoptimize. Arguments are already checked for smi.
1508 break; 1531 break;
1509 default: 1532 default:
1510 deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 1533 deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1511 kDeoptBinarySmiOp); 1534 kDeoptBinarySmiOp);
1512 } 1535 }
1536
1537 if (locs()->in(1).IsConstant()) {
1538 const Object& constant = locs()->in(1).constant();
1539 ASSERT(constant.IsSmi());
1540 const int64_t imm =
1541 reinterpret_cast<int64_t>(constant.raw());
1542 switch (op_kind()) {
1543 case Token::kADD: {
1544 __ addq(left, Immediate(imm));
1545 __ j(OVERFLOW, deopt);
1546 break;
1547 }
1548 case Token::kSUB: {
1549 __ subq(left, Immediate(imm));
1550 __ j(OVERFLOW, deopt);
1551 break;
1552 }
1553 case Token::kBIT_AND: {
1554 // No overflow check.
1555 __ andq(left, Immediate(imm));
1556 break;
1557 }
1558 case Token::kBIT_OR: {
1559 // No overflow check.
1560 __ orq(left, Immediate(imm));
1561 break;
1562 }
1563 case Token::kBIT_XOR: {
1564 // No overflow check.
1565 __ xorq(left, Immediate(imm));
1566 break;
1567 }
1568
1569 case Token::kSHR: {
1570 // sarq operation masks the count to 6 bits.
1571 const intptr_t kCountLimit = 0x3F;
1572 intptr_t value = Smi::Cast(constant).Value();
1573
1574 if (value == 0) {
1575 // TODO(vegorov): should be handled outside.
1576 break;
1577 } else if (value < 0) {
1578 // TODO(vegorov): should be handled outside.
1579 __ jmp(deopt);
1580 break;
1581 }
1582
1583 value = value + kSmiTagSize;
1584 if (value >= kCountLimit) value = kCountLimit;
1585
1586 __ sarq(left, Immediate(value));
1587 __ SmiTag(left);
1588 break;
1589 }
1590 default:
1591 UNREACHABLE();
1592 break;
1593 }
1594 return;
1595 }
1596
1597 Register right = locs()->in(1).reg();
1513 switch (op_kind()) { 1598 switch (op_kind()) {
1514 case Token::kADD: { 1599 case Token::kADD: {
1515 __ addq(left, right); 1600 __ addq(left, right);
1516 __ j(OVERFLOW, deopt); 1601 __ j(OVERFLOW, deopt);
1517 break; 1602 break;
1518 } 1603 }
1519 case Token::kSUB: { 1604 case Token::kSUB: {
1520 __ subq(left, right); 1605 __ subq(left, right);
1521 __ j(OVERFLOW, deopt); 1606 __ j(OVERFLOW, deopt);
1522 break; 1607 break;
(...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after
2198 } 2283 }
2199 __ j(ABOVE_EQUAL, deopt); 2284 __ j(ABOVE_EQUAL, deopt);
2200 } 2285 }
2201 2286
2202 2287
2203 } // namespace dart 2288 } // namespace dart
2204 2289
2205 #undef __ 2290 #undef __
2206 2291
2207 #endif // defined TARGET_ARCH_X64 2292 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698