mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-12 22:10:38 +02:00

------------------------------------------------------------------------ r39725 | pierre | 2018-09-10 13:28:33 +0000 (Mon, 10 Sep 2018) | 1 line Add branches for 3.2.0, 3.2.1 and 3.3.1 versions ------------------------------------------------------------------------ --- Merging r39725 into '.': U tests/utils/testsuite/utests.pp --- Recording mergeinfo for merge of r39725 into '.': U . ------------------------------------------------------------------------ r39733 | pierre | 2018-09-11 08:16:56 +0000 (Tue, 11 Sep 2018) | 1 line sparc64-linux objects recompiled with GCC 7.3.0 ------------------------------------------------------------------------ --- Merging r39733 into '.': U tests/test/cg/obj/readme.txt U tests/test/cg/obj/linux/sparc64/ctest.o U tests/test/cg/obj/linux/sparc64/cpptcl1.o U tests/test/cg/obj/linux/sparc64/cpptcl2.o U tests/test/cg/obj/linux/sparc64/tcext3.o U tests/test/cg/obj/linux/sparc64/tcext4.o U tests/test/cg/obj/linux/sparc64/tcext5.o U tests/test/cg/obj/linux/sparc64/tcext6.o --- Recording mergeinfo for merge of r39733 into '.': G . ------------------------------------------------------------------------ r39808 | pierre | 2018-09-26 09:29:33 +0000 (Wed, 26 Sep 2018) | 1 line Disable libraries not compiling for jvm-java or jvm-android targets ------------------------------------------------------------------------ --- Merging r39808 into '.': U packages/fppkg/fpmake.pp U packages/fcl-base/fpmake.pp U packages/rtl-extra/fpmake.pp U packages/hermes/fpmake.pp U packages/fcl-extra/fpmake.pp U packages/fcl-db/fpmake.pp U packages/unzip/fpmake.pp U packages/odbc/fpmake.pp U packages/gdbm/fpmake.pp U packages/pthreads/fpmake.pp U packages/fcl-json/fpmake.pp U packages/pcap/fpmake.pp U packages/numlib/fpmake.pp U packages/rtl-generics/fpmake.pp U packages/zlib/fpmake.pp U packages/paszlib/fpmake.pp U packages/webidl/fpmake.pp U packages/regexpr/fpmake.pp U packages/libgd/fpmake.pp U packages/fcl-net/fpmake.pp U packages/fcl-res/fpmake.pp U packages/libpng/fpmake.pp U packages/dblib/fpmake.pp U packages/tcl/fpmake.pp U packages/openssl/fpmake.pp U packages/ibase/fpmake.pp U packages/bzip2/fpmake.pp U packages/fcl-sdo/fpmake.pp U packages/fcl-sound/fpmake.pp U packages/fcl-passrc/fpmake.pp U packages/fcl-stl/fpmake.pp U packages/libmicrohttpd/fpmake.pp U packages/mysql/fpmake.pp U packages/postgres/fpmake.pp U packages/httpd22/fpmake.pp U packages/httpd24/fpmake.pp U packages/rtl-console/fpmake.pp U packages/sqlite/fpmake.pp U packages/fftw/fpmake.pp U packages/fcl-pdf/fpmake.pp U packages/rtl-objpas/fpmake.pp U packages/fcl-image/fpmake.pp U packages/pasjpeg/fpmake.pp U packages/chm/fpmake.pp U packages/fcl-registry/fpmake.pp U packages/libtar/fpmake.pp U packages/symbolic/fpmake.pp U packages/libenet/fpmake.pp U packages/imagemagick/fpmake.pp U packages/fcl-xml/fpmake.pp U packages/oracle/fpmake.pp U packages/fcl-fpcunit/fpmake.pp U packages/fcl-js/fpmake.pp U packages/fcl-async/fpmake.pp U packages/fcl-process/fpmake.pp U packages/pastojs/fpmake.pp U packages/hash/fpmake.pp U packages/rtl-unicode/fpmake.pp U packages/fpmkunit/fpmake.pp --- Recording mergeinfo for merge of r39808 into '.': G . ------------------------------------------------------------------------ r40027 | pierre | 2018-10-24 21:37:54 +0000 (Wed, 24 Oct 2018) | 1 line Fix compilation of RTL for watcom target ------------------------------------------------------------------------ --- Merging r40027 into '.': U compiler/x86/agx86int.pas --- Recording mergeinfo for merge of r40027 into '.': G . ------------------------------------------------------------------------ r40028 | pierre | 2018-10-25 06:39:42 +0000 (Thu, 25 Oct 2018) | 1 line Try to fix compilation error after commit #40027 ------------------------------------------------------------------------ --- Merging r40028 into '.': G compiler/x86/agx86int.pas --- Recording mergeinfo for merge of r40028 into '.': G . ------------------------------------------------------------------------ r40102 | pierre | 2018-10-31 09:07:57 +0000 (Wed, 31 Oct 2018) | 1 line Replace aint (which is a compiler specific type) by ptruint type, which is defined in system unit ------------------------------------------------------------------------ --- Merging r40102 into '.': U tests/test/tarray5.pp --- Recording mergeinfo for merge of r40102 into '.': G . ------------------------------------------------------------------------ r40103 | pierre | 2018-10-31 09:59:45 +0000 (Wed, 31 Oct 2018) | 1 line Use pdword to avoid range check erro in tentryfile.getdword method ------------------------------------------------------------------------ --- Merging r40103 into '.': U compiler/entfile.pas --- Recording mergeinfo for merge of r40103 into '.': G . ------------------------------------------------------------------------ r40104 | pierre | 2018-10-31 10:21:51 +0000 (Wed, 31 Oct 2018) | 1 line Use longint type instead of AWord for Initial parameter in CalcExecutionWeigths (to avoid range error for avr compiler) ------------------------------------------------------------------------ @@ begin Result:=fen_false; n.allocoptinfo; <<<<<<< MINE (select with 'mc') (367) Weight:=PAWord(arg)^; ||||||| ORIGINAL (367) Weight:=max(PAWord(arg)^,1); ======= Weight:=max(plongint(arg)^,1); >>>>>>> THEIRS (select with 'tc') (367) case n.nodetype of casen: begin --- Merging r40104 into '.': C compiler/optutils.pas --- Recording mergeinfo for merge of r40104 into '.': G . Summary of conflicts: Text conflicts: 1 ------------------------------------------------------------------------ r40110 | pierre | 2018-10-31 14:51:23 +0000 (Wed, 31 Oct 2018) | 1 line Avoid range check error in MaskLength evaluation ------------------------------------------------------------------------ --- Merging r40110 into '.': U compiler/x86/aoptx86.pas --- Recording mergeinfo for merge of r40110 into '.': G . ------------------------------------------------------------------------ r40111 | pierre | 2018-10-31 15:47:53 +0000 (Wed, 31 Oct 2018) | 1 line Complement commit 40104, by changing type of executionweight in toptinfo record and adapt pass_2 code ------------------------------------------------------------------------ --- Merging r40111 into '.': U compiler/pass_2.pas U compiler/optbase.pas --- Recording mergeinfo for merge of r40111 into '.': G . ------------------------------------------------------------------------ r40112 | pierre | 2018-10-31 15:48:32 +0000 (Wed, 31 Oct 2018) | 1 line Disable range check completely in arm/cgcpu unit ------------------------------------------------------------------------ --- Merging r40112 into '.': U compiler/arm/cgcpu.pas --- Recording mergeinfo for merge of r40112 into '.': G . ------------------------------------------------------------------------ r40113 | pierre | 2018-10-31 15:49:14 +0000 (Wed, 31 Oct 2018) | 1 line Avoid overflow in code ------------------------------------------------------------------------ --- Merging r40113 into '.': U compiler/symdef.pas --- Recording mergeinfo for merge of r40113 into '.': G . ------------------------------------------------------------------------ r40114 | pierre | 2018-10-31 15:50:26 +0000 (Wed, 31 Oct 2018) | 1 line Add explicit rtlclean/rtl targets in fullcycle rule if DOWPOCYCLE is set ------------------------------------------------------------------------ --- Merging r40114 into '.': U compiler/Makefile.fpc U compiler/Makefile --- Recording mergeinfo for merge of r40114 into '.': G . ------------------------------------------------------------------------ r40120 | pierre | 2018-10-31 23:15:22 +0000 (Wed, 31 Oct 2018) | 1 line Change RemoveCurrentP parameter type to tai, because GetNextInstruction does not always return a taicpu, adapt code in avr/aoptcpu unit ------------------------------------------------------------------------ --- Merging r40120 into '.': U compiler/aoptobj.pas U compiler/avr/aoptcpu.pas --- Recording mergeinfo for merge of r40120 into '.': G . ------------------------------------------------------------------------ r40121 | pierre | 2018-10-31 23:16:51 +0000 (Wed, 31 Oct 2018) | 1 line Add check about tloadnode.symtableentry type before typecast ------------------------------------------------------------------------ --- Merging r40121 into '.': U compiler/ncal.pas --- Recording mergeinfo for merge of r40121 into '.': G . ------------------------------------------------------------------------ r40122 | pierre | 2018-10-31 23:18:09 +0000 (Wed, 31 Oct 2018) | 1 line Fix typecast in FindRegDeAlloc call ------------------------------------------------------------------------ --- Merging r40122 into '.': U compiler/arm/aoptcpu.pas --- Recording mergeinfo for merge of r40122 into '.': G . ------------------------------------------------------------------------ r40123 | pierre | 2018-10-31 23:19:39 +0000 (Wed, 31 Oct 2018) | 1 line Remove unneeded typecasts in TryTOptimizeMove ------------------------------------------------------------------------ --- Merging r40123 into '.': U compiler/m68k/aoptcpu.pas --- Recording mergeinfo for merge of r40123 into '.': G . ------------------------------------------------------------------------ r40124 | pierre | 2018-10-31 23:20:29 +0000 (Wed, 31 Oct 2018) | 1 line Add global range check disable for i8086 cgcpu and x86 nx86add units ------------------------------------------------------------------------ --- Merging r40124 into '.': U compiler/i8086/cgcpu.pas U compiler/x86/nx86add.pas --- Recording mergeinfo for merge of r40124 into '.': G . ------------------------------------------------------------------------ r40131 | pierre | 2018-11-01 07:01:02 +0000 (Thu, 01 Nov 2018) | 1 line Remove another wrong typecast when testing that a tai is an instruction ------------------------------------------------------------------------ --- Merging r40131 into '.': G compiler/m68k/aoptcpu.pas --- Recording mergeinfo for merge of r40131 into '.': G . ------------------------------------------------------------------------ r40236 | pierre | 2018-11-06 07:40:31 +0000 (Tue, 06 Nov 2018) | 1 line Really change extension of hs1 local variable in get_exepath ------------------------------------------------------------------------ --- Merging r40236 into '.': U compiler/globals.pas --- Recording mergeinfo for merge of r40236 into '.': G . ------------------------------------------------------------------------ r40237 | pierre | 2018-11-06 07:41:15 +0000 (Tue, 06 Nov 2018) | 1 line Disable range checking in rax86int unit ------------------------------------------------------------------------ --- Merging r40237 into '.': U compiler/x86/rax86int.pas --- Recording mergeinfo for merge of r40237 into '.': G . ------------------------------------------------------------------------ r40278 | pierre | 2018-11-08 20:19:54 +0000 (Thu, 08 Nov 2018) | 1 line Downgrade EXTDEBUG warning to note about zero size temp, as it is used for empty sets ------------------------------------------------------------------------ --- Merging r40278 into '.': U compiler/tgobj.pas --- Recording mergeinfo for merge of r40278 into '.': G . git-svn-id: branches/fixes_3_2@40624 -
420 lines
13 KiB
ObjectPascal
420 lines
13 KiB
ObjectPascal
{
|
|
Helper routines for the optimizer
|
|
|
|
Copyright (c) 2007 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 optutils;
|
|
|
|
{$i fpcdefs.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
cclasses,
|
|
node,
|
|
globtype;
|
|
|
|
type
|
|
{ this implementation should be really improved,
|
|
its purpose is to find equal nodes }
|
|
TIndexedNodeSet = class(TFPList)
|
|
function Add(node : tnode) : boolean;
|
|
function Includes(node : tnode) : tnode;
|
|
function Remove(node : tnode) : boolean;
|
|
end;
|
|
|
|
procedure SetNodeSucessors(p,last : tnode);
|
|
procedure PrintDFAInfo(var f : text;p : tnode);
|
|
procedure PrintIndexedNodeSet(var f : text;s : TIndexedNodeSet);
|
|
{ determines the optinfo.defsum field for the given node
|
|
this field contains a sum of all expressions defined by
|
|
all child expressions reachable through p
|
|
}
|
|
procedure CalcDefSum(p : tnode);
|
|
|
|
{ calculates/estimates the field execution weight of optinfo }
|
|
procedure CalcExecutionWeights(p : tnode;Initial : longint = 100);
|
|
|
|
{ returns true, if n is a valid node and has life info }
|
|
function has_life_info(n : tnode) : boolean;
|
|
|
|
implementation
|
|
|
|
uses
|
|
cutils,
|
|
verbose,
|
|
optbase,
|
|
ncal,nbas,nflw,nutils,nset,ncon;
|
|
|
|
function TIndexedNodeSet.Add(node : tnode) : boolean;
|
|
var
|
|
i : Integer;
|
|
p : tnode;
|
|
begin
|
|
node.allocoptinfo;
|
|
p:=Includes(node);
|
|
if assigned(p) then
|
|
begin
|
|
result:=false;
|
|
node.optinfo^.index:=p.optinfo^.index;
|
|
end
|
|
else
|
|
begin
|
|
i:=inherited Add(node);
|
|
node.optinfo^.index:=i;
|
|
result:=true;
|
|
end
|
|
end;
|
|
|
|
|
|
function TIndexedNodeSet.Includes(node : tnode) : tnode;
|
|
var
|
|
i : longint;
|
|
begin
|
|
for i:=0 to Count-1 do
|
|
if tnode(List^[i]).isequal(node) then
|
|
begin
|
|
result:=tnode(List^[i]);
|
|
exit;
|
|
end;
|
|
result:=nil;
|
|
end;
|
|
|
|
|
|
function TIndexedNodeSet.Remove(node : tnode) : boolean;
|
|
var
|
|
p : tnode;
|
|
begin
|
|
result:=false;
|
|
p:=Includes(node);
|
|
if assigned(p) then
|
|
begin
|
|
if inherited Remove(p)<>-1 then
|
|
result:=true;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure PrintIndexedNodeSet(var f : text;s : TIndexedNodeSet);
|
|
var
|
|
i : integer;
|
|
begin
|
|
for i:=0 to s.count-1 do
|
|
begin
|
|
writeln(f,'=============================== Node ',i,' ===============================');
|
|
printnode(f,tnode(s[i]));
|
|
writeln(f);
|
|
end;
|
|
end;
|
|
|
|
|
|
function PrintNodeDFA(var n: tnode; arg: pointer): foreachnoderesult;
|
|
begin
|
|
if assigned(n.optinfo) and ((n.optinfo^.life<>nil) or (n.optinfo^.use<>nil) or (n.optinfo^.def<>nil)) then
|
|
begin
|
|
write(text(arg^),nodetype2str[n.nodetype],'(',n.fileinfo.line,',',n.fileinfo.column,') Life: ');
|
|
PrintDFASet(text(arg^),n.optinfo^.life);
|
|
write(text(arg^),' Def: ');
|
|
PrintDFASet(text(arg^),n.optinfo^.def);
|
|
write(text(arg^),' Use: ');
|
|
PrintDFASet(text(arg^),n.optinfo^.use);
|
|
if assigned(n.successor) then
|
|
write(text(arg^),' Successor: ',nodetype2str[n.successor.nodetype],'(',n.successor.fileinfo.line,',',n.successor.fileinfo.column,')')
|
|
else
|
|
write(text(arg^),' Successor: nil');
|
|
write(text(arg^),' DefSum: ');
|
|
PrintDFASet(text(arg^),n.optinfo^.defsum);
|
|
writeln(text(arg^));
|
|
end;
|
|
result:=fen_false;
|
|
end;
|
|
|
|
|
|
procedure PrintDFAInfo(var f : text;p : tnode);
|
|
begin
|
|
foreachnodestatic(pm_postprocess,p,@PrintNodeDFA,@f);
|
|
end;
|
|
|
|
|
|
procedure SetNodeSucessors(p,last : tnode);
|
|
var
|
|
Continuestack : TFPList;
|
|
Breakstack : TFPList;
|
|
{ sets the successor nodes of a node tree block
|
|
returns the first node of the tree if it's a controll flow node }
|
|
function DoSet(p : tnode;succ : tnode) : tnode;
|
|
var
|
|
hp1,hp2 : tnode;
|
|
i : longint;
|
|
begin
|
|
result:=nil;
|
|
if p=nil then
|
|
exit;
|
|
case p.nodetype of
|
|
statementn:
|
|
begin
|
|
hp1:=p;
|
|
result:=p;
|
|
while assigned(hp1) do
|
|
begin
|
|
{ does another statement follow? }
|
|
if assigned(tstatementnode(hp1).next) then
|
|
begin
|
|
hp2:=DoSet(tstatementnode(hp1).statement,tstatementnode(hp1).next);
|
|
if assigned(hp2) then
|
|
tstatementnode(hp1).successor:=hp2
|
|
else
|
|
tstatementnode(hp1).successor:=tstatementnode(hp1).next;
|
|
end
|
|
else
|
|
begin
|
|
hp2:=DoSet(tstatementnode(hp1).statement,succ);
|
|
if assigned(hp2) then
|
|
tstatementnode(hp1).successor:=hp2
|
|
else
|
|
tstatementnode(hp1).successor:=succ;
|
|
end;
|
|
hp1:=tstatementnode(hp1).next;
|
|
end;
|
|
end;
|
|
blockn:
|
|
begin
|
|
result:=p;
|
|
DoSet(tblocknode(p).statements,succ);
|
|
if assigned(tblocknode(p).statements) then
|
|
p.successor:=tblocknode(p).statements
|
|
else
|
|
p.successor:=succ;
|
|
end;
|
|
forn:
|
|
begin
|
|
Breakstack.Add(succ);
|
|
Continuestack.Add(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 }
|
|
tfornode(p).loopiteration:=cnothingnode.create;
|
|
|
|
DoSet(tfornode(p).t2,tfornode(p).loopiteration);
|
|
p.successor:=succ;
|
|
Breakstack.Delete(Breakstack.Count-1);
|
|
Continuestack.Delete(Continuestack.Count-1);
|
|
end;
|
|
breakn:
|
|
begin
|
|
result:=p;
|
|
p.successor:=tnode(Breakstack.Last);
|
|
end;
|
|
continuen:
|
|
begin
|
|
result:=p;
|
|
p.successor:=tnode(Continuestack.Last);
|
|
end;
|
|
whilerepeatn:
|
|
begin
|
|
Breakstack.Add(succ);
|
|
Continuestack.Add(p);
|
|
result:=p;
|
|
{ the successor of the last node of the while/repeat body is the while node itself }
|
|
DoSet(twhilerepeatnode(p).right,p);
|
|
|
|
p.successor:=succ;
|
|
|
|
{ special case: we do not do a dyn. dfa, but we should handle endless loops }
|
|
if is_constboolnode(twhilerepeatnode(p).left) then
|
|
begin
|
|
if ((lnf_testatbegin in twhilerepeatnode(p).loopflags) and
|
|
getbooleanvalue(twhilerepeatnode(p).left)) or (not(lnf_testatbegin in twhilerepeatnode(p).loopflags) and
|
|
not(getbooleanvalue(twhilerepeatnode(p).left))) then
|
|
p.successor:=nil;
|
|
end;
|
|
|
|
Breakstack.Delete(Breakstack.Count-1);
|
|
Continuestack.Delete(Continuestack.Count-1);
|
|
end;
|
|
ifn:
|
|
begin
|
|
result:=p;
|
|
DoSet(tifnode(p).right,succ);
|
|
DoSet(tifnode(p).t1,succ);
|
|
p.successor:=succ;
|
|
end;
|
|
labeln:
|
|
begin
|
|
result:=p;
|
|
if assigned(tlabelnode(p).left) then
|
|
begin
|
|
DoSet(tlabelnode(p).left,succ);
|
|
p.successor:=tlabelnode(p).left;
|
|
end
|
|
else
|
|
p.successor:=succ;
|
|
end;
|
|
assignn:
|
|
begin
|
|
result:=p;
|
|
p.successor:=succ;
|
|
end;
|
|
goton:
|
|
begin
|
|
result:=p;
|
|
if not(assigned(tgotonode(p).labelnode)) then
|
|
internalerror(2007050701);
|
|
p.successor:=tgotonode(p).labelnode;
|
|
end;
|
|
exitn:
|
|
begin
|
|
result:=p;
|
|
p.successor:=nil;
|
|
end;
|
|
casen:
|
|
begin
|
|
result:=p;
|
|
DoSet(tcasenode(p).elseblock,succ);
|
|
for i:=0 to tcasenode(p).blocks.count-1 do
|
|
DoSet(pcaseblock(tcasenode(p).blocks[i])^.statement,succ);
|
|
p.successor:=succ;
|
|
end;
|
|
calln:
|
|
begin
|
|
{ not sure if this is enough (FK) }
|
|
result:=p;
|
|
if not(cnf_call_never_returns in tcallnode(p).callnodeflags) then
|
|
p.successor:=succ;
|
|
end;
|
|
inlinen:
|
|
begin
|
|
{ not sure if this is enough (FK) }
|
|
result:=p;
|
|
p.successor:=succ;
|
|
end;
|
|
loadn,
|
|
tempcreaten,
|
|
tempdeleten,
|
|
nothingn:
|
|
begin
|
|
result:=p;
|
|
p.successor:=succ;
|
|
end;
|
|
raisen:
|
|
begin
|
|
result:=p;
|
|
{ raise never returns }
|
|
p.successor:=nil;
|
|
end;
|
|
withn,
|
|
tryexceptn,
|
|
tryfinallyn,
|
|
onn:
|
|
internalerror(2007050501);
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
Breakstack:=TFPList.Create;
|
|
Continuestack:=TFPList.Create;
|
|
DoSet(p,last);
|
|
Continuestack.Free;
|
|
Breakstack.Free;
|
|
end;
|
|
|
|
var
|
|
sum : TDFASet;
|
|
|
|
function adddef(var n: tnode; arg: pointer): foreachnoderesult;
|
|
begin
|
|
if assigned(n.optinfo) then
|
|
DFASetIncludeSet(sum,n.optinfo^.def);
|
|
Result:=fen_false;
|
|
end;
|
|
|
|
|
|
procedure CalcDefSum(p : tnode);
|
|
begin
|
|
p.allocoptinfo;
|
|
if not assigned(p.optinfo^.defsum) then
|
|
begin
|
|
sum:=nil;
|
|
foreachnodestatic(pm_postprocess,p,@adddef,nil);
|
|
p.optinfo^.defsum:=sum;
|
|
end;
|
|
end;
|
|
|
|
|
|
function SetExecutionWeight(var n: tnode; arg: pointer): foreachnoderesult;
|
|
var
|
|
Weight : longint;
|
|
i : Integer;
|
|
begin
|
|
Result:=fen_false;
|
|
n.allocoptinfo;
|
|
Weight:=max(plongint(arg)^,1);
|
|
case n.nodetype of
|
|
casen:
|
|
begin
|
|
CalcExecutionWeights(tcasenode(n).left,Weight);
|
|
for i:=0 to tcasenode(n).blocks.count-1 do
|
|
CalcExecutionWeights(pcaseblock(tcasenode(n).blocks[i])^.statement,max(1,Weight div case_count_labels(tcasenode(n).labels)));
|
|
|
|
CalcExecutionWeights(tcasenode(n).elseblock,max(1,Weight div case_count_labels(tcasenode(n).labels)));
|
|
Result:=fen_norecurse_false;
|
|
end;
|
|
whilerepeatn:
|
|
begin
|
|
CalcExecutionWeights(twhilerepeatnode(n).right,max(Weight,1)*8);
|
|
CalcExecutionWeights(twhilerepeatnode(n).left,max(Weight,1)*8);
|
|
Result:=fen_norecurse_false;
|
|
end;
|
|
ifn:
|
|
begin
|
|
CalcExecutionWeights(tifnode(n).left,Weight);
|
|
CalcExecutionWeights(tifnode(n).right,max(Weight div 2,1));
|
|
CalcExecutionWeights(tifnode(n).t1,max(Weight div 2,1));
|
|
Result:=fen_norecurse_false;
|
|
end;
|
|
else
|
|
{$push}
|
|
{ The code below emits two warnings if ptruint and aword are the same type }
|
|
{$warn 4044 off}
|
|
{$warn 6018 off}
|
|
if PAWord(arg)^ > high(aword) then
|
|
n.optinfo^.executionweight:=high(AWord)
|
|
else
|
|
n.optinfo^.executionweight:=PAWord(arg)^;
|
|
{$pop}
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure CalcExecutionWeights(p : tnode;Initial : longint = 100);
|
|
begin
|
|
if assigned(p) then
|
|
foreachnodestatic(pm_postprocess,p,@SetExecutionWeight,Pointer(@Initial));
|
|
end;
|
|
|
|
|
|
function has_life_info(n : tnode) : boolean;
|
|
begin
|
|
result:=assigned(n) and assigned(n.optinfo) and
|
|
assigned(n.optinfo^.life);
|
|
end;
|
|
|
|
end.
|
|
|