| 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 |