Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(356)

Side by Side Diff: src/arm/lithium-codegen-arm.cc

Issue 10382055: Array index computation dehoisting. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Simplified expression. Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 2730 matching lines...) Expand 10 before | Expand all | Expand 10 after
2741 2741
2742 2742
2743 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { 2743 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
2744 Register elements = ToRegister(instr->elements()); 2744 Register elements = ToRegister(instr->elements());
2745 Register key = EmitLoadRegister(instr->key(), scratch0()); 2745 Register key = EmitLoadRegister(instr->key(), scratch0());
2746 Register result = ToRegister(instr->result()); 2746 Register result = ToRegister(instr->result());
2747 Register scratch = scratch0(); 2747 Register scratch = scratch0();
2748 2748
2749 // Load the result. 2749 // Load the result.
2750 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); 2750 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2));
2751 __ ldr(result, FieldMemOperand(scratch, FixedArray::kHeaderSize)); 2751 __ ldr(result,
Jakob Kummerow 2012/05/15 15:53:23 Formatting proposal: uint32_t offset = FixedArr
2752 FieldMemOperand(scratch,
2753 FixedArray::kHeaderSize
2754 + (instr->additional_index()
2755 << kPointerSizeLog2)));
2752 2756
2753 // Check for the hole value. 2757 // Check for the hole value.
2754 if (instr->hydrogen()->RequiresHoleCheck()) { 2758 if (instr->hydrogen()->RequiresHoleCheck()) {
2755 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); 2759 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
2756 __ cmp(result, scratch); 2760 __ cmp(result, scratch);
2757 DeoptimizeIf(eq, instr->environment()); 2761 DeoptimizeIf(eq, instr->environment());
2758 } 2762 }
2759 } 2763 }
2760 2764
2761 2765
(...skipping 11 matching lines...) Expand all
2773 if (key_is_constant) { 2777 if (key_is_constant) {
2774 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); 2778 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
2775 if (constant_key & 0xF0000000) { 2779 if (constant_key & 0xF0000000) {
2776 Abort("array index constant value too big."); 2780 Abort("array index constant value too big.");
2777 } 2781 }
2778 } else { 2782 } else {
2779 key = ToRegister(instr->key()); 2783 key = ToRegister(instr->key());
2780 } 2784 }
2781 2785
2782 Operand operand = key_is_constant 2786 Operand operand = key_is_constant
2783 ? Operand(constant_key * (1 << shift_size) + 2787 ? Operand(((constant_key + instr->additional_index()) << shift_size) +
2784 FixedDoubleArray::kHeaderSize - kHeapObjectTag) 2788 FixedDoubleArray::kHeaderSize - kHeapObjectTag)
2785 : Operand(key, LSL, shift_size); 2789 : Operand(key, LSL, shift_size);
2786 __ add(elements, elements, operand); 2790 __ add(elements, elements, operand);
2787 if (!key_is_constant) { 2791 if (!key_is_constant) {
2788 __ add(elements, elements, 2792 __ add(elements, elements,
2789 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); 2793 Operand((FixedDoubleArray::kHeaderSize - kHeapObjectTag)
2794 + (instr->additional_index() << shift_size)));
Jakob Kummerow 2012/05/15 15:53:23 nit: for consistency, the operator goes at the end
2790 } 2795 }
2791 2796
2792 __ ldr(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); 2797 __ ldr(scratch, MemOperand(elements, sizeof(kHoleNanLower32)));
2793 __ cmp(scratch, Operand(kHoleNanUpper32)); 2798 __ cmp(scratch, Operand(kHoleNanUpper32));
2794 DeoptimizeIf(eq, instr->environment()); 2799 DeoptimizeIf(eq, instr->environment());
2795 2800
2796 __ vldr(result, elements, 0); 2801 __ vldr(result, elements, 0);
2797 } 2802 }
2798 2803
2799 2804
2800 void LCodeGen::DoLoadKeyedSpecializedArrayElement( 2805 void LCodeGen::DoLoadKeyedSpecializedArrayElement(
2801 LLoadKeyedSpecializedArrayElement* instr) { 2806 LLoadKeyedSpecializedArrayElement* instr) {
2802 Register external_pointer = ToRegister(instr->external_pointer()); 2807 Register external_pointer = ToRegister(instr->external_pointer());
2803 Register key = no_reg; 2808 Register key = no_reg;
2804 ElementsKind elements_kind = instr->elements_kind(); 2809 ElementsKind elements_kind = instr->elements_kind();
2805 bool key_is_constant = instr->key()->IsConstantOperand(); 2810 bool key_is_constant = instr->key()->IsConstantOperand();
2806 int constant_key = 0; 2811 int constant_key = 0;
2807 if (key_is_constant) { 2812 if (key_is_constant) {
2808 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); 2813 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
2809 if (constant_key & 0xF0000000) { 2814 if (constant_key & 0xF0000000) {
2810 Abort("array index constant value too big."); 2815 Abort("array index constant value too big.");
2811 } 2816 }
2812 } else { 2817 } else {
2813 key = ToRegister(instr->key()); 2818 key = ToRegister(instr->key());
2814 } 2819 }
2815 int shift_size = ElementsKindToShiftSize(elements_kind); 2820 int shift_size = ElementsKindToShiftSize(elements_kind);
2821 int additional_offset = instr->additional_index() << shift_size;
2816 2822
2817 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 2823 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
2818 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 2824 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
2819 CpuFeatures::Scope scope(VFP3); 2825 CpuFeatures::Scope scope(VFP3);
2820 DwVfpRegister result = ToDoubleRegister(instr->result()); 2826 DwVfpRegister result = ToDoubleRegister(instr->result());
2821 Operand operand = key_is_constant 2827 Operand operand = key_is_constant
2822 ? Operand(constant_key * (1 << shift_size)) 2828 ? Operand(constant_key * (1 << shift_size))
2823 : Operand(key, LSL, shift_size); 2829 : Operand(key, LSL, shift_size);
2824 __ add(scratch0(), external_pointer, operand); 2830 __ add(scratch0(), external_pointer, operand);
2825 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { 2831 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
2826 __ vldr(result.low(), scratch0(), 0); 2832 __ vldr(result.low(), scratch0(), additional_offset);
2827 __ vcvt_f64_f32(result, result.low()); 2833 __ vcvt_f64_f32(result, result.low());
2828 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS 2834 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
2829 __ vldr(result, scratch0(), 0); 2835 __ vldr(result, scratch0(), additional_offset);
2830 } 2836 }
2831 } else { 2837 } else {
2832 Register result = ToRegister(instr->result()); 2838 Register result = ToRegister(instr->result());
2839 if (instr->additional_index() != 0 && !key_is_constant) {
2840 __ add(scratch0(), key, Operand(instr->additional_index()));
2841 }
2833 MemOperand mem_operand(key_is_constant 2842 MemOperand mem_operand(key_is_constant
2834 ? MemOperand(external_pointer, constant_key * (1 << shift_size)) 2843 ? MemOperand(external_pointer,
2835 : MemOperand(external_pointer, key, LSL, shift_size)); 2844 constant_key * (1 << shift_size) + additional_offset)
Jakob Kummerow 2012/05/15 15:53:23 nit: drop the "* (1". Just "(constant_key << shift
2845 : (instr->additional_index() == 0
2846 ? MemOperand(external_pointer, key, LSL, shift_size)
2847 : MemOperand(external_pointer, scratch0(), LSL, shift_size)));
2836 switch (elements_kind) { 2848 switch (elements_kind) {
2837 case EXTERNAL_BYTE_ELEMENTS: 2849 case EXTERNAL_BYTE_ELEMENTS:
2838 __ ldrsb(result, mem_operand); 2850 __ ldrsb(result, mem_operand);
2839 break; 2851 break;
2840 case EXTERNAL_PIXEL_ELEMENTS: 2852 case EXTERNAL_PIXEL_ELEMENTS:
2841 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 2853 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
2842 __ ldrb(result, mem_operand); 2854 __ ldrb(result, mem_operand);
2843 break; 2855 break;
2844 case EXTERNAL_SHORT_ELEMENTS: 2856 case EXTERNAL_SHORT_ELEMENTS:
2845 __ ldrsh(result, mem_operand); 2857 __ ldrsh(result, mem_operand);
(...skipping 877 matching lines...) Expand 10 before | Expand all | Expand 10 after
3723 Register value = ToRegister(instr->value()); 3735 Register value = ToRegister(instr->value());
3724 Register elements = ToRegister(instr->object()); 3736 Register elements = ToRegister(instr->object());
3725 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; 3737 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg;
3726 Register scratch = scratch0(); 3738 Register scratch = scratch0();
3727 3739
3728 // Do the store. 3740 // Do the store.
3729 if (instr->key()->IsConstantOperand()) { 3741 if (instr->key()->IsConstantOperand()) {
3730 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); 3742 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
3731 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); 3743 LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
3732 int offset = 3744 int offset =
3733 ToInteger32(const_operand) * kPointerSize + FixedArray::kHeaderSize; 3745 (ToInteger32(const_operand) + instr->additional_index())
3746 * kPointerSize + FixedArray::kHeaderSize;
Jakob Kummerow 2012/05/15 15:53:23 nit: looks like "* kPointerSize" might just fit on
3734 __ str(value, FieldMemOperand(elements, offset)); 3747 __ str(value, FieldMemOperand(elements, offset));
3735 } else { 3748 } else {
3736 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); 3749 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2));
3750 if (instr->additional_index() != 0) {
3751 __ add(scratch,
3752 scratch,
3753 Operand(instr->additional_index() << kPointerSizeLog2));
3754 }
3737 __ str(value, FieldMemOperand(scratch, FixedArray::kHeaderSize)); 3755 __ str(value, FieldMemOperand(scratch, FixedArray::kHeaderSize));
3738 } 3756 }
3739 3757
3740 if (instr->hydrogen()->NeedsWriteBarrier()) { 3758 if (instr->hydrogen()->NeedsWriteBarrier()) {
3741 HType type = instr->hydrogen()->value()->type(); 3759 HType type = instr->hydrogen()->value()->type();
3742 SmiCheck check_needed = 3760 SmiCheck check_needed =
3743 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 3761 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
3744 // Compute address of modified element and store it into key register. 3762 // Compute address of modified element and store it into key register.
3745 __ add(key, scratch, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 3763 __ add(key, scratch, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
3746 __ RecordWrite(elements, 3764 __ RecordWrite(elements,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
3786 3804
3787 if (instr->NeedsCanonicalization()) { 3805 if (instr->NeedsCanonicalization()) {
3788 // Check for NaN. All NaNs must be canonicalized. 3806 // Check for NaN. All NaNs must be canonicalized.
3789 __ VFPCompareAndSetFlags(value, value); 3807 __ VFPCompareAndSetFlags(value, value);
3790 // Only load canonical NaN if the comparison above set the overflow. 3808 // Only load canonical NaN if the comparison above set the overflow.
3791 __ Vmov(value, 3809 __ Vmov(value,
3792 FixedDoubleArray::canonical_not_the_hole_nan_as_double(), 3810 FixedDoubleArray::canonical_not_the_hole_nan_as_double(),
3793 vs); 3811 vs);
3794 } 3812 }
3795 3813
3796 __ vstr(value, scratch, 0); 3814 __ vstr(value, scratch, instr->additional_index() << shift_size);
3797 } 3815 }
3798 3816
3799 3817
3800 void LCodeGen::DoStoreKeyedSpecializedArrayElement( 3818 void LCodeGen::DoStoreKeyedSpecializedArrayElement(
3801 LStoreKeyedSpecializedArrayElement* instr) { 3819 LStoreKeyedSpecializedArrayElement* instr) {
3802 3820
3803 Register external_pointer = ToRegister(instr->external_pointer()); 3821 Register external_pointer = ToRegister(instr->external_pointer());
3804 Register key = no_reg; 3822 Register key = no_reg;
3805 ElementsKind elements_kind = instr->elements_kind(); 3823 ElementsKind elements_kind = instr->elements_kind();
3806 bool key_is_constant = instr->key()->IsConstantOperand(); 3824 bool key_is_constant = instr->key()->IsConstantOperand();
3807 int constant_key = 0; 3825 int constant_key = 0;
3808 if (key_is_constant) { 3826 if (key_is_constant) {
3809 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); 3827 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
3810 if (constant_key & 0xF0000000) { 3828 if (constant_key & 0xF0000000) {
3811 Abort("array index constant value too big."); 3829 Abort("array index constant value too big.");
3812 } 3830 }
3813 } else { 3831 } else {
3814 key = ToRegister(instr->key()); 3832 key = ToRegister(instr->key());
3815 } 3833 }
3816 int shift_size = ElementsKindToShiftSize(elements_kind); 3834 int shift_size = ElementsKindToShiftSize(elements_kind);
3835 int additional_offset = instr->additional_index() << shift_size;
3817 3836
3818 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 3837 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
3819 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 3838 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
3820 CpuFeatures::Scope scope(VFP3); 3839 CpuFeatures::Scope scope(VFP3);
3821 DwVfpRegister value(ToDoubleRegister(instr->value())); 3840 DwVfpRegister value(ToDoubleRegister(instr->value()));
3822 Operand operand(key_is_constant ? Operand(constant_key * (1 << shift_size)) 3841 Operand operand(key_is_constant ? Operand(constant_key * (1 << shift_size))
3823 : Operand(key, LSL, shift_size)); 3842 : Operand(key, LSL, shift_size));
3824 __ add(scratch0(), external_pointer, operand); 3843 __ add(scratch0(), external_pointer, operand);
3825 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { 3844 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3826 __ vcvt_f32_f64(double_scratch0().low(), value); 3845 __ vcvt_f32_f64(double_scratch0().low(), value);
3827 __ vstr(double_scratch0().low(), scratch0(), 0); 3846 __ vstr(double_scratch0().low(), scratch0(), additional_offset);
3828 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS 3847 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
3829 __ vstr(value, scratch0(), 0); 3848 __ vstr(value, scratch0(), additional_offset);
3830 } 3849 }
3831 } else { 3850 } else {
3832 Register value(ToRegister(instr->value())); 3851 Register value(ToRegister(instr->value()));
3852 if (instr->additional_index() != 0 && !key_is_constant) {
3853 __ add(scratch0(), key, Operand(instr->additional_index()));
3854 }
3833 MemOperand mem_operand(key_is_constant 3855 MemOperand mem_operand(key_is_constant
3834 ? MemOperand(external_pointer, constant_key * (1 << shift_size)) 3856 ? MemOperand(external_pointer,
3835 : MemOperand(external_pointer, key, LSL, shift_size)); 3857 (constant_key + instr->additional_index())
3858 * (1 << shift_size))
3859 : (instr->additional_index() == 0
3860 ? MemOperand(external_pointer, key, LSL, shift_size)
Jakob Kummerow 2012/05/15 15:53:23 nit: 4 space indent please.
3861 : MemOperand(external_pointer, scratch0(), LSL, shift_size)));
3836 switch (elements_kind) { 3862 switch (elements_kind) {
3837 case EXTERNAL_PIXEL_ELEMENTS: 3863 case EXTERNAL_PIXEL_ELEMENTS:
3838 case EXTERNAL_BYTE_ELEMENTS: 3864 case EXTERNAL_BYTE_ELEMENTS:
3839 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 3865 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3840 __ strb(value, mem_operand); 3866 __ strb(value, mem_operand);
3841 break; 3867 break;
3842 case EXTERNAL_SHORT_ELEMENTS: 3868 case EXTERNAL_SHORT_ELEMENTS:
3843 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 3869 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3844 __ strh(value, mem_operand); 3870 __ strh(value, mem_operand);
3845 break; 3871 break;
(...skipping 1465 matching lines...) Expand 10 before | Expand all | Expand 10 after
5311 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); 5337 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize));
5312 __ ldr(result, FieldMemOperand(scratch, 5338 __ ldr(result, FieldMemOperand(scratch,
5313 FixedArray::kHeaderSize - kPointerSize)); 5339 FixedArray::kHeaderSize - kPointerSize));
5314 __ bind(&done); 5340 __ bind(&done);
5315 } 5341 }
5316 5342
5317 5343
5318 #undef __ 5344 #undef __
5319 5345
5320 } } // namespace v8::internal 5346 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698