Reviewers: Jakob,
Message:
PTAL
Description:
Improve constant element index access code generation
[email protected]
Please review this at http://codereview.chromium.org/10831049/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/arm/lithium-arm.cc
M src/arm/lithium-codegen-arm.cc
M src/hydrogen-instructions.h
M src/hydrogen.cc
M src/ia32/lithium-codegen-ia32.cc
M src/x64/lithium-codegen-x64.cc
Index: src/arm/lithium-arm.cc
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index
91afec53b1fa48b07f5409b671d984efc6ac2d9c..0dda5bdaa1416fae1802f457cfa91a533bb18c47
100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -1546,7 +1546,7 @@ LInstruction* LChunkBuilder::DoDateField(HDateField*
instr) {
LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
- LOperand* value = UseRegisterAtStart(instr->index());
+ LOperand* value = UseRegisterOrConstantAtStart(instr->index());
LOperand* length = UseRegister(instr->length());
return AssignEnvironment(new(zone()) LBoundsCheck(value, length));
}
@@ -1838,7 +1838,7 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
ASSERT(instr->key()->representation().IsInteger32() ||
instr->key()->representation().IsTagged());
LOperand* obj = UseRegisterAtStart(instr->object());
- LOperand* key = UseRegisterAtStart(instr->key());
+ LOperand* key = UseRegisterOrConstantAtStart(instr->key());
LLoadKeyedFastElement* result = new(zone()) LLoadKeyedFastElement(obj,
key);
if (instr->RequiresHoleCheck()) AssignEnvironment(result);
return DefineAsRegister(result);
Index: src/arm/lithium-codegen-arm.cc
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index
d94a1feb238c5e0abef2c1d2f670e30e2c72c6b9..90a315b2b6e360e1e6951ced76147b2ceff92f39
100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -2779,20 +2779,30 @@ void
LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
Register elements = ToRegister(instr->elements());
- Register key = EmitLoadRegister(instr->key(), scratch0());
Register result = ToRegister(instr->result());
Register scratch = scratch0();
- // Load the result.
- if (instr->hydrogen()->key()->representation().IsTagged()) {
- __ add(scratch, elements,
- Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize));
+ if (instr->key()->IsConstantOperand()) {
+ LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
+ int offset =
+ (ToInteger32(const_operand) + instr->additional_index()) *
kPointerSize
+ + FixedArray::kHeaderSize;
+ __ ldr(result, FieldMemOperand(elements, offset));
} else {
- __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2));
+ Register key = EmitLoadRegister(instr->key(), scratch0());
+ if (instr->hydrogen()->key()->representation().IsTagged()) {
+ __ add(scratch, elements,
+ Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize));
+ } else {
+ __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2));
+ }
+ if (instr->additional_index() != 0) {
+ __ add(scratch,
+ scratch,
+ Operand(instr->additional_index() << kPointerSizeLog2));
+ }
+ __ ldr(result, FieldMemOperand(scratch, FixedArray::kHeaderSize));
}
- uint32_t offset = FixedArray::kHeaderSize +
- (instr->additional_index() << kPointerSizeLog2);
- __ ldr(result, FieldMemOperand(scratch, offset));
// Check for the hole value.
if (instr->hydrogen()->RequiresHoleCheck()) {
@@ -3823,7 +3833,18 @@ void
LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
- __ cmp(ToRegister(instr->index()), ToRegister(instr->length()));
+ if (instr->index()->IsConstantOperand()) {
+ int constant_index =
+ ToInteger32(LConstantOperand::cast(instr->index()));
+ if (instr->hydrogen()->length()->representation().IsTagged()) {
+ __ mov(ip, Operand(Smi::FromInt(constant_index)));
+ } else {
+ __ mov(ip, Operand(constant_index));
+ }
+ __ cmp(ip, ToRegister(instr->length()));
+ } else {
+ __ cmp(ToRegister(instr->index()), ToRegister(instr->length()));
+ }
DeoptimizeIf(hs, instr->environment());
}
Index: src/hydrogen-instructions.h
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index
c2cb271277afc0e4ccdfb9fd15f3f374aab96cb3..a4377de165ab84721cf40d20c0b9248fefbeb90d
100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -2776,13 +2776,25 @@ class HBoundsCheck: public HTemplateInstruction<2> {
}
virtual Representation RequiredInputRepresentation(int arg_index) {
- if (index()->representation().IsTagged() &&
- !index()->IsConstant() &&
- key_mode_ == ALLOW_SMI_KEY) {
- return Representation::Tagged();
- } else {
+ if (key_mode_ == DONT_ALLOW_SMI_KEY ||
+ !length()->representation().IsTagged()) {
return Representation::Integer32();
}
+ // If the index is tagged and isn't constant, then allow the length
+ // to be tagged, since it is usually already tagged from loading it
out of
+ // the length field of a JSArray. This allows for direct comparison
without
+ // untagging.
+ if (index()->representation().IsTagged() && !index()->IsConstant()) {
+ return Representation::Tagged();
+ }
+ // Also allow the length to be tagged if the index is constant, because
+ // it can be tagged to allow direct comparison.
+ if (index()->IsConstant() &&
+ index()->representation().IsInteger32() &&
+ arg_index == 1) {
+ return Representation::Tagged();
+ }
+ return Representation::Integer32();
}
virtual void PrintDataTo(StringStream* stream);
Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index
df4d8fc99c650a0192a8782db7cbf302e311802e..6eece777a17fc0c141f6e3155f71375ce137390e
100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -5864,7 +5864,8 @@ HInstruction*
HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
} else {
length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements));
}
- checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
+ checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length,
+ ALLOW_SMI_KEY));
return BuildFastElementAccess(elements, checked_key, val, mapcheck,
map->elements_kind(), is_store);
}
Index: src/ia32/lithium-codegen-ia32.cc
diff --git a/src/ia32/lithium-codegen-ia32.cc
b/src/ia32/lithium-codegen-ia32.cc
index
f3bcf1abc3fc1974af2b7bd55a8aeec35aec8269..0687e82550d37411f34fe2df806718bb84d1bfce
100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -3681,8 +3681,14 @@ void
LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
if (instr->index()->IsConstantOperand()) {
- __ cmp(ToOperand(instr->length()),
- Immediate(ToInteger32(LConstantOperand::cast(instr->index()))));
+ int constant_index =
+ ToInteger32(LConstantOperand::cast(instr->index()));
+ if (instr->hydrogen()->length()->representation().IsTagged()) {
+ __ cmp(ToOperand(instr->length()),
+ Immediate(Smi::FromInt(constant_index)));
+ } else {
+ __ cmp(ToOperand(instr->length()), Immediate(constant_index));
+ }
DeoptimizeIf(below_equal, instr->environment());
} else {
__ cmp(ToRegister(instr->index()), ToOperand(instr->length()));
Index: src/x64/lithium-codegen-x64.cc
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index
3e688dfd004c7bc4aa29dfa2637ce62ba6203bc4..0d8bf77cd1b4da9aafd093d6d039057bb25ebe26
100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -3617,8 +3617,13 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
__ AbortIfNotZeroExtended(reg);
}
if (instr->index()->IsConstantOperand()) {
- __ cmpq(reg,
-
Immediate(ToInteger32(LConstantOperand::cast(instr->index()))));
+ int constant_index =
+ ToInteger32(LConstantOperand::cast(instr->index()));
+ if (instr->hydrogen()->length()->representation().IsTagged()) {
+ __ Cmp(reg, Smi::FromInt(constant_index));
+ } else {
+ __ cmpq(reg, Immediate(constant_index));
+ }
} else {
Register reg2 = ToRegister(instr->index());
if (FLAG_debug_code &&
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev