mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-18 05:39:26 +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,
|
||||
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;
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -357,6 +357,8 @@ end;
|
||||
Result:=OptPass2MOV(p);
|
||||
A_IMUL:
|
||||
Result:=OptPass2Imul(p);
|
||||
A_JMP:
|
||||
Result:=OptPass2Jmp(p);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
Loading…
Reference in New Issue
Block a user