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() { ...@@ -271,18 +271,18 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadFalse() {
BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister( BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister(
Register reg) { Register reg) {
// TODO(oth): Avoid loading the accumulator with the register if the if (!IsRegisterInAccumulator(reg)) {
// previous bytecode stored the accumulator with the same register. Output(Bytecode::kLdar, reg.ToOperand());
Output(Bytecode::kLdar, reg.ToOperand()); }
return *this; return *this;
} }
BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister( BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister(
Register reg) { Register reg) {
// TODO(oth): Avoid storing the accumulator in the register if the if (!IsRegisterInAccumulator(reg)) {
// previous bytecode loaded the accumulator with the same register. Output(Bytecode::kStar, reg.ToOperand());
Output(Bytecode::kStar, reg.ToOperand()); }
return *this; return *this;
} }
...@@ -952,12 +952,29 @@ bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, int operand_index, ...@@ -952,12 +952,29 @@ bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, int operand_index,
return false; return false;
} }
bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const { bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const {
return last_bytecode_start_ < bytecodes()->size() && return last_bytecode_start_ < bytecodes()->size() &&
last_bytecode_start_ >= last_block_end_; 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 // static
Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) { Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) {
switch (op) { switch (op) {
......
...@@ -251,6 +251,7 @@ class BytecodeArrayBuilder { ...@@ -251,6 +251,7 @@ class BytecodeArrayBuilder {
bool LastBytecodeInSameBlock() const; bool LastBytecodeInSameBlock() const;
bool NeedToBooleanCast(); bool NeedToBooleanCast();
bool IsRegisterInAccumulator(Register reg);
int BorrowTemporaryRegister(); int BorrowTemporaryRegister();
void ReturnTemporaryRegister(int reg_index); void ReturnTemporaryRegister(int reg_index);
......
...@@ -658,7 +658,7 @@ void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) { ...@@ -658,7 +658,7 @@ void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
BytecodeLabel body_label, condition_label, done_label; BytecodeLabel body_label, condition_label, done_label;
if (stmt->cond()->ToBooleanIsFalse()) { 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; return;
} }
......
...@@ -39,9 +39,12 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) { ...@@ -39,9 +39,12 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
.LoadTrue() .LoadTrue()
.LoadFalse(); .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); Register reg(0);
builder.LoadAccumulatorWithRegister(reg).StoreAccumulatorInRegister(reg); builder.LoadAccumulatorWithRegister(reg)
.LoadNull()
.StoreAccumulatorInRegister(reg);
// Emit global load / store operations. // Emit global load / store operations.
builder.LoadGlobal(0, 1, LanguageMode::SLOPPY, TypeofMode::NOT_INSIDE_TYPEOF) 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