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

Side by Side Diff: src/rewriter.cc

Issue 965001: Add static analysis to AST expressions that records whether a negative zero w... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « src/ia32/codegen-ia32.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 } 213 }
214 214
215 215
216 void AstOptimizer::VisitFunctionBoilerplateLiteral( 216 void AstOptimizer::VisitFunctionBoilerplateLiteral(
217 FunctionBoilerplateLiteral* node) { 217 FunctionBoilerplateLiteral* node) {
218 USE(node); 218 USE(node);
219 } 219 }
220 220
221 221
222 void AstOptimizer::VisitConditional(Conditional* node) { 222 void AstOptimizer::VisitConditional(Conditional* node) {
223 node->condition()->set_no_negative_zero(true);
223 Visit(node->condition()); 224 Visit(node->condition());
224 Visit(node->then_expression()); 225 Visit(node->then_expression());
225 Visit(node->else_expression()); 226 Visit(node->else_expression());
226 } 227 }
227 228
228 229
229 void AstOptimizer::VisitSlot(Slot* node) { 230 void AstOptimizer::VisitSlot(Slot* node) {
230 USE(node); 231 USE(node);
231 } 232 }
232 233
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 break; 313 break;
313 case Token::ASSIGN_BIT_OR: 314 case Token::ASSIGN_BIT_OR:
314 case Token::ASSIGN_BIT_XOR: 315 case Token::ASSIGN_BIT_XOR:
315 case Token::ASSIGN_BIT_AND: 316 case Token::ASSIGN_BIT_AND:
316 case Token::ASSIGN_SHL: 317 case Token::ASSIGN_SHL:
317 case Token::ASSIGN_SAR: 318 case Token::ASSIGN_SAR:
318 case Token::ASSIGN_SHR: 319 case Token::ASSIGN_SHR:
319 node->type()->SetAsLikelySmiIfUnknown(); 320 node->type()->SetAsLikelySmiIfUnknown();
320 node->target()->type()->SetAsLikelySmiIfUnknown(); 321 node->target()->type()->SetAsLikelySmiIfUnknown();
321 node->value()->type()->SetAsLikelySmiIfUnknown(); 322 node->value()->type()->SetAsLikelySmiIfUnknown();
323 node->value()->set_no_negative_zero(true);
322 break; 324 break;
323 case Token::ASSIGN_ADD: 325 case Token::ASSIGN_ADD:
324 case Token::ASSIGN_SUB: 326 case Token::ASSIGN_SUB:
325 case Token::ASSIGN_MUL: 327 case Token::ASSIGN_MUL:
326 case Token::ASSIGN_DIV: 328 case Token::ASSIGN_DIV:
327 case Token::ASSIGN_MOD: 329 case Token::ASSIGN_MOD:
328 if (node->type()->IsLikelySmi()) { 330 if (node->type()->IsLikelySmi()) {
329 node->target()->type()->SetAsLikelySmiIfUnknown(); 331 node->target()->type()->SetAsLikelySmiIfUnknown();
330 node->value()->type()->SetAsLikelySmiIfUnknown(); 332 node->value()->type()->SetAsLikelySmiIfUnknown();
331 } 333 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 } 388 }
387 } 389 }
388 390
389 391
390 void AstOptimizer::VisitThrow(Throw* node) { 392 void AstOptimizer::VisitThrow(Throw* node) {
391 Visit(node->exception()); 393 Visit(node->exception());
392 } 394 }
393 395
394 396
395 void AstOptimizer::VisitProperty(Property* node) { 397 void AstOptimizer::VisitProperty(Property* node) {
398 node->key()->set_no_negative_zero(true);
396 Visit(node->obj()); 399 Visit(node->obj());
397 Visit(node->key()); 400 Visit(node->key());
398 } 401 }
399 402
400 403
401 void AstOptimizer::VisitCall(Call* node) { 404 void AstOptimizer::VisitCall(Call* node) {
402 Visit(node->expression()); 405 Visit(node->expression());
403 OptimizeArguments(node->arguments()); 406 OptimizeArguments(node->arguments());
404 } 407 }
405 408
406 409
407 void AstOptimizer::VisitCallNew(CallNew* node) { 410 void AstOptimizer::VisitCallNew(CallNew* node) {
408 Visit(node->expression()); 411 Visit(node->expression());
409 OptimizeArguments(node->arguments()); 412 OptimizeArguments(node->arguments());
410 } 413 }
411 414
412 415
413 void AstOptimizer::VisitCallRuntime(CallRuntime* node) { 416 void AstOptimizer::VisitCallRuntime(CallRuntime* node) {
414 ScopedFuncNameInferrer scoped_fni(&func_name_inferrer_); 417 ScopedFuncNameInferrer scoped_fni(&func_name_inferrer_);
415 if (Factory::InitializeVarGlobal_symbol()->Equals(*node->name()) && 418 if (Factory::InitializeVarGlobal_symbol()->Equals(*node->name()) &&
416 node->arguments()->length() >= 2 && 419 node->arguments()->length() >= 2 &&
417 node->arguments()->at(1)->AsFunctionLiteral() != NULL) { 420 node->arguments()->at(1)->AsFunctionLiteral() != NULL) {
418 scoped_fni.Enter(); 421 scoped_fni.Enter();
419 } 422 }
420 OptimizeArguments(node->arguments()); 423 OptimizeArguments(node->arguments());
421 } 424 }
422 425
423 426
424 void AstOptimizer::VisitUnaryOperation(UnaryOperation* node) { 427 void AstOptimizer::VisitUnaryOperation(UnaryOperation* node) {
428 if (node->op() == Token::ADD || node->op() == Token::SUB) {
429 node->expression()->set_no_negative_zero(node->no_negative_zero());
430 } else {
431 node->expression()->set_no_negative_zero(true);
432 }
425 Visit(node->expression()); 433 Visit(node->expression());
426 if (FLAG_safe_int32_compiler) { 434 if (FLAG_safe_int32_compiler) {
427 switch (node->op()) { 435 switch (node->op()) {
428 case Token::BIT_NOT: 436 case Token::BIT_NOT:
429 node->expression()->set_to_int32(true); 437 node->expression()->set_to_int32(true);
430 // Fall through. 438 // Fall through.
431 case Token::ADD: 439 case Token::ADD:
432 case Token::SUB: 440 case Token::SUB:
433 case Token::NOT: 441 case Token::NOT:
434 node->set_side_effect_free(node->expression()->side_effect_free()); 442 node->set_side_effect_free(node->expression()->side_effect_free());
435 break; 443 break;
436 case Token::DELETE: 444 case Token::DELETE:
437 case Token::TYPEOF: 445 case Token::TYPEOF:
438 case Token::VOID: 446 case Token::VOID:
439 break; 447 break;
440 default: 448 default:
441 UNREACHABLE(); 449 UNREACHABLE();
442 break; 450 break;
443 } 451 }
444 } else if (node->op() == Token::BIT_NOT) { 452 } else if (node->op() == Token::BIT_NOT) {
445 node->expression()->set_to_int32(true); 453 node->expression()->set_to_int32(true);
446 } 454 }
447 } 455 }
448 456
449 457
450 void AstOptimizer::VisitCountOperation(CountOperation* node) { 458 void AstOptimizer::VisitCountOperation(CountOperation* node) {
451 // Count operations assume that they work on Smis. 459 // Count operations assume that they work on Smis.
460 node->expression()->set_no_negative_zero(node->is_prefix() ?
461 true :
462 node->no_negative_zero());
452 node->type()->SetAsLikelySmiIfUnknown(); 463 node->type()->SetAsLikelySmiIfUnknown();
453 node->expression()->type()->SetAsLikelySmiIfUnknown(); 464 node->expression()->type()->SetAsLikelySmiIfUnknown();
454 Visit(node->expression()); 465 Visit(node->expression());
455 } 466 }
456 467
457 468
458 void AstOptimizer::VisitBinaryOperation(BinaryOperation* node) { 469 void AstOptimizer::VisitBinaryOperation(BinaryOperation* node) {
459 // Depending on the operation we can propagate this node's type down the 470 // Depending on the operation we can propagate this node's type down the
460 // AST nodes. 471 // AST nodes.
461 switch (node->op()) { 472 switch (node->op()) {
462 case Token::COMMA: 473 case Token::COMMA:
463 case Token::OR: 474 case Token::OR:
475 node->left()->set_no_negative_zero(true);
476 node->right()->set_no_negative_zero(node->no_negative_zero());
477 break;
464 case Token::AND: 478 case Token::AND:
479 node->left()->set_no_negative_zero(node->no_negative_zero());
480 node->right()->set_no_negative_zero(node->no_negative_zero());
465 break; 481 break;
466 case Token::BIT_OR: 482 case Token::BIT_OR:
467 case Token::BIT_XOR: 483 case Token::BIT_XOR:
468 case Token::BIT_AND: 484 case Token::BIT_AND:
469 case Token::SHL: 485 case Token::SHL:
470 case Token::SAR: 486 case Token::SAR:
471 case Token::SHR: 487 case Token::SHR:
472 node->type()->SetAsLikelySmiIfUnknown(); 488 node->type()->SetAsLikelySmiIfUnknown();
473 node->left()->type()->SetAsLikelySmiIfUnknown(); 489 node->left()->type()->SetAsLikelySmiIfUnknown();
474 node->right()->type()->SetAsLikelySmiIfUnknown(); 490 node->right()->type()->SetAsLikelySmiIfUnknown();
475 node->left()->set_to_int32(true); 491 node->left()->set_to_int32(true);
476 node->right()->set_to_int32(true); 492 node->right()->set_to_int32(true);
493 node->left()->set_no_negative_zero(true);
494 node->right()->set_no_negative_zero(true);
477 break; 495 break;
478 case Token::ADD: 496 case Token::ADD:
479 case Token::SUB: 497 case Token::SUB:
480 case Token::MUL: 498 case Token::MUL:
481 case Token::DIV: 499 case Token::DIV:
482 case Token::MOD: 500 case Token::MOD:
483 if (node->type()->IsLikelySmi()) { 501 if (node->type()->IsLikelySmi()) {
484 node->left()->type()->SetAsLikelySmiIfUnknown(); 502 node->left()->type()->SetAsLikelySmiIfUnknown();
485 node->right()->type()->SetAsLikelySmiIfUnknown(); 503 node->right()->type()->SetAsLikelySmiIfUnknown();
486 } 504 }
505 node->left()->set_no_negative_zero(node->no_negative_zero());
506 node->right()->set_no_negative_zero(node->no_negative_zero());
507 if (node->op() == Token::DIV) {
508 node->right()->set_no_negative_zero(false);
509 } else if (node->op() == Token::MOD) {
510 node->right()->set_no_negative_zero(true);
511 }
487 break; 512 break;
488 default: 513 default:
489 UNREACHABLE(); 514 UNREACHABLE();
490 break; 515 break;
491 } 516 }
492 517
493 Visit(node->left()); 518 Visit(node->left());
494 Visit(node->right()); 519 Visit(node->right());
495 520
496 // After visiting the operand nodes we have to check if this node's type 521 // After visiting the operand nodes we have to check if this node's type
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
544 } 569 }
545 570
546 571
547 void AstOptimizer::VisitCompareOperation(CompareOperation* node) { 572 void AstOptimizer::VisitCompareOperation(CompareOperation* node) {
548 if (node->type()->IsKnown()) { 573 if (node->type()->IsKnown()) {
549 // Propagate useful information down towards the leafs. 574 // Propagate useful information down towards the leafs.
550 node->left()->type()->SetAsLikelySmiIfUnknown(); 575 node->left()->type()->SetAsLikelySmiIfUnknown();
551 node->right()->type()->SetAsLikelySmiIfUnknown(); 576 node->right()->type()->SetAsLikelySmiIfUnknown();
552 } 577 }
553 578
579 node->left()->set_no_negative_zero(true);
580 // Only [[HasInstance]] has the right argument passed unchanged to it.
581 node->right()->set_no_negative_zero(true);
582
554 Visit(node->left()); 583 Visit(node->left());
555 Visit(node->right()); 584 Visit(node->right());
556 585
557 // After visiting the operand nodes we have to check if this node's type 586 // After visiting the operand nodes we have to check if this node's type
558 // can be updated. If it does, then we can push that information down 587 // can be updated. If it does, then we can push that information down
559 // towards the leafs again if the new information is an upgrade over the 588 // towards the leafs again if the new information is an upgrade over the
560 // previous type of the operand nodes. 589 // previous type of the operand nodes.
561 if (node->type()->IsUnknown()) { 590 if (node->type()->IsUnknown()) {
562 if (node->left()->type()->IsLikelySmi() || 591 if (node->left()->type()->IsLikelySmi() ||
563 node->right()->type()->IsLikelySmi()) { 592 node->right()->type()->IsLikelySmi()) {
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
904 optimizer.Optimize(body); 933 optimizer.Optimize(body);
905 if (optimizer.HasStackOverflow()) { 934 if (optimizer.HasStackOverflow()) {
906 return false; 935 return false;
907 } 936 }
908 } 937 }
909 return true; 938 return true;
910 } 939 }
911 940
912 941
913 } } // namespace v8::internal 942 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/codegen-ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698