blob: be824460f0a1fb1b559cccc89391912c84ff784c [file] [log] [blame]
Leon Clarke4515c472010-02-03 11:58:03 +00001// Copyright 2010 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include "v8.h"
29
30#include "data-flow.h"
Steve Block6ded16b2010-05-10 14:33:55 +010031#include "scopes.h"
Leon Clarke4515c472010-02-03 11:58:03 +000032
33namespace v8 {
34namespace internal {
35
36
Steve Block6ded16b2010-05-10 14:33:55 +010037#ifdef DEBUG
38void BitVector::Print() {
39 bool first = true;
40 PrintF("{");
41 for (int i = 0; i < length(); i++) {
42 if (Contains(i)) {
43 if (!first) PrintF(",");
44 first = false;
Ben Murdochf87a2032010-10-22 12:50:53 +010045 PrintF("%d", i);
Steve Block6ded16b2010-05-10 14:33:55 +010046 }
47 }
48 PrintF("}");
49}
50#endif
51
52
Ben Murdochf87a2032010-10-22 12:50:53 +010053bool AssignedVariablesAnalyzer::Analyze(CompilationInfo* info) {
54 info_ = info;
55 Scope* scope = info->scope();
Kristian Monsen80d68ea2010-09-08 11:05:35 +010056 int variables = scope->num_parameters() + scope->num_stack_slots();
57 if (variables == 0) return true;
58 av_.ExpandTo(variables);
Ben Murdochf87a2032010-10-22 12:50:53 +010059 VisitStatements(info->function()->body());
Kristian Monsen80d68ea2010-09-08 11:05:35 +010060 return !HasStackOverflow();
Andrei Popescu402d9372010-02-26 13:31:12 +000061}
62
63
Steve Block6ded16b2010-05-10 14:33:55 +010064Variable* AssignedVariablesAnalyzer::FindSmiLoopVariable(ForStatement* stmt) {
65 // The loop must have all necessary parts.
66 if (stmt->init() == NULL || stmt->cond() == NULL || stmt->next() == NULL) {
67 return NULL;
68 }
69 // The initialization statement has to be a simple assignment.
70 Assignment* init = stmt->init()->StatementAsSimpleAssignment();
71 if (init == NULL) return NULL;
Andrei Popescu402d9372010-02-26 13:31:12 +000072
Steve Block6ded16b2010-05-10 14:33:55 +010073 // We only deal with local variables.
74 Variable* loop_var = init->target()->AsVariableProxy()->AsVariable();
75 if (loop_var == NULL || !loop_var->IsStackAllocated()) return NULL;
76
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +010077 // Don't try to get clever with const or dynamic variables.
78 if (loop_var->mode() != Variable::VAR) return NULL;
79
Steve Block6ded16b2010-05-10 14:33:55 +010080 // The initial value has to be a smi.
81 Literal* init_lit = init->value()->AsLiteral();
82 if (init_lit == NULL || !init_lit->handle()->IsSmi()) return NULL;
83 int init_value = Smi::cast(*init_lit->handle())->value();
84
85 // The condition must be a compare of variable with <, <=, >, or >=.
86 CompareOperation* cond = stmt->cond()->AsCompareOperation();
87 if (cond == NULL) return NULL;
88 if (cond->op() != Token::LT
89 && cond->op() != Token::LTE
90 && cond->op() != Token::GT
91 && cond->op() != Token::GTE) return NULL;
92
93 // The lhs must be the same variable as in the init expression.
94 if (cond->left()->AsVariableProxy()->AsVariable() != loop_var) return NULL;
95
96 // The rhs must be a smi.
97 Literal* term_lit = cond->right()->AsLiteral();
98 if (term_lit == NULL || !term_lit->handle()->IsSmi()) return NULL;
99 int term_value = Smi::cast(*term_lit->handle())->value();
100
101 // The count operation updates the same variable as in the init expression.
102 CountOperation* update = stmt->next()->StatementAsCountOperation();
103 if (update == NULL) return NULL;
104 if (update->expression()->AsVariableProxy()->AsVariable() != loop_var) {
105 return NULL;
106 }
107
108 // The direction of the count operation must agree with the start and the end
109 // value. We currently do not allow the initial value to be the same as the
110 // terminal value. This _would_ be ok as long as the loop body never executes
111 // or executes exactly one time.
112 if (init_value == term_value) return NULL;
113 if (init_value < term_value && update->op() != Token::INC) return NULL;
114 if (init_value > term_value && update->op() != Token::DEC) return NULL;
115
116 // Check that the update operation cannot overflow the smi range. This can
117 // occur in the two cases where the loop bound is equal to the largest or
118 // smallest smi.
119 if (update->op() == Token::INC && term_value == Smi::kMaxValue) return NULL;
120 if (update->op() == Token::DEC && term_value == Smi::kMinValue) return NULL;
121
122 // Found a smi loop variable.
123 return loop_var;
124}
125
126int AssignedVariablesAnalyzer::BitIndex(Variable* var) {
127 ASSERT(var != NULL);
128 ASSERT(var->IsStackAllocated());
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100129 Slot* slot = var->AsSlot();
Steve Block6ded16b2010-05-10 14:33:55 +0100130 if (slot->type() == Slot::PARAMETER) {
131 return slot->index();
132 } else {
Ben Murdochf87a2032010-10-22 12:50:53 +0100133 return info_->scope()->num_parameters() + slot->index();
Andrei Popescu402d9372010-02-26 13:31:12 +0000134 }
135}
136
137
Steve Block6ded16b2010-05-10 14:33:55 +0100138void AssignedVariablesAnalyzer::RecordAssignedVar(Variable* var) {
139 ASSERT(var != NULL);
140 if (var->IsStackAllocated()) {
141 av_.Add(BitIndex(var));
Andrei Popescu402d9372010-02-26 13:31:12 +0000142 }
143}
144
145
Steve Block6ded16b2010-05-10 14:33:55 +0100146void AssignedVariablesAnalyzer::MarkIfTrivial(Expression* expr) {
147 Variable* var = expr->AsVariableProxy()->AsVariable();
148 if (var != NULL &&
149 var->IsStackAllocated() &&
150 !var->is_arguments() &&
151 var->mode() != Variable::CONST &&
152 (var->is_this() || !av_.Contains(BitIndex(var)))) {
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100153 expr->AsVariableProxy()->MarkAsTrivial();
Andrei Popescu402d9372010-02-26 13:31:12 +0000154 }
155}
156
157
Steve Block6ded16b2010-05-10 14:33:55 +0100158void AssignedVariablesAnalyzer::ProcessExpression(Expression* expr) {
159 BitVector saved_av(av_);
160 av_.Clear();
161 Visit(expr);
162 av_.Union(saved_av);
Andrei Popescu402d9372010-02-26 13:31:12 +0000163}
164
Steve Block6ded16b2010-05-10 14:33:55 +0100165void AssignedVariablesAnalyzer::VisitBlock(Block* stmt) {
Andrei Popescu402d9372010-02-26 13:31:12 +0000166 VisitStatements(stmt->statements());
167}
168
169
Steve Block6ded16b2010-05-10 14:33:55 +0100170void AssignedVariablesAnalyzer::VisitExpressionStatement(
Andrei Popescu402d9372010-02-26 13:31:12 +0000171 ExpressionStatement* stmt) {
Steve Block6ded16b2010-05-10 14:33:55 +0100172 ProcessExpression(stmt->expression());
Andrei Popescu402d9372010-02-26 13:31:12 +0000173}
174
175
Steve Block6ded16b2010-05-10 14:33:55 +0100176void AssignedVariablesAnalyzer::VisitEmptyStatement(EmptyStatement* stmt) {
Andrei Popescu402d9372010-02-26 13:31:12 +0000177 // Do nothing.
178}
179
180
Steve Block6ded16b2010-05-10 14:33:55 +0100181void AssignedVariablesAnalyzer::VisitIfStatement(IfStatement* stmt) {
182 ProcessExpression(stmt->condition());
183 Visit(stmt->then_statement());
184 Visit(stmt->else_statement());
Andrei Popescu402d9372010-02-26 13:31:12 +0000185}
186
187
Steve Block6ded16b2010-05-10 14:33:55 +0100188void AssignedVariablesAnalyzer::VisitContinueStatement(
189 ContinueStatement* stmt) {
190 // Nothing to do.
Andrei Popescu402d9372010-02-26 13:31:12 +0000191}
192
193
Steve Block6ded16b2010-05-10 14:33:55 +0100194void AssignedVariablesAnalyzer::VisitBreakStatement(BreakStatement* stmt) {
195 // Nothing to do.
Andrei Popescu402d9372010-02-26 13:31:12 +0000196}
197
198
Steve Block6ded16b2010-05-10 14:33:55 +0100199void AssignedVariablesAnalyzer::VisitReturnStatement(ReturnStatement* stmt) {
200 ProcessExpression(stmt->expression());
Andrei Popescu402d9372010-02-26 13:31:12 +0000201}
202
203
Steve Block6ded16b2010-05-10 14:33:55 +0100204void AssignedVariablesAnalyzer::VisitWithEnterStatement(
Andrei Popescu402d9372010-02-26 13:31:12 +0000205 WithEnterStatement* stmt) {
Steve Block6ded16b2010-05-10 14:33:55 +0100206 ProcessExpression(stmt->expression());
Andrei Popescu402d9372010-02-26 13:31:12 +0000207}
208
209
Steve Block6ded16b2010-05-10 14:33:55 +0100210void AssignedVariablesAnalyzer::VisitWithExitStatement(
211 WithExitStatement* stmt) {
212 // Nothing to do.
Andrei Popescu402d9372010-02-26 13:31:12 +0000213}
214
215
Steve Block6ded16b2010-05-10 14:33:55 +0100216void AssignedVariablesAnalyzer::VisitSwitchStatement(SwitchStatement* stmt) {
217 BitVector result(av_);
218 av_.Clear();
219 Visit(stmt->tag());
220 result.Union(av_);
221 for (int i = 0; i < stmt->cases()->length(); i++) {
222 CaseClause* clause = stmt->cases()->at(i);
223 if (!clause->is_default()) {
224 av_.Clear();
225 Visit(clause->label());
226 result.Union(av_);
227 }
228 VisitStatements(clause->statements());
229 }
230 av_.Union(result);
Andrei Popescu402d9372010-02-26 13:31:12 +0000231}
232
233
Steve Block6ded16b2010-05-10 14:33:55 +0100234void AssignedVariablesAnalyzer::VisitDoWhileStatement(DoWhileStatement* stmt) {
235 ProcessExpression(stmt->cond());
236 Visit(stmt->body());
Andrei Popescu402d9372010-02-26 13:31:12 +0000237}
238
239
Steve Block6ded16b2010-05-10 14:33:55 +0100240void AssignedVariablesAnalyzer::VisitWhileStatement(WhileStatement* stmt) {
241 ProcessExpression(stmt->cond());
242 Visit(stmt->body());
Andrei Popescu402d9372010-02-26 13:31:12 +0000243}
244
245
Steve Block6ded16b2010-05-10 14:33:55 +0100246void AssignedVariablesAnalyzer::VisitForStatement(ForStatement* stmt) {
247 if (stmt->init() != NULL) Visit(stmt->init());
Steve Block6ded16b2010-05-10 14:33:55 +0100248 if (stmt->cond() != NULL) ProcessExpression(stmt->cond());
Steve Block6ded16b2010-05-10 14:33:55 +0100249 if (stmt->next() != NULL) Visit(stmt->next());
250
251 // Process loop body. After visiting the loop body av_ contains
252 // the assigned variables of the loop body.
253 BitVector saved_av(av_);
254 av_.Clear();
255 Visit(stmt->body());
256
257 Variable* var = FindSmiLoopVariable(stmt);
258 if (var != NULL && !av_.Contains(BitIndex(var))) {
259 stmt->set_loop_variable(var);
260 }
Steve Block6ded16b2010-05-10 14:33:55 +0100261 av_.Union(saved_av);
Andrei Popescu402d9372010-02-26 13:31:12 +0000262}
263
264
Steve Block6ded16b2010-05-10 14:33:55 +0100265void AssignedVariablesAnalyzer::VisitForInStatement(ForInStatement* stmt) {
266 ProcessExpression(stmt->each());
267 ProcessExpression(stmt->enumerable());
268 Visit(stmt->body());
Andrei Popescu402d9372010-02-26 13:31:12 +0000269}
270
271
Steve Block6ded16b2010-05-10 14:33:55 +0100272void AssignedVariablesAnalyzer::VisitTryCatchStatement(
273 TryCatchStatement* stmt) {
274 Visit(stmt->try_block());
275 Visit(stmt->catch_block());
Andrei Popescu402d9372010-02-26 13:31:12 +0000276}
277
278
Steve Block6ded16b2010-05-10 14:33:55 +0100279void AssignedVariablesAnalyzer::VisitTryFinallyStatement(
Andrei Popescu402d9372010-02-26 13:31:12 +0000280 TryFinallyStatement* stmt) {
Steve Block6ded16b2010-05-10 14:33:55 +0100281 Visit(stmt->try_block());
282 Visit(stmt->finally_block());
Andrei Popescu402d9372010-02-26 13:31:12 +0000283}
284
285
Steve Block6ded16b2010-05-10 14:33:55 +0100286void AssignedVariablesAnalyzer::VisitDebuggerStatement(
Andrei Popescu402d9372010-02-26 13:31:12 +0000287 DebuggerStatement* stmt) {
Steve Block6ded16b2010-05-10 14:33:55 +0100288 // Nothing to do.
289}
290
291
292void AssignedVariablesAnalyzer::VisitFunctionLiteral(FunctionLiteral* expr) {
293 // Nothing to do.
294 ASSERT(av_.IsEmpty());
295}
296
297
298void AssignedVariablesAnalyzer::VisitSharedFunctionInfoLiteral(
299 SharedFunctionInfoLiteral* expr) {
300 // Nothing to do.
301 ASSERT(av_.IsEmpty());
302}
303
304
305void AssignedVariablesAnalyzer::VisitConditional(Conditional* expr) {
306 ASSERT(av_.IsEmpty());
307
308 Visit(expr->condition());
309
310 BitVector result(av_);
311 av_.Clear();
312 Visit(expr->then_expression());
313 result.Union(av_);
314
315 av_.Clear();
316 Visit(expr->else_expression());
317 av_.Union(result);
318}
319
320
321void AssignedVariablesAnalyzer::VisitSlot(Slot* expr) {
Andrei Popescu402d9372010-02-26 13:31:12 +0000322 UNREACHABLE();
323}
324
325
Steve Block6ded16b2010-05-10 14:33:55 +0100326void AssignedVariablesAnalyzer::VisitVariableProxy(VariableProxy* expr) {
327 // Nothing to do.
328 ASSERT(av_.IsEmpty());
Andrei Popescu402d9372010-02-26 13:31:12 +0000329}
330
331
Steve Block6ded16b2010-05-10 14:33:55 +0100332void AssignedVariablesAnalyzer::VisitLiteral(Literal* expr) {
333 // Nothing to do.
334 ASSERT(av_.IsEmpty());
Andrei Popescu402d9372010-02-26 13:31:12 +0000335}
336
337
Steve Block6ded16b2010-05-10 14:33:55 +0100338void AssignedVariablesAnalyzer::VisitRegExpLiteral(RegExpLiteral* expr) {
339 // Nothing to do.
340 ASSERT(av_.IsEmpty());
Andrei Popescu402d9372010-02-26 13:31:12 +0000341}
342
343
Steve Block6ded16b2010-05-10 14:33:55 +0100344void AssignedVariablesAnalyzer::VisitObjectLiteral(ObjectLiteral* expr) {
345 ASSERT(av_.IsEmpty());
346 BitVector result(av_.length());
347 for (int i = 0; i < expr->properties()->length(); i++) {
348 Visit(expr->properties()->at(i)->value());
349 result.Union(av_);
350 av_.Clear();
351 }
352 av_ = result;
Andrei Popescu402d9372010-02-26 13:31:12 +0000353}
354
355
Steve Block6ded16b2010-05-10 14:33:55 +0100356void AssignedVariablesAnalyzer::VisitArrayLiteral(ArrayLiteral* expr) {
357 ASSERT(av_.IsEmpty());
358 BitVector result(av_.length());
359 for (int i = 0; i < expr->values()->length(); i++) {
360 Visit(expr->values()->at(i));
361 result.Union(av_);
362 av_.Clear();
363 }
364 av_ = result;
Andrei Popescu402d9372010-02-26 13:31:12 +0000365}
366
367
Steve Block6ded16b2010-05-10 14:33:55 +0100368void AssignedVariablesAnalyzer::VisitCatchExtensionObject(
Andrei Popescu402d9372010-02-26 13:31:12 +0000369 CatchExtensionObject* expr) {
Steve Block6ded16b2010-05-10 14:33:55 +0100370 ASSERT(av_.IsEmpty());
371 Visit(expr->key());
372 ProcessExpression(expr->value());
Andrei Popescu402d9372010-02-26 13:31:12 +0000373}
374
375
Steve Block6ded16b2010-05-10 14:33:55 +0100376void AssignedVariablesAnalyzer::VisitAssignment(Assignment* expr) {
377 ASSERT(av_.IsEmpty());
378
379 // There are three kinds of assignments: variable assignments, property
380 // assignments, and reference errors (invalid left-hand sides).
381 Variable* var = expr->target()->AsVariableProxy()->AsVariable();
Andrei Popescu402d9372010-02-26 13:31:12 +0000382 Property* prop = expr->target()->AsProperty();
Steve Block6ded16b2010-05-10 14:33:55 +0100383 ASSERT(var == NULL || prop == NULL);
Andrei Popescu402d9372010-02-26 13:31:12 +0000384
Steve Block6ded16b2010-05-10 14:33:55 +0100385 if (var != NULL) {
386 MarkIfTrivial(expr->value());
387 Visit(expr->value());
388 if (expr->is_compound()) {
389 // Left-hand side occurs also as an rvalue.
390 MarkIfTrivial(expr->target());
391 ProcessExpression(expr->target());
392 }
393 RecordAssignedVar(var);
Andrei Popescu402d9372010-02-26 13:31:12 +0000394
Steve Block6ded16b2010-05-10 14:33:55 +0100395 } else if (prop != NULL) {
396 MarkIfTrivial(expr->value());
397 Visit(expr->value());
398 if (!prop->key()->IsPropertyName()) {
399 MarkIfTrivial(prop->key());
400 ProcessExpression(prop->key());
401 }
402 MarkIfTrivial(prop->obj());
403 ProcessExpression(prop->obj());
404
405 } else {
406 Visit(expr->target());
407 }
Andrei Popescu402d9372010-02-26 13:31:12 +0000408}
409
410
Steve Block6ded16b2010-05-10 14:33:55 +0100411void AssignedVariablesAnalyzer::VisitThrow(Throw* expr) {
412 ASSERT(av_.IsEmpty());
413 Visit(expr->exception());
Andrei Popescu402d9372010-02-26 13:31:12 +0000414}
415
416
Steve Block6ded16b2010-05-10 14:33:55 +0100417void AssignedVariablesAnalyzer::VisitProperty(Property* expr) {
418 ASSERT(av_.IsEmpty());
419 if (!expr->key()->IsPropertyName()) {
420 MarkIfTrivial(expr->key());
421 Visit(expr->key());
422 }
423 MarkIfTrivial(expr->obj());
424 ProcessExpression(expr->obj());
Andrei Popescu402d9372010-02-26 13:31:12 +0000425}
426
427
Steve Block6ded16b2010-05-10 14:33:55 +0100428void AssignedVariablesAnalyzer::VisitCall(Call* expr) {
429 ASSERT(av_.IsEmpty());
430 Visit(expr->expression());
431 BitVector result(av_);
432 for (int i = 0; i < expr->arguments()->length(); i++) {
433 av_.Clear();
434 Visit(expr->arguments()->at(i));
435 result.Union(av_);
436 }
437 av_ = result;
Andrei Popescu402d9372010-02-26 13:31:12 +0000438}
439
440
Steve Block6ded16b2010-05-10 14:33:55 +0100441void AssignedVariablesAnalyzer::VisitCallNew(CallNew* expr) {
442 ASSERT(av_.IsEmpty());
443 Visit(expr->expression());
444 BitVector result(av_);
445 for (int i = 0; i < expr->arguments()->length(); i++) {
446 av_.Clear();
447 Visit(expr->arguments()->at(i));
448 result.Union(av_);
449 }
450 av_ = result;
Andrei Popescu402d9372010-02-26 13:31:12 +0000451}
452
453
Steve Block6ded16b2010-05-10 14:33:55 +0100454void AssignedVariablesAnalyzer::VisitCallRuntime(CallRuntime* expr) {
455 ASSERT(av_.IsEmpty());
456 BitVector result(av_);
457 for (int i = 0; i < expr->arguments()->length(); i++) {
458 av_.Clear();
459 Visit(expr->arguments()->at(i));
460 result.Union(av_);
461 }
462 av_ = result;
Andrei Popescu402d9372010-02-26 13:31:12 +0000463}
464
465
Steve Block6ded16b2010-05-10 14:33:55 +0100466void AssignedVariablesAnalyzer::VisitUnaryOperation(UnaryOperation* expr) {
467 ASSERT(av_.IsEmpty());
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100468 MarkIfTrivial(expr->expression());
Steve Block6ded16b2010-05-10 14:33:55 +0100469 Visit(expr->expression());
Andrei Popescu402d9372010-02-26 13:31:12 +0000470}
471
472
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100473void AssignedVariablesAnalyzer::VisitIncrementOperation(
474 IncrementOperation* expr) {
475 UNREACHABLE();
476}
477
478
Steve Block6ded16b2010-05-10 14:33:55 +0100479void AssignedVariablesAnalyzer::VisitCountOperation(CountOperation* expr) {
480 ASSERT(av_.IsEmpty());
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100481 if (expr->is_prefix()) MarkIfTrivial(expr->expression());
Steve Block6ded16b2010-05-10 14:33:55 +0100482 Visit(expr->expression());
483
484 Variable* var = expr->expression()->AsVariableProxy()->AsVariable();
485 if (var != NULL) RecordAssignedVar(var);
Andrei Popescu402d9372010-02-26 13:31:12 +0000486}
487
488
Steve Block6ded16b2010-05-10 14:33:55 +0100489void AssignedVariablesAnalyzer::VisitBinaryOperation(BinaryOperation* expr) {
490 ASSERT(av_.IsEmpty());
491 MarkIfTrivial(expr->right());
Andrei Popescu402d9372010-02-26 13:31:12 +0000492 Visit(expr->right());
Steve Block6ded16b2010-05-10 14:33:55 +0100493 MarkIfTrivial(expr->left());
494 ProcessExpression(expr->left());
Andrei Popescu402d9372010-02-26 13:31:12 +0000495}
496
497
Steve Block6ded16b2010-05-10 14:33:55 +0100498void AssignedVariablesAnalyzer::VisitCompareOperation(CompareOperation* expr) {
499 ASSERT(av_.IsEmpty());
500 MarkIfTrivial(expr->right());
501 Visit(expr->right());
502 MarkIfTrivial(expr->left());
503 ProcessExpression(expr->left());
Andrei Popescu402d9372010-02-26 13:31:12 +0000504}
505
506
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100507void AssignedVariablesAnalyzer::VisitCompareToNull(CompareToNull* expr) {
508 ASSERT(av_.IsEmpty());
509 MarkIfTrivial(expr->expression());
510 Visit(expr->expression());
511}
512
513
Steve Block6ded16b2010-05-10 14:33:55 +0100514void AssignedVariablesAnalyzer::VisitThisFunction(ThisFunction* expr) {
515 // Nothing to do.
516 ASSERT(av_.IsEmpty());
517}
518
519
520void AssignedVariablesAnalyzer::VisitDeclaration(Declaration* decl) {
Andrei Popescu402d9372010-02-26 13:31:12 +0000521 UNREACHABLE();
522}
523
524
Leon Clarke4515c472010-02-03 11:58:03 +0000525} } // namespace v8::internal