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

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

Issue 10442003: MIPS: Array index computation dehoisting. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: 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
« no previous file with comments | « no previous file | src/mips/lithium-mips.h » ('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 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 2486 matching lines...) Expand 10 before | Expand all | Expand 10 after
2497 2497
2498 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { 2498 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
2499 Register elements = ToRegister(instr->elements()); 2499 Register elements = ToRegister(instr->elements());
2500 Register key = EmitLoadRegister(instr->key(), scratch0()); 2500 Register key = EmitLoadRegister(instr->key(), scratch0());
2501 Register result = ToRegister(instr->result()); 2501 Register result = ToRegister(instr->result());
2502 Register scratch = scratch0(); 2502 Register scratch = scratch0();
2503 2503
2504 // Load the result. 2504 // Load the result.
2505 __ sll(scratch, key, kPointerSizeLog2); // Key indexes words. 2505 __ sll(scratch, key, kPointerSizeLog2); // Key indexes words.
2506 __ addu(scratch, elements, scratch); 2506 __ addu(scratch, elements, scratch);
2507 __ lw(result, FieldMemOperand(scratch, FixedArray::kHeaderSize)); 2507 uint32_t offset = FixedArray::kHeaderSize +
2508 (instr->additional_index() << kPointerSizeLog2);
2509 __ lw(result, FieldMemOperand(scratch, offset));
2508 2510
2509 // Check for the hole value. 2511 // Check for the hole value.
2510 if (instr->hydrogen()->RequiresHoleCheck()) { 2512 if (instr->hydrogen()->RequiresHoleCheck()) {
2511 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); 2513 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
2512 DeoptimizeIf(eq, instr->environment(), result, Operand(scratch)); 2514 DeoptimizeIf(eq, instr->environment(), result, Operand(scratch));
2513 } 2515 }
2514 } 2516 }
2515 2517
2516 2518
2517 void LCodeGen::DoLoadKeyedFastDoubleElement( 2519 void LCodeGen::DoLoadKeyedFastDoubleElement(
(...skipping 10 matching lines...) Expand all
2528 if (key_is_constant) { 2530 if (key_is_constant) {
2529 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); 2531 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
2530 if (constant_key & 0xF0000000) { 2532 if (constant_key & 0xF0000000) {
2531 Abort("array index constant value too big."); 2533 Abort("array index constant value too big.");
2532 } 2534 }
2533 } else { 2535 } else {
2534 key = ToRegister(instr->key()); 2536 key = ToRegister(instr->key());
2535 } 2537 }
2536 2538
2537 if (key_is_constant) { 2539 if (key_is_constant) {
2538 __ Addu(elements, elements, Operand(constant_key * (1 << shift_size) + 2540 __ Addu(elements, elements,
2539 FixedDoubleArray::kHeaderSize - kHeapObjectTag)); 2541 Operand(((constant_key + instr->additional_index()) << shift_size) +
2542 FixedDoubleArray::kHeaderSize - kHeapObjectTag));
2540 } else { 2543 } else {
2541 __ sll(scratch, key, shift_size); 2544 __ sll(scratch, key, shift_size);
2542 __ Addu(elements, elements, Operand(scratch)); 2545 __ Addu(elements, elements, Operand(scratch));
2543 __ Addu(elements, elements, 2546 __ Addu(elements, elements,
2544 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); 2547 Operand((FixedDoubleArray::kHeaderSize - kHeapObjectTag) +
2548 (instr->additional_index() << shift_size)));
2545 } 2549 }
2546 2550
2547 if (instr->hydrogen()->RequiresHoleCheck()) { 2551 if (instr->hydrogen()->RequiresHoleCheck()) {
2548 __ lw(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); 2552 __ lw(scratch, MemOperand(elements, sizeof(kHoleNanLower32)));
2549 DeoptimizeIf(eq, instr->environment(), scratch, Operand(kHoleNanUpper32)); 2553 DeoptimizeIf(eq, instr->environment(), scratch, Operand(kHoleNanUpper32));
2550 } 2554 }
2551 2555
2552 __ ldc1(result, MemOperand(elements)); 2556 __ ldc1(result, MemOperand(elements));
2553 } 2557 }
2554 2558
2555 2559
2556 void LCodeGen::DoLoadKeyedSpecializedArrayElement( 2560 void LCodeGen::DoLoadKeyedSpecializedArrayElement(
2557 LLoadKeyedSpecializedArrayElement* instr) { 2561 LLoadKeyedSpecializedArrayElement* instr) {
2558 Register external_pointer = ToRegister(instr->external_pointer()); 2562 Register external_pointer = ToRegister(instr->external_pointer());
2559 Register key = no_reg; 2563 Register key = no_reg;
2560 ElementsKind elements_kind = instr->elements_kind(); 2564 ElementsKind elements_kind = instr->elements_kind();
2561 bool key_is_constant = instr->key()->IsConstantOperand(); 2565 bool key_is_constant = instr->key()->IsConstantOperand();
2562 int constant_key = 0; 2566 int constant_key = 0;
2563 if (key_is_constant) { 2567 if (key_is_constant) {
2564 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); 2568 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
2565 if (constant_key & 0xF0000000) { 2569 if (constant_key & 0xF0000000) {
2566 Abort("array index constant value too big."); 2570 Abort("array index constant value too big.");
2567 } 2571 }
2568 } else { 2572 } else {
2569 key = ToRegister(instr->key()); 2573 key = ToRegister(instr->key());
2570 } 2574 }
2571 int shift_size = ElementsKindToShiftSize(elements_kind); 2575 int shift_size = ElementsKindToShiftSize(elements_kind);
2576 int additional_offset = instr->additional_index() << shift_size;
2572 2577
2573 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 2578 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
2574 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 2579 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
2575 FPURegister result = ToDoubleRegister(instr->result()); 2580 FPURegister result = ToDoubleRegister(instr->result());
2576 if (key_is_constant) { 2581 if (key_is_constant) {
2577 __ Addu(scratch0(), external_pointer, constant_key * (1 << shift_size)); 2582 __ Addu(scratch0(), external_pointer, constant_key << shift_size);
2578 } else { 2583 } else {
2579 __ sll(scratch0(), key, shift_size); 2584 __ sll(scratch0(), key, shift_size);
2580 __ Addu(scratch0(), scratch0(), external_pointer); 2585 __ Addu(scratch0(), scratch0(), external_pointer);
2581 } 2586 }
2582 2587
2583 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { 2588 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
2584 __ lwc1(result, MemOperand(scratch0())); 2589 __ lwc1(result, MemOperand(scratch0(), additional_offset));
2585 __ cvt_d_s(result, result); 2590 __ cvt_d_s(result, result);
2586 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS 2591 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
2587 __ ldc1(result, MemOperand(scratch0())); 2592 __ ldc1(result, MemOperand(scratch0(), additional_offset));
2588 } 2593 }
2589 } else { 2594 } else {
2590 Register result = ToRegister(instr->result()); 2595 Register result = ToRegister(instr->result());
2591 Register scratch = scratch0(); 2596 Register scratch = scratch0();
2597 if (instr->additional_index() != 0 && !key_is_constant) {
2598 __ Addu(scratch, key, instr->additional_index());
2599 }
2592 MemOperand mem_operand(zero_reg); 2600 MemOperand mem_operand(zero_reg);
2593 if (key_is_constant) { 2601 if (key_is_constant) {
2594 mem_operand = MemOperand(external_pointer, 2602 mem_operand = MemOperand(external_pointer,
2595 constant_key * (1 << shift_size)); 2603 (constant_key << shift_size) + additional_offset) ;
Massi 2012/05/24 09:01:31 Nit: the line exceeds 80 chars.
2596 } else { 2604 } else {
2597 __ sll(scratch, key, shift_size); 2605 if (instr->additional_index() == 0) {
2606 __ sll(scratch, key, shift_size);
2607 } else {
2608 __ sll(scratch, scratch, shift_size);
2609 }
2598 __ Addu(scratch, scratch, external_pointer); 2610 __ Addu(scratch, scratch, external_pointer);
2599 mem_operand = MemOperand(scratch); 2611 mem_operand = MemOperand(scratch);
2600 } 2612 }
2601 switch (elements_kind) { 2613 switch (elements_kind) {
2602 case EXTERNAL_BYTE_ELEMENTS: 2614 case EXTERNAL_BYTE_ELEMENTS:
2603 __ lb(result, mem_operand); 2615 __ lb(result, mem_operand);
2604 break; 2616 break;
2605 case EXTERNAL_PIXEL_ELEMENTS: 2617 case EXTERNAL_PIXEL_ELEMENTS:
2606 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 2618 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
2607 __ lbu(result, mem_operand); 2619 __ lbu(result, mem_operand);
(...skipping 897 matching lines...) Expand 10 before | Expand all | Expand 10 after
3505 Register value = ToRegister(instr->value()); 3517 Register value = ToRegister(instr->value());
3506 Register elements = ToRegister(instr->object()); 3518 Register elements = ToRegister(instr->object());
3507 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; 3519 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg;
3508 Register scratch = scratch0(); 3520 Register scratch = scratch0();
3509 3521
3510 // Do the store. 3522 // Do the store.
3511 if (instr->key()->IsConstantOperand()) { 3523 if (instr->key()->IsConstantOperand()) {
3512 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); 3524 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
3513 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); 3525 LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
3514 int offset = 3526 int offset =
3515 ToInteger32(const_operand) * kPointerSize + FixedArray::kHeaderSize; 3527 (ToInteger32(const_operand) + instr->additional_index()) * kPointerSize
3528 + FixedArray::kHeaderSize;
3516 __ sw(value, FieldMemOperand(elements, offset)); 3529 __ sw(value, FieldMemOperand(elements, offset));
3517 } else { 3530 } else {
3518 __ sll(scratch, key, kPointerSizeLog2); 3531 __ sll(scratch, key, kPointerSizeLog2);
3519 __ addu(scratch, elements, scratch); 3532 __ addu(scratch, elements, scratch);
3533 if (instr->additional_index() != 0) {
3534 __ Addu(scratch,
3535 scratch,
3536 instr->additional_index() << kPointerSizeLog2);
3537 }
3520 __ sw(value, FieldMemOperand(scratch, FixedArray::kHeaderSize)); 3538 __ sw(value, FieldMemOperand(scratch, FixedArray::kHeaderSize));
3521 } 3539 }
3522 3540
3523 if (instr->hydrogen()->NeedsWriteBarrier()) { 3541 if (instr->hydrogen()->NeedsWriteBarrier()) {
3524 HType type = instr->hydrogen()->value()->type(); 3542 HType type = instr->hydrogen()->value()->type();
3525 SmiCheck check_needed = 3543 SmiCheck check_needed =
3526 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 3544 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
3527 // Compute address of modified element and store it into key register. 3545 // Compute address of modified element and store it into key register.
3528 __ Addu(key, scratch, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 3546 __ Addu(key, scratch, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
3529 __ RecordWrite(elements, 3547 __ RecordWrite(elements,
(...skipping 22 matching lines...) Expand all
3552 if (key_is_constant) { 3570 if (key_is_constant) {
3553 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); 3571 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
3554 if (constant_key & 0xF0000000) { 3572 if (constant_key & 0xF0000000) {
3555 Abort("array index constant value too big."); 3573 Abort("array index constant value too big.");
3556 } 3574 }
3557 } else { 3575 } else {
3558 key = ToRegister(instr->key()); 3576 key = ToRegister(instr->key());
3559 } 3577 }
3560 int shift_size = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); 3578 int shift_size = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
3561 if (key_is_constant) { 3579 if (key_is_constant) {
3562 __ Addu(scratch, elements, Operand(constant_key * (1 << shift_size) + 3580 __ Addu(scratch, elements, Operand((constant_key << shift_size) +
3563 FixedDoubleArray::kHeaderSize - kHeapObjectTag)); 3581 FixedDoubleArray::kHeaderSize - kHeapObjectTag));
3564 } else { 3582 } else {
3565 __ sll(scratch, key, shift_size); 3583 __ sll(scratch, key, shift_size);
3566 __ Addu(scratch, elements, Operand(scratch)); 3584 __ Addu(scratch, elements, Operand(scratch));
3567 __ Addu(scratch, scratch, 3585 __ Addu(scratch, scratch,
3568 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); 3586 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
3569 } 3587 }
3570 3588
3571 if (instr->NeedsCanonicalization()) { 3589 if (instr->NeedsCanonicalization()) {
3572 Label is_nan; 3590 Label is_nan;
3573 // Check for NaN. All NaNs must be canonicalized. 3591 // Check for NaN. All NaNs must be canonicalized.
3574 __ BranchF(NULL, &is_nan, eq, value, value); 3592 __ BranchF(NULL, &is_nan, eq, value, value);
3575 __ Branch(&not_nan); 3593 __ Branch(&not_nan);
3576 3594
3577 // Only load canonical NaN if the comparison above set the overflow. 3595 // Only load canonical NaN if the comparison above set the overflow.
3578 __ bind(&is_nan); 3596 __ bind(&is_nan);
3579 __ Move(value, FixedDoubleArray::canonical_not_the_hole_nan_as_double()); 3597 __ Move(value, FixedDoubleArray::canonical_not_the_hole_nan_as_double());
3580 } 3598 }
3581 3599
3582 __ bind(&not_nan); 3600 __ bind(&not_nan);
3583 __ sdc1(value, MemOperand(scratch)); 3601 __ sdc1(value, MemOperand(scratch, instr->additional_index() << shift_size));
3584 } 3602 }
3585 3603
3586 3604
3587 void LCodeGen::DoStoreKeyedSpecializedArrayElement( 3605 void LCodeGen::DoStoreKeyedSpecializedArrayElement(
3588 LStoreKeyedSpecializedArrayElement* instr) { 3606 LStoreKeyedSpecializedArrayElement* instr) {
3589 3607
3590 Register external_pointer = ToRegister(instr->external_pointer()); 3608 Register external_pointer = ToRegister(instr->external_pointer());
3591 Register key = no_reg; 3609 Register key = no_reg;
3592 ElementsKind elements_kind = instr->elements_kind(); 3610 ElementsKind elements_kind = instr->elements_kind();
3593 bool key_is_constant = instr->key()->IsConstantOperand(); 3611 bool key_is_constant = instr->key()->IsConstantOperand();
3594 int constant_key = 0; 3612 int constant_key = 0;
3595 if (key_is_constant) { 3613 if (key_is_constant) {
3596 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); 3614 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
3597 if (constant_key & 0xF0000000) { 3615 if (constant_key & 0xF0000000) {
3598 Abort("array index constant value too big."); 3616 Abort("array index constant value too big.");
3599 } 3617 }
3600 } else { 3618 } else {
3601 key = ToRegister(instr->key()); 3619 key = ToRegister(instr->key());
3602 } 3620 }
3603 int shift_size = ElementsKindToShiftSize(elements_kind); 3621 int shift_size = ElementsKindToShiftSize(elements_kind);
3622 int additional_offset = instr->additional_index() << shift_size;
3604 3623
3605 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 3624 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
3606 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 3625 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
3607 FPURegister value(ToDoubleRegister(instr->value())); 3626 FPURegister value(ToDoubleRegister(instr->value()));
3608 if (key_is_constant) { 3627 if (key_is_constant) {
3609 __ Addu(scratch0(), external_pointer, constant_key * (1 << shift_size)); 3628 __ Addu(scratch0(), external_pointer, constant_key << shift_size);
3610 } else { 3629 } else {
3611 __ sll(scratch0(), key, shift_size); 3630 __ sll(scratch0(), key, shift_size);
3612 __ Addu(scratch0(), scratch0(), external_pointer); 3631 __ Addu(scratch0(), scratch0(), external_pointer);
3613 } 3632 }
3614 3633
3615 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { 3634 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3616 __ cvt_s_d(double_scratch0(), value); 3635 __ cvt_s_d(double_scratch0(), value);
3617 __ swc1(double_scratch0(), MemOperand(scratch0())); 3636 __ swc1(double_scratch0(), MemOperand(scratch0(), additional_offset));
3618 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS 3637 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
3619 __ sdc1(value, MemOperand(scratch0())); 3638 __ sdc1(value, MemOperand(scratch0(), additional_offset));
3620 } 3639 }
3621 } else { 3640 } else {
3622 Register value(ToRegister(instr->value())); 3641 Register value(ToRegister(instr->value()));
3642 Register scratch = scratch0();
3643 if (instr->additional_index() != 0 && !key_is_constant) {
3644 __ Addu(scratch0(), key, instr->additional_index());
Massi 2012/05/24 09:01:31 You moved the declaration "Register scratch = scra
palfia 2012/05/24 16:16:33 Yes, it is much cleaner.
3645 }
3623 MemOperand mem_operand(zero_reg); 3646 MemOperand mem_operand(zero_reg);
3624 Register scratch = scratch0();
3625 if (key_is_constant) { 3647 if (key_is_constant) {
3626 mem_operand = MemOperand(external_pointer, 3648 mem_operand = MemOperand(external_pointer,
3627 constant_key * (1 << shift_size)); 3649 ((constant_key + instr->additional_index())
3650 << shift_size));
3628 } else { 3651 } else {
3629 __ sll(scratch, key, shift_size); 3652 if (instr->additional_index() == 0) {
3653 __ sll(scratch, key, shift_size);
3654 } else {
3655 __ sll(scratch, scratch, shift_size);
3656 }
3630 __ Addu(scratch, scratch, external_pointer); 3657 __ Addu(scratch, scratch, external_pointer);
3631 mem_operand = MemOperand(scratch); 3658 mem_operand = MemOperand(scratch);
3632 } 3659 }
3633 switch (elements_kind) { 3660 switch (elements_kind) {
3634 case EXTERNAL_PIXEL_ELEMENTS: 3661 case EXTERNAL_PIXEL_ELEMENTS:
3635 case EXTERNAL_BYTE_ELEMENTS: 3662 case EXTERNAL_BYTE_ELEMENTS:
3636 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 3663 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3637 __ sb(value, mem_operand); 3664 __ sb(value, mem_operand);
3638 break; 3665 break;
3639 case EXTERNAL_SHORT_ELEMENTS: 3666 case EXTERNAL_SHORT_ELEMENTS:
(...skipping 1495 matching lines...) Expand 10 before | Expand all | Expand 10 after
5135 __ Subu(scratch, result, scratch); 5162 __ Subu(scratch, result, scratch);
5136 __ lw(result, FieldMemOperand(scratch, 5163 __ lw(result, FieldMemOperand(scratch,
5137 FixedArray::kHeaderSize - kPointerSize)); 5164 FixedArray::kHeaderSize - kPointerSize));
5138 __ bind(&done); 5165 __ bind(&done);
5139 } 5166 }
5140 5167
5141 5168
5142 #undef __ 5169 #undef __
5143 5170
5144 } } // namespace v8::internal 5171 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/mips/lithium-mips.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698