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

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

Issue 2104006: Push/pop is just one peephole optimization. Puth them all... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 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/flag-definitions.h ('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) 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 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 void Assembler::push(const Operand& src) { 426 void Assembler::push(const Operand& src) {
427 EnsureSpace ensure_space(this); 427 EnsureSpace ensure_space(this);
428 last_pc_ = pc_; 428 last_pc_ = pc_;
429 EMIT(0xFF); 429 EMIT(0xFF);
430 emit_operand(esi, src); 430 emit_operand(esi, src);
431 } 431 }
432 432
433 433
434 void Assembler::pop(Register dst) { 434 void Assembler::pop(Register dst) {
435 ASSERT(reloc_info_writer.last_pc() != NULL); 435 ASSERT(reloc_info_writer.last_pc() != NULL);
436 if (FLAG_push_pop_elimination && (reloc_info_writer.last_pc() <= last_pc_)) { 436 if (FLAG_peephole_optimization && (reloc_info_writer.last_pc() <= last_pc_)) {
437 // (last_pc_ != NULL) is rolled into the above check. 437 // (last_pc_ != NULL) is rolled into the above check.
438 // If a last_pc_ is set, we need to make sure that there has not been any 438 // If a last_pc_ is set, we need to make sure that there has not been any
439 // relocation information generated between the last instruction and this 439 // relocation information generated between the last instruction and this
440 // pop instruction. 440 // pop instruction.
441 byte instr = last_pc_[0]; 441 byte instr = last_pc_[0];
442 if ((instr & ~0x7) == 0x50) { 442 if ((instr & ~0x7) == 0x50) {
443 int push_reg_code = instr & 0x7; 443 int push_reg_code = instr & 0x7;
444 if (push_reg_code == dst.code()) { 444 if (push_reg_code == dst.code()) {
445 pc_ = last_pc_; 445 pc_ = last_pc_;
446 if (FLAG_print_push_pop_elimination) { 446 if (FLAG_print_peephole_optimization) {
447 PrintF("%d push/pop (same reg) eliminated\n", pc_offset()); 447 PrintF("%d push/pop (same reg) eliminated\n", pc_offset());
448 } 448 }
449 } else { 449 } else {
450 // Convert 'push src; pop dst' to 'mov dst, src'. 450 // Convert 'push src; pop dst' to 'mov dst, src'.
451 last_pc_[0] = 0x8b; 451 last_pc_[0] = 0x8b;
452 Register src = { push_reg_code }; 452 Register src = { push_reg_code };
453 EnsureSpace ensure_space(this); 453 EnsureSpace ensure_space(this);
454 emit_operand(dst, Operand(src)); 454 emit_operand(dst, Operand(src));
455 if (FLAG_print_push_pop_elimination) { 455 if (FLAG_print_peephole_optimization) {
456 PrintF("%d push/pop (reg->reg) eliminated\n", pc_offset()); 456 PrintF("%d push/pop (reg->reg) eliminated\n", pc_offset());
457 } 457 }
458 } 458 }
459 last_pc_ = NULL; 459 last_pc_ = NULL;
460 return; 460 return;
461 } else if (instr == 0xff) { // push of an operand, convert to a move 461 } else if (instr == 0xff) { // push of an operand, convert to a move
462 byte op1 = last_pc_[1]; 462 byte op1 = last_pc_[1];
463 // Check if the operation is really a push. 463 // Check if the operation is really a push.
464 if ((op1 & 0x38) == (6 << 3)) { 464 if ((op1 & 0x38) == (6 << 3)) {
465 op1 = (op1 & ~0x38) | static_cast<byte>(dst.code() << 3); 465 op1 = (op1 & ~0x38) | static_cast<byte>(dst.code() << 3);
466 last_pc_[0] = 0x8b; 466 last_pc_[0] = 0x8b;
467 last_pc_[1] = op1; 467 last_pc_[1] = op1;
468 last_pc_ = NULL; 468 last_pc_ = NULL;
469 if (FLAG_print_push_pop_elimination) { 469 if (FLAG_print_peephole_optimization) {
470 PrintF("%d push/pop (op->reg) eliminated\n", pc_offset()); 470 PrintF("%d push/pop (op->reg) eliminated\n", pc_offset());
471 } 471 }
472 return; 472 return;
473 } 473 }
474 } else if ((instr == 0x89) && 474 } else if ((instr == 0x89) &&
475 (last_pc_[1] == 0x04) && 475 (last_pc_[1] == 0x04) &&
476 (last_pc_[2] == 0x24)) { 476 (last_pc_[2] == 0x24)) {
477 // 0x71283c 396 890424 mov [esp],eax 477 // 0x71283c 396 890424 mov [esp],eax
478 // 0x71283f 399 58 pop eax 478 // 0x71283f 399 58 pop eax
479 if (dst.is(eax)) { 479 if (dst.is(eax)) {
480 // change to 480 // change to
481 // 0x710fac 216 83c404 add esp,0x4 481 // 0x710fac 216 83c404 add esp,0x4
482 last_pc_[0] = 0x83; 482 last_pc_[0] = 0x83;
483 last_pc_[1] = 0xc4; 483 last_pc_[1] = 0xc4;
484 last_pc_[2] = 0x04; 484 last_pc_[2] = 0x04;
485 last_pc_ = NULL; 485 last_pc_ = NULL;
486 if (FLAG_print_push_pop_elimination) { 486 if (FLAG_print_peephole_optimization) {
487 PrintF("%d push/pop (mov-pop) eliminated\n", pc_offset()); 487 PrintF("%d push/pop (mov-pop) eliminated\n", pc_offset());
488 } 488 }
489 return; 489 return;
490 } 490 }
491 } else if (instr == 0x6a && dst.is(eax)) { // push of immediate 8 bit 491 } else if (instr == 0x6a && dst.is(eax)) { // push of immediate 8 bit
492 byte imm8 = last_pc_[1]; 492 byte imm8 = last_pc_[1];
493 if (imm8 == 0) { 493 if (imm8 == 0) {
494 // 6a00 push 0x0 494 // 6a00 push 0x0
495 // 58 pop eax 495 // 58 pop eax
496 last_pc_[0] = 0x31; 496 last_pc_[0] = 0x31;
497 last_pc_[1] = 0xc0; 497 last_pc_[1] = 0xc0;
498 // change to 498 // change to
499 // 31c0 xor eax,eax 499 // 31c0 xor eax,eax
500 last_pc_ = NULL; 500 last_pc_ = NULL;
501 if (FLAG_print_push_pop_elimination) { 501 if (FLAG_print_peephole_optimization) {
502 PrintF("%d push/pop (imm->reg) eliminated\n", pc_offset()); 502 PrintF("%d push/pop (imm->reg) eliminated\n", pc_offset());
503 } 503 }
504 return; 504 return;
505 } else { 505 } else {
506 // 6a00 push 0xXX 506 // 6a00 push 0xXX
507 // 58 pop eax 507 // 58 pop eax
508 last_pc_[0] = 0xb8; 508 last_pc_[0] = 0xb8;
509 EnsureSpace ensure_space(this); 509 EnsureSpace ensure_space(this);
510 if ((imm8 & 0x80) != 0) { 510 if ((imm8 & 0x80) != 0) {
511 EMIT(0xff); 511 EMIT(0xff);
512 EMIT(0xff); 512 EMIT(0xff);
513 EMIT(0xff); 513 EMIT(0xff);
514 // change to 514 // change to
515 // b8XXffffff mov eax,0xffffffXX 515 // b8XXffffff mov eax,0xffffffXX
516 } else { 516 } else {
517 EMIT(0x00); 517 EMIT(0x00);
518 EMIT(0x00); 518 EMIT(0x00);
519 EMIT(0x00); 519 EMIT(0x00);
520 // change to 520 // change to
521 // b8XX000000 mov eax,0x000000XX 521 // b8XX000000 mov eax,0x000000XX
522 } 522 }
523 last_pc_ = NULL; 523 last_pc_ = NULL;
524 if (FLAG_print_push_pop_elimination) { 524 if (FLAG_print_peephole_optimization) {
525 PrintF("%d push/pop (imm->reg) eliminated\n", pc_offset()); 525 PrintF("%d push/pop (imm->reg) eliminated\n", pc_offset());
526 } 526 }
527 return; 527 return;
528 } 528 }
529 } else if (instr == 0x68 && dst.is(eax)) { // push of immediate 32 bit 529 } else if (instr == 0x68 && dst.is(eax)) { // push of immediate 32 bit
530 // 68XXXXXXXX push 0xXXXXXXXX 530 // 68XXXXXXXX push 0xXXXXXXXX
531 // 58 pop eax 531 // 58 pop eax
532 last_pc_[0] = 0xb8; 532 last_pc_[0] = 0xb8;
533 last_pc_ = NULL; 533 last_pc_ = NULL;
534 // change to 534 // change to
535 // b8XXXXXXXX mov eax,0xXXXXXXXX 535 // b8XXXXXXXX mov eax,0xXXXXXXXX
536 if (FLAG_print_push_pop_elimination) { 536 if (FLAG_print_peephole_optimization) {
537 PrintF("%d push/pop (imm->reg) eliminated\n", pc_offset()); 537 PrintF("%d push/pop (imm->reg) eliminated\n", pc_offset());
538 } 538 }
539 return; 539 return;
540 } 540 }
541 541
542 // Other potential patterns for peephole: 542 // Other potential patterns for peephole:
543 // 0x712716 102 890424 mov [esp], eax 543 // 0x712716 102 890424 mov [esp], eax
544 // 0x712719 105 8b1424 mov edx, [esp] 544 // 0x712719 105 8b1424 mov edx, [esp]
545 } 545 }
546 EnsureSpace ensure_space(this); 546 EnsureSpace ensure_space(this);
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
806 void Assembler::add(Register dst, const Operand& src) { 806 void Assembler::add(Register dst, const Operand& src) {
807 EnsureSpace ensure_space(this); 807 EnsureSpace ensure_space(this);
808 last_pc_ = pc_; 808 last_pc_ = pc_;
809 EMIT(0x03); 809 EMIT(0x03);
810 emit_operand(dst, src); 810 emit_operand(dst, src);
811 } 811 }
812 812
813 813
814 void Assembler::add(const Operand& dst, const Immediate& x) { 814 void Assembler::add(const Operand& dst, const Immediate& x) {
815 ASSERT(reloc_info_writer.last_pc() != NULL); 815 ASSERT(reloc_info_writer.last_pc() != NULL);
816 if (FLAG_push_pop_elimination && (reloc_info_writer.last_pc() <= last_pc_)) { 816 if (FLAG_peephole_optimization && (reloc_info_writer.last_pc() <= last_pc_)) {
817 byte instr = last_pc_[0]; 817 byte instr = last_pc_[0];
818 if ((instr & 0xf8) == 0x50) { 818 if ((instr & 0xf8) == 0x50) {
819 // Last instruction was a push. Check whether this is a pop without a 819 // Last instruction was a push. Check whether this is a pop without a
820 // result. 820 // result.
821 if ((dst.is_reg(esp)) && 821 if ((dst.is_reg(esp)) &&
822 (x.x_ == kPointerSize) && (x.rmode_ == RelocInfo::NONE)) { 822 (x.x_ == kPointerSize) && (x.rmode_ == RelocInfo::NONE)) {
823 pc_ = last_pc_; 823 pc_ = last_pc_;
824 last_pc_ = NULL; 824 last_pc_ = NULL;
825 if (FLAG_print_push_pop_elimination) { 825 if (FLAG_print_peephole_optimization) {
826 PrintF("%d push/pop(noreg) eliminated\n", pc_offset()); 826 PrintF("%d push/pop(noreg) eliminated\n", pc_offset());
827 } 827 }
828 return; 828 return;
829 } 829 }
830 } 830 }
831 } 831 }
832 EnsureSpace ensure_space(this); 832 EnsureSpace ensure_space(this);
833 last_pc_ = pc_; 833 last_pc_ = pc_;
834 emit_arith(0, dst, x); 834 emit_arith(0, dst, x);
835 } 835 }
(...skipping 1685 matching lines...) Expand 10 before | Expand all | Expand 10 after
2521 push_insn[1] = 13; // Skip over coverage insns. 2521 push_insn[1] = 13; // Skip over coverage insns.
2522 if (coverage_log != NULL) { 2522 if (coverage_log != NULL) {
2523 fprintf(coverage_log, "%s\n", file_line); 2523 fprintf(coverage_log, "%s\n", file_line);
2524 fflush(coverage_log); 2524 fflush(coverage_log);
2525 } 2525 }
2526 } 2526 }
2527 2527
2528 #endif 2528 #endif
2529 2529
2530 } } // namespace v8::internal 2530 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/flag-definitions.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698