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

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

Issue 14022011: Improvements in lithium code generation. Recognizing if some operands are constants, we can often s… (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Review updates Created 7 years, 8 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
« no previous file with comments | « src/ia32/lithium-ia32.cc ('k') | src/x64/lithium-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 2883 matching lines...) Expand 10 before | Expand all | Expand 10 after
2894 LLoadExternalArrayPointer* instr) { 2894 LLoadExternalArrayPointer* instr) {
2895 Register result = ToRegister(instr->result()); 2895 Register result = ToRegister(instr->result());
2896 Register input = ToRegister(instr->object()); 2896 Register input = ToRegister(instr->object());
2897 __ movq(result, FieldOperand(input, 2897 __ movq(result, FieldOperand(input,
2898 ExternalPixelArray::kExternalPointerOffset)); 2898 ExternalPixelArray::kExternalPointerOffset));
2899 } 2899 }
2900 2900
2901 2901
2902 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { 2902 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
2903 Register arguments = ToRegister(instr->arguments()); 2903 Register arguments = ToRegister(instr->arguments());
2904 Register length = ToRegister(instr->length());
2905 Register result = ToRegister(instr->result()); 2904 Register result = ToRegister(instr->result());
2906 // There are two words between the frame pointer and the last argument. 2905
2907 // Subtracting from length accounts for one of them add one more. 2906 if (instr->length()->IsConstantOperand() &&
2908 if (instr->index()->IsRegister()) { 2907 instr->index()->IsConstantOperand()) {
2909 __ subl(length, ToRegister(instr->index())); 2908 int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
2909 int const_length = ToInteger32(LConstantOperand::cast(instr->length()));
2910 int index = (const_length - const_index) + 1;
2911 __ movq(result, Operand(arguments, index * kPointerSize));
2910 } else { 2912 } else {
2911 __ subl(length, ToOperand(instr->index())); 2913 Register length = ToRegister(instr->length());
2914 // There are two words between the frame pointer and the last argument.
2915 // Subtracting from length accounts for one of them add one more.
2916 if (instr->index()->IsRegister()) {
2917 __ subl(length, ToRegister(instr->index()));
2918 } else {
2919 __ subl(length, ToOperand(instr->index()));
2920 }
2921 __ movq(result,
2922 Operand(arguments, length, times_pointer_size, kPointerSize));
2912 } 2923 }
2913 __ movq(result, Operand(arguments, length, times_pointer_size, kPointerSize));
2914 } 2924 }
2915 2925
2916 2926
2917 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { 2927 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
2918 ElementsKind elements_kind = instr->elements_kind(); 2928 ElementsKind elements_kind = instr->elements_kind();
2919 LOperand* key = instr->key(); 2929 LOperand* key = instr->key();
2920 if (!key->IsConstantOperand()) { 2930 if (!key->IsConstantOperand()) {
2921 Register key_reg = ToRegister(key); 2931 Register key_reg = ToRegister(key);
2922 // Even though the HLoad/StoreKeyed (in this case) instructions force 2932 // Even though the HLoad/StoreKeyed (in this case) instructions force
2923 // the input representation for the key to be an integer, the input 2933 // the input representation for the key to be an integer, the input
(...skipping 987 matching lines...) Expand 10 before | Expand all | Expand 10 after
3911 3921
3912 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) { 3922 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
3913 Register result = ToRegister(instr->result()); 3923 Register result = ToRegister(instr->result());
3914 Register base = ToRegister(instr->base_object()); 3924 Register base = ToRegister(instr->base_object());
3915 __ lea(result, Operand(base, instr->offset())); 3925 __ lea(result, Operand(base, instr->offset()));
3916 } 3926 }
3917 3927
3918 3928
3919 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { 3929 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
3920 Register object = ToRegister(instr->object()); 3930 Register object = ToRegister(instr->object());
3921 Register value = ToRegister(instr->value());
3922 int offset = instr->offset(); 3931 int offset = instr->offset();
3923 3932
3924 if (!instr->transition().is_null()) { 3933 if (!instr->transition().is_null()) {
3925 if (!instr->hydrogen()->NeedsWriteBarrierForMap()) { 3934 if (!instr->hydrogen()->NeedsWriteBarrierForMap()) {
3926 __ Move(FieldOperand(object, HeapObject::kMapOffset), 3935 __ Move(FieldOperand(object, HeapObject::kMapOffset),
3927 instr->transition()); 3936 instr->transition());
3928 } else { 3937 } else {
3929 Register temp = ToRegister(instr->temp()); 3938 Register temp = ToRegister(instr->temp());
3930 __ Move(kScratchRegister, instr->transition()); 3939 __ Move(kScratchRegister, instr->transition());
3931 __ movq(FieldOperand(object, HeapObject::kMapOffset), kScratchRegister); 3940 __ movq(FieldOperand(object, HeapObject::kMapOffset), kScratchRegister);
3932 // Update the write barrier for the map field. 3941 // Update the write barrier for the map field.
3933 __ RecordWriteField(object, 3942 __ RecordWriteField(object,
3934 HeapObject::kMapOffset, 3943 HeapObject::kMapOffset,
3935 kScratchRegister, 3944 kScratchRegister,
3936 temp, 3945 temp,
3937 kSaveFPRegs, 3946 kSaveFPRegs,
3938 OMIT_REMEMBERED_SET, 3947 OMIT_REMEMBERED_SET,
3939 OMIT_SMI_CHECK); 3948 OMIT_SMI_CHECK);
3940 } 3949 }
3941 } 3950 }
3942 3951
3943 // Do the store. 3952 // Do the store.
3944 HType type = instr->hydrogen()->value()->type(); 3953 HType type = instr->hydrogen()->value()->type();
3945 SmiCheck check_needed = 3954 SmiCheck check_needed =
3946 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 3955 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
3947 if (instr->is_in_object()) { 3956
3948 __ movq(FieldOperand(object, offset), value); 3957 Register write_register = object;
3949 if (instr->hydrogen()->NeedsWriteBarrier()) { 3958 if (!instr->is_in_object()) {
3950 Register temp = ToRegister(instr->temp()); 3959 write_register = ToRegister(instr->temp());
3951 // Update the write barrier for the object for in-object properties. 3960 __ movq(write_register, FieldOperand(object, JSObject::kPropertiesOffset));
3952 __ RecordWriteField(object, 3961 }
3953 offset, 3962
3954 value, 3963 if (instr->value()->IsConstantOperand()) {
3955 temp, 3964 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
3956 kSaveFPRegs, 3965 if (IsInteger32Constant(operand_value)) {
3957 EMIT_REMEMBERED_SET, 3966 int const_value = ToInteger32(operand_value);
3958 check_needed); 3967 __ movq(FieldOperand(write_register, offset), Immediate(const_value));
3968 } else {
3969 if (operand_value->IsRegister()) {
3970 __ movq(FieldOperand(write_register, offset),
3971 ToRegister(operand_value));
3972 } else {
3973 Handle<Object> handle_value = ToHandle(operand_value);
3974 __ Move(FieldOperand(write_register, offset), handle_value);
3975 }
3959 } 3976 }
3960 } else { 3977 } else {
3961 Register temp = ToRegister(instr->temp()); 3978 __ movq(FieldOperand(write_register, offset), ToRegister(instr->value()));
3962 __ movq(temp, FieldOperand(object, JSObject::kPropertiesOffset)); 3979 }
3963 __ movq(FieldOperand(temp, offset), value); 3980
3964 if (instr->hydrogen()->NeedsWriteBarrier()) { 3981 if (instr->hydrogen()->NeedsWriteBarrier()) {
3965 // Update the write barrier for the properties array. 3982 Register value = ToRegister(instr->value());
3966 // object is used as a scratch register. 3983 Register temp = instr->is_in_object() ? ToRegister(instr->temp()) : object;
3967 __ RecordWriteField(temp, 3984 // Update the write barrier for the object for in-object properties.
3968 offset, 3985 __ RecordWriteField(write_register,
3969 value, 3986 offset,
3970 object, 3987 value,
3971 kSaveFPRegs, 3988 temp,
3972 EMIT_REMEMBERED_SET, 3989 kSaveFPRegs,
3973 check_needed); 3990 EMIT_REMEMBERED_SET,
3974 } 3991 check_needed);
3975 } 3992 }
3976 } 3993 }
3977 3994
3978 3995
3979 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { 3996 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
3980 ASSERT(ToRegister(instr->object()).is(rdx)); 3997 ASSERT(ToRegister(instr->object()).is(rdx));
3981 ASSERT(ToRegister(instr->value()).is(rax)); 3998 ASSERT(ToRegister(instr->value()).is(rax));
3982 3999
3983 __ Move(rcx, instr->hydrogen()->name()); 4000 __ Move(rcx, instr->hydrogen()->name());
3984 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 4001 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
4130 key, 4147 key,
4131 FAST_DOUBLE_ELEMENTS, 4148 FAST_DOUBLE_ELEMENTS,
4132 FixedDoubleArray::kHeaderSize - kHeapObjectTag, 4149 FixedDoubleArray::kHeaderSize - kHeapObjectTag,
4133 instr->additional_index()); 4150 instr->additional_index());
4134 4151
4135 __ movsd(double_store_operand, value); 4152 __ movsd(double_store_operand, value);
4136 } 4153 }
4137 4154
4138 4155
4139 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { 4156 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
4140 Register value = ToRegister(instr->value());
4141 Register elements = ToRegister(instr->elements()); 4157 Register elements = ToRegister(instr->elements());
4142 LOperand* key = instr->key(); 4158 LOperand* key = instr->key();
4143 if (!key->IsConstantOperand()) { 4159 if (!key->IsConstantOperand()) {
4144 Register key_reg = ToRegister(key); 4160 Register key_reg = ToRegister(key);
4145 // Even though the HLoad/StoreKeyedFastElement instructions force 4161 // Even though the HLoad/StoreKeyedFastElement instructions force
4146 // the input representation for the key to be an integer, the 4162 // the input representation for the key to be an integer, the
4147 // input gets replaced during bound check elimination with the index 4163 // input gets replaced during bound check elimination with the index
4148 // argument to the bounds check, which can be tagged, so that case 4164 // argument to the bounds check, which can be tagged, so that case
4149 // must be handled here, too. 4165 // must be handled here, too.
4150 if (instr->hydrogen()->key()->representation().IsTagged()) { 4166 if (instr->hydrogen()->key()->representation().IsTagged()) {
4151 __ SmiToInteger64(key_reg, key_reg); 4167 __ SmiToInteger64(key_reg, key_reg);
4152 } else if (instr->hydrogen()->IsDehoisted()) { 4168 } else if (instr->hydrogen()->IsDehoisted()) {
4153 // Sign extend key because it could be a 32 bit negative value 4169 // Sign extend key because it could be a 32 bit negative value
4154 // and the dehoisted address computation happens in 64 bits 4170 // and the dehoisted address computation happens in 64 bits
4155 __ movsxlq(key_reg, key_reg); 4171 __ movsxlq(key_reg, key_reg);
4156 } 4172 }
4157 } 4173 }
4158 4174
4159 Operand operand = 4175 Operand operand =
4160 BuildFastArrayOperand(instr->elements(), 4176 BuildFastArrayOperand(instr->elements(),
4161 key, 4177 key,
4162 FAST_ELEMENTS, 4178 FAST_ELEMENTS,
4163 FixedArray::kHeaderSize - kHeapObjectTag, 4179 FixedArray::kHeaderSize - kHeapObjectTag,
4164 instr->additional_index()); 4180 instr->additional_index());
4181 if (instr->value()->IsRegister()) {
4182 __ movq(operand, ToRegister(instr->value()));
4183 } else {
4184 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4185 if (IsInteger32Constant(operand_value)) {
4186 Smi* smi_value = Smi::FromInt(ToInteger32(operand_value));
4187 __ Move(operand, smi_value);
4188 } else {
4189 Handle<Object> handle_value = ToHandle(operand_value);
4190 __ Move(operand, handle_value);
4191 }
4192 }
4165 4193
4166 if (instr->hydrogen()->NeedsWriteBarrier()) { 4194 if (instr->hydrogen()->NeedsWriteBarrier()) {
4195 ASSERT(instr->value()->IsRegister());
4196 Register value = ToRegister(instr->value());
4167 ASSERT(!instr->key()->IsConstantOperand()); 4197 ASSERT(!instr->key()->IsConstantOperand());
4168 HType type = instr->hydrogen()->value()->type(); 4198 HType type = instr->hydrogen()->value()->type();
4169 SmiCheck check_needed = 4199 SmiCheck check_needed =
4170 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 4200 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
4171 // Compute address of modified element and store it into key register. 4201 // Compute address of modified element and store it into key register.
4172 Register key_reg(ToRegister(key)); 4202 Register key_reg(ToRegister(key));
4173 __ lea(key_reg, operand); 4203 __ lea(key_reg, operand);
4174 __ movq(Operand(key_reg, 0), value);
4175 __ RecordWrite(elements, 4204 __ RecordWrite(elements,
4176 key_reg, 4205 key_reg,
4177 value, 4206 value,
4178 kSaveFPRegs, 4207 kSaveFPRegs,
4179 EMIT_REMEMBERED_SET, 4208 EMIT_REMEMBERED_SET,
4180 check_needed); 4209 check_needed);
4181 } else {
4182 __ movq(operand, value);
4183 } 4210 }
4184 } 4211 }
4185 4212
4186 4213
4187 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) { 4214 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) {
4188 if (instr->is_external()) { 4215 if (instr->is_external()) {
4189 DoStoreKeyedExternalArray(instr); 4216 DoStoreKeyedExternalArray(instr);
4190 } else if (instr->hydrogen()->value()->representation().IsDouble()) { 4217 } else if (instr->hydrogen()->value()->representation().IsDouble()) {
4191 DoStoreKeyedFixedDoubleArray(instr); 4218 DoStoreKeyedFixedDoubleArray(instr);
4192 } else { 4219 } else {
(...skipping 1468 matching lines...) Expand 10 before | Expand all | Expand 10 after
5661 FixedArray::kHeaderSize - kPointerSize)); 5688 FixedArray::kHeaderSize - kPointerSize));
5662 __ bind(&done); 5689 __ bind(&done);
5663 } 5690 }
5664 5691
5665 5692
5666 #undef __ 5693 #undef __
5667 5694
5668 } } // namespace v8::internal 5695 } } // namespace v8::internal
5669 5696
5670 #endif // V8_TARGET_ARCH_X64 5697 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/ia32/lithium-ia32.cc ('k') | src/x64/lithium-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698