X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fv8%2Fsrc%2Fhydrogen-gvn.cc;h=bc836890bb136544c560474c222d7b354c9ddb4a;hb=ff3e2503a20db9193d323c1d19c38c68004dec4a;hp=e3bf316f3790b555ef5fdf426e0f77a2b49745e2;hpb=172ee7c03df346ff158858709f7f6494e695e0e4;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/v8/src/hydrogen-gvn.cc b/src/v8/src/hydrogen-gvn.cc index e3bf316..bc83689 100644 --- a/src/v8/src/hydrogen-gvn.cc +++ b/src/v8/src/hydrogen-gvn.cc @@ -364,35 +364,48 @@ void HSideEffectMap::Store(GVNFlagSet flags, HInstruction* instr) { HGlobalValueNumberingPhase::HGlobalValueNumberingPhase(HGraph* graph) - : HPhase("H_Global value numbering", graph), - removed_side_effects_(false), - block_side_effects_(graph->blocks()->length(), zone()), - loop_side_effects_(graph->blocks()->length(), zone()), - visited_on_paths_(graph->blocks()->length(), zone()) { - ASSERT(!AllowHandleAllocation::IsAllowed()); - block_side_effects_.AddBlock(GVNFlagSet(), graph->blocks()->length(), - zone()); - loop_side_effects_.AddBlock(GVNFlagSet(), graph->blocks()->length(), + : HPhase("H_Global value numbering", graph), + removed_side_effects_(false), + block_side_effects_(graph->blocks()->length(), zone()), + loop_side_effects_(graph->blocks()->length(), zone()), + visited_on_paths_(graph->blocks()->length(), zone()) { + ASSERT(!AllowHandleAllocation::IsAllowed()); + block_side_effects_.AddBlock(GVNFlagSet(), graph->blocks()->length(), zone()); - } + loop_side_effects_.AddBlock(GVNFlagSet(), graph->blocks()->length(), + zone()); +} + + +void HGlobalValueNumberingPhase::Run() { + ASSERT(!removed_side_effects_); + for (int i = FLAG_gvn_iterations; i > 0; --i) { + // Compute the side effects. + ComputeBlockSideEffects(); + + // Perform loop invariant code motion if requested. + if (FLAG_loop_invariant_code_motion) LoopInvariantCodeMotion(); + + // Perform the actual value numbering. + AnalyzeGraph(); -void HGlobalValueNumberingPhase::Analyze() { - removed_side_effects_ = false; - ComputeBlockSideEffects(); - if (FLAG_loop_invariant_code_motion) { - LoopInvariantCodeMotion(); + // Continue GVN if we removed any side effects. + if (!removed_side_effects_) break; + removed_side_effects_ = false; + + // Clear all side effects. + ASSERT_EQ(block_side_effects_.length(), graph()->blocks()->length()); + ASSERT_EQ(loop_side_effects_.length(), graph()->blocks()->length()); + for (int i = 0; i < graph()->blocks()->length(); ++i) { + block_side_effects_[i].RemoveAll(); + loop_side_effects_[i].RemoveAll(); + } + visited_on_paths_.Clear(); } - AnalyzeGraph(); } void HGlobalValueNumberingPhase::ComputeBlockSideEffects() { - // The Analyze phase of GVN can be called multiple times. Clear loop side - // effects before computing them to erase the contents from previous Analyze - // passes. - for (int i = 0; i < loop_side_effects_.length(); ++i) { - loop_side_effects_[i].RemoveAll(); - } for (int i = graph()->blocks()->length() - 1; i >= 0; --i) { // Compute side effects for the block. HBasicBlock* block = graph()->blocks()->at(i); @@ -412,10 +425,13 @@ void HGlobalValueNumberingPhase::ComputeBlockSideEffects() { // Propagate loop side effects upwards. if (block->HasParentLoopHeader()) { - int header_id = block->parent_loop_header()->block_id(); - loop_side_effects_[header_id].Add(block->IsLoopHeader() - ? loop_side_effects_[id] - : side_effects); + HBasicBlock* with_parent = block; + if (block->IsLoopHeader()) side_effects = loop_side_effects_[id]; + do { + HBasicBlock* parent_block = with_parent->parent_loop_header(); + loop_side_effects_[parent_block->block_id()].Add(side_effects); + with_parent = parent_block; + } while (with_parent->HasParentLoopHeader()); } } } @@ -423,7 +439,7 @@ void HGlobalValueNumberingPhase::ComputeBlockSideEffects() { SmartArrayPointer GetGVNFlagsString(GVNFlagSet flags) { - char underlying_buffer[kLastFlag * 128]; + char underlying_buffer[kNumberOfFlags * 128]; Vector buffer(underlying_buffer, sizeof(underlying_buffer)); #if DEBUG int offset = 0; @@ -432,8 +448,8 @@ SmartArrayPointer GetGVNFlagsString(GVNFlagSet flags) { buffer[0] = 0; uint32_t set_depends_on = 0; uint32_t set_changes = 0; - for (int bit = 0; bit < kLastFlag; ++bit) { - if ((flags.ToIntegral() & (1 << bit)) != 0) { + for (int bit = 0; bit < kNumberOfFlags; ++bit) { + if (flags.Contains(static_cast(bit))) { if (bit % 2 == 0) { set_changes++; } else { @@ -441,16 +457,16 @@ SmartArrayPointer GetGVNFlagsString(GVNFlagSet flags) { } } } - bool positive_changes = set_changes < (kLastFlag / 2); - bool positive_depends_on = set_depends_on < (kLastFlag / 2); + bool positive_changes = set_changes < (kNumberOfFlags / 2); + bool positive_depends_on = set_depends_on < (kNumberOfFlags / 2); if (set_changes > 0) { if (positive_changes) { offset += OS::SNPrintF(buffer + offset, "changes ["); } else { offset += OS::SNPrintF(buffer + offset, "changes all except ["); } - for (int bit = 0; bit < kLastFlag; ++bit) { - if (((flags.ToIntegral() & (1 << bit)) != 0) == positive_changes) { + for (int bit = 0; bit < kNumberOfFlags; ++bit) { + if (flags.Contains(static_cast(bit)) == positive_changes) { switch (static_cast(bit)) { #define DECLARE_FLAG(type) \ case kChanges##type: \ @@ -478,8 +494,8 @@ GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG) } else { offset += OS::SNPrintF(buffer + offset, "depends on all except ["); } - for (int bit = 0; bit < kLastFlag; ++bit) { - if (((flags.ToIntegral() & (1 << bit)) != 0) == positive_depends_on) { + for (int bit = 0; bit < kNumberOfFlags; ++bit) { + if (flags.Contains(static_cast(bit)) == positive_depends_on) { switch (static_cast(bit)) { #define DECLARE_FLAG(type) \ case kDependsOn##type: \ @@ -517,15 +533,11 @@ void HGlobalValueNumberingPhase::LoopInvariantCodeMotion() { GVNFlagSet side_effects = loop_side_effects_[block->block_id()]; TRACE_GVN_2("Try loop invariant motion for block B%d %s\n", block->block_id(), - *GetGVNFlagsString(side_effects)); + GetGVNFlagsString(side_effects).get()); - GVNFlagSet accumulated_first_time_depends; - GVNFlagSet accumulated_first_time_changes; HBasicBlock* last = block->loop_information()->GetLastBackEdge(); for (int j = block->block_id(); j <= last->block_id(); ++j) { - ProcessLoopBlock(graph()->blocks()->at(j), block, side_effects, - &accumulated_first_time_depends, - &accumulated_first_time_changes); + ProcessLoopBlock(graph()->blocks()->at(j), block, side_effects); } } } @@ -535,24 +547,21 @@ void HGlobalValueNumberingPhase::LoopInvariantCodeMotion() { void HGlobalValueNumberingPhase::ProcessLoopBlock( HBasicBlock* block, HBasicBlock* loop_header, - GVNFlagSet loop_kills, - GVNFlagSet* first_time_depends, - GVNFlagSet* first_time_changes) { + GVNFlagSet loop_kills) { HBasicBlock* pre_header = loop_header->predecessors()->at(0); GVNFlagSet depends_flags = HValue::ConvertChangesToDependsFlags(loop_kills); TRACE_GVN_2("Loop invariant motion for B%d %s\n", block->block_id(), - *GetGVNFlagsString(depends_flags)); + GetGVNFlagsString(depends_flags).get()); HInstruction* instr = block->first(); while (instr != NULL) { HInstruction* next = instr->next(); - bool hoisted = false; if (instr->CheckFlag(HValue::kUseGVN)) { TRACE_GVN_4("Checking instruction %d (%s) %s. Loop %s\n", instr->id(), instr->Mnemonic(), - *GetGVNFlagsString(instr->gvn_flags()), - *GetGVNFlagsString(loop_kills)); + GetGVNFlagsString(instr->gvn_flags()).get(), + GetGVNFlagsString(loop_kills).get()); bool can_hoist = !instr->gvn_flags().ContainsAnyOf(depends_flags); if (can_hoist && !graph()->use_optimistic_licm()) { can_hoist = block->IsLoopSuccessorDominator(); @@ -567,31 +576,15 @@ void HGlobalValueNumberingPhase::ProcessLoopBlock( } if (inputs_loop_invariant && ShouldMove(instr, loop_header)) { - TRACE_GVN_1("Hoisting loop invariant instruction %d\n", instr->id()); + TRACE_GVN_2("Hoisting loop invariant instruction i%d to block B%d\n", + instr->id(), pre_header->block_id()); // Move the instruction out of the loop. instr->Unlink(); instr->InsertBefore(pre_header->end()); if (instr->HasSideEffects()) removed_side_effects_ = true; - hoisted = true; } } } - if (!hoisted) { - // If an instruction is not hoisted, we have to account for its side - // effects when hoisting later HTransitionElementsKind instructions. - GVNFlagSet previous_depends = *first_time_depends; - GVNFlagSet previous_changes = *first_time_changes; - first_time_depends->Add(instr->DependsOnFlags()); - first_time_changes->Add(instr->ChangesFlags()); - if (!(previous_depends == *first_time_depends)) { - TRACE_GVN_1("Updated first-time accumulated %s\n", - *GetGVNFlagsString(*first_time_depends)); - } - if (!(previous_changes == *first_time_changes)) { - TRACE_GVN_1("Updated first-time accumulated %s\n", - *GetGVNFlagsString(*first_time_changes)); - } - } instr = next; } } @@ -787,7 +780,9 @@ void HGlobalValueNumberingPhase::AnalyzeGraph() { instr->Mnemonic(), other->id(), other->Mnemonic()); - instr->HandleSideEffectDominator(changes_flag, other); + if (instr->HandleSideEffectDominator(changes_flag, other)) { + removed_side_effects_ = true; + } } } } @@ -801,7 +796,7 @@ void HGlobalValueNumberingPhase::AnalyzeGraph() { map->Kill(flags); dominators->Store(flags, instr); TRACE_GVN_2("Instruction %d %s\n", instr->id(), - *GetGVNFlagsString(flags)); + GetGVNFlagsString(flags).get()); } if (instr->CheckFlag(HValue::kUseGVN)) { ASSERT(!instr->HasObservableSideEffects());