mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-21 12:29: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;
|
||||
|
||||
|
||||
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);
|
||||
var
|
||||
Continuestack : TFPList;
|
||||
Breakstack : TFPList;
|
||||
BreakContinueStack : TBreakContinueStack;
|
||||
Exitsuccessor: TNode;
|
||||
{ sets the successor nodes of a node tree block
|
||||
returns the first node of the tree if it's a controll flow node }
|
||||
@ -216,8 +274,7 @@ unit optutils;
|
||||
end;
|
||||
forn:
|
||||
begin
|
||||
Breakstack.Add(succ);
|
||||
Continuestack.Add(p);
|
||||
BreakContinueStack.Push(succ,p);
|
||||
result:=p;
|
||||
{ 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 }
|
||||
@ -225,23 +282,21 @@ unit optutils;
|
||||
|
||||
DoSet(tfornode(p).t2,tfornode(p).loopiteration);
|
||||
p.successor:=succ;
|
||||
Breakstack.Delete(Breakstack.Count-1);
|
||||
Continuestack.Delete(Continuestack.Count-1);
|
||||
BreakContinueStack.Pop;
|
||||
end;
|
||||
breakn:
|
||||
begin
|
||||
result:=p;
|
||||
p.successor:=tnode(Breakstack.Last);
|
||||
p.successor:=BreakContinueStack.top^.brk;
|
||||
end;
|
||||
continuen:
|
||||
begin
|
||||
result:=p;
|
||||
p.successor:=tnode(Continuestack.Last);
|
||||
p.successor:=BreakContinueStack.top^.cont;
|
||||
end;
|
||||
whilerepeatn:
|
||||
begin
|
||||
Breakstack.Add(succ);
|
||||
Continuestack.Add(p);
|
||||
BreakContinueStack.Push(succ,p);
|
||||
result:=p;
|
||||
{ the successor of the last node of the while/repeat body is the while node itself }
|
||||
DoSet(twhilerepeatnode(p).right,p);
|
||||
@ -257,8 +312,7 @@ unit optutils;
|
||||
p.successor:=nil;
|
||||
end;
|
||||
|
||||
Breakstack.Delete(Breakstack.Count-1);
|
||||
Continuestack.Delete(Continuestack.Count-1);
|
||||
BreakContinueStack.Pop;
|
||||
end;
|
||||
ifn:
|
||||
begin
|
||||
@ -342,12 +396,10 @@ unit optutils;
|
||||
end;
|
||||
|
||||
begin
|
||||
Breakstack:=TFPList.Create;
|
||||
Continuestack:=TFPList.Create;
|
||||
BreakContinueStack.Init;
|
||||
Exitsuccessor:=nil;
|
||||
DoSet(p,last);
|
||||
Continuestack.Free;
|
||||
Breakstack.Free;
|
||||
BreakContinueStack.Done;
|
||||
end;
|
||||
|
||||
var
|
||||
|
Loading…
Reference in New Issue
Block a user