blob: 82eaeb28a46840d5087c1b0baf1ea754282641bb [file] [log] [blame]
Emily Bernier958fae72015-03-24 16:35:39 -04001// Copyright 2014 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/compiler/ast-loop-assignment-analyzer.h"
Ben Murdochf3b273f2017-01-17 12:11:28 +00006#include "src/ast/scopes.h"
7#include "src/compilation-info.h"
Emily Bernier958fae72015-03-24 16:35:39 -04008
9namespace v8 {
10namespace internal {
11namespace compiler {
12
13typedef class AstLoopAssignmentAnalyzer ALAA; // for code shortitude.
14
15ALAA::AstLoopAssignmentAnalyzer(Zone* zone, CompilationInfo* info)
Ben Murdoch014dc512016-03-22 12:00:34 +000016 : info_(info), zone_(zone), loop_stack_(zone) {
17 InitializeAstVisitor(info->isolate());
Emily Bernier958fae72015-03-24 16:35:39 -040018}
19
20
21LoopAssignmentAnalysis* ALAA::Analyze() {
Ben Murdoch014dc512016-03-22 12:00:34 +000022 LoopAssignmentAnalysis* a = new (zone_) LoopAssignmentAnalysis(zone_);
Emily Bernier958fae72015-03-24 16:35:39 -040023 result_ = a;
Ben Murdoch014dc512016-03-22 12:00:34 +000024 VisitStatements(info()->literal()->body());
25 result_ = nullptr;
Emily Bernier958fae72015-03-24 16:35:39 -040026 return a;
27}
28
29
30void ALAA::Enter(IterationStatement* loop) {
31 int num_variables = 1 + info()->scope()->num_parameters() +
32 info()->scope()->num_stack_slots();
Ben Murdoch014dc512016-03-22 12:00:34 +000033 BitVector* bits = new (zone_) BitVector(num_variables, zone_);
34 if (info()->is_osr() && info()->osr_ast_id() == loop->OsrEntryId())
35 bits->AddAll();
Emily Bernier958fae72015-03-24 16:35:39 -040036 loop_stack_.push_back(bits);
37}
38
39
40void ALAA::Exit(IterationStatement* loop) {
41 DCHECK(loop_stack_.size() > 0);
42 BitVector* bits = loop_stack_.back();
43 loop_stack_.pop_back();
44 if (!loop_stack_.empty()) {
45 loop_stack_.back()->Union(*bits);
46 }
47 result_->list_.push_back(
48 std::pair<IterationStatement*, BitVector*>(loop, bits));
49}
50
51
52// ---------------------------------------------------------------------------
53// -- Leaf nodes -------------------------------------------------------------
54// ---------------------------------------------------------------------------
55
56void ALAA::VisitVariableDeclaration(VariableDeclaration* leaf) {}
57void ALAA::VisitFunctionDeclaration(FunctionDeclaration* leaf) {}
Emily Bernier958fae72015-03-24 16:35:39 -040058void ALAA::VisitEmptyStatement(EmptyStatement* leaf) {}
59void ALAA::VisitContinueStatement(ContinueStatement* leaf) {}
60void ALAA::VisitBreakStatement(BreakStatement* leaf) {}
61void ALAA::VisitDebuggerStatement(DebuggerStatement* leaf) {}
62void ALAA::VisitFunctionLiteral(FunctionLiteral* leaf) {}
63void ALAA::VisitNativeFunctionLiteral(NativeFunctionLiteral* leaf) {}
64void ALAA::VisitVariableProxy(VariableProxy* leaf) {}
65void ALAA::VisitLiteral(Literal* leaf) {}
66void ALAA::VisitRegExpLiteral(RegExpLiteral* leaf) {}
67void ALAA::VisitThisFunction(ThisFunction* leaf) {}
Ben Murdoch014dc512016-03-22 12:00:34 +000068void ALAA::VisitSuperPropertyReference(SuperPropertyReference* leaf) {}
69void ALAA::VisitSuperCallReference(SuperCallReference* leaf) {}
Emily Bernier958fae72015-03-24 16:35:39 -040070
71
72// ---------------------------------------------------------------------------
73// -- Pass-through nodes------------------------------------------------------
74// ---------------------------------------------------------------------------
Emily Bernier958fae72015-03-24 16:35:39 -040075void ALAA::VisitBlock(Block* stmt) { VisitStatements(stmt->statements()); }
76
77
Ben Murdoch014dc512016-03-22 12:00:34 +000078void ALAA::VisitDoExpression(DoExpression* expr) {
79 Visit(expr->block());
80 Visit(expr->result());
81}
82
83
Emily Bernier958fae72015-03-24 16:35:39 -040084void ALAA::VisitExpressionStatement(ExpressionStatement* stmt) {
85 Visit(stmt->expression());
86}
87
88
89void ALAA::VisitIfStatement(IfStatement* stmt) {
90 Visit(stmt->condition());
91 Visit(stmt->then_statement());
92 Visit(stmt->else_statement());
93}
94
95
96void ALAA::VisitReturnStatement(ReturnStatement* stmt) {
97 Visit(stmt->expression());
98}
99
100
101void ALAA::VisitWithStatement(WithStatement* stmt) {
102 Visit(stmt->expression());
103 Visit(stmt->statement());
104}
105
106
107void ALAA::VisitSwitchStatement(SwitchStatement* stmt) {
108 Visit(stmt->tag());
109 ZoneList<CaseClause*>* clauses = stmt->cases();
110 for (int i = 0; i < clauses->length(); i++) {
111 Visit(clauses->at(i));
112 }
113}
114
115
116void ALAA::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
117 Visit(stmt->try_block());
118 Visit(stmt->finally_block());
119}
120
121
122void ALAA::VisitClassLiteral(ClassLiteral* e) {
123 VisitIfNotNull(e->extends());
124 VisitIfNotNull(e->constructor());
Ben Murdochf3b273f2017-01-17 12:11:28 +0000125 ZoneList<ClassLiteralProperty*>* properties = e->properties();
Emily Bernier958fae72015-03-24 16:35:39 -0400126 for (int i = 0; i < properties->length(); i++) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000127 Visit(properties->at(i)->key());
Emily Bernier958fae72015-03-24 16:35:39 -0400128 Visit(properties->at(i)->value());
129 }
130}
131
132
133void ALAA::VisitConditional(Conditional* e) {
134 Visit(e->condition());
135 Visit(e->then_expression());
136 Visit(e->else_expression());
137}
138
139
140void ALAA::VisitObjectLiteral(ObjectLiteral* e) {
141 ZoneList<ObjectLiteralProperty*>* properties = e->properties();
142 for (int i = 0; i < properties->length(); i++) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000143 Visit(properties->at(i)->key());
Emily Bernier958fae72015-03-24 16:35:39 -0400144 Visit(properties->at(i)->value());
145 }
146}
147
148
149void ALAA::VisitArrayLiteral(ArrayLiteral* e) { VisitExpressions(e->values()); }
150
151
152void ALAA::VisitYield(Yield* stmt) {
153 Visit(stmt->generator_object());
154 Visit(stmt->expression());
155}
156
157
158void ALAA::VisitThrow(Throw* stmt) { Visit(stmt->exception()); }
159
160
161void ALAA::VisitProperty(Property* e) {
162 Visit(e->obj());
163 Visit(e->key());
164}
165
166
167void ALAA::VisitCall(Call* e) {
168 Visit(e->expression());
169 VisitExpressions(e->arguments());
170}
171
172
173void ALAA::VisitCallNew(CallNew* e) {
174 Visit(e->expression());
175 VisitExpressions(e->arguments());
176}
177
178
179void ALAA::VisitCallRuntime(CallRuntime* e) {
180 VisitExpressions(e->arguments());
181}
182
183
184void ALAA::VisitUnaryOperation(UnaryOperation* e) { Visit(e->expression()); }
185
186
187void ALAA::VisitBinaryOperation(BinaryOperation* e) {
188 Visit(e->left());
189 Visit(e->right());
190}
191
192
193void ALAA::VisitCompareOperation(CompareOperation* e) {
194 Visit(e->left());
195 Visit(e->right());
196}
197
198
Ben Murdoch109988c2016-05-18 11:27:45 +0100199void ALAA::VisitSpread(Spread* e) { UNREACHABLE(); }
Ben Murdoch014dc512016-03-22 12:00:34 +0000200
201
202void ALAA::VisitEmptyParentheses(EmptyParentheses* e) { UNREACHABLE(); }
203
204
Emily Bernier958fae72015-03-24 16:35:39 -0400205void ALAA::VisitCaseClause(CaseClause* cc) {
206 if (!cc->is_default()) Visit(cc->label());
207 VisitStatements(cc->statements());
208}
209
210
Ben Murdoch014dc512016-03-22 12:00:34 +0000211void ALAA::VisitSloppyBlockFunctionStatement(
212 SloppyBlockFunctionStatement* stmt) {
213 Visit(stmt->statement());
Emily Bernier958fae72015-03-24 16:35:39 -0400214}
215
216
Ben Murdoch014dc512016-03-22 12:00:34 +0000217// ---------------------------------------------------------------------------
218// -- Interesting nodes-------------------------------------------------------
219// ---------------------------------------------------------------------------
Emily Bernier958fae72015-03-24 16:35:39 -0400220void ALAA::VisitTryCatchStatement(TryCatchStatement* stmt) {
221 Visit(stmt->try_block());
222 Visit(stmt->catch_block());
223 // TODO(turbofan): are catch variables well-scoped?
224 AnalyzeAssignment(stmt->variable());
225}
226
227
228void ALAA::VisitDoWhileStatement(DoWhileStatement* loop) {
229 Enter(loop);
230 Visit(loop->body());
231 Visit(loop->cond());
232 Exit(loop);
233}
234
235
236void ALAA::VisitWhileStatement(WhileStatement* loop) {
237 Enter(loop);
238 Visit(loop->cond());
239 Visit(loop->body());
240 Exit(loop);
241}
242
243
244void ALAA::VisitForStatement(ForStatement* loop) {
245 VisitIfNotNull(loop->init());
246 Enter(loop);
247 VisitIfNotNull(loop->cond());
248 Visit(loop->body());
249 VisitIfNotNull(loop->next());
250 Exit(loop);
251}
252
253
254void ALAA::VisitForInStatement(ForInStatement* loop) {
Ben Murdochf91f0612016-11-29 16:50:11 +0000255 Expression* l = loop->each();
Emily Bernier958fae72015-03-24 16:35:39 -0400256 Enter(loop);
Ben Murdochf91f0612016-11-29 16:50:11 +0000257 Visit(l);
Emily Bernier958fae72015-03-24 16:35:39 -0400258 Visit(loop->subject());
259 Visit(loop->body());
Ben Murdochf91f0612016-11-29 16:50:11 +0000260 if (l->IsVariableProxy()) AnalyzeAssignment(l->AsVariableProxy()->var());
Emily Bernier958fae72015-03-24 16:35:39 -0400261 Exit(loop);
262}
263
264
265void ALAA::VisitForOfStatement(ForOfStatement* loop) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000266 Visit(loop->assign_iterator());
Emily Bernier958fae72015-03-24 16:35:39 -0400267 Enter(loop);
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100268 Visit(loop->next_result());
269 Visit(loop->result_done());
Ben Murdoch014dc512016-03-22 12:00:34 +0000270 Visit(loop->assign_each());
Emily Bernier958fae72015-03-24 16:35:39 -0400271 Visit(loop->body());
272 Exit(loop);
273}
274
275
276void ALAA::VisitAssignment(Assignment* stmt) {
277 Expression* l = stmt->target();
278 Visit(l);
279 Visit(stmt->value());
280 if (l->IsVariableProxy()) AnalyzeAssignment(l->AsVariableProxy()->var());
281}
282
283
284void ALAA::VisitCountOperation(CountOperation* e) {
285 Expression* l = e->expression();
286 Visit(l);
287 if (l->IsVariableProxy()) AnalyzeAssignment(l->AsVariableProxy()->var());
288}
289
290
Ben Murdoch109988c2016-05-18 11:27:45 +0100291void ALAA::VisitRewritableExpression(RewritableExpression* expr) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000292 Visit(expr->expression());
293}
294
295
Emily Bernier958fae72015-03-24 16:35:39 -0400296void ALAA::AnalyzeAssignment(Variable* var) {
297 if (!loop_stack_.empty() && var->IsStackAllocated()) {
298 loop_stack_.back()->Add(GetVariableIndex(info()->scope(), var));
299 }
300}
301
Ben Murdochf91f0612016-11-29 16:50:11 +0000302int ALAA::GetVariableIndex(DeclarationScope* scope, Variable* var) {
Emily Bernier958fae72015-03-24 16:35:39 -0400303 CHECK(var->IsStackAllocated());
304 if (var->is_this()) return 0;
305 if (var->IsParameter()) return 1 + var->index();
306 return 1 + scope->num_parameters() + var->index();
307}
308
Ben Murdochf91f0612016-11-29 16:50:11 +0000309int LoopAssignmentAnalysis::GetAssignmentCountForTesting(
310 DeclarationScope* scope, Variable* var) {
Emily Bernier958fae72015-03-24 16:35:39 -0400311 int count = 0;
312 int var_index = AstLoopAssignmentAnalyzer::GetVariableIndex(scope, var);
313 for (size_t i = 0; i < list_.size(); i++) {
314 if (list_[i].second->Contains(var_index)) count++;
315 }
316 return count;
317}
Ben Murdoch014dc512016-03-22 12:00:34 +0000318} // namespace compiler
319} // namespace internal
320} // namespace v8