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:
parent
c86da7e5dc
commit
13395a8392
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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),
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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),
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user