summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorflorian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2>2017-05-06 21:07:02 +0000
committerflorian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2>2017-05-06 21:07:02 +0000
commitb0d3add053c14a47f3dbbdd171c4b7b8c2fff25c (patch)
tree3b0ba5a3d223e09e5ccc78b48df48840dc9bd118
parenta16d4c04b0aaa98c20db1f4ac0644dad48a11f59 (diff)
downloadfpc-b0d3add053c14a47f3dbbdd171c4b7b8c2fff25c.tar.gz
* SkipLabels moved to aoptutils
* factored out OptPass2Jmp assembler optimization * OptPass2Jmp now used by x86-64 as well git-svn-id: https://svn.freepascal.org/svn/fpc/trunk@36141 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r--compiler/aoptobj.pas22
-rw-r--r--compiler/aoptutils.pas23
-rw-r--r--compiler/i386/aoptcpu.pas50
-rw-r--r--compiler/x86/aoptx86.pas42
-rw-r--r--compiler/x86_64/aoptcpu.pas2
5 files changed, 72 insertions, 67 deletions
diff --git a/compiler/aoptobj.pas b/compiler/aoptobj.pas
index 7520280831..a393c88ccc 100644
--- a/compiler/aoptobj.pas
+++ b/compiler/aoptobj.pas
@@ -367,7 +367,8 @@ Unit AoptObj;
cutils,
globals,
verbose,
- procinfo;
+ procinfo,
+ aoptutils;
function JumpTargetOp(ai: taicpu): poper; inline;
@@ -1147,25 +1148,6 @@ Unit AoptObj;
end;
- function SkipLabels(hp: tai; var hp2: tai): boolean;
- {skips all labels and returns the next "real" instruction}
- begin
- while assigned(hp.next) and
- (tai(hp.next).typ in SkipInstr + [ait_label,ait_align]) Do
- hp := tai(hp.next);
- if assigned(hp.next) then
- begin
- SkipLabels := True;
- hp2 := tai(hp.next)
- end
- else
- begin
- hp2 := hp;
- SkipLabels := False
- end;
- end;
-
-
function FindAnyLabel(hp: tai; var l: tasmlabel): Boolean;
begin
FindAnyLabel := false;
diff --git a/compiler/aoptutils.pas b/compiler/aoptutils.pas
index 68043028e5..3d85618794 100644
--- a/compiler/aoptutils.pas
+++ b/compiler/aoptutils.pas
@@ -32,6 +32,9 @@ unit aoptutils;
function MatchOpType(const p : taicpu;type0: toptype) : Boolean;
function MatchOpType(const p : taicpu;type0,type1 : toptype) : Boolean;
+ { skips all labels and returns the next "real" instruction }
+ function SkipLabels(hp: tai; var hp2: tai): boolean;
+
implementation
function MatchOpType(const p : taicpu; type0: toptype) : Boolean;
@@ -45,5 +48,25 @@ unit aoptutils;
Result:=(p.oper[0]^.typ=type0) and (p.oper[0]^.typ=type1);
end;
+
+ { skips all labels and returns the next "real" instruction }
+ function SkipLabels(hp: tai; var hp2: tai): boolean;
+ begin
+ while assigned(hp.next) and
+ (tai(hp.next).typ in SkipInstr + [ait_label,ait_align]) Do
+ hp := tai(hp.next);
+ if assigned(hp.next) then
+ begin
+ SkipLabels := True;
+ hp2 := tai(hp.next)
+ end
+ else
+ begin
+ hp2 := hp;
+ SkipLabels := False
+ end;
+ end;
+
+
end.
diff --git a/compiler/i386/aoptcpu.pas b/compiler/i386/aoptcpu.pas
index 6b2994eccb..379fa91b76 100644
--- a/compiler/i386/aoptcpu.pas
+++ b/compiler/i386/aoptcpu.pas
@@ -56,6 +56,7 @@ unit aoptcpu;
aoptbase,
cpuinfo,
aasmcpu,
+ aoptutils,
procinfo,
cgutils,cgx86,
{ units we should get rid off: }
@@ -684,24 +685,6 @@ begin
end;
end;
-{ skips all labels and returns the next "real" instruction }
-function SkipLabels(hp: tai; var hp2: tai): boolean;
- begin
- while assigned(hp.next) and
- (tai(hp.next).typ in SkipInstr + [ait_label,ait_align]) Do
- hp := tai(hp.next);
- if assigned(hp.next) then
- begin
- SkipLabels := True;
- hp2 := tai(hp.next)
- end
- else
- begin
- hp2 := hp;
- SkipLabels := False
- end;
- end;
-
{ First pass of peephole optimizations }
procedure TCPUAsmOPtimizer.PeepHoleOptPass1;
@@ -1992,35 +1975,8 @@ begin
if OptPass2Imul(p) then
continue;
A_JMP:
- {
- change
- jmp .L1
- ...
- .L1:
- ret
- into
- ret
- }
- if (taicpu(p).oper[0]^.typ=top_ref) and (taicpu(p).oper[0]^.ref^.refaddr=addr_full) then
- begin
- hp1:=getlabelwithsym(tasmlabel(taicpu(p).oper[0]^.ref^.symbol));
- if assigned(hp1) and SkipLabels(hp1,hp1) and (hp1.typ=ait_instruction) and (taicpu(hp1).opcode=A_RET) and (taicpu(p).condition=C_None) then
- begin
- tasmlabel(taicpu(p).oper[0]^.ref^.symbol).decrefs;
- taicpu(p).opcode:=A_RET;
- taicpu(p).is_jmp:=false;
- taicpu(p).ops:=taicpu(hp1).ops;
- case taicpu(hp1).ops of
- 0:
- taicpu(p).clearop(0);
- 1:
- taicpu(p).loadconst(0,taicpu(hp1).oper[0]^.val);
- else
- internalerror(2016041301);
- end;
- continue;
- end;
- end;
+ if OptPass2Jmp(p) then
+ continue;
A_MOV:
if OptPass2MOV(p) then
continue;
diff --git a/compiler/x86/aoptx86.pas b/compiler/x86/aoptx86.pas
index a70b6d932b..2aab96d4a7 100644
--- a/compiler/x86/aoptx86.pas
+++ b/compiler/x86/aoptx86.pas
@@ -55,6 +55,7 @@ unit aoptx86;
function OptPass2MOV(var p : tai) : boolean;
function OptPass2Imul(var p : tai) : boolean;
+ function OptPass2Jmp(var p : tai) : boolean;
procedure DebugMsg(const s : string; p : tai);inline;
@@ -89,6 +90,8 @@ unit aoptx86;
cutils,
verbose,
procinfo,
+ aasmbase,
+ aoptutils,
symconst,symsym,
itcpugas;
@@ -1369,6 +1372,45 @@ unit aoptx86;
end;
+ function TX86AsmOptimizer.OptPass2Jmp(var p : tai) : boolean;
+ var
+ hp1 : tai;
+ begin
+ {
+ change
+ jmp .L1
+ ...
+ .L1:
+ ret
+ into
+ ret
+ }
+ result:=false;
+ if (taicpu(p).oper[0]^.typ=top_ref) and (taicpu(p).oper[0]^.ref^.refaddr=addr_full) and (taicpu(p).oper[0]^.ref^.base=NR_NO) and
+ (taicpu(p).oper[0]^.ref^.index=NR_NO) then
+ begin
+ hp1:=getlabelwithsym(tasmlabel(taicpu(p).oper[0]^.ref^.symbol));
+ if (taicpu(p).condition=C_None) and assigned(hp1) and SkipLabels(hp1,hp1) and
+ MatchInstruction(hp1,A_RET,[S_NO]) then
+ begin
+ tasmlabel(taicpu(p).oper[0]^.ref^.symbol).decrefs;
+ taicpu(p).opcode:=A_RET;
+ taicpu(p).is_jmp:=false;
+ taicpu(p).ops:=taicpu(hp1).ops;
+ case taicpu(hp1).ops of
+ 0:
+ taicpu(p).clearop(0);
+ 1:
+ taicpu(p).loadconst(0,taicpu(hp1).oper[0]^.val);
+ else
+ internalerror(2016041301);
+ end;
+ result:=true;
+ end;
+ end;
+ end;
+
+
function TX86AsmOptimizer.OptPass1AND(var p : tai) : boolean;
var
hp1 : tai;
diff --git a/compiler/x86_64/aoptcpu.pas b/compiler/x86_64/aoptcpu.pas
index 1bd495f52f..6c503b0285 100644
--- a/compiler/x86_64/aoptcpu.pas
+++ b/compiler/x86_64/aoptcpu.pas
@@ -357,6 +357,8 @@ end;
Result:=OptPass2MOV(p);
A_IMUL:
Result:=OptPass2Imul(p);
+ A_JMP:
+ Result:=OptPass2Jmp(p);
end;
end;
end;