Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 1359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1441 | 1442 |
| 1442 | 1443 |
| 1443 bool HGlobalValueNumberer::AllowCodeMotion() { | 1444 bool HGlobalValueNumberer::AllowCodeMotion() { |
| 1444 return info()->shared_info()->opt_count() + 1 < Compiler::kDefaultMaxOptCount; | 1445 return info()->shared_info()->opt_count() + 1 < Compiler::kDefaultMaxOptCount; |
| 1445 } | 1446 } |
| 1446 | 1447 |
| 1447 | 1448 |
| 1448 bool HGlobalValueNumberer::ShouldMove(HInstruction* instr, | 1449 bool HGlobalValueNumberer::ShouldMove(HInstruction* instr, |
| 1449 HBasicBlock* loop_header) { | 1450 HBasicBlock* loop_header) { |
| 1450 // If we've disabled code motion, don't move any instructions. | 1451 // If we've disabled code motion, don't move any instructions. |
| 1451 if (!AllowCodeMotion()) return false; | 1452 if (!AllowCodeMotion()) return false; |
|
Kevin Millikin (Chromium)
2011/06/09 15:18:00
return AllowCodeMotion() && !instr->block()->IsDeo
fschneider
2011/06/09 15:46:47
Done.
| |
| 1452 | 1453 // Don't hoist code from never executed paths. |
| 1453 // If --aggressive-loop-invariant-motion, move everything except change | 1454 if (instr->block()->IsDeoptimizing()) return false; |
| 1454 // instructions. | 1455 return true; |
| 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 } | 1456 } |
| 1482 | 1457 |
| 1483 | 1458 |
| 1484 int HGlobalValueNumberer::CollectSideEffectsOnPathsToDominatedBlock( | 1459 int HGlobalValueNumberer::CollectSideEffectsOnPathsToDominatedBlock( |
| 1485 HBasicBlock* dominator, HBasicBlock* dominated) { | 1460 HBasicBlock* dominator, HBasicBlock* dominated) { |
| 1486 int side_effects = 0; | 1461 int side_effects = 0; |
| 1487 for (int i = 0; i < dominated->predecessors()->length(); ++i) { | 1462 for (int i = 0; i < dominated->predecessors()->length(); ++i) { |
| 1488 HBasicBlock* block = dominated->predecessors()->at(i); | 1463 HBasicBlock* block = dominated->predecessors()->at(i); |
| 1489 if (dominator->block_id() < block->block_id() && | 1464 if (dominator->block_id() < block->block_id() && |
| 1490 block->block_id() < dominated->block_id() && | 1465 block->block_id() < dominated->block_id() && |
| (...skipping 3352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4843 } | 4818 } |
| 4844 | 4819 |
| 4845 | 4820 |
| 4846 void HGraphBuilder::VisitSub(UnaryOperation* expr) { | 4821 void HGraphBuilder::VisitSub(UnaryOperation* expr) { |
| 4847 CHECK_ALIVE(VisitForValue(expr->expression())); | 4822 CHECK_ALIVE(VisitForValue(expr->expression())); |
| 4848 HValue* value = Pop(); | 4823 HValue* value = Pop(); |
| 4849 HInstruction* instr = new(zone()) HMul(value, graph_->GetConstantMinus1()); | 4824 HInstruction* instr = new(zone()) HMul(value, graph_->GetConstantMinus1()); |
| 4850 TypeInfo info = oracle()->UnaryType(expr); | 4825 TypeInfo info = oracle()->UnaryType(expr); |
| 4851 if (info.IsUninitialized()) { | 4826 if (info.IsUninitialized()) { |
| 4852 AddInstruction(new(zone()) HSoftDeoptimize); | 4827 AddInstruction(new(zone()) HSoftDeoptimize); |
| 4828 current_block()->MarkAsDeoptimizing(); | |
| 4853 info = TypeInfo::Unknown(); | 4829 info = TypeInfo::Unknown(); |
| 4854 } | 4830 } |
| 4855 Representation rep = ToRepresentation(info); | 4831 Representation rep = ToRepresentation(info); |
| 4856 TraceRepresentation(expr->op(), info, instr, rep); | 4832 TraceRepresentation(expr->op(), info, instr, rep); |
| 4857 instr->AssumeRepresentation(rep); | 4833 instr->AssumeRepresentation(rep); |
| 4858 ast_context()->ReturnInstruction(instr, expr->id()); | 4834 ast_context()->ReturnInstruction(instr, expr->id()); |
| 4859 } | 4835 } |
| 4860 | 4836 |
| 4861 | 4837 |
| 4862 void HGraphBuilder::VisitBitNot(UnaryOperation* expr) { | 4838 void HGraphBuilder::VisitBitNot(UnaryOperation* expr) { |
| 4863 CHECK_ALIVE(VisitForValue(expr->expression())); | 4839 CHECK_ALIVE(VisitForValue(expr->expression())); |
| 4864 HValue* value = Pop(); | 4840 HValue* value = Pop(); |
| 4865 TypeInfo info = oracle()->UnaryType(expr); | 4841 TypeInfo info = oracle()->UnaryType(expr); |
| 4866 if (info.IsUninitialized()) { | 4842 if (info.IsUninitialized()) { |
| 4867 AddInstruction(new(zone()) HSoftDeoptimize); | 4843 AddInstruction(new(zone()) HSoftDeoptimize); |
| 4844 current_block()->MarkAsDeoptimizing(); | |
| 4868 } | 4845 } |
| 4869 HInstruction* instr = new(zone()) HBitNot(value); | 4846 HInstruction* instr = new(zone()) HBitNot(value); |
| 4870 ast_context()->ReturnInstruction(instr, expr->id()); | 4847 ast_context()->ReturnInstruction(instr, expr->id()); |
| 4871 } | 4848 } |
| 4872 | 4849 |
| 4873 | 4850 |
| 4874 void HGraphBuilder::VisitNot(UnaryOperation* expr) { | 4851 void HGraphBuilder::VisitNot(UnaryOperation* expr) { |
| 4875 // TODO(svenpanne) Perhaps a switch/virtual function is nicer here. | 4852 // TODO(svenpanne) Perhaps a switch/virtual function is nicer here. |
| 4876 if (ast_context()->IsTest()) { | 4853 if (ast_context()->IsTest()) { |
| 4877 TestContext* context = TestContext::cast(ast_context()); | 4854 TestContext* context = TestContext::cast(ast_context()); |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5093 return new(zone()) HStringCharCodeAt(string, checked_index); | 5070 return new(zone()) HStringCharCodeAt(string, checked_index); |
| 5094 } | 5071 } |
| 5095 | 5072 |
| 5096 | 5073 |
| 5097 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr, | 5074 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr, |
| 5098 HValue* left, | 5075 HValue* left, |
| 5099 HValue* right) { | 5076 HValue* right) { |
| 5100 TypeInfo info = oracle()->BinaryType(expr); | 5077 TypeInfo info = oracle()->BinaryType(expr); |
| 5101 if (info.IsUninitialized()) { | 5078 if (info.IsUninitialized()) { |
| 5102 AddInstruction(new(zone()) HSoftDeoptimize); | 5079 AddInstruction(new(zone()) HSoftDeoptimize); |
| 5080 current_block()->MarkAsDeoptimizing(); | |
| 5103 info = TypeInfo::Unknown(); | 5081 info = TypeInfo::Unknown(); |
| 5104 } | 5082 } |
| 5105 HInstruction* instr = NULL; | 5083 HInstruction* instr = NULL; |
| 5106 switch (expr->op()) { | 5084 switch (expr->op()) { |
| 5107 case Token::ADD: | 5085 case Token::ADD: |
| 5108 if (info.IsString()) { | 5086 if (info.IsString()) { |
| 5109 AddInstruction(new(zone()) HCheckNonSmi(left)); | 5087 AddInstruction(new(zone()) HCheckNonSmi(left)); |
| 5110 AddInstruction(HCheckInstanceType::NewIsString(left)); | 5088 AddInstruction(HCheckInstanceType::NewIsString(left)); |
| 5111 AddInstruction(new(zone()) HCheckNonSmi(right)); | 5089 AddInstruction(new(zone()) HCheckNonSmi(right)); |
| 5112 AddInstruction(HCheckInstanceType::NewIsString(right)); | 5090 AddInstruction(HCheckInstanceType::NewIsString(right)); |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5362 Handle<String>::cast(right_literal->handle())); | 5340 Handle<String>::cast(right_literal->handle())); |
| 5363 instr->set_position(expr->position()); | 5341 instr->set_position(expr->position()); |
| 5364 ast_context()->ReturnInstruction(instr, expr->id()); | 5342 ast_context()->ReturnInstruction(instr, expr->id()); |
| 5365 return; | 5343 return; |
| 5366 } | 5344 } |
| 5367 | 5345 |
| 5368 TypeInfo type_info = oracle()->CompareType(expr); | 5346 TypeInfo type_info = oracle()->CompareType(expr); |
| 5369 // Check if this expression was ever executed according to type feedback. | 5347 // Check if this expression was ever executed according to type feedback. |
| 5370 if (type_info.IsUninitialized()) { | 5348 if (type_info.IsUninitialized()) { |
| 5371 AddInstruction(new(zone()) HSoftDeoptimize); | 5349 AddInstruction(new(zone()) HSoftDeoptimize); |
| 5350 current_block()->MarkAsDeoptimizing(); | |
| 5372 type_info = TypeInfo::Unknown(); | 5351 type_info = TypeInfo::Unknown(); |
| 5373 } | 5352 } |
| 5374 | 5353 |
| 5375 CHECK_ALIVE(VisitForValue(expr->left())); | 5354 CHECK_ALIVE(VisitForValue(expr->left())); |
| 5376 CHECK_ALIVE(VisitForValue(expr->right())); | 5355 CHECK_ALIVE(VisitForValue(expr->right())); |
| 5377 | 5356 |
| 5378 HValue* right = Pop(); | 5357 HValue* right = Pop(); |
| 5379 HValue* left = Pop(); | 5358 HValue* left = Pop(); |
| 5380 Token::Value op = expr->op(); | 5359 Token::Value op = expr->op(); |
| 5381 | 5360 |
| (...skipping 1023 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6405 } | 6384 } |
| 6406 } | 6385 } |
| 6407 | 6386 |
| 6408 #ifdef DEBUG | 6387 #ifdef DEBUG |
| 6409 if (graph_ != NULL) graph_->Verify(); | 6388 if (graph_ != NULL) graph_->Verify(); |
| 6410 if (allocator_ != NULL) allocator_->Verify(); | 6389 if (allocator_ != NULL) allocator_->Verify(); |
| 6411 #endif | 6390 #endif |
| 6412 } | 6391 } |
| 6413 | 6392 |
| 6414 } } // namespace v8::internal | 6393 } } // namespace v8::internal |
| OLD | NEW |