[crankshaft] Refactor kAllowUndefinedAsNaN to kTruncatingToNumber.
The meaning of the HValue::kAllowUndefinedAsNaN is actually ToNumber conversion (except for the uses in HBranch and HCompareHoleAndBranch, which were confusing and useless anyways), so fix the naming to match that. Also properly integrate the handling of this flag with the existing truncation analysis that is run as part of the representation changes phase (i.e. where we already deal with truncating to int32 and smi). This is done in preparation of allowing Crankshaft to handle any kind of Oddball in the ToNumber truncation, instead of just undefined for truncation ToNumber and undefined or boolean for ToInt32. It also helps to make Crankshaft somewhat more compatible with the (saner) implementation in TurboFan. R=yangguo@chromium.org BUG=v8:5400 Review-Url: https://codereview.chromium.org/2449353002 Cr-Commit-Position: refs/heads/master@{#40577}
This commit is contained in:
parent
58e0e3f635
commit
df981a9ff5
2
BUILD.gn
2
BUILD.gn
@ -1244,8 +1244,6 @@ v8_source_set("v8_base") {
|
||||
"src/crankshaft/hydrogen-instructions.h",
|
||||
"src/crankshaft/hydrogen-load-elimination.cc",
|
||||
"src/crankshaft/hydrogen-load-elimination.h",
|
||||
"src/crankshaft/hydrogen-mark-deoptimize.cc",
|
||||
"src/crankshaft/hydrogen-mark-deoptimize.h",
|
||||
"src/crankshaft/hydrogen-mark-unreachable.cc",
|
||||
"src/crankshaft/hydrogen-mark-unreachable.h",
|
||||
"src/crankshaft/hydrogen-osr.cc",
|
||||
|
@ -1870,6 +1870,8 @@ class LNumberUntagD final : public LTemplateInstruction<1, 1, 0> {
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
|
||||
DECLARE_HYDROGEN_ACCESSOR(Change)
|
||||
|
||||
bool truncating() { return hydrogen()->CanTruncateToNumber(); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -4461,8 +4461,7 @@ void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
|
||||
void LCodeGen::EmitNumberUntagD(LNumberUntagD* instr, Register input_reg,
|
||||
DwVfpRegister result_reg,
|
||||
NumberUntagDMode mode) {
|
||||
bool can_convert_undefined_to_nan =
|
||||
instr->hydrogen()->can_convert_undefined_to_nan();
|
||||
bool can_convert_undefined_to_nan = instr->truncating();
|
||||
bool deoptimize_on_minus_zero = instr->hydrogen()->deoptimize_on_minus_zero();
|
||||
|
||||
Register scratch = scratch0();
|
||||
|
@ -1952,6 +1952,8 @@ class LNumberUntagD final : public LTemplateInstruction<1, 1, 1> {
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
|
||||
DECLARE_HYDROGEN_ACCESSOR(Change)
|
||||
|
||||
bool truncating() { return hydrogen()->CanTruncateToNumber(); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -4204,8 +4204,7 @@ void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
|
||||
Register input = ToRegister(instr->value());
|
||||
Register scratch = ToRegister(instr->temp());
|
||||
DoubleRegister result = ToDoubleRegister(instr->result());
|
||||
bool can_convert_undefined_to_nan =
|
||||
instr->hydrogen()->can_convert_undefined_to_nan();
|
||||
bool can_convert_undefined_to_nan = instr->truncating();
|
||||
|
||||
Label done, load_smi;
|
||||
|
||||
|
@ -1478,8 +1478,8 @@ std::ostream& HChange::PrintDataTo(std::ostream& os) const { // NOLINT
|
||||
|
||||
if (CanTruncateToSmi()) os << " truncating-smi";
|
||||
if (CanTruncateToInt32()) os << " truncating-int32";
|
||||
if (CanTruncateToNumber()) os << " truncating-number";
|
||||
if (CheckFlag(kBailoutOnMinusZero)) os << " -0?";
|
||||
if (CheckFlag(kAllowUndefinedAsNaN)) os << " allow-undefined-as-nan";
|
||||
return os;
|
||||
}
|
||||
|
||||
@ -1490,8 +1490,8 @@ HValue* HUnaryMathOperation::Canonicalize() {
|
||||
if (val->IsChange()) val = HChange::cast(val)->value();
|
||||
if (val->representation().IsSmiOrInteger32()) {
|
||||
if (val->representation().Equals(representation())) return val;
|
||||
return Prepend(new(block()->zone()) HChange(
|
||||
val, representation(), false, false));
|
||||
return Prepend(new (block()->zone())
|
||||
HChange(val, representation(), false, false, true));
|
||||
}
|
||||
}
|
||||
if (op() == kMathFloor && representation().IsSmiOrInteger32() &&
|
||||
@ -1506,8 +1506,8 @@ HValue* HUnaryMathOperation::Canonicalize() {
|
||||
// A change from an integer32 can be replaced by the integer32 value.
|
||||
left = HChange::cast(left)->value();
|
||||
} else if (hdiv->observed_input_representation(1).IsSmiOrInteger32()) {
|
||||
left = Prepend(new(block()->zone()) HChange(
|
||||
left, Representation::Integer32(), false, false));
|
||||
left = Prepend(new (block()->zone()) HChange(
|
||||
left, Representation::Integer32(), false, false, true));
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
@ -1525,8 +1525,8 @@ HValue* HUnaryMathOperation::Canonicalize() {
|
||||
// A change from an integer32 can be replaced by the integer32 value.
|
||||
right = HChange::cast(right)->value();
|
||||
} else if (hdiv->observed_input_representation(2).IsSmiOrInteger32()) {
|
||||
right = Prepend(new(block()->zone()) HChange(
|
||||
right, Representation::Integer32(), false, false));
|
||||
right = Prepend(new (block()->zone()) HChange(
|
||||
right, Representation::Integer32(), false, false, true));
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
@ -2866,7 +2866,7 @@ void HCompareNumericAndBranch::InferRepresentation(
|
||||
// comparisons must cause a deopt when one of their arguments is undefined.
|
||||
// See also v8:1434
|
||||
if (Token::IsOrderedRelationalCompareOp(token_)) {
|
||||
SetFlag(kAllowUndefinedAsNaN);
|
||||
SetFlag(kTruncatingToNumber);
|
||||
}
|
||||
}
|
||||
ChangeRepresentation(rep);
|
||||
@ -2965,7 +2965,7 @@ bool HLoadKeyed::UsesMustHandleHole() const {
|
||||
|
||||
bool HLoadKeyed::AllUsesCanTreatHoleAsNaN() const {
|
||||
return IsFastDoubleElementsKind(elements_kind()) &&
|
||||
CheckUsesForFlag(HValue::kAllowUndefinedAsNaN);
|
||||
CheckUsesForFlag(HValue::kTruncatingToNumber);
|
||||
}
|
||||
|
||||
|
||||
|
@ -411,7 +411,7 @@ class HValue : public ZoneObject {
|
||||
kLeftCanBeMinInt,
|
||||
kLeftCanBeNegative,
|
||||
kLeftCanBePositive,
|
||||
kAllowUndefinedAsNaN,
|
||||
kTruncatingToNumber,
|
||||
kIsArguments,
|
||||
kTruncatingToInt32,
|
||||
kAllUsesTruncatingToInt32,
|
||||
@ -1091,6 +1091,7 @@ class HInstruction : public HValue {
|
||||
bool Dominates(HInstruction* other);
|
||||
bool CanTruncateToSmi() const { return CheckFlag(kTruncatingToSmi); }
|
||||
bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
|
||||
bool CanTruncateToNumber() const { return CheckFlag(kTruncatingToNumber); }
|
||||
|
||||
virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
|
||||
|
||||
@ -1372,9 +1373,7 @@ class HBranch final : public HUnaryControlInstruction {
|
||||
ToBooleanICStub::Types(),
|
||||
HBasicBlock* true_target = NULL, HBasicBlock* false_target = NULL)
|
||||
: HUnaryControlInstruction(value, true_target, false_target),
|
||||
expected_input_types_(expected_input_types) {
|
||||
SetFlag(kAllowUndefinedAsNaN);
|
||||
}
|
||||
expected_input_types_(expected_input_types) {}
|
||||
|
||||
ToBooleanICStub::Types expected_input_types_;
|
||||
};
|
||||
@ -1570,13 +1569,10 @@ class HForceRepresentation final : public HTemplateInstruction<1> {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class HChange final : public HUnaryOperation {
|
||||
public:
|
||||
HChange(HValue* value,
|
||||
Representation to,
|
||||
bool is_truncating_to_smi,
|
||||
bool is_truncating_to_int32)
|
||||
HChange(HValue* value, Representation to, bool is_truncating_to_smi,
|
||||
bool is_truncating_to_int32, bool is_truncating_to_number)
|
||||
: HUnaryOperation(value) {
|
||||
DCHECK(!value->representation().IsNone());
|
||||
DCHECK(!to.IsNone());
|
||||
@ -1587,8 +1583,13 @@ class HChange final : public HUnaryOperation {
|
||||
if (is_truncating_to_smi && to.IsSmi()) {
|
||||
SetFlag(kTruncatingToSmi);
|
||||
SetFlag(kTruncatingToInt32);
|
||||
SetFlag(kTruncatingToNumber);
|
||||
} else if (is_truncating_to_int32) {
|
||||
SetFlag(kTruncatingToInt32);
|
||||
SetFlag(kTruncatingToNumber);
|
||||
} else if (is_truncating_to_number) {
|
||||
SetFlag(kTruncatingToNumber);
|
||||
}
|
||||
if (is_truncating_to_int32) SetFlag(kTruncatingToInt32);
|
||||
if (value->representation().IsSmi() || value->type().IsSmi()) {
|
||||
set_type(HType::Smi());
|
||||
} else {
|
||||
@ -1597,10 +1598,6 @@ class HChange final : public HUnaryOperation {
|
||||
}
|
||||
}
|
||||
|
||||
bool can_convert_undefined_to_nan() {
|
||||
return CheckUsesForFlag(kAllowUndefinedAsNaN);
|
||||
}
|
||||
|
||||
HType CalculateInferredType() override;
|
||||
HValue* Canonicalize() override;
|
||||
|
||||
@ -1646,7 +1643,7 @@ class HClampToUint8 final : public HUnaryOperation {
|
||||
explicit HClampToUint8(HValue* value)
|
||||
: HUnaryOperation(value) {
|
||||
set_representation(Representation::Integer32());
|
||||
SetFlag(kAllowUndefinedAsNaN);
|
||||
SetFlag(kTruncatingToNumber);
|
||||
SetFlag(kUseGVN);
|
||||
}
|
||||
|
||||
@ -2500,7 +2497,7 @@ class HUnaryMathOperation final : public HTemplateInstruction<2> {
|
||||
UNREACHABLE();
|
||||
}
|
||||
SetFlag(kUseGVN);
|
||||
SetFlag(kAllowUndefinedAsNaN);
|
||||
SetFlag(kTruncatingToNumber);
|
||||
}
|
||||
|
||||
bool IsDeletable() const override {
|
||||
@ -2914,7 +2911,6 @@ class HPhi final : public HValue {
|
||||
: inputs_(2, zone), merged_index_(merged_index) {
|
||||
DCHECK(merged_index >= 0 || merged_index == kInvalidMergedIndex);
|
||||
SetFlag(kFlexibleRepresentation);
|
||||
SetFlag(kAllowUndefinedAsNaN);
|
||||
}
|
||||
|
||||
Representation RepresentationFromInputs() override;
|
||||
@ -3730,7 +3726,7 @@ class HBitwiseBinaryOperation : public HBinaryOperation {
|
||||
: HBinaryOperation(context, left, right, type) {
|
||||
SetFlag(kFlexibleRepresentation);
|
||||
SetFlag(kTruncatingToInt32);
|
||||
SetFlag(kAllowUndefinedAsNaN);
|
||||
SetFlag(kTruncatingToNumber);
|
||||
SetAllSideEffects();
|
||||
}
|
||||
|
||||
@ -3793,7 +3789,7 @@ class HMathFloorOfDiv final : public HBinaryOperation {
|
||||
SetFlag(kLeftCanBeMinInt);
|
||||
SetFlag(kLeftCanBeNegative);
|
||||
SetFlag(kLeftCanBePositive);
|
||||
SetFlag(kAllowUndefinedAsNaN);
|
||||
SetFlag(kTruncatingToNumber);
|
||||
}
|
||||
|
||||
Range* InferRange(Zone* zone) override;
|
||||
@ -3808,7 +3804,7 @@ class HArithmeticBinaryOperation : public HBinaryOperation {
|
||||
: HBinaryOperation(context, left, right, HType::TaggedNumber()) {
|
||||
SetAllSideEffects();
|
||||
SetFlag(kFlexibleRepresentation);
|
||||
SetFlag(kAllowUndefinedAsNaN);
|
||||
SetFlag(kTruncatingToNumber);
|
||||
}
|
||||
|
||||
void RepresentationChanged(Representation to) override {
|
||||
@ -3941,7 +3937,6 @@ class HCompareHoleAndBranch final : public HUnaryControlInstruction {
|
||||
HBasicBlock* false_target = NULL)
|
||||
: HUnaryControlInstruction(value, true_target, false_target) {
|
||||
SetFlag(kFlexibleRepresentation);
|
||||
SetFlag(kAllowUndefinedAsNaN);
|
||||
}
|
||||
};
|
||||
|
||||
@ -4298,12 +4293,12 @@ class HAdd final : public HArithmeticBinaryOperation {
|
||||
}
|
||||
if (to.IsTagged()) {
|
||||
SetChangesFlag(kNewSpacePromotion);
|
||||
ClearFlag(kAllowUndefinedAsNaN);
|
||||
ClearFlag(kTruncatingToNumber);
|
||||
}
|
||||
if (!right()->type().IsTaggedNumber() &&
|
||||
!right()->representation().IsDouble() &&
|
||||
!right()->representation().IsSmiOrInteger32()) {
|
||||
ClearFlag(kAllowUndefinedAsNaN);
|
||||
ClearFlag(kTruncatingToNumber);
|
||||
}
|
||||
}
|
||||
|
||||
@ -6337,7 +6332,7 @@ class HStoreKeyed final : public HTemplateInstruction<4>,
|
||||
} else if (is_fixed_typed_array()) {
|
||||
SetChangesFlag(kTypedArrayElements);
|
||||
SetChangesFlag(kExternalMemory);
|
||||
SetFlag(kAllowUndefinedAsNaN);
|
||||
SetFlag(kTruncatingToNumber);
|
||||
} else {
|
||||
SetChangesFlag(kArrayElements);
|
||||
}
|
||||
|
@ -1,62 +0,0 @@
|
||||
// Copyright 2013 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "src/crankshaft/hydrogen-mark-deoptimize.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
void HMarkDeoptimizeOnUndefinedPhase::Run() {
|
||||
const ZoneList<HPhi*>* phi_list = graph()->phi_list();
|
||||
for (int i = 0; i < phi_list->length(); i++) {
|
||||
HPhi* phi = phi_list->at(i);
|
||||
if (phi->CheckFlag(HValue::kAllowUndefinedAsNaN) &&
|
||||
!phi->CheckUsesForFlag(HValue::kAllowUndefinedAsNaN)) {
|
||||
ProcessPhi(phi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HMarkDeoptimizeOnUndefinedPhase::ProcessPhi(HPhi* phi) {
|
||||
DCHECK(phi->CheckFlag(HValue::kAllowUndefinedAsNaN));
|
||||
DCHECK(worklist_.is_empty());
|
||||
|
||||
// Push the phi onto the worklist
|
||||
phi->ClearFlag(HValue::kAllowUndefinedAsNaN);
|
||||
worklist_.Add(phi, zone());
|
||||
|
||||
// Process all phis that can reach this phi
|
||||
while (!worklist_.is_empty()) {
|
||||
phi = worklist_.RemoveLast();
|
||||
for (int i = phi->OperandCount() - 1; i >= 0; --i) {
|
||||
HValue* input = phi->OperandAt(i);
|
||||
if (input->IsPhi() && input->CheckFlag(HValue::kAllowUndefinedAsNaN)) {
|
||||
input->ClearFlag(HValue::kAllowUndefinedAsNaN);
|
||||
worklist_.Add(HPhi::cast(input), zone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HComputeChangeUndefinedToNaN::Run() {
|
||||
const ZoneList<HBasicBlock*>* blocks(graph()->blocks());
|
||||
for (int i = 0; i < blocks->length(); ++i) {
|
||||
const HBasicBlock* block(blocks->at(i));
|
||||
for (HInstruction* current = block->first(); current != NULL; ) {
|
||||
HInstruction* next = current->next();
|
||||
if (current->IsChange()) {
|
||||
if (HChange::cast(current)->can_convert_undefined_to_nan()) {
|
||||
current->SetFlag(HValue::kAllowUndefinedAsNaN);
|
||||
}
|
||||
}
|
||||
current = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
@ -1,53 +0,0 @@
|
||||
// Copyright 2013 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef V8_CRANKSHAFT_HYDROGEN_MARK_DEOPTIMIZE_H_
|
||||
#define V8_CRANKSHAFT_HYDROGEN_MARK_DEOPTIMIZE_H_
|
||||
|
||||
#include "src/crankshaft/hydrogen.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
|
||||
// Compute DeoptimizeOnUndefined flag for phis. Any phi that can reach a use
|
||||
// with DeoptimizeOnUndefined set must have DeoptimizeOnUndefined set.
|
||||
// Currently only HCompareNumericAndBranch, with double input representation,
|
||||
// has this flag set. The flag is used by HChange tagged->double, which must
|
||||
// deoptimize if one of its uses has this flag set.
|
||||
class HMarkDeoptimizeOnUndefinedPhase : public HPhase {
|
||||
public:
|
||||
explicit HMarkDeoptimizeOnUndefinedPhase(HGraph* graph)
|
||||
: HPhase("H_Mark deoptimize on undefined", graph),
|
||||
worklist_(16, zone()) {}
|
||||
|
||||
void Run();
|
||||
|
||||
private:
|
||||
void ProcessPhi(HPhi* phi);
|
||||
|
||||
// Preallocated worklist used as an optimization so we don't have
|
||||
// to allocate a new ZoneList for every ProcessPhi() invocation.
|
||||
ZoneList<HPhi*> worklist_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(HMarkDeoptimizeOnUndefinedPhase);
|
||||
};
|
||||
|
||||
|
||||
class HComputeChangeUndefinedToNaN : public HPhase {
|
||||
public:
|
||||
explicit HComputeChangeUndefinedToNaN(HGraph* graph)
|
||||
: HPhase("H_Compute change undefined to nan", graph) {}
|
||||
|
||||
void Run();
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(HComputeChangeUndefinedToNaN);
|
||||
};
|
||||
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#endif // V8_CRANKSHAFT_HYDROGEN_MARK_DEOPTIMIZE_H_
|
@ -24,6 +24,8 @@ void HRepresentationChangesPhase::InsertRepresentationChangeForUse(
|
||||
HInstruction* new_value = NULL;
|
||||
bool is_truncating_to_smi = use_value->CheckFlag(HValue::kTruncatingToSmi);
|
||||
bool is_truncating_to_int = use_value->CheckFlag(HValue::kTruncatingToInt32);
|
||||
bool is_truncating_to_number =
|
||||
use_value->CheckFlag(HValue::kTruncatingToNumber);
|
||||
if (value->IsConstant()) {
|
||||
HConstant* constant = HConstant::cast(value);
|
||||
// Try to create a new copy of the constant with the new representation.
|
||||
@ -36,8 +38,9 @@ void HRepresentationChangesPhase::InsertRepresentationChangeForUse(
|
||||
}
|
||||
|
||||
if (new_value == NULL) {
|
||||
new_value = new(graph()->zone()) HChange(
|
||||
value, to, is_truncating_to_smi, is_truncating_to_int);
|
||||
new_value = new (graph()->zone())
|
||||
HChange(value, to, is_truncating_to_smi, is_truncating_to_int,
|
||||
is_truncating_to_number);
|
||||
if (!use_value->operand_position(use_index).IsUnknown()) {
|
||||
new_value->set_position(use_value->operand_position(use_index));
|
||||
} else {
|
||||
@ -116,10 +119,15 @@ void HRepresentationChangesPhase::InsertRepresentationChangesForValue(
|
||||
|
||||
|
||||
void HRepresentationChangesPhase::Run() {
|
||||
// Compute truncation flag for phis: Initially assume that all
|
||||
// int32-phis allow truncation and iteratively remove the ones that
|
||||
// are used in an operation that does not allow a truncating
|
||||
// conversion.
|
||||
// Compute truncation flag for phis:
|
||||
//
|
||||
// - Initially assume that all phis allow truncation to number and iteratively
|
||||
// remove the ones that are used in an operation that not do an implicit
|
||||
// ToNumber conversion.
|
||||
// - Also assume that all Integer32 phis allow ToInt32 truncation and all
|
||||
// Smi phis allow truncation to Smi.
|
||||
//
|
||||
ZoneList<HPhi*> number_worklist(8, zone());
|
||||
ZoneList<HPhi*> int_worklist(8, zone());
|
||||
ZoneList<HPhi*> smi_worklist(8, zone());
|
||||
|
||||
@ -132,22 +140,33 @@ void HRepresentationChangesPhase::Run() {
|
||||
phi->SetFlag(HValue::kTruncatingToSmi);
|
||||
phi->SetFlag(HValue::kTruncatingToInt32);
|
||||
}
|
||||
phi->SetFlag(HValue::kTruncatingToNumber);
|
||||
}
|
||||
|
||||
for (int i = 0; i < phi_list->length(); i++) {
|
||||
HPhi* phi = phi_list->at(i);
|
||||
HValue* value = NULL;
|
||||
if (phi->representation().IsSmiOrInteger32() &&
|
||||
|
||||
if (phi->CheckFlag(HValue::kTruncatingToNumber) &&
|
||||
!phi->CheckUsesForFlag(HValue::kTruncatingToNumber, &value)) {
|
||||
number_worklist.Add(phi, zone());
|
||||
phi->ClearFlag(HValue::kTruncatingToNumber);
|
||||
phi->ClearFlag(HValue::kTruncatingToInt32);
|
||||
phi->ClearFlag(HValue::kTruncatingToSmi);
|
||||
if (FLAG_trace_representation) {
|
||||
PrintF("#%d Phi is not truncating Number because of #%d %s\n",
|
||||
phi->id(), value->id(), value->Mnemonic());
|
||||
}
|
||||
} else if (phi->representation().IsSmiOrInteger32() &&
|
||||
!phi->CheckUsesForFlag(HValue::kTruncatingToInt32, &value)) {
|
||||
int_worklist.Add(phi, zone());
|
||||
phi->ClearFlag(HValue::kTruncatingToInt32);
|
||||
phi->ClearFlag(HValue::kTruncatingToSmi);
|
||||
if (FLAG_trace_representation) {
|
||||
PrintF("#%d Phi is not truncating Int32 because of #%d %s\n",
|
||||
phi->id(), value->id(), value->Mnemonic());
|
||||
}
|
||||
}
|
||||
|
||||
if (phi->representation().IsSmi() &&
|
||||
} else if (phi->representation().IsSmi() &&
|
||||
!phi->CheckUsesForFlag(HValue::kTruncatingToSmi, &value)) {
|
||||
smi_worklist.Add(phi, zone());
|
||||
phi->ClearFlag(HValue::kTruncatingToSmi);
|
||||
@ -158,6 +177,23 @@ void HRepresentationChangesPhase::Run() {
|
||||
}
|
||||
}
|
||||
|
||||
while (!number_worklist.is_empty()) {
|
||||
HPhi* current = number_worklist.RemoveLast();
|
||||
for (int i = current->OperandCount() - 1; i >= 0; --i) {
|
||||
HValue* input = current->OperandAt(i);
|
||||
if (input->IsPhi() && input->CheckFlag(HValue::kTruncatingToNumber)) {
|
||||
if (FLAG_trace_representation) {
|
||||
PrintF("#%d Phi is not truncating Number because of #%d %s\n",
|
||||
input->id(), current->id(), current->Mnemonic());
|
||||
}
|
||||
input->ClearFlag(HValue::kTruncatingToNumber);
|
||||
input->ClearFlag(HValue::kTruncatingToInt32);
|
||||
input->ClearFlag(HValue::kTruncatingToSmi);
|
||||
number_worklist.Add(HPhi::cast(input), zone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (!int_worklist.is_empty()) {
|
||||
HPhi* current = int_worklist.RemoveLast();
|
||||
for (int i = 0; i < current->OperandCount(); ++i) {
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include "src/crankshaft/hydrogen-infer-representation.h"
|
||||
#include "src/crankshaft/hydrogen-infer-types.h"
|
||||
#include "src/crankshaft/hydrogen-load-elimination.h"
|
||||
#include "src/crankshaft/hydrogen-mark-deoptimize.h"
|
||||
#include "src/crankshaft/hydrogen-mark-unreachable.h"
|
||||
#include "src/crankshaft/hydrogen-osr.h"
|
||||
#include "src/crankshaft/hydrogen-range-analysis.h"
|
||||
@ -2970,12 +2969,12 @@ void HGraphBuilder::BuildCopyElements(HValue* from_elements,
|
||||
if_hole.Else();
|
||||
HStoreKeyed* store =
|
||||
Add<HStoreKeyed>(to_elements, key, element, nullptr, kind);
|
||||
store->SetFlag(HValue::kAllowUndefinedAsNaN);
|
||||
store->SetFlag(HValue::kTruncatingToNumber);
|
||||
if_hole.End();
|
||||
} else {
|
||||
HStoreKeyed* store =
|
||||
Add<HStoreKeyed>(to_elements, key, element, nullptr, kind);
|
||||
store->SetFlag(HValue::kAllowUndefinedAsNaN);
|
||||
store->SetFlag(HValue::kTruncatingToNumber);
|
||||
}
|
||||
|
||||
builder.EndBody();
|
||||
@ -4131,7 +4130,6 @@ bool HGraph::Optimize(BailoutReason* bailout_reason) {
|
||||
// This must happen after inferring representations.
|
||||
Run<HMergeRemovableSimulatesPhase>();
|
||||
|
||||
Run<HMarkDeoptimizeOnUndefinedPhase>();
|
||||
Run<HRepresentationChangesPhase>();
|
||||
|
||||
Run<HInferTypesPhase>();
|
||||
@ -4151,8 +4149,6 @@ bool HGraph::Optimize(BailoutReason* bailout_reason) {
|
||||
|
||||
Run<HRangeAnalysisPhase>();
|
||||
|
||||
Run<HComputeChangeUndefinedToNaN>();
|
||||
|
||||
// Eliminate redundant stack checks on backwards branches.
|
||||
Run<HStackCheckEliminationPhase>();
|
||||
|
||||
@ -8769,7 +8765,7 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall(
|
||||
copy_kind, ALLOW_RETURN_HOLE);
|
||||
HStoreKeyed* store = Add<HStoreKeyed>(elements, new_key, element,
|
||||
nullptr, copy_kind);
|
||||
store->SetFlag(HValue::kAllowUndefinedAsNaN);
|
||||
store->SetFlag(HValue::kTruncatingToNumber);
|
||||
}
|
||||
loop.EndBody();
|
||||
|
||||
@ -11712,7 +11708,7 @@ void HOptimizedGraphBuilder::BuildEmitFixedDoubleArray(
|
||||
kind, ALLOW_RETURN_HOLE);
|
||||
HInstruction* store = Add<HStoreKeyed>(object_elements, key_constant,
|
||||
value_instruction, nullptr, kind);
|
||||
store->SetFlag(HValue::kAllowUndefinedAsNaN);
|
||||
store->SetFlag(HValue::kTruncatingToNumber);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4242,8 +4242,7 @@ void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
|
||||
void LCodeGen::EmitNumberUntagD(LNumberUntagD* instr, Register input_reg,
|
||||
Register temp_reg, XMMRegister result_reg,
|
||||
NumberUntagDMode mode) {
|
||||
bool can_convert_undefined_to_nan =
|
||||
instr->hydrogen()->can_convert_undefined_to_nan();
|
||||
bool can_convert_undefined_to_nan = instr->truncating();
|
||||
bool deoptimize_on_minus_zero = instr->hydrogen()->deoptimize_on_minus_zero();
|
||||
|
||||
Label convert, load_smi, done;
|
||||
|
@ -1885,6 +1885,8 @@ class LNumberUntagD final : public LTemplateInstruction<1, 1, 1> {
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
|
||||
DECLARE_HYDROGEN_ACCESSOR(Change);
|
||||
|
||||
bool truncating() { return hydrogen()->CanTruncateToNumber(); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -4417,8 +4417,7 @@ void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
|
||||
void LCodeGen::EmitNumberUntagD(LNumberUntagD* instr, Register input_reg,
|
||||
DoubleRegister result_reg,
|
||||
NumberUntagDMode mode) {
|
||||
bool can_convert_undefined_to_nan =
|
||||
instr->hydrogen()->can_convert_undefined_to_nan();
|
||||
bool can_convert_undefined_to_nan = instr->truncating();
|
||||
bool deoptimize_on_minus_zero = instr->hydrogen()->deoptimize_on_minus_zero();
|
||||
|
||||
Register scratch = scratch0();
|
||||
|
@ -1833,6 +1833,8 @@ class LNumberUntagD final : public LTemplateInstruction<1, 1, 0> {
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
|
||||
DECLARE_HYDROGEN_ACCESSOR(Change)
|
||||
|
||||
bool truncating() { return hydrogen()->CanTruncateToNumber(); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -4625,8 +4625,7 @@ void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
|
||||
void LCodeGen::EmitNumberUntagD(LNumberUntagD* instr, Register input_reg,
|
||||
DoubleRegister result_reg,
|
||||
NumberUntagDMode mode) {
|
||||
bool can_convert_undefined_to_nan =
|
||||
instr->hydrogen()->can_convert_undefined_to_nan();
|
||||
bool can_convert_undefined_to_nan = instr->truncating();
|
||||
bool deoptimize_on_minus_zero = instr->hydrogen()->deoptimize_on_minus_zero();
|
||||
|
||||
Register scratch = scratch0();
|
||||
|
@ -1879,6 +1879,8 @@ class LNumberUntagD final : public LTemplateInstruction<1, 1, 0> {
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
|
||||
DECLARE_HYDROGEN_ACCESSOR(Change)
|
||||
|
||||
bool truncating() { return hydrogen()->CanTruncateToNumber(); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -4532,8 +4532,7 @@ void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
|
||||
|
||||
void LCodeGen::EmitNumberUntagD(LNumberUntagD* instr, Register input_reg,
|
||||
XMMRegister result_reg, NumberUntagDMode mode) {
|
||||
bool can_convert_undefined_to_nan =
|
||||
instr->hydrogen()->can_convert_undefined_to_nan();
|
||||
bool can_convert_undefined_to_nan = instr->truncating();
|
||||
bool deoptimize_on_minus_zero = instr->hydrogen()->deoptimize_on_minus_zero();
|
||||
|
||||
Label convert, load_smi, done;
|
||||
|
@ -1876,6 +1876,8 @@ class LNumberUntagD final : public LTemplateInstruction<1, 1, 0> {
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
|
||||
DECLARE_HYDROGEN_ACCESSOR(Change);
|
||||
|
||||
bool truncating() { return hydrogen()->CanTruncateToNumber(); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -784,8 +784,6 @@
|
||||
'crankshaft/hydrogen-instructions.h',
|
||||
'crankshaft/hydrogen-load-elimination.cc',
|
||||
'crankshaft/hydrogen-load-elimination.h',
|
||||
'crankshaft/hydrogen-mark-deoptimize.cc',
|
||||
'crankshaft/hydrogen-mark-deoptimize.h',
|
||||
'crankshaft/hydrogen-mark-unreachable.cc',
|
||||
'crankshaft/hydrogen-mark-unreachable.h',
|
||||
'crankshaft/hydrogen-osr.cc',
|
||||
|
Loading…
Reference in New Issue
Block a user