Remove the first_right_arg hack for HMod.
Generate a proper subgraph in BuildBinaryOperation instead. R=svenpanne@chromium.org Review URL: https://codereview.chromium.org/77053003 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17919 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
8f88467bf6
commit
d38abc3bba
@ -1483,10 +1483,6 @@ LInstruction* LChunkBuilder::DoMod(HMod* instr) {
|
|||||||
instr->CheckFlag(HValue::kBailoutOnMinusZero))
|
instr->CheckFlag(HValue::kBailoutOnMinusZero))
|
||||||
? AssignEnvironment(result)
|
? AssignEnvironment(result)
|
||||||
: result;
|
: result;
|
||||||
} else if (instr->fixed_right_arg().has_value) {
|
|
||||||
LModI* mod = new(zone()) LModI(UseRegisterAtStart(left),
|
|
||||||
UseRegisterAtStart(right));
|
|
||||||
return AssignEnvironment(DefineAsRegister(mod));
|
|
||||||
} else if (CpuFeatures::IsSupported(SUDIV)) {
|
} else if (CpuFeatures::IsSupported(SUDIV)) {
|
||||||
LModI* mod = new(zone()) LModI(UseRegister(left),
|
LModI* mod = new(zone()) LModI(UseRegister(left),
|
||||||
UseRegister(right));
|
UseRegister(right));
|
||||||
|
@ -1133,36 +1133,6 @@ void LCodeGen::DoModI(LModI* instr) {
|
|||||||
__ bind(&left_is_not_negative);
|
__ bind(&left_is_not_negative);
|
||||||
__ and_(result_reg, left_reg, Operand(divisor - 1));
|
__ and_(result_reg, left_reg, Operand(divisor - 1));
|
||||||
__ bind(&done);
|
__ bind(&done);
|
||||||
|
|
||||||
} else if (hmod->fixed_right_arg().has_value) {
|
|
||||||
Register left_reg = ToRegister(instr->left());
|
|
||||||
Register right_reg = ToRegister(instr->right());
|
|
||||||
Register result_reg = ToRegister(instr->result());
|
|
||||||
|
|
||||||
int32_t divisor = hmod->fixed_right_arg().value;
|
|
||||||
ASSERT(IsPowerOf2(divisor));
|
|
||||||
|
|
||||||
// Check if our assumption of a fixed right operand still holds.
|
|
||||||
__ cmp(right_reg, Operand(divisor));
|
|
||||||
DeoptimizeIf(ne, instr->environment());
|
|
||||||
|
|
||||||
Label left_is_not_negative, done;
|
|
||||||
if (left->CanBeNegative()) {
|
|
||||||
__ cmp(left_reg, Operand::Zero());
|
|
||||||
__ b(pl, &left_is_not_negative);
|
|
||||||
__ rsb(result_reg, left_reg, Operand::Zero());
|
|
||||||
__ and_(result_reg, result_reg, Operand(divisor - 1));
|
|
||||||
__ rsb(result_reg, result_reg, Operand::Zero(), SetCC);
|
|
||||||
if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
|
||||||
DeoptimizeIf(eq, instr->environment());
|
|
||||||
}
|
|
||||||
__ b(&done);
|
|
||||||
}
|
|
||||||
|
|
||||||
__ bind(&left_is_not_negative);
|
|
||||||
__ and_(result_reg, left_reg, Operand(divisor - 1));
|
|
||||||
__ bind(&done);
|
|
||||||
|
|
||||||
} else if (CpuFeatures::IsSupported(SUDIV)) {
|
} else if (CpuFeatures::IsSupported(SUDIV)) {
|
||||||
CpuFeatureScope scope(masm(), SUDIV);
|
CpuFeatureScope scope(masm(), SUDIV);
|
||||||
|
|
||||||
|
@ -3930,8 +3930,7 @@ HInstruction* HMathMinMax::New(
|
|||||||
HInstruction* HMod::New(Zone* zone,
|
HInstruction* HMod::New(Zone* zone,
|
||||||
HValue* context,
|
HValue* context,
|
||||||
HValue* left,
|
HValue* left,
|
||||||
HValue* right,
|
HValue* right) {
|
||||||
Maybe<int> fixed_right_arg) {
|
|
||||||
if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) {
|
if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) {
|
||||||
HConstant* c_left = HConstant::cast(left);
|
HConstant* c_left = HConstant::cast(left);
|
||||||
HConstant* c_right = HConstant::cast(right);
|
HConstant* c_right = HConstant::cast(right);
|
||||||
@ -3950,7 +3949,7 @@ HInstruction* HMod::New(Zone* zone,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new(zone) HMod(context, left, right, fixed_right_arg);
|
return new(zone) HMod(context, left, right);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4901,10 +4901,7 @@ class HMod V8_FINAL : public HArithmeticBinaryOperation {
|
|||||||
static HInstruction* New(Zone* zone,
|
static HInstruction* New(Zone* zone,
|
||||||
HValue* context,
|
HValue* context,
|
||||||
HValue* left,
|
HValue* left,
|
||||||
HValue* right,
|
HValue* right);
|
||||||
Maybe<int> fixed_right_arg);
|
|
||||||
|
|
||||||
Maybe<int> fixed_right_arg() const { return fixed_right_arg_; }
|
|
||||||
|
|
||||||
bool HasPowerOf2Divisor() {
|
bool HasPowerOf2Divisor() {
|
||||||
if (right()->IsConstant() &&
|
if (right()->IsConstant() &&
|
||||||
@ -4938,15 +4935,10 @@ class HMod V8_FINAL : public HArithmeticBinaryOperation {
|
|||||||
private:
|
private:
|
||||||
HMod(HValue* context,
|
HMod(HValue* context,
|
||||||
HValue* left,
|
HValue* left,
|
||||||
HValue* right,
|
HValue* right) : HArithmeticBinaryOperation(context, left, right) {
|
||||||
Maybe<int> fixed_right_arg)
|
|
||||||
: HArithmeticBinaryOperation(context, left, right),
|
|
||||||
fixed_right_arg_(fixed_right_arg) {
|
|
||||||
SetFlag(kCanBeDivByZero);
|
SetFlag(kCanBeDivByZero);
|
||||||
SetFlag(kCanOverflow);
|
SetFlag(kCanOverflow);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Maybe<int> fixed_right_arg_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -8724,9 +8724,24 @@ HValue* HGraphBuilder::BuildBinaryOperation(
|
|||||||
case Token::MUL:
|
case Token::MUL:
|
||||||
instr = AddUncasted<HMul>(left, right);
|
instr = AddUncasted<HMul>(left, right);
|
||||||
break;
|
break;
|
||||||
case Token::MOD:
|
case Token::MOD: {
|
||||||
instr = AddUncasted<HMod>(left, right, fixed_right_arg);
|
if (fixed_right_arg.has_value) {
|
||||||
|
if (right->IsConstant()) {
|
||||||
|
ASSERT_EQ(fixed_right_arg.value,
|
||||||
|
HConstant::cast(right)->Integer32Value());
|
||||||
|
} else {
|
||||||
|
HConstant* fixed_right = Add<HConstant>(
|
||||||
|
static_cast<int>(fixed_right_arg.value));
|
||||||
|
IfBuilder if_same(this);
|
||||||
|
if_same.If<HCompareNumericAndBranch>(right, fixed_right, Token::EQ);
|
||||||
|
if_same.Then();
|
||||||
|
if_same.ElseDeopt("Unexpected RHS of binary operation");
|
||||||
|
right = fixed_right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
instr = AddUncasted<HMod>(left, right);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case Token::DIV:
|
case Token::DIV:
|
||||||
instr = AddUncasted<HDiv>(left, right);
|
instr = AddUncasted<HDiv>(left, right);
|
||||||
break;
|
break;
|
||||||
|
@ -1399,36 +1399,6 @@ void LCodeGen::DoModI(LModI* instr) {
|
|||||||
__ bind(&left_is_not_negative);
|
__ bind(&left_is_not_negative);
|
||||||
__ and_(left_reg, divisor - 1);
|
__ and_(left_reg, divisor - 1);
|
||||||
__ bind(&done);
|
__ bind(&done);
|
||||||
|
|
||||||
} else if (hmod->fixed_right_arg().has_value) {
|
|
||||||
Register left_reg = ToRegister(instr->left());
|
|
||||||
ASSERT(left_reg.is(ToRegister(instr->result())));
|
|
||||||
Register right_reg = ToRegister(instr->right());
|
|
||||||
|
|
||||||
int32_t divisor = hmod->fixed_right_arg().value;
|
|
||||||
ASSERT(IsPowerOf2(divisor));
|
|
||||||
|
|
||||||
// Check if our assumption of a fixed right operand still holds.
|
|
||||||
__ cmp(right_reg, Immediate(divisor));
|
|
||||||
DeoptimizeIf(not_equal, instr->environment());
|
|
||||||
|
|
||||||
Label left_is_not_negative, done;
|
|
||||||
if (left->CanBeNegative()) {
|
|
||||||
__ test(left_reg, Operand(left_reg));
|
|
||||||
__ j(not_sign, &left_is_not_negative, Label::kNear);
|
|
||||||
__ neg(left_reg);
|
|
||||||
__ and_(left_reg, divisor - 1);
|
|
||||||
__ neg(left_reg);
|
|
||||||
if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
|
||||||
DeoptimizeIf(zero, instr->environment());
|
|
||||||
}
|
|
||||||
__ jmp(&done, Label::kNear);
|
|
||||||
}
|
|
||||||
|
|
||||||
__ bind(&left_is_not_negative);
|
|
||||||
__ and_(left_reg, divisor - 1);
|
|
||||||
__ bind(&done);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Register left_reg = ToRegister(instr->left());
|
Register left_reg = ToRegister(instr->left());
|
||||||
ASSERT(left_reg.is(eax));
|
ASSERT(left_reg.is(eax));
|
||||||
|
@ -1558,10 +1558,6 @@ LInstruction* LChunkBuilder::DoMod(HMod* instr) {
|
|||||||
instr->CheckFlag(HValue::kBailoutOnMinusZero))
|
instr->CheckFlag(HValue::kBailoutOnMinusZero))
|
||||||
? AssignEnvironment(result)
|
? AssignEnvironment(result)
|
||||||
: result;
|
: result;
|
||||||
} else if (instr->fixed_right_arg().has_value) {
|
|
||||||
LModI* mod = new(zone()) LModI(UseRegister(left),
|
|
||||||
UseRegisterAtStart(right),
|
|
||||||
NULL);
|
|
||||||
return AssignEnvironment(DefineSameAsFirst(mod));
|
return AssignEnvironment(DefineSameAsFirst(mod));
|
||||||
} else {
|
} else {
|
||||||
// The temporary operand is necessary to ensure that right is not
|
// The temporary operand is necessary to ensure that right is not
|
||||||
|
@ -1013,36 +1013,6 @@ void LCodeGen::DoModI(LModI* instr) {
|
|||||||
__ bind(&left_is_not_negative);
|
__ bind(&left_is_not_negative);
|
||||||
__ andl(left_reg, Immediate(divisor - 1));
|
__ andl(left_reg, Immediate(divisor - 1));
|
||||||
__ bind(&done);
|
__ bind(&done);
|
||||||
|
|
||||||
} else if (hmod->fixed_right_arg().has_value) {
|
|
||||||
Register left_reg = ToRegister(instr->left());
|
|
||||||
ASSERT(left_reg.is(ToRegister(instr->result())));
|
|
||||||
Register right_reg = ToRegister(instr->right());
|
|
||||||
|
|
||||||
int32_t divisor = hmod->fixed_right_arg().value;
|
|
||||||
ASSERT(IsPowerOf2(divisor));
|
|
||||||
|
|
||||||
// Check if our assumption of a fixed right operand still holds.
|
|
||||||
__ cmpl(right_reg, Immediate(divisor));
|
|
||||||
DeoptimizeIf(not_equal, instr->environment());
|
|
||||||
|
|
||||||
Label left_is_not_negative, done;
|
|
||||||
if (left->CanBeNegative()) {
|
|
||||||
__ testl(left_reg, left_reg);
|
|
||||||
__ j(not_sign, &left_is_not_negative, Label::kNear);
|
|
||||||
__ negl(left_reg);
|
|
||||||
__ andl(left_reg, Immediate(divisor - 1));
|
|
||||||
__ negl(left_reg);
|
|
||||||
if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
|
||||||
DeoptimizeIf(zero, instr->environment());
|
|
||||||
}
|
|
||||||
__ jmp(&done, Label::kNear);
|
|
||||||
}
|
|
||||||
|
|
||||||
__ bind(&left_is_not_negative);
|
|
||||||
__ andl(left_reg, Immediate(divisor - 1));
|
|
||||||
__ bind(&done);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Register left_reg = ToRegister(instr->left());
|
Register left_reg = ToRegister(instr->left());
|
||||||
ASSERT(left_reg.is(rax));
|
ASSERT(left_reg.is(rax));
|
||||||
|
@ -1469,11 +1469,6 @@ LInstruction* LChunkBuilder::DoMod(HMod* instr) {
|
|||||||
instr->CheckFlag(HValue::kBailoutOnMinusZero))
|
instr->CheckFlag(HValue::kBailoutOnMinusZero))
|
||||||
? AssignEnvironment(result)
|
? AssignEnvironment(result)
|
||||||
: result;
|
: result;
|
||||||
} else if (instr->fixed_right_arg().has_value) {
|
|
||||||
LModI* mod = new(zone()) LModI(UseRegister(left),
|
|
||||||
UseRegisterAtStart(right),
|
|
||||||
NULL);
|
|
||||||
return AssignEnvironment(DefineSameAsFirst(mod));
|
|
||||||
} else {
|
} else {
|
||||||
// The temporary operand is necessary to ensure that right is not
|
// The temporary operand is necessary to ensure that right is not
|
||||||
// allocated into edx.
|
// allocated into edx.
|
||||||
|
Loading…
Reference in New Issue
Block a user