mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-11 19:05:54 +02:00
* SkipLabels moved to aoptutils
* factored out OptPass2Jmp assembler optimization * OptPass2Jmp now used by x86-64 as well git-svn-id: trunk@36141 -
This commit is contained in:
parent
04807d1ac4
commit
e3f0b338d4
@ -367,7 +367,8 @@ Unit AoptObj;
|
|||||||
cutils,
|
cutils,
|
||||||
globals,
|
globals,
|
||||||
verbose,
|
verbose,
|
||||||
procinfo;
|
procinfo,
|
||||||
|
aoptutils;
|
||||||
|
|
||||||
|
|
||||||
function JumpTargetOp(ai: taicpu): poper; inline;
|
function JumpTargetOp(ai: taicpu): poper; inline;
|
||||||
@ -1147,25 +1148,6 @@ Unit AoptObj;
|
|||||||
end;
|
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;
|
function FindAnyLabel(hp: tai; var l: tasmlabel): Boolean;
|
||||||
begin
|
begin
|
||||||
FindAnyLabel := false;
|
FindAnyLabel := false;
|
||||||
|
@ -32,6 +32,9 @@ unit aoptutils;
|
|||||||
function MatchOpType(const p : taicpu;type0: toptype) : Boolean;
|
function MatchOpType(const p : taicpu;type0: toptype) : Boolean;
|
||||||
function MatchOpType(const p : taicpu;type0,type1 : 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
|
implementation
|
||||||
|
|
||||||
function MatchOpType(const p : taicpu; type0: toptype) : Boolean;
|
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);
|
Result:=(p.oper[0]^.typ=type0) and (p.oper[0]^.typ=type1);
|
||||||
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;
|
||||||
|
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -56,6 +56,7 @@ unit aoptcpu;
|
|||||||
aoptbase,
|
aoptbase,
|
||||||
cpuinfo,
|
cpuinfo,
|
||||||
aasmcpu,
|
aasmcpu,
|
||||||
|
aoptutils,
|
||||||
procinfo,
|
procinfo,
|
||||||
cgutils,cgx86,
|
cgutils,cgx86,
|
||||||
{ units we should get rid off: }
|
{ units we should get rid off: }
|
||||||
@ -684,24 +685,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
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 }
|
{ First pass of peephole optimizations }
|
||||||
procedure TCPUAsmOPtimizer.PeepHoleOptPass1;
|
procedure TCPUAsmOPtimizer.PeepHoleOptPass1;
|
||||||
@ -1992,35 +1975,8 @@ begin
|
|||||||
if OptPass2Imul(p) then
|
if OptPass2Imul(p) then
|
||||||
continue;
|
continue;
|
||||||
A_JMP:
|
A_JMP:
|
||||||
{
|
if OptPass2Jmp(p) then
|
||||||
change
|
continue;
|
||||||
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;
|
|
||||||
A_MOV:
|
A_MOV:
|
||||||
if OptPass2MOV(p) then
|
if OptPass2MOV(p) then
|
||||||
continue;
|
continue;
|
||||||
|
@ -55,6 +55,7 @@ unit aoptx86;
|
|||||||
|
|
||||||
function OptPass2MOV(var p : tai) : boolean;
|
function OptPass2MOV(var p : tai) : boolean;
|
||||||
function OptPass2Imul(var p : tai) : boolean;
|
function OptPass2Imul(var p : tai) : boolean;
|
||||||
|
function OptPass2Jmp(var p : tai) : boolean;
|
||||||
|
|
||||||
procedure DebugMsg(const s : string; p : tai);inline;
|
procedure DebugMsg(const s : string; p : tai);inline;
|
||||||
|
|
||||||
@ -89,6 +90,8 @@ unit aoptx86;
|
|||||||
cutils,
|
cutils,
|
||||||
verbose,
|
verbose,
|
||||||
procinfo,
|
procinfo,
|
||||||
|
aasmbase,
|
||||||
|
aoptutils,
|
||||||
symconst,symsym,
|
symconst,symsym,
|
||||||
itcpugas;
|
itcpugas;
|
||||||
|
|
||||||
@ -1369,6 +1372,45 @@ unit aoptx86;
|
|||||||
end;
|
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;
|
function TX86AsmOptimizer.OptPass1AND(var p : tai) : boolean;
|
||||||
var
|
var
|
||||||
hp1 : tai;
|
hp1 : tai;
|
||||||
|
@ -357,6 +357,8 @@ end;
|
|||||||
Result:=OptPass2MOV(p);
|
Result:=OptPass2MOV(p);
|
||||||
A_IMUL:
|
A_IMUL:
|
||||||
Result:=OptPass2Imul(p);
|
Result:=OptPass2Imul(p);
|
||||||
|
A_JMP:
|
||||||
|
Result:=OptPass2Jmp(p);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
Loading…
Reference in New Issue
Block a user