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

Side by Side Diff: src/arm/assembler-arm.cc

Issue 7003025: Remove peephole optimiziations from IA32 and ARM assembler. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 7 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 | « src/arm/assembler-arm.h ('k') | src/ia32/assembler-ia32.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) 1994-2006 Sun Microsystems Inc. 1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
2 // All Rights Reserved. 2 // All Rights Reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions 5 // modification, are permitted provided that the following conditions
6 // are met: 6 // are met:
7 // 7 //
8 // - Redistributions of source code must retain the above copyright notice, 8 // - Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer. 9 // this list of conditions and the following disclaimer.
10 // 10 //
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 const Instr kLdrStrOffsetMask = 0x00000fff; 282 const Instr kLdrStrOffsetMask = 0x00000fff;
283 283
284 284
285 // Spare buffer. 285 // Spare buffer.
286 static const int kMinimalBufferSize = 4*KB; 286 static const int kMinimalBufferSize = 4*KB;
287 287
288 288
289 Assembler::Assembler(Isolate* arg_isolate, void* buffer, int buffer_size) 289 Assembler::Assembler(Isolate* arg_isolate, void* buffer, int buffer_size)
290 : AssemblerBase(arg_isolate), 290 : AssemblerBase(arg_isolate),
291 positions_recorder_(this), 291 positions_recorder_(this),
292 allow_peephole_optimization_(false),
293 emit_debug_code_(FLAG_debug_code) { 292 emit_debug_code_(FLAG_debug_code) {
294 allow_peephole_optimization_ = FLAG_peephole_optimization;
295 if (buffer == NULL) { 293 if (buffer == NULL) {
296 // Do our own buffer management. 294 // Do our own buffer management.
297 if (buffer_size <= kMinimalBufferSize) { 295 if (buffer_size <= kMinimalBufferSize) {
298 buffer_size = kMinimalBufferSize; 296 buffer_size = kMinimalBufferSize;
299 297
300 if (isolate()->assembler_spare_buffer() != NULL) { 298 if (isolate()->assembler_spare_buffer() != NULL) {
301 buffer = isolate()->assembler_spare_buffer(); 299 buffer = isolate()->assembler_spare_buffer();
302 isolate()->set_assembler_spare_buffer(NULL); 300 isolate()->set_assembler_spare_buffer(NULL);
303 } 301 }
304 } 302 }
(...skipping 784 matching lines...) Expand 10 before | Expand all | Expand 10 after
1089 1087
1090 void Assembler::rsb(Register dst, Register src1, const Operand& src2, 1088 void Assembler::rsb(Register dst, Register src1, const Operand& src2,
1091 SBit s, Condition cond) { 1089 SBit s, Condition cond) {
1092 addrmod1(cond | RSB | s, src1, dst, src2); 1090 addrmod1(cond | RSB | s, src1, dst, src2);
1093 } 1091 }
1094 1092
1095 1093
1096 void Assembler::add(Register dst, Register src1, const Operand& src2, 1094 void Assembler::add(Register dst, Register src1, const Operand& src2,
1097 SBit s, Condition cond) { 1095 SBit s, Condition cond) {
1098 addrmod1(cond | ADD | s, src1, dst, src2); 1096 addrmod1(cond | ADD | s, src1, dst, src2);
1099
1100 // Eliminate pattern: push(r), pop()
1101 // str(src, MemOperand(sp, 4, NegPreIndex), al);
1102 // add(sp, sp, Operand(kPointerSize));
1103 // Both instructions can be eliminated.
1104 if (can_peephole_optimize(2) &&
1105 // Pattern.
1106 instr_at(pc_ - 1 * kInstrSize) == kPopInstruction &&
1107 (instr_at(pc_ - 2 * kInstrSize) & ~kRdMask) == kPushRegPattern) {
1108 pc_ -= 2 * kInstrSize;
1109 if (FLAG_print_peephole_optimization) {
1110 PrintF("%x push(reg)/pop() eliminated\n", pc_offset());
1111 }
1112 }
1113 } 1097 }
1114 1098
1115 1099
1116 void Assembler::adc(Register dst, Register src1, const Operand& src2, 1100 void Assembler::adc(Register dst, Register src1, const Operand& src2,
1117 SBit s, Condition cond) { 1101 SBit s, Condition cond) {
1118 addrmod1(cond | ADC | s, src1, dst, src2); 1102 addrmod1(cond | ADC | s, src1, dst, src2);
1119 } 1103 }
1120 1104
1121 1105
1122 void Assembler::sbc(Register dst, Register src1, const Operand& src2, 1106 void Assembler::sbc(Register dst, Register src1, const Operand& src2,
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
1407 emit(cond | instr | B24 | B21 | fields | 15*B12); 1391 emit(cond | instr | B24 | B21 | fields | 15*B12);
1408 } 1392 }
1409 1393
1410 1394
1411 // Load/Store instructions. 1395 // Load/Store instructions.
1412 void Assembler::ldr(Register dst, const MemOperand& src, Condition cond) { 1396 void Assembler::ldr(Register dst, const MemOperand& src, Condition cond) {
1413 if (dst.is(pc)) { 1397 if (dst.is(pc)) {
1414 positions_recorder()->WriteRecordedPositions(); 1398 positions_recorder()->WriteRecordedPositions();
1415 } 1399 }
1416 addrmod2(cond | B26 | L, dst, src); 1400 addrmod2(cond | B26 | L, dst, src);
1417
1418 // Eliminate pattern: push(ry), pop(rx)
1419 // str(ry, MemOperand(sp, 4, NegPreIndex), al)
1420 // ldr(rx, MemOperand(sp, 4, PostIndex), al)
1421 // Both instructions can be eliminated if ry = rx.
1422 // If ry != rx, a register copy from ry to rx is inserted
1423 // after eliminating the push and the pop instructions.
1424 if (can_peephole_optimize(2)) {
1425 Instr push_instr = instr_at(pc_ - 2 * kInstrSize);
1426 Instr pop_instr = instr_at(pc_ - 1 * kInstrSize);
1427
1428 if (IsPush(push_instr) && IsPop(pop_instr)) {
1429 if (Instruction::RdValue(pop_instr) != Instruction::RdValue(push_instr)) {
1430 // For consecutive push and pop on different registers,
1431 // we delete both the push & pop and insert a register move.
1432 // push ry, pop rx --> mov rx, ry
1433 Register reg_pushed, reg_popped;
1434 reg_pushed = GetRd(push_instr);
1435 reg_popped = GetRd(pop_instr);
1436 pc_ -= 2 * kInstrSize;
1437 // Insert a mov instruction, which is better than a pair of push & pop
1438 mov(reg_popped, reg_pushed);
1439 if (FLAG_print_peephole_optimization) {
1440 PrintF("%x push/pop (diff reg) replaced by a reg move\n",
1441 pc_offset());
1442 }
1443 } else {
1444 // For consecutive push and pop on the same register,
1445 // both the push and the pop can be deleted.
1446 pc_ -= 2 * kInstrSize;
1447 if (FLAG_print_peephole_optimization) {
1448 PrintF("%x push/pop (same reg) eliminated\n", pc_offset());
1449 }
1450 }
1451 }
1452 }
1453
1454 if (can_peephole_optimize(2)) {
1455 Instr str_instr = instr_at(pc_ - 2 * kInstrSize);
1456 Instr ldr_instr = instr_at(pc_ - 1 * kInstrSize);
1457
1458 if ((IsStrRegFpOffset(str_instr) &&
1459 IsLdrRegFpOffset(ldr_instr)) ||
1460 (IsStrRegFpNegOffset(str_instr) &&
1461 IsLdrRegFpNegOffset(ldr_instr))) {
1462 if ((ldr_instr & kLdrStrInstrArgumentMask) ==
1463 (str_instr & kLdrStrInstrArgumentMask)) {
1464 // Pattern: Ldr/str same fp+offset, same register.
1465 //
1466 // The following:
1467 // str rx, [fp, #-12]
1468 // ldr rx, [fp, #-12]
1469 //
1470 // Becomes:
1471 // str rx, [fp, #-12]
1472
1473 pc_ -= 1 * kInstrSize;
1474 if (FLAG_print_peephole_optimization) {
1475 PrintF("%x str/ldr (fp + same offset), same reg\n", pc_offset());
1476 }
1477 } else if ((ldr_instr & kLdrStrOffsetMask) ==
1478 (str_instr & kLdrStrOffsetMask)) {
1479 // Pattern: Ldr/str same fp+offset, different register.
1480 //
1481 // The following:
1482 // str rx, [fp, #-12]
1483 // ldr ry, [fp, #-12]
1484 //
1485 // Becomes:
1486 // str rx, [fp, #-12]
1487 // mov ry, rx
1488
1489 Register reg_stored, reg_loaded;
1490 reg_stored = GetRd(str_instr);
1491 reg_loaded = GetRd(ldr_instr);
1492 pc_ -= 1 * kInstrSize;
1493 // Insert a mov instruction, which is better than ldr.
1494 mov(reg_loaded, reg_stored);
1495 if (FLAG_print_peephole_optimization) {
1496 PrintF("%x str/ldr (fp + same offset), diff reg \n", pc_offset());
1497 }
1498 }
1499 }
1500 }
1501
1502 if (can_peephole_optimize(3)) {
1503 Instr mem_write_instr = instr_at(pc_ - 3 * kInstrSize);
1504 Instr ldr_instr = instr_at(pc_ - 2 * kInstrSize);
1505 Instr mem_read_instr = instr_at(pc_ - 1 * kInstrSize);
1506 if (IsPush(mem_write_instr) &&
1507 IsPop(mem_read_instr)) {
1508 if ((IsLdrRegFpOffset(ldr_instr) ||
1509 IsLdrRegFpNegOffset(ldr_instr))) {
1510 if (Instruction::RdValue(mem_write_instr) ==
1511 Instruction::RdValue(mem_read_instr)) {
1512 // Pattern: push & pop from/to same register,
1513 // with a fp+offset ldr in between
1514 //
1515 // The following:
1516 // str rx, [sp, #-4]!
1517 // ldr rz, [fp, #-24]
1518 // ldr rx, [sp], #+4
1519 //
1520 // Becomes:
1521 // if(rx == rz)
1522 // delete all
1523 // else
1524 // ldr rz, [fp, #-24]
1525
1526 if (Instruction::RdValue(mem_write_instr) ==
1527 Instruction::RdValue(ldr_instr)) {
1528 pc_ -= 3 * kInstrSize;
1529 } else {
1530 pc_ -= 3 * kInstrSize;
1531 // Reinsert back the ldr rz.
1532 emit(ldr_instr);
1533 }
1534 if (FLAG_print_peephole_optimization) {
1535 PrintF("%x push/pop -dead ldr fp+offset in middle\n", pc_offset());
1536 }
1537 } else {
1538 // Pattern: push & pop from/to different registers
1539 // with a fp+offset ldr in between
1540 //
1541 // The following:
1542 // str rx, [sp, #-4]!
1543 // ldr rz, [fp, #-24]
1544 // ldr ry, [sp], #+4
1545 //
1546 // Becomes:
1547 // if(ry == rz)
1548 // mov ry, rx;
1549 // else if(rx != rz)
1550 // ldr rz, [fp, #-24]
1551 // mov ry, rx
1552 // else if((ry != rz) || (rx == rz)) becomes:
1553 // mov ry, rx
1554 // ldr rz, [fp, #-24]
1555
1556 Register reg_pushed, reg_popped;
1557 if (Instruction::RdValue(mem_read_instr) ==
1558 Instruction::RdValue(ldr_instr)) {
1559 reg_pushed = GetRd(mem_write_instr);
1560 reg_popped = GetRd(mem_read_instr);
1561 pc_ -= 3 * kInstrSize;
1562 mov(reg_popped, reg_pushed);
1563 } else if (Instruction::RdValue(mem_write_instr) !=
1564 Instruction::RdValue(ldr_instr)) {
1565 reg_pushed = GetRd(mem_write_instr);
1566 reg_popped = GetRd(mem_read_instr);
1567 pc_ -= 3 * kInstrSize;
1568 emit(ldr_instr);
1569 mov(reg_popped, reg_pushed);
1570 } else if ((Instruction::RdValue(mem_read_instr) !=
1571 Instruction::RdValue(ldr_instr)) ||
1572 (Instruction::RdValue(mem_write_instr) ==
1573 Instruction::RdValue(ldr_instr))) {
1574 reg_pushed = GetRd(mem_write_instr);
1575 reg_popped = GetRd(mem_read_instr);
1576 pc_ -= 3 * kInstrSize;
1577 mov(reg_popped, reg_pushed);
1578 emit(ldr_instr);
1579 }
1580 if (FLAG_print_peephole_optimization) {
1581 PrintF("%x push/pop (ldr fp+off in middle)\n", pc_offset());
1582 }
1583 }
1584 }
1585 }
1586 }
1587 } 1401 }
1588 1402
1589 1403
1590 void Assembler::str(Register src, const MemOperand& dst, Condition cond) { 1404 void Assembler::str(Register src, const MemOperand& dst, Condition cond) {
1591 addrmod2(cond | B26, src, dst); 1405 addrmod2(cond | B26, src, dst);
1592
1593 // Eliminate pattern: pop(), push(r)
1594 // add sp, sp, #4 LeaveCC, al; str r, [sp, #-4], al
1595 // -> str r, [sp, 0], al
1596 if (can_peephole_optimize(2) &&
1597 // Pattern.
1598 instr_at(pc_ - 1 * kInstrSize) == (kPushRegPattern | src.code() * B12) &&
1599 instr_at(pc_ - 2 * kInstrSize) == kPopInstruction) {
1600 pc_ -= 2 * kInstrSize;
1601 emit(al | B26 | 0 | Offset | sp.code() * B16 | src.code() * B12);
1602 if (FLAG_print_peephole_optimization) {
1603 PrintF("%x pop()/push(reg) eliminated\n", pc_offset());
1604 }
1605 }
1606 } 1406 }
1607 1407
1608 1408
1609 void Assembler::ldrb(Register dst, const MemOperand& src, Condition cond) { 1409 void Assembler::ldrb(Register dst, const MemOperand& src, Condition cond) {
1610 addrmod2(cond | B26 | B | L, dst, src); 1410 addrmod2(cond | B26 | B | L, dst, src);
1611 } 1411 }
1612 1412
1613 1413
1614 void Assembler::strb(Register src, const MemOperand& dst, Condition cond) { 1414 void Assembler::strb(Register src, const MemOperand& dst, Condition cond) {
1615 addrmod2(cond | B26 | B, src, dst); 1415 addrmod2(cond | B26 | B, src, dst);
(...skipping 1236 matching lines...) Expand 10 before | Expand all | Expand 10 after
2852 2652
2853 // Since a constant pool was just emitted, move the check offset forward by 2653 // Since a constant pool was just emitted, move the check offset forward by
2854 // the standard interval. 2654 // the standard interval.
2855 next_buffer_check_ = pc_offset() + kCheckConstInterval; 2655 next_buffer_check_ = pc_offset() + kCheckConstInterval;
2856 } 2656 }
2857 2657
2858 2658
2859 } } // namespace v8::internal 2659 } } // namespace v8::internal
2860 2660
2861 #endif // V8_TARGET_ARCH_ARM 2661 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/assembler-arm.h ('k') | src/ia32/assembler-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698