* dfa fixes by Sergei Gorelkin, resolve #15402

git-svn-id: trunk@14455 -
This commit is contained in:
florian 2009-12-20 21:02:11 +00:00
parent b99a49d982
commit 9955e6b2bf
5 changed files with 122 additions and 28 deletions

2
.gitattributes vendored
View File

@ -8737,6 +8737,8 @@ tests/test/opt/tcmov.pp svneol=native#text/plain
tests/test/opt/tcse1.pp svneol=native#text/plain
tests/test/opt/tcse2.pp svneol=native#text/plain
tests/test/opt/tcse3.pp svneol=native#text/plain
tests/test/opt/tdfa1.pp svneol=native#text/pascal
tests/test/opt/tdfa2.pp svneol=native#text/pascal
tests/test/opt/tgotoreg.pp svneol=native#text/plain
tests/test/opt/treg1.pp svneol=native#text/plain
tests/test/opt/treg2.pp svneol=native#text/plain

View File

@ -241,6 +241,7 @@ unit optdfa;
var
dfainfo : tdfainfo;
l : TDFASet;
save: TDFASet;
i : longint;
begin
@ -265,34 +266,50 @@ unit optdfa;
case node.nodetype of
whilerepeatn:
begin
calclife(node);
{ take care of repeat until! }
if lnf_testatbegin in twhilerepeatnode(node).loopflags then
{ analyze the loop condition }
if not(assigned(node.optinfo^.def)) and
not(assigned(node.optinfo^.use)) then
begin
node.allocoptinfo;
if not(assigned(node.optinfo^.def)) and
not(assigned(node.optinfo^.use)) then
begin
dfainfo.use:=@node.optinfo^.use;
dfainfo.def:=@node.optinfo^.def;
dfainfo.map:=map;
foreachnodestatic(pm_postprocess,twhilerepeatnode(node).left,@AddDefUse,@dfainfo);
end;
calclife(node);
{ now iterate through the loop }
CreateInfo(twhilerepeatnode(node).right);
{ update while node }
{ life:=life+use+right.life }
l:=node.optinfo^.life;
DFASetIncludeSet(l,node.optinfo^.use);
DFASetIncludeSet(l,twhilerepeatnode(node).right.optinfo^.life);
UpdateLifeInfo(node,l);
{ ... and a second iteration for fast convergence }
CreateInfo(twhilerepeatnode(node).right);
dfainfo.use:=@node.optinfo^.use;
dfainfo.def:=@node.optinfo^.def;
dfainfo.map:=map;
foreachnodestatic(pm_postprocess,twhilerepeatnode(node).left,@AddDefUse,@dfainfo);
end;
{ NB: this node should typically have empty def set }
if assigned(node.successor) then
DFASetDiff(l,node.successor.optinfo^.life,node.optinfo^.def)
else if assigned(resultnode) then
DFASetDiff(l,resultnode.optinfo^.life,node.optinfo^.def)
else
l:=nil;
{ for repeat..until, node use set in included at the end of loop }
if not (lnf_testatbegin in twhilerepeatnode(node).loopflags) then
DFASetIncludeSet(l,node.optinfo^.use);
DFASetIncludeSet(l,node.optinfo^.life);
save:=node.optinfo^.life;
{ to process body correctly, we need life info in place (because
whilerepeatnode is successor of its body). }
node.optinfo^.life:=l;
{ now process the body }
CreateInfo(twhilerepeatnode(node).right);
{ restore, to prevent infinite recursion via changed flag }
node.optinfo^.life:=save;
{ for while loops, node use set is included at the beginning of loop }
l:=twhilerepeatnode(node).right.optinfo^.life;
if lnf_testatbegin in twhilerepeatnode(node).loopflags then
DFASetIncludeSet(l,node.optinfo^.use);
UpdateLifeInfo(node,l);
{ ... and a second iteration for fast convergence }
CreateInfo(twhilerepeatnode(node).right);
end;
forn:
@ -326,9 +343,11 @@ unit optdfa;
{ update for node }
{ life:=life+use+body }
l:=node.optinfo^.life;
l:=copy(node.optinfo^.life);
DFASetIncludeSet(l,node.optinfo^.use);
DFASetIncludeSet(l,tfornode(node).t2.optinfo^.life);
{ the for loop always updates its control variable }
DFASetDiff(l,l,node.optinfo^.def);
UpdateLifeInfo(node,l);
{ ... and a second iteration for fast convergence }

View File

@ -792,7 +792,7 @@ implementation
CGMessage(sym_w_function_result_uninitialized)
else
begin
if varsym.owner=procdef.localst then
if (varsym.owner=procdef.localst) and not (vo_is_typed_const in varsym.varoptions) then
CGMessage1(sym_w_uninitialized_local_variable,varsym.realname);
end;
end;

19
tests/test/opt/tdfa1.pp Normal file
View File

@ -0,0 +1,19 @@
{ %OPT=-Oodfa -Sew -vw}
{ %NORUN}
{ %FAIL}
program tdfa1;
procedure p;
var
counter: Integer;
c1: Word;
begin
repeat
c1 := counter; // counter not initialized
counter:=15;
until counter>=10;
end;
begin
end.

54
tests/test/opt/tdfa2.pp Normal file
View File

@ -0,0 +1,54 @@
{ %OPT=-Oodfa -Sew -vw}
unit tdfa;
{$mode objfpc}{$h+}
interface
implementation
procedure test0;
const
c: array[0..3] of integer = (0,1,2,3);
begin
writeln(c[1]);
end;
procedure test1;
var
i: integer;
begin
for i:=0 to 10 do
if i=5 then
;
end;
function test2(S1: PWideChar; Len: Integer): Integer;
var
counter: Integer;
c1: Word;
begin
counter:=0;
repeat
c1 := ord(s1[counter]);
counter:=counter+1;
until counter>=len;
result := c1;
end;
function test3(S1: PWideChar; Len: Integer): Integer;
var
counter: Integer;
c1: Word;
begin
counter:=0;
while counter<len do
begin
c1 := ord(s1[counter]);
counter:=counter+1;
end;
result := c1;
end;
end.