Generalize skip instruction optimization for both sbix and sbrx.

git-svn-id: trunk@42154 -
This commit is contained in:
Jeppe Johansen 2019-06-01 15:20:34 +00:00
parent 833e00bfbd
commit c867d2b7f6

View File

@ -42,6 +42,8 @@ Type
function RegLoadedWithNewValue(reg : tregister; 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 }
function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
procedure PeepHoleOptPass2;override;
@ -225,6 +227,71 @@ Implementation
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;
var
hp1,hp2,hp3,hp4,hp5: tai;
@ -520,6 +587,9 @@ Implementation
result:=true;
end;
if InvertSkipInstruction(p) then
result:=true;
end;
A_ANDI:
begin
@ -1023,33 +1093,8 @@ Implementation
op
.L1:
}
if GetNextInstruction(p, hp1) and
(hp1.typ=ait_instruction) and
(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
if InvertSkipInstruction(p) then
result:=true
{
Turn
sbiX X, y