diff options
author | Magnus Lång <[email protected]> | 2016-06-04 20:10:02 +0200 |
---|---|---|
committer | Magnus Lång <[email protected]> | 2016-08-30 17:19:13 +0200 |
commit | 1567585dda8bc604871be06a37aa5d19ad6d28f3 (patch) | |
tree | 459dd0611f10364ee930227d63b5693baddd93cc /lib/hipe/x86/hipe_x86_ra_postconditions.erl | |
parent | cca2b0a38dd4cbc3dfef026e0d8c2cba57270935 (diff) | |
download | otp-1567585dda8bc604871be06a37aa5d19ad6d28f3.tar.gz otp-1567585dda8bc604871be06a37aa5d19ad6d28f3.tar.bz2 otp-1567585dda8bc604871be06a37aa5d19ad6d28f3.zip |
hipe_x86: Use lea instead of move+add
This is primarily useful for heap allocations, as a two-address 'add'
can't be used to both copy the heap pointer to another register, and add
the tag.
Diffstat (limited to 'lib/hipe/x86/hipe_x86_ra_postconditions.erl')
-rw-r--r-- | lib/hipe/x86/hipe_x86_ra_postconditions.erl | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/lib/hipe/x86/hipe_x86_ra_postconditions.erl b/lib/hipe/x86/hipe_x86_ra_postconditions.erl index 343d04977d..c73d029b9b 100644 --- a/lib/hipe/x86/hipe_x86_ra_postconditions.erl +++ b/lib/hipe/x86/hipe_x86_ra_postconditions.erl @@ -173,14 +173,22 @@ do_jmp_switch(I, TempMap, Strategy) -> %%% Fix a lea op. do_lea(I, TempMap, Strategy) -> - #lea{temp=Temp} = I, - case is_spilled(Temp, TempMap) of - false -> - {[I], false}; - true -> - NewTmp = spill_temp('untagged', Strategy), - {[I#lea{temp=NewTmp}, hipe_x86:mk_move(NewTmp, Temp)], - true} + #lea{mem=Mem0,temp=Temp0} = I, + {FixMem, Mem, DidSpill1} = fix_mem_operand(Mem0, TempMap, temp1(Strategy)), + case Mem of + #x86_mem{base=Base, off=#x86_imm{value=0}} -> + %% We've decayed into a move due to both operands being memory (there's an + %% 'add' in FixMem). + {FixMem ++ [hipe_x86:mk_move(Base, Temp0)], DidSpill1}; + #x86_mem{} -> + {StoreTemp, Temp, DidSpill2} = + case is_mem_opnd(Temp0, TempMap) of + false -> {[], Temp0, false}; + true -> + Temp1 = clone2(Temp0, temp0(Strategy)), + {[hipe_x86:mk_move(Temp1, Temp0)], Temp1, true} + end, + {FixMem ++ [I#lea{mem=Mem,temp=Temp} | StoreTemp], DidSpill1 or DidSpill2} end. %%% Fix a move op. |