Commit 17c4dc86 authored by sgjesse@chromium.org's avatar sgjesse@chromium.org

MIPS: Remove peeophole optimizations from assembler.

Following r7854.

BUG=
TEST=

Review URL: http://codereview.chromium.org//7037004

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7908 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent f801756b
...@@ -240,9 +240,7 @@ static const int kMinimalBufferSize = 4 * KB; ...@@ -240,9 +240,7 @@ static const int kMinimalBufferSize = 4 * KB;
Assembler::Assembler(Isolate* arg_isolate, void* buffer, int buffer_size) Assembler::Assembler(Isolate* arg_isolate, void* buffer, int buffer_size)
: AssemblerBase(arg_isolate), : AssemblerBase(arg_isolate),
positions_recorder_(this), positions_recorder_(this),
allow_peephole_optimization_(false),
emit_debug_code_(FLAG_debug_code) { emit_debug_code_(FLAG_debug_code) {
allow_peephole_optimization_ = FLAG_peephole_optimization;
if (buffer == NULL) { if (buffer == NULL) {
// Do our own buffer management. // Do our own buffer management.
if (buffer_size <= kMinimalBufferSize) { if (buffer_size <= kMinimalBufferSize) {
...@@ -279,6 +277,7 @@ Assembler::Assembler(Isolate* arg_isolate, void* buffer, int buffer_size) ...@@ -279,6 +277,7 @@ Assembler::Assembler(Isolate* arg_isolate, void* buffer, int buffer_size)
trampoline_pool_blocked_nesting_ = 0; trampoline_pool_blocked_nesting_ = 0;
next_buffer_check_ = kMaxBranchOffset - kTrampolineSize; next_buffer_check_ = kMaxBranchOffset - kTrampolineSize;
internal_trampoline_exception_ = false; internal_trampoline_exception_ = false;
last_bound_pos_ = 0;
ast_id_for_reloc_info_ = kNoASTId; ast_id_for_reloc_info_ = kNoASTId;
} }
...@@ -1089,158 +1088,6 @@ void Assembler::addu(Register rd, Register rs, Register rt) { ...@@ -1089,158 +1088,6 @@ void Assembler::addu(Register rd, Register rs, Register rt) {
void Assembler::addiu(Register rd, Register rs, int32_t j) { void Assembler::addiu(Register rd, Register rs, int32_t j) {
GenInstrImmediate(ADDIU, rs, rd, j); GenInstrImmediate(ADDIU, rs, rd, j);
// Eliminate pattern: push(r), pop().
// addiu(sp, sp, Operand(-kPointerSize));
// sw(src, MemOperand(sp, 0);
// addiu(sp, sp, Operand(kPointerSize));
// Both instructions can be eliminated.
if (can_peephole_optimize(3) &&
// Pattern.
instr_at(pc_ - 1 * kInstrSize) == kPopInstruction &&
(instr_at(pc_ - 2 * kInstrSize) & ~kRtMask) == kPushRegPattern &&
(instr_at(pc_ - 3 * kInstrSize)) == kPushInstruction) {
pc_ -= 3 * kInstrSize;
if (FLAG_print_peephole_optimization) {
PrintF("%x push(reg)/pop() eliminated\n", pc_offset());
}
}
// Eliminate pattern: push(ry), pop(rx).
// addiu(sp, sp, -kPointerSize)
// sw(ry, MemOperand(sp, 0)
// lw(rx, MemOperand(sp, 0)
// addiu(sp, sp, kPointerSize);
// Both instructions can be eliminated if ry = rx.
// If ry != rx, a register copy from ry to rx is inserted
// after eliminating the push and the pop instructions.
if (can_peephole_optimize(4)) {
Instr pre_push_sp_set = instr_at(pc_ - 4 * kInstrSize);
Instr push_instr = instr_at(pc_ - 3 * kInstrSize);
Instr pop_instr = instr_at(pc_ - 2 * kInstrSize);
Instr post_pop_sp_set = instr_at(pc_ - 1 * kInstrSize);
if (IsPush(push_instr) &&
IsPop(pop_instr) && pre_push_sp_set == kPushInstruction &&
post_pop_sp_set == kPopInstruction) {
if ((pop_instr & kRtMask) != (push_instr & kRtMask)) {
// For consecutive push and pop on different registers,
// we delete both the push & pop and insert a register move.
// push ry, pop rx --> mov rx, ry.
Register reg_pushed, reg_popped;
reg_pushed = GetRtReg(push_instr);
reg_popped = GetRtReg(pop_instr);
pc_ -= 4 * kInstrSize;
// Insert a mov instruction, which is better than a pair of push & pop.
or_(reg_popped, reg_pushed, zero_reg);
if (FLAG_print_peephole_optimization) {
PrintF("%x push/pop (diff reg) replaced by a reg move\n",
pc_offset());
}
} else {
// For consecutive push and pop on the same register,
// both the push and the pop can be deleted.
pc_ -= 4 * kInstrSize;
if (FLAG_print_peephole_optimization) {
PrintF("%x push/pop (same reg) eliminated\n", pc_offset());
}
}
}
}
if (can_peephole_optimize(5)) {
Instr pre_push_sp_set = instr_at(pc_ - 5 * kInstrSize);
Instr mem_write_instr = instr_at(pc_ - 4 * kInstrSize);
Instr lw_instr = instr_at(pc_ - 3 * kInstrSize);
Instr mem_read_instr = instr_at(pc_ - 2 * kInstrSize);
Instr post_pop_sp_set = instr_at(pc_ - 1 * kInstrSize);
if (IsPush(mem_write_instr) &&
pre_push_sp_set == kPushInstruction &&
IsPop(mem_read_instr) &&
post_pop_sp_set == kPopInstruction) {
if ((IsLwRegFpOffset(lw_instr) ||
IsLwRegFpNegOffset(lw_instr))) {
if ((mem_write_instr & kRtMask) ==
(mem_read_instr & kRtMask)) {
// Pattern: push & pop from/to same register,
// with a fp + offset lw in between.
//
// The following:
// addiu sp, sp, -4
// sw rx, [sp, #0]!
// lw rz, [fp, #-24]
// lw rx, [sp, 0],
// addiu sp, sp, 4
//
// Becomes:
// if(rx == rz)
// delete all
// else
// lw rz, [fp, #-24]
if ((mem_write_instr & kRtMask) == (lw_instr & kRtMask)) {
pc_ -= 5 * kInstrSize;
} else {
pc_ -= 5 * kInstrSize;
// Reinsert back the lw rz.
emit(lw_instr);
}
if (FLAG_print_peephole_optimization) {
PrintF("%x push/pop -dead ldr fp + offset in middle\n",
pc_offset());
}
} else {
// Pattern: push & pop from/to different registers
// with a fp + offset lw in between.
//
// The following:
// addiu sp, sp ,-4
// sw rx, [sp, 0]
// lw rz, [fp, #-24]
// lw ry, [sp, 0]
// addiu sp, sp, 4
//
// Becomes:
// if(ry == rz)
// mov ry, rx;
// else if(rx != rz)
// lw rz, [fp, #-24]
// mov ry, rx
// else if((ry != rz) || (rx == rz)) becomes:
// mov ry, rx
// lw rz, [fp, #-24]
Register reg_pushed, reg_popped;
if ((mem_read_instr & kRtMask) == (lw_instr & kRtMask)) {
reg_pushed = GetRtReg(mem_write_instr);
reg_popped = GetRtReg(mem_read_instr);
pc_ -= 5 * kInstrSize;
or_(reg_popped, reg_pushed, zero_reg); // Move instruction.
} else if ((mem_write_instr & kRtMask)
!= (lw_instr & kRtMask)) {
reg_pushed = GetRtReg(mem_write_instr);
reg_popped = GetRtReg(mem_read_instr);
pc_ -= 5 * kInstrSize;
emit(lw_instr);
or_(reg_popped, reg_pushed, zero_reg); // Move instruction.
} else if (((mem_read_instr & kRtMask)
!= (lw_instr & kRtMask)) ||
((mem_write_instr & kRtMask)
== (lw_instr & kRtMask)) ) {
reg_pushed = GetRtReg(mem_write_instr);
reg_popped = GetRtReg(mem_read_instr);
pc_ -= 5 * kInstrSize;
or_(reg_popped, reg_pushed, zero_reg); // Move instruction.
emit(lw_instr);
}
if (FLAG_print_peephole_optimization) {
PrintF("%x push/pop (ldr fp+off in middle)\n", pc_offset());
}
}
}
}
}
} }
...@@ -1428,54 +1275,6 @@ void Assembler::lw(Register rd, const MemOperand& rs) { ...@@ -1428,54 +1275,6 @@ void Assembler::lw(Register rd, const MemOperand& rs) {
LoadRegPlusOffsetToAt(rs); LoadRegPlusOffsetToAt(rs);
GenInstrImmediate(LW, at, rd, 0); // Equiv to lw(rd, MemOperand(at, 0)); GenInstrImmediate(LW, at, rd, 0); // Equiv to lw(rd, MemOperand(at, 0));
} }
if (can_peephole_optimize(2)) {
Instr sw_instr = instr_at(pc_ - 2 * kInstrSize);
Instr lw_instr = instr_at(pc_ - 1 * kInstrSize);
if ((IsSwRegFpOffset(sw_instr) &&
IsLwRegFpOffset(lw_instr)) ||
(IsSwRegFpNegOffset(sw_instr) &&
IsLwRegFpNegOffset(lw_instr))) {
if ((lw_instr & kLwSwInstrArgumentMask) ==
(sw_instr & kLwSwInstrArgumentMask)) {
// Pattern: Lw/sw same fp+offset, same register.
//
// The following:
// sw rx, [fp, #-12]
// lw rx, [fp, #-12]
//
// Becomes:
// sw rx, [fp, #-12]
pc_ -= 1 * kInstrSize;
if (FLAG_print_peephole_optimization) {
PrintF("%x sw/lw (fp + same offset), same reg\n", pc_offset());
}
} else if ((lw_instr & kLwSwOffsetMask) ==
(sw_instr & kLwSwOffsetMask)) {
// Pattern: Lw/sw same fp+offset, different register.
//
// The following:
// sw rx, [fp, #-12]
// lw ry, [fp, #-12]
//
// Becomes:
// sw rx, [fp, #-12]
// mov ry, rx
Register reg_stored, reg_loaded;
reg_stored = GetRtReg(sw_instr);
reg_loaded = GetRtReg(lw_instr);
pc_ -= 1 * kInstrSize;
// Insert a mov instruction, which is better than lw.
or_(reg_loaded, reg_stored, zero_reg); // Move instruction.
if (FLAG_print_peephole_optimization) {
PrintF("%x sw/lw (fp + same offset), diff reg \n", pc_offset());
}
}
}
}
} }
...@@ -1516,23 +1315,6 @@ void Assembler::sw(Register rd, const MemOperand& rs) { ...@@ -1516,23 +1315,6 @@ void Assembler::sw(Register rd, const MemOperand& rs) {
LoadRegPlusOffsetToAt(rs); LoadRegPlusOffsetToAt(rs);
GenInstrImmediate(SW, at, rd, 0); // Equiv to sw(rd, MemOperand(at, 0)); GenInstrImmediate(SW, at, rd, 0); // Equiv to sw(rd, MemOperand(at, 0));
} }
// Eliminate pattern: pop(), push(r).
// addiu sp, sp, Operand(kPointerSize);
// addiu sp, sp, Operand(-kPointerSize);
// -> sw r, MemOpernad(sp, 0);
if (can_peephole_optimize(3) &&
// Pattern.
instr_at(pc_ - 1 * kInstrSize) ==
(kPushRegPattern | (rd.code() << kRtShift)) &&
instr_at(pc_ - 2 * kInstrSize) == kPushInstruction &&
instr_at(pc_ - 3 * kInstrSize) == kPopInstruction) {
pc_ -= 3 * kInstrSize;
GenInstrImmediate(SW, rs.rm(), rd, rs.offset_);
if (FLAG_print_peephole_optimization) {
PrintF("%x pop()/push(reg) eliminated\n", pc_offset());
}
}
} }
......
...@@ -816,12 +816,6 @@ class Assembler : public AssemblerBase { ...@@ -816,12 +816,6 @@ class Assembler : public AssemblerBase {
PositionsRecorder* positions_recorder() { return &positions_recorder_; } PositionsRecorder* positions_recorder() { return &positions_recorder_; }
bool can_peephole_optimize(int instructions) {
if (!allow_peephole_optimization_) return false;
if (last_bound_pos_ > pc_offset() - instructions * kInstrSize) return false;
return reloc_info_writer.last_pc() <= pc_ - instructions * kInstrSize;
}
// Postpone the generation of the trampoline pool for the specified number of // Postpone the generation of the trampoline pool for the specified number of
// instructions. // instructions.
void BlockTrampolinePoolFor(int instructions); void BlockTrampolinePoolFor(int instructions);
...@@ -1126,7 +1120,6 @@ class Assembler : public AssemblerBase { ...@@ -1126,7 +1120,6 @@ class Assembler : public AssemblerBase {
friend class BlockTrampolinePoolScope; friend class BlockTrampolinePoolScope;
PositionsRecorder positions_recorder_; PositionsRecorder positions_recorder_;
bool allow_peephole_optimization_;
bool emit_debug_code_; bool emit_debug_code_;
friend class PositionsRecorder; friend class PositionsRecorder;
friend class EnsureSpace; friend class EnsureSpace;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment