Commit f665c823 authored by mythria's avatar mythria Committed by Commit bot

[Interpreter] Adds an optimization to remove redundant Ldar/Star.

Adds an optimization to omit generating Ldar/Star if the same register
is loaded or stored from the accumulator in the earlier instruction.

BUG=v8:4280
LOG=N

Review URL: https://codereview.chromium.org/1435283002

Cr-Commit-Position: refs/heads/master@{#31984}
parent 24e058d0
......@@ -271,18 +271,18 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadFalse() {
BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister(
Register reg) {
// TODO(oth): Avoid loading the accumulator with the register if the
// previous bytecode stored the accumulator with the same register.
Output(Bytecode::kLdar, reg.ToOperand());
if (!IsRegisterInAccumulator(reg)) {
Output(Bytecode::kLdar, reg.ToOperand());
}
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister(
Register reg) {
// TODO(oth): Avoid storing the accumulator in the register if the
// previous bytecode loaded the accumulator with the same register.
Output(Bytecode::kStar, reg.ToOperand());
if (!IsRegisterInAccumulator(reg)) {
Output(Bytecode::kStar, reg.ToOperand());
}
return *this;
}
......@@ -952,12 +952,29 @@ bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, int operand_index,
return false;
}
bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const {
return last_bytecode_start_ < bytecodes()->size() &&
last_bytecode_start_ >= last_block_end_;
}
bool BytecodeArrayBuilder::IsRegisterInAccumulator(Register reg) {
if (!LastBytecodeInSameBlock()) return false;
Bytecode previous_bytecode =
Bytecodes::FromByte(bytecodes()->at(last_bytecode_start_));
if (previous_bytecode == Bytecode::kLdar ||
previous_bytecode == Bytecode::kStar) {
size_t operand_offset = last_bytecode_start_ +
Bytecodes::GetOperandOffset(previous_bytecode, 0);
if (reg == Register::FromOperand(bytecodes()->at(operand_offset))) {
return true;
}
}
return false;
}
// static
Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) {
switch (op) {
......
......@@ -251,6 +251,7 @@ class BytecodeArrayBuilder {
bool LastBytecodeInSameBlock() const;
bool NeedToBooleanCast();
bool IsRegisterInAccumulator(Register reg);
int BorrowTemporaryRegister();
void ReturnTemporaryRegister(int reg_index);
......
......@@ -658,7 +658,7 @@ void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
BytecodeLabel body_label, condition_label, done_label;
if (stmt->cond()->ToBooleanIsFalse()) {
// If the condition is false there is no need to generating the loop.
// If the condition is false there is no need to generate the loop.
return;
}
......
......@@ -39,9 +39,12 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
.LoadTrue()
.LoadFalse();
// Emit accumulator transfers.
// Emit accumulator transfers. Stores followed by loads to the same register
// are not generated. Hence, a dummy instruction in between.
Register reg(0);
builder.LoadAccumulatorWithRegister(reg).StoreAccumulatorInRegister(reg);
builder.LoadAccumulatorWithRegister(reg)
.LoadNull()
.StoreAccumulatorInRegister(reg);
// Emit global load / store operations.
builder.LoadGlobal(0, 1, LanguageMode::SLOPPY, TypeofMode::NOT_INSIDE_TYPEOF)
......
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