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

Side by Side Diff: src/compiler/arm/instruction-selector-arm.cc

Issue 1361913003: [arm] Optimize vcmp when lhs operand is #0.0 (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 2 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
OLDNEW
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/base/adapters.h" 5 #include "src/base/adapters.h"
6 #include "src/base/bits.h" 6 #include "src/base/bits.h"
7 #include "src/compiler/instruction-selector-impl.h" 7 #include "src/compiler/instruction-selector-impl.h"
8 #include "src/compiler/node-matchers.h" 8 #include "src/compiler/node-matchers.h"
9 #include "src/compiler/node-properties.h" 9 #include "src/compiler/node-properties.h"
10 10
(...skipping 1249 matching lines...) Expand 10 before | Expand all | Expand 10 after
1260 auto* outputs = output_count ? &buffer.outputs.front() : nullptr; 1260 auto* outputs = output_count ? &buffer.outputs.front() : nullptr;
1261 Emit(opcode, output_count, outputs, buffer.instruction_args.size(), 1261 Emit(opcode, output_count, outputs, buffer.instruction_args.size(),
1262 &buffer.instruction_args.front())->MarkAsCall(); 1262 &buffer.instruction_args.front())->MarkAsCall();
1263 Emit(kArchRet, 0, nullptr, output_count, outputs); 1263 Emit(kArchRet, 0, nullptr, output_count, outputs);
1264 } 1264 }
1265 } 1265 }
1266 1266
1267 1267
1268 namespace { 1268 namespace {
1269 1269
1270 // Shared routine for multiple compare operations.
1271 void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
1272 InstructionOperand left, InstructionOperand right,
1273 FlagsContinuation* cont) {
1274 ArmOperandGenerator g(selector);
1275 opcode = cont->Encode(opcode);
1276 if (cont->IsBranch()) {
1277 selector->Emit(opcode, g.NoOutput(), left, right,
1278 g.Label(cont->true_block()), g.Label(cont->false_block()));
1279 } else {
1280 DCHECK(cont->IsSet());
1281 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
1282 }
1283 }
1284
1285
1270 // Shared routine for multiple float32 compare operations. 1286 // Shared routine for multiple float32 compare operations.
1271 void VisitFloat32Compare(InstructionSelector* selector, Node* node, 1287 void VisitFloat32Compare(InstructionSelector* selector, Node* node,
1272 FlagsContinuation* cont) { 1288 FlagsContinuation* cont) {
1273 ArmOperandGenerator g(selector); 1289 ArmOperandGenerator g(selector);
1274 Float32BinopMatcher m(node); 1290 Float32BinopMatcher m(node);
1275 InstructionOperand rhs = m.right().Is(0.0) ? g.UseImmediate(m.right().node()) 1291 if (m.right().Is(0.0f)) {
1276 : g.UseRegister(m.right().node()); 1292 VisitCompare(selector, kArmVcmpF32, g.UseRegister(m.left().node()),
1277 if (cont->IsBranch()) { 1293 g.UseImmediate(m.right().node()), cont);
1278 selector->Emit(cont->Encode(kArmVcmpF32), g.NoOutput(), 1294 } else if (m.left().Is(0.0f)) {
1279 g.UseRegister(m.left().node()), rhs, 1295 cont->Commute();
1280 g.Label(cont->true_block()), g.Label(cont->false_block())); 1296 VisitCompare(selector, kArmVcmpF32, g.UseRegister(m.right().node()),
1297 g.UseImmediate(m.left().node()), cont);
1281 } else { 1298 } else {
1282 DCHECK(cont->IsSet()); 1299 VisitCompare(selector, kArmVcmpF32, g.UseRegister(m.left().node()),
1283 selector->Emit(cont->Encode(kArmVcmpF32), 1300 g.UseRegister(m.right().node()), cont);
1284 g.DefineAsRegister(cont->result()),
1285 g.UseRegister(m.left().node()), rhs);
1286 } 1301 }
1287 } 1302 }
1288 1303
1289 1304
1290 // Shared routine for multiple float64 compare operations. 1305 // Shared routine for multiple float64 compare operations.
1291 void VisitFloat64Compare(InstructionSelector* selector, Node* node, 1306 void VisitFloat64Compare(InstructionSelector* selector, Node* node,
1292 FlagsContinuation* cont) { 1307 FlagsContinuation* cont) {
1293 ArmOperandGenerator g(selector); 1308 ArmOperandGenerator g(selector);
1294 Float64BinopMatcher m(node); 1309 Float64BinopMatcher m(node);
1295 InstructionOperand rhs = m.right().Is(0.0) ? g.UseImmediate(m.right().node()) 1310 if (m.right().Is(0.0)) {
1296 : g.UseRegister(m.right().node()); 1311 VisitCompare(selector, kArmVcmpF64, g.UseRegister(m.left().node()),
1297 if (cont->IsBranch()) { 1312 g.UseImmediate(m.right().node()), cont);
1298 selector->Emit(cont->Encode(kArmVcmpF64), g.NoOutput(), 1313 } else if (m.left().Is(0.0)) {
1299 g.UseRegister(m.left().node()), rhs, 1314 cont->Commute();
1300 g.Label(cont->true_block()), g.Label(cont->false_block())); 1315 VisitCompare(selector, kArmVcmpF64, g.UseRegister(m.right().node()),
1316 g.UseImmediate(m.left().node()), cont);
1301 } else { 1317 } else {
1302 DCHECK(cont->IsSet()); 1318 VisitCompare(selector, kArmVcmpF64, g.UseRegister(m.left().node()),
1303 selector->Emit(cont->Encode(kArmVcmpF64), 1319 g.UseRegister(m.right().node()), cont);
1304 g.DefineAsRegister(cont->result()),
1305 g.UseRegister(m.left().node()), rhs);
1306 } 1320 }
1307 } 1321 }
1308 1322
1309 1323
1310 // Shared routine for multiple word compare operations. 1324 // Shared routine for multiple word compare operations.
1311 void VisitWordCompare(InstructionSelector* selector, Node* node, 1325 void VisitWordCompare(InstructionSelector* selector, Node* node,
1312 InstructionCode opcode, FlagsContinuation* cont) { 1326 InstructionCode opcode, FlagsContinuation* cont) {
1313 ArmOperandGenerator g(selector); 1327 ArmOperandGenerator g(selector);
1314 Int32BinopMatcher m(node); 1328 Int32BinopMatcher m(node);
1315 InstructionOperand inputs[5]; 1329 InstructionOperand inputs[5];
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1382 case IrOpcode::kUint32LessThan: 1396 case IrOpcode::kUint32LessThan:
1383 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); 1397 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
1384 return VisitWordCompare(selector, value, cont); 1398 return VisitWordCompare(selector, value, cont);
1385 case IrOpcode::kUint32LessThanOrEqual: 1399 case IrOpcode::kUint32LessThanOrEqual:
1386 cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); 1400 cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
1387 return VisitWordCompare(selector, value, cont); 1401 return VisitWordCompare(selector, value, cont);
1388 case IrOpcode::kFloat32Equal: 1402 case IrOpcode::kFloat32Equal:
1389 cont->OverwriteAndNegateIfEqual(kEqual); 1403 cont->OverwriteAndNegateIfEqual(kEqual);
1390 return VisitFloat32Compare(selector, value, cont); 1404 return VisitFloat32Compare(selector, value, cont);
1391 case IrOpcode::kFloat32LessThan: 1405 case IrOpcode::kFloat32LessThan:
1392 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); 1406 cont->OverwriteAndNegateIfEqual(kFloatLessThan);
1393 return VisitFloat32Compare(selector, value, cont); 1407 return VisitFloat32Compare(selector, value, cont);
1394 case IrOpcode::kFloat32LessThanOrEqual: 1408 case IrOpcode::kFloat32LessThanOrEqual:
1395 cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); 1409 cont->OverwriteAndNegateIfEqual(kFloatLessThanOrEqual);
1396 return VisitFloat32Compare(selector, value, cont); 1410 return VisitFloat32Compare(selector, value, cont);
1397 case IrOpcode::kFloat64Equal: 1411 case IrOpcode::kFloat64Equal:
1398 cont->OverwriteAndNegateIfEqual(kEqual); 1412 cont->OverwriteAndNegateIfEqual(kEqual);
1399 return VisitFloat64Compare(selector, value, cont); 1413 return VisitFloat64Compare(selector, value, cont);
1400 case IrOpcode::kFloat64LessThan: 1414 case IrOpcode::kFloat64LessThan:
1401 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); 1415 cont->OverwriteAndNegateIfEqual(kFloatLessThan);
1402 return VisitFloat64Compare(selector, value, cont); 1416 return VisitFloat64Compare(selector, value, cont);
1403 case IrOpcode::kFloat64LessThanOrEqual: 1417 case IrOpcode::kFloat64LessThanOrEqual:
1404 cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); 1418 cont->OverwriteAndNegateIfEqual(kFloatLessThanOrEqual);
1405 return VisitFloat64Compare(selector, value, cont); 1419 return VisitFloat64Compare(selector, value, cont);
1406 case IrOpcode::kProjection: 1420 case IrOpcode::kProjection:
1407 // Check if this is the overflow output projection of an 1421 // Check if this is the overflow output projection of an
1408 // <Operation>WithOverflow node. 1422 // <Operation>WithOverflow node.
1409 if (ProjectionIndexOf(value->op()) == 1u) { 1423 if (ProjectionIndexOf(value->op()) == 1u) {
1410 // We cannot combine the <Operation>WithOverflow with this branch 1424 // We cannot combine the <Operation>WithOverflow with this branch
1411 // unless the 0th projection (the use of the actual value of the 1425 // unless the 0th projection (the use of the actual value of the
1412 // <Operation> is either NULL, which means there's no use of the 1426 // <Operation> is either NULL, which means there's no use of the
1413 // actual value, or was already defined, which means it is scheduled 1427 // actual value, or was already defined, which means it is scheduled
1414 // *AFTER* this branch). 1428 // *AFTER* this branch).
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
1558 } 1572 }
1559 1573
1560 1574
1561 void InstructionSelector::VisitFloat32Equal(Node* node) { 1575 void InstructionSelector::VisitFloat32Equal(Node* node) {
1562 FlagsContinuation cont(kEqual, node); 1576 FlagsContinuation cont(kEqual, node);
1563 VisitFloat32Compare(this, node, &cont); 1577 VisitFloat32Compare(this, node, &cont);
1564 } 1578 }
1565 1579
1566 1580
1567 void InstructionSelector::VisitFloat32LessThan(Node* node) { 1581 void InstructionSelector::VisitFloat32LessThan(Node* node) {
1568 FlagsContinuation cont(kUnsignedLessThan, node); 1582 FlagsContinuation cont(kFloatLessThan, node);
1569 VisitFloat32Compare(this, node, &cont); 1583 VisitFloat32Compare(this, node, &cont);
1570 } 1584 }
1571 1585
1572 1586
1573 void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) { 1587 void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) {
1574 FlagsContinuation cont(kUnsignedLessThanOrEqual, node); 1588 FlagsContinuation cont(kFloatLessThanOrEqual, node);
1575 VisitFloat32Compare(this, node, &cont); 1589 VisitFloat32Compare(this, node, &cont);
1576 } 1590 }
1577 1591
1578 1592
1579 void InstructionSelector::VisitFloat64Equal(Node* node) { 1593 void InstructionSelector::VisitFloat64Equal(Node* node) {
1580 FlagsContinuation cont(kEqual, node); 1594 FlagsContinuation cont(kEqual, node);
1581 VisitFloat64Compare(this, node, &cont); 1595 VisitFloat64Compare(this, node, &cont);
1582 } 1596 }
1583 1597
1584 1598
1585 void InstructionSelector::VisitFloat64LessThan(Node* node) { 1599 void InstructionSelector::VisitFloat64LessThan(Node* node) {
1586 FlagsContinuation cont(kUnsignedLessThan, node); 1600 FlagsContinuation cont(kFloatLessThan, node);
1587 VisitFloat64Compare(this, node, &cont); 1601 VisitFloat64Compare(this, node, &cont);
1588 } 1602 }
1589 1603
1590 1604
1591 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) { 1605 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
1592 FlagsContinuation cont(kUnsignedLessThanOrEqual, node); 1606 FlagsContinuation cont(kFloatLessThanOrEqual, node);
1593 VisitFloat64Compare(this, node, &cont); 1607 VisitFloat64Compare(this, node, &cont);
1594 } 1608 }
1595 1609
1596 1610
1597 void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) { 1611 void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) {
1598 VisitRR(this, kArmVmovLowU32F64, node); 1612 VisitRR(this, kArmVmovLowU32F64, node);
1599 } 1613 }
1600 1614
1601 1615
1602 void InstructionSelector::VisitFloat64ExtractHighWord32(Node* node) { 1616 void InstructionSelector::VisitFloat64ExtractHighWord32(Node* node) {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1646 flags |= MachineOperatorBuilder::kFloat64RoundDown | 1660 flags |= MachineOperatorBuilder::kFloat64RoundDown |
1647 MachineOperatorBuilder::kFloat64RoundTruncate | 1661 MachineOperatorBuilder::kFloat64RoundTruncate |
1648 MachineOperatorBuilder::kFloat64RoundTiesAway; 1662 MachineOperatorBuilder::kFloat64RoundTiesAway;
1649 } 1663 }
1650 return flags; 1664 return flags;
1651 } 1665 }
1652 1666
1653 } // namespace compiler 1667 } // namespace compiler
1654 } // namespace internal 1668 } // namespace internal
1655 } // namespace v8 1669 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/arm/code-generator-arm.cc ('k') | test/unittests/compiler/arm/instruction-selector-arm-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698