Commit f633218b authored by rmcilroy's avatar rmcilroy Committed by Commit bot

[Interpreter] Remove all Ldr style bytecodes and replace with Star lookahead.

We seem to get some small wins from avoiding the Ldr bytecodes, probably due
to reduced icache pressure since there are less bytecode handlers. Replace
the Ldr bytecodes with Star lookahead inlined into the Lda versions.

Also fixes IsAccumulatorLoadWithoutEffects to include LdaContextSlot and
LdaCurrentContextSlot

BUG=v8:4280

Review-Url: https://codereview.chromium.org/2489513005
Cr-Commit-Position: refs/heads/master@{#40883}
parent 6aa16edf
......@@ -708,11 +708,6 @@ void BytecodeGraphBuilder::VisitLdaUndefined() {
environment()->BindAccumulator(node);
}
void BytecodeGraphBuilder::VisitLdrUndefined() {
Node* node = jsgraph()->UndefinedConstant();
environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), node);
}
void BytecodeGraphBuilder::VisitLdaNull() {
Node* node = jsgraph()->NullConstant();
environment()->BindAccumulator(node);
......@@ -767,14 +762,6 @@ void BytecodeGraphBuilder::VisitLdaGlobal() {
environment()->BindAccumulator(node, Environment::kAttachFrameState);
}
void BytecodeGraphBuilder::VisitLdrGlobal() {
PrepareEagerCheckpoint();
Node* node = BuildLoadGlobal(bytecode_iterator().GetIndexOperand(0),
TypeofMode::NOT_INSIDE_TYPEOF);
environment()->BindRegister(bytecode_iterator().GetRegisterOperand(1), node,
Environment::kAttachFrameState);
}
void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeof() {
PrepareEagerCheckpoint();
Node* node = BuildLoadGlobal(bytecode_iterator().GetIndexOperand(0),
......@@ -803,7 +790,7 @@ void BytecodeGraphBuilder::VisitStaGlobalStrict() {
BuildStoreGlobal(LanguageMode::STRICT);
}
Node* BytecodeGraphBuilder::BuildLoadContextSlot() {
void BytecodeGraphBuilder::VisitLdaContextSlot() {
// TODO(mythria): immutable flag is also set to false. This information is not
// available in bytecode array. update this code when the implementation
// changes.
......@@ -812,39 +799,21 @@ Node* BytecodeGraphBuilder::BuildLoadContextSlot() {
bytecode_iterator().GetIndexOperand(1), false);
Node* context =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
return NewNode(op, context);
Node* node = NewNode(op, context);
environment()->BindAccumulator(node);
}
Node* BytecodeGraphBuilder::BuildLoadCurrentContextSlot() {
void BytecodeGraphBuilder::VisitLdaCurrentContextSlot() {
// TODO(mythria): immutable flag is also set to false. This information is not
// available in bytecode array. update this code when the implementation
// changes.
const Operator* op = javascript()->LoadContext(
0, bytecode_iterator().GetIndexOperand(0), false);
Node* context = environment()->Context();
return NewNode(op, context);
}
void BytecodeGraphBuilder::VisitLdaContextSlot() {
Node* node = BuildLoadContextSlot();
Node* node = NewNode(op, context);
environment()->BindAccumulator(node);
}
void BytecodeGraphBuilder::VisitLdaCurrentContextSlot() {
Node* node = BuildLoadCurrentContextSlot();
environment()->BindAccumulator(node);
}
void BytecodeGraphBuilder::VisitLdrContextSlot() {
Node* node = BuildLoadContextSlot();
environment()->BindRegister(bytecode_iterator().GetRegisterOperand(3), node);
}
void BytecodeGraphBuilder::VisitLdrCurrentContextSlot() {
Node* node = BuildLoadCurrentContextSlot();
environment()->BindRegister(bytecode_iterator().GetRegisterOperand(1), node);
}
void BytecodeGraphBuilder::VisitStaContextSlot() {
const Operator* op = javascript()->StoreContext(
bytecode_iterator().GetUnsignedImmediateOperand(2),
......
......@@ -134,8 +134,6 @@ class BytecodeGraphBuilder {
void ClearNonLiveSlotsInFrameStates();
void BuildCreateArguments(CreateArgumentsType type);
Node* BuildLoadContextSlot();
Node* BuildLoadCurrentContextSlot();
Node* BuildLoadGlobal(uint32_t feedback_slot_index, TypeofMode typeof_mode);
void BuildStoreGlobal(LanguageMode language_mode);
void BuildNamedStore(LanguageMode language_mode);
......
......@@ -116,24 +116,6 @@ bool BytecodePeepholeOptimizer::CanElideLastBasedOnSourcePosition(
namespace {
void TransformLdaStarToLdrLdar(Bytecode new_bytecode, BytecodeNode* const last,
BytecodeNode* const current) {
DCHECK_EQ(current->bytecode(), Bytecode::kStar);
//
// An example transformation here would be:
//
// LdaGlobal i0, i1 ____\ LdrGlobal i0, i1, R
// Star R ====/ Ldar R
//
// which loads a global value into both a register and the
// accumulator. However, in the second form the Ldar can often be
// peephole optimized away unlike the Star in the first form.
//
last->Transform(new_bytecode, current->operand(0));
current->set_bytecode(Bytecode::kLdar, current->operand(0));
}
void TransformLdaSmiBinaryOpToBinaryOpWithSmi(Bytecode new_bytecode,
BytecodeNode* const last,
BytecodeNode* const current) {
......@@ -239,17 +221,6 @@ void BytecodePeepholeOptimizer::ChangeBytecodeAction(
DefaultAction(node);
}
void BytecodePeepholeOptimizer::TransformLdaStarToLdrLdarAction(
BytecodeNode* const node, const PeepholeActionAndData* action_data) {
DCHECK(LastIsValid());
DCHECK(!Bytecodes::IsJump(node->bytecode()));
if (!node->source_info().is_statement()) {
TransformLdaStarToLdrLdar(action_data->bytecode, last(), node);
}
DefaultAction(node);
}
void BytecodePeepholeOptimizer::TransformLdaSmiBinaryOpToBinaryOpWithSmiAction(
BytecodeNode* const node, const PeepholeActionAndData* action_data) {
DCHECK(LastIsValid());
......
......@@ -19,7 +19,6 @@ namespace interpreter {
V(ElideCurrentIfOperand0MatchesAction) \
V(ElideLastAction) \
V(ChangeBytecodeAction) \
V(TransformLdaStarToLdrLdarAction) \
V(TransformLdaSmiBinaryOpToBinaryOpWithSmiAction) \
V(TransformLdaZeroBinaryOpToBinaryOpWithZeroAction)
......
......@@ -211,8 +211,12 @@ bool Bytecodes::IsStarLookahead(Bytecode bytecode, OperandScale operand_scale) {
case Bytecode::kLdaNull:
case Bytecode::kLdaTheHole:
case Bytecode::kLdaConstant:
case Bytecode::kLdaUndefined:
case Bytecode::kLdaGlobal:
case Bytecode::kLdaNamedProperty:
case Bytecode::kLdaKeyedProperty:
case Bytecode::kLdaContextSlot:
case Bytecode::kLdaCurrentContextSlot:
case Bytecode::kAdd:
case Bytecode::kSub:
case Bytecode::kMul:
......
......@@ -37,12 +37,8 @@ namespace interpreter {
V(LdaFalse, AccumulatorUse::kWrite) \
V(LdaConstant, AccumulatorUse::kWrite, OperandType::kIdx) \
\
/* Loading registers */ \
V(LdrUndefined, AccumulatorUse::kNone, OperandType::kRegOut) \
\
/* Globals */ \
V(LdaGlobal, AccumulatorUse::kWrite, OperandType::kIdx) \
V(LdrGlobal, AccumulatorUse::kNone, OperandType::kIdx, OperandType::kRegOut) \
V(LdaGlobalInsideTypeof, AccumulatorUse::kWrite, OperandType::kIdx) \
V(StaGlobalSloppy, AccumulatorUse::kRead, OperandType::kIdx, \
OperandType::kIdx) \
......@@ -55,10 +51,6 @@ namespace interpreter {
V(LdaContextSlot, AccumulatorUse::kWrite, OperandType::kReg, \
OperandType::kIdx, OperandType::kUImm) \
V(LdaCurrentContextSlot, AccumulatorUse::kWrite, OperandType::kIdx) \
V(LdrContextSlot, AccumulatorUse::kNone, OperandType::kReg, \
OperandType::kIdx, OperandType::kUImm, OperandType::kRegOut) \
V(LdrCurrentContextSlot, AccumulatorUse::kNone, OperandType::kIdx, \
OperandType::kRegOut) \
V(StaContextSlot, AccumulatorUse::kRead, OperandType::kReg, \
OperandType::kIdx, OperandType::kUImm) \
V(StaCurrentContextSlot, AccumulatorUse::kRead, OperandType::kIdx) \
......@@ -430,15 +422,16 @@ class V8_EXPORT_PRIVATE Bytecodes final {
bytecode == Bytecode::kLdaTrue || bytecode == Bytecode::kLdaFalse ||
bytecode == Bytecode::kLdaUndefined ||
bytecode == Bytecode::kLdaTheHole ||
bytecode == Bytecode::kLdaConstant;
bytecode == Bytecode::kLdaConstant ||
bytecode == Bytecode::kLdaContextSlot ||
bytecode == Bytecode::kLdaCurrentContextSlot;
}
// Return true if |bytecode| is a register load without effects,
// e.g. Mov, Star, LdrUndefined.
// e.g. Mov, Star.
static CONSTEXPR bool IsRegisterLoadWithoutEffects(Bytecode bytecode) {
return bytecode == Bytecode::kMov || bytecode == Bytecode::kPopContext ||
bytecode == Bytecode::kPushContext || bytecode == Bytecode::kStar ||
bytecode == Bytecode::kLdrUndefined;
bytecode == Bytecode::kPushContext || bytecode == Bytecode::kStar;
}
// Returns true if the bytecode is a conditional jump taking
......
......@@ -352,17 +352,6 @@ void Interpreter::DoLdaUndefined(InterpreterAssembler* assembler) {
__ Dispatch();
}
// LdrUndefined <reg>
//
// Loads undefined into the accumulator and |reg|.
void Interpreter::DoLdrUndefined(InterpreterAssembler* assembler) {
Node* undefined_value =
__ HeapConstant(isolate_->factory()->undefined_value());
Node* destination = __ BytecodeOperandReg(0);
__ StoreRegister(undefined_value, destination);
__ Dispatch();
}
// LdaNull
//
// Load Null into the accumulator.
......@@ -460,23 +449,6 @@ void Interpreter::DoLdaGlobal(InterpreterAssembler* assembler) {
__ Dispatch();
}
// LdrGlobal <slot> <reg>
//
// Load the global with name in constant pool entry <name_index> into
// register <reg> using FeedBackVector slot <slot> outside of a typeof.
void Interpreter::DoLdrGlobal(InterpreterAssembler* assembler) {
Callable ic =
CodeFactory::LoadGlobalICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF);
Node* context = __ GetContext();
Node* raw_slot = __ BytecodeOperandIdx(0);
Node* result = BuildLoadGlobal(ic, context, raw_slot, assembler);
Node* destination = __ BytecodeOperandReg(1);
__ StoreRegister(result, destination);
__ Dispatch();
}
// LdaGlobalInsideTypeof <slot>
//
// Load the global with name in constant pool entry <name_index> into the
......@@ -534,29 +506,17 @@ void Interpreter::DoStaGlobalStrict(InterpreterAssembler* assembler) {
DoStaGlobal(ic, assembler);
}
compiler::Node* Interpreter::BuildLoadContextSlot(
InterpreterAssembler* assembler) {
Node* reg_index = __ BytecodeOperandReg(0);
Node* context = __ LoadRegister(reg_index);
Node* slot_index = __ BytecodeOperandIdx(1);
Node* depth = __ BytecodeOperandUImm(2);
Node* slot_context = __ GetContextAtDepth(context, depth);
return __ LoadContextElement(slot_context, slot_index);
}
compiler::Node* Interpreter::BuildLoadCurrentContextSlot(
InterpreterAssembler* assembler) {
Node* slot_index = __ BytecodeOperandIdx(0);
Node* slot_context = __ GetContext();
return __ LoadContextElement(slot_context, slot_index);
}
// LdaContextSlot <context> <slot_index> <depth>
//
// Load the object in |slot_index| of the context at |depth| in the context
// chain starting at |context| into the accumulator.
void Interpreter::DoLdaContextSlot(InterpreterAssembler* assembler) {
Node* result = BuildLoadContextSlot(assembler);
Node* reg_index = __ BytecodeOperandReg(0);
Node* context = __ LoadRegister(reg_index);
Node* slot_index = __ BytecodeOperandIdx(1);
Node* depth = __ BytecodeOperandUImm(2);
Node* slot_context = __ GetContextAtDepth(context, depth);
Node* result = __ LoadContextElement(slot_context, slot_index);
__ SetAccumulator(result);
__ Dispatch();
}
......@@ -565,32 +525,13 @@ void Interpreter::DoLdaContextSlot(InterpreterAssembler* assembler) {
//
// Load the object in |slot_index| of the current context into the accumulator.
void Interpreter::DoLdaCurrentContextSlot(InterpreterAssembler* assembler) {
Node* result = BuildLoadCurrentContextSlot(assembler);
Node* slot_index = __ BytecodeOperandIdx(0);
Node* slot_context = __ GetContext();
Node* result = __ LoadContextElement(slot_context, slot_index);
__ SetAccumulator(result);
__ Dispatch();
}
// LdrContextSlot <context> <slot_index> <depth> <reg>
//
// Load the object in |slot_index| of the context at |depth| in the context
// chain of |context| into register |reg|.
void Interpreter::DoLdrContextSlot(InterpreterAssembler* assembler) {
Node* result = BuildLoadContextSlot(assembler);
Node* destination = __ BytecodeOperandReg(3);
__ StoreRegister(result, destination);
__ Dispatch();
}
// LdrCurrentContextSlot <slot_index> <reg>
//
// Load the object in |slot_index| of the current context into register |reg|.
void Interpreter::DoLdrCurrentContextSlot(InterpreterAssembler* assembler) {
Node* result = BuildLoadCurrentContextSlot(assembler);
Node* destination = __ BytecodeOperandReg(1);
__ StoreRegister(result, destination);
__ Dispatch();
}
// StaContextSlot <context> <slot_index> <depth>
//
// Stores the object in the accumulator into |slot_index| of the context at
......
......@@ -139,12 +139,6 @@ class Interpreter {
void DoStaLookupSlot(LanguageMode language_mode,
InterpreterAssembler* assembler);
// Generates code to load a context slot.
compiler::Node* BuildLoadContextSlot(InterpreterAssembler* assembler);
// Generates code to load a slot in the current context.
compiler::Node* BuildLoadCurrentContextSlot(InterpreterAssembler* assembler);
// Generates code to load a global.
compiler::Node* BuildLoadGlobal(Callable ic, compiler::Node* context,
compiler::Node* feedback_slot,
......
......@@ -79,30 +79,6 @@ const char* PeepholeActionTableWriter::kNamespaceElements[] = {"v8", "internal",
// static
PeepholeActionAndData PeepholeActionTableWriter::LookupActionAndData(
Bytecode last, Bytecode current) {
// Optimize various accumulator loads followed by store accumulator
// to an equivalent register load and loading the accumulator with
// the register. The latter accumulator load can often be elided as
// it is side-effect free and often followed by another accumulator
// load so can be elided.
if (current == Bytecode::kStar) {
switch (last) {
case Bytecode::kLdaGlobal:
return {PeepholeAction::kTransformLdaStarToLdrLdarAction,
Bytecode::kLdrGlobal};
case Bytecode::kLdaContextSlot:
return {PeepholeAction::kTransformLdaStarToLdrLdarAction,
Bytecode::kLdrContextSlot};
case Bytecode::kLdaCurrentContextSlot:
return {PeepholeAction::kTransformLdaStarToLdrLdarAction,
Bytecode::kLdrCurrentContextSlot};
case Bytecode::kLdaUndefined:
return {PeepholeAction::kTransformLdaStarToLdrLdarAction,
Bytecode::kLdrUndefined};
default:
break;
}
}
// ToName bytecodes can be replaced by Star with the same output register if
// the value in the accumulator is already a name.
if (current == Bytecode::kToName && Bytecodes::PutsNameInAccumulator(last)) {
......
......@@ -14,11 +14,13 @@ snippet: "
"
frame size: 2
parameter count: 1
bytecode array length: 12
bytecode array length: 14
bytecodes: [
/* 27 E> */ B(StackCheck),
/* 32 S> */ B(LdrUndefined), R(1),
B(LdrGlobal), U8(4), R(0),
/* 32 S> */ B(LdaUndefined),
B(Star), R(1),
B(LdaGlobal), U8(4),
B(Star), R(0),
/* 39 E> */ B(Call), R(0), R(1), U8(1), U8(2),
/* 44 S> */ B(Return),
]
......@@ -35,11 +37,13 @@ snippet: "
"
frame size: 5
parameter count: 1
bytecode array length: 24
bytecode array length: 26
bytecodes: [
/* 34 E> */ B(StackCheck),
/* 39 S> */ B(LdrUndefined), R(1),
B(LdrGlobal), U8(4), R(0),
/* 39 S> */ B(LdaUndefined),
B(Star), R(1),
B(LdaGlobal), U8(4),
B(Star), R(0),
B(LdaSmi), U8(1),
B(Star), R(2),
B(LdaSmi), U8(2),
......
......@@ -14,11 +14,11 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 12
bytecode array length: 11
bytecodes: [
/* 45 E> */ B(StackCheck),
/* 50 S> */ B(LdrGlobal), U8(4), R(0),
B(Ldar), R(0),
/* 50 S> */ B(LdaGlobal), U8(4),
B(Star), R(0),
/* 57 E> */ B(New), R(0), R(0), U8(0), U8(2),
/* 68 S> */ B(Return),
]
......@@ -35,10 +35,11 @@ snippet: "
"
frame size: 2
parameter count: 1
bytecode array length: 16
bytecode array length: 17
bytecodes: [
/* 58 E> */ B(StackCheck),
/* 63 S> */ B(LdrGlobal), U8(4), R(0),
/* 63 S> */ B(LdaGlobal), U8(4),
B(Star), R(0),
B(LdaSmi), U8(3),
B(Star), R(1),
B(Ldar), R(0),
......@@ -63,10 +64,11 @@ snippet: "
"
frame size: 4
parameter count: 1
bytecode array length: 24
bytecode array length: 25
bytecodes: [
/* 100 E> */ B(StackCheck),
/* 105 S> */ B(LdrGlobal), U8(4), R(0),
/* 105 S> */ B(LdaGlobal), U8(4),
B(Star), R(0),
B(LdaSmi), U8(3),
B(Star), R(1),
B(LdaSmi), U8(4),
......
......@@ -72,10 +72,11 @@ snippet: "
"
frame size: 2
parameter count: 1
bytecode array length: 14
bytecode array length: 15
bytecodes: [
/* 10 E> */ B(StackCheck),
/* 15 S> */ B(LdrUndefined), R(0),
/* 15 S> */ B(LdaUndefined),
B(Star), R(0),
B(CreateArrayLiteral), U8(0), U8(0), U8(9),
B(Star), R(1),
B(CallJSRuntime), U8(150), R(0), U8(2),
......
......@@ -149,8 +149,8 @@ bytecodes: [
B(Star), R(4),
B(LdaNamedProperty), R(4), U8(3), U8(2),
B(Star), R(5),
/* 75 E> */ B(LdaCurrentContextSlot), U8(4),
B(ToName), R(7),
B(LdaCurrentContextSlot), U8(4),
/* 75 E> */ B(ToName), R(7),
B(CreateClosure), U8(4), U8(2),
B(Star), R(8),
B(LdaSmi), U8(2),
......@@ -159,8 +159,8 @@ bytecodes: [
B(Star), R(10),
B(Mov), R(5), R(6),
B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(6), U8(5),
/* 106 E> */ B(LdaCurrentContextSlot), U8(5),
B(ToName), R(7),
B(LdaCurrentContextSlot), U8(5),
/* 106 E> */ B(ToName), R(7),
B(LdaConstant), U8(3),
B(TestEqualStrict), R(7), U8(0),
B(Mov), R(4), R(6),
......
......@@ -109,7 +109,7 @@ snippet: "
"
frame size: 2
parameter count: 1
bytecode array length: 23
bytecode array length: 24
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(0),
......@@ -117,7 +117,8 @@ bytecodes: [
/* 42 S> */ B(LdaSmi), U8(1),
/* 42 E> */ B(StaCurrentContextSlot), U8(4),
/* 45 S> */ B(CreateClosure), U8(0), U8(2),
/* 75 S> */ B(LdrCurrentContextSlot), U8(4), R(1),
/* 75 S> */ B(LdaCurrentContextSlot), U8(4),
B(Star), R(1),
B(BitwiseOrSmi), U8(24), R(1), U8(2),
/* 77 E> */ B(StaCurrentContextSlot), U8(4),
B(LdaUndefined),
......
......@@ -74,11 +74,11 @@ bytecodes: [
/* 30 E> */ B(StackCheck),
/* 47 S> */ B(LdaSmi), U8(20),
B(Star), R(2),
/* 47 E> */ B(LdaCurrentContextSlot), U8(4),
B(LdaCurrentContextSlot), U8(4),
B(JumpIfNotHole), U8(11),
B(LdaConstant), U8(1),
B(Star), R(3),
B(CallRuntime), U16(Runtime::kThrowReferenceError), R(3), U8(1),
/* 47 E> */ B(CallRuntime), U16(Runtime::kThrowReferenceError), R(3), U8(1),
B(CallRuntime), U16(Runtime::kThrowConstAssignError), R(0), U8(0),
/* 47 E> */ B(StaCurrentContextSlot), U8(4),
B(LdaUndefined),
......
......@@ -77,12 +77,13 @@ snippet: "
"
frame size: 3
parameter count: 1
bytecode array length: 20
bytecode array length: 21
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(0),
/* 30 E> */ B(StackCheck),
/* 41 S> */ B(LdrUndefined), R(2),
/* 41 S> */ B(LdaUndefined),
B(Star), R(2),
B(CreateClosure), U8(0), U8(2),
B(Star), R(1),
/* 64 E> */ B(Call), R(1), R(2), U8(1), U8(2),
......@@ -389,7 +390,7 @@ snippet: "
"
frame size: 3
parameter count: 1
bytecode array length: 789
bytecode array length: 791
bytecodes: [
B(CreateFunctionContext), U8(254),
B(PushContext), R(0),
......@@ -900,8 +901,10 @@ bytecodes: [
/* 3421 E> */ B(StaCurrentContextSlot), U8(254),
/* 3435 S> */ B(LdaZero),
/* 3435 E> */ B(StaCurrentContextSlot), U8(255),
/* 3438 S> */ B(LdrUndefined), R(2),
/* 3438 E> */ B(LdrGlobal), U8(4), R(1),
/* 3438 S> */ B(LdaUndefined),
B(Star), R(2),
/* 3438 E> */ B(LdaGlobal), U8(4),
B(Star), R(1),
/* 3438 E> */ B(Call), R(1), R(2), U8(1), U8(2),
/* 3454 S> */ B(LdaSmi), U8(100),
/* 3454 E> */ B(Wide), B(StaCurrentContextSlot), U16(256),
......
......@@ -104,7 +104,7 @@ snippet: "
"
frame size: 4
parameter count: 1
bytecode array length: 29
bytecode array length: 31
bytecodes: [
B(LdaConstant), U8(0),
B(Star), R(1),
......@@ -113,8 +113,10 @@ bytecodes: [
B(Mov), R(closure), R(3),
B(CallRuntime), U16(Runtime::kDeclareGlobalsForInterpreter), R(1), U8(3),
/* 0 E> */ B(StackCheck),
/* 16 S> */ B(LdrUndefined), R(2),
B(LdrGlobal), U8(2), R(1),
/* 16 S> */ B(LdaUndefined),
B(Star), R(2),
B(LdaGlobal), U8(2),
B(Star), R(1),
/* 16 E> */ B(Call), R(1), R(2), U8(1), U8(4),
B(Star), R(0),
/* 20 S> */ B(Return),
......
......@@ -98,7 +98,7 @@ snippet: "
"
frame size: 2
parameter count: 1
bytecode array length: 25
bytecode array length: 26
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(0),
......@@ -107,7 +107,8 @@ bytecodes: [
B(Ldar), R(1),
/* 56 E> */ B(StaCurrentContextSlot), U8(4),
/* 64 S> */ B(CreateClosure), U8(1), U8(2),
/* 93 S> */ B(LdrCurrentContextSlot), U8(4), R(1),
/* 93 S> */ B(LdaCurrentContextSlot), U8(4),
B(Star), R(1),
B(LdaSmi), U8(1),
B(DeletePropertyStrict), R(1),
/* 113 S> */ B(Return),
......
......@@ -30,13 +30,13 @@ snippet: "
"
frame size: 3
parameter count: 1
bytecode array length: 13
bytecode array length: 12
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 55 S> */ B(LdaSmi), U8(100),
B(Star), R(0),
/* 42 S> */ B(LdrUndefined), R(1),
B(Ldar), R(1),
/* 42 S> */ B(LdaUndefined),
B(Star), R(1),
B(Star), R(2),
/* 63 S> */ B(Nop),
/* 73 S> */ B(Return),
......
......@@ -11,7 +11,7 @@ snippet: "
"
frame size: 15
parameter count: 1
bytecode array length: 281
bytecode array length: 282
bytecodes: [
/* 30 E> */ B(StackCheck),
B(LdaZero),
......@@ -45,7 +45,7 @@ bytecodes: [
B(LdaZero),
B(Star), R(4),
B(JumpLoop), U8(-51), U8(0),
B(Jump), U8(35),
B(Jump), U8(36),
B(Star), R(13),
B(Ldar), R(closure),
B(CreateCatchContext), R(13), U8(5), U8(6),
......@@ -56,7 +56,8 @@ bytecodes: [
B(JumpIfFalse), U8(6),
B(LdaSmi), U8(1),
B(Star), R(4),
B(LdrCurrentContextSlot), U8(4), R(13),
B(LdaCurrentContextSlot), U8(4),
B(Star), R(13),
B(CallRuntime), U16(Runtime::kReThrow), R(13), U8(1),
B(PopContext), R(8),
B(LdaSmi), U8(-1),
......@@ -141,9 +142,9 @@ constant pool: [
FIXED_ARRAY_TYPE,
]
handlers: [
[7, 119, 125],
[7, 120, 126],
[10, 84, 86],
[203, 213, 215],
[204, 214, 216],
]
---
......@@ -153,7 +154,7 @@ snippet: "
"
frame size: 16
parameter count: 1
bytecode array length: 292
bytecode array length: 293
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaConstant), U8(0),
......@@ -187,8 +188,8 @@ bytecodes: [
/* 73 S> */ B(LdaZero),
B(Star), R(10),
B(Mov), R(1), R(11),
B(Jump), U8(49),
B(Jump), U8(35),
B(Jump), U8(50),
B(Jump), U8(36),
B(Star), R(14),
B(Ldar), R(closure),
B(CreateCatchContext), R(14), U8(5), U8(6),
......@@ -199,7 +200,8 @@ bytecodes: [
B(JumpIfFalse), U8(6),
B(LdaSmi), U8(1),
B(Star), R(5),
B(LdrCurrentContextSlot), U8(4), R(14),
B(LdaCurrentContextSlot), U8(4),
B(Star), R(14),
B(CallRuntime), U16(Runtime::kReThrow), R(14), U8(1),
B(PopContext), R(9),
B(LdaSmi), U8(-1),
......@@ -289,9 +291,9 @@ constant pool: [
FIXED_ARRAY_TYPE,
]
handlers: [
[11, 119, 125],
[11, 120, 126],
[14, 84, 86],
[204, 214, 216],
[205, 215, 217],
]
---
......@@ -303,7 +305,7 @@ snippet: "
"
frame size: 15
parameter count: 1
bytecode array length: 299
bytecode array length: 300
bytecodes: [
/* 30 E> */ B(StackCheck),
B(LdaZero),
......@@ -345,7 +347,7 @@ bytecodes: [
B(LdaZero),
B(Star), R(4),
B(JumpLoop), U8(-69), U8(0),
B(Jump), U8(35),
B(Jump), U8(36),
B(Star), R(13),
B(Ldar), R(closure),
B(CreateCatchContext), R(13), U8(5), U8(6),
......@@ -356,7 +358,8 @@ bytecodes: [
B(JumpIfFalse), U8(6),
B(LdaSmi), U8(1),
B(Star), R(4),
B(LdrCurrentContextSlot), U8(4), R(13),
B(LdaCurrentContextSlot), U8(4),
B(Star), R(13),
B(CallRuntime), U16(Runtime::kReThrow), R(13), U8(1),
B(PopContext), R(8),
B(LdaSmi), U8(-1),
......@@ -441,9 +444,9 @@ constant pool: [
FIXED_ARRAY_TYPE,
]
handlers: [
[7, 137, 143],
[7, 138, 144],
[10, 102, 104],
[221, 231, 233],
[222, 232, 234],
]
---
......@@ -453,7 +456,7 @@ snippet: "
"
frame size: 14
parameter count: 1
bytecode array length: 306
bytecode array length: 307
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(1), R(8),
......@@ -491,8 +494,8 @@ bytecodes: [
B(Star), R(9),
B(LdaZero),
B(Star), R(8),
B(Jump), U8(49),
B(Jump), U8(35),
B(Jump), U8(50),
B(Jump), U8(36),
B(Star), R(12),
B(Ldar), R(closure),
B(CreateCatchContext), R(12), U8(7), U8(8),
......@@ -503,7 +506,8 @@ bytecodes: [
B(JumpIfFalse), U8(6),
B(LdaSmi), U8(1),
B(Star), R(3),
B(LdrCurrentContextSlot), U8(4), R(12),
B(LdaCurrentContextSlot), U8(4),
B(Star), R(12),
B(CallRuntime), U16(Runtime::kReThrow), R(12), U8(1),
B(PopContext), R(7),
B(LdaSmi), U8(-1),
......@@ -595,8 +599,8 @@ constant pool: [
FIXED_ARRAY_TYPE,
]
handlers: [
[15, 133, 139],
[15, 134, 140],
[18, 98, 100],
[218, 228, 230],
[219, 229, 231],
]
......@@ -29,10 +29,11 @@ snippet: "
"
frame size: 2
parameter count: 1
bytecode array length: 14
bytecode array length: 15
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 34 S> */ B(LdrUndefined), R(1),
/* 34 S> */ B(LdaUndefined),
B(Star), R(1),
B(CreateClosure), U8(0), U8(2),
B(Star), R(0),
/* 56 E> */ B(Call), R(0), R(1), U8(1), U8(2),
......@@ -50,10 +51,11 @@ snippet: "
"
frame size: 3
parameter count: 1
bytecode array length: 18
bytecode array length: 19
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 34 S> */ B(LdrUndefined), R(1),
/* 34 S> */ B(LdaUndefined),
B(Star), R(1),
B(CreateClosure), U8(0), U8(2),
B(Star), R(0),
B(LdaSmi), U8(1),
......
......@@ -14,10 +14,11 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 12
bytecode array length: 13
bytecodes: [
/* 26 E> */ B(StackCheck),
/* 31 S> */ B(LdrGlobal), U8(2), R(0),
/* 31 S> */ B(LdaGlobal), U8(2),
B(Star), R(0),
B(BitwiseAndSmi), U8(1), R(0), U8(4),
/* 45 E> */ B(StaGlobalSloppy), U8(0), U8(5),
/* 51 S> */ B(Return),
......@@ -36,10 +37,11 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 12
bytecode array length: 13
bytecodes: [
/* 27 E> */ B(StackCheck),
/* 32 S> */ B(LdrGlobal), U8(2), R(0),
/* 32 S> */ B(LdaGlobal), U8(2),
B(Star), R(0),
B(AddSmi), U8(1), R(0), U8(4),
/* 51 E> */ B(StaGlobalSloppy), U8(0), U8(5),
/* 57 S> */ B(Return),
......
......@@ -16,10 +16,11 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 9
bytecode array length: 10
bytecodes: [
/* 32 E> */ B(StackCheck),
/* 39 S> */ B(LdrGlobal), U8(2), R(0),
/* 39 S> */ B(LdaGlobal), U8(2),
B(Star), R(0),
B(LdaConstant), U8(0),
B(DeletePropertySloppy), R(0),
/* 58 S> */ B(Return),
......@@ -41,10 +42,11 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 9
bytecode array length: 10
bytecodes: [
/* 28 E> */ B(StackCheck),
/* 51 S> */ B(LdrGlobal), U8(2), R(0),
/* 51 S> */ B(LdaGlobal), U8(2),
B(Star), R(0),
B(LdaSmi), U8(1),
B(DeletePropertyStrict), R(0),
/* 71 S> */ B(Return),
......@@ -64,11 +66,13 @@ snippet: "
"
frame size: 2
parameter count: 1
bytecode array length: 14
bytecode array length: 16
bytecodes: [
/* 32 E> */ B(StackCheck),
/* 39 S> */ B(LdrCurrentContextSlot), U8(3), R(0),
B(LdrContextSlot), R(0), U8(2), U8(0), R(1),
/* 39 S> */ B(LdaCurrentContextSlot), U8(3),
B(Star), R(0),
B(LdaContextSlot), R(0), U8(2), U8(0),
B(Star), R(1),
B(LdaConstant), U8(0),
B(DeletePropertySloppy), R(1),
/* 56 S> */ B(Return),
......@@ -89,11 +93,13 @@ snippet: "
"
frame size: 2
parameter count: 1
bytecode array length: 14
bytecode array length: 16
bytecodes: [
/* 18 E> */ B(StackCheck),
/* 25 S> */ B(LdrCurrentContextSlot), U8(3), R(0),
B(LdrContextSlot), R(0), U8(2), U8(0), R(1),
/* 25 S> */ B(LdaCurrentContextSlot), U8(3),
B(Star), R(0),
B(LdaContextSlot), R(0), U8(2), U8(0),
B(Star), R(1),
B(LdaConstant), U8(0),
B(DeletePropertySloppy), R(1),
/* 42 S> */ B(Return),
......
......@@ -74,11 +74,11 @@ bytecodes: [
/* 30 E> */ B(StackCheck),
/* 45 S> */ B(LdaSmi), U8(20),
B(Star), R(2),
/* 45 E> */ B(LdaCurrentContextSlot), U8(4),
B(LdaCurrentContextSlot), U8(4),
B(JumpIfNotHole), U8(11),
B(LdaConstant), U8(1),
B(Star), R(3),
B(CallRuntime), U16(Runtime::kThrowReferenceError), R(3), U8(1),
/* 45 E> */ B(CallRuntime), U16(Runtime::kThrowReferenceError), R(3), U8(1),
B(Ldar), R(2),
B(StaCurrentContextSlot), U8(4),
/* 45 E> */ B(StaCurrentContextSlot), U8(4),
......
......@@ -20,12 +20,13 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 12
bytecode array length: 13
bytecodes: [
/* 97 E> */ B(StackCheck),
/* 102 S> */ B(LdrContextSlot), R(context), U8(4), U8(1), R(0),
/* 120 E> */ B(LdaCurrentContextSlot), U8(4),
B(Mul), R(0), U8(2),
/* 102 S> */ B(LdaContextSlot), R(context), U8(4), U8(1),
B(Star), R(0),
B(LdaCurrentContextSlot), U8(4),
/* 120 E> */ B(Mul), R(0), U8(2),
/* 130 S> */ B(Return),
]
constant pool: [
......
......@@ -96,7 +96,7 @@ snippet: "
"
frame size: 3
parameter count: 1
bytecode array length: 23
bytecode array length: 22
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(Wide), B(LdaSmi), U16(1234),
......@@ -105,8 +105,8 @@ bytecodes: [
/* 66 E> */ B(Mul), R(0), U8(2),
B(Star), R(2),
B(SubSmi), U8(1), R(2), U8(3),
B(LdrUndefined), R(1),
B(Ldar), R(1),
B(LdaUndefined),
B(Star), R(1),
/* 74 S> */ B(Nop),
/* 84 S> */ B(Return),
]
......
......@@ -54,7 +54,7 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
.LoadLiteral(factory->NewStringFromStaticChars("A constant"))
.StoreAccumulatorInRegister(reg)
.LoadUndefined()
.Debugger() // Prevent peephole optimization LdaNull, Star -> LdrNull.
.StoreAccumulatorInRegister(reg)
.LoadNull()
.StoreAccumulatorInRegister(reg)
.LoadTheHole()
......@@ -308,17 +308,6 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
.StoreLookupSlot(wide_name, LanguageMode::SLOPPY)
.StoreLookupSlot(wide_name, LanguageMode::STRICT);
// Emit loads which will be transformed to Ldr equivalents by the peephole
// optimizer.
builder.LoadContextSlot(reg, 1, 0)
.StoreAccumulatorInRegister(reg)
.LoadContextSlot(Register::current_context(), 1, 0)
.StoreAccumulatorInRegister(reg)
.LoadGlobal(0, TypeofMode::NOT_INSIDE_TYPEOF)
.StoreAccumulatorInRegister(reg)
.LoadUndefined()
.StoreAccumulatorInRegister(reg);
// CreateClosureWide
builder.CreateClosure(1000, NOT_TENURED);
......@@ -392,10 +381,6 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
if (!FLAG_ignition_peephole) {
// Insert entries for bytecodes only emitted by peephole optimizer.
scorecard[Bytecodes::ToByte(Bytecode::kLdrGlobal)] = 1;
scorecard[Bytecodes::ToByte(Bytecode::kLdrContextSlot)] = 1;
scorecard[Bytecodes::ToByte(Bytecode::kLdrCurrentContextSlot)] = 1;
scorecard[Bytecodes::ToByte(Bytecode::kLdrUndefined)] = 1;
scorecard[Bytecodes::ToByte(Bytecode::kLogicalNot)] = 1;
scorecard[Bytecodes::ToByte(Bytecode::kJump)] = 1;
scorecard[Bytecodes::ToByte(Bytecode::kJumpIfTrue)] = 1;
......
......@@ -321,81 +321,6 @@ TEST_F(BytecodePeepholeOptimizerTest, NopStatementStackCheck) {
// Tests covering BytecodePeepholeOptimizer::UpdateLastAndCurrentBytecodes().
TEST_F(BytecodePeepholeOptimizerTest, MergeLdaGlobalStar) {
const uint32_t operands[] = {19191,
static_cast<uint32_t>(Register(1).ToOperand())};
const int expected_operand_count = static_cast<int>(arraysize(operands));
BytecodeNode first(Bytecode::kLdaGlobal, operands[0]);
BytecodeNode second(Bytecode::kStar, operands[1]);
BytecodeNode third(Bytecode::kReturn);
optimizer()->Write(&first);
optimizer()->Write(&second);
CHECK_EQ(write_count(), 1);
CHECK_EQ(last_written().bytecode(), Bytecode::kLdrGlobal);
CHECK_EQ(last_written().operand_count(), expected_operand_count);
for (int i = 0; i < expected_operand_count; ++i) {
CHECK_EQ(last_written().operand(i), operands[i]);
}
optimizer()->Write(&third);
CHECK_EQ(write_count(), 2);
CHECK_EQ(last_written().bytecode(), Bytecode::kLdar);
CHECK_EQ(last_written().operand(0), operands[expected_operand_count - 1]);
Flush();
CHECK_EQ(last_written().bytecode(), third.bytecode());
}
TEST_F(BytecodePeepholeOptimizerTest, MergeLdaContextSlotStar) {
const uint32_t operands[] = {
static_cast<uint32_t>(Register(200000).ToOperand()), 55005500,
static_cast<uint32_t>(Register(0).ToOperand()),
static_cast<uint32_t>(Register(1).ToOperand())};
const int expected_operand_count = static_cast<int>(arraysize(operands));
BytecodeNode first(Bytecode::kLdaContextSlot, operands[0], operands[1],
operands[2]);
BytecodeNode second(Bytecode::kStar, operands[3]);
BytecodeNode third(Bytecode::kReturn);
optimizer()->Write(&first);
optimizer()->Write(&second);
CHECK_EQ(write_count(), 1);
CHECK_EQ(last_written().bytecode(), Bytecode::kLdrContextSlot);
CHECK_EQ(last_written().operand_count(), expected_operand_count);
for (int i = 0; i < expected_operand_count; ++i) {
CHECK_EQ(last_written().operand(i), operands[i]);
}
optimizer()->Write(&third);
CHECK_EQ(write_count(), 2);
CHECK_EQ(last_written().bytecode(), Bytecode::kLdar);
CHECK_EQ(last_written().operand(0), operands[expected_operand_count - 1]);
Flush();
CHECK_EQ(last_written().bytecode(), third.bytecode());
}
TEST_F(BytecodePeepholeOptimizerTest, MergeLdaUndefinedStar) {
const uint32_t operands[] = {
static_cast<uint32_t>(Register(100000).ToOperand())};
const int expected_operand_count = static_cast<int>(arraysize(operands));
BytecodeNode first(Bytecode::kLdaUndefined);
BytecodeNode second(Bytecode::kStar, operands[0]);
BytecodeNode third(Bytecode::kReturn);
optimizer()->Write(&first);
optimizer()->Write(&second);
CHECK_EQ(write_count(), 1);
CHECK_EQ(last_written().bytecode(), Bytecode::kLdrUndefined);
CHECK_EQ(last_written().operand_count(), expected_operand_count);
for (int i = 0; i < expected_operand_count; ++i) {
CHECK_EQ(last_written().operand(i), operands[i]);
}
optimizer()->Write(&third);
CHECK_EQ(write_count(), 2);
CHECK_EQ(last_written().bytecode(), Bytecode::kLdar);
CHECK_EQ(last_written().operand(0), operands[expected_operand_count - 1]);
Flush();
CHECK_EQ(last_written().bytecode(), third.bytecode());
}
TEST_F(BytecodePeepholeOptimizerTest, MergeLdaSmiWithBinaryOp) {
Bytecode operator_replacement_pairs[][2] = {
{Bytecode::kAdd, Bytecode::kAddSmi},
......
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