| Index: src/hydrogen-instructions.cc
|
| diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
|
| index b36706b49b48119b6332a54e6782a9904e929ee5..1ae4f90b88132d28b16e5746b657c8add43f322f 100644
|
| --- a/src/hydrogen-instructions.cc
|
| +++ b/src/hydrogen-instructions.cc
|
| @@ -1511,30 +1511,52 @@ void HChange::PrintDataTo(StringStream* stream) {
|
| }
|
|
|
|
|
| +static HValue* SimplifiedDividendForMathFloorOfDiv(
|
| + HValue* dividend,
|
| + Representation observed_representation) {
|
| + // 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();
|
| + }
|
| + // If we've only seen integers so far, insert an appropriate change.
|
| + if (observed_representation.IsSmiOrInteger32()) {
|
| + return new(dividend->block()->zone())
|
| + HChange(dividend, Representation::Integer32(), false, false);
|
| + }
|
| + return NULL;
|
| +}
|
| +
|
| +
|
| HValue* HUnaryMathOperation::Canonicalize() {
|
| if (op() == kMathFloor) {
|
| - // If the input is integer32 then we replace the floor instruction
|
| - // with its input. This happens before the representation changes are
|
| - // introduced.
|
| -
|
| - // TODO(2205): The above comment is lying. All of this happens
|
| - // *after* representation changes are introduced. We should check
|
| - // for value->IsChange() and react accordingly if yes.
|
| + HValue* val = value();
|
| + if (val->IsChange()) val = HChange::cast(val)->value();
|
|
|
| - if (value()->representation().IsInteger32()) return value();
|
| + // If the input is integer32 then we replace the floor instruction
|
| + // with its input.
|
| + if (val->representation().IsInteger32()) return val;
|
|
|
| #if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_IA32) || \
|
| defined(V8_TARGET_ARCH_X64)
|
| - if (value()->IsDiv() && (value()->UseCount() == 1)) {
|
| - // TODO(2038): Implement this optimization for non ARM architectures.
|
| - HDiv* hdiv = HDiv::cast(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 =
|
| - LChunkBuilder::SimplifiedDividendForMathFloorOfDiv(left);
|
| + HValue* new_left = SimplifiedDividendForMathFloorOfDiv(
|
| + left, hdiv->observed_input_representation(1));
|
| HValue* new_right =
|
| - LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(right);
|
| + LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(right);
|
| + if (new_right == NULL &&
|
| + hdiv->observed_input_representation(2).IsSmiOrInteger32()) {
|
| + new_right = new(block()->zone())
|
| + HChange(right, Representation::Integer32(), false, false);
|
| + }
|
|
|
| // Return if left or right are not optimizable.
|
| if ((new_left == NULL) || (new_right == NULL)) return this;
|
| @@ -1548,9 +1570,8 @@ HValue* HUnaryMathOperation::Canonicalize() {
|
| !HInstruction::cast(new_right)->IsLinked()) {
|
| HInstruction::cast(new_right)->InsertBefore(this);
|
| }
|
| - HMathFloorOfDiv* instr = new(block()->zone()) HMathFloorOfDiv(context(),
|
| - new_left,
|
| - new_right);
|
| + HMathFloorOfDiv* instr = new(block()->zone())
|
| + HMathFloorOfDiv(context(), new_left, new_right);
|
| // Replace this HMathFloor instruction by the new HMathFloorOfDiv.
|
| instr->InsertBefore(this);
|
| ReplaceAllUsesWith(instr);
|
|
|