| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 25 matching lines...) Expand all Loading... |
| 36 #include "hydrogen-bce.h" | 36 #include "hydrogen-bce.h" |
| 37 #include "hydrogen-dce.h" | 37 #include "hydrogen-dce.h" |
| 38 #include "hydrogen-environment-liveness.h" | 38 #include "hydrogen-environment-liveness.h" |
| 39 #include "hydrogen-escape-analysis.h" | 39 #include "hydrogen-escape-analysis.h" |
| 40 #include "hydrogen-infer-representation.h" | 40 #include "hydrogen-infer-representation.h" |
| 41 #include "hydrogen-infer-types.h" | 41 #include "hydrogen-infer-types.h" |
| 42 #include "hydrogen-gvn.h" | 42 #include "hydrogen-gvn.h" |
| 43 #include "hydrogen-osr.h" | 43 #include "hydrogen-osr.h" |
| 44 #include "hydrogen-range-analysis.h" | 44 #include "hydrogen-range-analysis.h" |
| 45 #include "hydrogen-redundant-phi.h" | 45 #include "hydrogen-redundant-phi.h" |
| 46 #include "hydrogen-representation-changes.h" |
| 46 #include "hydrogen-sce.h" | 47 #include "hydrogen-sce.h" |
| 47 #include "hydrogen-uint32-analysis.h" | 48 #include "hydrogen-uint32-analysis.h" |
| 48 #include "lithium-allocator.h" | 49 #include "lithium-allocator.h" |
| 49 #include "parser.h" | 50 #include "parser.h" |
| 50 #include "scopeinfo.h" | 51 #include "scopeinfo.h" |
| 51 #include "scopes.h" | 52 #include "scopes.h" |
| 52 #include "stub-cache.h" | 53 #include "stub-cache.h" |
| 53 #include "typing.h" | 54 #include "typing.h" |
| 54 | 55 |
| 55 #if V8_TARGET_ARCH_IA32 | 56 #if V8_TARGET_ARCH_IA32 |
| (...skipping 2605 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2661 visited->Add(minmax->id()); | 2662 visited->Add(minmax->id()); |
| 2662 PropagateMinusZeroChecks(minmax->left(), visited); | 2663 PropagateMinusZeroChecks(minmax->left(), visited); |
| 2663 PropagateMinusZeroChecks(minmax->right(), visited); | 2664 PropagateMinusZeroChecks(minmax->right(), visited); |
| 2664 } | 2665 } |
| 2665 | 2666 |
| 2666 current = current->EnsureAndPropagateNotMinusZero(visited); | 2667 current = current->EnsureAndPropagateNotMinusZero(visited); |
| 2667 } | 2668 } |
| 2668 } | 2669 } |
| 2669 | 2670 |
| 2670 | 2671 |
| 2671 void HGraph::InsertRepresentationChangeForUse(HValue* value, | |
| 2672 HValue* use_value, | |
| 2673 int use_index, | |
| 2674 Representation to) { | |
| 2675 // Insert the representation change right before its use. For phi-uses we | |
| 2676 // insert at the end of the corresponding predecessor. | |
| 2677 HInstruction* next = NULL; | |
| 2678 if (use_value->IsPhi()) { | |
| 2679 next = use_value->block()->predecessors()->at(use_index)->end(); | |
| 2680 } else { | |
| 2681 next = HInstruction::cast(use_value); | |
| 2682 } | |
| 2683 // For constants we try to make the representation change at compile | |
| 2684 // time. When a representation change is not possible without loss of | |
| 2685 // information we treat constants like normal instructions and insert the | |
| 2686 // change instructions for them. | |
| 2687 HInstruction* new_value = NULL; | |
| 2688 bool is_truncating = use_value->CheckFlag(HValue::kTruncatingToInt32); | |
| 2689 bool allow_undefined_as_nan = | |
| 2690 use_value->CheckFlag(HValue::kAllowUndefinedAsNaN); | |
| 2691 if (value->IsConstant()) { | |
| 2692 HConstant* constant = HConstant::cast(value); | |
| 2693 // Try to create a new copy of the constant with the new representation. | |
| 2694 new_value = (is_truncating && to.IsInteger32()) | |
| 2695 ? constant->CopyToTruncatedInt32(zone()) | |
| 2696 : constant->CopyToRepresentation(to, zone()); | |
| 2697 } | |
| 2698 | |
| 2699 if (new_value == NULL) { | |
| 2700 new_value = new(zone()) HChange(value, to, | |
| 2701 is_truncating, allow_undefined_as_nan); | |
| 2702 } | |
| 2703 | |
| 2704 new_value->InsertBefore(next); | |
| 2705 use_value->SetOperandAt(use_index, new_value); | |
| 2706 } | |
| 2707 | |
| 2708 | |
| 2709 void HGraph::InsertRepresentationChangesForValue(HValue* value) { | |
| 2710 Representation r = value->representation(); | |
| 2711 if (r.IsNone()) return; | |
| 2712 if (value->HasNoUses()) return; | |
| 2713 | |
| 2714 for (HUseIterator it(value->uses()); !it.Done(); it.Advance()) { | |
| 2715 HValue* use_value = it.value(); | |
| 2716 int use_index = it.index(); | |
| 2717 Representation req = use_value->RequiredInputRepresentation(use_index); | |
| 2718 if (req.IsNone() || req.Equals(r)) continue; | |
| 2719 InsertRepresentationChangeForUse(value, use_value, use_index, req); | |
| 2720 } | |
| 2721 if (value->HasNoUses()) { | |
| 2722 ASSERT(value->IsConstant()); | |
| 2723 value->DeleteAndReplaceWith(NULL); | |
| 2724 } | |
| 2725 | |
| 2726 // The only purpose of a HForceRepresentation is to represent the value | |
| 2727 // after the (possible) HChange instruction. We make it disappear. | |
| 2728 if (value->IsForceRepresentation()) { | |
| 2729 value->DeleteAndReplaceWith(HForceRepresentation::cast(value)->value()); | |
| 2730 } | |
| 2731 } | |
| 2732 | |
| 2733 | |
| 2734 void HGraph::InsertRepresentationChanges() { | |
| 2735 HPhase phase("H_Representation changes", this); | |
| 2736 | |
| 2737 // Compute truncation flag for phis: Initially assume that all | |
| 2738 // int32-phis allow truncation and iteratively remove the ones that | |
| 2739 // are used in an operation that does not allow a truncating | |
| 2740 // conversion. | |
| 2741 ZoneList<HPhi*> worklist(8, zone()); | |
| 2742 | |
| 2743 for (int i = 0; i < phi_list()->length(); i++) { | |
| 2744 HPhi* phi = phi_list()->at(i); | |
| 2745 if (phi->representation().IsInteger32()) { | |
| 2746 phi->SetFlag(HValue::kTruncatingToInt32); | |
| 2747 } | |
| 2748 } | |
| 2749 | |
| 2750 for (int i = 0; i < phi_list()->length(); i++) { | |
| 2751 HPhi* phi = phi_list()->at(i); | |
| 2752 for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) { | |
| 2753 // If a Phi is used as a non-truncating int32 or as a double, | |
| 2754 // clear its "truncating" flag. | |
| 2755 HValue* use = it.value(); | |
| 2756 Representation input_representation = | |
| 2757 use->RequiredInputRepresentation(it.index()); | |
| 2758 if (!input_representation.IsInteger32() || | |
| 2759 !use->CheckFlag(HValue::kTruncatingToInt32)) { | |
| 2760 if (FLAG_trace_representation) { | |
| 2761 PrintF("#%d Phi is not truncating because of #%d %s\n", | |
| 2762 phi->id(), it.value()->id(), it.value()->Mnemonic()); | |
| 2763 } | |
| 2764 phi->ClearFlag(HValue::kTruncatingToInt32); | |
| 2765 worklist.Add(phi, zone()); | |
| 2766 break; | |
| 2767 } | |
| 2768 } | |
| 2769 } | |
| 2770 | |
| 2771 while (!worklist.is_empty()) { | |
| 2772 HPhi* current = worklist.RemoveLast(); | |
| 2773 for (int i = 0; i < current->OperandCount(); ++i) { | |
| 2774 HValue* input = current->OperandAt(i); | |
| 2775 if (input->IsPhi() && | |
| 2776 input->representation().IsInteger32() && | |
| 2777 input->CheckFlag(HValue::kTruncatingToInt32)) { | |
| 2778 if (FLAG_trace_representation) { | |
| 2779 PrintF("#%d Phi is not truncating because of #%d %s\n", | |
| 2780 input->id(), current->id(), current->Mnemonic()); | |
| 2781 } | |
| 2782 input->ClearFlag(HValue::kTruncatingToInt32); | |
| 2783 worklist.Add(HPhi::cast(input), zone()); | |
| 2784 } | |
| 2785 } | |
| 2786 } | |
| 2787 | |
| 2788 for (int i = 0; i < blocks_.length(); ++i) { | |
| 2789 // Process phi instructions first. | |
| 2790 const ZoneList<HPhi*>* phis = blocks_[i]->phis(); | |
| 2791 for (int j = 0; j < phis->length(); j++) { | |
| 2792 InsertRepresentationChangesForValue(phis->at(j)); | |
| 2793 } | |
| 2794 | |
| 2795 // Process normal instructions. | |
| 2796 HInstruction* current = blocks_[i]->first(); | |
| 2797 while (current != NULL) { | |
| 2798 HInstruction* next = current->next(); | |
| 2799 InsertRepresentationChangesForValue(current); | |
| 2800 current = next; | |
| 2801 } | |
| 2802 } | |
| 2803 } | |
| 2804 | |
| 2805 | |
| 2806 void HGraph::RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi* phi) { | 2672 void HGraph::RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi* phi) { |
| 2807 if (!phi->CheckFlag(HValue::kAllowUndefinedAsNaN)) return; | 2673 if (!phi->CheckFlag(HValue::kAllowUndefinedAsNaN)) return; |
| 2808 phi->ClearFlag(HValue::kAllowUndefinedAsNaN); | 2674 phi->ClearFlag(HValue::kAllowUndefinedAsNaN); |
| 2809 for (int i = 0; i < phi->OperandCount(); ++i) { | 2675 for (int i = 0; i < phi->OperandCount(); ++i) { |
| 2810 HValue* input = phi->OperandAt(i); | 2676 HValue* input = phi->OperandAt(i); |
| 2811 if (input->IsPhi()) { | 2677 if (input->IsPhi()) { |
| 2812 RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi::cast(input)); | 2678 RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi::cast(input)); |
| 2813 } | 2679 } |
| 2814 } | 2680 } |
| 2815 } | 2681 } |
| (...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3327 if (has_osr()) osr()->FinishOsrValues(); | 3193 if (has_osr()) osr()->FinishOsrValues(); |
| 3328 | 3194 |
| 3329 Run<HInferRepresentationPhase>(); | 3195 Run<HInferRepresentationPhase>(); |
| 3330 | 3196 |
| 3331 // Remove HSimulate instructions that have turned out not to be needed | 3197 // Remove HSimulate instructions that have turned out not to be needed |
| 3332 // after all by folding them into the following HSimulate. | 3198 // after all by folding them into the following HSimulate. |
| 3333 // This must happen after inferring representations. | 3199 // This must happen after inferring representations. |
| 3334 MergeRemovableSimulates(); | 3200 MergeRemovableSimulates(); |
| 3335 | 3201 |
| 3336 MarkDeoptimizeOnUndefined(); | 3202 MarkDeoptimizeOnUndefined(); |
| 3337 InsertRepresentationChanges(); | 3203 Run<HRepresentationChangesPhase>(); |
| 3338 | 3204 |
| 3339 Run<HInferTypesPhase>(); | 3205 Run<HInferTypesPhase>(); |
| 3340 | 3206 |
| 3341 // Must be performed before canonicalization to ensure that Canonicalize | 3207 // Must be performed before canonicalization to ensure that Canonicalize |
| 3342 // will not remove semantically meaningful ToInt32 operations e.g. BIT_OR with | 3208 // will not remove semantically meaningful ToInt32 operations e.g. BIT_OR with |
| 3343 // zero. | 3209 // zero. |
| 3344 if (FLAG_opt_safe_uint32_operations) Run<HUint32AnalysisPhase>(); | 3210 if (FLAG_opt_safe_uint32_operations) Run<HUint32AnalysisPhase>(); |
| 3345 | 3211 |
| 3346 if (FLAG_use_canonicalizing) Canonicalize(); | 3212 if (FLAG_use_canonicalizing) Canonicalize(); |
| 3347 | 3213 |
| (...skipping 6890 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10238 if (ShouldProduceTraceOutput()) { | 10104 if (ShouldProduceTraceOutput()) { |
| 10239 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 10105 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 10240 } | 10106 } |
| 10241 | 10107 |
| 10242 #ifdef DEBUG | 10108 #ifdef DEBUG |
| 10243 graph_->Verify(false); // No full verify. | 10109 graph_->Verify(false); // No full verify. |
| 10244 #endif | 10110 #endif |
| 10245 } | 10111 } |
| 10246 | 10112 |
| 10247 } } // namespace v8::internal | 10113 } } // namespace v8::internal |
| OLD | NEW |