mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-01 20:46:06 +02:00
* fixed some small problems in loop unrolling
git-svn-id: trunk@447 -
This commit is contained in:
parent
7cd67ea3f0
commit
b7d874635c
@ -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 }
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user