* 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:
Jonas Maebe 2011-08-20 07:48:38 +00:00
parent b023627f6a
commit fda72aaed6

View File

@ -74,7 +74,21 @@ implementation
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
simplestoressp = [a_astore,a_fstore,a_istore];
simplestoresdp = [a_dstore,a_lstore];
@ -88,9 +102,12 @@ implementation
((reg=NR_NO) or
(taicpu(p).oper[0]^.typ=top_reg) and
(taicpu(p).oper[0]^.reg=reg));
if result and
(reg=NR_NO) then
reg:=taicpu(p).oper[0]^.reg;
end;
function issimpleregload(p: tai; reg: tregister; doubleprecisionok: boolean): boolean;
function issimpleregload(p: tai; var reg: tregister; doubleprecisionok: boolean): boolean;
const
simpleloadssp = [a_aload,a_fload,a_iload];
simpleloadsdp = [a_dload,a_lload];
@ -104,56 +121,60 @@ implementation
((reg=NR_NO) or
(taicpu(p).oper[0]^.typ=top_reg) and
(taicpu(p).oper[0]^.reg=reg));
if result and
(reg=NR_NO) then
reg:=taicpu(p).oper[0]^.reg;
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
q: tai;
dealloc,
load: tai;
reg: tregister;
begin
result:=false;
{ check for:
alloc regx
store regx
dealloc regx
load regx
and remove. We don't have to check that the load/store
types match, because they have to for this to be
valid JVM code }
if issimpleregstore(tai(p.next),reg,true) and
assigned(p.next.next) and
(tai(p.next.next).typ=ait_regalloc) and
(tai_regalloc(p.next.next).ratype=ra_dealloc) and
(tai_regalloc(p.next.next).reg=reg) and
issimpleregload(tai(p.next.next.next),reg,true) then
dealloc:=nextskipping(p,[ait_comment]);
load:=nextskipping(dealloc,[ait_comment]);
reg:=NR_NO;
if issimpleregstore(p,reg,true) and
isregallocoftyp(dealloc,ra_dealloc,reg) and
issimpleregload(load,reg,true) then
begin
{ remove the whole sequence: the allocation }
q:=Tai(p.next);
{ remove the whole sequence: the store }
list.remove(p);
p.free;
p:=q;
{ 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;
p:=Tai(load.next);
{ the load }
q:=Tai(p.next);
list.remove(p);
p.free;
p:=q;
list.remove(load);
load.free;
result:=true;
end;
end;
var
p: tai;
p,next: tai;
reg: tregister;
removedsomething: boolean;
begin
@ -165,31 +186,48 @@ implementation
case p.typ of
ait_regalloc:
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
reg:=tai_regalloc(p).reg;
if try_remove_alloc_store_dealloc_load(p,reg) then
begin
removedsomething:=true;
continue;
end;
{ todo in peephole optimizer:
alloc regx // not double precision
store regx // not double precision
load regy or memy
dealloc regx
load regx
-> change into
load regy or memy
swap // can only handle single precision
and then
swap
<commutative op>
-> remove swap
}
list.remove(p);
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
removedsomething:=true;
continue;
end;
{ todo in peephole optimizer:
alloc regx // not double precision
store regx // not double precision
load regy or memy
dealloc regx
load regx
-> change into
load regy or memy
swap // can only handle single precision
and then
swap
<commutative op>
-> remove swap
}
end;
end;
p:=tai(p.next);
end;