mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-14 19:49:09 +02:00
* patch by J. Gareth Moreton for less invasive DEBUG_AOPTCPU
git-svn-id: trunk@39239 -
This commit is contained in:
parent
373061043b
commit
a0b343a787
@ -105,8 +105,15 @@ unit aoptx86;
|
|||||||
and having an offset }
|
and having an offset }
|
||||||
function MatchReferenceWithOffset(const ref : treference;base,index : TRegister) : Boolean;
|
function MatchReferenceWithOffset(const ref : treference;base,index : TRegister) : Boolean;
|
||||||
|
|
||||||
|
{$ifdef DEBUG_AOPTCPU}
|
||||||
const
|
const
|
||||||
SPeepholeOptimization: string = 'Peephole Optimization: ';
|
SPeepholeOptimization: shortstring = 'Peephole Optimization: ';
|
||||||
|
{$else DEBUG_AOPTCPU}
|
||||||
|
{ Empty strings help the optimizer to remove string concatenations that won't
|
||||||
|
ever appear to the user on release builds. [Kit] }
|
||||||
|
const
|
||||||
|
SPeepholeOptimization = '';
|
||||||
|
{$endif DEBUG_AOPTCPU}
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
@ -485,10 +492,91 @@ unit aoptx86;
|
|||||||
begin
|
begin
|
||||||
asml.insertbefore(tai_comment.Create(strpnew(s)), p);
|
asml.insertbefore(tai_comment.Create(strpnew(s)), p);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function debug_tostr(i: tcgint): string; inline;
|
||||||
|
begin
|
||||||
|
Result := tostr(i);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function debug_regname(r: TRegister): string; inline;
|
||||||
|
begin
|
||||||
|
Result := '%' + std_regname(r);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Debug output function - creates a string representation of an operator }
|
||||||
|
function debug_operstr(oper: TOper): string;
|
||||||
|
begin
|
||||||
|
case oper.typ of
|
||||||
|
top_const:
|
||||||
|
Result := '$' + debug_tostr(oper.val);
|
||||||
|
top_reg:
|
||||||
|
Result := debug_regname(oper.reg);
|
||||||
|
top_ref:
|
||||||
|
begin
|
||||||
|
if oper.ref^.offset <> 0 then
|
||||||
|
Result := debug_tostr(oper.ref^.offset) + '('
|
||||||
|
else
|
||||||
|
Result := '(';
|
||||||
|
|
||||||
|
if (oper.ref^.base <> NR_INVALID) and (oper.ref^.base <> NR_NO) then
|
||||||
|
begin
|
||||||
|
Result := Result + debug_regname(oper.ref^.base);
|
||||||
|
if (oper.ref^.index <> NR_INVALID) and (oper.ref^.index <> NR_NO) then
|
||||||
|
Result := Result + ',' + debug_regname(oper.ref^.index);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if (oper.ref^.index <> NR_INVALID) and (oper.ref^.index <> NR_NO) then
|
||||||
|
Result := Result + debug_regname(oper.ref^.index);
|
||||||
|
|
||||||
|
if (oper.ref^.scalefactor > 1) then
|
||||||
|
Result := Result + ',' + debug_tostr(oper.ref^.scalefactor) + ')'
|
||||||
|
else
|
||||||
|
Result := Result + ')';
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
Result := '[UNKNOWN]';
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function debug_op2str(opcode: tasmop): string; inline;
|
||||||
|
begin
|
||||||
|
Result := std_op2str[opcode];
|
||||||
|
end;
|
||||||
|
|
||||||
|
function debug_opsize2str(opsize: topsize): string; inline;
|
||||||
|
begin
|
||||||
|
Result := gas_opsize2str[opsize];
|
||||||
|
end;
|
||||||
|
|
||||||
{$else DEBUG_AOPTCPU}
|
{$else DEBUG_AOPTCPU}
|
||||||
procedure TX86AsmOptimizer.DebugMsg(const s: string;p : tai);inline;
|
procedure TX86AsmOptimizer.DebugMsg(const s: string;p : tai);inline;
|
||||||
begin
|
begin
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function debug_tostr(i: tcgint): string; inline;
|
||||||
|
begin
|
||||||
|
Result := '';
|
||||||
|
end;
|
||||||
|
|
||||||
|
function debug_regname(r: TRegister): string; inline;
|
||||||
|
begin
|
||||||
|
Result := '';
|
||||||
|
end;
|
||||||
|
|
||||||
|
function debug_operstr(oper: TOper): string; inline;
|
||||||
|
begin
|
||||||
|
Result := '';
|
||||||
|
end;
|
||||||
|
|
||||||
|
function debug_op2str(opcode: tasmop): string; inline;
|
||||||
|
begin
|
||||||
|
Result := '';
|
||||||
|
end;
|
||||||
|
|
||||||
|
function debug_opsize2str(opsize: topsize): string; inline;
|
||||||
|
begin
|
||||||
|
Result := '';
|
||||||
|
end;
|
||||||
{$endif DEBUG_AOPTCPU}
|
{$endif DEBUG_AOPTCPU}
|
||||||
|
|
||||||
|
|
||||||
@ -890,9 +978,9 @@ unit aoptx86;
|
|||||||
If not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,hp2,TmpUsedRegs)) then
|
If not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,hp2,TmpUsedRegs)) then
|
||||||
begin
|
begin
|
||||||
DebugMsg(SPeepholeOptimization + 'MovapXOpMovapX2Op ('+
|
DebugMsg(SPeepholeOptimization + 'MovapXOpMovapX2Op ('+
|
||||||
std_op2str[taicpu(p).opcode]+' '+
|
debug_op2str(taicpu(p).opcode)+' '+
|
||||||
std_op2str[taicpu(hp1).opcode]+' '+
|
debug_op2str(taicpu(hp1).opcode)+' '+
|
||||||
std_op2str[taicpu(hp2).opcode]+') done',p);
|
debug_op2str(taicpu(hp2).opcode)+') done',p);
|
||||||
{ we cannot eliminate the first move if
|
{ we cannot eliminate the first move if
|
||||||
the operations uses the same register for source and dest }
|
the operations uses the same register for source and dest }
|
||||||
if not(OpsEqual(taicpu(hp1).oper[1]^,taicpu(hp1).oper[0]^)) then
|
if not(OpsEqual(taicpu(hp1).oper[1]^,taicpu(hp1).oper[0]^)) then
|
||||||
@ -1118,12 +1206,8 @@ unit aoptx86;
|
|||||||
(getsupreg(taicpu(p).oper[1]^.reg) = getsupreg(taicpu(hp1).oper[1]^.reg))
|
(getsupreg(taicpu(p).oper[1]^.reg) = getsupreg(taicpu(hp1).oper[1]^.reg))
|
||||||
then
|
then
|
||||||
begin
|
begin
|
||||||
if taicpu(p).oper[0]^.typ = top_reg then
|
InputVal := debug_operstr(taicpu(p).oper[0]^);
|
||||||
InputVal := '%' + std_regname(taicpu(p).oper[0]^.reg)
|
MaskNum := debug_tostr(taicpu(hp1).oper[0]^.val);
|
||||||
else
|
|
||||||
InputVal := 'x';
|
|
||||||
|
|
||||||
MaskNum := tostr(taicpu(hp1).oper[0]^.val);
|
|
||||||
|
|
||||||
case taicpu(p).opsize of
|
case taicpu(p).opsize of
|
||||||
S_B:
|
S_B:
|
||||||
@ -1137,8 +1221,8 @@ unit aoptx86;
|
|||||||
|
|
||||||
(Identical registers, just different sizes)
|
(Identical registers, just different sizes)
|
||||||
}
|
}
|
||||||
RegName1 := std_regname(taicpu(p).oper[1]^.reg); { 8-bit register name }
|
RegName1 := debug_regname(taicpu(p).oper[1]^.reg); { 8-bit register name }
|
||||||
RegName2 := std_regname(taicpu(hp1).oper[1]^.reg); { 16/32-bit register name }
|
RegName2 := debug_regname(taicpu(hp1).oper[1]^.reg); { 16/32-bit register name }
|
||||||
|
|
||||||
case taicpu(hp1).opsize of
|
case taicpu(hp1).opsize of
|
||||||
S_W: NewSize := S_BW;
|
S_W: NewSize := S_BW;
|
||||||
@ -1163,8 +1247,8 @@ unit aoptx86;
|
|||||||
|
|
||||||
(Identical registers, just different sizes)
|
(Identical registers, just different sizes)
|
||||||
}
|
}
|
||||||
RegName1 := std_regname(taicpu(p).oper[1]^.reg); { 16-bit register name }
|
RegName1 := debug_regname(taicpu(p).oper[1]^.reg); { 16-bit register name }
|
||||||
RegName2 := std_regname(taicpu(hp1).oper[1]^.reg); { 32-bit register name }
|
RegName2 := debug_regname(taicpu(hp1).oper[1]^.reg); { 32-bit register name }
|
||||||
|
|
||||||
case taicpu(hp1).opsize of
|
case taicpu(hp1).opsize of
|
||||||
S_L: NewSize := S_WL;
|
S_L: NewSize := S_WL;
|
||||||
@ -1183,7 +1267,7 @@ unit aoptx86;
|
|||||||
|
|
||||||
if NewSize <> S_NO then
|
if NewSize <> S_NO then
|
||||||
begin
|
begin
|
||||||
PreMessage := 'mov' + gas_opsize2str[taicpu(p).opsize] + ' ' + InputVal + ',%' + RegName1;
|
PreMessage := 'mov' + debug_opsize2str(taicpu(p).opsize) + ' ' + InputVal + ',' + RegName1;
|
||||||
|
|
||||||
{ The actual optimization }
|
{ The actual optimization }
|
||||||
taicpu(p).opcode := A_MOVZX;
|
taicpu(p).opcode := A_MOVZX;
|
||||||
@ -1201,12 +1285,12 @@ unit aoptx86;
|
|||||||
Peephole Optimizer. [Kit] }
|
Peephole Optimizer. [Kit] }
|
||||||
|
|
||||||
DebugMsg(SPeepholeOptimization + PreMessage +
|
DebugMsg(SPeepholeOptimization + PreMessage +
|
||||||
' -> movz' + gas_opsize2str[NewSize] + ' ' + InputVal + ',%' + RegName2, p);
|
' -> movz' + debug_opsize2str(NewSize) + ' ' + InputVal + ',' + RegName2, p);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
DebugMsg(SPeepholeOptimization + PreMessage + '; and' + gas_opsize2str[taicpu(hp1).opsize] + ' $' + MaskNum + ',%' + RegName2 +
|
DebugMsg(SPeepholeOptimization + PreMessage + '; and' + debug_opsize2str(taicpu(hp1).opsize) + ' $' + MaskNum + ',' + RegName2 +
|
||||||
' -> movz' + gas_opsize2str[NewSize] + ' ' + InputVal + ',%' + RegName2, p);
|
' -> movz' + debug_opsize2str(NewSize) + ' ' + InputVal + ',' + RegName2, p);
|
||||||
|
|
||||||
asml.Remove(hp1);
|
asml.Remove(hp1);
|
||||||
hp1.Free;
|
hp1.Free;
|
||||||
@ -1667,9 +1751,9 @@ unit aoptx86;
|
|||||||
movw %ax,%si movw %ax,%si hp2
|
movw %ax,%si movw %ax,%si hp2
|
||||||
}
|
}
|
||||||
DebugMsg(SPeepholeOptimization + 'MovOpMov2Op ('+
|
DebugMsg(SPeepholeOptimization + 'MovOpMov2Op ('+
|
||||||
std_op2str[taicpu(p).opcode]+gas_opsize2str[taicpu(p).opsize]+' '+
|
debug_op2str(taicpu(p).opcode)+debug_opsize2str(taicpu(p).opsize)+' '+
|
||||||
std_op2str[taicpu(hp1).opcode]+gas_opsize2str[taicpu(hp1).opsize]+' '+
|
debug_op2str(taicpu(hp1).opcode)+debug_opsize2str(taicpu(hp1).opsize)+' '+
|
||||||
std_op2str[taicpu(hp2).opcode]+gas_opsize2str[taicpu(hp2).opsize],p);
|
debug_op2str(taicpu(hp2).opcode)+debug_opsize2str(taicpu(hp2).opsize),p);
|
||||||
taicpu(hp1).changeopsize(taicpu(hp2).opsize);
|
taicpu(hp1).changeopsize(taicpu(hp2).opsize);
|
||||||
{
|
{
|
||||||
->
|
->
|
||||||
@ -3014,14 +3098,14 @@ unit aoptx86;
|
|||||||
case taicpu(p).opsize of
|
case taicpu(p).opsize of
|
||||||
S_Q:
|
S_Q:
|
||||||
begin
|
begin
|
||||||
RegName := std_regname(taicpu(p).oper[1]^.reg); { 64-bit register name }
|
RegName := debug_regname(taicpu(p).oper[1]^.reg); { 64-bit register name }
|
||||||
Value := tostr(taicpu(p).oper[0]^.val);
|
Value := debug_tostr(taicpu(p).oper[0]^.val);
|
||||||
|
|
||||||
{ The actual optimization }
|
{ The actual optimization }
|
||||||
setsubreg(taicpu(p).oper[1]^.reg, R_SUBD);
|
setsubreg(taicpu(p).oper[1]^.reg, R_SUBD);
|
||||||
taicpu(p).changeopsize(S_L);
|
taicpu(p).changeopsize(S_L);
|
||||||
|
|
||||||
DebugMsg(SPeepholeOptimization + 'movq $' + Value + ',%' + RegName + ' -> movl $' + Value + ',%' + std_regname(taicpu(p).oper[1]^.reg) + ' (immediate can be represented with just 32 bits)', p);
|
DebugMsg(SPeepholeOptimization + 'movq $' + Value + ',' + RegName + ' -> movl $' + Value + ',' + debug_regname(taicpu(p).oper[1]^.reg) + ' (immediate can be represented with just 32 bits)', p);
|
||||||
Result := True;
|
Result := True;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -3203,7 +3287,7 @@ unit aoptx86;
|
|||||||
then
|
then
|
||||||
begin
|
begin
|
||||||
{ Has 64-bit register name and opcode suffix }
|
{ Has 64-bit register name and opcode suffix }
|
||||||
PreMessage := 'movz' + gas_opsize2str[taicpu(p).opsize] + ' x,%' + std_regname(taicpu(p).oper[1]^.reg) + ' -> movz';
|
PreMessage := 'movz' + debug_opsize2str(taicpu(p).opsize) + ' ' + debug_operstr(taicpu(p).oper[0]^) + ',' + debug_regname(taicpu(p).oper[1]^.reg) + ' -> movz';
|
||||||
|
|
||||||
{ The actual optimization }
|
{ The actual optimization }
|
||||||
setsubreg(taicpu(p).oper[1]^.reg, R_SUBD);
|
setsubreg(taicpu(p).oper[1]^.reg, R_SUBD);
|
||||||
@ -3213,7 +3297,7 @@ unit aoptx86;
|
|||||||
taicpu(p).changeopsize(S_WL);
|
taicpu(p).changeopsize(S_WL);
|
||||||
|
|
||||||
DebugMsg(SPeepholeOptimization + PreMessage +
|
DebugMsg(SPeepholeOptimization + PreMessage +
|
||||||
gas_opsize2str[taicpu(p).opsize] + ' x,%' + std_regname(taicpu(p).oper[1]^.reg) + ' (removes REX prefix)', p);
|
debug_opsize2str(taicpu(p).opsize) + ' ' + debug_operstr(taicpu(p).oper[0]^) + ',' + debug_regname(taicpu(p).oper[1]^.reg) + ' (removes REX prefix)', p);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -3238,17 +3322,17 @@ unit aoptx86;
|
|||||||
S_Q:
|
S_Q:
|
||||||
if (getsupreg(taicpu(p).oper[0]^.reg) in [RS_RAX, RS_RCX, RS_RDX, RS_RBX, RS_RSI, RS_RDI, RS_RBP, RS_RSP]) then
|
if (getsupreg(taicpu(p).oper[0]^.reg) in [RS_RAX, RS_RCX, RS_RDX, RS_RBX, RS_RSI, RS_RDI, RS_RBP, RS_RSP]) then
|
||||||
begin
|
begin
|
||||||
RegName := std_regname(taicpu(p).oper[0]^.reg); { 64-bit register name }
|
RegName := debug_regname(taicpu(p).oper[0]^.reg); { 64-bit register name }
|
||||||
PreMessage := 'xorq %' + RegName + ',%' + RegName + ' -> xorl %';
|
PreMessage := 'xorq ' + RegName + ',' + RegName + ' -> xorl ';
|
||||||
|
|
||||||
{ The actual optimization }
|
{ The actual optimization }
|
||||||
setsubreg(taicpu(p).oper[0]^.reg, R_SUBD);
|
setsubreg(taicpu(p).oper[0]^.reg, R_SUBD);
|
||||||
setsubreg(taicpu(p).oper[1]^.reg, R_SUBD);
|
setsubreg(taicpu(p).oper[1]^.reg, R_SUBD);
|
||||||
taicpu(p).changeopsize(S_L);
|
taicpu(p).changeopsize(S_L);
|
||||||
|
|
||||||
RegName := std_regname(taicpu(p).oper[0]^.reg); { 32-bit register name }
|
RegName := debug_regname(taicpu(p).oper[0]^.reg); { 32-bit register name }
|
||||||
|
|
||||||
DebugMsg(SPeepholeOptimization + PreMessage + RegName + ',%' + RegName + ' (removes REX prefix)', p);
|
DebugMsg(SPeepholeOptimization + PreMessage + RegName + ',' + RegName + ' (removes REX prefix)', p);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
Loading…
Reference in New Issue
Block a user