+ LeaOp2Op optimization

* replaced some manual removels of p by RemoveCurrentP calls

git-svn-id: trunk@43456 -
This commit is contained in:
florian 2019-11-12 22:04:23 +00:00
parent 5c0a5b73c7
commit 7ee0ad4d63

View File

@ -2292,6 +2292,8 @@ unit aoptx86;
var
hp1, hp2, hp3: tai;
l : ASizeInt;
ref: Integer;
saveref: treference;
begin
Result:=false;
{ removes seg register prefixes from LEA operations, as they
@ -2318,11 +2320,8 @@ unit aoptx86;
end
else if (taicpu(p).oper[0]^.ref^.offset = 0) then
begin
hp1:=taicpu(p.Next);
DebugMsg(SPeepholeOptimization + 'Lea2Nop done',p);
asml.remove(p);
p.free;
p:=hp1;
RemoveCurrentP(p);
Result:=true;
exit;
end
@ -2407,10 +2406,76 @@ unit aoptx86;
DebugMsg(SPeepholeOptimization + 'LeaLea2Lea done',p);
inc(taicpu(hp1).oper[0]^.ref^.offset,taicpu(p).oper[0]^.ref^.offset);
taicpu(hp1).oper[0]^.ref^.base:=taicpu(p).oper[0]^.ref^.base;
asml.Remove(p);
p.Free;
p:=hp1;
RemoveCurrentP(p);
result:=true;
exit;
end;
{ changes
lea <ref1>, reg1
<op> ...,<ref. with reg1>,...
to
<op> ...,<ref1>,... }
if (taicpu(p).oper[1]^.reg<>current_procinfo.framepointer) and
(taicpu(p).oper[1]^.reg<>NR_STACK_POINTER_REG) and
GetNextInstruction(p,hp1) and
(hp1.typ=ait_instruction) and
not(MatchInstruction(hp1,A_LEA,[])) then
begin
if (taicpu(hp1).ops>=1) and (taicpu(hp1).oper[0]^.typ=top_ref) and RegInOp(taicpu(p).oper[1]^.reg,taicpu(hp1).oper[0]^) then
ref:=0
else if (taicpu(hp1).ops>=2) and (taicpu(hp1).oper[1]^.typ=top_ref) and RegInOp(taicpu(p).oper[1]^.reg,taicpu(hp1).oper[1]^) then
ref:=1
else
ref:=-1;
if (ref<>-1) and
((taicpu(hp1).oper[ref]^.ref^.base=taicpu(p).oper[1]^.reg) xor (taicpu(hp1).oper[ref]^.ref^.index=taicpu(p).oper[1]^.reg)) then
begin
saveref:=taicpu(hp1).oper[ref]^.ref^;
if taicpu(hp1).oper[ref]^.ref^.base=taicpu(p).oper[1]^.reg then
taicpu(hp1).oper[ref]^.ref^.base:=NR_NO
else if taicpu(hp1).oper[ref]^.ref^.index=taicpu(p).oper[1]^.reg then
taicpu(hp1).oper[ref]^.ref^.index:=NR_NO
else
Internalerror(2019111201);
if ((taicpu(hp1).oper[ref]^.ref^.base=taicpu(p).oper[1]^.reg) or (taicpu(hp1).oper[ref]^.ref^.scalefactor in [0,1])) and
((taicpu(p).oper[0]^.ref^.base=NR_NO) or (taicpu(hp1).oper[ref]^.ref^.base=NR_NO)) and
((taicpu(p).oper[0]^.ref^.index=NR_NO) or (taicpu(hp1).oper[ref]^.ref^.index=NR_NO)) and
((taicpu(p).oper[0]^.ref^.symbol=nil) or (taicpu(hp1).oper[ref]^.ref^.symbol=nil)) and
((taicpu(p).oper[0]^.ref^.relsymbol=nil) or (taicpu(hp1).oper[ref]^.ref^.relsymbol=nil)) and
((taicpu(p).oper[0]^.ref^.scalefactor in [0,1]) or (taicpu(hp1).oper[ref]^.ref^.scalefactor in [0,1])) and
(taicpu(p).oper[0]^.ref^.segment=NR_NO) and (taicpu(hp1).oper[ref]^.ref^.segment=NR_NO)
{$ifdef x86_64}
and (abs(taicpu(hp1).oper[ref]^.ref^.offset+taicpu(p).oper[0]^.ref^.offset)<=$7fffffff)
{$endif x86_64}
then
begin
if not(RegInInstruction(taicpu(p).oper[1]^.reg,taicpu(hp1))) then
begin
TransferUsedRegs(TmpUsedRegs);
UpdateUsedRegs(TmpUsedRegs, tai(p.next));
if not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,hp1,TmpUsedRegs)) then
begin
DebugMsg(SPeepholeOptimization + 'LeaOp2Op done',p);
if taicpu(p).oper[0]^.ref^.base<>NR_NO then
taicpu(hp1).oper[ref]^.ref^.base:=taicpu(p).oper[0]^.ref^.base;
if taicpu(p).oper[0]^.ref^.index<>NR_NO then
taicpu(hp1).oper[ref]^.ref^.index:=taicpu(p).oper[0]^.ref^.index;
if taicpu(p).oper[0]^.ref^.symbol<>nil then
taicpu(hp1).oper[ref]^.ref^.symbol:=taicpu(p).oper[0]^.ref^.symbol;
if taicpu(p).oper[0]^.ref^.relsymbol<>nil then
taicpu(hp1).oper[ref]^.ref^.relsymbol:=taicpu(p).oper[0]^.ref^.relsymbol;
if not(taicpu(p).oper[0]^.ref^.scalefactor in [0,1]) then
taicpu(hp1).oper[ref]^.ref^.scalefactor:=taicpu(p).oper[0]^.ref^.scalefactor;
inc(taicpu(hp1).oper[ref]^.ref^.offset,taicpu(p).oper[0]^.ref^.offset);
RemoveCurrentP(p);
result:=true;
exit;
end
end;
end;
{ recover }
taicpu(hp1).oper[ref]^.ref^:=saveref;
end;
end;
{ replace
lea x(stackpointer),stackpointer