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