[fpc-devel] More peephole
Martin
lazarus at mfriebe.de
Mon Jan 20 01:18:16 CET 2014
Just been looking at the peehole opt (i386). Other than the 2 items
already mailed, I found that:
1) Gode as follows is sometimes generated (at various opt levels)
.Ll2:
# [36] i := 1;
movl $1,%eax
.Ll3:
# [38] i := i + 1;
movl $2,%eax
I could not find any code dealing with it, and added some. It does catch
a noticeable amount of occurrences during build of fpc and lazarus.
2)
Commented existing code (apparently since revision 1) for
{movl [mem1],reg1 to movl [mem1],reg1
movl [mem1],reg2 movl reg1,reg2 }
It used
(taicpu(p).oper[1]^.reg<>taicpu(hp1).oper[0]^^.ref^.base) and
(taicpu(p).oper[1]^.reg<>taicpu(hp1).oper[0]^^.ref^.index) then
but should only compare the supregister part
I replaced that
not(RegInOp(getsupreg(taicpu(p).oper[1]^.reg),taicpu(hp1).oper[0]^)) then
uncommented, and tested.
It does catch a big lot of occurrences.
Both pass all tests form the test dir (except those failing already (see
my other mail / compared at slightly diff settings)
Both build a working FPC and Lazarus.
Patch with all 3 changes at the end of the mail. I will separate them,
if all else is ok, and needed.
New Code
for removing double move to register. Code is in a block where opsize,
and other restraints have already been confirmed.
if (taicpu(p).oper[1]^.typ = top_reg) and
(taicpu(hp1).oper[1]^.typ = top_reg) and
(taicpu(p).oper[1]^.reg =
taicpu(hp1).oper[1]^.reg) and
not(RegInOp(getsupreg(taicpu(p).oper[1]^.reg),taicpu(hp1).oper[0]^)) then
{ We have mov xxx, reg1 mov yyy, reg1 }
begin
asml.remove(p);
p.free;
p := hp1;
end
existing, now uncommented
else
{movl [mem1],reg1 to movl [mem1],reg1
movl [mem1],reg2 movl reg1,reg2 }
if (taicpu(p).oper[0]^.typ = top_ref) and
(taicpu(p).oper[1]^.typ = top_reg) and
(taicpu(hp1).oper[0]^.typ = top_ref) and
(taicpu(hp1).oper[1]^.typ = top_reg) and
RefsEqual(TReference(taicpu(p).oper[0]^.ref^),taicpu(hp1).oper[0]^.ref^) and
not(RegInOp(getsupreg(taicpu(p).oper[1]^.reg),taicpu(hp1).oper[0]^)) then
//(taicpu(p).oper[1]^.reg<>taicpu(hp1).oper[0]^^.ref^.base) and
//(taicpu(p).oper[1]^.reg<>taicpu(hp1).oper[0]^^.ref^.index) then
begin
taicpu(hp1).loadReg(0,taicpu(p).oper[1]^.reg)
end
Index: compiler/i386/popt386.pas
===================================================================
--- compiler/i386/popt386.pas (revision 26519)
+++ compiler/i386/popt386.pas (working copy)
@@ -1369,39 +1369,50 @@
end
end
else
-(* {movl [mem1],reg1
- movl [mem1],reg2
- to:
- movl [mem1],reg1
- movl reg1,reg2 }
- if (taicpu(p).oper[0]^.typ = top_ref) and
- (taicpu(p).oper[1]^.typ = top_reg) and
- (taicpu(hp1).oper[0]^.typ = top_ref) and
- (taicpu(hp1).oper[1]^.typ = top_reg) and
- (taicpu(p).opsize = taicpu(hp1).opsize) and
- RefsEqual(TReference(taicpu(p).oper[0]^^),taicpu(hp1).oper[0]^^.ref^) and
- (taicpu(p).oper[1]^.reg<>taicpu(hp1).oper[0]^^.ref^.base) and
- (taicpu(p).oper[1]^.reg<>taicpu(hp1).oper[0]^^.ref^.index) then
- taicpu(hp1).loadReg(0,taicpu(p).oper[1]^.reg)
- else*)
- { movl const1,[mem1]
- movl [mem1],reg1
- to:
- movl const1,reg1
- movl reg1,[mem1] }
- if (taicpu(p).oper[0]^.typ = top_const) and
- (taicpu(p).oper[1]^.typ = top_ref) and
+ if (taicpu(p).oper[1]^.typ = top_reg) and
+ (taicpu(hp1).oper[1]^.typ = top_reg) and
+ (taicpu(p).oper[1]^.reg =
taicpu(hp1).oper[1]^.reg) and
+ not(RegInOp(getsupreg(taicpu(p).oper[1]^.reg),taicpu(hp1).oper[0]^)) then
+ { We have mov xxx, reg1 mov yyy, reg1 }
+ begin
+ asml.remove(p);
+ p.free;
+ p := hp1;
+ end
+ else
+ {movl [mem1],reg1 to movl [mem1],reg1
+ movl [mem1],reg2 movl reg1,reg2 }
+ if (taicpu(p).oper[0]^.typ = top_ref) and
+ (taicpu(p).oper[1]^.typ = top_reg) and
(taicpu(hp1).oper[0]^.typ = top_ref) and
(taicpu(hp1).oper[1]^.typ = top_reg) and
- (taicpu(p).opsize =
taicpu(hp1).opsize) and
- RefsEqual(taicpu(hp1).oper[0]^.ref^,taicpu(p).oper[1]^.ref^) and
-
not(reginref(getsupreg(taicpu(hp1).oper[1]^.reg),taicpu(hp1).oper[0]^.ref^))
then
+
RefsEqual(TReference(taicpu(p).oper[0]^.ref^),taicpu(hp1).oper[0]^.ref^) and
+ not(RegInOp(getsupreg(taicpu(p).oper[1]^.reg),taicpu(hp1).oper[0]^)) then
+ //(taicpu(p).oper[1]^.reg<>taicpu(hp1).oper[0]^^.ref^.base) and
+ //(taicpu(p).oper[1]^.reg<>taicpu(hp1).oper[0]^^.ref^.index) then
begin
- allocregbetween(asml,taicpu(hp1).oper[1]^.reg,p,hp1,usedregs);
- taicpu(hp1).loadReg(0,taicpu(hp1).oper[1]^.reg);
- taicpu(hp1).loadRef(1,taicpu(p).oper[1]^.ref^);
- taicpu(p).loadReg(1,taicpu(hp1).oper[0]^.reg);
+ taicpu(hp1).loadReg(0,taicpu(p).oper[1]^.reg)
end
+ else
+ { movl const1,[mem1]
+ movl [mem1],reg1
+ to:
+ movl const1,reg1
+ movl reg1,[mem1] }
+ if (taicpu(p).oper[0]^.typ = top_const) and
+ (taicpu(p).oper[1]^.typ = top_ref) and
+ (taicpu(hp1).oper[0]^.typ = top_ref) and
+ (taicpu(hp1).oper[1]^.typ = top_reg) and
+ RefsEqual(taicpu(hp1).oper[0]^.ref^,taicpu(p).oper[1]^.ref^) and
+
not(reginref(getsupreg(taicpu(hp1).oper[1]^.reg),taicpu(hp1).oper[0]^.ref^))
then
+ begin
+ allocregbetween(asml,taicpu(hp1).oper[1]^.reg,p,hp1,usedregs);
+ taicpu(hp1).loadReg(0,taicpu(hp1).oper[1]^.reg);
+ taicpu(hp1).loadRef(1,taicpu(p).oper[1]^.ref^);
+ taicpu(p).loadReg(1,taicpu(hp1).oper[0]^.reg);
+ // Storing the value to memory
should be part of the first instruction
+ taicpu(hp1).fileinfo :=
taicpu(p).fileinfo;
+ end;
end;
if GetNextInstruction(p, hp1) and
MatchInstruction(hp1,A_BTS,A_BTR,[Taicpu(p).opsize]) and
More information about the fpc-devel
mailing list