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

Side by Side Diff: src/interpreter/bytecode-peephole-optimizer.cc

Issue 1947403002: [interpreter] Introduce bytecode generation pipeline. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Remove unreadable git cl formatting. Created 4 years, 7 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/interpreter/bytecode-peephole-optimizer.h"
6
7 #include "src/interpreter/constant-array-builder.h"
8 #include "src/objects-inl.h"
9 #include "src/objects.h"
10
11 namespace v8 {
12 namespace internal {
13 namespace interpreter {
14
15 BytecodePeepholeOptimizer::BytecodePeepholeOptimizer(
16 ConstantArrayBuilder* constant_array_builder,
17 BytecodePipelineStage* next_stage)
18 : constant_array_builder_(constant_array_builder),
19 next_stage_(next_stage),
20 last_(Bytecode::kNop),
21 last_is_valid_(false),
22 last_is_discardable_(false) {}
23
24 void BytecodePeepholeOptimizer::InvalidateLast() { last_is_valid_ = false; }
25
26 bool BytecodePeepholeOptimizer::LastIsValid() const { return last_is_valid_; }
27
28 void BytecodePeepholeOptimizer::SetLast(const BytecodeNode* const node) {
29 last_.Clone(node);
30 last_is_valid_ = true;
31 last_is_discardable_ = true;
32 }
33
34 // override
35 size_t BytecodePeepholeOptimizer::FlushForOffset() {
36 size_t buffered_size = next_stage_->FlushForOffset();
37 if (LastIsValid()) {
38 if (last_.bytecode() == Bytecode::kNop &&
39 !last_.source_info().is_statement()) {
40 InvalidateLast();
41 } else {
42 buffered_size += last_.Size();
43 last_is_discardable_ = false;
44 }
45 }
46 return buffered_size;
47 }
48
49 // override
50 void BytecodePeepholeOptimizer::FlushBasicBlock() {
51 if (LastIsValid()) {
52 next_stage_->Write(&last_);
53 InvalidateLast();
54 }
55 next_stage_->FlushBasicBlock();
56 }
57
58 // override
59 void BytecodePeepholeOptimizer::Write(BytecodeNode* node) {
60 // Attempt optimization if there is an earlier node to optimize with.
61 if (LastIsValid()) {
62 node = Optimize(node);
63 // Only output if optimization did not invalidate earlier node.
64 if (LastIsValid()) {
65 next_stage_->Write(&last_);
66 InvalidateLast();
67 }
68 }
69
70 if (node != nullptr) {
71 SetLast(node);
72 }
73 }
74
75 Handle<Object> BytecodePeepholeOptimizer::GetConstantForIndexOperand(
76 const BytecodeNode* const node, int index) const {
77 DCHECK_LE(index, node->operand_count());
78 DCHECK_EQ(Bytecodes::GetOperandType(node->bytecode(), 0), OperandType::kIdx);
79 uint32_t index_operand = node->operand(0);
80 return constant_array_builder_->At(index_operand);
81 }
82
83 bool BytecodePeepholeOptimizer::LastBytecodePutsNameInAccumulator() const {
84 DCHECK(LastIsValid());
85 return (last_.bytecode() == Bytecode::kTypeOf ||
86 last_.bytecode() == Bytecode::kToName ||
87 (last_.bytecode() == Bytecode::kLdaConstant &&
88 GetConstantForIndexOperand(&last_, 0)->IsName()));
89 }
90
91 void BytecodePeepholeOptimizer::UpdateCurrentBytecode(BytecodeNode* current) {
92 // Conditional jumps with boolean conditions are emiitted in
93 // ToBoolean form by the bytecode array builder,
94 // i.e. JumpIfToBooleanTrue rather JumpIfTrue. The ToBoolean element
95 // can be removed if the previous bytecode put a boolean value in
96 // the accumulator.
97 if (Bytecodes::IsJumpIfToBoolean(current->bytecode()) &&
98 Bytecodes::WritesBooleanToAccumulator(last_.bytecode())) {
99 Bytecode jump = Bytecodes::GetJumpWithoutToBoolean(current->bytecode());
100 current->set_bytecode(jump, current->operand(0), current->operand_scale());
101 }
102 }
103
104 bool BytecodePeepholeOptimizer::CanElideCurrent(
105 const BytecodeNode* const current) const {
106 if (Bytecodes::IsLdarOrStar(last_.bytecode()) &&
107 Bytecodes::IsLdarOrStar(current->bytecode()) &&
108 current->operand(0) == last_.operand(0)) {
109 // Ldar and Star make the accumulator and register hold equivalent
110 // values. Only the first bytecode is needed if there's a sequence
111 // of back-to-back of Ldar and Star bytecodes with the same operand.
112 return true;
113 } else if (current->bytecode() == Bytecode::kToName &&
114 LastBytecodePutsNameInAccumulator()) {
115 // If the previous bytecode ensured a name was in the accumulator,
116 // the type coercion ToName() can be elided.
117 return true;
118 } else {
119 return false;
120 }
121 }
122
123 bool BytecodePeepholeOptimizer::CanElideLast(
124 const BytecodeNode* const current) const {
125 if (!last_is_discardable_) {
126 return false;
127 }
128
129 if (last_.bytecode() == Bytecode::kNop) {
130 // Nop are placeholders for holding source position information
131 // and can be elided.
132 return true;
133 } else if (Bytecodes::IsAccumulatorLoadWithoutEffects(current->bytecode()) &&
134 Bytecodes::IsAccumulatorLoadWithoutEffects(last_.bytecode())) {
135 // The accumulator is invisible to the debugger. If there is a sequence of
136 // consecutive accumulator loads (that don't have side effects) then only
137 // the final load is potentially visible.
138 return true;
139 } else {
140 return false;
141 }
142 }
143
144 BytecodeNode* BytecodePeepholeOptimizer::Optimize(BytecodeNode* current) {
145 UpdateCurrentBytecode(current);
146
147 if (CanElideCurrent(current)) {
148 if (current->source_info().is_valid()) {
149 current->set_bytecode(Bytecode::kNop);
150 } else {
151 current = nullptr;
152 }
153 } else if (CanElideLast(current)) {
154 if (last_.source_info().is_valid()) {
155 current->source_info().Update(last_.source_info());
156 }
157 InvalidateLast();
158 }
159 return current;
160 }
161
162 } // namespace interpreter
163 } // namespace internal
164 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698