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

Unified Diff: src/interpreter/bytecode-peephole-optimizer.cc

Issue 2118183002: [interpeter] Move to table based peephole optimizer. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Undo experimental in last patch set. Created 4 years, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/interpreter/bytecode-peephole-optimizer.h ('k') | src/interpreter/bytecodes.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/interpreter/bytecode-peephole-optimizer.cc
diff --git a/src/interpreter/bytecode-peephole-optimizer.cc b/src/interpreter/bytecode-peephole-optimizer.cc
index 1108d8304f855f74dcd5b3f6e2965104f068684c..f303bcc3e562718bfc3c0d47d97e6520d3e13336 100644
--- a/src/interpreter/bytecode-peephole-optimizer.cc
+++ b/src/interpreter/bytecode-peephole-optimizer.cc
@@ -12,10 +12,209 @@ namespace v8 {
namespace internal {
namespace interpreter {
+namespace {
+
+// Actions to take when a pair of bytes is encountered. A handler
+// exists for each action.
+enum class PeepholeAction : uint8_t {
+ // Actions for non-jump bytecodes.
+ kDefaultAction,
+ kUpdateLastAction,
+ kElideCurrentAction,
+ kElideCurrentIfOperand0MatchesAction,
+ kElideCurrentIfLoadingNameConstantAction,
+ kElideLastAction,
+ kChangeBytecodeAction,
+ kTransformLdaStarToLdrLdarAction,
+
+ // Actions for jump bytecodes.
+ kDefaultJumpAction,
+ kUpdateLastJumpAction,
+ kChangeJumpBytecodeAction,
+ kElideLastBeforeJumpAction,
+};
+
+// Tuple of action to take when pair of bytecodes is encountered and
+// optional data to invoke handler with.
+struct PeepholeActionAndData final {
+ // Action to take when tuple of bytecodes encountered.
+ PeepholeAction action;
+
+ // Replacement bytecode (if valid).
+ Bytecode bytecode;
+};
+
+class PeepholeActionTable final {
+ public:
+ static void Initialize();
+
+ static const PeepholeActionAndData* const Lookup(Bytecode last,
+ Bytecode current) {
+ size_t index = ToIndex(last, current);
+ return &table_[index];
+ }
+
+ static bool initialized() { return initialized_; }
+
+ private:
+ static const size_t kNumberOfBytecodes =
+ static_cast<size_t>(Bytecode::kLast) + 1;
+ static const size_t kTableSize = kNumberOfBytecodes * kNumberOfBytecodes;
+
+ static PeepholeActionAndData LookupActionAndData(Bytecode last,
+ Bytecode current);
+ static void InsertActionAndData(Bytecode last, Bytecode current,
+ PeepholeActionAndData action_data);
+ static Bytecode NextBytecode(Bytecode bytecode);
+ static size_t ToIndex(Bytecode last, Bytecode current);
+
+ static bool initialized_;
+ static PeepholeActionAndData table_[kTableSize];
+};
+
+bool PeepholeActionTable::initialized_ = false;
+PeepholeActionAndData PeepholeActionTable::table_[kTableSize];
+
+// static
+void PeepholeActionTable::Initialize() {
+ DCHECK(!initialized_);
+ for (Bytecode last = Bytecode::kWide; last <= Bytecode::kLast;
+ last = NextBytecode(last)) {
+ for (Bytecode current = Bytecode::kWide; current <= Bytecode::kLast;
+ current = NextBytecode(current)) {
+ PeepholeActionAndData action_data = LookupActionAndData(last, current);
+ InsertActionAndData(last, current, action_data);
+ }
+ }
+ initialized_ = true;
+}
+
+// static
+Bytecode PeepholeActionTable::NextBytecode(Bytecode bytecode) {
+ return static_cast<Bytecode>(static_cast<size_t>(bytecode) + 1);
+}
+
+// static
+size_t PeepholeActionTable::ToIndex(Bytecode last, Bytecode current) {
+ return static_cast<size_t>(last) * kNumberOfBytecodes +
+ static_cast<size_t>(current);
+}
+
+// static
+void PeepholeActionTable::InsertActionAndData(
+ Bytecode last, Bytecode current, PeepholeActionAndData action_data) {
+ size_t index = ToIndex(last, current);
+ table_[index] = action_data;
+}
+
+// static
+PeepholeActionAndData PeepholeActionTable::LookupActionAndData(
+ Bytecode last, Bytecode current) {
+ // TODO(oth): Investigate generating this table at compile time.
+
+ // 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 && last == Bytecode::kLdaNamedProperty) {
+ return {PeepholeAction::kTransformLdaStarToLdrLdarAction,
+ Bytecode::kLdrNamedProperty};
+ } else if (current == Bytecode::kStar &&
+ last == Bytecode::kLdaKeyedProperty) {
+ return {PeepholeAction::kTransformLdaStarToLdrLdarAction,
+ Bytecode::kLdrKeyedProperty};
+ } else if (current == Bytecode::kStar && last == Bytecode::kLdaGlobal) {
+ return {PeepholeAction::kTransformLdaStarToLdrLdarAction,
+ Bytecode::kLdrGlobal};
+ } else if (current == Bytecode::kStar && last == Bytecode::kLdaContextSlot) {
+ return {PeepholeAction::kTransformLdaStarToLdrLdarAction,
+ Bytecode::kLdrContextSlot};
+ } else if (current == Bytecode::kStar && last == Bytecode::kLdaUndefined) {
+ return {PeepholeAction::kTransformLdaStarToLdrLdarAction,
+ Bytecode::kLdrUndefined};
+ }
+
+ // ToName optimizations: remove unnecessary ToName bytecodes.
+ if (last == Bytecode::kLdaConstant && current == Bytecode::kToName) {
+ return {PeepholeAction::kElideCurrentIfLoadingNameConstantAction,
+ Bytecode::kIllegal};
+ } else if (Bytecodes::PutsNameInAccumulator(last) &&
+ current == Bytecode::kToName) {
+ return {PeepholeAction::kElideCurrentAction, Bytecode::kIllegal};
+ }
+
+ // Nop are placeholders for holding source position information and can be
+ // elided if there is no source information.
+ if (last == Bytecode::kNop) {
+ if (Bytecodes::IsJump(current)) {
+ return {PeepholeAction::kElideLastBeforeJumpAction, Bytecode::kIllegal};
+ } else {
+ return {PeepholeAction::kElideLastAction, Bytecode::kIllegal};
+ }
+ }
+
+ // The accumulator is invisible to the debugger. If there is a sequence
+ // of consecutive accumulator loads (that don't have side effects) then
+ // only the final load is potentially visible.
+ if (Bytecodes::IsAccumulatorLoadWithoutEffects(last) &&
+ Bytecodes::IsAccumulatorLoadWithoutEffects(current)) {
+ return {PeepholeAction::kElideLastAction, Bytecode::kIllegal};
+ }
+
+ // The current instruction clobbers the accumulator without reading
+ // it. The load in the last instruction can be elided as it has no
+ // effect.
+ if (Bytecodes::IsAccumulatorLoadWithoutEffects(last) &&
+ Bytecodes::GetAccumulatorUse(current) == AccumulatorUse::kWrite) {
+ return {PeepholeAction::kElideLastAction, Bytecode::kIllegal};
+ }
+
+ // Ldar and Star make the accumulator and register hold equivalent
+ // values. Only the first bytecode is needed if there's a sequence
+ // of back-to-back Ldar and Star bytecodes with the same operand.
+ if (Bytecodes::IsLdarOrStar(last) && Bytecodes::IsLdarOrStar(current)) {
+ return {PeepholeAction::kElideCurrentIfOperand0MatchesAction,
+ Bytecode::kIllegal};
+ }
+
+ // Remove ToBoolean coercion from conditional jumps where possible.
+ if (Bytecodes::WritesBooleanToAccumulator(last) &&
+ Bytecodes::IsJumpIfToBoolean(current)) {
+ return {PeepholeAction::kChangeJumpBytecodeAction,
+ Bytecodes::GetJumpWithoutToBoolean(current)};
+ } else if (Bytecodes::WritesBooleanToAccumulator(last) &&
+ current == Bytecode::kToBooleanLogicalNot) {
+ return {PeepholeAction::kChangeBytecodeAction, Bytecode::kLogicalNot};
+ }
+
+ // If there is no last bytecode to optimize against, store the incoming
+ // bytecode or for jumps emit incoming bytecode immediately.
+ if (last == Bytecode::kIllegal) {
+ if (Bytecodes::IsJump(current)) {
+ return {PeepholeAction::kUpdateLastJumpAction, Bytecode::kIllegal};
+ } else {
+ return {PeepholeAction::kUpdateLastAction, Bytecode::kIllegal};
+ }
+ }
+
+ // No matches, take the default action.
+ if (Bytecodes::IsJump(current)) {
+ return {PeepholeAction::kDefaultJumpAction, Bytecode::kIllegal};
+ } else {
+ return {PeepholeAction::kDefaultAction, Bytecode::kIllegal};
+ }
+}
+
+} // namespace
+
BytecodePeepholeOptimizer::BytecodePeepholeOptimizer(
ConstantArrayBuilder* constant_array_builder,
BytecodePipelineStage* next_stage)
: constant_array_builder_(constant_array_builder), next_stage_(next_stage) {
+ if (!PeepholeActionTable::initialized()) {
+ PeepholeActionTable::Initialize();
rmcilroy 2016/07/04 12:45:46 How does this play with threading? There could be
+ }
InvalidateLast();
}
@@ -29,21 +228,6 @@ Handle<BytecodeArray> BytecodePeepholeOptimizer::ToBytecodeArray(
}
// override
-void BytecodePeepholeOptimizer::Write(BytecodeNode* node) {
- node = OptimizeAndEmitLast(node);
- if (node != nullptr) {
- SetLast(node);
- }
-}
-
-// override
-void BytecodePeepholeOptimizer::WriteJump(BytecodeNode* node,
- BytecodeLabel* label) {
- node = OptimizeAndEmitLast(node);
- next_stage_->WriteJump(node, label);
-}
-
-// override
void BytecodePeepholeOptimizer::BindLabel(BytecodeLabel* label) {
Flush();
next_stage_->BindLabel(label);
@@ -52,14 +236,22 @@ void BytecodePeepholeOptimizer::BindLabel(BytecodeLabel* label) {
// override
void BytecodePeepholeOptimizer::BindLabel(const BytecodeLabel& target,
BytecodeLabel* label) {
- // There is no need to flush here, it will have been flushed when |target|
- // was bound.
+ // There is no need to flush here, it will have been flushed when
+ // |target| was bound.
next_stage_->BindLabel(target, label);
}
+// override
+void BytecodePeepholeOptimizer::WriteJump(BytecodeNode* node,
+ BytecodeLabel* label) {
+ Optimize(node);
+ next_stage()->WriteJump(node, label);
+}
+
+// override
+void BytecodePeepholeOptimizer::Write(BytecodeNode* node) { Optimize(node); }
+
void BytecodePeepholeOptimizer::Flush() {
- // TODO(oth/rmcilroy): We could check CanElideLast() here to potentially
- // eliminate last rather than writing it.
if (LastIsValid()) {
next_stage_->Write(&last_);
InvalidateLast();
@@ -86,50 +278,6 @@ Handle<Object> BytecodePeepholeOptimizer::GetConstantForIndexOperand(
return constant_array_builder_->At(index_operand);
}
-bool BytecodePeepholeOptimizer::LastBytecodePutsNameInAccumulator() const {
- DCHECK(LastIsValid());
- return (last_.bytecode() == Bytecode::kTypeOf ||
- last_.bytecode() == Bytecode::kToName ||
- (last_.bytecode() == Bytecode::kLdaConstant &&
- GetConstantForIndexOperand(&last_, 0)->IsName()));
-}
-
-void BytecodePeepholeOptimizer::TryToRemoveLastExpressionPosition(
- const BytecodeNode* const current) {
- if (current->source_info().is_valid() &&
- last_.source_info().is_expression() &&
- Bytecodes::IsWithoutExternalSideEffects(last_.bytecode())) {
- // The last bytecode has been marked as expression. It has no
- // external effects so can't throw and the current bytecode is a
- // source position. Remove the expression position on the last
- // bytecode to open up potential peephole optimizations and to
- // save the memory and perf cost of storing the unneeded
- // expression position.
- last_.source_info().set_invalid();
- }
-}
-
-bool BytecodePeepholeOptimizer::CanElideCurrent(
- const BytecodeNode* const current) const {
- if (Bytecodes::IsLdarOrStar(last_.bytecode()) &&
- Bytecodes::IsLdarOrStar(current->bytecode()) &&
- current->operand(0) == last_.operand(0)) {
- // Ldar and Star make the accumulator and register hold equivalent
- // values. Only the first bytecode is needed if there's a sequence
- // of back-to-back Ldar and Star bytecodes with the same operand.
- return true;
- } else if (current->bytecode() == Bytecode::kToName &&
- LastBytecodePutsNameInAccumulator()) {
- // If the previous bytecode ensured a name was in the accumulator,
- // the type coercion ToName() can be elided.
- return true;
- } else {
- // Additional candidates for eliding current:
- // (i) ToNumber if the last puts a number in the accumulator.
- return false;
- }
-}
-
bool BytecodePeepholeOptimizer::CanElideLastBasedOnSourcePosition(
const BytecodeNode* const current) const {
//
@@ -155,10 +303,7 @@ bool BytecodePeepholeOptimizer::CanElideLastBasedOnSourcePosition(
// The last bytecode can be elided for the MAYBE cases if the last
// bytecode is known not to throw. If it throws, the system would
// not have correct stack trace information. The appropriate check
- // for this would be Bytecodes::IsWithoutExternalSideEffects(),
- // which is checked in
- // BytecodePeepholeOptimizer::TransformLastAndCurrentBytecodes() to
- // keep the check here simple.
+ // for this would be Bytecodes::IsWithoutExternalSideEffects().
//
// In rare cases, bytecode generation produces consecutive bytecodes
// with the same expression positions. In principle, the latter of
@@ -190,136 +335,178 @@ void TransformLdaStarToLdrLdar(Bytecode new_bytecode, BytecodeNode* const last,
} // namespace
-bool BytecodePeepholeOptimizer::TransformLastAndCurrentBytecodes(
- BytecodeNode* const current) {
- if (current->bytecode() == Bytecode::kStar &&
- !current->source_info().is_statement()) {
- // Note: If the Star is tagged with a statement position, we can't
- // perform this transform as the store to the register will
- // have the wrong ordering for stepping in the debugger.
- switch (last_.bytecode()) {
- case Bytecode::kLdaNamedProperty:
- TransformLdaStarToLdrLdar(Bytecode::kLdrNamedProperty, &last_, current);
- return true;
- case Bytecode::kLdaKeyedProperty:
- TransformLdaStarToLdrLdar(Bytecode::kLdrKeyedProperty, &last_, current);
- return true;
- case Bytecode::kLdaGlobal:
- TransformLdaStarToLdrLdar(Bytecode::kLdrGlobal, &last_, current);
- return true;
- case Bytecode::kLdaContextSlot:
- TransformLdaStarToLdrLdar(Bytecode::kLdrContextSlot, &last_, current);
- return true;
- case Bytecode::kLdaUndefined:
- TransformLdaStarToLdrLdar(Bytecode::kLdrUndefined, &last_, current);
- return true;
- default:
- break;
- }
- }
- return false;
+void BytecodePeepholeOptimizer::DefaultAction(BytecodeNode* const node) {
+ DCHECK(LastIsValid());
+ DCHECK(!Bytecodes::IsJump(node->bytecode()));
+
+ next_stage()->Write(last());
+ SetLast(node);
}
-bool BytecodePeepholeOptimizer::RemoveToBooleanFromJump(
- BytecodeNode* const current) {
- bool can_remove = Bytecodes::IsJumpIfToBoolean(current->bytecode()) &&
- Bytecodes::WritesBooleanToAccumulator(last_.bytecode());
- if (can_remove) {
- // Conditional jumps with boolean conditions are emiitted in
- // ToBoolean form by the bytecode array builder,
- // i.e. JumpIfToBooleanTrue rather JumpIfTrue. The ToBoolean
- // element can be removed if the previous bytecode put a boolean
- // value in the accumulator.
- Bytecode jump = Bytecodes::GetJumpWithoutToBoolean(current->bytecode());
- current->set_bytecode(jump, current->operand(0));
- }
- return can_remove;
+void BytecodePeepholeOptimizer::UpdateLastAction(BytecodeNode* const node) {
+ DCHECK(!LastIsValid());
+ DCHECK(!Bytecodes::IsJump(node->bytecode()));
+
+ SetLast(node);
}
-bool BytecodePeepholeOptimizer::RemoveToBooleanFromLogicalNot(
- BytecodeNode* const current) {
- bool can_remove = current->bytecode() == Bytecode::kToBooleanLogicalNot &&
- Bytecodes::WritesBooleanToAccumulator(last_.bytecode());
- if (can_remove) {
- // Logical-nots are emitted in ToBoolean form by the bytecode array
- // builder, The ToBoolean element can be removed if the previous bytecode
- // put a boolean value in the accumulator.
- current->set_bytecode(Bytecode::kLogicalNot);
+void BytecodePeepholeOptimizer::ElideCurrentAction(BytecodeNode* const node) {
+ DCHECK(LastIsValid());
+ DCHECK(!Bytecodes::IsJump(node->bytecode()));
+
+ if (node->source_info().is_valid()) {
+ // Preserve the source information by replacing the node bytecode
+ // with a no op bytecode.
+ node->set_bytecode(Bytecode::kNop);
+ DefaultAction(node);
+ } else {
+ // Nothing to do, keep last and wait for next bytecode to pair with it.
}
- return can_remove;
}
-bool BytecodePeepholeOptimizer::TransformCurrentBytecode(
- BytecodeNode* const current) {
- return RemoveToBooleanFromJump(current) ||
- RemoveToBooleanFromLogicalNot(current);
-}
+void BytecodePeepholeOptimizer::ElideCurrentIfOperand0MatchesAction(
+ BytecodeNode* const node) {
+ DCHECK(LastIsValid());
+ DCHECK(!Bytecodes::IsJump(node->bytecode()));
-bool BytecodePeepholeOptimizer::CanElideLast(
- const BytecodeNode* const current) const {
- if (last_.bytecode() == Bytecode::kNop) {
- // Nop are placeholders for holding source position information.
- return true;
- } else if (Bytecodes::IsAccumulatorLoadWithoutEffects(current->bytecode()) &&
- Bytecodes::IsAccumulatorLoadWithoutEffects(last_.bytecode())) {
- // The accumulator is invisible to the debugger. If there is a sequence of
- // consecutive accumulator loads (that don't have side effects) then only
- // the final load is potentially visible.
- return true;
- } else if (Bytecodes::GetAccumulatorUse(current->bytecode()) ==
- AccumulatorUse::kWrite &&
- Bytecodes::IsAccumulatorLoadWithoutEffects(last_.bytecode())) {
- // The current instruction clobbers the accumulator without reading it. The
- // load in the last instruction can be elided as it has no effect.
- return true;
+ if (last()->operand(0) == node->operand(0)) {
+ ElideCurrentAction(node);
} else {
- return false;
+ DefaultAction(node);
}
}
-BytecodeNode* BytecodePeepholeOptimizer::Optimize(BytecodeNode* current) {
- TryToRemoveLastExpressionPosition(current);
+void BytecodePeepholeOptimizer::ElideCurrentIfLoadingNameConstantAction(
+ BytecodeNode* const node) {
+ DCHECK_EQ(last()->bytecode(), Bytecode::kLdaConstant);
+ DCHECK(!Bytecodes::IsJump(node->bytecode()));
- if (TransformCurrentBytecode(current) ||
- TransformLastAndCurrentBytecodes(current)) {
- return current;
+ if (GetConstantForIndexOperand(last(), 0)->IsName()) {
+ ElideCurrentAction(node);
+ } else {
+ DefaultAction(node);
}
+}
- if (CanElideCurrent(current)) {
- if (current->source_info().is_valid()) {
- // Preserve the source information by replacing the current bytecode
- // with a no op bytecode.
- current->set_bytecode(Bytecode::kNop);
- } else {
- current = nullptr;
+void BytecodePeepholeOptimizer::ElideLastAction(BytecodeNode* const node) {
+ DCHECK(LastIsValid());
+ DCHECK(!Bytecodes::IsJump(node->bytecode()));
+
+ if (CanElideLastBasedOnSourcePosition(node)) {
+ if (last()->source_info().is_valid()) {
+ // Node can not be valid per CanElideLastBasedOnSourcePosition().
+ node->source_info().Clone(last()->source_info());
}
- return current;
+ SetLast(node);
+ } else {
+ DefaultAction(node);
}
+}
- if (CanElideLast(current) && CanElideLastBasedOnSourcePosition(current)) {
- if (last_.source_info().is_valid()) {
- // Current can not be valid per CanElideLastBasedOnSourcePosition().
- current->source_info().Clone(last_.source_info());
- }
- InvalidateLast();
- return current;
+void BytecodePeepholeOptimizer::ChangeBytecodeAction(BytecodeNode* node,
+ Bytecode replacement) {
+ DCHECK(LastIsValid());
+ DCHECK(!Bytecodes::IsJump(node->bytecode()));
+
+ node->set_bytecode(replacement);
+ DefaultAction(node);
+}
+
+void BytecodePeepholeOptimizer::TransformLdaStarToLdrLdarAction(
+ BytecodeNode* node, Bytecode replacement) {
+ DCHECK(LastIsValid());
+ DCHECK(!Bytecodes::IsJump(node->bytecode()));
+
+ if (!node->source_info().is_statement()) {
+ TransformLdaStarToLdrLdar(replacement, last(), node);
}
+ DefaultAction(node);
+}
+
+void BytecodePeepholeOptimizer::DefaultJumpAction(BytecodeNode* node) {
+ DCHECK(LastIsValid());
+ DCHECK(Bytecodes::IsJump(node->bytecode()));
- return current;
+ next_stage()->Write(last());
+ InvalidateLast();
}
-BytecodeNode* BytecodePeepholeOptimizer::OptimizeAndEmitLast(
- BytecodeNode* current) {
- // Attempt optimization if there is an earlier node to optimize with.
- if (LastIsValid()) {
- current = Optimize(current);
- // Only output the last node if it wasn't invalidated by the optimization.
- if (LastIsValid()) {
- next_stage_->Write(&last_);
- InvalidateLast();
- }
+void BytecodePeepholeOptimizer::UpdateLastJumpAction(BytecodeNode* node) {
+ DCHECK(!LastIsValid());
+ DCHECK(Bytecodes::IsJump(node->bytecode()));
+}
+
+void BytecodePeepholeOptimizer::ChangeJumpBytecodeAction(BytecodeNode* node,
+ Bytecode replacement) {
+ DCHECK(LastIsValid());
+ DCHECK(Bytecodes::IsJump(node->bytecode()));
+
+ next_stage()->Write(last());
+ InvalidateLast();
+ node->set_bytecode(replacement, node->operand(0));
+}
+
+void BytecodePeepholeOptimizer::ElideLastBeforeJumpAction(BytecodeNode* node) {
+ DCHECK(LastIsValid());
+ DCHECK(Bytecodes::IsJump(node->bytecode()));
+
+ if (!node->source_info().is_valid()) {
+ node->source_info().Clone(last()->source_info());
+ } else {
+ next_stage()->Write(last());
+ }
+ InvalidateLast();
+}
+
+void BytecodePeepholeOptimizer::Optimize(BytecodeNode* const node) {
+ // A single table is used for looking up peephole optimization
+ // matches as it is observed to have better performance. This is
+ // inspite of the fact that jump bytecodes and non-jump bytecodes
+ // have different processing logic, in particular a jump bytecode
+ // always needs to emit the jump via WriteJump().
+ const PeepholeActionAndData* const action_data =
+ PeepholeActionTable::Lookup(last()->bytecode(), node->bytecode());
rmcilroy 2016/07/04 12:45:46 You could possibly store function pointers in the
+ switch (action_data->action) {
+ case PeepholeAction::kDefaultAction:
+ DefaultAction(node);
+ break;
+ case PeepholeAction::kUpdateLastAction:
+ UpdateLastAction(node);
+ break;
+ case PeepholeAction::kElideCurrentAction:
+ ElideCurrentAction(node);
+ break;
+ case PeepholeAction::kElideCurrentIfOperand0MatchesAction:
+ ElideCurrentIfOperand0MatchesAction(node);
+ break;
+ case PeepholeAction::kElideCurrentIfLoadingNameConstantAction:
+ ElideCurrentIfLoadingNameConstantAction(node);
+ break;
+ case PeepholeAction::kElideLastAction:
+ ElideLastAction(node);
+ break;
+ case PeepholeAction::kChangeBytecodeAction:
+ ChangeBytecodeAction(node, action_data->bytecode);
+ break;
+ case PeepholeAction::kTransformLdaStarToLdrLdarAction:
+ TransformLdaStarToLdrLdarAction(node, action_data->bytecode);
+ break;
+ case PeepholeAction::kDefaultJumpAction:
+ DefaultJumpAction(node);
+ break;
+ case PeepholeAction::kUpdateLastJumpAction:
+ UpdateLastJumpAction(node);
+ break;
+ case PeepholeAction::kChangeJumpBytecodeAction:
+ ChangeJumpBytecodeAction(node, action_data->bytecode);
+ break;
+ case PeepholeAction::kElideLastBeforeJumpAction:
+ ElideLastBeforeJumpAction(node);
+ break;
+ default:
+ UNREACHABLE();
+ break;
}
- return current;
}
} // namespace interpreter
« no previous file with comments | « src/interpreter/bytecode-peephole-optimizer.h ('k') | src/interpreter/bytecodes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698