OLD | NEW |
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 2033 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2044 HBasicBlock* result = new(zone()) HBasicBlock(this); | 2044 HBasicBlock* result = new(zone()) HBasicBlock(this); |
2045 blocks_.Add(result, zone()); | 2045 blocks_.Add(result, zone()); |
2046 return result; | 2046 return result; |
2047 } | 2047 } |
2048 | 2048 |
2049 | 2049 |
2050 void HGraph::FinalizeUniqueValueIds() { | 2050 void HGraph::FinalizeUniqueValueIds() { |
2051 DisallowHeapAllocation no_gc; | 2051 DisallowHeapAllocation no_gc; |
2052 ASSERT(!isolate()->optimizing_compiler_thread()->IsOptimizerThread()); | 2052 ASSERT(!isolate()->optimizing_compiler_thread()->IsOptimizerThread()); |
2053 for (int i = 0; i < blocks()->length(); ++i) { | 2053 for (int i = 0; i < blocks()->length(); ++i) { |
2054 for (HInstruction* instr = blocks()->at(i)->first(); | 2054 for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) { |
2055 instr != NULL; | 2055 it.Current()->FinalizeUniqueValueId(); |
2056 instr = instr->next()) { | |
2057 instr->FinalizeUniqueValueId(); | |
2058 } | 2056 } |
2059 } | 2057 } |
2060 } | 2058 } |
2061 | 2059 |
2062 | 2060 |
2063 void HGraph::Canonicalize() { | 2061 void HGraph::Canonicalize() { |
2064 HPhase phase("H_Canonicalize", this); | 2062 HPhase phase("H_Canonicalize", this); |
2065 // Before removing no-op instructions, save their semantic value. | 2063 // Before removing no-op instructions, save their semantic value. |
2066 // We must be careful not to set the flag unnecessarily, because GVN | 2064 // We must be careful not to set the flag unnecessarily, because GVN |
2067 // cannot identify two instructions when their flag value differs. | 2065 // cannot identify two instructions when their flag value differs. |
2068 for (int i = 0; i < blocks()->length(); ++i) { | 2066 for (int i = 0; i < blocks()->length(); ++i) { |
2069 HInstruction* instr = blocks()->at(i)->first(); | 2067 for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) { |
2070 while (instr != NULL) { | 2068 HInstruction* instr = it.Current(); |
2071 if (instr->IsArithmeticBinaryOperation() && | 2069 if (instr->IsArithmeticBinaryOperation() && |
2072 instr->representation().IsInteger32() && | 2070 instr->representation().IsInteger32() && |
2073 instr->HasAtLeastOneUseWithFlagAndNoneWithout( | 2071 instr->HasAtLeastOneUseWithFlagAndNoneWithout( |
2074 HInstruction::kTruncatingToInt32)) { | 2072 HInstruction::kTruncatingToInt32)) { |
2075 instr->SetFlag(HInstruction::kAllUsesTruncatingToInt32); | 2073 instr->SetFlag(HInstruction::kAllUsesTruncatingToInt32); |
2076 } | 2074 } |
2077 instr = instr->next(); | |
2078 } | 2075 } |
2079 } | 2076 } |
2080 // Perform actual Canonicalization pass. | 2077 // Perform actual Canonicalization pass. |
2081 for (int i = 0; i < blocks()->length(); ++i) { | 2078 for (int i = 0; i < blocks()->length(); ++i) { |
2082 HInstruction* instr = blocks()->at(i)->first(); | 2079 for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) { |
2083 while (instr != NULL) { | 2080 HInstruction* instr = it.Current(); |
2084 HValue* value = instr->Canonicalize(); | 2081 HValue* value = instr->Canonicalize(); |
2085 if (value != instr) instr->DeleteAndReplaceWith(value); | 2082 if (value != instr) instr->DeleteAndReplaceWith(value); |
2086 instr = instr->next(); | |
2087 } | 2083 } |
2088 } | 2084 } |
2089 } | 2085 } |
2090 | 2086 |
2091 // Block ordering was implemented with two mutually recursive methods, | 2087 // Block ordering was implemented with two mutually recursive methods, |
2092 // HGraph::Postorder and HGraph::PostorderLoopBlocks. | 2088 // HGraph::Postorder and HGraph::PostorderLoopBlocks. |
2093 // The recursion could lead to stack overflow so the algorithm has been | 2089 // The recursion could lead to stack overflow so the algorithm has been |
2094 // implemented iteratively. | 2090 // implemented iteratively. |
2095 // At a high level the algorithm looks like this: | 2091 // At a high level the algorithm looks like this: |
2096 // | 2092 // |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2451 const ZoneList<HBasicBlock*>* predecessors = block->predecessors(); | 2447 const ZoneList<HBasicBlock*>* predecessors = block->predecessors(); |
2452 int predecessors_length = predecessors->length(); | 2448 int predecessors_length = predecessors->length(); |
2453 bool all_predecessors_deoptimizing = (predecessors_length > 0); | 2449 bool all_predecessors_deoptimizing = (predecessors_length > 0); |
2454 for (int j = 0; j < predecessors_length; ++j) { | 2450 for (int j = 0; j < predecessors_length; ++j) { |
2455 if (!predecessors->at(j)->IsDeoptimizing()) { | 2451 if (!predecessors->at(j)->IsDeoptimizing()) { |
2456 all_predecessors_deoptimizing = false; | 2452 all_predecessors_deoptimizing = false; |
2457 break; | 2453 break; |
2458 } | 2454 } |
2459 } | 2455 } |
2460 if (all_predecessors_deoptimizing) nullify = true; | 2456 if (all_predecessors_deoptimizing) nullify = true; |
2461 for (HInstruction* instr = block->first(); instr != NULL; | 2457 for (HInstructionIterator it(block); !it.Done(); it.Advance()) { |
2462 instr = instr->next()) { | 2458 HInstruction* instr = it.Current(); |
2463 // Leave the basic structure of the graph intact. | 2459 // Leave the basic structure of the graph intact. |
2464 if (instr->IsBlockEntry()) continue; | 2460 if (instr->IsBlockEntry()) continue; |
2465 if (instr->IsControlInstruction()) continue; | 2461 if (instr->IsControlInstruction()) continue; |
2466 if (instr->IsSimulate()) continue; | 2462 if (instr->IsSimulate()) continue; |
2467 if (instr->IsEnterInlined()) continue; | 2463 if (instr->IsEnterInlined()) continue; |
2468 if (instr->IsLeaveInlined()) continue; | 2464 if (instr->IsLeaveInlined()) continue; |
2469 if (nullify) { | 2465 if (nullify) { |
2470 HInstruction* last_dummy = NULL; | 2466 HInstruction* last_dummy = NULL; |
2471 for (int j = 0; j < instr->OperandCount(); ++j) { | 2467 for (int j = 0; j < instr->OperandCount(); ++j) { |
2472 HValue* operand = instr->OperandAt(j); | 2468 HValue* operand = instr->OperandAt(j); |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2719 } | 2715 } |
2720 } | 2716 } |
2721 | 2717 |
2722 // Process phi instructions. | 2718 // Process phi instructions. |
2723 for (int i = 0; i < block->phis()->length(); ++i) { | 2719 for (int i = 0; i < block->phis()->length(); ++i) { |
2724 HPhi* phi = block->phis()->at(i); | 2720 HPhi* phi = block->phis()->at(i); |
2725 InferRange(phi); | 2721 InferRange(phi); |
2726 } | 2722 } |
2727 | 2723 |
2728 // Go through all instructions of the current block. | 2724 // Go through all instructions of the current block. |
2729 HInstruction* instr = block->first(); | 2725 for (HInstructionIterator it(block); !it.Done(); it.Advance()) { |
2730 while (instr != block->end()) { | 2726 InferRange(it.Current()); |
2731 InferRange(instr); | |
2732 instr = instr->next(); | |
2733 } | 2727 } |
2734 | 2728 |
2735 // Continue analysis in all dominated blocks. | 2729 // Continue analysis in all dominated blocks. |
2736 for (int i = 0; i < block->dominated_blocks()->length(); ++i) { | 2730 for (int i = 0; i < block->dominated_blocks()->length(); ++i) { |
2737 Analyze(block->dominated_blocks()->at(i)); | 2731 Analyze(block->dominated_blocks()->at(i)); |
2738 } | 2732 } |
2739 | 2733 |
2740 RollBackTo(last_changed_range); | 2734 RollBackTo(last_changed_range); |
2741 } | 2735 } |
2742 | 2736 |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2849 // For each loop block walk the dominator tree from the backwards branch to | 2843 // For each loop block walk the dominator tree from the backwards branch to |
2850 // the loop header. If a call instruction is encountered the backwards branch | 2844 // the loop header. If a call instruction is encountered the backwards branch |
2851 // is dominated by a call and the stack check in the backwards branch can be | 2845 // is dominated by a call and the stack check in the backwards branch can be |
2852 // removed. | 2846 // removed. |
2853 for (int i = 0; i < graph_->blocks()->length(); i++) { | 2847 for (int i = 0; i < graph_->blocks()->length(); i++) { |
2854 HBasicBlock* block = graph_->blocks()->at(i); | 2848 HBasicBlock* block = graph_->blocks()->at(i); |
2855 if (block->IsLoopHeader()) { | 2849 if (block->IsLoopHeader()) { |
2856 HBasicBlock* back_edge = block->loop_information()->GetLastBackEdge(); | 2850 HBasicBlock* back_edge = block->loop_information()->GetLastBackEdge(); |
2857 HBasicBlock* dominator = back_edge; | 2851 HBasicBlock* dominator = back_edge; |
2858 while (true) { | 2852 while (true) { |
2859 HInstruction* instr = dominator->first(); | 2853 for (HInstructionIterator it(dominator); !it.Done(); it.Advance()) { |
2860 while (instr != NULL) { | 2854 if (it.Current()->IsCall()) { |
2861 if (instr->IsCall()) { | |
2862 block->loop_information()->stack_check()->Eliminate(); | 2855 block->loop_information()->stack_check()->Eliminate(); |
2863 break; | 2856 break; |
2864 } | 2857 } |
2865 instr = instr->next(); | |
2866 } | 2858 } |
2867 | 2859 |
2868 // Done when the loop header is processed. | 2860 // Done when the loop header is processed. |
2869 if (dominator == block) break; | 2861 if (dominator == block) break; |
2870 | 2862 |
2871 // Move up the dominator tree. | 2863 // Move up the dominator tree. |
2872 dominator = dominator->dominator(); | 2864 dominator = dominator->dominator(); |
2873 } | 2865 } |
2874 } | 2866 } |
2875 } | 2867 } |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2972 } | 2964 } |
2973 | 2965 |
2974 // Initialize work list | 2966 // Initialize work list |
2975 for (int i = 0; i < graph_->blocks()->length(); ++i) { | 2967 for (int i = 0; i < graph_->blocks()->length(); ++i) { |
2976 HBasicBlock* block = graph_->blocks()->at(i); | 2968 HBasicBlock* block = graph_->blocks()->at(i); |
2977 const ZoneList<HPhi*>* phis = block->phis(); | 2969 const ZoneList<HPhi*>* phis = block->phis(); |
2978 for (int j = 0; j < phis->length(); ++j) { | 2970 for (int j = 0; j < phis->length(); ++j) { |
2979 AddToWorklist(phis->at(j)); | 2971 AddToWorklist(phis->at(j)); |
2980 } | 2972 } |
2981 | 2973 |
2982 HInstruction* current = block->first(); | 2974 for (HInstructionIterator it(block); !it.Done(); it.Advance()) { |
2983 while (current != NULL) { | 2975 AddToWorklist(it.Current()); |
2984 AddToWorklist(current); | |
2985 current = current->next(); | |
2986 } | 2976 } |
2987 } | 2977 } |
2988 | 2978 |
2989 // Do a fixed point iteration, trying to improve representations | 2979 // Do a fixed point iteration, trying to improve representations |
2990 while (!worklist_.is_empty()) { | 2980 while (!worklist_.is_empty()) { |
2991 HValue* current = worklist_.RemoveLast(); | 2981 HValue* current = worklist_.RemoveLast(); |
2992 in_worklist_.Remove(current->id()); | 2982 in_worklist_.Remove(current->id()); |
2993 current->InferRepresentation(this); | 2983 current->InferRepresentation(this); |
2994 } | 2984 } |
2995 | 2985 |
2996 // Lastly: any instruction that we don't have representation information | 2986 // Lastly: any instruction that we don't have representation information |
2997 // for defaults to Tagged. | 2987 // for defaults to Tagged. |
2998 for (int i = 0; i < graph_->blocks()->length(); ++i) { | 2988 for (int i = 0; i < graph_->blocks()->length(); ++i) { |
2999 HBasicBlock* block = graph_->blocks()->at(i); | 2989 HBasicBlock* block = graph_->blocks()->at(i); |
3000 const ZoneList<HPhi*>* phis = block->phis(); | 2990 const ZoneList<HPhi*>* phis = block->phis(); |
3001 for (int j = 0; j < phis->length(); ++j) { | 2991 for (int j = 0; j < phis->length(); ++j) { |
3002 HPhi* phi = phis->at(j); | 2992 HPhi* phi = phis->at(j); |
3003 if (phi->representation().IsNone()) { | 2993 if (phi->representation().IsNone()) { |
3004 phi->ChangeRepresentation(Representation::Tagged()); | 2994 phi->ChangeRepresentation(Representation::Tagged()); |
3005 } | 2995 } |
3006 } | 2996 } |
3007 for (HInstruction* current = block->first(); | 2997 for (HInstructionIterator it(block); !it.Done(); it.Advance()) { |
3008 current != NULL; current = current->next()) { | 2998 HInstruction* current = it.Current(); |
3009 if (current->representation().IsNone() && | 2999 if (current->representation().IsNone() && |
3010 current->CheckFlag(HInstruction::kFlexibleRepresentation)) { | 3000 current->CheckFlag(HInstruction::kFlexibleRepresentation)) { |
3011 if (current->CheckFlag(HInstruction::kCannotBeTagged)) { | 3001 if (current->CheckFlag(HInstruction::kCannotBeTagged)) { |
3012 current->ChangeRepresentation(Representation::Double()); | 3002 current->ChangeRepresentation(Representation::Double()); |
3013 } else { | 3003 } else { |
3014 current->ChangeRepresentation(Representation::Tagged()); | 3004 current->ChangeRepresentation(Representation::Tagged()); |
3015 } | 3005 } |
3016 } | 3006 } |
3017 } | 3007 } |
3018 } | 3008 } |
3019 } | 3009 } |
3020 | 3010 |
3021 | 3011 |
3022 void HGraph::MergeRemovableSimulates() { | 3012 void HGraph::MergeRemovableSimulates() { |
3023 HPhase phase("H_Merge removable simulates", this); | 3013 HPhase phase("H_Merge removable simulates", this); |
3024 ZoneList<HSimulate*> mergelist(2, zone()); | 3014 ZoneList<HSimulate*> mergelist(2, zone()); |
3025 for (int i = 0; i < blocks()->length(); ++i) { | 3015 for (int i = 0; i < blocks()->length(); ++i) { |
3026 HBasicBlock* block = blocks()->at(i); | 3016 HBasicBlock* block = blocks()->at(i); |
3027 // Make sure the merge list is empty at the start of a block. | 3017 // Make sure the merge list is empty at the start of a block. |
3028 ASSERT(mergelist.is_empty()); | 3018 ASSERT(mergelist.is_empty()); |
3029 // Nasty heuristic: Never remove the first simulate in a block. This | 3019 // Nasty heuristic: Never remove the first simulate in a block. This |
3030 // just so happens to have a beneficial effect on register allocation. | 3020 // just so happens to have a beneficial effect on register allocation. |
3031 bool first = true; | 3021 bool first = true; |
3032 for (HInstruction* current = block->first(); | 3022 for (HInstructionIterator it(block); !it.Done(); it.Advance()) { |
3033 current != NULL; current = current->next()) { | 3023 HInstruction* current = it.Current(); |
3034 if (current->IsLeaveInlined()) { | 3024 if (current->IsLeaveInlined()) { |
3035 // Never fold simulates from inlined environments into simulates | 3025 // Never fold simulates from inlined environments into simulates |
3036 // in the outer environment. | 3026 // in the outer environment. |
3037 // (Before each HEnterInlined, there is a non-foldable HSimulate | 3027 // (Before each HEnterInlined, there is a non-foldable HSimulate |
3038 // anyway, so we get the barrier in the other direction for free.) | 3028 // anyway, so we get the barrier in the other direction for free.) |
3039 // Simply remove all accumulated simulates without merging. This | 3029 // Simply remove all accumulated simulates without merging. This |
3040 // is safe because simulates after instructions with side effects | 3030 // is safe because simulates after instructions with side effects |
3041 // are never added to the merge list. | 3031 // are never added to the merge list. |
3042 while (!mergelist.is_empty()) { | 3032 while (!mergelist.is_empty()) { |
3043 mergelist.RemoveLast()->DeleteAndReplaceWith(NULL); | 3033 mergelist.RemoveLast()->DeleteAndReplaceWith(NULL); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3090 | 3080 |
3091 void HGraph::InitializeInferredTypes(int from_inclusive, int to_inclusive) { | 3081 void HGraph::InitializeInferredTypes(int from_inclusive, int to_inclusive) { |
3092 for (int i = from_inclusive; i <= to_inclusive; ++i) { | 3082 for (int i = from_inclusive; i <= to_inclusive; ++i) { |
3093 HBasicBlock* block = blocks_[i]; | 3083 HBasicBlock* block = blocks_[i]; |
3094 | 3084 |
3095 const ZoneList<HPhi*>* phis = block->phis(); | 3085 const ZoneList<HPhi*>* phis = block->phis(); |
3096 for (int j = 0; j < phis->length(); j++) { | 3086 for (int j = 0; j < phis->length(); j++) { |
3097 phis->at(j)->UpdateInferredType(); | 3087 phis->at(j)->UpdateInferredType(); |
3098 } | 3088 } |
3099 | 3089 |
3100 HInstruction* current = block->first(); | 3090 for (HInstructionIterator it(block); !it.Done(); it.Advance()) { |
3101 while (current != NULL) { | 3091 it.Current()->UpdateInferredType(); |
3102 current->UpdateInferredType(); | |
3103 current = current->next(); | |
3104 } | 3092 } |
3105 | 3093 |
3106 if (block->IsLoopHeader()) { | 3094 if (block->IsLoopHeader()) { |
3107 HBasicBlock* last_back_edge = | 3095 HBasicBlock* last_back_edge = |
3108 block->loop_information()->GetLastBackEdge(); | 3096 block->loop_information()->GetLastBackEdge(); |
3109 InitializeInferredTypes(i + 1, last_back_edge->block_id()); | 3097 InitializeInferredTypes(i + 1, last_back_edge->block_id()); |
3110 // Skip all blocks already processed by the recursive call. | 3098 // Skip all blocks already processed by the recursive call. |
3111 i = last_back_edge->block_id(); | 3099 i = last_back_edge->block_id(); |
3112 // Update phis of the loop header now after the whole loop body is | 3100 // Update phis of the loop header now after the whole loop body is |
3113 // guaranteed to be processed. | 3101 // guaranteed to be processed. |
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3547 // this information transitively potentially clearing kUint32 flag | 3535 // this information transitively potentially clearing kUint32 flag |
3548 // from some non-phi operations that are used as operands to unsafe phis. | 3536 // from some non-phi operations that are used as operands to unsafe phis. |
3549 analysis.UnmarkUnsafePhis(); | 3537 analysis.UnmarkUnsafePhis(); |
3550 } | 3538 } |
3551 | 3539 |
3552 | 3540 |
3553 void HGraph::ComputeMinusZeroChecks() { | 3541 void HGraph::ComputeMinusZeroChecks() { |
3554 HPhase phase("H_Compute minus zero checks", this); | 3542 HPhase phase("H_Compute minus zero checks", this); |
3555 BitVector visited(GetMaximumValueID(), zone()); | 3543 BitVector visited(GetMaximumValueID(), zone()); |
3556 for (int i = 0; i < blocks_.length(); ++i) { | 3544 for (int i = 0; i < blocks_.length(); ++i) { |
3557 for (HInstruction* current = blocks_[i]->first(); | 3545 for (HInstructionIterator it(blocks_[i]); !it.Done(); it.Advance()) { |
3558 current != NULL; | 3546 HInstruction* current = it.Current(); |
3559 current = current->next()) { | |
3560 if (current->IsChange()) { | 3547 if (current->IsChange()) { |
3561 HChange* change = HChange::cast(current); | 3548 HChange* change = HChange::cast(current); |
3562 // Propagate flags for negative zero checks upwards from conversions | 3549 // Propagate flags for negative zero checks upwards from conversions |
3563 // int32-to-tagged and int32-to-double. | 3550 // int32-to-tagged and int32-to-double. |
3564 Representation from = change->value()->representation(); | 3551 Representation from = change->value()->representation(); |
3565 ASSERT(from.Equals(change->from())); | 3552 ASSERT(from.Equals(change->from())); |
3566 if (from.IsInteger32()) { | 3553 if (from.IsInteger32()) { |
3567 ASSERT(change->to().IsTagged() || | 3554 ASSERT(change->to().IsTagged() || |
3568 change->to().IsDouble() || | 3555 change->to().IsDouble() || |
3569 change->to().IsSmi()); | 3556 change->to().IsSmi()); |
(...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4119 | 4106 |
4120 void HGraph::SetupInformativeDefinitionsInBlock(HBasicBlock* block) { | 4107 void HGraph::SetupInformativeDefinitionsInBlock(HBasicBlock* block) { |
4121 for (int phi_index = 0; phi_index < block->phis()->length(); phi_index++) { | 4108 for (int phi_index = 0; phi_index < block->phis()->length(); phi_index++) { |
4122 HPhi* phi = block->phis()->at(phi_index); | 4109 HPhi* phi = block->phis()->at(phi_index); |
4123 phi->AddInformativeDefinitions(); | 4110 phi->AddInformativeDefinitions(); |
4124 phi->SetFlag(HValue::kIDefsProcessingDone); | 4111 phi->SetFlag(HValue::kIDefsProcessingDone); |
4125 // We do not support phis that "redefine just one operand". | 4112 // We do not support phis that "redefine just one operand". |
4126 ASSERT(!phi->IsInformativeDefinition()); | 4113 ASSERT(!phi->IsInformativeDefinition()); |
4127 } | 4114 } |
4128 | 4115 |
4129 for (HInstruction* i = block->first(); i != NULL; i = i->next()) { | 4116 for (HInstructionIterator it(block); !it.Done(); it.Advance()) { |
| 4117 HInstruction* i = it.Current(); |
4130 i->AddInformativeDefinitions(); | 4118 i->AddInformativeDefinitions(); |
4131 i->SetFlag(HValue::kIDefsProcessingDone); | 4119 i->SetFlag(HValue::kIDefsProcessingDone); |
4132 i->UpdateRedefinedUsesWhileSettingUpInformativeDefinitions(); | 4120 i->UpdateRedefinedUsesWhileSettingUpInformativeDefinitions(); |
4133 } | 4121 } |
4134 } | 4122 } |
4135 | 4123 |
4136 | 4124 |
4137 // This method is recursive, so if its stack frame is large it could | 4125 // This method is recursive, so if its stack frame is large it could |
4138 // cause a stack overflow. | 4126 // cause a stack overflow. |
4139 // To keep the individual stack frames small we do the actual work inside | 4127 // To keep the individual stack frames small we do the actual work inside |
4140 // SetupInformativeDefinitionsInBlock(); | 4128 // SetupInformativeDefinitionsInBlock(); |
4141 void HGraph::SetupInformativeDefinitionsRecursively(HBasicBlock* block) { | 4129 void HGraph::SetupInformativeDefinitionsRecursively(HBasicBlock* block) { |
4142 SetupInformativeDefinitionsInBlock(block); | 4130 SetupInformativeDefinitionsInBlock(block); |
4143 for (int i = 0; i < block->dominated_blocks()->length(); ++i) { | 4131 for (int i = 0; i < block->dominated_blocks()->length(); ++i) { |
4144 SetupInformativeDefinitionsRecursively(block->dominated_blocks()->at(i)); | 4132 SetupInformativeDefinitionsRecursively(block->dominated_blocks()->at(i)); |
4145 } | 4133 } |
4146 | 4134 |
4147 for (HInstruction* i = block->first(); i != NULL; i = i->next()) { | 4135 for (HInstructionIterator it(block); !it.Done(); it.Advance()) { |
| 4136 HInstruction* i = it.Current(); |
4148 if (i->IsBoundsCheck()) { | 4137 if (i->IsBoundsCheck()) { |
4149 HBoundsCheck* check = HBoundsCheck::cast(i); | 4138 HBoundsCheck* check = HBoundsCheck::cast(i); |
4150 check->ApplyIndexChange(); | 4139 check->ApplyIndexChange(); |
4151 } | 4140 } |
4152 } | 4141 } |
4153 } | 4142 } |
4154 | 4143 |
4155 | 4144 |
4156 void HGraph::SetupInformativeDefinitions() { | 4145 void HGraph::SetupInformativeDefinitions() { |
4157 HPhase phase("H_Setup informative definitions", this); | 4146 HPhase phase("H_Setup informative definitions", this); |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4440 | 4429 |
4441 // Eliminates checks in bb and recursively in the dominated blocks. | 4430 // Eliminates checks in bb and recursively in the dominated blocks. |
4442 // Also replace the results of check instructions with the original value, if | 4431 // Also replace the results of check instructions with the original value, if |
4443 // the result is used. This is safe now, since we don't do code motion after | 4432 // the result is used. This is safe now, since we don't do code motion after |
4444 // this point. It enables better register allocation since the value produced | 4433 // this point. It enables better register allocation since the value produced |
4445 // by check instructions is really a copy of the original value. | 4434 // by check instructions is really a copy of the original value. |
4446 void HGraph::EliminateRedundantBoundsChecks(HBasicBlock* bb, | 4435 void HGraph::EliminateRedundantBoundsChecks(HBasicBlock* bb, |
4447 BoundsCheckTable* table) { | 4436 BoundsCheckTable* table) { |
4448 BoundsCheckBbData* bb_data_list = NULL; | 4437 BoundsCheckBbData* bb_data_list = NULL; |
4449 | 4438 |
4450 for (HInstruction* i = bb->first(); i != NULL; i = i->next()) { | 4439 for (HInstructionIterator it(bb); !it.Done(); it.Advance()) { |
| 4440 HInstruction* i = it.Current(); |
4451 if (!i->IsBoundsCheck()) continue; | 4441 if (!i->IsBoundsCheck()) continue; |
4452 | 4442 |
4453 HBoundsCheck* check = HBoundsCheck::cast(i); | 4443 HBoundsCheck* check = HBoundsCheck::cast(i); |
4454 int32_t offset; | 4444 int32_t offset; |
4455 BoundsCheckKey* key = | 4445 BoundsCheckKey* key = |
4456 BoundsCheckKey::Create(zone(), check, &offset); | 4446 BoundsCheckKey::Create(zone(), check, &offset); |
4457 if (key == NULL) continue; | 4447 if (key == NULL) continue; |
4458 BoundsCheckBbData** data_p = table->LookupOrInsert(key, zone()); | 4448 BoundsCheckBbData** data_p = table->LookupOrInsert(key, zone()); |
4459 BoundsCheckBbData* data = *data_p; | 4449 BoundsCheckBbData* data = *data_p; |
4460 if (data == NULL) { | 4450 if (data == NULL) { |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4562 } | 4552 } |
4563 ASSERT(value >= 0); | 4553 ASSERT(value >= 0); |
4564 array_operation->SetIndexOffset(static_cast<uint32_t>(value)); | 4554 array_operation->SetIndexOffset(static_cast<uint32_t>(value)); |
4565 array_operation->SetDehoisted(true); | 4555 array_operation->SetDehoisted(true); |
4566 } | 4556 } |
4567 | 4557 |
4568 | 4558 |
4569 void HGraph::DehoistSimpleArrayIndexComputations() { | 4559 void HGraph::DehoistSimpleArrayIndexComputations() { |
4570 HPhase phase("H_Dehoist index computations", this); | 4560 HPhase phase("H_Dehoist index computations", this); |
4571 for (int i = 0; i < blocks()->length(); ++i) { | 4561 for (int i = 0; i < blocks()->length(); ++i) { |
4572 for (HInstruction* instr = blocks()->at(i)->first(); | 4562 for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) { |
4573 instr != NULL; | 4563 HInstruction* instr = it.Current(); |
4574 instr = instr->next()) { | |
4575 ArrayInstructionInterface* array_instruction = NULL; | 4564 ArrayInstructionInterface* array_instruction = NULL; |
4576 if (instr->IsLoadKeyed()) { | 4565 if (instr->IsLoadKeyed()) { |
4577 HLoadKeyed* op = HLoadKeyed::cast(instr); | 4566 HLoadKeyed* op = HLoadKeyed::cast(instr); |
4578 array_instruction = static_cast<ArrayInstructionInterface*>(op); | 4567 array_instruction = static_cast<ArrayInstructionInterface*>(op); |
4579 } else if (instr->IsStoreKeyed()) { | 4568 } else if (instr->IsStoreKeyed()) { |
4580 HStoreKeyed* op = HStoreKeyed::cast(instr); | 4569 HStoreKeyed* op = HStoreKeyed::cast(instr); |
4581 array_instruction = static_cast<ArrayInstructionInterface*>(op); | 4570 array_instruction = static_cast<ArrayInstructionInterface*>(op); |
4582 } else { | 4571 } else { |
4583 continue; | 4572 continue; |
4584 } | 4573 } |
4585 DehoistArrayIndex(array_instruction); | 4574 DehoistArrayIndex(array_instruction); |
4586 } | 4575 } |
4587 } | 4576 } |
4588 } | 4577 } |
4589 | 4578 |
4590 | 4579 |
4591 void HGraph::DeadCodeElimination(const char* phase_name) { | 4580 void HGraph::DeadCodeElimination(const char* phase_name) { |
4592 HPhase phase(phase_name, this); | 4581 HPhase phase(phase_name, this); |
4593 MarkLiveInstructions(); | 4582 MarkLiveInstructions(); |
4594 RemoveDeadInstructions(); | 4583 RemoveDeadInstructions(); |
4595 } | 4584 } |
4596 | 4585 |
4597 | 4586 |
4598 void HGraph::MarkLiveInstructions() { | 4587 void HGraph::MarkLiveInstructions() { |
4599 ZoneList<HValue*> worklist(blocks_.length(), zone()); | 4588 ZoneList<HValue*> worklist(blocks_.length(), zone()); |
4600 | 4589 |
4601 // Mark initial root instructions for dead code elimination. | 4590 // Mark initial root instructions for dead code elimination. |
4602 for (int i = 0; i < blocks()->length(); ++i) { | 4591 for (int i = 0; i < blocks()->length(); ++i) { |
4603 HBasicBlock* block = blocks()->at(i); | 4592 HBasicBlock* block = blocks()->at(i); |
4604 for (HInstruction* instr = block->first(); | 4593 for (HInstructionIterator it(block); !it.Done(); it.Advance()) { |
4605 instr != NULL; | 4594 HInstruction* instr = it.Current(); |
4606 instr = instr->next()) { | |
4607 if (instr->CannotBeEliminated()) MarkLive(NULL, instr, &worklist); | 4595 if (instr->CannotBeEliminated()) MarkLive(NULL, instr, &worklist); |
4608 } | 4596 } |
4609 for (int j = 0; j < block->phis()->length(); j++) { | 4597 for (int j = 0; j < block->phis()->length(); j++) { |
4610 HPhi* phi = block->phis()->at(j); | 4598 HPhi* phi = block->phis()->at(j); |
4611 if (phi->CannotBeEliminated()) MarkLive(NULL, phi, &worklist); | 4599 if (phi->CannotBeEliminated()) MarkLive(NULL, phi, &worklist); |
4612 } | 4600 } |
4613 } | 4601 } |
4614 | 4602 |
4615 // Transitively mark all inputs of live instructions live. | 4603 // Transitively mark all inputs of live instructions live. |
4616 while (!worklist.is_empty()) { | 4604 while (!worklist.is_empty()) { |
(...skipping 25 matching lines...) Expand all Loading... |
4642 } | 4630 } |
4643 } | 4631 } |
4644 | 4632 |
4645 | 4633 |
4646 void HGraph::RemoveDeadInstructions() { | 4634 void HGraph::RemoveDeadInstructions() { |
4647 ZoneList<HPhi*> dead_phis(blocks_.length(), zone()); | 4635 ZoneList<HPhi*> dead_phis(blocks_.length(), zone()); |
4648 | 4636 |
4649 // Remove any instruction not marked kIsLive. | 4637 // Remove any instruction not marked kIsLive. |
4650 for (int i = 0; i < blocks()->length(); ++i) { | 4638 for (int i = 0; i < blocks()->length(); ++i) { |
4651 HBasicBlock* block = blocks()->at(i); | 4639 HBasicBlock* block = blocks()->at(i); |
4652 for (HInstruction* instr = block->first(); | 4640 for (HInstructionIterator it(block); !it.Done(); it.Advance()) { |
4653 instr != NULL; | 4641 HInstruction* instr = it.Current(); |
4654 instr = instr->next()) { | |
4655 if (!instr->CheckFlag(HValue::kIsLive)) { | 4642 if (!instr->CheckFlag(HValue::kIsLive)) { |
4656 // Instruction has not been marked live; assume it is dead and remove. | 4643 // Instruction has not been marked live; assume it is dead and remove. |
4657 // TODO(titzer): we don't remove constants because some special ones | 4644 // TODO(titzer): we don't remove constants because some special ones |
4658 // might be used by later phases and are assumed to be in the graph | 4645 // might be used by later phases and are assumed to be in the graph |
4659 if (!instr->IsConstant()) instr->DeleteAndReplaceWith(NULL); | 4646 if (!instr->IsConstant()) instr->DeleteAndReplaceWith(NULL); |
4660 } else { | 4647 } else { |
4661 // Clear the liveness flag to leave the graph clean for the next DCE. | 4648 // Clear the liveness flag to leave the graph clean for the next DCE. |
4662 instr->ClearFlag(HValue::kIsLive); | 4649 instr->ClearFlag(HValue::kIsLive); |
4663 } | 4650 } |
4664 } | 4651 } |
(...skipping 24 matching lines...) Expand all Loading... |
4689 for (int block_index = 0; block_index < blocks()->length(); block_index++) { | 4676 for (int block_index = 0; block_index < blocks()->length(); block_index++) { |
4690 HBasicBlock* block = blocks()->at(block_index); | 4677 HBasicBlock* block = blocks()->at(block_index); |
4691 | 4678 |
4692 #ifdef DEBUG | 4679 #ifdef DEBUG |
4693 for (int i = 0; i < block->phis()->length(); i++) { | 4680 for (int i = 0; i < block->phis()->length(); i++) { |
4694 HPhi* phi = block->phis()->at(i); | 4681 HPhi* phi = block->phis()->at(i); |
4695 ASSERT(phi->ActualValue() == phi); | 4682 ASSERT(phi->ActualValue() == phi); |
4696 } | 4683 } |
4697 #endif | 4684 #endif |
4698 | 4685 |
4699 for (HInstruction* instruction = block->first(); | 4686 for (HInstructionIterator it(block); !it.Done(); it.Advance()) { |
4700 instruction != NULL; | 4687 HInstruction* instruction = it.Current(); |
4701 instruction = instruction->next()) { | |
4702 if (instruction->ActualValue() != instruction) { | 4688 if (instruction->ActualValue() != instruction) { |
4703 ASSERT(instruction->IsInformativeDefinition()); | 4689 ASSERT(instruction->IsInformativeDefinition()); |
4704 if (instruction->IsPurelyInformativeDefinition()) { | 4690 if (instruction->IsPurelyInformativeDefinition()) { |
4705 instruction->DeleteAndReplaceWith(instruction->RedefinedOperand()); | 4691 instruction->DeleteAndReplaceWith(instruction->RedefinedOperand()); |
4706 } else { | 4692 } else { |
4707 instruction->ReplaceAllUsesWith(instruction->ActualValue()); | 4693 instruction->ReplaceAllUsesWith(instruction->ActualValue()); |
4708 } | 4694 } |
4709 } | 4695 } |
4710 } | 4696 } |
4711 } | 4697 } |
(...skipping 6697 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11409 trace_.Add("%d ", phi->merged_index()); | 11395 trace_.Add("%d ", phi->merged_index()); |
11410 phi->PrintNameTo(&trace_); | 11396 phi->PrintNameTo(&trace_); |
11411 trace_.Add(" "); | 11397 trace_.Add(" "); |
11412 phi->PrintTo(&trace_); | 11398 phi->PrintTo(&trace_); |
11413 trace_.Add("\n"); | 11399 trace_.Add("\n"); |
11414 } | 11400 } |
11415 } | 11401 } |
11416 | 11402 |
11417 { | 11403 { |
11418 Tag HIR_tag(this, "HIR"); | 11404 Tag HIR_tag(this, "HIR"); |
11419 HInstruction* instruction = current->first(); | 11405 for (HInstructionIterator it(current); !it.Done(); it.Advance()) { |
11420 while (instruction != NULL) { | 11406 HInstruction* instruction = it.Current(); |
11421 int bci = 0; | 11407 int bci = 0; |
11422 int uses = instruction->UseCount(); | 11408 int uses = instruction->UseCount(); |
11423 PrintIndent(); | 11409 PrintIndent(); |
11424 trace_.Add("%d %d ", bci, uses); | 11410 trace_.Add("%d %d ", bci, uses); |
11425 instruction->PrintNameTo(&trace_); | 11411 instruction->PrintNameTo(&trace_); |
11426 trace_.Add(" "); | 11412 trace_.Add(" "); |
11427 instruction->PrintTo(&trace_); | 11413 instruction->PrintTo(&trace_); |
11428 trace_.Add(" <|@\n"); | 11414 trace_.Add(" <|@\n"); |
11429 instruction = instruction->next(); | |
11430 } | 11415 } |
11431 } | 11416 } |
11432 | 11417 |
11433 | 11418 |
11434 if (chunk != NULL) { | 11419 if (chunk != NULL) { |
11435 Tag LIR_tag(this, "LIR"); | 11420 Tag LIR_tag(this, "LIR"); |
11436 int first_index = current->first_instruction_index(); | 11421 int first_index = current->first_instruction_index(); |
11437 int last_index = current->last_instruction_index(); | 11422 int last_index = current->last_instruction_index(); |
11438 if (first_index != -1 && last_index != -1) { | 11423 if (first_index != -1 && last_index != -1) { |
11439 const ZoneList<LInstruction*>* instructions = chunk->instructions(); | 11424 const ZoneList<LInstruction*>* instructions = chunk->instructions(); |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11615 if (ShouldProduceTraceOutput()) { | 11600 if (ShouldProduceTraceOutput()) { |
11616 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 11601 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
11617 } | 11602 } |
11618 | 11603 |
11619 #ifdef DEBUG | 11604 #ifdef DEBUG |
11620 graph_->Verify(false); // No full verify. | 11605 graph_->Verify(false); // No full verify. |
11621 #endif | 11606 #endif |
11622 } | 11607 } |
11623 | 11608 |
11624 } } // namespace v8::internal | 11609 } } // namespace v8::internal |
OLD | NEW |