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

Side by Side Diff: src/hydrogen.cc

Issue 9365057: Relax TransitionElementsKind DependsOn/Changes dependencies. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Remove redundant code 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
« no previous file with comments | « no previous file | src/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1413 matching lines...) Expand 10 before | Expand all | Expand 10 after
1424 private: 1424 private:
1425 GVNFlagSet CollectSideEffectsOnPathsToDominatedBlock( 1425 GVNFlagSet CollectSideEffectsOnPathsToDominatedBlock(
1426 HBasicBlock* dominator, 1426 HBasicBlock* dominator,
1427 HBasicBlock* dominated); 1427 HBasicBlock* dominated);
1428 void AnalyzeBlock(HBasicBlock* block, HValueMap* map); 1428 void AnalyzeBlock(HBasicBlock* block, HValueMap* map);
1429 void ComputeBlockSideEffects(); 1429 void ComputeBlockSideEffects();
1430 void LoopInvariantCodeMotion(); 1430 void LoopInvariantCodeMotion();
1431 void ProcessLoopBlock(HBasicBlock* block, 1431 void ProcessLoopBlock(HBasicBlock* block,
1432 HBasicBlock* before_loop, 1432 HBasicBlock* before_loop,
1433 GVNFlagSet loop_kills, 1433 GVNFlagSet loop_kills,
1434 GVNFlagSet* accumulated_first_time_depends); 1434 GVNFlagSet* accumulated_first_time_depends,
1435 GVNFlagSet* accumulated_first_time_changes);
1435 bool AllowCodeMotion(); 1436 bool AllowCodeMotion();
1436 bool ShouldMove(HInstruction* instr, HBasicBlock* loop_header); 1437 bool ShouldMove(HInstruction* instr, HBasicBlock* loop_header);
1437 1438
1438 HGraph* graph() { return graph_; } 1439 HGraph* graph() { return graph_; }
1439 CompilationInfo* info() { return info_; } 1440 CompilationInfo* info() { return info_; }
1440 Zone* zone() { return graph_->zone(); } 1441 Zone* zone() { return graph_->zone(); }
1441 1442
1442 HGraph* graph_; 1443 HGraph* graph_;
1443 CompilationInfo* info_; 1444 CompilationInfo* info_;
1444 bool removed_side_effects_; 1445 bool removed_side_effects_;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1505 void HGlobalValueNumberer::LoopInvariantCodeMotion() { 1506 void HGlobalValueNumberer::LoopInvariantCodeMotion() {
1506 for (int i = graph_->blocks()->length() - 1; i >= 0; --i) { 1507 for (int i = graph_->blocks()->length() - 1; i >= 0; --i) {
1507 HBasicBlock* block = graph_->blocks()->at(i); 1508 HBasicBlock* block = graph_->blocks()->at(i);
1508 if (block->IsLoopHeader()) { 1509 if (block->IsLoopHeader()) {
1509 GVNFlagSet side_effects = loop_side_effects_[block->block_id()]; 1510 GVNFlagSet side_effects = loop_side_effects_[block->block_id()];
1510 TraceGVN("Try loop invariant motion for block B%d effects=0x%x\n", 1511 TraceGVN("Try loop invariant motion for block B%d effects=0x%x\n",
1511 block->block_id(), 1512 block->block_id(),
1512 side_effects.ToIntegral()); 1513 side_effects.ToIntegral());
1513 1514
1514 GVNFlagSet accumulated_first_time_depends; 1515 GVNFlagSet accumulated_first_time_depends;
1516 GVNFlagSet accumulated_first_time_changes;
1515 HBasicBlock* last = block->loop_information()->GetLastBackEdge(); 1517 HBasicBlock* last = block->loop_information()->GetLastBackEdge();
1516 for (int j = block->block_id(); j <= last->block_id(); ++j) { 1518 for (int j = block->block_id(); j <= last->block_id(); ++j) {
1517 ProcessLoopBlock(graph_->blocks()->at(j), block, side_effects, 1519 ProcessLoopBlock(graph_->blocks()->at(j), block, side_effects,
1518 &accumulated_first_time_depends); 1520 &accumulated_first_time_depends,
1521 &accumulated_first_time_changes);
1519 } 1522 }
1520 } 1523 }
1521 } 1524 }
1522 } 1525 }
1523 1526
1524 1527
1525 void HGlobalValueNumberer::ProcessLoopBlock( 1528 void HGlobalValueNumberer::ProcessLoopBlock(
1526 HBasicBlock* block, 1529 HBasicBlock* block,
1527 HBasicBlock* loop_header, 1530 HBasicBlock* loop_header,
1528 GVNFlagSet loop_kills, 1531 GVNFlagSet loop_kills,
1529 GVNFlagSet* accumulated_first_time_depends) { 1532 GVNFlagSet* first_time_depends,
1533 GVNFlagSet* first_time_changes) {
1530 HBasicBlock* pre_header = loop_header->predecessors()->at(0); 1534 HBasicBlock* pre_header = loop_header->predecessors()->at(0);
1531 GVNFlagSet depends_flags = HValue::ConvertChangesToDependsFlags(loop_kills); 1535 GVNFlagSet depends_flags = HValue::ConvertChangesToDependsFlags(loop_kills);
1532 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",
1533 block->block_id(), 1537 block->block_id(),
1534 depends_flags.ToIntegral()); 1538 depends_flags.ToIntegral());
1535 HInstruction* instr = block->first(); 1539 HInstruction* instr = block->first();
1536 while (instr != NULL) { 1540 while (instr != NULL) {
1537 HInstruction* next = instr->next(); 1541 HInstruction* next = instr->next();
1538 bool hoisted = false; 1542 bool hoisted = false;
1539 if (instr->CheckFlag(HValue::kUseGVN)) { 1543 if (instr->CheckFlag(HValue::kUseGVN)) {
1540 TraceGVN("Checking instruction %d (%s) instruction GVN flags 0x%X, " 1544 TraceGVN("Checking instruction %d (%s) instruction GVN flags 0x%X, "
1541 "loop kills 0x%X\n", 1545 "loop kills 0x%X\n",
1542 instr->id(), 1546 instr->id(),
1543 instr->Mnemonic(), 1547 instr->Mnemonic(),
1544 instr->gvn_flags().ToIntegral(), 1548 instr->gvn_flags().ToIntegral(),
1545 depends_flags.ToIntegral()); 1549 depends_flags.ToIntegral());
1546 bool can_hoist = !instr->gvn_flags().ContainsAnyOf(depends_flags); 1550 bool can_hoist = !instr->gvn_flags().ContainsAnyOf(depends_flags);
1547 if (!can_hoist && instr->IsTransitionElementsKind()) { 1551 if (instr->IsTransitionElementsKind()) {
1548 // It's only possible to hoist one time side effects if there are no 1552 // It's possible to hoist transitions out of a loop as long as the
1549 // dependencies on their changes from the loop header to the current 1553 // hoisting wouldn't move the transition past a DependsOn of one of it's
1550 // instruction. 1554 // changes or any instructions that might change an objects map or
1551 GVNFlagSet converted_changes = 1555 // elements contents.
1552 HValue::ConvertChangesToDependsFlags(instr->ChangesFlags()); 1556 GVNFlagSet changes = instr->ChangesFlags();
1553 TraceGVN("Checking dependencies on one-time instruction %d (%s) " 1557 GVNFlagSet hoist_depends_blockers =
1554 "converted changes 0x%X, accumulated depends 0x%X\n", 1558 HValue::ConvertChangesToDependsFlags(changes);
1559 // In addition to not hoisting transitions above other instructions that
1560 // change dependencies that the transition changes, it must not be
1561 // hoisted above map changes and stores to an elements backing store
1562 // that the transition might change.
1563 GVNFlagSet hoist_change_blockers = changes;
1564 hoist_change_blockers.Add(kChangesMaps);
1565 HTransitionElementsKind* trans = HTransitionElementsKind::cast(instr);
1566 if (trans->original_map()->has_fast_double_elements()) {
1567 hoist_change_blockers.Add(kChangesDoubleArrayElements);
1568 }
1569 if (trans->transitioned_map()->has_fast_double_elements()) {
1570 hoist_change_blockers.Add(kChangesArrayElements);
1571 }
1572 TraceGVN("Checking dependencies on HTransitionElementsKind %d (%s) "
1573 "hoist depends blockers 0x%X, hoist change blockers 0x%X, "
1574 "accumulated depends 0x%X, accumulated changes 0x%X\n",
1555 instr->id(), 1575 instr->id(),
1556 instr->Mnemonic(), 1576 instr->Mnemonic(),
1557 converted_changes.ToIntegral(), 1577 hoist_depends_blockers.ToIntegral(),
1558 accumulated_first_time_depends->ToIntegral()); 1578 hoist_change_blockers.ToIntegral(),
1559 // It's possible to hoist one-time side effects from the current loop 1579 first_time_depends->ToIntegral(),
1560 // loop only if they dominate all of the successor blocks in the same 1580 first_time_changes->ToIntegral());
1561 // loop and there are not any instructions that have Changes/DependsOn 1581 // It's possible to hoist transition from the current loop loop only if
1562 // that intervene between it and the beginning of the loop header. 1582 // they dominate all of the successor blocks in the same loop and there
1583 // are not any instructions that have Changes/DependsOn that intervene
1584 // between it and the beginning of the loop header.
1563 bool in_nested_loop = block != loop_header && 1585 bool in_nested_loop = block != loop_header &&
1564 ((block->parent_loop_header() != loop_header) || 1586 ((block->parent_loop_header() != loop_header) ||
1565 block->IsLoopHeader()); 1587 block->IsLoopHeader());
1566 can_hoist = !in_nested_loop && 1588 can_hoist = !in_nested_loop &&
1567 block->IsLoopSuccessorDominator() && 1589 block->IsLoopSuccessorDominator() &&
1568 !accumulated_first_time_depends->ContainsAnyOf(converted_changes); 1590 !first_time_depends->ContainsAnyOf(hoist_depends_blockers) &&
1591 !first_time_changes->ContainsAnyOf(hoist_change_blockers);
1569 } 1592 }
1570 1593
1571 if (can_hoist) { 1594 if (can_hoist) {
1572 bool inputs_loop_invariant = true; 1595 bool inputs_loop_invariant = true;
1573 for (int i = 0; i < instr->OperandCount(); ++i) { 1596 for (int i = 0; i < instr->OperandCount(); ++i) {
1574 if (instr->OperandAt(i)->IsDefinedAfter(pre_header)) { 1597 if (instr->OperandAt(i)->IsDefinedAfter(pre_header)) {
1575 inputs_loop_invariant = false; 1598 inputs_loop_invariant = false;
1576 } 1599 }
1577 } 1600 }
1578 1601
1579 if (inputs_loop_invariant && ShouldMove(instr, loop_header)) { 1602 if (inputs_loop_invariant && ShouldMove(instr, loop_header)) {
1580 TraceGVN("Hoisting loop invariant instruction %d\n", instr->id()); 1603 TraceGVN("Hoisting loop invariant instruction %d\n", instr->id());
1581 // Move the instruction out of the loop. 1604 // Move the instruction out of the loop.
1582 instr->Unlink(); 1605 instr->Unlink();
1583 instr->InsertBefore(pre_header->end()); 1606 instr->InsertBefore(pre_header->end());
1584 if (instr->HasSideEffects()) removed_side_effects_ = true; 1607 if (instr->HasSideEffects()) removed_side_effects_ = true;
1585 hoisted = true; 1608 hoisted = true;
1586 } 1609 }
1587 } 1610 }
1588 } 1611 }
1589 if (!hoisted) { 1612 if (!hoisted) {
1590 // If an instruction is not hoisted, we have to account for its side 1613 // If an instruction is not hoisted, we have to account for its side
1591 // effects when hoisting later HTransitionElementsKind instructions. 1614 // effects when hoisting later HTransitionElementsKind instructions.
1592 accumulated_first_time_depends->Add(instr->DependsOnFlags()); 1615 first_time_depends->Add(instr->DependsOnFlags());
1593 GVNFlagSet converted_changes = 1616 first_time_changes->Add(instr->ChangesFlags());
1594 HValue::ConvertChangesToDependsFlags(instr->SideEffectFlags());
1595 accumulated_first_time_depends->Add(converted_changes);
1596 } 1617 }
1597 instr = next; 1618 instr = next;
1598 } 1619 }
1599 } 1620 }
1600 1621
1601 1622
1602 bool HGlobalValueNumberer::AllowCodeMotion() { 1623 bool HGlobalValueNumberer::AllowCodeMotion() {
1603 return info()->shared_info()->opt_count() + 1 < Compiler::kDefaultMaxOptCount; 1624 return info()->shared_info()->opt_count() + 1 < Compiler::kDefaultMaxOptCount;
1604 } 1625 }
1605 1626
(...skipping 2841 matching lines...) Expand 10 before | Expand all | Expand 10 after
4447 map->FindTransitionedMap(&possible_transitioned_maps); 4468 map->FindTransitionedMap(&possible_transitioned_maps);
4448 transition_target.Add(transitioned_map); 4469 transition_target.Add(transitioned_map);
4449 } 4470 }
4450 4471
4451 int num_untransitionable_maps = 0; 4472 int num_untransitionable_maps = 0;
4452 Handle<Map> untransitionable_map; 4473 Handle<Map> untransitionable_map;
4453 for (int i = 0; i < maps->length(); ++i) { 4474 for (int i = 0; i < maps->length(); ++i) {
4454 Handle<Map> map = maps->at(i); 4475 Handle<Map> map = maps->at(i);
4455 ASSERT(map->IsMap()); 4476 ASSERT(map->IsMap());
4456 if (!transition_target.at(i).is_null()) { 4477 if (!transition_target.at(i).is_null()) {
4457 object = AddInstruction(new(zone()) HTransitionElementsKind( 4478 AddInstruction(new(zone()) HTransitionElementsKind(
4458 object, map, transition_target.at(i))); 4479 object, map, transition_target.at(i)));
4459 } else { 4480 } else {
4460 type_todo[map->elements_kind()] = true; 4481 type_todo[map->elements_kind()] = true;
4461 if (map->elements_kind() >= FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND) { 4482 if (map->elements_kind() >= FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND) {
4462 todo_external_array = true; 4483 todo_external_array = true;
4463 } 4484 }
4464 num_untransitionable_maps++; 4485 num_untransitionable_maps++;
4465 untransitionable_map = map; 4486 untransitionable_map = map;
4466 } 4487 }
4467 } 4488 }
(...skipping 3239 matching lines...) Expand 10 before | Expand all | Expand 10 after
7707 } 7728 }
7708 } 7729 }
7709 7730
7710 #ifdef DEBUG 7731 #ifdef DEBUG
7711 if (graph_ != NULL) graph_->Verify(false); // No full verify. 7732 if (graph_ != NULL) graph_->Verify(false); // No full verify.
7712 if (allocator_ != NULL) allocator_->Verify(); 7733 if (allocator_ != NULL) allocator_->Verify();
7713 #endif 7734 #endif
7714 } 7735 }
7715 7736
7716 } } // namespace v8::internal 7737 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698