Bläddra i källkod

+ LeaOp2Op optimization
* replaced some manual removels of p by RemoveCurrentP calls

git-svn-id: trunk@43456 -

florian 5 år sedan
förälder
incheckning
7ee0ad4d63
1 ändrade filer med 72 tillägg och 7 borttagningar
  1. 72 7
      compiler/x86/aoptx86.pas

+ 72 - 7
compiler/x86/aoptx86.pas

@@ -2292,6 +2292,8 @@ unit aoptx86;
       var
         hp1, hp2, hp3: tai;
         l : ASizeInt;
+        ref: Integer;
+        saveref: treference;
       begin
         Result:=false;
         { removes seg register prefixes from LEA operations, as they
@@ -2318,11 +2320,8 @@ unit aoptx86;
               end
             else if (taicpu(p).oper[0]^.ref^.offset = 0) then
               begin
-                hp1:=taicpu(p.Next);
                 DebugMsg(SPeepholeOptimization + 'Lea2Nop done',p);
-                asml.remove(p);
-                p.free;
-                p:=hp1;
+                RemoveCurrentP(p);
                 Result:=true;
                 exit;
               end
@@ -2407,10 +2406,76 @@ unit aoptx86;
             DebugMsg(SPeepholeOptimization + 'LeaLea2Lea done',p);
             inc(taicpu(hp1).oper[0]^.ref^.offset,taicpu(p).oper[0]^.ref^.offset);
             taicpu(hp1).oper[0]^.ref^.base:=taicpu(p).oper[0]^.ref^.base;
-            asml.Remove(p);
-            p.Free;
-            p:=hp1;
+            RemoveCurrentP(p);
             result:=true;
+            exit;
+          end;
+        { changes
+            lea <ref1>, reg1
+            <op> ...,<ref. with reg1>,...
+            to
+            <op> ...,<ref1>,... }
+        if (taicpu(p).oper[1]^.reg<>current_procinfo.framepointer) and
+          (taicpu(p).oper[1]^.reg<>NR_STACK_POINTER_REG) and
+          GetNextInstruction(p,hp1) and
+          (hp1.typ=ait_instruction) and
+          not(MatchInstruction(hp1,A_LEA,[])) then
+          begin
+            if (taicpu(hp1).ops>=1) and (taicpu(hp1).oper[0]^.typ=top_ref) and RegInOp(taicpu(p).oper[1]^.reg,taicpu(hp1).oper[0]^) then
+              ref:=0
+            else if (taicpu(hp1).ops>=2) and (taicpu(hp1).oper[1]^.typ=top_ref) and RegInOp(taicpu(p).oper[1]^.reg,taicpu(hp1).oper[1]^) then
+              ref:=1
+            else
+              ref:=-1;
+            if (ref<>-1) and
+              ((taicpu(hp1).oper[ref]^.ref^.base=taicpu(p).oper[1]^.reg) xor (taicpu(hp1).oper[ref]^.ref^.index=taicpu(p).oper[1]^.reg)) then
+              begin
+                saveref:=taicpu(hp1).oper[ref]^.ref^;
+                if taicpu(hp1).oper[ref]^.ref^.base=taicpu(p).oper[1]^.reg then
+                  taicpu(hp1).oper[ref]^.ref^.base:=NR_NO
+                else if taicpu(hp1).oper[ref]^.ref^.index=taicpu(p).oper[1]^.reg then
+                  taicpu(hp1).oper[ref]^.ref^.index:=NR_NO
+                else
+                  Internalerror(2019111201);
+                if ((taicpu(hp1).oper[ref]^.ref^.base=taicpu(p).oper[1]^.reg) or (taicpu(hp1).oper[ref]^.ref^.scalefactor in [0,1])) and
+                  ((taicpu(p).oper[0]^.ref^.base=NR_NO) or (taicpu(hp1).oper[ref]^.ref^.base=NR_NO)) and
+                  ((taicpu(p).oper[0]^.ref^.index=NR_NO) or (taicpu(hp1).oper[ref]^.ref^.index=NR_NO)) and
+                  ((taicpu(p).oper[0]^.ref^.symbol=nil) or (taicpu(hp1).oper[ref]^.ref^.symbol=nil)) and
+                  ((taicpu(p).oper[0]^.ref^.relsymbol=nil) or (taicpu(hp1).oper[ref]^.ref^.relsymbol=nil)) and
+                  ((taicpu(p).oper[0]^.ref^.scalefactor in [0,1]) or (taicpu(hp1).oper[ref]^.ref^.scalefactor in [0,1])) and
+                  (taicpu(p).oper[0]^.ref^.segment=NR_NO) and (taicpu(hp1).oper[ref]^.ref^.segment=NR_NO)
+{$ifdef x86_64}
+                  and (abs(taicpu(hp1).oper[ref]^.ref^.offset+taicpu(p).oper[0]^.ref^.offset)<=$7fffffff)
+{$endif x86_64}
+                  then
+                  begin
+                    if not(RegInInstruction(taicpu(p).oper[1]^.reg,taicpu(hp1))) then
+                      begin
+                        TransferUsedRegs(TmpUsedRegs);
+                        UpdateUsedRegs(TmpUsedRegs, tai(p.next));
+                        if not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,hp1,TmpUsedRegs)) then
+                          begin
+                            DebugMsg(SPeepholeOptimization + 'LeaOp2Op done',p);
+                            if taicpu(p).oper[0]^.ref^.base<>NR_NO then
+                              taicpu(hp1).oper[ref]^.ref^.base:=taicpu(p).oper[0]^.ref^.base;
+                            if taicpu(p).oper[0]^.ref^.index<>NR_NO then
+                              taicpu(hp1).oper[ref]^.ref^.index:=taicpu(p).oper[0]^.ref^.index;
+                            if taicpu(p).oper[0]^.ref^.symbol<>nil then
+                              taicpu(hp1).oper[ref]^.ref^.symbol:=taicpu(p).oper[0]^.ref^.symbol;
+                            if taicpu(p).oper[0]^.ref^.relsymbol<>nil then
+                              taicpu(hp1).oper[ref]^.ref^.relsymbol:=taicpu(p).oper[0]^.ref^.relsymbol;
+                            if not(taicpu(p).oper[0]^.ref^.scalefactor in [0,1]) then
+                              taicpu(hp1).oper[ref]^.ref^.scalefactor:=taicpu(p).oper[0]^.ref^.scalefactor;
+                            inc(taicpu(hp1).oper[ref]^.ref^.offset,taicpu(p).oper[0]^.ref^.offset);
+                            RemoveCurrentP(p);
+                            result:=true;
+                            exit;
+                          end
+                      end;
+                  end;
+                { recover }
+                taicpu(hp1).oper[ref]^.ref^:=saveref;
+              end;
           end;
         { replace
             lea    x(stackpointer),stackpointer