nflw.pas 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. Type checking and register allocation for nodes that influence
  5. the flow
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. ****************************************************************************
  18. }
  19. unit nflw;
  20. {$i fpcdefs.inc}
  21. interface
  22. uses
  23. node,cpubase,
  24. aasmbase,aasmtai,aasmcpu,symnot,
  25. symppu,symtype,symbase,symdef,symsym;
  26. type
  27. { flags used by loop nodes }
  28. tloopflags = (
  29. { set if it is a for ... downto ... do loop }
  30. lnf_backward,
  31. { Do we need to parse childs to set var state? }
  32. lnf_varstate,
  33. { Do a test at the begin of the loop?}
  34. lnf_testatbegin,
  35. { Negate the loop test? }
  36. lnf_checknegate,
  37. { Should the value of the loop variable on exit be correct. }
  38. lnf_dont_mind_loopvar_on_exit);
  39. const
  40. { loop flags which must match to consider loop nodes equal regarding the flags }
  41. loopflagsequal = [lnf_backward];
  42. type
  43. tloopnode = class(tbinarynode)
  44. t1,t2 : tnode;
  45. loopflags : set of tloopflags;
  46. constructor create(tt : tnodetype;l,r,_t1,_t2 : tnode);virtual;
  47. destructor destroy;override;
  48. function getcopy : tnode;override;
  49. constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
  50. procedure ppuwrite(ppufile:tcompilerppufile);override;
  51. procedure derefimpl;override;
  52. procedure insertintolist(l : tnodelist);override;
  53. {$ifdef extdebug}
  54. procedure _dowrite;override;
  55. {$endif extdebug}
  56. function docompare(p: tnode): boolean; override;
  57. end;
  58. twhilerepeatnode = class(tloopnode)
  59. constructor create(l,r,_t1:Tnode;tab,cn:boolean);virtual;
  60. function det_resulttype:tnode;override;
  61. function pass_1 : tnode;override;
  62. {$ifdef state_tracking}
  63. function track_state_pass(exec_known:boolean):boolean;override;
  64. {$endif}
  65. end;
  66. twhilerepeatnodeclass = class of twhilerepeatnode;
  67. tifnode = class(tloopnode)
  68. constructor create(l,r,_t1 : tnode);virtual;
  69. function det_resulttype:tnode;override;
  70. function pass_1 : tnode;override;
  71. end;
  72. tifnodeclass = class of tifnode;
  73. tfornode = class(tloopnode)
  74. loopvar_notid:cardinal;
  75. constructor create(l,r,_t1,_t2 : tnode;back : boolean);virtual;
  76. procedure loop_var_access(not_type:Tnotification_flag;symbol:Tsym);
  77. function det_resulttype:tnode;override;
  78. function pass_1 : tnode;override;
  79. end;
  80. tfornodeclass = class of tfornode;
  81. texitnode = class(tunarynode)
  82. onlyassign : boolean;
  83. constructor create(l:tnode);virtual;
  84. constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
  85. procedure ppuwrite(ppufile:tcompilerppufile);override;
  86. function det_resulttype:tnode;override;
  87. function pass_1 : tnode;override;
  88. end;
  89. texitnodeclass = class of texitnode;
  90. tbreaknode = class(tnode)
  91. constructor create;virtual;
  92. function det_resulttype:tnode;override;
  93. function pass_1 : tnode;override;
  94. end;
  95. tbreaknodeclass = class of tbreaknode;
  96. tcontinuenode = class(tnode)
  97. constructor create;virtual;
  98. function det_resulttype:tnode;override;
  99. function pass_1 : tnode;override;
  100. end;
  101. tcontinuenodeclass = class of tcontinuenode;
  102. tgotonode = class(tnode)
  103. labsym : tlabelsym;
  104. exceptionblock : integer;
  105. constructor create(p : tlabelsym);virtual;
  106. constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
  107. procedure ppuwrite(ppufile:tcompilerppufile);override;
  108. procedure derefimpl;override;
  109. function getcopy : tnode;override;
  110. function det_resulttype:tnode;override;
  111. function pass_1 : tnode;override;
  112. function docompare(p: tnode): boolean; override;
  113. end;
  114. tgotonodeclass = class of tgotonode;
  115. tlabelnode = class(tunarynode)
  116. labelnr : tasmlabel;
  117. labsym : tlabelsym;
  118. exceptionblock : integer;
  119. constructor createcase(p : tasmlabel;l:tnode);virtual;
  120. constructor create(p : tlabelsym;l:tnode);virtual;
  121. constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
  122. procedure ppuwrite(ppufile:tcompilerppufile);override;
  123. procedure derefimpl;override;
  124. function getcopy : tnode;override;
  125. function det_resulttype:tnode;override;
  126. function pass_1 : tnode;override;
  127. function docompare(p: tnode): boolean; override;
  128. end;
  129. tlabelnodeclass = class of tlabelnode;
  130. traisenode = class(tbinarynode)
  131. frametree : tnode;
  132. constructor create(l,taddr,tframe:tnode);virtual;
  133. constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
  134. procedure ppuwrite(ppufile:tcompilerppufile);override;
  135. procedure derefimpl;override;
  136. function getcopy : tnode;override;
  137. procedure insertintolist(l : tnodelist);override;
  138. function det_resulttype:tnode;override;
  139. function pass_1 : tnode;override;
  140. function docompare(p: tnode): boolean; override;
  141. end;
  142. traisenodeclass = class of traisenode;
  143. ttryexceptnode = class(tloopnode)
  144. constructor create(l,r,_t1 : tnode);virtual;
  145. function det_resulttype:tnode;override;
  146. function pass_1 : tnode;override;
  147. end;
  148. ttryexceptnodeclass = class of ttryexceptnode;
  149. ttryfinallynode = class(tbinarynode)
  150. constructor create(l,r:tnode);virtual;
  151. function det_resulttype:tnode;override;
  152. function pass_1 : tnode;override;
  153. end;
  154. ttryfinallynodeclass = class of ttryfinallynode;
  155. tonnode = class(tbinarynode)
  156. exceptsymtable : tsymtable;
  157. excepttype : tobjectdef;
  158. constructor create(l,r:tnode);virtual;
  159. destructor destroy;override;
  160. constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
  161. function det_resulttype:tnode;override;
  162. function pass_1 : tnode;override;
  163. function getcopy : tnode;override;
  164. function docompare(p: tnode): boolean; override;
  165. end;
  166. tonnodeclass = class of tonnode;
  167. tfailnode = class(tnode)
  168. constructor create;virtual;
  169. function det_resulttype:tnode;override;
  170. function pass_1: tnode;override;
  171. function docompare(p: tnode): boolean; override;
  172. end;
  173. tfailnodeclass = class of tfailnode;
  174. { for compatibilty }
  175. function genloopnode(t : tnodetype;l,r,n1 : tnode;back : boolean) : tnode;
  176. var
  177. cwhilerepeatnode : twhilerepeatnodeclass;
  178. cifnode : tifnodeclass;
  179. cfornode : tfornodeclass;
  180. cexitnode : texitnodeclass;
  181. cbreaknode : tbreaknodeclass;
  182. ccontinuenode : tcontinuenodeclass;
  183. cgotonode : tgotonodeclass;
  184. clabelnode : tlabelnodeclass;
  185. craisenode : traisenodeclass;
  186. ctryexceptnode : ttryexceptnodeclass;
  187. ctryfinallynode : ttryfinallynodeclass;
  188. connode : tonnodeclass;
  189. cfailnode : tfailnodeclass;
  190. implementation
  191. uses
  192. globtype,systems,
  193. cutils,verbose,globals,
  194. symconst,symtable,paramgr,defutil,htypechk,pass_1,
  195. ncon,nmem,nld,ncnv,nbas,rgobj,
  196. {$ifdef state_tracking}
  197. nstate,
  198. {$endif}
  199. cgbase
  200. ;
  201. function genloopnode(t : tnodetype;l,r,n1 : tnode;back : boolean) : tnode;
  202. var
  203. p : tnode;
  204. begin
  205. case t of
  206. ifn:
  207. p:=cifnode.create(l,r,n1);
  208. whilerepeatn:
  209. if back then
  210. {Repeat until.}
  211. p:=cwhilerepeatnode.create(l,r,n1,false,true)
  212. else
  213. {While do.}
  214. p:=cwhilerepeatnode.create(l,r,n1,true,false);
  215. forn:
  216. p:=cfornode.create(l,r,n1,nil,back);
  217. end;
  218. genloopnode:=p;
  219. end;
  220. {****************************************************************************
  221. TLOOPNODE
  222. *****************************************************************************}
  223. constructor tloopnode.create(tt : tnodetype;l,r,_t1,_t2 : tnode);
  224. begin
  225. inherited create(tt,l,r);
  226. t1:=_t1;
  227. t2:=_t2;
  228. set_file_line(l);
  229. end;
  230. destructor tloopnode.destroy;
  231. begin
  232. t1.free;
  233. t2.free;
  234. inherited destroy;
  235. end;
  236. constructor tloopnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  237. begin
  238. inherited ppuload(t,ppufile);
  239. t1:=ppuloadnode(ppufile);
  240. t2:=ppuloadnode(ppufile);
  241. end;
  242. procedure tloopnode.ppuwrite(ppufile:tcompilerppufile);
  243. begin
  244. inherited ppuwrite(ppufile);
  245. ppuwritenode(ppufile,t1);
  246. ppuwritenode(ppufile,t2);
  247. end;
  248. procedure tloopnode.derefimpl;
  249. begin
  250. inherited derefimpl;
  251. if assigned(t1) then
  252. t1.derefimpl;
  253. if assigned(t2) then
  254. t2.derefimpl;
  255. end;
  256. function tloopnode.getcopy : tnode;
  257. var
  258. p : tloopnode;
  259. begin
  260. p:=tloopnode(inherited getcopy);
  261. if assigned(t1) then
  262. p.t1:=t1.getcopy
  263. else
  264. p.t1:=nil;
  265. if assigned(t2) then
  266. p.t2:=t2.getcopy
  267. else
  268. p.t2:=nil;
  269. getcopy:=p;
  270. end;
  271. procedure tloopnode.insertintolist(l : tnodelist);
  272. begin
  273. end;
  274. {$ifdef extdebug}
  275. procedure tloopnode._dowrite;
  276. begin
  277. inherited _dowrite;
  278. writenodeindention:=writenodeindention+' ';
  279. writenode(t1);
  280. writenode(t2);
  281. delete(writenodeindention,1,4);
  282. end;
  283. {$endif extdebug}
  284. function tloopnode.docompare(p: tnode): boolean;
  285. begin
  286. docompare :=
  287. inherited docompare(p) and
  288. (loopflags*loopflagsequal=tloopnode(p).loopflags*loopflagsequal) and
  289. t1.isequal(tloopnode(p).t1) and
  290. t2.isequal(tloopnode(p).t2);
  291. end;
  292. {****************************************************************************
  293. TWHILEREPEATNODE
  294. *****************************************************************************}
  295. constructor Twhilerepeatnode.create(l,r,_t1:Tnode;tab,cn:boolean);
  296. begin
  297. inherited create(whilerepeatn,l,r,_t1,nil);
  298. if tab then
  299. include(loopflags, lnf_testatbegin);
  300. if cn then
  301. include(loopflags,lnf_checknegate);
  302. end;
  303. function twhilerepeatnode.det_resulttype:tnode;
  304. var
  305. t:Tunarynode;
  306. begin
  307. result:=nil;
  308. resulttype:=voidtype;
  309. resulttypepass(left);
  310. {A not node can be removed.}
  311. if left.nodetype=notn then
  312. begin
  313. t:=Tunarynode(left);
  314. left:=Tunarynode(left).left;
  315. t.left:=nil;
  316. t.destroy;
  317. {$ifdef Delphi}
  318. { How can this be handled in Delphi ? }
  319. RunError(255);
  320. {$else}
  321. {Symdif operator, in case you are wondering:}
  322. loopflags:=loopflags >< [lnf_checknegate];
  323. {$endif}
  324. end;
  325. { loop instruction }
  326. if assigned(right) then
  327. resulttypepass(right);
  328. set_varstate(left,true);
  329. if codegenerror then
  330. exit;
  331. if not is_boolean(left.resulttype.def) then
  332. begin
  333. CGMessage(type_e_mismatch);
  334. exit;
  335. end;
  336. end;
  337. function twhilerepeatnode.pass_1 : tnode;
  338. var
  339. old_t_times : longint;
  340. begin
  341. result:=nil;
  342. old_t_times:=rg.t_times;
  343. { calc register weight }
  344. if not(cs_littlesize in aktglobalswitches ) then
  345. rg.t_times:=rg.t_times*8;
  346. rg.cleartempgen;
  347. firstpass(left);
  348. if codegenerror then
  349. exit;
  350. registers32:=left.registers32;
  351. registersfpu:=left.registersfpu;
  352. {$ifdef SUPPORT_MMX}
  353. registersmmx:=left.registersmmx;
  354. {$endif SUPPORT_MMX}
  355. { loop instruction }
  356. if assigned(right) then
  357. begin
  358. rg.cleartempgen;
  359. firstpass(right);
  360. if codegenerror then
  361. exit;
  362. if registers32<right.registers32 then
  363. registers32:=right.registers32;
  364. if registersfpu<right.registersfpu then
  365. registersfpu:=right.registersfpu;
  366. {$ifdef SUPPORT_MMX}
  367. if registersmmx<right.registersmmx then
  368. registersmmx:=right.registersmmx;
  369. {$endif SUPPORT_MMX}
  370. end;
  371. rg.t_times:=old_t_times;
  372. end;
  373. {$ifdef state_tracking}
  374. function Twhilerepeatnode.track_state_pass(exec_known:boolean):boolean;
  375. var condition:Tnode;
  376. code:Tnode;
  377. done:boolean;
  378. value:boolean;
  379. change:boolean;
  380. firsttest:boolean;
  381. factval:Tnode;
  382. begin
  383. track_state_pass:=false;
  384. done:=false;
  385. firsttest:=true;
  386. {For repeat until statements, first do a pass through the code.}
  387. if not(lnf_testatbegin in flags) then
  388. begin
  389. code:=right.getcopy;
  390. if code.track_state_pass(exec_known) then
  391. track_state_pass:=true;
  392. code.destroy;
  393. end;
  394. repeat
  395. condition:=left.getcopy;
  396. code:=right.getcopy;
  397. change:=condition.track_state_pass(exec_known);
  398. factval:=aktstate.find_fact(left);
  399. if factval<>nil then
  400. begin
  401. condition.destroy;
  402. condition:=factval.getcopy;
  403. change:=true;
  404. end;
  405. if change then
  406. begin
  407. track_state_pass:=true;
  408. {Force new resulttype pass.}
  409. condition.resulttype.def:=nil;
  410. do_resulttypepass(condition);
  411. end;
  412. if is_constboolnode(condition) then
  413. begin
  414. {Try to turn a while loop into a repeat loop.}
  415. if firsttest then
  416. exclude(flags,testatbegin);
  417. value:=(Tordconstnode(condition).value<>0) xor checknegate;
  418. if value then
  419. begin
  420. if code.track_state_pass(exec_known) then
  421. track_state_pass:=true;
  422. end
  423. else
  424. done:=true;
  425. end
  426. else
  427. begin
  428. {Remove any modified variables from the state.}
  429. code.track_state_pass(false);
  430. done:=true;
  431. end;
  432. code.destroy;
  433. condition.destroy;
  434. firsttest:=false;
  435. until done;
  436. {The loop condition is also known, for example:
  437. while i<10 do
  438. begin
  439. ...
  440. end;
  441. When the loop is done, we do know that i<10 = false.
  442. }
  443. condition:=left.getcopy;
  444. if condition.track_state_pass(exec_known) then
  445. begin
  446. track_state_pass:=true;
  447. {Force new resulttype pass.}
  448. condition.resulttype.def:=nil;
  449. do_resulttypepass(condition);
  450. end;
  451. if not is_constboolnode(condition) then
  452. aktstate.store_fact(condition,
  453. cordconstnode.create(byte(checknegate),booltype,true))
  454. else
  455. condition.destroy;
  456. end;
  457. {$endif}
  458. {*****************************************************************************
  459. TIFNODE
  460. *****************************************************************************}
  461. constructor tifnode.create(l,r,_t1 : tnode);
  462. begin
  463. inherited create(ifn,l,r,_t1,nil);
  464. end;
  465. function tifnode.det_resulttype:tnode;
  466. begin
  467. result:=nil;
  468. resulttype:=voidtype;
  469. resulttypepass(left);
  470. { if path }
  471. if assigned(right) then
  472. resulttypepass(right);
  473. { else path }
  474. if assigned(t1) then
  475. resulttypepass(t1);
  476. set_varstate(left,true);
  477. if codegenerror then
  478. exit;
  479. if not is_boolean(left.resulttype.def) then
  480. Message1(type_e_boolean_expr_expected,left.resulttype.def.typename);
  481. end;
  482. function tifnode.pass_1 : tnode;
  483. var
  484. old_t_times : longint;
  485. hp : tnode;
  486. begin
  487. result:=nil;
  488. old_t_times:=rg.t_times;
  489. rg.cleartempgen;
  490. firstpass(left);
  491. registers32:=left.registers32;
  492. registersfpu:=left.registersfpu;
  493. {$ifdef SUPPORT_MMX}
  494. registersmmx:=left.registersmmx;
  495. {$endif SUPPORT_MMX}
  496. { determines registers weigths }
  497. if not(cs_littlesize in aktglobalswitches) then
  498. rg.t_times:=rg.t_times div 2;
  499. if rg.t_times=0 then
  500. rg.t_times:=1;
  501. { if path }
  502. if assigned(right) then
  503. begin
  504. rg.cleartempgen;
  505. firstpass(right);
  506. if registers32<right.registers32 then
  507. registers32:=right.registers32;
  508. if registersfpu<right.registersfpu then
  509. registersfpu:=right.registersfpu;
  510. {$ifdef SUPPORT_MMX}
  511. if registersmmx<right.registersmmx then
  512. registersmmx:=right.registersmmx;
  513. {$endif SUPPORT_MMX}
  514. end;
  515. { else path }
  516. if assigned(t1) then
  517. begin
  518. rg.cleartempgen;
  519. firstpass(t1);
  520. if registers32<t1.registers32 then
  521. registers32:=t1.registers32;
  522. if registersfpu<t1.registersfpu then
  523. registersfpu:=t1.registersfpu;
  524. {$ifdef SUPPORT_MMX}
  525. if registersmmx<t1.registersmmx then
  526. registersmmx:=t1.registersmmx;
  527. {$endif SUPPORT_MMX}
  528. end;
  529. { leave if we've got an error in one of the paths }
  530. if codegenerror then
  531. exit;
  532. if left.nodetype=ordconstn then
  533. begin
  534. { optimize }
  535. if tordconstnode(left).value=1 then
  536. begin
  537. hp:=right;
  538. right:=nil;
  539. { we cannot set p to nil !!! }
  540. if assigned(hp) then
  541. result:=hp
  542. else
  543. result:=cnothingnode.create;
  544. end
  545. else
  546. begin
  547. hp:=t1;
  548. t1:=nil;
  549. { we cannot set p to nil !!! }
  550. if assigned(hp) then
  551. result:=hp
  552. else
  553. result:=cnothingnode.create;
  554. end;
  555. end;
  556. rg.t_times:=old_t_times;
  557. end;
  558. {*****************************************************************************
  559. TFORNODE
  560. *****************************************************************************}
  561. constructor tfornode.create(l,r,_t1,_t2 : tnode;back : boolean);
  562. begin
  563. inherited create(forn,l,r,_t1,_t2);
  564. if back then
  565. include(loopflags,lnf_backward);
  566. include(loopflags,lnf_testatbegin);
  567. end;
  568. procedure Tfornode.loop_var_access(not_type:Tnotification_flag;
  569. symbol:Tsym);
  570. begin
  571. {If there is a read access, the value of the loop counter is important;
  572. at the end of the loop the loop variable should contain the value it
  573. had in the last iteration.}
  574. if not_type=vn_onwrite then
  575. begin
  576. writeln('Loopvar does not matter on exit');
  577. end
  578. else
  579. begin
  580. exclude(loopflags,lnf_dont_mind_loopvar_on_exit);
  581. writeln('Loopvar does matter on exit');
  582. end;
  583. Tvarsym(symbol).unregister_notification(loopvar_notid);
  584. end;
  585. function tfornode.det_resulttype:tnode;
  586. var
  587. hp : tnode;
  588. begin
  589. result:=nil;
  590. resulttype:=voidtype;
  591. if left.nodetype<>assignn then
  592. begin
  593. CGMessage(cg_e_illegal_expression);
  594. exit;
  595. end;
  596. {Can we spare the first comparision?}
  597. if (right.nodetype=ordconstn) and (Tassignmentnode(left).right.nodetype=ordconstn) then
  598. if (
  599. (lnf_backward in loopflags) and
  600. (Tordconstnode(Tassignmentnode(left).right).value>=Tordconstnode(right).value)
  601. )
  602. or not(
  603. (lnf_backward in loopflags) and
  604. (Tordconstnode(Tassignmentnode(left).right).value<=Tordconstnode(right).value)
  605. ) then
  606. exclude(loopflags,lnf_testatbegin);
  607. { save counter var }
  608. t2:=tassignmentnode(left).left.getcopy;
  609. resulttypepass(left);
  610. set_varstate(left,false);
  611. if assigned(t1) then
  612. begin
  613. resulttypepass(t1);
  614. if codegenerror then
  615. exit;
  616. end;
  617. { process count var }
  618. resulttypepass(t2);
  619. set_varstate(t2,true);
  620. if codegenerror then
  621. exit;
  622. { Check count var, record fields are also allowed in tp7 }
  623. hp:=t2;
  624. while (hp.nodetype=subscriptn) or
  625. ((hp.nodetype=vecn) and
  626. is_constintnode(tvecnode(hp).right)) do
  627. hp:=tunarynode(hp).left;
  628. { we need a simple loadn, but the load must be in a global symtable or
  629. in the same lexlevel }
  630. if (hp.nodetype=funcretn) or
  631. (
  632. (hp.nodetype=loadn) and
  633. (
  634. (tloadnode(hp).symtable.symtablelevel<=1) or
  635. (tloadnode(hp).symtable.symtablelevel=lexlevel)
  636. ) and
  637. not(
  638. (tloadnode(hp).symtableentry.typ=varsym) and
  639. ((tvarsym(tloadnode(hp).symtableentry).varspez in [vs_var,vs_out]) or
  640. (vo_is_thread_var in tvarsym(tloadnode(hp).symtableentry).varoptions))
  641. )
  642. ) then
  643. begin
  644. if (hp.nodetype=loadn) and
  645. (tloadnode(hp).symtableentry.typ=varsym) then
  646. tvarsym(tloadnode(hp).symtableentry).varstate:=vs_used;
  647. if (not(is_ordinal(t2.resulttype.def)) or is_64bitint(t2.resulttype.def)) then
  648. CGMessagePos(hp.fileinfo,type_e_ordinal_expr_expected);
  649. end
  650. else
  651. CGMessagePos(hp.fileinfo,cg_e_illegal_count_var);
  652. resulttypepass(right);
  653. set_varstate(right,true);
  654. inserttypeconv(right,t2.resulttype);
  655. end;
  656. function tfornode.pass_1 : tnode;
  657. var
  658. old_t_times : longint;
  659. {$ifdef loopvar_dont_mind}
  660. hp : Tnode;
  661. {$endif loopvar_dont_mind}
  662. begin
  663. result:=nil;
  664. { Calc register weight }
  665. old_t_times:=rg.t_times;
  666. if not(cs_littlesize in aktglobalswitches) then
  667. rg.t_times:=rg.t_times*8;
  668. rg.cleartempgen;
  669. firstpass(left);
  670. rg.cleartempgen;
  671. if assigned(t1) then
  672. begin
  673. firstpass(t1);
  674. if codegenerror then
  675. exit;
  676. end;
  677. registers32:=t1.registers32;
  678. registersfpu:=t1.registersfpu;
  679. {$ifdef SUPPORT_MMX}
  680. registersmmx:=left.registersmmx;
  681. {$endif SUPPORT_MMX}
  682. if left.registers32>registers32 then
  683. registers32:=left.registers32;
  684. if left.registersfpu>registersfpu then
  685. registersfpu:=left.registersfpu;
  686. {$ifdef SUPPORT_MMX}
  687. if left.registersmmx>registersmmx then
  688. registersmmx:=left.registersmmx;
  689. {$endif SUPPORT_MMX}
  690. { process count var }
  691. rg.cleartempgen;
  692. firstpass(t2);
  693. if codegenerror then
  694. exit;
  695. if t2.registers32>registers32 then
  696. registers32:=t2.registers32;
  697. if t2.registersfpu>registersfpu then
  698. registersfpu:=t2.registersfpu;
  699. {$ifdef SUPPORT_MMX}
  700. if t2.registersmmx>registersmmx then
  701. registersmmx:=t2.registersmmx;
  702. {$endif SUPPORT_MMX}
  703. rg.cleartempgen;
  704. firstpass(right);
  705. {$ifdef loopvar_dont_mind}
  706. { Check count var, record fields are also allowed in tp7 }
  707. include(loopflags,lnf_dont_mind_loopvar_on_exit);
  708. hp:=t2;
  709. while (hp.nodetype=subscriptn) or
  710. ((hp.nodetype=vecn) and
  711. is_constintnode(tvecnode(hp).right)) do
  712. hp:=tunarynode(hp).left;
  713. if (hp.nodetype=loadn) and (Tloadnode(hp).symtableentry.typ=varsym) then
  714. loopvar_notid:=Tvarsym(Tloadnode(hp).symtableentry).
  715. register_notification([vn_onread,vn_onwrite],@loop_var_access);
  716. {$endif}
  717. if right.registers32>registers32 then
  718. registers32:=right.registers32;
  719. if right.registersfpu>registersfpu then
  720. registersfpu:=right.registersfpu;
  721. {$ifdef SUPPORT_MMX}
  722. if right.registersmmx>registersmmx then
  723. registersmmx:=right.registersmmx;
  724. {$endif SUPPORT_MMX}
  725. { we need at least one register for comparisons PM }
  726. if registers32=0 then
  727. inc(registers32);
  728. rg.t_times:=old_t_times;
  729. end;
  730. {*****************************************************************************
  731. TEXITNODE
  732. *****************************************************************************}
  733. constructor texitnode.create(l:tnode);
  734. begin
  735. inherited create(exitn,l);
  736. onlyassign:=false;
  737. end;
  738. constructor texitnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  739. begin
  740. inherited ppuload(t,ppufile);
  741. onlyassign:=boolean(ppufile.getbyte);
  742. end;
  743. procedure texitnode.ppuwrite(ppufile:tcompilerppufile);
  744. begin
  745. inherited ppuwrite(ppufile);
  746. ppufile.putbyte(byte(onlyassign));
  747. end;
  748. function texitnode.det_resulttype:tnode;
  749. var
  750. pt : tnode;
  751. begin
  752. result:=nil;
  753. { Check the 2 types }
  754. if not inlining_procedure then
  755. begin
  756. if assigned(left) then
  757. begin
  758. inserttypeconv(left,aktprocdef.rettype);
  759. if paramanager.ret_in_param(aktprocdef.rettype.def,aktprocdef.proccalloption) or
  760. (procinfo.no_fast_exit) or
  761. ((procinfo.flags and pi_uses_exceptions)<>0) then
  762. begin
  763. pt:=cfuncretnode.create(aktprocdef.funcretsym);
  764. left:=cassignmentnode.create(pt,left);
  765. onlyassign:=true;
  766. end;
  767. tfuncretsym(aktprocdef.funcretsym).funcretstate:=vs_assigned;
  768. end;
  769. end;
  770. if assigned(left) then
  771. begin
  772. resulttypepass(left);
  773. set_varstate(left,true);
  774. end;
  775. resulttype:=voidtype;
  776. end;
  777. function texitnode.pass_1 : tnode;
  778. begin
  779. result:=nil;
  780. if assigned(left) then
  781. begin
  782. firstpass(left);
  783. if codegenerror then
  784. exit;
  785. registers32:=left.registers32;
  786. registersfpu:=left.registersfpu;
  787. {$ifdef SUPPORT_MMX}
  788. registersmmx:=left.registersmmx;
  789. {$endif SUPPORT_MMX}
  790. end;
  791. end;
  792. {*****************************************************************************
  793. TBREAKNODE
  794. *****************************************************************************}
  795. constructor tbreaknode.create;
  796. begin
  797. inherited create(breakn);
  798. end;
  799. function tbreaknode.det_resulttype:tnode;
  800. begin
  801. result:=nil;
  802. resulttype:=voidtype;
  803. end;
  804. function tbreaknode.pass_1 : tnode;
  805. begin
  806. result:=nil;
  807. end;
  808. {*****************************************************************************
  809. TCONTINUENODE
  810. *****************************************************************************}
  811. constructor tcontinuenode.create;
  812. begin
  813. inherited create(continuen);
  814. end;
  815. function tcontinuenode.det_resulttype:tnode;
  816. begin
  817. result:=nil;
  818. resulttype:=voidtype;
  819. end;
  820. function tcontinuenode.pass_1 : tnode;
  821. begin
  822. result:=nil;
  823. end;
  824. {*****************************************************************************
  825. TGOTONODE
  826. *****************************************************************************}
  827. constructor tgotonode.create(p : tlabelsym);
  828. begin
  829. inherited create(goton);
  830. exceptionblock:=aktexceptblock;
  831. labsym:=p;
  832. end;
  833. constructor tgotonode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  834. begin
  835. inherited ppuload(t,ppufile);
  836. labsym:=tlabelsym(ppufile.getderef);
  837. exceptionblock:=ppufile.getbyte;
  838. end;
  839. procedure tgotonode.ppuwrite(ppufile:tcompilerppufile);
  840. begin
  841. inherited ppuwrite(ppufile);
  842. ppufile.putderef(labsym);
  843. ppufile.putbyte(exceptionblock);
  844. end;
  845. procedure tgotonode.derefimpl;
  846. begin
  847. inherited derefimpl;
  848. resolvesym(pointer(labsym));
  849. end;
  850. function tgotonode.det_resulttype:tnode;
  851. begin
  852. result:=nil;
  853. resulttype:=voidtype;
  854. end;
  855. function tgotonode.pass_1 : tnode;
  856. begin
  857. result:=nil;
  858. { check if }
  859. if assigned(labsym) and
  860. assigned(labsym.code) and
  861. (exceptionblock<>tlabelnode(labsym.code).exceptionblock) then
  862. begin
  863. writeln('goto exceptblock: ',exceptionblock);
  864. writeln('label exceptblock: ',tlabelnode(labsym.code).exceptionblock);
  865. CGMessage(cg_e_goto_inout_of_exception_block);
  866. end;
  867. end;
  868. function tgotonode.getcopy : tnode;
  869. var
  870. p : tgotonode;
  871. begin
  872. p:=tgotonode(inherited getcopy);
  873. p.labsym:=labsym;
  874. p.exceptionblock:=exceptionblock;
  875. result:=p;
  876. end;
  877. function tgotonode.docompare(p: tnode): boolean;
  878. begin
  879. docompare := false;
  880. end;
  881. {*****************************************************************************
  882. TLABELNODE
  883. *****************************************************************************}
  884. constructor tlabelnode.createcase(p : tasmlabel;l:tnode);
  885. begin
  886. inherited create(labeln,l);
  887. { it shouldn't be possible to jump to case labels using goto }
  888. exceptionblock:=-1;
  889. labsym:=nil;
  890. labelnr:=p;
  891. end;
  892. constructor tlabelnode.create(p : tlabelsym;l:tnode);
  893. begin
  894. inherited create(labeln,l);
  895. exceptionblock:=aktexceptblock;
  896. labsym:=p;
  897. labelnr:=p.lab;
  898. { save the current labelnode in the labelsym }
  899. p.code:=self;
  900. end;
  901. constructor tlabelnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  902. begin
  903. inherited ppuload(t,ppufile);
  904. labsym:=tlabelsym(ppufile.getderef);
  905. labelnr:=tasmlabel(ppufile.getasmsymbol);
  906. exceptionblock:=ppufile.getbyte;
  907. end;
  908. procedure tlabelnode.ppuwrite(ppufile:tcompilerppufile);
  909. begin
  910. inherited ppuwrite(ppufile);
  911. ppufile.putderef(labsym);
  912. ppufile.putasmsymbol(labelnr);
  913. ppufile.putbyte(exceptionblock);
  914. end;
  915. procedure tlabelnode.derefimpl;
  916. begin
  917. inherited derefimpl;
  918. resolvesym(pointer(labsym));
  919. objectlibrary.derefasmsymbol(tasmsymbol(labelnr));
  920. end;
  921. function tlabelnode.det_resulttype:tnode;
  922. begin
  923. result:=nil;
  924. { left could still be unassigned }
  925. if assigned(left) then
  926. resulttypepass(left);
  927. resulttype:=voidtype;
  928. end;
  929. function tlabelnode.pass_1 : tnode;
  930. begin
  931. result:=nil;
  932. if assigned(left) then
  933. begin
  934. rg.cleartempgen;
  935. firstpass(left);
  936. registers32:=left.registers32;
  937. registersfpu:=left.registersfpu;
  938. {$ifdef SUPPORT_MMX}
  939. registersmmx:=left.registersmmx;
  940. {$endif SUPPORT_MMX}
  941. end;
  942. end;
  943. function tlabelnode.getcopy : tnode;
  944. var
  945. p : tlabelnode;
  946. begin
  947. p:=tlabelnode(inherited getcopy);
  948. p.labelnr:=labelnr;
  949. p.exceptionblock:=exceptionblock;
  950. p.labsym:=labsym;
  951. result:=p;
  952. end;
  953. function tlabelnode.docompare(p: tnode): boolean;
  954. begin
  955. docompare := false;
  956. end;
  957. {*****************************************************************************
  958. TRAISENODE
  959. *****************************************************************************}
  960. constructor traisenode.create(l,taddr,tframe:tnode);
  961. begin
  962. inherited create(raisen,l,taddr);
  963. frametree:=tframe;
  964. end;
  965. constructor traisenode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  966. begin
  967. inherited ppuload(t,ppufile);
  968. frametree:=ppuloadnode(ppufile);
  969. end;
  970. procedure traisenode.ppuwrite(ppufile:tcompilerppufile);
  971. begin
  972. inherited ppuwrite(ppufile);
  973. ppuwritenode(ppufile,frametree);
  974. end;
  975. procedure traisenode.derefimpl;
  976. begin
  977. inherited derefimpl;
  978. if assigned(frametree) then
  979. frametree.derefimpl;
  980. end;
  981. function traisenode.getcopy : tnode;
  982. var
  983. n : traisenode;
  984. begin
  985. n:=traisenode(inherited getcopy);
  986. if assigned(frametree) then
  987. n.frametree:=frametree.getcopy
  988. else
  989. n.frametree:=nil;
  990. getcopy:=n;
  991. end;
  992. procedure traisenode.insertintolist(l : tnodelist);
  993. begin
  994. end;
  995. function traisenode.det_resulttype:tnode;
  996. begin
  997. result:=nil;
  998. resulttype:=voidtype;
  999. if assigned(left) then
  1000. begin
  1001. { first para must be a _class_ }
  1002. resulttypepass(left);
  1003. set_varstate(left,true);
  1004. if codegenerror then
  1005. exit;
  1006. if not(is_class(left.resulttype.def)) then
  1007. CGMessage(type_e_mismatch);
  1008. { insert needed typeconvs for addr,frame }
  1009. if assigned(right) then
  1010. begin
  1011. { addr }
  1012. resulttypepass(right);
  1013. inserttypeconv(right,voidpointertype);
  1014. { frame }
  1015. if assigned(frametree) then
  1016. begin
  1017. resulttypepass(frametree);
  1018. inserttypeconv(frametree,voidpointertype);
  1019. end;
  1020. end;
  1021. end;
  1022. end;
  1023. function traisenode.pass_1 : tnode;
  1024. begin
  1025. result:=nil;
  1026. if assigned(left) then
  1027. begin
  1028. { first para must be a _class_ }
  1029. firstpass(left);
  1030. { insert needed typeconvs for addr,frame }
  1031. if assigned(right) then
  1032. begin
  1033. { addr }
  1034. firstpass(right);
  1035. { frame }
  1036. if assigned(frametree) then
  1037. firstpass(frametree);
  1038. end;
  1039. left_right_max;
  1040. end;
  1041. end;
  1042. function traisenode.docompare(p: tnode): boolean;
  1043. begin
  1044. docompare := false;
  1045. end;
  1046. {*****************************************************************************
  1047. TTRYEXCEPTNODE
  1048. *****************************************************************************}
  1049. constructor ttryexceptnode.create(l,r,_t1 : tnode);
  1050. begin
  1051. inherited create(tryexceptn,l,r,_t1,nil);
  1052. end;
  1053. function ttryexceptnode.det_resulttype:tnode;
  1054. begin
  1055. result:=nil;
  1056. resulttypepass(left);
  1057. { on statements }
  1058. if assigned(right) then
  1059. resulttypepass(right);
  1060. { else block }
  1061. if assigned(t1) then
  1062. resulttypepass(t1);
  1063. resulttype:=voidtype;
  1064. end;
  1065. function ttryexceptnode.pass_1 : tnode;
  1066. begin
  1067. result:=nil;
  1068. rg.cleartempgen;
  1069. firstpass(left);
  1070. { on statements }
  1071. if assigned(right) then
  1072. begin
  1073. rg.cleartempgen;
  1074. firstpass(right);
  1075. registers32:=max(registers32,right.registers32);
  1076. registersfpu:=max(registersfpu,right.registersfpu);
  1077. {$ifdef SUPPORT_MMX}
  1078. registersmmx:=max(registersmmx,right.registersmmx);
  1079. {$endif SUPPORT_MMX}
  1080. end;
  1081. { else block }
  1082. if assigned(t1) then
  1083. begin
  1084. firstpass(t1);
  1085. registers32:=max(registers32,t1.registers32);
  1086. registersfpu:=max(registersfpu,t1.registersfpu);
  1087. {$ifdef SUPPORT_MMX}
  1088. registersmmx:=max(registersmmx,t1.registersmmx);
  1089. {$endif SUPPORT_MMX}
  1090. end;
  1091. end;
  1092. {*****************************************************************************
  1093. TTRYFINALLYNODE
  1094. *****************************************************************************}
  1095. constructor ttryfinallynode.create(l,r:tnode);
  1096. begin
  1097. inherited create(tryfinallyn,l,r);
  1098. end;
  1099. function ttryfinallynode.det_resulttype:tnode;
  1100. begin
  1101. result:=nil;
  1102. resulttype:=voidtype;
  1103. resulttypepass(left);
  1104. set_varstate(left,true);
  1105. resulttypepass(right);
  1106. set_varstate(right,true);
  1107. end;
  1108. function ttryfinallynode.pass_1 : tnode;
  1109. begin
  1110. result:=nil;
  1111. rg.cleartempgen;
  1112. firstpass(left);
  1113. rg.cleartempgen;
  1114. firstpass(right);
  1115. left_right_max;
  1116. end;
  1117. {*****************************************************************************
  1118. TONNODE
  1119. *****************************************************************************}
  1120. constructor tonnode.create(l,r:tnode);
  1121. begin
  1122. inherited create(onn,l,r);
  1123. exceptsymtable:=nil;
  1124. excepttype:=nil;
  1125. end;
  1126. destructor tonnode.destroy;
  1127. begin
  1128. if assigned(exceptsymtable) then
  1129. exceptsymtable.free;
  1130. inherited destroy;
  1131. end;
  1132. constructor tonnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  1133. begin
  1134. inherited ppuload(t,ppufile);
  1135. exceptsymtable:=nil;
  1136. excepttype:=nil;
  1137. end;
  1138. function tonnode.getcopy : tnode;
  1139. var
  1140. n : tonnode;
  1141. begin
  1142. n:=tonnode(inherited getcopy);
  1143. n.exceptsymtable:=exceptsymtable;
  1144. n.excepttype:=excepttype;
  1145. result:=n;
  1146. end;
  1147. function tonnode.det_resulttype:tnode;
  1148. begin
  1149. result:=nil;
  1150. resulttype:=voidtype;
  1151. if not(is_class(excepttype)) then
  1152. CGMessage(type_e_mismatch);
  1153. if assigned(left) then
  1154. resulttypepass(left);
  1155. if assigned(right) then
  1156. resulttypepass(right);
  1157. end;
  1158. function tonnode.pass_1 : tnode;
  1159. begin
  1160. result:=nil;
  1161. rg.cleartempgen;
  1162. registers32:=0;
  1163. registersfpu:=0;
  1164. {$ifdef SUPPORT_MMX}
  1165. registersmmx:=0;
  1166. {$endif SUPPORT_MMX}
  1167. if assigned(left) then
  1168. begin
  1169. firstpass(left);
  1170. registers32:=left.registers32;
  1171. registersfpu:=left.registersfpu;
  1172. {$ifdef SUPPORT_MMX}
  1173. registersmmx:=left.registersmmx;
  1174. {$endif SUPPORT_MMX}
  1175. end;
  1176. rg.cleartempgen;
  1177. if assigned(right) then
  1178. begin
  1179. firstpass(right);
  1180. registers32:=max(registers32,right.registers32);
  1181. registersfpu:=max(registersfpu,right.registersfpu);
  1182. {$ifdef SUPPORT_MMX}
  1183. registersmmx:=max(registersmmx,right.registersmmx);
  1184. {$endif SUPPORT_MMX}
  1185. end;
  1186. end;
  1187. function tonnode.docompare(p: tnode): boolean;
  1188. begin
  1189. docompare := false;
  1190. end;
  1191. {*****************************************************************************
  1192. TFAILNODE
  1193. *****************************************************************************}
  1194. constructor tfailnode.create;
  1195. begin
  1196. inherited create(failn);
  1197. end;
  1198. function tfailnode.det_resulttype:tnode;
  1199. begin
  1200. result:=nil;
  1201. resulttype:=voidtype;
  1202. end;
  1203. function tfailnode.pass_1 : tnode;
  1204. begin
  1205. result:=nil;
  1206. end;
  1207. function tfailnode.docompare(p: tnode): boolean;
  1208. begin
  1209. docompare := false;
  1210. end;
  1211. begin
  1212. cwhilerepeatnode:=twhilerepeatnode;
  1213. cifnode:=tifnode;
  1214. cfornode:=tfornode;
  1215. cexitnode:=texitnode;
  1216. cgotonode:=tgotonode;
  1217. clabelnode:=tlabelnode;
  1218. craisenode:=traisenode;
  1219. ctryexceptnode:=ttryexceptnode;
  1220. ctryfinallynode:=ttryfinallynode;
  1221. connode:=tonnode;
  1222. cfailnode:=tfailnode;
  1223. end.
  1224. {
  1225. $Log$
  1226. Revision 1.65 2003-03-20 15:54:46 peter
  1227. * don't allow var and out parameters as for loop counter
  1228. Revision 1.64 2003/01/09 21:52:37 peter
  1229. * merged some verbosity options.
  1230. * V_LineInfo is a verbosity flag to include line info
  1231. Revision 1.63 2003/01/04 08:08:47 daniel
  1232. * Readded missing variable
  1233. Revision 1.62 2003/01/03 17:16:57 peter
  1234. * fixed warning about unset funcret
  1235. Revision 1.61 2003/01/03 12:15:56 daniel
  1236. * Removed ifdefs around notifications
  1237. ifdefs around for loop optimizations remain
  1238. Revision 1.60 2002/12/31 09:55:58 daniel
  1239. + Notification implementation complete
  1240. + Add for loop code optimization using notifications
  1241. results in 1.5-1.9% speed improvement in nestloop benchmark
  1242. Optimization incomplete, compiler does not cycle yet with
  1243. notifications enabled.
  1244. Revision 1.59 2002/12/30 22:44:53 daniel
  1245. * Some work on notifications
  1246. Revision 1.58 2002/12/27 15:25:40 peter
  1247. * do not allow threadvar as loop counter
  1248. Revision 1.57 2002/11/28 11:17:02 florian
  1249. * loop node flags from node flags splitted
  1250. Revision 1.56 2002/11/25 17:43:18 peter
  1251. * splitted defbase in defutil,symutil,defcmp
  1252. * merged isconvertable and is_equal into compare_defs(_ext)
  1253. * made operator search faster by walking the list only once
  1254. Revision 1.55 2002/11/18 17:31:56 peter
  1255. * pass proccalloption to ret_in_xxx and push_xxx functions
  1256. Revision 1.54 2002/10/20 15:31:49 peter
  1257. * set funcret state for exit(0)
  1258. Revision 1.53 2002/10/05 12:43:25 carl
  1259. * fixes for Delphi 6 compilation
  1260. (warning : Some features do not work under Delphi)
  1261. Revision 1.52 2002/09/07 15:25:03 peter
  1262. * old logs removed and tabs fixed
  1263. Revision 1.51 2002/09/07 12:16:04 carl
  1264. * second part bug report 1996 fix, testrange in cordconstnode
  1265. only called if option is set (also make parsing a tiny faster)
  1266. Revision 1.50 2002/09/01 18:47:00 peter
  1267. * assignn check in exitnode changed to use a separate boolean as the
  1268. assignn can be changed to a calln
  1269. Revision 1.49 2002/09/01 08:01:16 daniel
  1270. * Removed sets from Tcallnode.det_resulttype
  1271. + Added read/write notifications of variables. These will be usefull
  1272. for providing information for several optimizations. For example
  1273. the value of the loop variable of a for loop does matter is the
  1274. variable is read after the for loop, but if it's no longer used
  1275. or written, it doesn't matter and this can be used to optimize
  1276. the loop code generation.
  1277. Revision 1.48 2002/08/22 15:15:20 daniel
  1278. * Fixed the detection wether the first check of a for loop can be skipped
  1279. Revision 1.47 2002/08/19 19:36:43 peter
  1280. * More fixes for cross unit inlining, all tnodes are now implemented
  1281. * Moved pocall_internconst to po_internconst because it is not a
  1282. calling type at all and it conflicted when inlining of these small
  1283. functions was requested
  1284. Revision 1.46 2002/08/17 22:09:46 florian
  1285. * result type handling in tcgcal.pass_2 overhauled
  1286. * better tnode.dowrite
  1287. * some ppc stuff fixed
  1288. Revision 1.45 2002/08/17 09:23:37 florian
  1289. * first part of procinfo rewrite
  1290. Revision 1.44 2002/07/21 06:58:49 daniel
  1291. * Changed booleans into flags
  1292. Revision 1.43 2002/07/20 11:57:54 florian
  1293. * types.pas renamed to defbase.pas because D6 contains a types
  1294. unit so this would conflicts if D6 programms are compiled
  1295. + Willamette/SSE2 instructions to assembler added
  1296. Revision 1.42 2002/07/20 11:18:18 daniel
  1297. * Small mistake fixed; the skip test was done before we know the for node
  1298. is correct.
  1299. Revision 1.40 2002/07/20 08:19:31 daniel
  1300. * State tracker automatically changes while loops into repeat loops
  1301. Revision 1.39 2002/07/19 12:55:27 daniel
  1302. * Further developed state tracking in whilerepeatn
  1303. Revision 1.38 2002/07/19 11:41:35 daniel
  1304. * State tracker work
  1305. * The whilen and repeatn are now completely unified into whilerepeatn. This
  1306. allows the state tracker to change while nodes automatically into
  1307. repeat nodes.
  1308. * Resulttypepass improvements to the notn. 'not not a' is optimized away and
  1309. 'not(a>b)' is optimized into 'a<=b'.
  1310. * Resulttypepass improvements to the whilerepeatn. 'while not a' is optimized
  1311. by removing the notn and later switchting the true and falselabels. The
  1312. same is done with 'repeat until not a'.
  1313. Revision 1.37 2002/07/16 13:57:02 florian
  1314. * raise takes now a void pointer as at and frame address
  1315. instead of a longint
  1316. Revision 1.36 2002/07/15 18:03:15 florian
  1317. * readded removed changes
  1318. Revision 1.35 2002/07/14 18:00:44 daniel
  1319. + Added the beginning of a state tracker. This will track the values of
  1320. variables through procedures and optimize things away.
  1321. Revision 1.34 2002/07/11 14:41:28 florian
  1322. * start of the new generic parameter handling
  1323. Revision 1.33 2002/07/01 18:46:23 peter
  1324. * internal linker
  1325. * reorganized aasm layer
  1326. Revision 1.32 2002/05/18 13:34:10 peter
  1327. * readded missing revisions
  1328. Revision 1.31 2002/05/16 19:46:38 carl
  1329. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  1330. + try to fix temp allocation (still in ifdef)
  1331. + generic constructor calls
  1332. + start of tassembler / tmodulebase class cleanup
  1333. }