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

Side by Side Diff: src/hydrogen.cc

Issue 9141016: Improve GVN handling of ElementTransitions. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: nits Created 8 years, 10 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 predecessors_(2), 63 predecessors_(2),
64 dominator_(NULL), 64 dominator_(NULL),
65 dominated_blocks_(4), 65 dominated_blocks_(4),
66 last_environment_(NULL), 66 last_environment_(NULL),
67 argument_count_(-1), 67 argument_count_(-1),
68 first_instruction_index_(-1), 68 first_instruction_index_(-1),
69 last_instruction_index_(-1), 69 last_instruction_index_(-1),
70 deleted_phis_(4), 70 deleted_phis_(4),
71 parent_loop_header_(NULL), 71 parent_loop_header_(NULL),
72 is_inline_return_target_(false), 72 is_inline_return_target_(false),
73 is_deoptimizing_(false) { } 73 is_deoptimizing_(false),
74 dominates_loop_successors_(false) { }
74 75
75 76
76 void HBasicBlock::AttachLoopInformation() { 77 void HBasicBlock::AttachLoopInformation() {
77 ASSERT(!IsLoopHeader()); 78 ASSERT(!IsLoopHeader());
78 loop_information_ = new(zone()) HLoopInformation(this); 79 loop_information_ = new(zone()) HLoopInformation(this);
79 } 80 }
80 81
81 82
82 void HBasicBlock::DetachLoopInformation() { 83 void HBasicBlock::DetachLoopInformation() {
83 ASSERT(IsLoopHeader()); 84 ASSERT(IsLoopHeader());
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 if (dominator_ != first) { 309 if (dominator_ != first) {
309 ASSERT(dominator_->dominated_blocks_.Contains(this)); 310 ASSERT(dominator_->dominated_blocks_.Contains(this));
310 dominator_->dominated_blocks_.RemoveElement(this); 311 dominator_->dominated_blocks_.RemoveElement(this);
311 dominator_ = first; 312 dominator_ = first;
312 first->AddDominatedBlock(this); 313 first->AddDominatedBlock(this);
313 } 314 }
314 } 315 }
315 } 316 }
316 317
317 318
319 void HBasicBlock::AssignLoopSuccessorDominators() {
320 // Mark blocks that dominate all subsequent reachable blocks inside their
321 // loop. Exploit the fact that blocks are sorted in reverse post order. When
322 // the loop is visited in increasing block id order, if the number of
323 // non-loop-exiting successor edges at the dominator_candidate block doesn't
324 // exceed the number of previously encountered predecessor edges, there is no
325 // path from the loop header to any block with higher id that doesn't go
326 // through the dominator_candidate block. In this case, the
327 // dominator_candidate block is guaranteed to dominate all blocks reachable
328 // from it with higher ids.
329 HBasicBlock* last = loop_information()->GetLastBackEdge();
330 int outstanding_sucsessors = 1; // one edge from the pre-header
fschneider 2012/02/02 14:59:50 s/sucsessors/successors/g
danno 2012/02/06 16:54:57 Done.
331 // Header always dominates everything.
332 MarkAsLoopSuccessorDominator();
333 for (int j = block_id(); j <= last->block_id(); ++j) {
fschneider 2012/02/02 14:59:50 Maybe this be simplified: The header is always mar
danno 2012/02/06 16:54:57 You have to iterate over every block's successors,
334 HBasicBlock* dominator_candidate = graph_->blocks()->at(j);
335 const ZoneList<HBasicBlock*>* predecessor_list =
336 dominator_candidate->predecessors();
337 int predecessor_count = predecessor_list->length();
338 for (int i = 0; i < predecessor_count; ++i) {
fschneider 2012/02/02 14:59:50 Maybe it would make sense to introduce a HPredeces
danno 2012/02/06 16:54:57 Done.
339 HBasicBlock* predecessor = predecessor_list->at(i);
340 // Don't count back edges.
341 if (predecessor->block_id() < dominator_candidate->block_id()) {
342 outstanding_sucsessors--;
343 }
344 }
345
346 // If more successors than predecessors have been seen in the loop up to
347 // now, it's not possible to guarantee that the current block dominates
348 // all of the blocks with higher IDs. In this case, assume conservatively
349 // that those paths through loop that don't go through the current block
350 // contain all of the loop's dependencies. Also be careful to record
351 // dominator information about the current loop that's being processed,
352 // and not nested loops, which will be processed when
353 // AssignLoopSuccessorDominators gets called on their header.
354 ASSERT(outstanding_sucsessors >= 0);
355 HBasicBlock* parent_loop_header = dominator_candidate->parent_loop_header();
356 if (outstanding_sucsessors == 0 &&
357 (parent_loop_header == this && !dominator_candidate->IsLoopHeader())) {
358 MarkAsLoopSuccessorDominator();
fschneider 2012/02/02 14:59:50 I guess this should be: candidate_dominator->Mark
danno 2012/02/06 16:54:57 Done.
359 }
360 HControlInstruction* end_instr = dominator_candidate->end();
361 int successor_count = end_instr->SuccessorCount();
362 for (int current = 0; current < successor_count; ++current) {
fschneider 2012/02/02 14:59:50 You can use HSuccessorIterator here.
danno 2012/02/06 16:54:57 Done.
363 HBasicBlock* successor = end_instr->SuccessorAt(current);
364 // Only count successors that remain inside the loop and don't loop back
365 // to a loop header.
366 if (successor->block_id() > dominator_candidate->block_id() &&
367 successor->block_id() <= last->block_id()) {
368 // Backwards edges must land on loop headers.
369 ASSERT(successor->block_id() > dominator_candidate->block_id() ||
370 successor->IsLoopHeader());
371 outstanding_sucsessors++;
372 }
373 }
374 }
375 }
376
377
318 int HBasicBlock::PredecessorIndexOf(HBasicBlock* predecessor) const { 378 int HBasicBlock::PredecessorIndexOf(HBasicBlock* predecessor) const {
319 for (int i = 0; i < predecessors_.length(); ++i) { 379 for (int i = 0; i < predecessors_.length(); ++i) {
320 if (predecessors_[i] == predecessor) return i; 380 if (predecessors_[i] == predecessor) return i;
321 } 381 }
322 UNREACHABLE(); 382 UNREACHABLE();
323 return -1; 383 return -1;
324 } 384 }
325 385
326 386
327 #ifdef DEBUG 387 #ifdef DEBUG
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
747 ASSERT(block->end()->SecondSuccessor() == NULL || 807 ASSERT(block->end()->SecondSuccessor() == NULL ||
748 order->Contains(block->end()->SecondSuccessor()) || 808 order->Contains(block->end()->SecondSuccessor()) ||
749 block->end()->SecondSuccessor()->IsLoopHeader()); 809 block->end()->SecondSuccessor()->IsLoopHeader());
750 order->Add(block); 810 order->Add(block);
751 } 811 }
752 812
753 813
754 void HGraph::AssignDominators() { 814 void HGraph::AssignDominators() {
755 HPhase phase("Assign dominators", this); 815 HPhase phase("Assign dominators", this);
756 for (int i = 0; i < blocks_.length(); ++i) { 816 for (int i = 0; i < blocks_.length(); ++i) {
757 if (blocks_[i]->IsLoopHeader()) { 817 HBasicBlock* block = blocks_[i];
818 if (block->IsLoopHeader()) {
758 // Only the first predecessor of a loop header is from outside the loop. 819 // Only the first predecessor of a loop header is from outside the loop.
759 // All others are back edges, and thus cannot dominate the loop header. 820 // All others are back edges, and thus cannot dominate the loop header.
760 blocks_[i]->AssignCommonDominator(blocks_[i]->predecessors()->first()); 821 block->AssignCommonDominator(block->predecessors()->first());
822 block->AssignLoopSuccessorDominators();
761 } else { 823 } else {
762 for (int j = blocks_[i]->predecessors()->length() - 1; j >= 0; --j) { 824 for (int j = blocks_[i]->predecessors()->length() - 1; j >= 0; --j) {
763 blocks_[i]->AssignCommonDominator(blocks_[i]->predecessors()->at(j)); 825 blocks_[i]->AssignCommonDominator(blocks_[i]->predecessors()->at(j));
764 } 826 }
765 } 827 }
766 } 828 }
767 } 829 }
768 830
769 // Mark all blocks that are dominated by an unconditional soft deoptimize to 831 // Mark all blocks that are dominated by an unconditional soft deoptimize to
770 // prevent code motion across those blocks. 832 // prevent code motion across those blocks.
(...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after
1368 1430
1369 private: 1431 private:
1370 GVNFlagSet CollectSideEffectsOnPathsToDominatedBlock( 1432 GVNFlagSet CollectSideEffectsOnPathsToDominatedBlock(
1371 HBasicBlock* dominator, 1433 HBasicBlock* dominator,
1372 HBasicBlock* dominated); 1434 HBasicBlock* dominated);
1373 void AnalyzeBlock(HBasicBlock* block, HValueMap* map); 1435 void AnalyzeBlock(HBasicBlock* block, HValueMap* map);
1374 void ComputeBlockSideEffects(); 1436 void ComputeBlockSideEffects();
1375 void LoopInvariantCodeMotion(); 1437 void LoopInvariantCodeMotion();
1376 void ProcessLoopBlock(HBasicBlock* block, 1438 void ProcessLoopBlock(HBasicBlock* block,
1377 HBasicBlock* before_loop, 1439 HBasicBlock* before_loop,
1378 GVNFlagSet loop_kills); 1440 GVNFlagSet loop_kills,
1441 GVNFlagSet* accumulated_first_time_depends);
1379 bool AllowCodeMotion(); 1442 bool AllowCodeMotion();
1380 bool ShouldMove(HInstruction* instr, HBasicBlock* loop_header); 1443 bool ShouldMove(HInstruction* instr, HBasicBlock* loop_header);
1381 1444
1382 HGraph* graph() { return graph_; } 1445 HGraph* graph() { return graph_; }
1383 CompilationInfo* info() { return info_; } 1446 CompilationInfo* info() { return info_; }
1384 Zone* zone() { return graph_->zone(); } 1447 Zone* zone() { return graph_->zone(); }
1385 1448
1386 HGraph* graph_; 1449 HGraph* graph_;
1387 CompilationInfo* info_; 1450 CompilationInfo* info_;
1388 bool removed_side_effects_; 1451 bool removed_side_effects_;
1389 1452
1390 // A map of block IDs to their side effects. 1453 // A map of block IDs to their side effects.
1391 ZoneList<GVNFlagSet> block_side_effects_; 1454 ZoneList<GVNFlagSet> block_side_effects_;
1392 1455
1393 // A map of loop header block IDs to their loop's side effects. 1456 // A map of loop header block IDs to their loop's side effects.
1394 ZoneList<GVNFlagSet> loop_side_effects_; 1457 ZoneList<GVNFlagSet> loop_side_effects_;
1395 1458
1396 // Used when collecting side effects on paths from dominator to 1459 // Used when collecting side effects on paths from dominator to
1397 // dominated. 1460 // dominated.
1398 SparseSet visited_on_paths_; 1461 SparseSet visited_on_paths_;
1399 }; 1462 };
1400 1463
1401 1464
1402 bool HGlobalValueNumberer::Analyze() { 1465 bool HGlobalValueNumberer::Analyze() {
1466 removed_side_effects_ = false;
1403 ComputeBlockSideEffects(); 1467 ComputeBlockSideEffects();
1404 if (FLAG_loop_invariant_code_motion) { 1468 if (FLAG_loop_invariant_code_motion) {
1405 LoopInvariantCodeMotion(); 1469 LoopInvariantCodeMotion();
1406 } 1470 }
1407 HValueMap* map = new(zone()) HValueMap(); 1471 HValueMap* map = new(zone()) HValueMap();
1408 AnalyzeBlock(graph_->entry_block(), map); 1472 AnalyzeBlock(graph_->entry_block(), map);
1409 return removed_side_effects_; 1473 return removed_side_effects_;
1410 } 1474 }
1411 1475
1412 1476
1413 void HGlobalValueNumberer::ComputeBlockSideEffects() { 1477 void HGlobalValueNumberer::ComputeBlockSideEffects() {
1478 for (int i = 0; i < loop_side_effects_.length(); ++i) {
fschneider 2012/02/02 14:59:50 Comment on why resetting the loop side effect sets
danno 2012/02/06 16:54:57 Done.
1479 loop_side_effects_[i].RemoveAll();
1480 }
1414 for (int i = graph_->blocks()->length() - 1; i >= 0; --i) { 1481 for (int i = graph_->blocks()->length() - 1; i >= 0; --i) {
1415 // Compute side effects for the block. 1482 // Compute side effects for the block.
1416 HBasicBlock* block = graph_->blocks()->at(i); 1483 HBasicBlock* block = graph_->blocks()->at(i);
1417 HInstruction* instr = block->first(); 1484 HInstruction* instr = block->first();
1418 int id = block->block_id(); 1485 int id = block->block_id();
1419 GVNFlagSet side_effects; 1486 GVNFlagSet side_effects;
1420 while (instr != NULL) { 1487 while (instr != NULL) {
1421 side_effects.Add(instr->ChangesFlags()); 1488 side_effects.Add(instr->ChangesFlags());
1422 instr = instr->next(); 1489 instr = instr->next();
1423 } 1490 }
(...skipping 17 matching lines...) Expand all
1441 1508
1442 void HGlobalValueNumberer::LoopInvariantCodeMotion() { 1509 void HGlobalValueNumberer::LoopInvariantCodeMotion() {
1443 for (int i = graph_->blocks()->length() - 1; i >= 0; --i) { 1510 for (int i = graph_->blocks()->length() - 1; i >= 0; --i) {
1444 HBasicBlock* block = graph_->blocks()->at(i); 1511 HBasicBlock* block = graph_->blocks()->at(i);
1445 if (block->IsLoopHeader()) { 1512 if (block->IsLoopHeader()) {
1446 GVNFlagSet side_effects = loop_side_effects_[block->block_id()]; 1513 GVNFlagSet side_effects = loop_side_effects_[block->block_id()];
1447 TraceGVN("Try loop invariant motion for block B%d effects=0x%x\n", 1514 TraceGVN("Try loop invariant motion for block B%d effects=0x%x\n",
1448 block->block_id(), 1515 block->block_id(),
1449 side_effects.ToIntegral()); 1516 side_effects.ToIntegral());
1450 1517
1518 GVNFlagSet accumulated_first_time_depends;
1451 HBasicBlock* last = block->loop_information()->GetLastBackEdge(); 1519 HBasicBlock* last = block->loop_information()->GetLastBackEdge();
1452 for (int j = block->block_id(); j <= last->block_id(); ++j) { 1520 for (int j = block->block_id(); j <= last->block_id(); ++j) {
1453 ProcessLoopBlock(graph_->blocks()->at(j), block, side_effects); 1521 ProcessLoopBlock(graph_->blocks()->at(j), block, side_effects,
1522 &accumulated_first_time_depends);
1454 } 1523 }
1455 } 1524 }
1456 } 1525 }
1457 } 1526 }
1458 1527
1459 1528
1460 void HGlobalValueNumberer::ProcessLoopBlock(HBasicBlock* block, 1529 void HGlobalValueNumberer::ProcessLoopBlock(
1461 HBasicBlock* loop_header, 1530 HBasicBlock* block,
1462 GVNFlagSet loop_kills) { 1531 HBasicBlock* loop_header,
1532 GVNFlagSet loop_kills,
1533 GVNFlagSet* accumulated_first_time_depends) {
1463 HBasicBlock* pre_header = loop_header->predecessors()->at(0); 1534 HBasicBlock* pre_header = loop_header->predecessors()->at(0);
1464 GVNFlagSet depends_flags = HValue::ConvertChangesToDependsFlags(loop_kills); 1535 GVNFlagSet depends_flags = HValue::ConvertChangesToDependsFlags(loop_kills);
1465 TraceGVN("Loop invariant motion for B%d depends_flags=0x%x\n", 1536 TraceGVN("Loop invariant motion for B%d depends_flags=0x%x\n",
1466 block->block_id(), 1537 block->block_id(),
1467 depends_flags.ToIntegral()); 1538 depends_flags.ToIntegral());
1468 HInstruction* instr = block->first(); 1539 HInstruction* instr = block->first();
1469 while (instr != NULL) { 1540 while (instr != NULL) {
1470 HInstruction* next = instr->next(); 1541 HInstruction* next = instr->next();
1471 if (instr->CheckFlag(HValue::kUseGVN) && 1542 bool hoisted = false;
1472 !instr->gvn_flags().ContainsAnyOf(depends_flags)) { 1543 if (instr->CheckFlag(HValue::kUseGVN)) {
1473 TraceGVN("Checking instruction %d (%s)\n", 1544 TraceGVN("Checking instruction %d (%s) instruction GVN flags 0x%X, "
1545 "loop kills 0x%X\n",
1474 instr->id(), 1546 instr->id(),
1475 instr->Mnemonic()); 1547 instr->Mnemonic(),
1476 bool inputs_loop_invariant = true; 1548 instr->gvn_flags().ToIntegral(),
1477 for (int i = 0; i < instr->OperandCount(); ++i) { 1549 depends_flags.ToIntegral());
1478 if (instr->OperandAt(i)->IsDefinedAfter(pre_header)) { 1550 bool can_hoist = !instr->gvn_flags().ContainsAnyOf(depends_flags);
1479 inputs_loop_invariant = false; 1551 if (!can_hoist &&
1552 !instr->HasObservableSideEffects() &&
fschneider 2012/02/02 14:59:50 maybe just say: if (!can_hoist && instr->IsTrans
danno 2012/02/06 16:54:57 Done.
1553 instr->HasOneTimeSideEffects()) {
1554 // It's only possible to hoist one time side effects if there are no
1555 // dependencies on their changes from the loop header to the current
1556 // instruction.
1557 GVNFlagSet converted_changes =
1558 HValue::ConvertChangesToDependsFlags(instr->ChangesFlags());
1559 TraceGVN("Checking dependencies on one-time instruction %d (%s) "
1560 "converted changes 0x%X, accumulated depends 0x%X\n",
1561 instr->id(),
1562 instr->Mnemonic(),
1563 converted_changes.ToIntegral(),
1564 accumulated_first_time_depends->ToIntegral());
1565 // It's possible to hoist one-time side effects from the current loop
1566 // loop only if they dominate all of the successor blocks in the same
1567 // loop and there are not any instructions that have Changes/DependsOn
1568 // that intervene between it and the beginning of the loop header.
1569 bool not_in_nested_loop = block == loop_header ||
1570 (block->parent_loop_header() ==
1571 loop_header && !block->IsLoopHeader());
1572 can_hoist = !not_in_nested_loop &&
fschneider 2012/02/02 14:59:50 The double negation !not... should be avoided for
danno 2012/02/06 16:54:57 Done.
1573 block->IsLoopSuccessorDominator() &&
1574 !accumulated_first_time_depends->ContainsAnyOf(converted_changes);
1575 }
1576
1577 if (can_hoist) {
1578 bool inputs_loop_invariant = true;
1579 for (int i = 0; i < instr->OperandCount(); ++i) {
1580 if (instr->OperandAt(i)->IsDefinedAfter(pre_header)) {
1581 inputs_loop_invariant = false;
1582 }
1583 }
1584
1585 if (inputs_loop_invariant && ShouldMove(instr, loop_header)) {
1586 TraceGVN("Hoisting loop invariant instruction %d\n", instr->id());
1587 // Move the instruction out of the loop.
1588 instr->Unlink();
1589 instr->InsertBefore(pre_header->end());
1590 if (instr->HasSideEffects()) removed_side_effects_ = true;
1591 hoisted = true;
1480 } 1592 }
1481 } 1593 }
1482 1594 }
1483 if (inputs_loop_invariant && ShouldMove(instr, loop_header)) { 1595 if (!hoisted) {
1484 TraceGVN("Found loop invariant instruction %d\n", instr->id()); 1596 // Hoisting an instruction to the preheader causes its DependsOn or
1485 // Move the instruction out of the loop. 1597 // SideEffects flags to not prevent hosting OneTimeSideEffecct
fschneider 2012/02/02 14:59:50 I find the double negation in the comment confusin
danno 2012/02/06 16:54:57 Done.
1486 instr->Unlink(); 1598 // instructions.
1487 instr->InsertBefore(pre_header->end()); 1599 accumulated_first_time_depends->Add(instr->DependsOnFlags());
1488 } 1600 GVNFlagSet converted_changes =
1601 HValue::ConvertChangesToDependsFlags(instr->SideEffectFlags());
1602 accumulated_first_time_depends->Add(converted_changes);
1489 } 1603 }
1490 instr = next; 1604 instr = next;
1491 } 1605 }
1492 } 1606 }
1493 1607
1494 1608
1495 bool HGlobalValueNumberer::AllowCodeMotion() { 1609 bool HGlobalValueNumberer::AllowCodeMotion() {
1496 return info()->shared_info()->opt_count() + 1 < Compiler::kDefaultMaxOptCount; 1610 return info()->shared_info()->opt_count() + 1 < Compiler::kDefaultMaxOptCount;
1497 } 1611 }
1498 1612
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1540 while (instr != NULL) { 1654 while (instr != NULL) {
1541 HInstruction* next = instr->next(); 1655 HInstruction* next = instr->next();
1542 GVNFlagSet flags = instr->ChangesFlags(); 1656 GVNFlagSet flags = instr->ChangesFlags();
1543 if (!flags.IsEmpty()) { 1657 if (!flags.IsEmpty()) {
1544 // Clear all instructions in the map that are affected by side effects. 1658 // Clear all instructions in the map that are affected by side effects.
1545 map->Kill(flags); 1659 map->Kill(flags);
1546 TraceGVN("Instruction %d kills\n", instr->id()); 1660 TraceGVN("Instruction %d kills\n", instr->id());
1547 } 1661 }
1548 if (instr->CheckFlag(HValue::kUseGVN)) { 1662 if (instr->CheckFlag(HValue::kUseGVN)) {
1549 ASSERT(!instr->HasObservableSideEffects()); 1663 ASSERT(!instr->HasObservableSideEffects());
1664 ASSERT(!instr->HasSideEffects() || instr->HasOneTimeSideEffects());
1550 HValue* other = map->Lookup(instr); 1665 HValue* other = map->Lookup(instr);
1551 if (other != NULL) { 1666 if (other != NULL) {
1552 ASSERT(instr->Equals(other) && other->Equals(instr)); 1667 ASSERT(instr->Equals(other) && other->Equals(instr));
1553 TraceGVN("Replacing value %d (%s) with value %d (%s)\n", 1668 TraceGVN("Replacing value %d (%s) with value %d (%s)\n",
1554 instr->id(), 1669 instr->id(),
1555 instr->Mnemonic(), 1670 instr->Mnemonic(),
1556 other->id(), 1671 other->id(),
1557 other->Mnemonic()); 1672 other->Mnemonic());
1558 if (instr->HasSideEffects()) removed_side_effects_ = true; 1673 if (instr->HasSideEffects()) removed_side_effects_ = true;
1559 instr->DeleteAndReplaceWith(other); 1674 instr->DeleteAndReplaceWith(other);
(...skipping 827 matching lines...) Expand 10 before | Expand all | Expand 10 after
2387 2502
2388 // Perform common subexpression elimination and loop-invariant code motion. 2503 // Perform common subexpression elimination and loop-invariant code motion.
2389 if (FLAG_use_gvn) { 2504 if (FLAG_use_gvn) {
2390 HPhase phase("Global value numbering", graph()); 2505 HPhase phase("Global value numbering", graph());
2391 HGlobalValueNumberer gvn(graph(), info()); 2506 HGlobalValueNumberer gvn(graph(), info());
2392 bool removed_side_effects = gvn.Analyze(); 2507 bool removed_side_effects = gvn.Analyze();
2393 // Trigger a second analysis pass to further eliminate duplicate values that 2508 // Trigger a second analysis pass to further eliminate duplicate values that
2394 // could only be discovered by removing side-effect-generating instructions 2509 // could only be discovered by removing side-effect-generating instructions
2395 // during the first pass. 2510 // during the first pass.
2396 if (FLAG_smi_only_arrays && removed_side_effects) { 2511 if (FLAG_smi_only_arrays && removed_side_effects) {
2397 gvn.Analyze(); 2512 removed_side_effects = gvn.Analyze();
2513 ASSERT(!removed_side_effects);
2398 } 2514 }
2399 } 2515 }
2400 2516
2401 if (FLAG_use_range) { 2517 if (FLAG_use_range) {
2402 HRangeAnalysis rangeAnalysis(graph()); 2518 HRangeAnalysis rangeAnalysis(graph());
2403 rangeAnalysis.Analyze(); 2519 rangeAnalysis.Analyze();
2404 } 2520 }
2405 graph()->ComputeMinusZeroChecks(); 2521 graph()->ComputeMinusZeroChecks();
2406 2522
2407 // Eliminate redundant stack checks on backwards branches. 2523 // Eliminate redundant stack checks on backwards branches.
(...skipping 5047 matching lines...) Expand 10 before | Expand all | Expand 10 after
7455 } 7571 }
7456 } 7572 }
7457 7573
7458 #ifdef DEBUG 7574 #ifdef DEBUG
7459 if (graph_ != NULL) graph_->Verify(false); // No full verify. 7575 if (graph_ != NULL) graph_->Verify(false); // No full verify.
7460 if (allocator_ != NULL) allocator_->Verify(); 7576 if (allocator_ != NULL) allocator_->Verify();
7461 #endif 7577 #endif
7462 } 7578 }
7463 7579
7464 } } // namespace v8::internal 7580 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698