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

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: Incorporate review comments. 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_(nullptr),
21 last_is_discardable_(true) {}
22
23 // override
24 size_t BytecodePeepholeOptimizer::FlushForOffset() {
25 size_t buffered_size = next_stage_->FlushForOffset();
26 if (last_ != nullptr) {
27 if (last_->bytecode() == Bytecode::kNop &&
28 !last_->source_info().is_statement()) {
29 last_->Release();
30 last_ = nullptr;
31 } else {
32 buffered_size += last_->Size();
33 last_is_discardable_ = false;
34 }
35 }
36 return buffered_size;
37 }
38
39 // override
40 void BytecodePeepholeOptimizer::LeaveBasicBlock() {
rmcilroy 2016/05/10 11:14:09 How about FlushForNewBasicBlock()?
oth 2016/05/11 13:17:30 I hate to bikeshed, but it really is used at the e
rmcilroy 2016/05/12 12:15:13 Works for me, thanks!
41 if (last_ != nullptr) {
42 next_stage_->Write(last_);
43 last_ = nullptr;
44 }
45 last_is_discardable_ = false;
46 next_stage_->LeaveBasicBlock();
47 }
48
49 // override
50 void BytecodePeepholeOptimizer::Write(BytecodeNode* node) {
51 // Attempt optimization if there is an earlier node to optimize with.
52 if (last_ != nullptr) {
53 node = Optimize(node);
54 }
55
56 // Only output if optimization did not remove earlier node.
57 if (last_ != nullptr) {
58 next_stage_->Write(last_);
59 }
60
61 last_ = node;
62 last_is_discardable_ = true;
63 }
64
65 Handle<Object> BytecodePeepholeOptimizer::GetConstantForIndexOperand(
66 const BytecodeNode* const node, int index) const {
67 DCHECK_LE(index, node->operand_count());
68 DCHECK_EQ(Bytecodes::GetOperandType(node->bytecode(), 0), OperandType::kIdx);
69 uint32_t index_operand = node->operands()[0];
70 return constant_array_builder_->At(index_operand);
71 }
72
73 void BytecodePeepholeOptimizer::UpdateCurrentBytecode(BytecodeNode* current) {
74 if (Bytecodes::IsJumpIfToBoolean(current->bytecode()) &&
75 Bytecodes::WritesAccumulatorWithBoolean(last_->bytecode())) {
76 Bytecode jump = Bytecodes::GetJumpWithoutToBoolean(current->bytecode());
rmcilroy 2016/05/10 11:14:09 nit - comment.
oth 2016/05/11 13:17:31 Done.
77 current->replace_bytecode(jump);
78 }
79 }
80
81 bool BytecodePeepholeOptimizer::CanElideCurrent(
82 const BytecodeNode* const current) const {
83 if ((last_->bytecode() == Bytecode::kLdar ||
84 last_->bytecode() == Bytecode::kStar) &&
rmcilroy 2016/05/10 11:14:10 nit - add Bytecodes::IsLdarOrStar() helper
oth 2016/05/11 13:17:30 Done.
85 (current->bytecode() == Bytecode::kLdar ||
86 current->bytecode() == Bytecode::kStar) &&
87 current->operands()[0] == last_->operands()[0]) {
88 return true;
rmcilroy 2016/05/10 11:14:09 Comment on all branches with reasoning behind deci
oth 2016/05/11 13:17:31 Done.
89 } else if (current->bytecode() == Bytecode::kToName &&
90 (last_->bytecode() == Bytecode::kTypeOf ||
91 (last_->bytecode() == Bytecode::kLdaConstant &&
92 GetConstantForIndexOperand(last_, 0)->IsName()) ||
93 last_->bytecode() == Bytecode::kToName)) {
rmcilroy 2016/05/10 11:14:10 This if check is pretty difficult to parse. Could
oth 2016/05/11 13:17:30 Done.
94 return true;
95 } else {
96 return false;
97 }
98 }
99
100 bool BytecodePeepholeOptimizer::CanElideLast(
101 const BytecodeNode* const current) const {
102 if (!last_is_discardable_ || (last_->source_info().is_statement() &&
103 current->source_info().is_statement())) {
104 return false;
rmcilroy 2016/05/10 11:14:10 Comment on all branches with reasoning behind deci
oth 2016/05/11 13:17:30 Done.
105 } else if (last_->bytecode() == Bytecode::kNop) {
106 return true;
107 } else if (Bytecodes::IsAccumulatorLoadWithoutEffects(current->bytecode()) &&
108 Bytecodes::IsAccumulatorLoadWithoutEffects(last_->bytecode())) {
109 return true;
110 } else {
111 return false;
112 }
113 }
114
115 BytecodeNode* BytecodePeepholeOptimizer::Optimize(BytecodeNode* current) {
116 UpdateCurrentBytecode(current);
117
118 if (CanElideCurrent(current)) {
119 if (current->source_info().is_valid()) {
120 current->replace_bytecode(Bytecode::kNop);
121 } else {
122 current->Release();
123 current = nullptr;
124 }
125 } else if (CanElideLast(current)) {
126 if (last_->source_info().is_valid()) {
127 current->source_info().Update(last_->source_info());
128 }
129 last_->Release();
130 last_ = nullptr;
131 }
132
133 return current;
134 }
135
136 } // namespace interpreter
137 } // namespace internal
138 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698