mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-21 12:29:46 +02:00
* fold <arithmed. op> ...; cmp ...,#0into cmps on arm
* remove unnecessary ldr after str to the same memoy location, however, to do this optimization safely, we should add support for volatile variables git-svn-id: trunk@20399 -
This commit is contained in:
parent
f0f64a573b
commit
e2c9a8c6a1
@ -47,6 +47,7 @@ Implementation
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
verbose,
|
verbose,
|
||||||
|
cgutils,
|
||||||
aasmbase,aasmcpu;
|
aasmbase,aasmcpu;
|
||||||
|
|
||||||
function CanBeCond(p : tai) : boolean;
|
function CanBeCond(p : tai) : boolean;
|
||||||
@ -59,16 +60,95 @@ Implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function RefsEqual(const r1, r2: treference): boolean;
|
||||||
|
begin
|
||||||
|
refsequal :=
|
||||||
|
(r1.offset = r2.offset) and
|
||||||
|
(r1.base = r2.base) and
|
||||||
|
(r1.index = r2.index) and (r1.scalefactor = r2.scalefactor) and
|
||||||
|
(r1.symbol=r2.symbol) and (r1.refaddr = r2.refaddr) and
|
||||||
|
(r1.relsymbol = r2.relsymbol) and
|
||||||
|
(r1.signindex = r2.signindex) and
|
||||||
|
(r1.shiftimm = r2.shiftimm) and
|
||||||
|
(r1.addressmode = r2.addressmode) and
|
||||||
|
(r1.shiftmode = r2.shiftmode);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
|
function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
|
||||||
var
|
var
|
||||||
next1: tai;
|
next1: tai;
|
||||||
hp1: tai;
|
hp1,hp2: tai;
|
||||||
begin
|
begin
|
||||||
result := false;
|
result := false;
|
||||||
case p.typ of
|
case p.typ of
|
||||||
ait_instruction:
|
ait_instruction:
|
||||||
begin
|
begin
|
||||||
|
{
|
||||||
|
change
|
||||||
|
<op> reg,x,y
|
||||||
|
cmp reg,#0
|
||||||
|
into
|
||||||
|
<op>s reg,x,y
|
||||||
|
}
|
||||||
|
{ this optimization can applied only to the currently enabled operations because
|
||||||
|
the other operations do not update all flags and FPC does not track flag usage }
|
||||||
|
if (taicpu(p).opcode in [A_ADC,A_ADD,A_SUB {A_UDIV,A_SDIV,A_MUL,A_MVN,A_MOV,A_ORR,A_EOR,A_AND}]) and
|
||||||
|
(taicpu(p).oper[0]^.typ = top_reg) and
|
||||||
|
(taicpu(p).oppostfix = PF_None) and
|
||||||
|
(taicpu(p).condition = C_None) and
|
||||||
|
GetNextInstruction(p, hp1) and
|
||||||
|
(tai(hp1).typ = ait_instruction) and
|
||||||
|
(taicpu(hp1).opcode = A_CMP) and
|
||||||
|
(taicpu(hp1).oppostfix = PF_None) and
|
||||||
|
(taicpu(hp1).condition = C_None) and
|
||||||
|
(taicpu(hp1).oper[0]^.typ = top_reg) and
|
||||||
|
(taicpu(hp1).oper[1]^.typ = top_const) and
|
||||||
|
(taicpu(p).oper[0]^.reg = taicpu(hp1).oper[0]^.reg) and
|
||||||
|
(taicpu(hp1).oper[1]^.val = 0) { and
|
||||||
|
GetNextInstruction(hp1, hp2) and
|
||||||
|
(tai(hp2).typ = ait_instruction) and
|
||||||
|
// be careful here, following instructions could use other flags
|
||||||
|
// however after a jump fpc never depends on the value of flags
|
||||||
|
(taicpu(hp2).opcode = A_B) and
|
||||||
|
(taicpu(hp2).condition in [C_EQ,C_NE,C_MI,C_PL])} then
|
||||||
|
begin
|
||||||
|
taicpu(p).oppostfix:=PF_S;
|
||||||
|
asml.remove(hp1);
|
||||||
|
hp1.free;
|
||||||
|
end
|
||||||
|
else
|
||||||
case taicpu(p).opcode of
|
case taicpu(p).opcode of
|
||||||
|
A_STR:
|
||||||
|
begin
|
||||||
|
{ change
|
||||||
|
str reg1,ref
|
||||||
|
ldr reg2,ref
|
||||||
|
into
|
||||||
|
str reg1,ref
|
||||||
|
mov reg2,reg1
|
||||||
|
}
|
||||||
|
if (taicpu(p).oper[1]^.ref^.addressmode=AM_OFFSET) and
|
||||||
|
getnextinstruction(p,hp1) and
|
||||||
|
(hp1.typ = ait_instruction) and
|
||||||
|
(taicpu(hp1).opcode = A_LDR) and
|
||||||
|
RefsEqual(taicpu(p).oper[1]^.ref^,taicpu(hp1).oper[1]^.ref^) and
|
||||||
|
(taicpu(hp1).oper[1]^.ref^.addressmode=AM_OFFSET) then
|
||||||
|
begin
|
||||||
|
if taicpu(hp1).oper[0]^.reg=taicpu(p).oper[0]^.reg then
|
||||||
|
begin
|
||||||
|
asml.remove(hp1);
|
||||||
|
hp1.free;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
taicpu(hp1).opcode:=A_MOV;
|
||||||
|
taicpu(hp1).oppostfix:=PF_None;
|
||||||
|
taicpu(hp1).loadreg(1,taicpu(p).oper[0]^.reg);
|
||||||
|
end;
|
||||||
|
result := true;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
A_MOV:
|
A_MOV:
|
||||||
begin
|
begin
|
||||||
{ fold
|
{ fold
|
||||||
|
Loading…
Reference in New Issue
Block a user