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

Side by Side Diff: src/hydrogen.cc

Issue 7003087: Simplify the check when to perform loop invariant code motion. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 6 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/hydrogen.h ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 loop_information_(NULL), 61 loop_information_(NULL),
62 predecessors_(2), 62 predecessors_(2),
63 dominator_(NULL), 63 dominator_(NULL),
64 dominated_blocks_(4), 64 dominated_blocks_(4),
65 last_environment_(NULL), 65 last_environment_(NULL),
66 argument_count_(-1), 66 argument_count_(-1),
67 first_instruction_index_(-1), 67 first_instruction_index_(-1),
68 last_instruction_index_(-1), 68 last_instruction_index_(-1),
69 deleted_phis_(4), 69 deleted_phis_(4),
70 parent_loop_header_(NULL), 70 parent_loop_header_(NULL),
71 is_inline_return_target_(false) { } 71 is_inline_return_target_(false),
72 is_deoptimizing_(false) { }
72 73
73 74
74 void HBasicBlock::AttachLoopInformation() { 75 void HBasicBlock::AttachLoopInformation() {
75 ASSERT(!IsLoopHeader()); 76 ASSERT(!IsLoopHeader());
76 loop_information_ = new(zone()) HLoopInformation(this); 77 loop_information_ = new(zone()) HLoopInformation(this);
77 } 78 }
78 79
79 80
80 void HBasicBlock::DetachLoopInformation() { 81 void HBasicBlock::DetachLoopInformation() {
81 ASSERT(IsLoopHeader()); 82 ASSERT(IsLoopHeader());
(...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after
734 HPhase phase("Assign dominators", this); 735 HPhase phase("Assign dominators", this);
735 for (int i = 0; i < blocks_.length(); ++i) { 736 for (int i = 0; i < blocks_.length(); ++i) {
736 if (blocks_[i]->IsLoopHeader()) { 737 if (blocks_[i]->IsLoopHeader()) {
737 blocks_[i]->AssignCommonDominator(blocks_[i]->predecessors()->first()); 738 blocks_[i]->AssignCommonDominator(blocks_[i]->predecessors()->first());
738 } else { 739 } else {
739 for (int j = 0; j < blocks_[i]->predecessors()->length(); ++j) { 740 for (int j = 0; j < blocks_[i]->predecessors()->length(); ++j) {
740 blocks_[i]->AssignCommonDominator(blocks_[i]->predecessors()->at(j)); 741 blocks_[i]->AssignCommonDominator(blocks_[i]->predecessors()->at(j));
741 } 742 }
742 } 743 }
743 } 744 }
745
746 // Propagate flag marking blocks containing unconditional deoptimize.
747 MarkAsDeoptimizingRecursively(entry_block());
744 } 748 }
745 749
746 750
751 // Mark all blocks that are dominated by an unconditional deoptimize.
752 void HGraph::MarkAsDeoptimizingRecursively(HBasicBlock* block) {
753 for (int i = 0; i < block->dominated_blocks()->length(); ++i) {
754 HBasicBlock* dominated = block->dominated_blocks()->at(i);
755 if (block->IsDeoptimizing()) dominated->MarkAsDeoptimizing();
756 MarkAsDeoptimizingRecursively(dominated);
757 }
758 }
759
747 void HGraph::EliminateRedundantPhis() { 760 void HGraph::EliminateRedundantPhis() {
748 HPhase phase("Redundant phi elimination", this); 761 HPhase phase("Redundant phi elimination", this);
749 762
750 // Worklist of phis that can potentially be eliminated. Initialized with 763 // Worklist of phis that can potentially be eliminated. Initialized with
751 // all phi nodes. When elimination of a phi node modifies another phi node 764 // all phi nodes. When elimination of a phi node modifies another phi node
752 // the modified phi node is added to the worklist. 765 // the modified phi node is added to the worklist.
753 ZoneList<HPhi*> worklist(blocks_.length()); 766 ZoneList<HPhi*> worklist(blocks_.length());
754 for (int i = 0; i < blocks_.length(); ++i) { 767 for (int i = 0; i < blocks_.length(); ++i) {
755 worklist.AddAll(*blocks_[i]->phis()); 768 worklist.AddAll(*blocks_[i]->phis());
756 } 769 }
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
890 va_list arguments; 903 va_list arguments;
891 va_start(arguments, msg); 904 va_start(arguments, msg);
892 OS::VPrint(msg, arguments); 905 OS::VPrint(msg, arguments);
893 va_end(arguments); 906 va_end(arguments);
894 } 907 }
895 } 908 }
896 909
897 910
898 void HRangeAnalysis::Analyze() { 911 void HRangeAnalysis::Analyze() {
899 HPhase phase("Range analysis", graph_); 912 HPhase phase("Range analysis", graph_);
900 Analyze(graph_->blocks()->at(0)); 913 Analyze(graph_->entry_block());
901 } 914 }
902 915
903 916
904 void HRangeAnalysis::Analyze(HBasicBlock* block) { 917 void HRangeAnalysis::Analyze(HBasicBlock* block) {
905 TraceRange("Analyzing block B%d\n", block->block_id()); 918 TraceRange("Analyzing block B%d\n", block->block_id());
906 919
907 int last_changed_range = changed_ranges_.length() - 1; 920 int last_changed_range = changed_ranges_.length() - 1;
908 921
909 // Infer range based on control flow. 922 // Infer range based on control flow.
910 if (block->predecessors()->length() == 1) { 923 if (block->predecessors()->length() == 1) {
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
1348 SparseSet visited_on_paths_; 1361 SparseSet visited_on_paths_;
1349 }; 1362 };
1350 1363
1351 1364
1352 void HGlobalValueNumberer::Analyze() { 1365 void HGlobalValueNumberer::Analyze() {
1353 ComputeBlockSideEffects(); 1366 ComputeBlockSideEffects();
1354 if (FLAG_loop_invariant_code_motion) { 1367 if (FLAG_loop_invariant_code_motion) {
1355 LoopInvariantCodeMotion(); 1368 LoopInvariantCodeMotion();
1356 } 1369 }
1357 HValueMap* map = new(zone()) HValueMap(); 1370 HValueMap* map = new(zone()) HValueMap();
1358 AnalyzeBlock(graph_->blocks()->at(0), map); 1371 AnalyzeBlock(graph_->entry_block(), map);
1359 } 1372 }
1360 1373
1361 1374
1362 void HGlobalValueNumberer::ComputeBlockSideEffects() { 1375 void HGlobalValueNumberer::ComputeBlockSideEffects() {
1363 for (int i = graph_->blocks()->length() - 1; i >= 0; --i) { 1376 for (int i = graph_->blocks()->length() - 1; i >= 0; --i) {
1364 // Compute side effects for the block. 1377 // Compute side effects for the block.
1365 HBasicBlock* block = graph_->blocks()->at(i); 1378 HBasicBlock* block = graph_->blocks()->at(i);
1366 HInstruction* instr = block->first(); 1379 HInstruction* instr = block->first();
1367 int id = block->block_id(); 1380 int id = block->block_id();
1368 int side_effects = 0; 1381 int side_effects = 0;
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1440 } 1453 }
1441 1454
1442 1455
1443 bool HGlobalValueNumberer::AllowCodeMotion() { 1456 bool HGlobalValueNumberer::AllowCodeMotion() {
1444 return info()->shared_info()->opt_count() + 1 < Compiler::kDefaultMaxOptCount; 1457 return info()->shared_info()->opt_count() + 1 < Compiler::kDefaultMaxOptCount;
1445 } 1458 }
1446 1459
1447 1460
1448 bool HGlobalValueNumberer::ShouldMove(HInstruction* instr, 1461 bool HGlobalValueNumberer::ShouldMove(HInstruction* instr,
1449 HBasicBlock* loop_header) { 1462 HBasicBlock* loop_header) {
1450 // If we've disabled code motion, don't move any instructions. 1463 // If we've disabled code motion or we're in a block that unconditionally
1451 if (!AllowCodeMotion()) return false; 1464 // deoptimizes, don't move any instructions.
1452 1465 return AllowCodeMotion() && !instr->block()->IsDeoptimizing();
1453 // If --aggressive-loop-invariant-motion, move everything except change
1454 // instructions.
1455 if (FLAG_aggressive_loop_invariant_motion && !instr->IsChange()) {
1456 return true;
1457 }
1458
1459 // Otherwise only move instructions that postdominate the loop header
1460 // (i.e. are always executed inside the loop). This is to avoid
1461 // unnecessary deoptimizations assuming the loop is executed at least
1462 // once. TODO(fschneider): Better type feedback should give us
1463 // information about code that was never executed.
1464 HBasicBlock* block = instr->block();
1465 bool result = true;
1466 if (block != loop_header) {
1467 for (int i = 1; i < loop_header->predecessors()->length(); ++i) {
1468 bool found = false;
1469 HBasicBlock* pred = loop_header->predecessors()->at(i);
1470 while (pred != loop_header) {
1471 if (pred == block) found = true;
1472 pred = pred->dominator();
1473 }
1474 if (!found) {
1475 result = false;
1476 break;
1477 }
1478 }
1479 }
1480 return result;
1481 } 1466 }
1482 1467
1483 1468
1484 int HGlobalValueNumberer::CollectSideEffectsOnPathsToDominatedBlock( 1469 int HGlobalValueNumberer::CollectSideEffectsOnPathsToDominatedBlock(
1485 HBasicBlock* dominator, HBasicBlock* dominated) { 1470 HBasicBlock* dominator, HBasicBlock* dominated) {
1486 int side_effects = 0; 1471 int side_effects = 0;
1487 for (int i = 0; i < dominated->predecessors()->length(); ++i) { 1472 for (int i = 0; i < dominated->predecessors()->length(); ++i) {
1488 HBasicBlock* block = dominated->predecessors()->at(i); 1473 HBasicBlock* block = dominated->predecessors()->at(i);
1489 if (dominator->block_id() < block->block_id() && 1474 if (dominator->block_id() < block->block_id() &&
1490 block->block_id() < dominated->block_id() && 1475 block->block_id() < dominated->block_id() &&
(...skipping 3356 matching lines...) Expand 10 before | Expand all | Expand 10 after
4847 } 4832 }
4848 4833
4849 4834
4850 void HGraphBuilder::VisitSub(UnaryOperation* expr) { 4835 void HGraphBuilder::VisitSub(UnaryOperation* expr) {
4851 CHECK_ALIVE(VisitForValue(expr->expression())); 4836 CHECK_ALIVE(VisitForValue(expr->expression()));
4852 HValue* value = Pop(); 4837 HValue* value = Pop();
4853 HInstruction* instr = new(zone()) HMul(value, graph_->GetConstantMinus1()); 4838 HInstruction* instr = new(zone()) HMul(value, graph_->GetConstantMinus1());
4854 TypeInfo info = oracle()->UnaryType(expr); 4839 TypeInfo info = oracle()->UnaryType(expr);
4855 if (info.IsUninitialized()) { 4840 if (info.IsUninitialized()) {
4856 AddInstruction(new(zone()) HSoftDeoptimize); 4841 AddInstruction(new(zone()) HSoftDeoptimize);
4842 current_block()->MarkAsDeoptimizing();
4857 info = TypeInfo::Unknown(); 4843 info = TypeInfo::Unknown();
4858 } 4844 }
4859 Representation rep = ToRepresentation(info); 4845 Representation rep = ToRepresentation(info);
4860 TraceRepresentation(expr->op(), info, instr, rep); 4846 TraceRepresentation(expr->op(), info, instr, rep);
4861 instr->AssumeRepresentation(rep); 4847 instr->AssumeRepresentation(rep);
4862 ast_context()->ReturnInstruction(instr, expr->id()); 4848 ast_context()->ReturnInstruction(instr, expr->id());
4863 } 4849 }
4864 4850
4865 4851
4866 void HGraphBuilder::VisitBitNot(UnaryOperation* expr) { 4852 void HGraphBuilder::VisitBitNot(UnaryOperation* expr) {
4867 CHECK_ALIVE(VisitForValue(expr->expression())); 4853 CHECK_ALIVE(VisitForValue(expr->expression()));
4868 HValue* value = Pop(); 4854 HValue* value = Pop();
4869 TypeInfo info = oracle()->UnaryType(expr); 4855 TypeInfo info = oracle()->UnaryType(expr);
4870 if (info.IsUninitialized()) { 4856 if (info.IsUninitialized()) {
4871 AddInstruction(new(zone()) HSoftDeoptimize); 4857 AddInstruction(new(zone()) HSoftDeoptimize);
4858 current_block()->MarkAsDeoptimizing();
4872 } 4859 }
4873 HInstruction* instr = new(zone()) HBitNot(value); 4860 HInstruction* instr = new(zone()) HBitNot(value);
4874 ast_context()->ReturnInstruction(instr, expr->id()); 4861 ast_context()->ReturnInstruction(instr, expr->id());
4875 } 4862 }
4876 4863
4877 4864
4878 void HGraphBuilder::VisitNot(UnaryOperation* expr) { 4865 void HGraphBuilder::VisitNot(UnaryOperation* expr) {
4879 // TODO(svenpanne) Perhaps a switch/virtual function is nicer here. 4866 // TODO(svenpanne) Perhaps a switch/virtual function is nicer here.
4880 if (ast_context()->IsTest()) { 4867 if (ast_context()->IsTest()) {
4881 TestContext* context = TestContext::cast(ast_context()); 4868 TestContext* context = TestContext::cast(ast_context());
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
5097 return new(zone()) HStringCharCodeAt(string, checked_index); 5084 return new(zone()) HStringCharCodeAt(string, checked_index);
5098 } 5085 }
5099 5086
5100 5087
5101 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr, 5088 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr,
5102 HValue* left, 5089 HValue* left,
5103 HValue* right) { 5090 HValue* right) {
5104 TypeInfo info = oracle()->BinaryType(expr); 5091 TypeInfo info = oracle()->BinaryType(expr);
5105 if (info.IsUninitialized()) { 5092 if (info.IsUninitialized()) {
5106 AddInstruction(new(zone()) HSoftDeoptimize); 5093 AddInstruction(new(zone()) HSoftDeoptimize);
5094 current_block()->MarkAsDeoptimizing();
5107 info = TypeInfo::Unknown(); 5095 info = TypeInfo::Unknown();
5108 } 5096 }
5109 HInstruction* instr = NULL; 5097 HInstruction* instr = NULL;
5110 switch (expr->op()) { 5098 switch (expr->op()) {
5111 case Token::ADD: 5099 case Token::ADD:
5112 if (info.IsString()) { 5100 if (info.IsString()) {
5113 AddInstruction(new(zone()) HCheckNonSmi(left)); 5101 AddInstruction(new(zone()) HCheckNonSmi(left));
5114 AddInstruction(HCheckInstanceType::NewIsString(left)); 5102 AddInstruction(HCheckInstanceType::NewIsString(left));
5115 AddInstruction(new(zone()) HCheckNonSmi(right)); 5103 AddInstruction(new(zone()) HCheckNonSmi(right));
5116 AddInstruction(HCheckInstanceType::NewIsString(right)); 5104 AddInstruction(HCheckInstanceType::NewIsString(right));
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
5366 Handle<String>::cast(right_literal->handle())); 5354 Handle<String>::cast(right_literal->handle()));
5367 instr->set_position(expr->position()); 5355 instr->set_position(expr->position());
5368 ast_context()->ReturnInstruction(instr, expr->id()); 5356 ast_context()->ReturnInstruction(instr, expr->id());
5369 return; 5357 return;
5370 } 5358 }
5371 5359
5372 TypeInfo type_info = oracle()->CompareType(expr); 5360 TypeInfo type_info = oracle()->CompareType(expr);
5373 // Check if this expression was ever executed according to type feedback. 5361 // Check if this expression was ever executed according to type feedback.
5374 if (type_info.IsUninitialized()) { 5362 if (type_info.IsUninitialized()) {
5375 AddInstruction(new(zone()) HSoftDeoptimize); 5363 AddInstruction(new(zone()) HSoftDeoptimize);
5364 current_block()->MarkAsDeoptimizing();
5376 type_info = TypeInfo::Unknown(); 5365 type_info = TypeInfo::Unknown();
5377 } 5366 }
5378 5367
5379 CHECK_ALIVE(VisitForValue(expr->left())); 5368 CHECK_ALIVE(VisitForValue(expr->left()));
5380 CHECK_ALIVE(VisitForValue(expr->right())); 5369 CHECK_ALIVE(VisitForValue(expr->right()));
5381 5370
5382 HValue* right = Pop(); 5371 HValue* right = Pop();
5383 HValue* left = Pop(); 5372 HValue* left = Pop();
5384 Token::Value op = expr->op(); 5373 Token::Value op = expr->op();
5385 5374
(...skipping 1023 matching lines...) Expand 10 before | Expand all | Expand 10 after
6409 } 6398 }
6410 } 6399 }
6411 6400
6412 #ifdef DEBUG 6401 #ifdef DEBUG
6413 if (graph_ != NULL) graph_->Verify(); 6402 if (graph_ != NULL) graph_->Verify();
6414 if (allocator_ != NULL) allocator_->Verify(); 6403 if (allocator_ != NULL) allocator_->Verify();
6415 #endif 6404 #endif
6416 } 6405 }
6417 6406
6418 } } // namespace v8::internal 6407 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698