Simplify HUnaryMathOperation::Canonicalize.

Made the logic architecture-independent, although we should really have some kind of instruction selection instead of trying to handle some weird cases at the hydrogen level.

Some tiny related cleanups on the way.

R=bmeurer@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18824 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
svenpanne@chromium.org 2014-01-24 14:05:11 +00:00
parent c86da7e5dc
commit 13395a8392
14 changed files with 104 additions and 211 deletions

View File

@ -1250,7 +1250,7 @@ LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
if (instr->representation().IsSmiOrInteger32()) {
ASSERT(instr->left()->representation().Equals(instr->representation()));
ASSERT(instr->right()->representation().Equals(instr->representation()));
if (instr->HasPowerOf2Divisor()) {
if (instr->RightIsPowerOf2()) {
ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero));
LOperand* value = UseRegisterAtStart(instr->left());
LDivI* div = new(zone()) LDivI(value, UseConstant(instr->right()), NULL);
@ -1296,43 +1296,25 @@ bool LChunkBuilder::HasMagicNumberForDivisor(int32_t divisor) {
}
HValue* LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(HValue* divisor) {
if (CpuFeatures::IsSupported(SUDIV)) {
// A value with an integer representation does not need to be transformed.
if (divisor->representation().IsInteger32()) {
return divisor;
// A change from an integer32 can be replaced by the integer32 value.
} else if (divisor->IsChange() &&
HChange::cast(divisor)->from().IsInteger32()) {
return HChange::cast(divisor)->value();
}
}
if (divisor->IsConstant() && HConstant::cast(divisor)->HasInteger32Value()) {
HConstant* constant_val = HConstant::cast(divisor);
int32_t int32_val = constant_val->Integer32Value();
if (LChunkBuilder::HasMagicNumberForDivisor(int32_val) ||
CpuFeatures::IsSupported(SUDIV)) {
return constant_val->CopyToRepresentation(Representation::Integer32(),
divisor->block()->zone());
}
}
return NULL;
}
LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
// LMathFloorOfDiv can only handle a subset of divisors, so fall
// back to a flooring division in all other cases.
HValue* right = instr->right();
if (!right->IsInteger32Constant() ||
(!CpuFeatures::IsSupported(SUDIV) &&
!HasMagicNumberForDivisor(HConstant::cast(right)->Integer32Value()))) {
LOperand* dividend = UseRegister(instr->left());
LOperand* divisor = UseRegister(right);
LOperand* temp = CpuFeatures::IsSupported(SUDIV) ? NULL : FixedTemp(d4);
LDivI* div = new(zone()) LDivI(dividend, divisor, temp);
return AssignEnvironment(DefineAsRegister(div));
}
LOperand* dividend = UseRegister(instr->left());
LOperand* divisor = CpuFeatures::IsSupported(SUDIV)
? UseRegister(right)
: UseOrConstant(right);
LOperand* remainder = TempRegister();
ASSERT(CpuFeatures::IsSupported(SUDIV) ||
(right->IsConstant() &&
HConstant::cast(right)->HasInteger32Value() &&
HasMagicNumberForDivisor(HConstant::cast(right)->Integer32Value())));
return AssignEnvironment(DefineAsRegister(
new(zone()) LMathFloorOfDiv(dividend, divisor, remainder)));
}
@ -1344,7 +1326,7 @@ LInstruction* LChunkBuilder::DoMod(HMod* instr) {
if (instr->representation().IsSmiOrInteger32()) {
ASSERT(instr->left()->representation().Equals(instr->representation()));
ASSERT(instr->right()->representation().Equals(instr->representation()));
if (instr->HasPowerOf2Divisor()) {
if (instr->RightIsPowerOf2()) {
ASSERT(!right->CanBeZero());
LModI* mod = new(zone()) LModI(UseRegisterAtStart(left),
UseConstant(right));

View File

@ -654,6 +654,8 @@ class LDivI V8_FINAL : public LTemplateInstruction<1, 2, 1> {
LOperand* right() { return inputs_[1]; }
LOperand* temp() { return temps_[0]; }
bool is_flooring() { return hydrogen_value()->IsMathFloorOfDiv(); }
DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
DECLARE_HYDROGEN_ACCESSOR(Div)
};
@ -2695,7 +2697,6 @@ class LChunkBuilder V8_FINAL : public LChunkBuilderBase {
LInstruction* DoRSub(HSub* instr);
static bool HasMagicNumberForDivisor(int32_t divisor);
static HValue* SimplifiedDivisorForMathFloorOfDiv(HValue* val);
LInstruction* DoMathFloor(HUnaryMathOperation* instr);
LInstruction* DoMathRound(HUnaryMathOperation* instr);

View File

@ -1115,7 +1115,7 @@ void LCodeGen::DoModI(LModI* instr) {
HMod* hmod = instr->hydrogen();
HValue* left = hmod->left();
HValue* right = hmod->right();
if (hmod->HasPowerOf2Divisor()) {
if (hmod->RightIsPowerOf2()) {
// TODO(svenpanne) We should really do the strength reduction on the
// Hydrogen level.
Register left_reg = ToRegister(instr->left());
@ -1345,7 +1345,7 @@ void LCodeGen::EmitSignedIntegerDivisionByConstant(
void LCodeGen::DoDivI(LDivI* instr) {
if (instr->hydrogen()->HasPowerOf2Divisor()) {
if (!instr->is_flooring() && instr->hydrogen()->RightIsPowerOf2()) {
const Register dividend = ToRegister(instr->left());
const Register result = ToRegister(instr->result());
int32_t divisor = instr->hydrogen()->right()->GetInteger32Constant();
@ -1402,15 +1402,15 @@ void LCodeGen::DoDivI(LDivI* instr) {
const Register result = ToRegister(instr->result());
// Check for x / 0.
if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
if (instr->hydrogen_value()->CheckFlag(HValue::kCanBeDivByZero)) {
__ cmp(right, Operand::Zero());
DeoptimizeIf(eq, instr->environment());
}
// Check for (0 / -x) that will produce negative zero.
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
if (instr->hydrogen_value()->CheckFlag(HValue::kBailoutOnMinusZero)) {
Label positive;
if (!instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
if (!instr->hydrogen_value()->CheckFlag(HValue::kCanBeDivByZero)) {
// Do the test only if it hadn't be done above.
__ cmp(right, Operand::Zero());
}
@ -1421,9 +1421,10 @@ void LCodeGen::DoDivI(LDivI* instr) {
}
// Check for (kMinInt / -1).
if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow) &&
if (instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow) &&
(!CpuFeatures::IsSupported(SUDIV) ||
!instr->hydrogen()->CheckFlag(HValue::kAllUsesTruncatingToInt32))) {
!instr->hydrogen_value()->CheckFlag(
HValue::kAllUsesTruncatingToInt32))) {
// We don't need to check for overflow when truncating with sdiv
// support because, on ARM, sdiv kMinInt, -1 -> kMinInt.
__ cmp(left, Operand(kMinInt));
@ -1435,7 +1436,7 @@ void LCodeGen::DoDivI(LDivI* instr) {
CpuFeatureScope scope(masm(), SUDIV);
__ sdiv(result, left, right);
if (!instr->hydrogen()->CheckFlag(
if (!instr->hydrogen_value()->CheckFlag(
HInstruction::kAllUsesTruncatingToInt32)) {
// Compute remainder and deopt if it's not zero.
const Register remainder = scratch0();
@ -1454,7 +1455,7 @@ void LCodeGen::DoDivI(LDivI* instr) {
__ vcvt_s32_f64(double_scratch0().low(), vleft);
__ vmov(result, double_scratch0().low());
if (!instr->hydrogen()->CheckFlag(
if (!instr->hydrogen_value()->CheckFlag(
HInstruction::kAllUsesTruncatingToInt32)) {
// Deopt if exact conversion to integer was not possible.
// Use vright as scratch register.

View File

@ -1408,81 +1408,51 @@ void HChange::PrintDataTo(StringStream* stream) {
}
static HValue* SimplifiedDividendForMathFloorOfDiv(HValue* dividend) {
// A value with an integer representation does not need to be transformed.
if (dividend->representation().IsInteger32()) {
return dividend;
}
// A change from an integer32 can be replaced by the integer32 value.
if (dividend->IsChange() &&
HChange::cast(dividend)->from().IsInteger32()) {
return HChange::cast(dividend)->value();
}
return NULL;
}
HValue* HUnaryMathOperation::Canonicalize() {
if (op() == kMathRound || op() == kMathFloor) {
HValue* val = value();
if (val->IsChange()) val = HChange::cast(val)->value();
// If the input is smi or integer32 then we replace the instruction with its
// input.
if (val->representation().IsSmiOrInteger32()) {
if (!val->representation().Equals(representation())) {
HChange* result = new(block()->zone()) HChange(
val, representation(), false, false);
result->InsertBefore(this);
return result;
}
return val;
if (val->representation().Equals(representation())) return val;
return Prepend(new(block()->zone()) HChange(
val, representation(), false, false));
}
}
if (op() == kMathFloor && value()->IsDiv() && value()->UseCount() == 1) {
HDiv* hdiv = HDiv::cast(value());
if (op() == kMathFloor) {
HValue* val = value();
if (val->IsDiv() && (val->UseCount() == 1)) {
HDiv* hdiv = HDiv::cast(val);
HValue* left = hdiv->left();
HValue* right = hdiv->right();
// Try to simplify left and right values of the division.
HValue* new_left = SimplifiedDividendForMathFloorOfDiv(left);
if (new_left == NULL &&
hdiv->observed_input_representation(1).IsSmiOrInteger32()) {
new_left = new(block()->zone()) HChange(
left, Representation::Integer32(), false, false);
HChange::cast(new_left)->InsertBefore(this);
}
HValue* new_right =
LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(right);
if (new_right == NULL &&
#if V8_TARGET_ARCH_ARM
CpuFeatures::IsSupported(SUDIV) &&
#endif
hdiv->observed_input_representation(2).IsSmiOrInteger32()) {
new_right = new(block()->zone()) HChange(
right, Representation::Integer32(), false, false);
HChange::cast(new_right)->InsertBefore(this);
}
// Return if left or right are not optimizable.
if ((new_left == NULL) || (new_right == NULL)) return this;
// Insert the new values in the graph.
if (new_left->IsInstruction() &&
!HInstruction::cast(new_left)->IsLinked()) {
HInstruction::cast(new_left)->InsertBefore(this);
}
if (new_right->IsInstruction() &&
!HInstruction::cast(new_right)->IsLinked()) {
HInstruction::cast(new_right)->InsertBefore(this);
}
HMathFloorOfDiv* instr =
HMathFloorOfDiv::New(block()->zone(), context(), new_left, new_right);
instr->InsertBefore(this);
return instr;
HValue* left = hdiv->left();
if (left->representation().IsInteger32()) {
// A value with an integer representation does not need to be transformed.
} else if (left->IsChange() && HChange::cast(left)->from().IsInteger32()) {
// 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));
} else {
return this;
}
HValue* right = hdiv->right();
if (right->IsInteger32Constant()) {
right = Prepend(HConstant::cast(right)->CopyToRepresentation(
Representation::Integer32(), right->block()->zone()));
} else if (right->representation().IsInteger32()) {
// A value with an integer representation does not need to be transformed.
} else if (right->IsChange() &&
HChange::cast(right)->from().IsInteger32()) {
// 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));
} else {
return this;
}
return Prepend(HMathFloorOfDiv::New(
block()->zone(), context(), left, right));
}
return this;
}
@ -3226,10 +3196,8 @@ HValue* HLoadKeyedGeneric::Canonicalize() {
key_load->elements_kind());
map_check->InsertBefore(this);
index->InsertBefore(this);
HLoadFieldByIndex* load = new(block()->zone()) HLoadFieldByIndex(
object(), index);
load->InsertBefore(this);
return load;
return Prepend(new(block()->zone()) HLoadFieldByIndex(
object(), index));
}
}
}

View File

@ -46,6 +46,7 @@ namespace internal {
// Forward declarations.
class HBasicBlock;
class HDiv;
class HEnvironment;
class HInferRepresentationPhase;
class HInstruction;
@ -1207,9 +1208,21 @@ class HInstruction : public HValue {
bool IsLinked() const { return block() != NULL; }
void Unlink();
void InsertBefore(HInstruction* next);
template<class T> T* Prepend(T* instr) {
instr->InsertBefore(this);
return instr;
}
void InsertAfter(HInstruction* previous);
template<class T> T* Append(T* instr) {
instr->InsertAfter(this);
return instr;
}
// The position is a write-once variable.
virtual int position() const V8_OVERRIDE {
return position_.position();
@ -2706,6 +2719,9 @@ class HUnaryMathOperation V8_FINAL : public HTemplateInstruction<2> {
virtual bool IsDeletable() const V8_OVERRIDE { return true; }
HValue* SimplifiedDividendForMathFloorOfDiv(HDiv* hdiv);
HValue* SimplifiedDivisorForMathFloorOfDiv(HDiv* hdiv);
BuiltinFunctionId op_;
};
@ -3476,10 +3492,8 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> {
int32_t value,
Representation representation,
HInstruction* instruction) {
HConstant* new_constant =
HConstant::New(zone, context, value, representation);
new_constant->InsertAfter(instruction);
return new_constant;
return instruction->Append(HConstant::New(
zone, context, value, representation));
}
static HConstant* CreateAndInsertBefore(Zone* zone,
@ -3487,21 +3501,17 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> {
int32_t value,
Representation representation,
HInstruction* instruction) {
HConstant* new_constant =
HConstant::New(zone, context, value, representation);
new_constant->InsertBefore(instruction);
return new_constant;
return instruction->Prepend(HConstant::New(
zone, context, value, representation));
}
static HConstant* CreateAndInsertBefore(Zone* zone,
Unique<Object> unique,
bool is_not_in_new_space,
HInstruction* instruction) {
HConstant* new_constant = new(zone) HConstant(unique,
Representation::Tagged(), HType::Tagged(), false, is_not_in_new_space,
false, false);
new_constant->InsertBefore(instruction);
return new_constant;
return instruction->Prepend(new(zone) HConstant(
unique, Representation::Tagged(), HType::Tagged(), false,
is_not_in_new_space, false, false));
}
Handle<Object> handle(Isolate* isolate) {
@ -4188,7 +4198,14 @@ class HArithmeticBinaryOperation : public HBinaryOperation {
}
}
bool RightIsPowerOf2() {
if (!right()->IsInteger32Constant()) return false;
int32_t value = right()->GetInteger32Constant();
return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
}
DECLARE_ABSTRACT_INSTRUCTION(ArithmeticBinaryOperation)
private:
virtual bool IsDeletable() const V8_OVERRIDE { return true; }
};
@ -4887,16 +4904,6 @@ class HMod V8_FINAL : public HArithmeticBinaryOperation {
HValue* left,
HValue* right);
bool HasPowerOf2Divisor() {
if (right()->IsConstant() &&
HConstant::cast(right())->HasInteger32Value()) {
int32_t value = HConstant::cast(right())->Integer32Value();
return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
}
return false;
}
virtual HValue* EnsureAndPropagateNotMinusZero(
BitVector* visited) V8_OVERRIDE;
@ -4933,15 +4940,6 @@ class HDiv V8_FINAL : public HArithmeticBinaryOperation {
HValue* left,
HValue* right);
bool HasPowerOf2Divisor() {
if (right()->IsInteger32Constant()) {
int32_t value = right()->GetInteger32Constant();
return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
}
return false;
}
virtual HValue* EnsureAndPropagateNotMinusZero(
BitVector* visited) V8_OVERRIDE;

View File

@ -1372,7 +1372,7 @@ void LCodeGen::DoModI(LModI* instr) {
HMod* hmod = instr->hydrogen();
HValue* left = hmod->left();
HValue* right = hmod->right();
if (hmod->HasPowerOf2Divisor()) {
if (hmod->RightIsPowerOf2()) {
// TODO(svenpanne) We should really do the strength reduction on the
// Hydrogen level.
Register left_reg = ToRegister(instr->left());
@ -1454,7 +1454,7 @@ void LCodeGen::DoModI(LModI* instr) {
void LCodeGen::DoDivI(LDivI* instr) {
if (!instr->is_flooring() && instr->hydrogen()->HasPowerOf2Divisor()) {
if (!instr->is_flooring() && instr->hydrogen()->RightIsPowerOf2()) {
Register dividend = ToRegister(instr->left());
int32_t divisor = instr->hydrogen()->right()->GetInteger32Constant();
int32_t test_value = 0;

View File

@ -1332,7 +1332,7 @@ LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
if (instr->representation().IsSmiOrInteger32()) {
ASSERT(instr->left()->representation().Equals(instr->representation()));
ASSERT(instr->right()->representation().Equals(instr->representation()));
if (instr->HasPowerOf2Divisor()) {
if (instr->RightIsPowerOf2()) {
ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero));
LOperand* value = UseRegisterAtStart(instr->left());
LDivI* div =
@ -1354,25 +1354,6 @@ LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
}
HValue* LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(HValue* divisor) {
if (divisor->IsConstant() &&
HConstant::cast(divisor)->HasInteger32Value()) {
HConstant* constant_val = HConstant::cast(divisor);
return constant_val->CopyToRepresentation(Representation::Integer32(),
divisor->block()->zone());
}
// A value with an integer representation does not need to be transformed.
if (divisor->representation().IsInteger32()) {
return divisor;
// A change from an integer32 can be replaced by the integer32 value.
} else if (divisor->IsChange() &&
HChange::cast(divisor)->from().IsInteger32()) {
return HChange::cast(divisor)->value();
}
return NULL;
}
LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
HValue* right = instr->right();
if (!right->IsConstant()) {
@ -1418,7 +1399,7 @@ LInstruction* LChunkBuilder::DoMod(HMod* instr) {
ASSERT(instr->left()->representation().Equals(instr->representation()));
ASSERT(instr->right()->representation().Equals(instr->representation()));
if (instr->HasPowerOf2Divisor()) {
if (instr->RightIsPowerOf2()) {
ASSERT(!right->CanBeZero());
LModI* mod = new(zone()) LModI(UseRegisterAtStart(left),
UseOrConstant(right),

View File

@ -2703,8 +2703,6 @@ class LChunkBuilder V8_FINAL : public LChunkBuilderBase {
HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
#undef DECLARE_DO
static HValue* SimplifiedDivisorForMathFloorOfDiv(HValue* val);
LInstruction* DoMathFloor(HUnaryMathOperation* instr);
LInstruction* DoMathRound(HUnaryMathOperation* instr);
LInstruction* DoMathAbs(HUnaryMathOperation* instr);

View File

@ -1066,7 +1066,7 @@ void LCodeGen::DoModI(LModI* instr) {
HMod* hmod = instr->hydrogen();
HValue* left = hmod->left();
HValue* right = hmod->right();
if (hmod->HasPowerOf2Divisor()) {
if (hmod->RightIsPowerOf2()) {
const Register left_reg = ToRegister(instr->left());
const Register result_reg = ToRegister(instr->result());

View File

@ -1295,20 +1295,6 @@ bool LChunkBuilder::HasMagicNumberForDivisor(int32_t divisor) {
}
HValue* LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(HValue* divisor) {
// Only optimize when we have magic numbers for the divisor.
// The standard integer division routine is usually slower than transitionning
// to FPU.
if (divisor->IsConstant() &&
HConstant::cast(divisor)->HasInteger32Value()) {
HConstant* constant_val = HConstant::cast(divisor);
return constant_val->CopyToRepresentation(Representation::Integer32(),
divisor->block()->zone());
}
return NULL;
}
LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
HValue* right = instr->right();
LOperand* dividend = UseRegister(instr->left());
@ -1325,7 +1311,7 @@ LInstruction* LChunkBuilder::DoMod(HMod* instr) {
if (instr->representation().IsSmiOrInteger32()) {
ASSERT(instr->left()->representation().Equals(instr->representation()));
ASSERT(instr->right()->representation().Equals(instr->representation()));
if (instr->HasPowerOf2Divisor()) {
if (instr->RightIsPowerOf2()) {
ASSERT(!right->CanBeZero());
LModI* mod = new(zone()) LModI(UseRegisterAtStart(left),
UseConstant(right));

View File

@ -2669,7 +2669,6 @@ class LChunkBuilder V8_FINAL : public LChunkBuilderBase {
LInstruction* DoMultiplyAdd(HMul* mul, HValue* addend);
static bool HasMagicNumberForDivisor(int32_t divisor);
static HValue* SimplifiedDivisorForMathFloorOfDiv(HValue* val);
LInstruction* DoMathFloor(HUnaryMathOperation* instr);
LInstruction* DoMathRound(HUnaryMathOperation* instr);

View File

@ -987,7 +987,7 @@ void LCodeGen::DoModI(LModI* instr) {
HMod* hmod = instr->hydrogen();
HValue* left = hmod->left();
HValue* right = hmod->right();
if (hmod->HasPowerOf2Divisor()) {
if (hmod->RightIsPowerOf2()) {
// TODO(svenpanne) We should really do the strength reduction on the
// Hydrogen level.
Register left_reg = ToRegister(instr->left());
@ -1153,7 +1153,7 @@ void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) {
void LCodeGen::DoDivI(LDivI* instr) {
if (!instr->is_flooring() && instr->hydrogen()->HasPowerOf2Divisor()) {
if (!instr->is_flooring() && instr->hydrogen()->RightIsPowerOf2()) {
Register dividend = ToRegister(instr->left());
int32_t divisor =
HConstant::cast(instr->hydrogen()->right())->Integer32Value();

View File

@ -1253,7 +1253,7 @@ LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
if (instr->representation().IsSmiOrInteger32()) {
ASSERT(instr->left()->representation().Equals(instr->representation()));
ASSERT(instr->right()->representation().Equals(instr->representation()));
if (instr->HasPowerOf2Divisor()) {
if (instr->RightIsPowerOf2()) {
ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero));
LOperand* value = UseRegisterAtStart(instr->left());
LDivI* div =
@ -1275,25 +1275,6 @@ LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
}
HValue* LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(HValue* divisor) {
if (divisor->IsConstant() &&
HConstant::cast(divisor)->HasInteger32Value()) {
HConstant* constant_val = HConstant::cast(divisor);
return constant_val->CopyToRepresentation(Representation::Integer32(),
divisor->block()->zone());
}
// A value with an integer representation does not need to be transformed.
if (divisor->representation().IsInteger32()) {
return divisor;
// A change from an integer32 can be replaced by the integer32 value.
} else if (divisor->IsChange() &&
HChange::cast(divisor)->from().IsInteger32()) {
return HChange::cast(divisor)->value();
}
return NULL;
}
LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
HValue* right = instr->right();
if (!right->IsConstant()) {
@ -1336,7 +1317,7 @@ LInstruction* LChunkBuilder::DoMod(HMod* instr) {
if (instr->representation().IsSmiOrInteger32()) {
ASSERT(left->representation().Equals(instr->representation()));
ASSERT(right->representation().Equals(instr->representation()));
if (instr->HasPowerOf2Divisor()) {
if (instr->RightIsPowerOf2()) {
ASSERT(!right->CanBeZero());
LModI* mod = new(zone()) LModI(UseRegisterAtStart(left),
UseOrConstant(right),

View File

@ -2618,8 +2618,6 @@ class LChunkBuilder V8_FINAL : public LChunkBuilderBase {
HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
#undef DECLARE_DO
static HValue* SimplifiedDivisorForMathFloorOfDiv(HValue* val);
LInstruction* DoMathFloor(HUnaryMathOperation* instr);
LInstruction* DoMathRound(HUnaryMathOperation* instr);
LInstruction* DoMathAbs(HUnaryMathOperation* instr);