OLD | NEW |
| (Empty) |
1 // Copyright 2013 the V8 project authors. All rights reserved. | |
2 // Redistribution and use in source and binary forms, with or without | |
3 // modification, are permitted provided that the following conditions are | |
4 // met: | |
5 // | |
6 // * Redistributions of source code must retain the above copyright | |
7 // notice, this list of conditions and the following disclaimer. | |
8 // * Redistributions in binary form must reproduce the above | |
9 // copyright notice, this list of conditions and the following | |
10 // disclaimer in the documentation and/or other materials provided | |
11 // with the distribution. | |
12 // * Neither the name of Google Inc. nor the names of its | |
13 // contributors may be used to endorse or promote products derived | |
14 // from this software without specific prior written permission. | |
15 // | |
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
27 | |
28 #include "hydrogen-minus-zero.h" | |
29 | |
30 namespace v8 { | |
31 namespace internal { | |
32 | |
33 void HComputeMinusZeroChecksPhase::Run() { | |
34 const ZoneList<HBasicBlock*>* blocks(graph()->blocks()); | |
35 for (int i = 0; i < blocks->length(); ++i) { | |
36 for (HInstructionIterator it(blocks->at(i)); !it.Done(); it.Advance()) { | |
37 HInstruction* current = it.Current(); | |
38 if (current->IsChange()) { | |
39 HChange* change = HChange::cast(current); | |
40 // Propagate flags for negative zero checks upwards from conversions | |
41 // int32-to-tagged and int32-to-double. | |
42 Representation from = change->value()->representation(); | |
43 ASSERT(from.Equals(change->from())); | |
44 if (from.IsSmiOrInteger32()) { | |
45 ASSERT(change->to().IsTagged() || | |
46 change->to().IsDouble() || | |
47 change->to().IsSmiOrInteger32()); | |
48 PropagateMinusZeroChecks(change->value()); | |
49 } | |
50 } else if (current->IsCompareMinusZeroAndBranch()) { | |
51 HCompareMinusZeroAndBranch* check = | |
52 HCompareMinusZeroAndBranch::cast(current); | |
53 if (check->value()->representation().IsSmiOrInteger32()) { | |
54 PropagateMinusZeroChecks(check->value()); | |
55 } | |
56 } | |
57 } | |
58 } | |
59 } | |
60 | |
61 | |
62 void HComputeMinusZeroChecksPhase::PropagateMinusZeroChecks(HValue* value) { | |
63 ASSERT(worklist_.is_empty()); | |
64 ASSERT(in_worklist_.IsEmpty()); | |
65 | |
66 AddToWorklist(value); | |
67 while (!worklist_.is_empty()) { | |
68 value = worklist_.RemoveLast(); | |
69 | |
70 if (value->IsPhi()) { | |
71 // For phis, we must propagate the check to all of its inputs. | |
72 HPhi* phi = HPhi::cast(value); | |
73 for (int i = 0; i < phi->OperandCount(); ++i) { | |
74 AddToWorklist(phi->OperandAt(i)); | |
75 } | |
76 } else if (value->IsUnaryMathOperation()) { | |
77 HUnaryMathOperation* instr = HUnaryMathOperation::cast(value); | |
78 if (instr->representation().IsSmiOrInteger32() && | |
79 !instr->value()->representation().Equals(instr->representation())) { | |
80 if (instr->value()->range() == NULL || | |
81 instr->value()->range()->CanBeMinusZero()) { | |
82 instr->SetFlag(HValue::kBailoutOnMinusZero); | |
83 } | |
84 } | |
85 if (instr->RequiredInputRepresentation(0).IsSmiOrInteger32() && | |
86 instr->representation().Equals( | |
87 instr->RequiredInputRepresentation(0))) { | |
88 AddToWorklist(instr->value()); | |
89 } | |
90 } else if (value->IsChange()) { | |
91 HChange* instr = HChange::cast(value); | |
92 if (!instr->from().IsSmiOrInteger32() && | |
93 !instr->CanTruncateToInt32() && | |
94 (instr->value()->range() == NULL || | |
95 instr->value()->range()->CanBeMinusZero())) { | |
96 instr->SetFlag(HValue::kBailoutOnMinusZero); | |
97 } | |
98 } else if (value->IsForceRepresentation()) { | |
99 HForceRepresentation* instr = HForceRepresentation::cast(value); | |
100 AddToWorklist(instr->value()); | |
101 } else if (value->IsMod()) { | |
102 HMod* instr = HMod::cast(value); | |
103 if (instr->range() == NULL || instr->range()->CanBeMinusZero()) { | |
104 instr->SetFlag(HValue::kBailoutOnMinusZero); | |
105 AddToWorklist(instr->left()); | |
106 } | |
107 } else if (value->IsDiv() || value->IsMul()) { | |
108 HBinaryOperation* instr = HBinaryOperation::cast(value); | |
109 if (instr->range() == NULL || instr->range()->CanBeMinusZero()) { | |
110 instr->SetFlag(HValue::kBailoutOnMinusZero); | |
111 } | |
112 AddToWorklist(instr->right()); | |
113 AddToWorklist(instr->left()); | |
114 } else if (value->IsMathFloorOfDiv()) { | |
115 HMathFloorOfDiv* instr = HMathFloorOfDiv::cast(value); | |
116 instr->SetFlag(HValue::kBailoutOnMinusZero); | |
117 } else if (value->IsAdd() || value->IsSub()) { | |
118 HBinaryOperation* instr = HBinaryOperation::cast(value); | |
119 if (instr->range() == NULL || instr->range()->CanBeMinusZero()) { | |
120 // Propagate to the left argument. If the left argument cannot be -0, | |
121 // then the result of the add/sub operation cannot be either. | |
122 AddToWorklist(instr->left()); | |
123 } | |
124 } else if (value->IsMathMinMax()) { | |
125 HMathMinMax* instr = HMathMinMax::cast(value); | |
126 AddToWorklist(instr->right()); | |
127 AddToWorklist(instr->left()); | |
128 } | |
129 } | |
130 | |
131 in_worklist_.Clear(); | |
132 ASSERT(in_worklist_.IsEmpty()); | |
133 ASSERT(worklist_.is_empty()); | |
134 } | |
135 | |
136 } } // namespace v8::internal | |
OLD | NEW |