Commit 5664bcae authored by bmeurer@chromium.org's avatar bmeurer@chromium.org

Refactor compute minus zero checks into a proper HPhase.

R=dslomov@chromium.org

Review URL: https://codereview.chromium.org/18666006

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15595 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 854e9b99
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "hydrogen-minus-zero.h"
namespace v8 {
namespace internal {
void HComputeMinusZeroChecksPhase::Run() {
const ZoneList<HBasicBlock*>* blocks(graph()->blocks());
for (int i = 0; i < blocks->length(); ++i) {
for (HInstructionIterator it(blocks->at(i)); !it.Done(); it.Advance()) {
HInstruction* current = it.Current();
if (current->IsChange()) {
HChange* change = HChange::cast(current);
// Propagate flags for negative zero checks upwards from conversions
// int32-to-tagged and int32-to-double.
Representation from = change->value()->representation();
ASSERT(from.Equals(change->from()));
if (from.IsInteger32()) {
ASSERT(change->to().IsTagged() ||
change->to().IsDouble() ||
change->to().IsSmi());
ASSERT(visited_.IsEmpty());
PropagateMinusZeroChecks(change->value());
visited_.Clear();
}
}
}
}
}
void HComputeMinusZeroChecksPhase::PropagateMinusZeroChecks(HValue* value) {
for (HValue* current = value;
current != NULL && !visited_.Contains(current->id());
current = current->EnsureAndPropagateNotMinusZero(&visited_)) {
// For phis, we must propagate the check to all of its inputs.
if (current->IsPhi()) {
visited_.Add(current->id());
HPhi* phi = HPhi::cast(current);
for (int i = 0; i < phi->OperandCount(); ++i) {
PropagateMinusZeroChecks(phi->OperandAt(i));
}
break;
}
// For multiplication, division, and Math.min/max(), we must propagate
// to the left and the right side.
if (current->IsMul() || current->IsDiv() || current->IsMathMinMax()) {
HBinaryOperation* operation = HBinaryOperation::cast(current);
operation->EnsureAndPropagateNotMinusZero(&visited_);
PropagateMinusZeroChecks(operation->left());
PropagateMinusZeroChecks(operation->right());
}
}
}
} } // namespace v8::internal
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef V8_HYDROGEN_MINUS_ZERO_H_
#define V8_HYDROGEN_MINUS_ZERO_H_
#include "hydrogen.h"
namespace v8 {
namespace internal {
class HComputeMinusZeroChecksPhase : public HPhase {
public:
explicit HComputeMinusZeroChecksPhase(HGraph* graph)
: HPhase("H_Compute minus zero checks", graph),
visited_(graph->GetMaximumValueID(), zone()) { }
void Run();
private:
void PropagateMinusZeroChecks(HValue* value);
BitVector visited_;
DISALLOW_COPY_AND_ASSIGN(HComputeMinusZeroChecksPhase);
};
} } // namespace v8::internal
#endif // V8_HYDROGEN_MINUS_ZERO_H_
......@@ -40,6 +40,7 @@
#include "hydrogen-infer-representation.h"
#include "hydrogen-infer-types.h"
#include "hydrogen-gvn.h"
#include "hydrogen-minus-zero.h"
#include "hydrogen-osr.h"
#include "hydrogen-range-analysis.h"
#include "hydrogen-redundant-phi.h"
......@@ -2634,45 +2635,6 @@ void HGraph::MergeRemovableSimulates() {
}
void HGraph::PropagateMinusZeroChecks(HValue* value, BitVector* visited) {
HValue* current = value;
while (current != NULL) {
if (visited->Contains(current->id())) return;
// For phis, we must propagate the check to all of its inputs.
if (current->IsPhi()) {
visited->Add(current->id());
HPhi* phi = HPhi::cast(current);
for (int i = 0; i < phi->OperandCount(); ++i) {
PropagateMinusZeroChecks(phi->OperandAt(i), visited);
}
break;
}
// For multiplication, division, and Math.min/max(), we must propagate
// to the left and the right side.
if (current->IsMul()) {
HMul* mul = HMul::cast(current);
mul->EnsureAndPropagateNotMinusZero(visited);
PropagateMinusZeroChecks(mul->left(), visited);
PropagateMinusZeroChecks(mul->right(), visited);
} else if (current->IsDiv()) {
HDiv* div = HDiv::cast(current);
div->EnsureAndPropagateNotMinusZero(visited);
PropagateMinusZeroChecks(div->left(), visited);
PropagateMinusZeroChecks(div->right(), visited);
} else if (current->IsMathMinMax()) {
HMathMinMax* minmax = HMathMinMax::cast(current);
visited->Add(minmax->id());
PropagateMinusZeroChecks(minmax->left(), visited);
PropagateMinusZeroChecks(minmax->right(), visited);
}
current = current->EnsureAndPropagateNotMinusZero(visited);
}
}
void HGraph::RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi* phi) {
if (!phi->CheckFlag(HValue::kAllowUndefinedAsNaN)) return;
phi->ClearFlag(HValue::kAllowUndefinedAsNaN);
......@@ -2705,32 +2667,6 @@ void HGraph::MarkDeoptimizeOnUndefined() {
}
void HGraph::ComputeMinusZeroChecks() {
HPhase phase("H_Compute minus zero checks", this);
BitVector visited(GetMaximumValueID(), zone());
for (int i = 0; i < blocks_.length(); ++i) {
for (HInstructionIterator it(blocks_[i]); !it.Done(); it.Advance()) {
HInstruction* current = it.Current();
if (current->IsChange()) {
HChange* change = HChange::cast(current);
// Propagate flags for negative zero checks upwards from conversions
// int32-to-tagged and int32-to-double.
Representation from = change->value()->representation();
ASSERT(from.Equals(change->from()));
if (from.IsInteger32()) {
ASSERT(change->to().IsTagged() ||
change->to().IsDouble() ||
change->to().IsSmi());
ASSERT(visited.IsEmpty());
PropagateMinusZeroChecks(change->value(), &visited);
visited.Clear();
}
}
}
}
}
// Implementation of utility class to encapsulate the translation state for
// a (possibly inlined) function.
FunctionState::FunctionState(HOptimizedGraphBuilder* owner,
......@@ -3221,7 +3157,7 @@ bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) {
if (FLAG_use_range) Run<HRangeAnalysisPhase>();
ComputeMinusZeroChecks();
Run<HComputeMinusZeroChecksPhase>();
// Eliminate redundant stack checks on backwards branches.
Run<HStackCheckEliminationPhase>();
......
......@@ -294,7 +294,6 @@ class HGraph: public ZoneObject {
void InsertTypeConversions();
void MergeRemovableSimulates();
void MarkDeoptimizeOnUndefined();
void ComputeMinusZeroChecks();
bool ProcessArgumentsObject();
void Canonicalize();
void OrderBlocks();
......@@ -449,7 +448,6 @@ class HGraph: public ZoneObject {
void MarkAsDeoptimizingRecursively(HBasicBlock* block);
void NullifyUnreachableInstructions();
void InsertTypeConversions(HInstruction* instr);
void PropagateMinusZeroChecks(HValue* value, BitVector* visited);
void RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi* phi);
void CheckForBackEdge(HBasicBlock* block, HBasicBlock* successor);
void SetupInformativeDefinitionsInBlock(HBasicBlock* block);
......
......@@ -353,6 +353,8 @@
'../../src/hydrogen-infer-representation.h',
'../../src/hydrogen-infer-types.cc',
'../../src/hydrogen-infer-types.h',
'../../src/hydrogen-minus-zero.cc',
'../../src/hydrogen-minus-zero.h',
'../../src/hydrogen-range-analysis.cc',
'../../src/hydrogen-range-analysis.h',
'../../src/hydrogen-redundant-phi.cc',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment