diff --git a/compiler/aarch64/ncpuadd.pas b/compiler/aarch64/ncpuadd.pas index 534019e909..fc5c140a4f 100644 --- a/compiler/aarch64/ncpuadd.pas +++ b/compiler/aarch64/ncpuadd.pas @@ -415,7 +415,7 @@ interface secondpass(left); { Skip the not node completely } - Include(right.flags, nf_do_not_execute); + Include(right.transientflags, tnf_do_not_execute); secondpass(tnotnode(right).left); { allocate registers } diff --git a/compiler/hlcgobj.pas b/compiler/hlcgobj.pas index d197261da0..beec187ec9 100644 --- a/compiler/hlcgobj.pas +++ b/compiler/hlcgobj.pas @@ -4478,7 +4478,7 @@ implementation var storepos : tfileposinfo; begin - if nf_error in p.flags then + if tnf_error in p.transientflags then exit; storepos:=current_filepos; current_filepos:=p.fileinfo; diff --git a/compiler/nadd.pas b/compiler/nadd.pas index dde30a81ec..2e9fa4a74c 100644 --- a/compiler/nadd.pas +++ b/compiler/nadd.pas @@ -1906,7 +1906,7 @@ implementation else nt:=equaln; result:=caddnode.create(nt,t,cordconstnode.create(0,vl.resultdef,false)); - Include(flags, nf_do_not_execute); + Include(transientflags,tnf_do_not_execute); if t=left then left:=nil else diff --git a/compiler/nbas.pas b/compiler/nbas.pas index 0635e108e3..d4466a976d 100644 --- a/compiler/nbas.pas +++ b/compiler/nbas.pas @@ -471,7 +471,7 @@ implementation function terrornode.pass_typecheck:tnode; begin result:=nil; - include(flags,nf_error); + include(transientflags,tnf_error); codegenerror:=true; resultdef:=generrordef; end; diff --git a/compiler/ncal.pas b/compiler/ncal.pas index 8955729e75..36a9ed98d0 100644 --- a/compiler/ncal.pas +++ b/compiler/ncal.pas @@ -5602,7 +5602,7 @@ implementation typecheckpass(tnode(inlineblock)); doinlinesimplify(tnode(inlineblock)); - node_reset_flags(tnode(inlineblock),[nf_pass1_done]); + node_reset_flags(tnode(inlineblock),[],[tnf_pass1_done]); firstpass(tnode(inlineblock)); result:=inlineblock; diff --git a/compiler/ncgutil.pas b/compiler/ncgutil.pas index b525048499..7bb880c394 100644 --- a/compiler/ncgutil.pas +++ b/compiler/ncgutil.pas @@ -236,7 +236,7 @@ implementation storepos : tfileposinfo; tmpreg : tregister; begin - if nf_error in p.flags then + if tnf_error in p.transientflags then exit; storepos:=current_filepos; current_filepos:=p.fileinfo; diff --git a/compiler/nflw.pas b/compiler/nflw.pas index 8f48dadaab..e0d0a8cb00 100644 --- a/compiler/nflw.pas +++ b/compiler/nflw.pas @@ -1860,7 +1860,7 @@ implementation (cs_opt_loopunroll in current_settings.optimizerswitches) and assigned(t2) and { statements must be error free } - not(nf_error in t2.flags) then + not(tnf_error in t2.transientflags) then begin typecheckpass(t2); res:=t2.simplify(false); @@ -1925,7 +1925,7 @@ implementation begin { get rid of nf_write etc. as the left node is now only read } leftcopy:=left.getcopy; - node_reset_flags(leftcopy,[nf_pass1_done,nf_modify,nf_write]); + node_reset_flags(leftcopy,[nf_modify,nf_write],[tnf_pass1_done]); if fw then addstatement(s, @@ -2079,7 +2079,7 @@ implementation { get rid of nf_write etc. as the left node is now only read } leftcopy:=left.getcopy; - node_reset_flags(leftcopy,[nf_pass1_done,nf_modify,nf_write]); + node_reset_flags(leftcopy,[nf_modify,nf_write],[tnf_pass1_done]); if needsifblock then begin diff --git a/compiler/node.pas b/compiler/node.pas index e5fba9bcad..3fec3b4e6d 100644 --- a/compiler/node.pas +++ b/compiler/node.pas @@ -208,14 +208,10 @@ interface type { all boolean field of ttree are now collected in flags } tnodeflag = ( - { tbinop operands can be swaped } - nf_swapable, { tbinop operands are swaped } nf_swapped, - nf_error, { general } - nf_pass1_done, { Node is written to } nf_write, { Node is modified } @@ -224,7 +220,6 @@ interface nf_address_taken, nf_is_funcret, nf_isproperty, - nf_processing, { Node cannot be assigned to } nf_no_lvalue, { this node is the user code entry, if a node with this flag is removed @@ -255,19 +250,34 @@ interface nf_ignore_for_wpo, { we know that this loadvmtaddrnode cannot be used to construct a class instance } { node is derived from generic parameter } - nf_generic_para, - - { internal flag to indicate that this node has been removed from the tree or must otherwise not be - execute. Running it through firstpass etc. will raise an internal error } - nf_do_not_execute + nf_generic_para ); tnodeflags = set of tnodeflag; + TTransientNodeFlag = ( + { general } + tnf_pass1_done, + tnf_error, + + { tbinop operands can be swaped } + tnf_swapable, + + tnf_processing, + + { internal flag to indicate that this node has been removed from the tree or must otherwise not be + execute. Running it through firstpass etc. will raise an internal error } + tnf_do_not_execute + ); + + TTransientNodeFlags = set of TTransientNodeFlag; + + const { contains the flags which must be equal for the equality } { of nodes } - flagsequal : tnodeflags = [nf_error]; + flagsequal : tnodeflags = []; + transientflagsequal : TTransientNodeFlags = [tnf_error]; type tnodelist = class @@ -296,6 +306,7 @@ interface successor : tnode; { there are some properties about the node stored } flags : tnodeflags; + transientflags : TTransientNodeFlags; resultdef : tdef; resultdefderef : tderef; fileinfo : tfileposinfo; @@ -759,7 +770,7 @@ implementation ppufile.getset(tppuset5(localswitches)); verbosity:=ppufile.getlongint; ppufile.getderef(resultdefderef); - ppufile.getset(tppuset4(flags)); + ppufile.getset(tppuset2(flags)); { updated by firstpass } expectloc:=LOC_INVALID; { updated by secondpass } @@ -774,7 +785,7 @@ implementation ppufile.putset(tppuset5(localswitches)); ppufile.putlongint(verbosity); ppufile.putderef(resultdefderef); - ppufile.putset(tppuset4(flags)); + ppufile.putset(tppuset2(flags)); end; @@ -867,7 +878,7 @@ implementation write(t, i); end; write(t,']'); - if (nf_pass1_done in flags) then + if (tnf_pass1_done in transientflags) then write(t,', cmplx = ',node_complexity(self)); if assigned(optinfo) then write(t,', optinfo = ',HexStr(optinfo)); @@ -895,7 +906,8 @@ implementation instead call XMLPrintNode to write a complete tree } procedure tnode.XMLPrintNodeInfo(var T: Text); var - i: TNodeFlag; + i_nf: TNodeFlag; + i_tnf: TTransientNodeFlag; first: Boolean; begin if Assigned(resultdef) then @@ -904,19 +916,31 @@ implementation Write(T,' pos="',fileinfo.line,',',fileinfo.column); First := True; - for i := Low(TNodeFlag) to High(TNodeFlag) do - if i in flags then - begin - if First then - begin - Write(T, '" flags="', i); - First := False; - end - else - Write(T, ',', i) - end; - write(t,'"'); - if (nf_pass1_done in flags) then + for i_nf in flags do + begin + if First then + begin + Write(T, '" flags="', i_nf); + First := False; + end + else + Write(T, ',', i_nf) + end; + + First := True; + for i_tnf in transientflags do + begin + if First then + begin + Write(T, '" transientflags="', i_tnf); + First := False; + end + else + Write(T, ',', i_tnf) + end; + write(T,'"'); + + if (tnf_pass1_done in transientflags) then write(t,' complexity="',node_complexity(self),'"'); end; @@ -947,6 +971,7 @@ implementation (p.classtype=classtype) and (p.nodetype=nodetype) and (flags*flagsequal=p.flags*flagsequal) and + (transientflags*transientflagsequal=p.transientflags*transientflagsequal) and docompare(p)); end; @@ -1000,6 +1025,7 @@ implementation p.expectloc:=expectloc; p.location:=location; p.flags:=flags; + p.transientflags:=transientflags; p.resultdef:=resultdef; p.fileinfo:=fileinfo; p.localswitches:=localswitches; @@ -1128,7 +1154,7 @@ implementation begin Result := left; left := nil; - Include(flags, nf_do_not_execute); + Include(transientflags, tnf_do_not_execute); end; @@ -1282,7 +1308,7 @@ implementation begin Result := right; right := nil; - Include(flags, nf_do_not_execute); + Include(transientflags, tnf_do_not_execute); end; @@ -1397,7 +1423,7 @@ implementation begin Result := third; third := nil; - Include(flags, nf_do_not_execute); + Include(transientflags, tnf_do_not_execute); end; @@ -1415,7 +1441,7 @@ implementation begin docompare:=(inherited docompare(p)) or { if that's in the flags, is p then always a tbinopnode (?) (JM) } - ((nf_swapable in flags) and + ((tnf_swapable in transientflags) and left.isequal(tbinopnode(p).right) and right.isequal(tbinopnode(p).left)); end; diff --git a/compiler/nutils.pas b/compiler/nutils.pas index 93220fc1f0..6145585a62 100644 --- a/compiler/nutils.pas +++ b/compiler/nutils.pas @@ -162,7 +162,7 @@ interface function get_open_const_array(p : tnode) : tnode; { excludes the flags passed in nf from the node tree passed } - procedure node_reset_flags(p : tnode;nf : tnodeflags); + procedure node_reset_flags(p : tnode;nf : TNodeFlags; tnf : TTransientNodeFlags); { include or exclude cs from p.localswitches } procedure node_change_local_switch(p : tnode;cs : tlocalswitch;enable : boolean); @@ -1565,17 +1565,28 @@ implementation result:=get_open_const_array(taddrnode(tderefnode(result).left).left); end; + type + TFlagSet = record + nf : TNodeFlags; + tnf : TTransientNodeFlags; + end; + function do_node_reset_flags(var n: tnode; arg: pointer): foreachnoderesult; begin result:=fen_false; - n.flags:=n.flags-tnodeflags(arg^); + n.flags:=n.flags-TFlagSet(arg^).nf; + n.transientflags:=n.transientflags-TFlagSet(arg^).tnf; end; - procedure node_reset_flags(p : tnode; nf : tnodeflags); + procedure node_reset_flags(p : tnode; nf : TNodeFlags; tnf : TTransientNodeFlags); + var + FlagSet: TFlagSet; begin - foreachnodestatic(p,@do_node_reset_flags,@nf); + FlagSet.nf:=nf; + FlagSet.tnf:=tnf; + foreachnodestatic(p,@do_node_reset_flags,@FlagSet); end; type @@ -1709,7 +1720,8 @@ implementation function _node_reset_pass1_write(var n: tnode; arg: pointer): foreachnoderesult; begin Result := fen_false; - n.flags := n.flags - [nf_pass1_done,nf_write,nf_modify]; + n.flags := n.flags - [nf_write,nf_modify]; + n.transientflags := n.transientflags - [tnf_pass1_done]; if n.nodetype = assignn then begin { Force re-evaluation of assignments so nf_modify and nf_write diff --git a/compiler/optconstprop.pas b/compiler/optconstprop.pas index c6f8cdadd5..1f9d1b0d1a 100644 --- a/compiler/optconstprop.pas +++ b/compiler/optconstprop.pas @@ -288,7 +288,7 @@ unit optconstprop; if n.nodetype<>callparan then begin if tree_modified then - exclude(n.flags,nf_pass1_done); + exclude(n.transientflags,tnf_pass1_done); do_firstpass(n); end; diff --git a/compiler/optcse.pas b/compiler/optcse.pas index d8a5e1736b..3dafa745df 100644 --- a/compiler/optcse.pas +++ b/compiler/optcse.pas @@ -398,7 +398,7 @@ unit optcse; { the transformed tree could result in new possibilities to fold constants so force a firstpass on the root node } - exclude(tbinarynode(n).right.flags,nf_pass1_done); + exclude(tbinarynode(n).right.transientflags,tnf_pass1_done); do_firstpass(tbinarynode(n).right); end else diff --git a/compiler/optdfa.pas b/compiler/optdfa.pas index 7f19d030fa..cdfdf9e64b 100644 --- a/compiler/optdfa.pas +++ b/compiler/optdfa.pas @@ -148,7 +148,7 @@ unit optdfa; function ResetProcessing(var n: tnode; arg: pointer): foreachnoderesult; begin - exclude(n.flags,nf_processing); + exclude(n.transientflags,tnf_processing); { dfa works only on normalized trees, so do not recurse into expressions, because ResetProcessing eats a signififcant amount of time of CheckAndWarn @@ -237,9 +237,9 @@ unit optdfa; { ensure we've already optinfo set } node.allocoptinfo; - if nf_processing in node.flags then + if tnf_processing in node.transientflags then exit; - include(node.flags,nf_processing); + include(node.transientflags,tnf_processing); if assigned(node.successor) then CreateInfo(node.successor); @@ -609,7 +609,7 @@ unit optdfa; CreateInfo(node); foreachnodestatic(pm_postprocess,node,@ResetProcessing,nil); { the result node is not reached by foreachnodestatic } - exclude(resultnode.flags,nf_processing); + exclude(resultnode.transientflags,tnf_processing); {$ifdef DEBUG_DFA} PrintIndexedNodeSet(output,map); PrintDFAInfo(output,node); @@ -895,9 +895,9 @@ unit optdfa; if node=nil then exit; - if nf_processing in node.flags then + if tnf_processing in node.transientflags then exit; - include(node.flags,nf_processing); + include(node.transientflags,tnf_processing); if not(assigned(node.optinfo)) or not(DFASetIn(node.optinfo^.life,nodetosearch.optinfo^.index)) then exit; diff --git a/compiler/optloop.pas b/compiler/optloop.pas index 1dab34d8e2..123dfbf3a8 100644 --- a/compiler/optloop.pas +++ b/compiler/optloop.pas @@ -675,7 +675,7 @@ unit optloop; cordconstnode.create(1,tfornode(n).left.resultdef,false)); tfornode(n).t1:=cordconstnode.create(1,tfornode(n).left.resultdef,false); include(tfornode(n).loopflags,lnf_counter_not_used); - exclude(n.flags,nf_pass1_done); + exclude(n.transientflags,tnf_pass1_done); do_firstpass(n); {$ifdef DEBUG_OPTFORLOOP} writeln('Loop reverted: '); diff --git a/compiler/pass_1.pas b/compiler/pass_1.pas index fee62800fd..510466a688 100644 --- a/compiler/pass_1.pas +++ b/compiler/pass_1.pas @@ -87,7 +87,7 @@ implementation assigned(hp.resultdef); if codegenerror then begin - include(p.flags,nf_error); + include(p.transientflags,tnf_error); { default to errortype if no type is set yet } if p.resultdef=nil then p.resultdef:=generrordef; @@ -117,7 +117,7 @@ implementation else begin { update the codegenerror boolean with the previous result of this node } - if (nf_error in p.flags) then + if (tnf_error in p.transientflags) then codegenerror:=true; end; end; @@ -156,10 +156,10 @@ implementation hp : tnode; nodechanged : boolean; begin - if (nf_pass1_done in p.flags) then + if (tnf_pass1_done in p.transientflags) then exit; - if not(nf_error in p.flags) then + if not(tnf_error in p.transientflags) then begin oldcodegenerror:=codegenerror; oldpos:=current_filepos; @@ -168,8 +168,8 @@ implementation codegenerror:=false; repeat { The error flag takes precedence over the 'do not execute' flag, - as its assumed the node tree isn't tenable beyond this point } - if (nf_do_not_execute in p.flags) then + as it's assumed the node tree isn't tenable beyond this point } + if (tnf_do_not_execute in p.transientflags) then InternalError(2022112401); { checks make always a call } @@ -182,7 +182,7 @@ implementation end; hp:=nil; - if not(nf_error in p.flags) then + if not(tnf_error in p.transientflags) then begin current_filepos:=p.fileinfo; current_settings.localswitches:=p.localswitches; @@ -201,11 +201,11 @@ implementation p:=hp; end; if codegenerror then - include(p.flags,nf_error); + include(p.transientflags,tnf_error); end; until not assigned(hp) or - (nf_pass1_done in hp.flags); - include(p.flags,nf_pass1_done); + (tnf_pass1_done in hp.transientflags); + include(p.transientflags,tnf_pass1_done); {$ifdef EXTDEBUG} if not(nf_error in p.flags) then begin diff --git a/compiler/pass_2.pas b/compiler/pass_2.pas index 565d373913..fa90b90b69 100644 --- a/compiler/pass_2.pas +++ b/compiler/pass_2.pas @@ -187,11 +187,11 @@ implementation begin if not assigned(p) then internalerror(200208221); - if not(nf_error in p.flags) then + if not(tnf_error in p.transientflags) then begin { The error flag takes precedence over the 'do not execute' flag, - as its assumed the node tree isn't tenable beyond this point } - if (nf_do_not_execute in p.flags) then + as it's assumed the node tree isn't tenable beyond this point } + if (tnf_do_not_execute in p.transientflags) then InternalError(2022112402); oldcodegenerror:=codegenerror; @@ -237,7 +237,7 @@ implementation end; {$endif EXTDEBUG} if codegenerror then - include(p.flags,nf_error); + include(p.transientflags,tnf_error); codegenerror:=codegenerror or oldcodegenerror; current_settings.localswitches:=oldlocalswitches; current_filepos:=oldpos; @@ -256,7 +256,7 @@ implementation { clear errors before starting } codegenerror:=false; - if not(nf_error in p.flags) then + if not(tnf_error in p.transientflags) then secondpass(p); do_secondpass:=codegenerror; end; diff --git a/compiler/ppu.pas b/compiler/ppu.pas index 577b6dc2f8..d9ccb50558 100644 --- a/compiler/ppu.pas +++ b/compiler/ppu.pas @@ -48,7 +48,7 @@ const CurrentPPUVersion = 208; { for any other changes to the ppu format, increase this version number (it's a cardinal) } - CurrentPPULongVersion = 23; + CurrentPPULongVersion = 24; { unit flags } uf_big_endian = $000004; diff --git a/compiler/x86/nx86add.pas b/compiler/x86/nx86add.pas index 330334d5a1..bc52ba838d 100644 --- a/compiler/x86/nx86add.pas +++ b/compiler/x86/nx86add.pas @@ -1976,7 +1976,7 @@ unit nx86add; secondpass(left); { Skip the not node completely } - Include(right.flags, nf_do_not_execute); + Include(right.transientflags, tnf_do_not_execute); secondpass(tnotnode(right).left); { allocate registers } @@ -2051,8 +2051,8 @@ unit nx86add; secondpass(left); { Skip the subtract and shift nodes completely } - Include(right.flags, nf_do_not_execute); - Include(taddnode(right).left.flags, nf_do_not_execute); + Include(right.transientflags, tnf_do_not_execute); + Include(taddnode(right).left.transientflags, tnf_do_not_execute); { Helps avoid all the awkward typecasts } indexnode := tshlshrnode(taddnode(right).left).right; @@ -2063,7 +2063,7 @@ unit nx86add; begin { Convert to the 32-bit type } indexnode.resultdef := resultdef; - node_reset_flags(indexnode,[nf_pass1_done]); + node_reset_flags(indexnode,[],[tnf_pass1_done]); { We should't be getting any new errors } if do_firstpass(indexnode) then diff --git a/compiler/x86/nx86inl.pas b/compiler/x86/nx86inl.pas index beca515596..b0b31d8033 100644 --- a/compiler/x86/nx86inl.pas +++ b/compiler/x86/nx86inl.pas @@ -658,15 +658,15 @@ implementation (def_cgsize(TTypeConvNode(indexnode).resultdef) in [OS_64, OS_S64]) then begin { Convert to the 32-bit type } - indexnode.resultdef := loadnode.resultdef; - node_reset_flags(indexnode,[nf_pass1_done]); + indexnode.resultdef:=loadnode.resultdef; + node_reset_flags(indexnode,[],[tnf_pass1_done]); { We should't be getting any new errors } if do_firstpass(indexnode) then InternalError(2022110202); { Keep things internally consistent in case indexnode changed } - tshlshrnode(taddnode(valuenode).left).right := indexnode; + tshlshrnode(taddnode(valuenode).left).right:=indexnode; end; {$endif x86_64} secondpass(indexnode);