mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-12 16:09:25 +02:00
* (modified) patch by Rika: optutils.SetNodeSucessors improvement, resolves #39509
This commit is contained in:
parent
50a37d00e7
commit
2b7c28e41a
@ -159,10 +159,68 @@ unit optutils;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
type
|
||||||
|
PBreakContinueStackNode = ^TBreakContinueStackNode;
|
||||||
|
TBreakContinueStackNode = record
|
||||||
|
{ successor node for a break statement in the current loop }
|
||||||
|
brk,
|
||||||
|
{ successor node for a continue statement in the current loop }
|
||||||
|
cont : tnode;
|
||||||
|
next : PBreakContinueStackNode;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ implements a stack to track successor nodes for break and continue
|
||||||
|
statements }
|
||||||
|
TBreakContinueStack = object
|
||||||
|
top: PBreakContinueStackNode;
|
||||||
|
procedure Init; {$ifdef USEINLINE} inline; {$endif}
|
||||||
|
procedure Done; {$ifdef USEINLINE} inline; {$endif}
|
||||||
|
procedure Push(brk,cont : tnode);
|
||||||
|
procedure Pop;
|
||||||
|
end;
|
||||||
|
|
||||||
|
const
|
||||||
|
NullBreakContinueStackNode : TBreakContinueStackNode = (brk: nil; cont: nil; next: nil);
|
||||||
|
|
||||||
|
|
||||||
|
procedure TBreakContinueStack.Init;
|
||||||
|
begin
|
||||||
|
top:=@NullBreakContinueStackNode;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TBreakContinueStack.Done;
|
||||||
|
begin
|
||||||
|
while top<>@NullBreakContinueStackNode do
|
||||||
|
Pop;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TBreakContinueStack.Push(brk,cont : tnode);
|
||||||
|
var
|
||||||
|
n : PBreakContinueStackNode;
|
||||||
|
begin
|
||||||
|
new(n);
|
||||||
|
n^.brk:=brk;
|
||||||
|
n^.cont:=cont;
|
||||||
|
n^.next:=top;
|
||||||
|
top:=n;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TBreakContinueStack.Pop;
|
||||||
|
var
|
||||||
|
n : PBreakContinueStackNode;
|
||||||
|
begin
|
||||||
|
n:=top;
|
||||||
|
top:=n^.next;
|
||||||
|
Dispose(n);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure SetNodeSucessors(p,last : tnode);
|
procedure SetNodeSucessors(p,last : tnode);
|
||||||
var
|
var
|
||||||
Continuestack : TFPList;
|
BreakContinueStack : TBreakContinueStack;
|
||||||
Breakstack : TFPList;
|
|
||||||
Exitsuccessor: TNode;
|
Exitsuccessor: TNode;
|
||||||
{ sets the successor nodes of a node tree block
|
{ sets the successor nodes of a node tree block
|
||||||
returns the first node of the tree if it's a controll flow node }
|
returns the first node of the tree if it's a controll flow node }
|
||||||
@ -216,8 +274,7 @@ unit optutils;
|
|||||||
end;
|
end;
|
||||||
forn:
|
forn:
|
||||||
begin
|
begin
|
||||||
Breakstack.Add(succ);
|
BreakContinueStack.Push(succ,p);
|
||||||
Continuestack.Add(p);
|
|
||||||
result:=p;
|
result:=p;
|
||||||
{ the successor of the last node of the for body is the dummy loop iteration node
|
{ the successor of the last node of the for body is the dummy loop iteration node
|
||||||
it allows the dfa to inject needed life information into the loop }
|
it allows the dfa to inject needed life information into the loop }
|
||||||
@ -225,23 +282,21 @@ unit optutils;
|
|||||||
|
|
||||||
DoSet(tfornode(p).t2,tfornode(p).loopiteration);
|
DoSet(tfornode(p).t2,tfornode(p).loopiteration);
|
||||||
p.successor:=succ;
|
p.successor:=succ;
|
||||||
Breakstack.Delete(Breakstack.Count-1);
|
BreakContinueStack.Pop;
|
||||||
Continuestack.Delete(Continuestack.Count-1);
|
|
||||||
end;
|
end;
|
||||||
breakn:
|
breakn:
|
||||||
begin
|
begin
|
||||||
result:=p;
|
result:=p;
|
||||||
p.successor:=tnode(Breakstack.Last);
|
p.successor:=BreakContinueStack.top^.brk;
|
||||||
end;
|
end;
|
||||||
continuen:
|
continuen:
|
||||||
begin
|
begin
|
||||||
result:=p;
|
result:=p;
|
||||||
p.successor:=tnode(Continuestack.Last);
|
p.successor:=BreakContinueStack.top^.cont;
|
||||||
end;
|
end;
|
||||||
whilerepeatn:
|
whilerepeatn:
|
||||||
begin
|
begin
|
||||||
Breakstack.Add(succ);
|
BreakContinueStack.Push(succ,p);
|
||||||
Continuestack.Add(p);
|
|
||||||
result:=p;
|
result:=p;
|
||||||
{ the successor of the last node of the while/repeat body is the while node itself }
|
{ the successor of the last node of the while/repeat body is the while node itself }
|
||||||
DoSet(twhilerepeatnode(p).right,p);
|
DoSet(twhilerepeatnode(p).right,p);
|
||||||
@ -257,8 +312,7 @@ unit optutils;
|
|||||||
p.successor:=nil;
|
p.successor:=nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Breakstack.Delete(Breakstack.Count-1);
|
BreakContinueStack.Pop;
|
||||||
Continuestack.Delete(Continuestack.Count-1);
|
|
||||||
end;
|
end;
|
||||||
ifn:
|
ifn:
|
||||||
begin
|
begin
|
||||||
@ -342,12 +396,10 @@ unit optutils;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Breakstack:=TFPList.Create;
|
BreakContinueStack.Init;
|
||||||
Continuestack:=TFPList.Create;
|
|
||||||
Exitsuccessor:=nil;
|
Exitsuccessor:=nil;
|
||||||
DoSet(p,last);
|
DoSet(p,last);
|
||||||
Continuestack.Free;
|
BreakContinueStack.Done;
|
||||||
Breakstack.Free;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
|
Loading…
Reference in New Issue
Block a user