Home | History | Annotate | Download | only in src
      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           ASSERT(visited_.IsEmpty());
     49           PropagateMinusZeroChecks(change->value());
     50           visited_.Clear();
     51         }
     52       } else if (current->IsCompareMinusZeroAndBranch()) {
     53         HCompareMinusZeroAndBranch* check =
     54             HCompareMinusZeroAndBranch::cast(current);
     55         if (check->value()->representation().IsSmiOrInteger32()) {
     56           ASSERT(visited_.IsEmpty());
     57           PropagateMinusZeroChecks(check->value());
     58           visited_.Clear();
     59         }
     60       }
     61     }
     62   }
     63 }
     64 
     65 
     66 void HComputeMinusZeroChecksPhase::PropagateMinusZeroChecks(HValue* value) {
     67   for (HValue* current = value;
     68        current != NULL && !visited_.Contains(current->id());
     69        current = current->EnsureAndPropagateNotMinusZero(&visited_)) {
     70     // For phis, we must propagate the check to all of its inputs.
     71     if (current->IsPhi()) {
     72       visited_.Add(current->id());
     73       HPhi* phi = HPhi::cast(current);
     74       for (int i = 0; i < phi->OperandCount(); ++i) {
     75         PropagateMinusZeroChecks(phi->OperandAt(i));
     76       }
     77       break;
     78     }
     79 
     80     // For multiplication, division, and Math.min/max(), we must propagate
     81     // to the left and the right side.
     82     if (current->IsMul() || current->IsDiv() || current->IsMathMinMax()) {
     83       HBinaryOperation* operation = HBinaryOperation::cast(current);
     84       operation->EnsureAndPropagateNotMinusZero(&visited_);
     85       PropagateMinusZeroChecks(operation->left());
     86       PropagateMinusZeroChecks(operation->right());
     87     }
     88   }
     89 }
     90 
     91 } }  // namespace v8::internal
     92