mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-17 08:19:22 +02:00
* made the remove_dummy_load_stores() implementation more extensible
and skip comments (so it works again when -ar is used, because tlhcgjvm.inc/decstack() insert comments in that case) git-svn-id: branches/jvmbackend@18340 -
This commit is contained in:
parent
b023627f6a
commit
fda72aaed6
@ -74,7 +74,21 @@ implementation
|
|||||||
|
|
||||||
class procedure trgcpu.remove_dummy_load_stores(list: TAsmList; headertai: tai);
|
class procedure trgcpu.remove_dummy_load_stores(list: TAsmList; headertai: tai);
|
||||||
|
|
||||||
function issimpleregstore(p: tai; reg: tregister; doubleprecisionok: boolean): boolean;
|
type
|
||||||
|
taitypeset = set of taitype;
|
||||||
|
|
||||||
|
function nextskipping(p: tai; const skip: taitypeset): tai;
|
||||||
|
begin
|
||||||
|
result:=p;
|
||||||
|
if not assigned(result) then
|
||||||
|
exit;
|
||||||
|
repeat
|
||||||
|
result:=tai(result.next);
|
||||||
|
until not assigned(result) or
|
||||||
|
not(result.typ in skip);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function issimpleregstore(p: tai; var reg: tregister; doubleprecisionok: boolean): boolean;
|
||||||
const
|
const
|
||||||
simplestoressp = [a_astore,a_fstore,a_istore];
|
simplestoressp = [a_astore,a_fstore,a_istore];
|
||||||
simplestoresdp = [a_dstore,a_lstore];
|
simplestoresdp = [a_dstore,a_lstore];
|
||||||
@ -88,9 +102,12 @@ implementation
|
|||||||
((reg=NR_NO) or
|
((reg=NR_NO) or
|
||||||
(taicpu(p).oper[0]^.typ=top_reg) and
|
(taicpu(p).oper[0]^.typ=top_reg) and
|
||||||
(taicpu(p).oper[0]^.reg=reg));
|
(taicpu(p).oper[0]^.reg=reg));
|
||||||
|
if result and
|
||||||
|
(reg=NR_NO) then
|
||||||
|
reg:=taicpu(p).oper[0]^.reg;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function issimpleregload(p: tai; reg: tregister; doubleprecisionok: boolean): boolean;
|
function issimpleregload(p: tai; var reg: tregister; doubleprecisionok: boolean): boolean;
|
||||||
const
|
const
|
||||||
simpleloadssp = [a_aload,a_fload,a_iload];
|
simpleloadssp = [a_aload,a_fload,a_iload];
|
||||||
simpleloadsdp = [a_dload,a_lload];
|
simpleloadsdp = [a_dload,a_lload];
|
||||||
@ -104,56 +121,60 @@ implementation
|
|||||||
((reg=NR_NO) or
|
((reg=NR_NO) or
|
||||||
(taicpu(p).oper[0]^.typ=top_reg) and
|
(taicpu(p).oper[0]^.typ=top_reg) and
|
||||||
(taicpu(p).oper[0]^.reg=reg));
|
(taicpu(p).oper[0]^.reg=reg));
|
||||||
|
if result and
|
||||||
|
(reg=NR_NO) then
|
||||||
|
reg:=taicpu(p).oper[0]^.reg;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function isregallocoftyp(p: tai; typ: TRegAllocType;var reg: tregister): boolean;
|
||||||
|
begin
|
||||||
|
result:=
|
||||||
|
assigned(p) and
|
||||||
|
(p.typ=ait_regalloc) and
|
||||||
|
(tai_regalloc(p).ratype=typ);
|
||||||
|
if result then
|
||||||
|
if reg=NR_NO then
|
||||||
|
reg:=tai_regalloc(p).reg
|
||||||
|
else
|
||||||
|
result:=tai_regalloc(p).reg=reg;
|
||||||
|
end;
|
||||||
|
|
||||||
function try_remove_alloc_store_dealloc_load(var p: tai; reg: tregister): boolean;
|
function try_remove_store_dealloc_load(var p: tai): boolean;
|
||||||
var
|
var
|
||||||
q: tai;
|
dealloc,
|
||||||
|
load: tai;
|
||||||
|
reg: tregister;
|
||||||
begin
|
begin
|
||||||
result:=false;
|
result:=false;
|
||||||
{ check for:
|
{ check for:
|
||||||
alloc regx
|
|
||||||
store regx
|
store regx
|
||||||
dealloc regx
|
dealloc regx
|
||||||
load regx
|
load regx
|
||||||
and remove. We don't have to check that the load/store
|
and remove. We don't have to check that the load/store
|
||||||
types match, because they have to for this to be
|
types match, because they have to for this to be
|
||||||
valid JVM code }
|
valid JVM code }
|
||||||
if issimpleregstore(tai(p.next),reg,true) and
|
dealloc:=nextskipping(p,[ait_comment]);
|
||||||
assigned(p.next.next) and
|
load:=nextskipping(dealloc,[ait_comment]);
|
||||||
(tai(p.next.next).typ=ait_regalloc) and
|
reg:=NR_NO;
|
||||||
(tai_regalloc(p.next.next).ratype=ra_dealloc) and
|
if issimpleregstore(p,reg,true) and
|
||||||
(tai_regalloc(p.next.next).reg=reg) and
|
isregallocoftyp(dealloc,ra_dealloc,reg) and
|
||||||
issimpleregload(tai(p.next.next.next),reg,true) then
|
issimpleregload(load,reg,true) then
|
||||||
begin
|
begin
|
||||||
{ remove the whole sequence: the allocation }
|
{ remove the whole sequence: the store }
|
||||||
q:=Tai(p.next);
|
|
||||||
list.remove(p);
|
list.remove(p);
|
||||||
p.free;
|
p.free;
|
||||||
p:=q;
|
p:=Tai(load.next);
|
||||||
{ the store }
|
|
||||||
q:=Tai(p.next);
|
|
||||||
list.remove(p);
|
|
||||||
p.free;
|
|
||||||
p:=q;
|
|
||||||
{ the dealloc }
|
|
||||||
q:=Tai(p.next);
|
|
||||||
list.remove(p);
|
|
||||||
p.free;
|
|
||||||
p:=q;
|
|
||||||
{ the load }
|
{ the load }
|
||||||
q:=Tai(p.next);
|
list.remove(load);
|
||||||
list.remove(p);
|
load.free;
|
||||||
p.free;
|
|
||||||
p:=q;
|
|
||||||
result:=true;
|
result:=true;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
var
|
var
|
||||||
p: tai;
|
p,next: tai;
|
||||||
reg: tregister;
|
reg: tregister;
|
||||||
removedsomething: boolean;
|
removedsomething: boolean;
|
||||||
begin
|
begin
|
||||||
@ -165,10 +186,28 @@ implementation
|
|||||||
case p.typ of
|
case p.typ of
|
||||||
ait_regalloc:
|
ait_regalloc:
|
||||||
begin
|
begin
|
||||||
if (tai_regalloc(p).ratype=ra_alloc) then
|
reg:=NR_NO;
|
||||||
|
next:=nextskipping(p,[ait_comment]);
|
||||||
|
{ remove
|
||||||
|
alloc reg
|
||||||
|
dealloc reg
|
||||||
|
(can appear after optimisations, necessary to prevent
|
||||||
|
useless stack slot allocations) }
|
||||||
|
if isregallocoftyp(p,ra_alloc,reg) and
|
||||||
|
isregallocoftyp(next,ra_dealloc,reg) then
|
||||||
begin
|
begin
|
||||||
reg:=tai_regalloc(p).reg;
|
list.remove(p);
|
||||||
if try_remove_alloc_store_dealloc_load(p,reg) then
|
p.free;
|
||||||
|
p:=tai(next.next);
|
||||||
|
list.remove(next);
|
||||||
|
next.free;
|
||||||
|
removedsomething:=true;
|
||||||
|
continue;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
ait_instruction:
|
||||||
|
begin
|
||||||
|
if try_remove_store_dealloc_load(p) then
|
||||||
begin
|
begin
|
||||||
removedsomething:=true;
|
removedsomething:=true;
|
||||||
continue;
|
continue;
|
||||||
@ -190,7 +229,6 @@ implementation
|
|||||||
}
|
}
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
|
||||||
p:=tai(p.next);
|
p:=tai(p.next);
|
||||||
end;
|
end;
|
||||||
until not removedsomething;
|
until not removedsomething;
|
||||||
|
Loading…
Reference in New Issue
Block a user