* patch by J. Gareth Moreton: introduce RemoveInstruction and make as much as possible use of RemoveCurrentP, resolves #37399

git-svn-id: trunk@46862 -
This commit is contained in:
florian 2020-09-13 19:35:09 +00:00
parent 7f8f733963
commit 2c54477807
2 changed files with 101 additions and 195 deletions

View File

@ -344,6 +344,9 @@ Unit AoptObj;
{ removes p from asml, updates registers and replaces p with hp1 (if the next instruction was known beforehand) } { removes p from asml, updates registers and replaces p with hp1 (if the next instruction was known beforehand) }
procedure RemoveCurrentP(var p: tai; const hp1: tai); inline; procedure RemoveCurrentP(var p: tai; const hp1: tai); inline;
{ removes hp from asml then frees it }
procedure RemoveInstruction(const hp: tai); inline;
{ traces sucessive jumps to their final destination and sets it, e.g. { traces sucessive jumps to their final destination and sets it, e.g.
je l1 je l3 je l1 je l3
<code> <code> <code> <code>
@ -1510,6 +1513,13 @@ Unit AoptObj;
end; end;
procedure TAOptObj.RemoveInstruction(const hp: tai); inline;
begin
AsmL.Remove(hp);
hp.Free;
end;
function FindLiveLabel(hp: tai; var l: tasmlabel): Boolean; function FindLiveLabel(hp: tai; var l: tasmlabel): Boolean;
var var
next: tai; next: tai;

View File

@ -1090,8 +1090,7 @@ unit aoptx86;
else else
Internalerror(2017050701) Internalerror(2017050701)
end; end;
asml.remove(hp1); RemoveInstruction(hp1);
hp1.free;
end; end;
end; end;
end; end;
@ -1383,8 +1382,7 @@ unit aoptx86;
(getregtype(tai_regalloc(hp2).reg) = R_INTREGISTER) and (getregtype(tai_regalloc(hp2).reg) = R_INTREGISTER) and
(getsupreg(tai_regalloc(hp2).reg) = supreg) then (getsupreg(tai_regalloc(hp2).reg) = supreg) then
begin begin
asml.remove(hp2); RemoveInstruction(hp2);
hp2.free;
break; break;
end; end;
until not(assigned(hp2)) or regInInstruction(newreg(R_INTREGISTER,supreg,R_SUBWHOLE),hp2); until not(assigned(hp2)) or regInInstruction(newreg(R_INTREGISTER,supreg,R_SUBWHOLE),hp2);
@ -1444,8 +1442,7 @@ unit aoptx86;
begin begin
DebugMsg(SPeepholeOptimization + '(V)MOVA*(V)MOVA*2(V)MOVA* 1',p); DebugMsg(SPeepholeOptimization + '(V)MOVA*(V)MOVA*2(V)MOVA* 1',p);
taicpu(p).loadoper(1,taicpu(hp1).oper[1]^); taicpu(p).loadoper(1,taicpu(hp1).oper[1]^);
asml.Remove(hp1); RemoveInstruction(hp1);
hp1.Free;
result:=true; result:=true;
exit; exit;
end end
@ -1457,8 +1454,7 @@ unit aoptx86;
else if MatchOperand(taicpu(p).oper[0]^,taicpu(hp1).oper[1]^) then else if MatchOperand(taicpu(p).oper[0]^,taicpu(hp1).oper[1]^) then
begin begin
DebugMsg(SPeepholeOptimization + '(V)MOVA*(V)MOVA*2(V)MOVA* 2',p); DebugMsg(SPeepholeOptimization + '(V)MOVA*(V)MOVA*2(V)MOVA* 2',p);
asml.Remove(hp1); RemoveInstruction(hp1);
hp1.Free;
result:=true; result:=true;
exit; exit;
end end
@ -1482,8 +1478,7 @@ unit aoptx86;
DebugMsg(SPeepholeOptimization + '(V)MOVA*(V)MOVS*2(V)MOVS* 1',p); DebugMsg(SPeepholeOptimization + '(V)MOVA*(V)MOVS*2(V)MOVS* 1',p);
taicpu(p).opcode:=taicpu(hp1).opcode; taicpu(p).opcode:=taicpu(hp1).opcode;
taicpu(p).loadoper(1,taicpu(hp1).oper[1]^); taicpu(p).loadoper(1,taicpu(hp1).oper[1]^);
asml.Remove(hp1); RemoveInstruction(hp1);
hp1.Free;
result:=true; result:=true;
exit; exit;
end end
@ -1566,8 +1561,7 @@ unit aoptx86;
begin begin
taicpu(hp1).loadoper(2,taicpu(p).oper[0]^); taicpu(hp1).loadoper(2,taicpu(p).oper[0]^);
RemoveCurrentP(p, hp1); // <-- Is this actually safe? hp1 is not necessarily the next instruction. [Kit] RemoveCurrentP(p, hp1); // <-- Is this actually safe? hp1 is not necessarily the next instruction. [Kit]
asml.Remove(hp2); RemoveInstruction(hp2);
hp2.Free;
end; end;
end end
else if (hp1.typ = ait_instruction) and else if (hp1.typ = ait_instruction) and
@ -1606,8 +1600,7 @@ unit aoptx86;
RemoveCurrentP(p, nil); RemoveCurrentP(p, nil);
p:=hp1; p:=hp1;
taicpu(hp1).loadoper(1, taicpu(hp2).oper[1]^); taicpu(hp1).loadoper(1, taicpu(hp2).oper[1]^);
asml.remove(hp2); RemoveInstruction(hp2);
hp2.Free;
result:=true; result:=true;
end; end;
end; end;
@ -1643,8 +1636,7 @@ unit aoptx86;
begin begin
taicpu(p).loadoper(2,taicpu(hp1).oper[1]^); taicpu(p).loadoper(2,taicpu(hp1).oper[1]^);
DebugMsg(SPeepholeOptimization + 'VOpVmov2VOp done',p); DebugMsg(SPeepholeOptimization + 'VOpVmov2VOp done',p);
asml.Remove(hp1); RemoveInstruction(hp1);
hp1.Free;
result:=true; result:=true;
end; end;
end; end;
@ -1972,9 +1964,7 @@ unit aoptx86;
begin begin
{ We can remove the original MOV } { We can remove the original MOV }
DebugMsg(SPeepholeOptimization + 'Mov2Nop 3 done',p); DebugMsg(SPeepholeOptimization + 'Mov2Nop 3 done',p);
Asml.Remove(p); RemoveCurrentp(p, hp1);
p.Free;
p := hp1;
{ TmpUsedRegs contains the results of "UpdateUsedRegs(tai(p.Next))" already, { TmpUsedRegs contains the results of "UpdateUsedRegs(tai(p.Next))" already,
so just restore it to UsedRegs instead of calculating it again } so just restore it to UsedRegs instead of calculating it again }
@ -2042,8 +2032,7 @@ unit aoptx86;
begin begin
GetNextInstruction_p := GetNextInstruction(hp1, hp2); GetNextInstruction_p := GetNextInstruction(hp1, hp2);
DebugMsg(SPeepholeOptimization + 'Mov2Nop 4 done',hp1); DebugMsg(SPeepholeOptimization + 'Mov2Nop 4 done',hp1);
asml.remove(hp1); RemoveInstruction(hp1);
hp1.free;
{ The instruction after what was hp1 is now the immediate next instruction, { The instruction after what was hp1 is now the immediate next instruction,
so we can continue to make optimisations if it's present } so we can continue to make optimisations if it's present }
@ -2130,8 +2119,7 @@ unit aoptx86;
InternalError(2020021001); InternalError(2020021001);
end; end;
DebugMsg(SPeepholeOptimization + 'MovMovXX2MovXX 2 done',p); DebugMsg(SPeepholeOptimization + 'MovMovXX2MovXX 2 done',p);
asml.Remove(hp1); RemoveInstruction(hp1);
hp1.Free;
Result := True; Result := True;
Exit; Exit;
end; end;
@ -2186,8 +2174,7 @@ unit aoptx86;
and ffffffffh, %reg and ffffffffh, %reg
} }
DebugMsg(SPeepholeOptimization + 'MovAnd2Mov 1 done',p); DebugMsg(SPeepholeOptimization + 'MovAnd2Mov 1 done',p);
asml.remove(hp1); RemoveInstruction(hp1);
hp1.free;
Result:=true; Result:=true;
exit; exit;
end; end;
@ -2199,8 +2186,7 @@ unit aoptx86;
and ffffffffffffffffh, %reg and ffffffffffffffffh, %reg
} }
DebugMsg(SPeepholeOptimization + 'MovAnd2Mov 2 done',p); DebugMsg(SPeepholeOptimization + 'MovAnd2Mov 2 done',p);
asml.remove(hp1); RemoveInstruction(hp1);
hp1.free;
Result:=true; Result:=true;
exit; exit;
end; end;
@ -2225,8 +2211,7 @@ unit aoptx86;
DebugMsg(SPeepholeOptimization + 'MovAndTest2Test done',p); DebugMsg(SPeepholeOptimization + 'MovAndTest2Test done',p);
taicpu(hp1).loadoper(1,taicpu(p).oper[0]^); taicpu(hp1).loadoper(1,taicpu(p).oper[0]^);
taicpu(hp1).opcode:=A_TEST; taicpu(hp1).opcode:=A_TEST;
asml.Remove(hp2); RemoveInstruction(hp2);
hp2.free;
RemoveCurrentP(p, hp1); RemoveCurrentP(p, hp1);
Result:=true; Result:=true;
exit; exit;
@ -2325,8 +2310,7 @@ unit aoptx86;
DebugMsg(SPeepholeOptimization + PreMessage + '; and' + debug_opsize2str(taicpu(hp1).opsize) + ' $' + MaskNum + ',' + RegName2 + DebugMsg(SPeepholeOptimization + PreMessage + '; and' + debug_opsize2str(taicpu(hp1).opsize) + ' $' + MaskNum + ',' + RegName2 +
' -> movz' + debug_opsize2str(NewSize) + ' ' + InputVal + ',' + RegName2, p); ' -> movz' + debug_opsize2str(NewSize) + ' ' + InputVal + ',' + RegName2, p);
asml.Remove(hp1); RemoveInstruction(hp1);
hp1.Free;
end; end;
Result := True; Result := True;
@ -2375,8 +2359,7 @@ unit aoptx86;
AllocRegBetween(taicpu(hp1).oper[1]^.reg,p,hp1,usedregs); AllocRegBetween(taicpu(hp1).oper[1]^.reg,p,hp1,usedregs);
taicpu(p).loadOper(1,taicpu(hp1).oper[1]^); taicpu(p).loadOper(1,taicpu(hp1).oper[1]^);
DebugMsg(SPeepholeOptimization + 'MovMov2Mov 5 done',p); DebugMsg(SPeepholeOptimization + 'MovMov2Mov 5 done',p);
asml.remove(hp1); RemoveInstruction(hp1);
hp1.free;
Result:=true; Result:=true;
Exit; Exit;
end; end;
@ -2394,8 +2377,7 @@ unit aoptx86;
} }
taicpu(p).loadreg(1, taicpu(hp1).oper[1]^.reg); taicpu(p).loadreg(1, taicpu(hp1).oper[1]^.reg);
DebugMsg(SPeepholeOptimization + 'MovMov2Mov 3 done',p); DebugMsg(SPeepholeOptimization + 'MovMov2Mov 3 done',p);
asml.remove(hp1); RemoveInstruction(hp1);
hp1.free;
Result:=true; Result:=true;
Exit; Exit;
end; end;
@ -2438,8 +2420,7 @@ unit aoptx86;
if taicpu(p).oper[0]^.typ=top_reg then if taicpu(p).oper[0]^.typ=top_reg then
AllocRegBetween(taicpu(p).oper[0]^.reg,p,hp1,usedregs); AllocRegBetween(taicpu(p).oper[0]^.reg,p,hp1,usedregs);
DebugMsg(SPeepholeOptimization + 'MovMov2Mov 1',p); DebugMsg(SPeepholeOptimization + 'MovMov2Mov 1',p);
asml.remove(hp1); RemoveInstruction(hp1);
hp1.free;
Result:=true; Result:=true;
exit; exit;
end end
@ -2462,8 +2443,7 @@ unit aoptx86;
cmp mem1, reg1 cmp mem1, reg1
} }
begin begin
asml.remove(hp2); RemoveInstruction(hp2);
hp2.free;
taicpu(hp1).opcode := A_CMP; taicpu(hp1).opcode := A_CMP;
taicpu(hp1).loadref(1,taicpu(hp1).oper[0]^.ref^); taicpu(hp1).loadref(1,taicpu(hp1).oper[0]^.ref^);
taicpu(hp1).loadreg(0,taicpu(p).oper[0]^.reg); taicpu(hp1).loadreg(0,taicpu(p).oper[0]^.reg);
@ -2502,8 +2482,7 @@ unit aoptx86;
DebugMsg(SPeepholeOptimization + 'MovMovMov2MovMov 1 done',p); DebugMsg(SPeepholeOptimization + 'MovMovMov2MovMov 1 done',p);
taicpu(p).loadoper(1,taicpu(hp2).oper[1]^); taicpu(p).loadoper(1,taicpu(hp2).oper[1]^);
taicpu(hp1).loadoper(0,taicpu(hp2).oper[1]^); taicpu(hp1).loadoper(0,taicpu(hp2).oper[1]^);
asml.remove(hp2); RemoveInstruction(hp2);
hp2.free;
end end
{$ifdef i386} {$ifdef i386}
{ this is enabled for i386 only, as the rules to create the reg sets below { this is enabled for i386 only, as the rules to create the reg sets below
@ -2548,8 +2527,7 @@ unit aoptx86;
end end
else else
begin begin
asml.remove(hp2); RemoveInstruction(hp2);
hp2.free;
end end
{$endif i386} {$endif i386}
; ;
@ -2663,13 +2641,11 @@ unit aoptx86;
begin begin
DebugMsg(SPeepholeOptimization + debug_regname(CurrentReg) + ' = ' + RegName1 + '; removed unnecessary instruction (MovMov2MovNop 6b}',hp2); DebugMsg(SPeepholeOptimization + debug_regname(CurrentReg) + ' = ' + RegName1 + '; removed unnecessary instruction (MovMov2MovNop 6b}',hp2);
AllocRegBetween(CurrentReg, p, hp2, UsedRegs); AllocRegBetween(CurrentReg, p, hp2, UsedRegs);
asml.remove(hp2); RemoveInstruction(hp2);
hp2.Free;
end end
else else
begin begin
asml.remove(hp2); RemoveInstruction(hp2);
hp2.Free;
{ We can remove the original MOV too } { We can remove the original MOV too }
DebugMsg(SPeepholeOptimization + 'MovMov2NopNop 6b done',p); DebugMsg(SPeepholeOptimization + 'MovMov2NopNop 6b done',p);
@ -2769,8 +2745,7 @@ unit aoptx86;
DebugMsg(SPeepholeOptimization + 'Removed movs/z instruction and extended earlier write (MovMovs/z2Mov/s/z)', hp2); DebugMsg(SPeepholeOptimization + 'Removed movs/z instruction and extended earlier write (MovMovs/z2Mov/s/z)', hp2);
AllocRegBetween(taicpu(hp2).oper[1]^.reg, p, hp2, UsedRegs); AllocRegBetween(taicpu(hp2).oper[1]^.reg, p, hp2, UsedRegs);
AsmL.Remove(hp2); RemoveInstruction(hp2);
hp2.Free;
Result := True; Result := True;
Exit; Exit;
@ -2800,8 +2775,7 @@ unit aoptx86;
and ffffffffh, %reg and ffffffffh, %reg
} }
DebugMsg(SPeepholeOptimization + 'MovAnd2Mov 3 done',p); DebugMsg(SPeepholeOptimization + 'MovAnd2Mov 3 done',p);
asml.remove(hp2); RemoveInstruction(hp2);
hp2.free;
Result:=true; Result:=true;
exit; exit;
end; end;
@ -2833,9 +2807,7 @@ unit aoptx86;
) )
) then ) then
begin begin
asml.remove(p); RemoveCurrentp(p, hp1);
p.free;
p:=hp1;
DebugMsg(SPeepholeOptimization + 'removed deadstore before leave/ret',p); DebugMsg(SPeepholeOptimization + 'removed deadstore before leave/ret',p);
RemoveLastDeallocForFuncRes(p); RemoveLastDeallocForFuncRes(p);
Result:=true; Result:=true;
@ -2975,8 +2947,7 @@ unit aoptx86;
-> ->
decw %si addw %dx,%si p decw %si addw %dx,%si p
} }
asml.remove(hp2); RemoveInstruction(hp2);
hp2.Free;
RemoveCurrentP(p, hp1); RemoveCurrentP(p, hp1);
Result:=True; Result:=True;
Exit; Exit;
@ -3060,8 +3031,7 @@ unit aoptx86;
-> ->
decw %si addw %dx,%si p decw %si addw %dx,%si p
} }
asml.remove(hp2); RemoveInstruction(hp2);
hp2.Free;
end; end;
end; end;
@ -3080,9 +3050,7 @@ unit aoptx86;
Taicpu(hp2).opcode:=A_MOV; Taicpu(hp2).opcode:=A_MOV;
asml.remove(hp1); asml.remove(hp1);
insertllitem(hp2,hp2.next,hp1); insertllitem(hp2,hp2.next,hp1);
asml.remove(p); RemoveCurrentp(p, hp1);
p.free;
p:=hp1;
Result:=true; Result:=true;
exit; exit;
end; end;
@ -3124,15 +3092,15 @@ unit aoptx86;
if (taicpu(p).oper[1]^.typ=top_reg) and if (taicpu(p).oper[1]^.typ=top_reg) and
not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,hp1,UsedRegs)) then not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,hp1,UsedRegs)) then
begin begin
asml.remove(p);
p.free;
GetNextInstruction(hp1,p);
DebugMsg(SPeepholeOptimization + 'MovXXMovXX2Nop 1 done',p); DebugMsg(SPeepholeOptimization + 'MovXXMovXX2Nop 1 done',p);
RemoveInstruction(hp1);
RemoveCurrentp(p); { p will now be equal to the instruction that follows what was hp1 }
end end
else else
DebugMsg(SPeepholeOptimization + 'MovXXMovXX2MoVXX 1 done',p); begin
asml.remove(hp1); DebugMsg(SPeepholeOptimization + 'MovXXMovXX2MoVXX 1 done',p);
hp1.free; RemoveInstruction(hp1);
end;
Result:=true; Result:=true;
exit; exit;
end end
@ -3171,8 +3139,7 @@ unit aoptx86;
taicpu(p).loadoper(0,taicpu(hp1).oper[0]^); taicpu(p).loadoper(0,taicpu(hp1).oper[0]^);
taicpu(p).loadoper(1,taicpu(hp1).oper[1]^); taicpu(p).loadoper(1,taicpu(hp1).oper[1]^);
DebugMsg(SPeepholeOptimization + 'OpMov2Op done',p); DebugMsg(SPeepholeOptimization + 'OpMov2Op done',p);
asml.Remove(hp1); RemoveInstruction(hp1);
hp1.Free;
result:=true; result:=true;
end; end;
end; end;
@ -3243,8 +3210,7 @@ unit aoptx86;
begin begin
taicpu(p).loadoper(1,taicpu(hp1).oper[1]^); taicpu(p).loadoper(1,taicpu(hp1).oper[1]^);
DebugMsg(SPeepholeOptimization + 'LeaMov2Lea done',p); DebugMsg(SPeepholeOptimization + 'LeaMov2Lea done',p);
asml.Remove(hp1); RemoveInstruction(hp1);
hp1.Free;
result:=true; result:=true;
end; end;
end; end;
@ -3403,16 +3369,14 @@ unit aoptx86;
MatchOperand(taicpu(hp1).oper[0]^,taicpu(p).oper[1]^) then MatchOperand(taicpu(hp1).oper[0]^,taicpu(p).oper[1]^) then
begin begin
taicpu(p).loadConst(0,taicpu(p).oper[0]^.val+1); taicpu(p).loadConst(0,taicpu(p).oper[0]^.val+1);
asml.remove(hp1); RemoveInstruction(hp1);
hp1.free;
end; end;
A_SUB: A_SUB:
if MatchOpType(taicpu(hp1),top_const,top_reg) and if MatchOpType(taicpu(hp1),top_const,top_reg) and
MatchOperand(taicpu(hp1).oper[1]^,taicpu(p).oper[1]^) then MatchOperand(taicpu(hp1).oper[1]^,taicpu(p).oper[1]^) then
begin begin
taicpu(p).loadConst(0,taicpu(p).oper[0]^.val+taicpu(hp1).oper[0]^.val); taicpu(p).loadConst(0,taicpu(p).oper[0]^.val+taicpu(hp1).oper[0]^.val);
asml.remove(hp1); RemoveInstruction(hp1);
hp1.free;
end; end;
A_ADD: A_ADD:
begin begin
@ -3420,13 +3384,11 @@ unit aoptx86;
MatchOperand(taicpu(hp1).oper[1]^,taicpu(p).oper[1]^) then MatchOperand(taicpu(hp1).oper[1]^,taicpu(p).oper[1]^) then
begin begin
taicpu(p).loadConst(0,taicpu(p).oper[0]^.val-taicpu(hp1).oper[0]^.val); taicpu(p).loadConst(0,taicpu(p).oper[0]^.val-taicpu(hp1).oper[0]^.val);
asml.remove(hp1); RemoveInstruction(hp1);
hp1.free;
if (taicpu(p).oper[0]^.val = 0) then if (taicpu(p).oper[0]^.val = 0) then
begin begin
hp1 := tai(p.next); hp1 := tai(p.next);
asml.remove(p); RemoveInstruction(p); { Note, the choice to not use RemoveCurrentp is deliberate }
p.free;
if not GetLastInstruction(hp1, p) then if not GetLastInstruction(hp1, p) then
p := hp1; p := hp1;
DoSubAddOpt := True; DoSubAddOpt := True;
@ -3474,9 +3436,7 @@ unit aoptx86;
if taicpu(hp1).oper[0]^.typ=top_reg then if taicpu(hp1).oper[0]^.typ=top_reg then
setsubreg(taicpu(hp1).oper[0]^.reg,R_SUBWHOLE); setsubreg(taicpu(hp1).oper[0]^.reg,R_SUBWHOLE);
hp1 := tai(p.next); hp1 := tai(p.next);
asml.remove(p); RemoveCurrentp(p, hp1);
p.free;
p := hp1;
Result:=true; Result:=true;
exit; exit;
end; end;
@ -3546,8 +3506,7 @@ unit aoptx86;
if taicpu(hp1).oper[0]^.ref^.scalefactor<>0 then if taicpu(hp1).oper[0]^.ref^.scalefactor<>0 then
tmpref.scalefactor:=tmpref.scalefactor*taicpu(hp1).oper[0]^.ref^.scalefactor; tmpref.scalefactor:=tmpref.scalefactor*taicpu(hp1).oper[0]^.ref^.scalefactor;
TmpRef.base := taicpu(hp1).oper[0]^.ref^.base; TmpRef.base := taicpu(hp1).oper[0]^.ref^.base;
asml.remove(hp1); RemoveInstruction(hp1);
hp1.free;
end end
end end
else if (taicpu(hp1).oper[0]^.typ = Top_Const) then else if (taicpu(hp1).oper[0]^.typ = Top_Const) then
@ -3562,8 +3521,7 @@ unit aoptx86;
else else
internalerror(2019050536); internalerror(2019050536);
end; end;
asml.remove(hp1); RemoveInstruction(hp1);
hp1.free;
end end
else else
if (taicpu(hp1).oper[0]^.typ = Top_Reg) and if (taicpu(hp1).oper[0]^.typ = Top_Reg) and
@ -3584,8 +3542,7 @@ unit aoptx86;
else else
internalerror(2019050535); internalerror(2019050535);
end; end;
asml.remove(hp1); RemoveInstruction(hp1);
hp1.free;
end; end;
end; end;
if TmpBool2 if TmpBool2
@ -3715,14 +3672,12 @@ unit aoptx86;
{ Don't remove the 'mov' instruction if its register is used elsewhere } { Don't remove the 'mov' instruction if its register is used elsewhere }
if not(RegUsedAfterInstruction(taicpu(hp1).oper[1]^.reg, hp2, TmpUsedRegs)) then if not(RegUsedAfterInstruction(taicpu(hp1).oper[1]^.reg, hp2, TmpUsedRegs)) then
begin begin
asml.Remove(hp1); RemoveInstruction(hp1);
hp1.Free;
Result := True; Result := True;
end; end;
{ Only set Result to True if the 'mov' instruction was removed } { Only set Result to True if the 'mov' instruction was removed }
asml.Remove(hp2); RemoveInstruction(hp2);
hp2.Free;
end; end;
end end
else else
@ -3734,8 +3689,7 @@ unit aoptx86;
if not(RegUsedAfterInstruction(NR_DEFAULTFLAGS, hp1, TmpUsedRegs)) then if not(RegUsedAfterInstruction(NR_DEFAULTFLAGS, hp1, TmpUsedRegs)) then
begin begin
DebugMsg(SPeepholeOptimization + 'ShlAnd2Shl', p); DebugMsg(SPeepholeOptimization + 'ShlAnd2Shl', p);
asml.Remove(hp1); RemoveInstruction(hp1);
hp1.Free;
Result := True; Result := True;
end; end;
end; end;
@ -3825,8 +3779,7 @@ unit aoptx86;
Exit; Exit;
end; end;
asml.Remove(hp1); RemoveInstruction(hp1);
hp1.Free;
if Unconditional then if Unconditional then
MakeUnconditional(taicpu(hp2)) MakeUnconditional(taicpu(hp2))
@ -3840,11 +3793,8 @@ unit aoptx86;
if not RegUsedAfterInstruction(taicpu(p).oper[0]^.reg, hp2, TmpUsedRegs) then if not RegUsedAfterInstruction(taicpu(p).oper[0]^.reg, hp2, TmpUsedRegs) then
begin begin
asml.Remove(p); RemoveCurrentp(p, hp2);
UpdateUsedRegs(next);
p.Free;
Result := True; Result := True;
p := hp2;
end; end;
DebugMsg(SPeepholeOptimization + 'SETcc/TESTCmp/Jcc -> Jcc',p); DebugMsg(SPeepholeOptimization + 'SETcc/TESTCmp/Jcc -> Jcc',p);
@ -3879,11 +3829,8 @@ unit aoptx86;
(taicpu(p).oper[0]^.ref^.offset < tabstractnormalvarsym(current_procinfo.procdef.funcretsym).localloc.reference.offset)) and (taicpu(p).oper[0]^.ref^.offset < tabstractnormalvarsym(current_procinfo.procdef.funcretsym).localloc.reference.offset)) and
(taicpu(p).oper[0]^.ref^.index = NR_NO) then (taicpu(p).oper[0]^.ref^.index = NR_NO) then
begin begin
asml.remove(p); RemoveInstruction(hp1);
asml.remove(hp1); RemoveCurrentP(p, hp2);
p.free;
hp1.free;
p := hp2;
RemoveLastDeallocForFuncRes(p); RemoveLastDeallocForFuncRes(p);
Result := true; Result := true;
end end
@ -3896,8 +3843,7 @@ unit aoptx86;
if (taicpu(p).opcode = A_FSTP) then if (taicpu(p).opcode = A_FSTP) then
taicpu(p).opcode := A_FST taicpu(p).opcode := A_FST
else taicpu(p).opcode := A_FIST; else taicpu(p).opcode := A_FIST;
asml.remove(hp1); RemoveInstruction(hp1);
hp1.free;
end end
*) *)
end; end;
@ -3937,9 +3883,7 @@ unit aoptx86;
end; end;
taicpu(hp1).oper[0]^.reg := taicpu(p).oper[0]^.reg; taicpu(hp1).oper[0]^.reg := taicpu(p).oper[0]^.reg;
taicpu(hp1).oper[1]^.reg := NR_ST; taicpu(hp1).oper[1]^.reg := NR_ST;
asml.remove(p); RemoveCurrentP(p, hp1);
p.free;
p := hp1;
Result:=true; Result:=true;
exit; exit;
end; end;
@ -3967,9 +3911,7 @@ unit aoptx86;
faddp/ fmul st, st faddp/ fmul st, st
fmulp st, st1 (hp2) } fmulp st, st1 (hp2) }
begin begin
asml.remove(p); RemoveCurrentP(p, hp1);
p.free;
p := hp1;
if (taicpu(hp2).opcode = A_FADDP) then if (taicpu(hp2).opcode = A_FADDP) then
taicpu(hp2).opcode := A_FADD taicpu(hp2).opcode := A_FADD
else else
@ -4004,8 +3946,7 @@ unit aoptx86;
else else
internalerror(2019050533); internalerror(2019050533);
end; end;
asml.remove(hp2); RemoveInstruction(hp2);
hp2.free;
end end
else else
; ;
@ -4055,8 +3996,7 @@ unit aoptx86;
begin begin
DebugMsg(SPeepholeOptimization + 'Cmpcc2Testcc - condition B/C/NAE/O --> Never (jump removed)', hp1); DebugMsg(SPeepholeOptimization + 'Cmpcc2Testcc - condition B/C/NAE/O --> Never (jump removed)', hp1);
TAsmLabel(taicpu(hp1).oper[0]^.ref^.symbol).decrefs; TAsmLabel(taicpu(hp1).oper[0]^.ref^.symbol).decrefs;
AsmL.Remove(hp1); RemoveInstruction(hp1);
hp1.Free;
{ Since hp1 was deleted, hp2 must not be updated } { Since hp1 was deleted, hp2 must not be updated }
Continue; Continue;
end end
@ -4221,8 +4161,7 @@ unit aoptx86;
MatchOperand(taicpu(hp1).oper[0]^,taicpu(hp1).oper[1]^) then MatchOperand(taicpu(hp1).oper[0]^,taicpu(hp1).oper[1]^) then
begin begin
DebugMsg(SPeepholeOptimization + 'PXorPXor2PXor done',hp1); DebugMsg(SPeepholeOptimization + 'PXorPXor2PXor done',hp1);
asml.Remove(hp1); RemoveInstruction(hp1);
hp1.Free;
Result:=true; Result:=true;
Exit; Exit;
end; end;
@ -4249,8 +4188,7 @@ unit aoptx86;
MatchOperand(taicpu(hp1).oper[0]^,taicpu(hp1).oper[1]^,taicpu(hp1).oper[2]^) then MatchOperand(taicpu(hp1).oper[0]^,taicpu(hp1).oper[1]^,taicpu(hp1).oper[2]^) then
begin begin
DebugMsg(SPeepholeOptimization + 'VPXorVPXor2PXor done',hp1); DebugMsg(SPeepholeOptimization + 'VPXorVPXor2PXor done',hp1);
asml.Remove(hp1); RemoveInstruction(hp1);
hp1.Free;
Result:=true; Result:=true;
Exit; Exit;
end; end;
@ -4348,8 +4286,7 @@ unit aoptx86;
taicpu(p).opcode := A_LEA; taicpu(p).opcode := A_LEA;
taicpu(p).loadref(0, NewRef); taicpu(p).loadref(0, NewRef);
Asml.Remove(hp1); RemoveInstruction(hp1);
hp1.Free;
Result := True; Result := True;
Exit; Exit;
@ -4379,9 +4316,7 @@ unit aoptx86;
not RegUsedAfterInstruction(taicpu(p).oper[1]^.reg, hp1, TmpUsedRegs) not RegUsedAfterInstruction(taicpu(p).oper[1]^.reg, hp1, TmpUsedRegs)
then then
begin begin
asml.remove(p); RemoveCurrentP(p, hp1);
p.free;
p := hp1;
Result:=true; Result:=true;
end; end;
@ -4420,12 +4355,9 @@ unit aoptx86;
AllocRegBetween(taicpu(hp2).oper[1]^.reg, p, hp1, UsedRegs); AllocRegBetween(taicpu(hp2).oper[1]^.reg, p, hp1, UsedRegs);
taicpu(hp1).opcode := A_XCHG; taicpu(hp1).opcode := A_XCHG;
asml.Remove(p); RemoveCurrentP(p, hp1);
asml.Remove(hp2); RemoveInstruction(hp2);
p.Free;
hp2.Free;
p := hp1;
Result := True; Result := True;
Exit; Exit;
end; end;
@ -4449,8 +4381,7 @@ unit aoptx86;
cltd cltd
} }
DebugMsg(SPeepholeOptimization + 'MovSar2Cltd', p); DebugMsg(SPeepholeOptimization + 'MovSar2Cltd', p);
Asml.Remove(hp1); RemoveInstruction(hp1);
hp1.Free;
taicpu(p).opcode := A_CDQ; taicpu(p).opcode := A_CDQ;
taicpu(p).opsize := S_NO; taicpu(p).opsize := S_NO;
taicpu(p).clearop(1); taicpu(p).clearop(1);
@ -4531,8 +4462,7 @@ unit aoptx86;
taicpu(p).clearop(0); taicpu(p).clearop(0);
taicpu(p).ops:=0; taicpu(p).ops:=0;
AsmL.Remove(hp1); RemoveInstruction(hp1);
hp1.Free;
taicpu(hp2).loadreg(0, NR_EDX); taicpu(hp2).loadreg(0, NR_EDX);
taicpu(hp2).loadreg(1, NR_EAX); taicpu(hp2).loadreg(1, NR_EAX);
@ -4578,8 +4508,7 @@ unit aoptx86;
cqto cqto
} }
DebugMsg(SPeepholeOptimization + 'MovSar2Cqto', p); DebugMsg(SPeepholeOptimization + 'MovSar2Cqto', p);
Asml.Remove(hp1); RemoveInstruction(hp1);
hp1.Free;
taicpu(p).opcode := A_CQO; taicpu(p).opcode := A_CQO;
taicpu(p).opsize := S_NO; taicpu(p).opsize := S_NO;
taicpu(p).clearop(1); taicpu(p).clearop(1);
@ -4660,8 +4589,7 @@ unit aoptx86;
taicpu(hp1).clearop(0); taicpu(hp1).clearop(0);
taicpu(hp1).ops:=0; taicpu(hp1).ops:=0;
AsmL.Remove(hp2); RemoveInstruction(hp2);
hp2.Free;
(* (*
{$ifdef x86_64} {$ifdef x86_64}
end end
@ -4708,8 +4636,7 @@ unit aoptx86;
taicpu(hp1).clearop(0); taicpu(hp1).clearop(0);
taicpu(hp1).ops:=0; taicpu(hp1).ops:=0;
AsmL.Remove(hp2); RemoveInstruction(hp2);
hp2.Free;
{$endif x86_64} {$endif x86_64}
*) *)
end; end;
@ -4799,8 +4726,7 @@ unit aoptx86;
taicpu(hp1).opcode := A_ADD; taicpu(hp1).opcode := A_ADD;
{ Delete old ADD/LEA instruction } { Delete old ADD/LEA instruction }
asml.remove(hp2); RemoveInstruction(hp2);
hp2.free;
{ Convert "shrq $1, reg1q" to "rcr $1, reg1d" } { Convert "shrq $1, reg1q" to "rcr $1, reg1d" }
taicpu(hp3).opcode := A_RCR; taicpu(hp3).opcode := A_RCR;
@ -4839,8 +4765,7 @@ unit aoptx86;
taicpu(p).loadreg(2,taicpu(p).oper[1]^.reg); taicpu(p).loadreg(2,taicpu(p).oper[1]^.reg);
taicpu(p).loadreg(1,taicpu(hp1).oper[0]^.reg); taicpu(p).loadreg(1,taicpu(hp1).oper[0]^.reg);
DebugMsg(SPeepholeOptimization + 'MovImul2Imul done',p); DebugMsg(SPeepholeOptimization + 'MovImul2Imul done',p);
asml.remove(hp1); RemoveInstruction(hp1);
hp1.free;
result:=true; result:=true;
end; end;
end; end;
@ -5270,8 +5195,7 @@ unit aoptx86;
DebugMsg(SPeepholeOptimization+'JccMov2CMov',p); DebugMsg(SPeepholeOptimization+'JccMov2CMov',p);
{ Remove the original jump } { Remove the original jump }
asml.Remove(p); RemoveInstruction(p); { Note, the choice to not use RemoveCurrentp is deliberate }
p.Free;
GetNextInstruction(hp2, p); { Instruction after the label } GetNextInstruction(hp2, p); { Instruction after the label }
@ -5369,8 +5293,7 @@ unit aoptx86;
DebugMsg(SPeepholeOptimization+'JccMovJmpMov2CMovCMov',hp1); DebugMsg(SPeepholeOptimization+'JccMovJmpMov2CMovCMov',hp1);
{ remove jCC } { remove jCC }
asml.remove(hp1); RemoveInstruction(hp1);
hp1.free;
{ Now we can safely decrement it } { Now we can safely decrement it }
tasmlabel(symbol).decrefs; tasmlabel(symbol).decrefs;
@ -5381,8 +5304,7 @@ unit aoptx86;
{ remove jmp } { remove jmp }
symbol := taicpu(hp2).oper[0]^.ref^.symbol; symbol := taicpu(hp2).oper[0]^.ref^.symbol;
asml.remove(hp2); RemoveInstruction(hp2);
hp2.free;
{ As before, now we can safely decrement it } { As before, now we can safely decrement it }
tasmlabel(symbol).decrefs; tasmlabel(symbol).decrefs;
@ -5483,11 +5405,8 @@ unit aoptx86;
decw %si addw %dx,%si p decw %si addw %dx,%si p
} }
DebugMsg(SPeepholeOptimization + 'var3',p); DebugMsg(SPeepholeOptimization + 'var3',p);
asml.remove(p); RemoveCurrentP(p, hp1);
asml.remove(hp2); RemoveInstruction(hp2);
p.free;
hp2.free;
p:=hp1;
end end
else if reg_and_hp1_is_instr and else if reg_and_hp1_is_instr and
(taicpu(hp1).opcode = A_MOV) and (taicpu(hp1).opcode = A_MOV) and
@ -5525,8 +5444,7 @@ unit aoptx86;
else else
{$endif x86_64} {$endif x86_64}
taicpu(p).loadreg(1,taicpu(hp1).oper[1]^.reg); taicpu(p).loadreg(1,taicpu(hp1).oper[1]^.reg);
asml.remove(hp1); RemoveInstruction(hp1);
hp1.Free;
end; end;
end end
else if reg_and_hp1_is_instr and else if reg_and_hp1_is_instr and
@ -5571,15 +5489,13 @@ unit aoptx86;
if (taicpu(hp1).oper[0]^.val = $ff) then if (taicpu(hp1).oper[0]^.val = $ff) then
begin begin
DebugMsg(SPeepholeOptimization + 'var4',p); DebugMsg(SPeepholeOptimization + 'var4',p);
asml.remove(hp1); RemoveInstruction(hp1);
hp1.free;
end; end;
S_WL{$ifdef x86_64}, S_WQ{$endif x86_64}: S_WL{$ifdef x86_64}, S_WQ{$endif x86_64}:
if (taicpu(hp1).oper[0]^.val = $ffff) then if (taicpu(hp1).oper[0]^.val = $ffff) then
begin begin
DebugMsg(SPeepholeOptimization + 'var5',p); DebugMsg(SPeepholeOptimization + 'var5',p);
asml.remove(hp1); RemoveInstruction(hp1);
hp1.free;
end; end;
{$ifdef x86_64} {$ifdef x86_64}
S_LQ: S_LQ:
@ -5587,8 +5503,7 @@ unit aoptx86;
begin begin
if (cs_asm_source in current_settings.globalswitches) then if (cs_asm_source in current_settings.globalswitches) then
asml.insertbefore(tai_comment.create(strpnew(SPeepholeOptimization + 'var6')),p); asml.insertbefore(tai_comment.create(strpnew(SPeepholeOptimization + 'var6')),p);
asml.remove(hp1); RemoveInstruction(hp1);
hp1.Free;
end; end;
{$endif x86_64} {$endif x86_64}
else else
@ -5781,9 +5696,7 @@ unit aoptx86;
begin begin
taicpu(hp1).loadConst(0, taicpu(p).oper[0]^.val and taicpu(hp1).oper[0]^.val); taicpu(hp1).loadConst(0, taicpu(p).oper[0]^.val and taicpu(hp1).oper[0]^.val);
DebugMsg(SPeepholeOptimization + 'AndAnd2And done',hp1); DebugMsg(SPeepholeOptimization + 'AndAnd2And done',hp1);
asml.remove(p); RemoveCurrentP(p, hp1);
p.Free;
p:=hp1;
Result:=true; Result:=true;
exit; exit;
end end
@ -5819,8 +5732,7 @@ unit aoptx86;
} }
DebugMsg(SPeepholeOptimization + 'AndMovzToAnd done',p); DebugMsg(SPeepholeOptimization + 'AndMovzToAnd done',p);
asml.remove(hp1); RemoveInstruction(hp1);
hp1.free;
Exit; Exit;
end; end;
end end
@ -5880,8 +5792,7 @@ unit aoptx86;
then then
begin begin
DebugMsg(SPeepholeOptimization + 'AndMovsxToAnd',p); DebugMsg(SPeepholeOptimization + 'AndMovsxToAnd',p);
asml.remove(hp1); RemoveInstruction(hp1);
hp1.free;
Exit; Exit;
end; end;
end end
@ -6074,10 +5985,8 @@ unit aoptx86;
taicpu(hp1).is_jmp := true; taicpu(hp1).is_jmp := true;
DebugMsg(SPeepholeOptimization + 'LeaCallLeaRet2Jmp done',p); DebugMsg(SPeepholeOptimization + 'LeaCallLeaRet2Jmp done',p);
RemoveCurrentP(p, hp4); RemoveCurrentP(p, hp4);
AsmL.Remove(hp2); RemoveInstruction(hp2);
hp2.free; RemoveInstruction(hp3);
AsmL.Remove(hp3);
hp3.free;
Result:=true; Result:=true;
end; end;
end; end;
@ -6127,10 +6036,8 @@ unit aoptx86;
taicpu(hp1).is_jmp := true; taicpu(hp1).is_jmp := true;
DebugMsg(SPeepholeOptimization + 'PushCallPushRet2Jmp done',p); DebugMsg(SPeepholeOptimization + 'PushCallPushRet2Jmp done',p);
RemoveCurrentP(p, hp4); RemoveCurrentP(p, hp4);
AsmL.Remove(hp2); RemoveInstruction(hp2);
hp2.free; RemoveInstruction(hp3);
AsmL.Remove(hp3);
hp3.free;
Result:=true; Result:=true;
end; end;
{$endif x86_64} {$endif x86_64}
@ -6283,10 +6190,7 @@ unit aoptx86;
((taicpu(hp1).opcode <> A_ADD) and ((taicpu(hp1).opcode <> A_ADD) and
(taicpu(hp1).opcode <> A_SUB))) then (taicpu(hp1).opcode <> A_SUB))) then
begin begin
hp1 := tai(p.next); RemoveCurrentP(p, hp2);
asml.remove(p);
p.free;
p := tai(hp1);
Result:=true; Result:=true;
end; end;
end; end;
@ -6302,10 +6206,7 @@ unit aoptx86;
{ and in case of carry for A(E)/B(E)/C/NC } { and in case of carry for A(E)/B(E)/C/NC }
(taicpu(hp2).condition in [C_Z,C_NZ,C_E,C_NE]) then (taicpu(hp2).condition in [C_Z,C_NZ,C_E,C_NE]) then
begin begin
hp1 := tai(p.next); RemoveCurrentP(p, hp2);
asml.remove(p);
p.free;
p := tai(hp1);
Result:=true; Result:=true;
end; end;
end; end;
@ -6333,10 +6234,7 @@ unit aoptx86;
else else
; ;
end; end;
hp1 := tai(p.next); RemoveCurrentP(p, hp2);
asml.remove(p);
p.free;
p := tai(hp1);
Result:=true; Result:=true;
end; end;
end end
@ -6373,8 +6271,7 @@ unit aoptx86;
InsertLLItem(p.previous, p, hp2); InsertLLItem(p.previous, p, hp2);
taicpu(p).opcode := A_JMP; taicpu(p).opcode := A_JMP;
taicpu(p).is_jmp := true; taicpu(p).is_jmp := true;
asml.remove(hp1); RemoveInstruction(hp1);
hp1.free;
Result:=true; Result:=true;
end end
else else
@ -6405,8 +6302,7 @@ unit aoptx86;
end end
else else
DebugMsg(SPeepholeOptimization + 'CallRet2Call done',p); DebugMsg(SPeepholeOptimization + 'CallRet2Call done',p);
asml.remove(hp1); RemoveInstruction(hp1);
hp1.free;
Result:=true; Result:=true;
end; end;
end; end;