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

Side by Side Diff: src/compiler/ppc/code-generator-ppc.cc

Issue 2123983002: PPC/s390: [turbofan]: Support using push instructions for setting up tail call parameters (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 5 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
« no previous file with comments | « no previous file | src/compiler/s390/code-generator-s390.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 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/code-generator.h" 5 #include "src/compiler/code-generator.h"
6 6
7 #include "src/ast/scopes.h" 7 #include "src/ast/scopes.h"
8 #include "src/compiler/code-generator-impl.h" 8 #include "src/compiler/code-generator-impl.h"
9 #include "src/compiler/gap-resolver.h" 9 #include "src/compiler/gap-resolver.h"
10 #include "src/compiler/node-matchers.h" 10 #include "src/compiler/node-matchers.h"
(...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after
721 } else { \ 721 } else { \
722 __ asm_instrx(value, operand); \ 722 __ asm_instrx(value, operand); \
723 } \ 723 } \
724 DCHECK_EQ(LeaveRC, i.OutputRCBit()); \ 724 DCHECK_EQ(LeaveRC, i.OutputRCBit()); \
725 } while (0) 725 } while (0)
726 726
727 void CodeGenerator::AssembleDeconstructFrame() { 727 void CodeGenerator::AssembleDeconstructFrame() {
728 __ LeaveFrame(StackFrame::MANUAL); 728 __ LeaveFrame(StackFrame::MANUAL);
729 } 729 }
730 730
731 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { 731 void CodeGenerator::AssemblePrepareTailCall() {
732 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
733 if (sp_slot_delta > 0) {
734 __ Add(sp, sp, sp_slot_delta * kPointerSize, r0);
735 }
736 frame_access_state()->SetFrameAccessToDefault();
737 }
738
739
740 void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) {
741 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
742 if (sp_slot_delta < 0) {
743 __ Add(sp, sp, sp_slot_delta * kPointerSize, r0);
744 frame_access_state()->IncreaseSPDelta(-sp_slot_delta);
745 }
746 if (frame_access_state()->has_frame()) { 732 if (frame_access_state()->has_frame()) {
747 __ RestoreFrameStateForTailCall(); 733 __ RestoreFrameStateForTailCall();
748 } 734 }
749 frame_access_state()->SetFrameAccessToSP(); 735 frame_access_state()->SetFrameAccessToSP();
750 } 736 }
751 737
752 void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg, 738 void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
753 Register scratch1, 739 Register scratch1,
754 Register scratch2, 740 Register scratch2,
755 Register scratch3) { 741 Register scratch3) {
(...skipping 11 matching lines...) Expand all
767 __ LoadP(caller_args_count_reg, 753 __ LoadP(caller_args_count_reg,
768 MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset)); 754 MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
769 __ SmiUntag(caller_args_count_reg); 755 __ SmiUntag(caller_args_count_reg);
770 756
771 ParameterCount callee_args_count(args_reg); 757 ParameterCount callee_args_count(args_reg);
772 __ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2, 758 __ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2,
773 scratch3); 759 scratch3);
774 __ bind(&done); 760 __ bind(&done);
775 } 761 }
776 762
763 namespace {
764
765 void FlushPendingPushRegisters(MacroAssembler* masm,
766 FrameAccessState* frame_access_state,
767 ZoneVector<Register>* pending_pushes) {
768 switch (pending_pushes->size()) {
769 case 0:
770 break;
771 case 1:
772 masm->Push((*pending_pushes)[0]);
773 break;
774 case 2:
775 masm->Push((*pending_pushes)[0], (*pending_pushes)[1]);
776 break;
777 case 3:
778 masm->Push((*pending_pushes)[0], (*pending_pushes)[1],
779 (*pending_pushes)[2]);
780 break;
781 default:
782 UNREACHABLE();
783 break;
784 }
785 frame_access_state->IncreaseSPDelta(pending_pushes->size());
786 pending_pushes->resize(0);
787 }
788
789 void AddPendingPushRegister(MacroAssembler* masm,
790 FrameAccessState* frame_access_state,
791 ZoneVector<Register>* pending_pushes,
792 Register reg) {
793 pending_pushes->push_back(reg);
794 if (pending_pushes->size() == 3 || reg.is(ip)) {
795 FlushPendingPushRegisters(masm, frame_access_state, pending_pushes);
796 }
797 }
798
799 void AdjustStackPointerForTailCall(
800 MacroAssembler* masm, FrameAccessState* state, int new_slot_above_sp,
801 ZoneVector<Register>* pending_pushes = nullptr,
802 bool allow_shrinkage = true) {
803 int current_sp_offset = state->GetSPToFPSlotCount() +
804 StandardFrameConstants::kFixedSlotCountAboveFp;
805 int stack_slot_delta = new_slot_above_sp - current_sp_offset;
806 if (stack_slot_delta > 0) {
807 if (pending_pushes != nullptr) {
808 FlushPendingPushRegisters(masm, state, pending_pushes);
809 }
810 masm->Add(sp, sp, -stack_slot_delta * kPointerSize, r0);
811 state->IncreaseSPDelta(stack_slot_delta);
812 } else if (allow_shrinkage && stack_slot_delta < 0) {
813 if (pending_pushes != nullptr) {
814 FlushPendingPushRegisters(masm, state, pending_pushes);
815 }
816 masm->Add(sp, sp, -stack_slot_delta * kPointerSize, r0);
817 state->IncreaseSPDelta(stack_slot_delta);
818 }
819 }
820
821 } // namespace
822
823 void CodeGenerator::AssembleTailCallBeforeGap(Instruction* instr,
824 int first_unused_stack_slot) {
825 CodeGenerator::PushTypeFlags flags(kImmediatePush | kScalarPush);
826 ZoneVector<MoveOperands*> pushes(zone());
827 GetPushCompatibleMoves(instr, flags, &pushes);
828
829 if (!pushes.empty() &&
830 (LocationOperand::cast(pushes.back()->destination()).index() + 1 ==
831 first_unused_stack_slot)) {
832 PPCOperandConverter g(this, instr);
833 ZoneVector<Register> pending_pushes(zone());
834 for (auto move : pushes) {
835 LocationOperand destination_location(
836 LocationOperand::cast(move->destination()));
837 InstructionOperand source(move->source());
838 AdjustStackPointerForTailCall(
839 masm(), frame_access_state(),
840 destination_location.index() - pending_pushes.size(),
841 &pending_pushes);
842 if (source.IsStackSlot()) {
843 LocationOperand source_location(LocationOperand::cast(source));
844 __ LoadP(ip, g.SlotToMemOperand(source_location.index()));
845 AddPendingPushRegister(masm(), frame_access_state(), &pending_pushes,
846 ip);
847 } else if (source.IsRegister()) {
848 LocationOperand source_location(LocationOperand::cast(source));
849 AddPendingPushRegister(masm(), frame_access_state(), &pending_pushes,
850 source_location.GetRegister());
851 } else if (source.IsImmediate()) {
852 AddPendingPushRegister(masm(), frame_access_state(), &pending_pushes,
853 ip);
854 } else {
855 // Pushes of non-scalar data types is not supported.
856 UNIMPLEMENTED();
857 }
858 move->Eliminate();
859 }
860 FlushPendingPushRegisters(masm(), frame_access_state(), &pending_pushes);
861 }
862 AdjustStackPointerForTailCall(masm(), frame_access_state(),
863 first_unused_stack_slot, nullptr, false);
864 }
865
866 void CodeGenerator::AssembleTailCallAfterGap(Instruction* instr,
867 int first_unused_stack_slot) {
868 AdjustStackPointerForTailCall(masm(), frame_access_state(),
869 first_unused_stack_slot);
870 }
871
872
777 // Assembles an instruction after register allocation, producing machine code. 873 // Assembles an instruction after register allocation, producing machine code.
778 CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( 874 CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
779 Instruction* instr) { 875 Instruction* instr) {
780 PPCOperandConverter i(this, instr); 876 PPCOperandConverter i(this, instr);
781 ArchOpcode opcode = ArchOpcodeField::decode(instr->opcode()); 877 ArchOpcode opcode = ArchOpcodeField::decode(instr->opcode());
782 878
783 switch (opcode) { 879 switch (opcode) {
784 case kArchCallCodeObject: { 880 case kArchCallCodeObject: {
785 v8::internal::Assembler::BlockTrampolinePoolScope block_trampoline_pool( 881 v8::internal::Assembler::BlockTrampolinePoolScope block_trampoline_pool(
786 masm()); 882 masm());
787 EnsureSpaceForLazyDeopt(); 883 EnsureSpaceForLazyDeopt();
788 if (HasRegisterInput(instr, 0)) { 884 if (HasRegisterInput(instr, 0)) {
789 __ addi(ip, i.InputRegister(0), 885 __ addi(ip, i.InputRegister(0),
790 Operand(Code::kHeaderSize - kHeapObjectTag)); 886 Operand(Code::kHeaderSize - kHeapObjectTag));
791 __ Call(ip); 887 __ Call(ip);
792 } else { 888 } else {
793 __ Call(Handle<Code>::cast(i.InputHeapObject(0)), 889 __ Call(Handle<Code>::cast(i.InputHeapObject(0)),
794 RelocInfo::CODE_TARGET); 890 RelocInfo::CODE_TARGET);
795 } 891 }
796 RecordCallPosition(instr); 892 RecordCallPosition(instr);
797 DCHECK_EQ(LeaveRC, i.OutputRCBit()); 893 DCHECK_EQ(LeaveRC, i.OutputRCBit());
798 frame_access_state()->ClearSPDelta(); 894 frame_access_state()->ClearSPDelta();
799 break; 895 break;
800 } 896 }
801 case kArchTailCallCodeObjectFromJSFunction: 897 case kArchTailCallCodeObjectFromJSFunction:
802 case kArchTailCallCodeObject: { 898 case kArchTailCallCodeObject: {
803 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
804 AssembleDeconstructActivationRecord(stack_param_delta);
805 if (opcode == kArchTailCallCodeObjectFromJSFunction) { 899 if (opcode == kArchTailCallCodeObjectFromJSFunction) {
806 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister, 900 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
807 i.TempRegister(0), i.TempRegister(1), 901 i.TempRegister(0), i.TempRegister(1),
808 i.TempRegister(2)); 902 i.TempRegister(2));
809 } 903 }
810 if (HasRegisterInput(instr, 0)) { 904 if (HasRegisterInput(instr, 0)) {
811 __ addi(ip, i.InputRegister(0), 905 __ addi(ip, i.InputRegister(0),
812 Operand(Code::kHeaderSize - kHeapObjectTag)); 906 Operand(Code::kHeaderSize - kHeapObjectTag));
813 __ Jump(ip); 907 __ Jump(ip);
814 } else { 908 } else {
815 // We cannot use the constant pool to load the target since 909 // We cannot use the constant pool to load the target since
816 // we've already restored the caller's frame. 910 // we've already restored the caller's frame.
817 ConstantPoolUnavailableScope constant_pool_unavailable(masm()); 911 ConstantPoolUnavailableScope constant_pool_unavailable(masm());
818 __ Jump(Handle<Code>::cast(i.InputHeapObject(0)), 912 __ Jump(Handle<Code>::cast(i.InputHeapObject(0)),
819 RelocInfo::CODE_TARGET); 913 RelocInfo::CODE_TARGET);
820 } 914 }
821 DCHECK_EQ(LeaveRC, i.OutputRCBit()); 915 DCHECK_EQ(LeaveRC, i.OutputRCBit());
822 frame_access_state()->ClearSPDelta(); 916 frame_access_state()->ClearSPDelta();
917 frame_access_state()->SetFrameAccessToDefault();
823 break; 918 break;
824 } 919 }
825 case kArchTailCallAddress: { 920 case kArchTailCallAddress: {
826 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
827 AssembleDeconstructActivationRecord(stack_param_delta);
828 CHECK(!instr->InputAt(0)->IsImmediate()); 921 CHECK(!instr->InputAt(0)->IsImmediate());
829 __ Jump(i.InputRegister(0)); 922 __ Jump(i.InputRegister(0));
830 frame_access_state()->ClearSPDelta(); 923 frame_access_state()->ClearSPDelta();
924 frame_access_state()->SetFrameAccessToDefault();
831 break; 925 break;
832 } 926 }
833 case kArchCallJSFunction: { 927 case kArchCallJSFunction: {
834 v8::internal::Assembler::BlockTrampolinePoolScope block_trampoline_pool( 928 v8::internal::Assembler::BlockTrampolinePoolScope block_trampoline_pool(
835 masm()); 929 masm());
836 EnsureSpaceForLazyDeopt(); 930 EnsureSpaceForLazyDeopt();
837 Register func = i.InputRegister(0); 931 Register func = i.InputRegister(0);
838 if (FLAG_debug_code) { 932 if (FLAG_debug_code) {
839 // Check the function's context matches the context argument. 933 // Check the function's context matches the context argument.
840 __ LoadP(kScratchReg, 934 __ LoadP(kScratchReg,
(...skipping 11 matching lines...) Expand all
852 case kArchTailCallJSFunctionFromJSFunction: 946 case kArchTailCallJSFunctionFromJSFunction:
853 case kArchTailCallJSFunction: { 947 case kArchTailCallJSFunction: {
854 Register func = i.InputRegister(0); 948 Register func = i.InputRegister(0);
855 if (FLAG_debug_code) { 949 if (FLAG_debug_code) {
856 // Check the function's context matches the context argument. 950 // Check the function's context matches the context argument.
857 __ LoadP(kScratchReg, 951 __ LoadP(kScratchReg,
858 FieldMemOperand(func, JSFunction::kContextOffset)); 952 FieldMemOperand(func, JSFunction::kContextOffset));
859 __ cmp(cp, kScratchReg); 953 __ cmp(cp, kScratchReg);
860 __ Assert(eq, kWrongFunctionContext); 954 __ Assert(eq, kWrongFunctionContext);
861 } 955 }
862 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
863 AssembleDeconstructActivationRecord(stack_param_delta);
864 if (opcode == kArchTailCallJSFunctionFromJSFunction) { 956 if (opcode == kArchTailCallJSFunctionFromJSFunction) {
865 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister, 957 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
866 i.TempRegister(0), i.TempRegister(1), 958 i.TempRegister(0), i.TempRegister(1),
867 i.TempRegister(2)); 959 i.TempRegister(2));
868 } 960 }
869 __ LoadP(ip, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); 961 __ LoadP(ip, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
870 __ Jump(ip); 962 __ Jump(ip);
871 DCHECK_EQ(LeaveRC, i.OutputRCBit()); 963 DCHECK_EQ(LeaveRC, i.OutputRCBit());
872 frame_access_state()->ClearSPDelta(); 964 frame_access_state()->ClearSPDelta();
965 frame_access_state()->SetFrameAccessToDefault();
873 break; 966 break;
874 } 967 }
875 case kArchPrepareCallCFunction: { 968 case kArchPrepareCallCFunction: {
876 int const num_parameters = MiscField::decode(instr->opcode()); 969 int const num_parameters = MiscField::decode(instr->opcode());
877 __ PrepareCallCFunction(num_parameters, kScratchReg); 970 __ PrepareCallCFunction(num_parameters, kScratchReg);
878 // Frame alignment requires using FP-relative frame addressing. 971 // Frame alignment requires using FP-relative frame addressing.
879 frame_access_state()->SetFrameAccessToFP(); 972 frame_access_state()->SetFrameAccessToFP();
880 break; 973 break;
881 } 974 }
882 case kArchPrepareTailCall: 975 case kArchPrepareTailCall:
883 AssemblePrepareTailCall(i.InputInt32(instr->InputCount() - 1)); 976 AssemblePrepareTailCall();
884 break; 977 break;
885 case kArchCallCFunction: { 978 case kArchCallCFunction: {
886 int const num_parameters = MiscField::decode(instr->opcode()); 979 int const num_parameters = MiscField::decode(instr->opcode());
887 if (instr->InputAt(0)->IsImmediate()) { 980 if (instr->InputAt(0)->IsImmediate()) {
888 ExternalReference ref = i.InputExternalReference(0); 981 ExternalReference ref = i.InputExternalReference(0);
889 __ CallCFunction(ref, num_parameters); 982 __ CallCFunction(ref, num_parameters);
890 } else { 983 } else {
891 Register func = i.InputRegister(0); 984 Register func = i.InputRegister(0);
892 __ CallCFunction(func, num_parameters); 985 __ CallCFunction(func, num_parameters);
893 } 986 }
(...skipping 1357 matching lines...) Expand 10 before | Expand all | Expand 10 after
2251 padding_size -= v8::internal::Assembler::kInstrSize; 2344 padding_size -= v8::internal::Assembler::kInstrSize;
2252 } 2345 }
2253 } 2346 }
2254 } 2347 }
2255 2348
2256 #undef __ 2349 #undef __
2257 2350
2258 } // namespace compiler 2351 } // namespace compiler
2259 } // namespace internal 2352 } // namespace internal
2260 } // namespace v8 2353 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/compiler/s390/code-generator-s390.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698