| Index: src/hydrogen.cc
|
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc
|
| index 328ec327b14a97f33feca09a64558c120ef23d88..78a69c1afd5b815a5dfb0418cb4829ab1aecc850 100644
|
| --- a/src/hydrogen.cc
|
| +++ b/src/hydrogen.cc
|
| @@ -431,6 +431,32 @@ void HLoopInformation::RegisterBackEdge(HBasicBlock* block) {
|
| }
|
|
|
|
|
| +void HLoopInformation::ProcessEdge(HBasicBlock* destination) {
|
| + HLoopInformation* target_loop = destination->current_loop();
|
| + if (IsNestedInThisLoop(target_loop)) return;
|
| +
|
| + HLoopInformation* current_loop = this;
|
| + // TODO(mmassi) When we will support try..catch we will need to break out of
|
| + // this loop when we meet the catch block.
|
| + // From a correctness PoV we're safe anyway, but unnecessarily marking loops
|
| + // as having additional exits could prevent hoisting of bounds checks.
|
| + while (current_loop != NULL) {
|
| + if (target_loop == current_loop) return;
|
| + current_loop->exits_count_++;
|
| + current_loop = current_loop->parent_loop();
|
| + }
|
| +}
|
| +
|
| +
|
| +void HLoopInformation::ProcessThrow() {
|
| + HLoopInformation* current_loop = this;
|
| + while (current_loop != NULL) {
|
| + current_loop->exits_count_++;
|
| + current_loop = current_loop->parent_loop();
|
| + }
|
| +}
|
| +
|
| +
|
| HBasicBlock* HLoopInformation::GetLastBackEdge() const {
|
| int max_id = -1;
|
| HBasicBlock* result = NULL;
|
| @@ -2099,6 +2125,7 @@ HGraph::HGraph(CompilationInfo* info)
|
| uint32_instructions_(NULL),
|
| info_(info),
|
| zone_(info->zone()),
|
| + evaluated_relations_table_(info->zone()),
|
| is_recursive_(false),
|
| use_optimistic_licm_(false),
|
| has_soft_deoptimize_(false),
|
| @@ -2464,6 +2491,22 @@ void HGraph::OrderBlocks() {
|
| HBasicBlock* b = reverse_result[i];
|
| blocks_.Add(b, zone());
|
| b->set_block_id(index++);
|
| +
|
| + HLoopInformation* loop = b->current_loop();
|
| + if (loop != NULL) {
|
| + for (int i = 0; i < b->end()->SuccessorCount(); i++) {
|
| + HBasicBlock* successor = b->end()->SuccessorAt(i);
|
| + loop->ProcessEdge(successor);
|
| + }
|
| +
|
| + for (HInstruction* instruction = b->first();
|
| + instruction != NULL;
|
| + instruction = instruction->next()) {
|
| + if (instruction->IsThrow()) {
|
| + loop->ProcessThrow();
|
| + }
|
| + }
|
| + }
|
| }
|
| }
|
|
|
| @@ -4922,15 +4965,16 @@ bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) {
|
| sce.Process();
|
|
|
| if (FLAG_idefs) SetupInformativeDefinitions();
|
| - if (FLAG_array_bounds_checks_elimination && !FLAG_idefs) {
|
| + if (FLAG_array_bounds_checks_elimination) {
|
| EliminateRedundantBoundsChecks();
|
| }
|
| if (FLAG_array_index_dehoisting) DehoistSimpleArrayIndexComputations();
|
| + RestoreActualValues();
|
| +
|
| if (FLAG_dead_code_elimination) {
|
| DeadCodeElimination("H_Eliminate late dead code");
|
| }
|
|
|
| - RestoreActualValues();
|
|
|
| return true;
|
| }
|
| @@ -4962,13 +5006,6 @@ void HGraph::SetupInformativeDefinitionsRecursively(HBasicBlock* block) {
|
| for (int i = 0; i < block->dominated_blocks()->length(); ++i) {
|
| SetupInformativeDefinitionsRecursively(block->dominated_blocks()->at(i));
|
| }
|
| -
|
| - for (HInstruction* i = block->first(); i != NULL; i = i->next()) {
|
| - if (i->IsBoundsCheck()) {
|
| - HBoundsCheck* check = HBoundsCheck::cast(i);
|
| - check->ApplyIndexChange();
|
| - }
|
| - }
|
| }
|
|
|
|
|
| @@ -5257,6 +5294,36 @@ class BoundsCheckTable : private ZoneHashMap {
|
| };
|
|
|
|
|
| +void HGraph::EliminateRedundantBoundsChecksUsingIdefs(HBasicBlock* bb) {
|
| + for (HInstruction* i = bb->first(); i != NULL; i = i->next()) {
|
| + if (i->IsBoundsCheck()) {
|
| + HBoundsCheck* check = HBoundsCheck::cast(i);
|
| + if (check->index()->TryGuaranteeRange(check->length(), bb)) {
|
| + check->set_skip_check();
|
| + }
|
| + }
|
| + }
|
| +
|
| + for (int i = 0; i < bb->dominated_blocks()->length(); ++i) {
|
| + EliminateRedundantBoundsChecksUsingIdefs(bb->dominated_blocks()->at(i));
|
| + }
|
| +}
|
| +
|
| +
|
| +void HGraph::ApplyBoundsChecksIndexChanges(HBasicBlock* bb) {
|
| + for (HInstruction* i = bb->first(); i != NULL; i = i->next()) {
|
| + if (i->IsBoundsCheck()) {
|
| + HBoundsCheck* check = HBoundsCheck::cast(i);
|
| + check->ApplyIndexChange();
|
| + }
|
| + }
|
| +
|
| + for (int i = 0; i < bb->dominated_blocks()->length(); ++i) {
|
| + ApplyBoundsChecksIndexChanges(bb->dominated_blocks()->at(i));
|
| + }
|
| +}
|
| +
|
| +
|
| // Eliminates checks in bb and recursively in the dominated blocks.
|
| // Also replace the results of check instructions with the original value, if
|
| // the result is used. This is safe now, since we don't do code motion after
|
| @@ -5330,8 +5397,13 @@ void HGraph::EliminateRedundantBoundsChecks(HBasicBlock* bb,
|
|
|
| void HGraph::EliminateRedundantBoundsChecks() {
|
| HPhase phase("H_Eliminate bounds checks", this);
|
| - BoundsCheckTable checks_table(zone());
|
| - EliminateRedundantBoundsChecks(entry_block(), &checks_table);
|
| + if (FLAG_idefs) {
|
| + EliminateRedundantBoundsChecksUsingIdefs(entry_block());
|
| + ApplyBoundsChecksIndexChanges(entry_block());
|
| + } else {
|
| + BoundsCheckTable checks_table(zone());
|
| + EliminateRedundantBoundsChecks(entry_block(), &checks_table);
|
| + }
|
| }
|
|
|
|
|
|
|