[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