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 |