* fixed some small problems in loop unrolling

git-svn-id: trunk@447 -
This commit is contained in:
florian 2005-06-19 21:00:27 +00:00
parent 7cd67ea3f0
commit b7d874635c
4 changed files with 84 additions and 7 deletions

View File

@ -354,8 +354,13 @@ implementation
count_var_is_signed:=is_signed(left.resulttype.def);
{ first set the to value
because the count var can be in the expression !! }
do_loopvar_at_end:=lnf_dont_mind_loopvar_on_exit in loopflags;
because the count var can be in the expression ! }
do_loopvar_at_end:=(lnf_dont_mind_loopvar_on_exit in loopflags)
{ if the loop is unrolled and there is a jump into the loop,
then we can't do the trick with incrementing the loop var only at the
end
}
and not(assigned(entrylabel));
secondpass(t1);
{ calculate pointer value and check if changeable and if so }

View File

@ -1,5 +1,28 @@
{
Common subexpression elimination on base blocks
Copyright (c) 2005 by Florian Klaempfl
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
****************************************************************************
}
unit optcse;
{$i fpcdefs.inc}
interface
procedure docse(rootnode : tnode);

View File

@ -1,3 +1,24 @@
{
Loop unrolling
Copyright (c) 2005 by Florian Klaempfl
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
****************************************************************************
}
unit optunrol;
{$i fpcdefs.inc}
@ -85,15 +106,16 @@ unit optunrol;
{ let's unroll (and rock of course) }
for i:=1 to unrolls do
begin
{ create and insert copy of the statement block }
addstatement(unrollstatement,tfornode(tfornode(node).t2).getcopy);
{ set and insert entry label? }
if (counts mod unrolls<>0) and
((counts mod unrolls)=unrolls-i+1) then
((counts mod unrolls)=unrolls-i) then
begin
tfornode(node).entrylabel:=clabelnode.create(cnothingnode.create);
addstatement(unrollstatement,tfornode(node).entrylabel);
end;
{ create and insert copy of the statement block }
addstatement(unrollstatement,tfornode(tfornode(node).t2).getcopy);
{ for itself increases at the last iteration }
if i<unrolls then
@ -109,7 +131,32 @@ unit optunrol;
end
else
begin
{ for now, we can't handle this }
{ unrolling is a little bit more tricky if we don't know the
loop count at compile time, but the solution is to use a jump table
which is indexed by "loop count mod unrolls" at run time and which
jumps then at the appropriate place inside the loop. Because
a module division is expensive, we can use only unroll counts dividable
by 2 }
case unrolls of
1..2:
;
3:
unrolls:=2;
4..7:
unrolls:=4;
{ unrolls>4 already make no sense imo, but who knows (FK) }
8..15:
unrolls:=8;
16..31:
unrolls:=16;
32..63:
unrolls:=32;
64..$7fff:
unrolls:=64;
else
exit;
end;
{ we don't handle this yet }
exit;
end;
if not(assigned(result)) then

View File

@ -5,11 +5,13 @@ var
begin
s:=0.0;
for i:=1 to 2 do
s:=s+1;
for i:=1 to 10 do
s:=s+1;
for i:=1 to 11 do
s:=s+1;
if s<>21 then
if s<>23 then
halt(1);
writeln('ok');
end.