mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-14 22:59:29 +02:00
* dfa fixes by Sergei Gorelkin, resolve #15402
git-svn-id: trunk@14455 -
This commit is contained in:
parent
b99a49d982
commit
9955e6b2bf
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -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
|
||||
|
@ -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 }
|
||||
|
@ -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
19
tests/test/opt/tdfa1.pp
Normal 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
54
tests/test/opt/tdfa2.pp
Normal 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.
|
Loading…
Reference in New Issue
Block a user