From c52b2cf226cb3f1bb1b16bee28d47785506adff3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20L=C3=A5ng?= Date: Thu, 16 Mar 2017 15:30:00 +0100 Subject: hipe: Add pseudo_spill_f?move instructions These pseudo instructions are added to all backends and allow spill slot to spill slot move coalescing in a clean way. They have regular move semantics, but contain an additional scratch register to be used if both source and destination are spilled, and can not be move coalesced. Additionally, a register allocator callback Target:is_spill_move(Instr, Context) is added which allows the spill slot allocators to check for these instructions and try to coalesce the spill slots the two temporaries are allocated to. --- lib/hipe/arm/hipe_arm_frame.erl | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'lib/hipe/arm/hipe_arm_frame.erl') diff --git a/lib/hipe/arm/hipe_arm_frame.erl b/lib/hipe/arm/hipe_arm_frame.erl index e323907e31..a1004fb609 100644 --- a/lib/hipe/arm/hipe_arm_frame.erl +++ b/lib/hipe/arm/hipe_arm_frame.erl @@ -69,6 +69,8 @@ do_insn(I, LiveOut, Context, FPoff) -> do_pseudo_call_prepare(I, FPoff); #pseudo_move{} -> {do_pseudo_move(I, Context, FPoff), FPoff}; + #pseudo_spill_move{} -> + {do_pseudo_spill_move(I, Context, FPoff), FPoff}; #pseudo_tailcall{} -> {do_pseudo_tailcall(I, Context), context_framesize(Context)}; _ -> @@ -99,6 +101,26 @@ do_pseudo_move(I, Context, FPoff) -> pseudo_offset(Temp, FPoff, Context) -> FPoff + context_offset(Context, Temp). +%%% +%%% Moves from one spill slot to another +%%% + +do_pseudo_spill_move(I, Context, FPoff) -> + #pseudo_spill_move{dst=Dst, temp=Temp, src=Src} = I, + case temp_is_pseudo(Src) andalso temp_is_pseudo(Dst) of + false -> % Register allocator changed its mind, turn back to move + do_pseudo_move(hipe_arm:mk_pseudo_move(Dst, Src), Context, FPoff); + true -> + SrcOffset = pseudo_offset(Src, FPoff, Context), + DstOffset = pseudo_offset(Dst, FPoff, Context), + case SrcOffset =:= DstOffset of + true -> []; % omit move-to-self + false -> + mk_load('ldr', Temp, SrcOffset, mk_sp(), + mk_store('str', Temp, DstOffset, mk_sp(), [])) + end + end. + %%% %%% Return - deallocate frame and emit 'ret $N' insn. %%% -- cgit v1.2.3