aboutsummaryrefslogtreecommitdiffstats
path: root/lib/hipe/x86/hipe_x86_postpass.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/hipe/x86/hipe_x86_postpass.erl')
-rw-r--r--lib/hipe/x86/hipe_x86_postpass.erl12
1 files changed, 12 insertions, 0 deletions
diff --git a/lib/hipe/x86/hipe_x86_postpass.erl b/lib/hipe/x86/hipe_x86_postpass.erl
index bd232041b6..390f5bf5e7 100644
--- a/lib/hipe/x86/hipe_x86_postpass.erl
+++ b/lib/hipe/x86/hipe_x86_postpass.erl
@@ -183,6 +183,18 @@ peep([B = #alu{aluop=Op,src=#x86_imm{value=Val},dst=Dst}|Insns], Res, Lst) ->
peep(Insns, [B|Res], Lst)
end;
+%% LeaToAdd
+%% This rule transforms lea into add when the destination is the same as one of
+%% the operands. Sound because lea is never used where the condition codes are
+%% live (and would be clobbered by add).
+%% ----------
+peep([#lea{mem=#x86_mem{base=#x86_temp{reg=DstR},off=Src},
+ temp=Dst=#x86_temp{reg=DstR}}|Insns], Res, Lst) ->
+ peep(Insns, [#alu{aluop='add',src=Src,dst=Dst}|Res], [leaToAdd|Lst]);
+peep([#lea{mem=#x86_mem{base=Src,off=#x86_temp{reg=DstR}},
+ temp=Dst=#x86_temp{reg=DstR}}|Insns], Res, Lst) ->
+ peep(Insns, [#alu{aluop='add',src=Src,dst=Dst}|Res], [leaToAdd|Lst]);
+
%% SubToDec
%% This rule turns "subl $1,Dst; jl Lab" into "decl Dst; jl Lab", which
%% changes reduction counter tests to use decl instead of subl.