mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-14 10:09:20 +02:00
Generalize skip instruction optimization for both sbix and sbrx.
git-svn-id: trunk@42154 -
This commit is contained in:
parent
833e00bfbd
commit
c867d2b7f6
@ -42,6 +42,8 @@ Type
|
|||||||
function RegLoadedWithNewValue(reg : tregister; hp : tai) : boolean; override;
|
function RegLoadedWithNewValue(reg : tregister; hp : tai) : boolean; override;
|
||||||
function InstructionLoadsFromReg(const reg : TRegister; const hp : tai) : boolean; override;
|
function InstructionLoadsFromReg(const reg : TRegister; const hp : tai) : boolean; override;
|
||||||
|
|
||||||
|
function InvertSkipInstruction(var p: tai): boolean;
|
||||||
|
|
||||||
{ uses the same constructor as TAopObj }
|
{ uses the same constructor as TAopObj }
|
||||||
function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
|
function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
|
||||||
procedure PeepHoleOptPass2;override;
|
procedure PeepHoleOptPass2;override;
|
||||||
@ -225,6 +227,71 @@ Implementation
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
Turns
|
||||||
|
sbis ?
|
||||||
|
jmp .Lx
|
||||||
|
op
|
||||||
|
.Lx:
|
||||||
|
|
||||||
|
Into
|
||||||
|
sbic ?
|
||||||
|
op
|
||||||
|
|
||||||
|
For all types of skip instructions
|
||||||
|
}
|
||||||
|
function TCpuAsmOptimizer.InvertSkipInstruction(var p: tai): boolean;
|
||||||
|
|
||||||
|
function GetNextInstructionWithoutLabel(p: tai; var next: tai): boolean;
|
||||||
|
begin
|
||||||
|
repeat
|
||||||
|
result:=GetNextInstruction(p,next);
|
||||||
|
p:=next;
|
||||||
|
until
|
||||||
|
(not result) or
|
||||||
|
(not assigned(next)) or
|
||||||
|
(next.typ in [ait_instruction]);
|
||||||
|
|
||||||
|
result:=assigned(next) and (next.typ in [ait_instruction]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
hp1, hp2, hp3: tai;
|
||||||
|
s: string;
|
||||||
|
begin
|
||||||
|
result:=false;
|
||||||
|
|
||||||
|
if GetNextInstruction(taicpu(p),hp1) and
|
||||||
|
(hp1.typ=ait_instruction) and
|
||||||
|
(taicpu(hp1).opcode in [A_RJMP,A_JMP]) and
|
||||||
|
(taicpu(hp1).ops=1) and
|
||||||
|
(taicpu(hp1).oper[0]^.typ=top_ref) and
|
||||||
|
(taicpu(hp1).oper[0]^.ref^.offset=0) and
|
||||||
|
(taicpu(hp1).oper[0]^.ref^.symbol is TAsmLabel) and
|
||||||
|
GetNextInstructionWithoutLabel(hp1,hp2) and
|
||||||
|
(hp2.typ=ait_instruction) and
|
||||||
|
(not taicpu(hp2).is_jmp) and
|
||||||
|
GetNextInstruction(hp2,hp3) and
|
||||||
|
FindLabel(TAsmLabel(taicpu(hp1).oper[0]^.ref^.symbol),hp3) then
|
||||||
|
begin
|
||||||
|
DebugMsg('SkipJump2InvertedSkip', p);
|
||||||
|
|
||||||
|
case taicpu(p).opcode of
|
||||||
|
A_SBIS: taicpu(p).opcode:=A_SBIC;
|
||||||
|
A_SBIC: taicpu(p).opcode:=A_SBIS;
|
||||||
|
A_SBRS: taicpu(p).opcode:=A_SBRC;
|
||||||
|
A_SBRC: taicpu(p).opcode:=A_SBRS;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TAsmLabel(taicpu(hp1).oper[0]^.ref^.symbol).decrefs;
|
||||||
|
|
||||||
|
asml.remove(hp1);
|
||||||
|
hp1.free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
|
function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
|
||||||
var
|
var
|
||||||
hp1,hp2,hp3,hp4,hp5: tai;
|
hp1,hp2,hp3,hp4,hp5: tai;
|
||||||
@ -520,6 +587,9 @@ Implementation
|
|||||||
|
|
||||||
result:=true;
|
result:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
if InvertSkipInstruction(p) then
|
||||||
|
result:=true;
|
||||||
end;
|
end;
|
||||||
A_ANDI:
|
A_ANDI:
|
||||||
begin
|
begin
|
||||||
@ -1023,33 +1093,8 @@ Implementation
|
|||||||
op
|
op
|
||||||
.L1:
|
.L1:
|
||||||
}
|
}
|
||||||
if GetNextInstruction(p, hp1) and
|
if InvertSkipInstruction(p) then
|
||||||
(hp1.typ=ait_instruction) and
|
result:=true
|
||||||
(taicpu(hp1).opcode in [A_JMP,A_RJMP]) and
|
|
||||||
(taicpu(hp1).ops>0) and
|
|
||||||
(taicpu(hp1).oper[0]^.typ = top_ref) and
|
|
||||||
(taicpu(hp1).oper[0]^.ref^.symbol is TAsmLabel) and
|
|
||||||
GetNextInstruction(hp1, hp2) and
|
|
||||||
(hp2.typ=ait_instruction) and
|
|
||||||
(not taicpu(hp2).is_jmp) and
|
|
||||||
GetNextInstruction(hp2, hp3) and
|
|
||||||
(hp3.typ=ait_label) and
|
|
||||||
(taicpu(hp1).oper[0]^.ref^.symbol=tai_label(hp3).labsym) then
|
|
||||||
begin
|
|
||||||
DebugMsg('Peephole SbiJmp2Sbi performed',p);
|
|
||||||
|
|
||||||
if taicpu(p).opcode=A_SBIC then
|
|
||||||
taicpu(p).opcode:=A_SBIS
|
|
||||||
else
|
|
||||||
taicpu(p).opcode:=A_SBIC;
|
|
||||||
|
|
||||||
tai_label(hp3).labsym.decrefs;
|
|
||||||
|
|
||||||
AsmL.remove(hp1);
|
|
||||||
taicpu(hp1).Free;
|
|
||||||
|
|
||||||
result:=true;
|
|
||||||
end
|
|
||||||
{
|
{
|
||||||
Turn
|
Turn
|
||||||
sbiX X, y
|
sbiX X, y
|
||||||
|
Loading…
Reference in New Issue
Block a user