Reviewers: Jakob,
Message:
Still incomplete (collecting the right thing on ia32 only), just to see if
things are going into the right direction...
Description:
Improve integer div/mod with constant right operands.
Please review this at https://chromiumcodereview.appspot.com/15735005/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/code-stubs.h
M src/ia32/code-stubs-ia32.cc
M src/ic.cc
Index: src/code-stubs.h
diff --git a/src/code-stubs.h b/src/code-stubs.h
index
aa6a4101951f3d762df2659d2ae870a677a91cc7..2d59c9eba4cf5d61d41a69e2f825cf2cd8ac3ef7
100644
--- a/src/code-stubs.h
+++ b/src/code-stubs.h
@@ -870,7 +870,9 @@ class BinaryOpStub: public PlatformCodeStub {
platform_specific_bit_(false),
left_type_(BinaryOpIC::UNINITIALIZED),
right_type_(BinaryOpIC::UNINITIALIZED),
- result_type_(BinaryOpIC::UNINITIALIZED) {
+ result_type_(BinaryOpIC::UNINITIALIZED),
+ has_fixed_right_arg_(false),
+ encoded_right_arg_(encode_arg_value(1)) {
Initialize();
ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
}
@@ -879,13 +881,17 @@ class BinaryOpStub: public PlatformCodeStub {
int key,
BinaryOpIC::TypeInfo left_type,
BinaryOpIC::TypeInfo right_type,
- BinaryOpIC::TypeInfo result_type = BinaryOpIC::UNINITIALIZED)
+ BinaryOpIC::TypeInfo result_type,
+ bool has_fixed_right_arg,
+ int fixed_right_arg_value)
: op_(OpBits::decode(key)),
mode_(ModeBits::decode(key)),
platform_specific_bit_(PlatformSpecificBits::decode(key)),
left_type_(left_type),
right_type_(right_type),
- result_type_(result_type) { }
+ result_type_(result_type),
+ has_fixed_right_arg_(has_fixed_right_arg),
+ encoded_right_arg_(encode_arg_value(fixed_right_arg_value)) { }
static void decode_types_from_minor_key(int minor_key,
BinaryOpIC::TypeInfo* left_type,
@@ -903,6 +909,24 @@ class BinaryOpStub: public PlatformCodeStub {
return static_cast<Token::Value>(OpBits::decode(minor_key));
}
+ static bool decode_has_fixed_right_arg_from_minor_key(int minor_key) {
+ return HasFixedRightArgBits::decode(minor_key);
+ }
+
+ static int decode_fixed_right_arg_value_from_minor_key(int minor_key) {
+ return decode_arg_value(FixedRightArgValueBits::decode(minor_key));
+ }
+
+ int fixed_right_arg_value() const {
+ return decode_arg_value(encoded_right_arg_);
+ }
+
+ static bool can_encode_arg_value(int value) {
+ return value > 0 &&
+ IsPowerOf2(value) &&
+ WhichPowerOf2(value) <
static_cast<int>(FixedRightArgValueBits::kSize);
+ }
+
enum SmiCodeGenerateHeapNumberResults {
ALLOW_HEAPNUMBER_RESULTS,
NO_HEAPNUMBER_RESULTS
@@ -918,6 +942,18 @@ class BinaryOpStub: public PlatformCodeStub {
BinaryOpIC::TypeInfo right_type_;
BinaryOpIC::TypeInfo result_type_;
+ bool has_fixed_right_arg_;
+ int encoded_right_arg_;
+
+ static int encode_arg_value(int value) {
+ ASSERT(can_encode_arg_value(value));
+ return WhichPowerOf2(value);
+ }
+
+ static int decode_arg_value(int value) {
+ return 1 << value;
+ }
+
virtual void PrintName(StringStream* stream);
// Minor key encoding in 19 bits TTTRRRLLLSOOOOOOOMM.
@@ -927,6 +963,8 @@ class BinaryOpStub: public PlatformCodeStub {
class LeftTypeBits: public BitField<BinaryOpIC::TypeInfo, 10, 3> {};
class RightTypeBits: public BitField<BinaryOpIC::TypeInfo, 13, 3> {};
class ResultTypeBits: public BitField<BinaryOpIC::TypeInfo, 16, 3> {};
+ class HasFixedRightArgBits: public BitField<bool, 19, 1> {};
+ class FixedRightArgValueBits: public BitField<int, 20, 5> {};
Major MajorKey() { return BinaryOp; }
int MinorKey() {
@@ -935,7 +973,9 @@ class BinaryOpStub: public PlatformCodeStub {
| PlatformSpecificBits::encode(platform_specific_bit_)
| LeftTypeBits::encode(left_type_)
| RightTypeBits::encode(right_type_)
- | ResultTypeBits::encode(result_type_);
+ | ResultTypeBits::encode(result_type_)
+ | HasFixedRightArgBits::encode(has_fixed_right_arg_)
+ | FixedRightArgValueBits::encode(encoded_right_arg_);
}
Index: src/ia32/code-stubs-ia32.cc
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index
507aeb6772a1c1919c04ad0e39b36a13af5716c9..c0297e9f5793bbb6854b08b40ecf22ea19c03f0a
100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -1611,7 +1611,7 @@ static void BinaryOpStub_GenerateSmiCode(
void BinaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
- Label call_runtime;
+ Label right_arg_changed, call_runtime;
switch (op_) {
case Token::ADD:
@@ -1632,6 +1632,11 @@ void BinaryOpStub::GenerateSmiStub(MacroAssembler*
masm) {
UNREACHABLE();
}
+ if (op_ == Token::MOD && has_fixed_right_arg_) {
+ __ cmp(eax, Immediate(Smi::FromInt(fixed_right_arg_value())));
+ __ j(not_equal, &right_arg_changed);
+ }
+
if (result_type_ == BinaryOpIC::UNINITIALIZED ||
result_type_ == BinaryOpIC::SMI) {
BinaryOpStub_GenerateSmiCode(
@@ -1643,6 +1648,7 @@ void BinaryOpStub::GenerateSmiStub(MacroAssembler*
masm) {
// Code falls through if the result is not returned as either a smi or
heap
// number.
+ __ bind(&right_arg_changed);
switch (op_) {
case Token::ADD:
case Token::SUB:
@@ -1745,8 +1751,7 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler*
masm) {
case Token::MUL:
case Token::DIV:
case Token::MOD: {
- Label not_floats;
- Label not_int32;
+ Label not_floats, not_int32, right_arg_changed;
if (CpuFeatures::IsSupported(SSE2)) {
CpuFeatureScope use_sse2(masm, SSE2);
// It could be that only SMIs have been seen at either the left
@@ -1764,6 +1769,10 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler*
masm) {
FloatingPointHelper::LoadSSE2Operands(masm, ¬_floats);
FloatingPointHelper::CheckSSE2OperandsAreInt32(masm, ¬_int32,
ecx);
if (op_ == Token::MOD) {
+ if (has_fixed_right_arg_) {
+ __ cmp(eax, Immediate(Smi::FromInt(fixed_right_arg_value())));
+ __ j(not_equal, &right_arg_changed);
+ }
GenerateRegisterArgsPush(masm);
__ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION);
} else {
@@ -1816,6 +1825,7 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler*
masm) {
__ bind(¬_floats);
__ bind(¬_int32);
+ __ bind(&right_arg_changed);
GenerateTypeTransition(masm);
break;
}
Index: src/ic.cc
diff --git a/src/ic.cc b/src/ic.cc
index
ea0c1fbbe1d70438ee2983ee0d682ef5d3700f24..655f5f5ab3ca6fa05aefa746c25c598132e65bde
100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -2619,18 +2619,45 @@ RUNTIME_FUNCTION(MaybeObject*, BinaryOp_Patch) {
}
}
- BinaryOpStub stub(key, new_left, new_right, result_type);
+ bool previous_has_fixed_right_arg =
+ BinaryOpStub::decode_has_fixed_right_arg_from_minor_key(key);
+ int previous_fixed_right_arg_value =
+ BinaryOpStub::decode_fixed_right_arg_value_from_minor_key(key);
+
+ bool new_has_fixed_right_arg = false;
+ int new_fixed_right_arg_value = 1;
+
+ if (op == Token::MOD && right->IsSmi()) {
+ int value = Smi::cast(*right)->value();
+ if (BinaryOpStub::can_encode_arg_value(value) &&
+ (!previous_has_fixed_right_arg ||
+ previous_fixed_right_arg_value == value)) {
+ new_has_fixed_right_arg = true;
+ new_fixed_right_arg_value = value;
+ }
+ }
+
+ BinaryOpStub stub(key, new_left, new_right, result_type,
+ new_has_fixed_right_arg, new_fixed_right_arg_value);
Handle<Code> code = stub.GetCode(isolate);
if (!code.is_null()) {
#ifdef DEBUG
if (FLAG_trace_ic) {
PrintF("[BinaryOpIC in ");
JavaScriptFrame::PrintTop(isolate, stdout, false, true);
- PrintF(" ((%s+%s)->((%s+%s)->%s))#%s @ %p]\n",
+ PrintF(" ((%s+%s",
BinaryOpIC::GetName(previous_left),
- BinaryOpIC::GetName(previous_right),
+ BinaryOpIC::GetName(previous_right));
+ if (previous_has_fixed_right_arg) {
+ PrintF("{%d}", previous_fixed_right_arg_value);
+ }
+ PrintF(")->((%s+%s",
BinaryOpIC::GetName(new_left),
- BinaryOpIC::GetName(new_right),
+ BinaryOpIC::GetName(new_right));
+ if (new_has_fixed_right_arg) {
+ PrintF("{%d}", new_fixed_right_arg_value);
+ }
+ PrintF(")->%s))#%s @ %p]\n",
BinaryOpIC::GetName(result_type),
Token::Name(op),
static_cast<void*>(*code));
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.