nflw.pas 47 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615
  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. cginfo,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. expectloc:=LOC_VOID;
  343. old_t_times:=rg.t_times;
  344. { calc register weight }
  345. if not(cs_littlesize in aktglobalswitches ) then
  346. rg.t_times:=rg.t_times*8;
  347. rg.cleartempgen;
  348. firstpass(left);
  349. if codegenerror then
  350. exit;
  351. registers32:=left.registers32;
  352. registersfpu:=left.registersfpu;
  353. {$ifdef SUPPORT_MMX}
  354. registersmmx:=left.registersmmx;
  355. {$endif SUPPORT_MMX}
  356. { loop instruction }
  357. if assigned(right) then
  358. begin
  359. rg.cleartempgen;
  360. firstpass(right);
  361. if codegenerror then
  362. exit;
  363. if registers32<right.registers32 then
  364. registers32:=right.registers32;
  365. if registersfpu<right.registersfpu then
  366. registersfpu:=right.registersfpu;
  367. {$ifdef SUPPORT_MMX}
  368. if registersmmx<right.registersmmx then
  369. registersmmx:=right.registersmmx;
  370. {$endif SUPPORT_MMX}
  371. end;
  372. rg.t_times:=old_t_times;
  373. end;
  374. {$ifdef state_tracking}
  375. function Twhilerepeatnode.track_state_pass(exec_known:boolean):boolean;
  376. var condition:Tnode;
  377. code:Tnode;
  378. done:boolean;
  379. value:boolean;
  380. change:boolean;
  381. firsttest:boolean;
  382. factval:Tnode;
  383. begin
  384. track_state_pass:=false;
  385. done:=false;
  386. firsttest:=true;
  387. {For repeat until statements, first do a pass through the code.}
  388. if not(lnf_testatbegin in flags) then
  389. begin
  390. code:=right.getcopy;
  391. if code.track_state_pass(exec_known) then
  392. track_state_pass:=true;
  393. code.destroy;
  394. end;
  395. repeat
  396. condition:=left.getcopy;
  397. code:=right.getcopy;
  398. change:=condition.track_state_pass(exec_known);
  399. factval:=aktstate.find_fact(left);
  400. if factval<>nil then
  401. begin
  402. condition.destroy;
  403. condition:=factval.getcopy;
  404. change:=true;
  405. end;
  406. if change then
  407. begin
  408. track_state_pass:=true;
  409. {Force new resulttype pass.}
  410. condition.resulttype.def:=nil;
  411. do_resulttypepass(condition);
  412. end;
  413. if is_constboolnode(condition) then
  414. begin
  415. {Try to turn a while loop into a repeat loop.}
  416. if firsttest then
  417. exclude(flags,testatbegin);
  418. value:=(Tordconstnode(condition).value<>0) xor checknegate;
  419. if value then
  420. begin
  421. if code.track_state_pass(exec_known) then
  422. track_state_pass:=true;
  423. end
  424. else
  425. done:=true;
  426. end
  427. else
  428. begin
  429. {Remove any modified variables from the state.}
  430. code.track_state_pass(false);
  431. done:=true;
  432. end;
  433. code.destroy;
  434. condition.destroy;
  435. firsttest:=false;
  436. until done;
  437. {The loop condition is also known, for example:
  438. while i<10 do
  439. begin
  440. ...
  441. end;
  442. When the loop is done, we do know that i<10 = false.
  443. }
  444. condition:=left.getcopy;
  445. if condition.track_state_pass(exec_known) then
  446. begin
  447. track_state_pass:=true;
  448. {Force new resulttype pass.}
  449. condition.resulttype.def:=nil;
  450. do_resulttypepass(condition);
  451. end;
  452. if not is_constboolnode(condition) then
  453. aktstate.store_fact(condition,
  454. cordconstnode.create(byte(checknegate),booltype,true))
  455. else
  456. condition.destroy;
  457. end;
  458. {$endif}
  459. {*****************************************************************************
  460. TIFNODE
  461. *****************************************************************************}
  462. constructor tifnode.create(l,r,_t1 : tnode);
  463. begin
  464. inherited create(ifn,l,r,_t1,nil);
  465. end;
  466. function tifnode.det_resulttype:tnode;
  467. begin
  468. result:=nil;
  469. resulttype:=voidtype;
  470. resulttypepass(left);
  471. { if path }
  472. if assigned(right) then
  473. resulttypepass(right);
  474. { else path }
  475. if assigned(t1) then
  476. resulttypepass(t1);
  477. set_varstate(left,true);
  478. if codegenerror then
  479. exit;
  480. if not is_boolean(left.resulttype.def) then
  481. Message1(type_e_boolean_expr_expected,left.resulttype.def.typename);
  482. end;
  483. function tifnode.pass_1 : tnode;
  484. var
  485. old_t_times : longint;
  486. hp : tnode;
  487. begin
  488. result:=nil;
  489. expectloc:=LOC_VOID;
  490. old_t_times:=rg.t_times;
  491. rg.cleartempgen;
  492. firstpass(left);
  493. registers32:=left.registers32;
  494. registersfpu:=left.registersfpu;
  495. {$ifdef SUPPORT_MMX}
  496. registersmmx:=left.registersmmx;
  497. {$endif SUPPORT_MMX}
  498. { determines registers weigths }
  499. if not(cs_littlesize in aktglobalswitches) then
  500. rg.t_times:=rg.t_times div 2;
  501. if rg.t_times=0 then
  502. rg.t_times:=1;
  503. { if path }
  504. if assigned(right) then
  505. begin
  506. rg.cleartempgen;
  507. firstpass(right);
  508. if registers32<right.registers32 then
  509. registers32:=right.registers32;
  510. if registersfpu<right.registersfpu then
  511. registersfpu:=right.registersfpu;
  512. {$ifdef SUPPORT_MMX}
  513. if registersmmx<right.registersmmx then
  514. registersmmx:=right.registersmmx;
  515. {$endif SUPPORT_MMX}
  516. end;
  517. { else path }
  518. if assigned(t1) then
  519. begin
  520. rg.cleartempgen;
  521. firstpass(t1);
  522. if registers32<t1.registers32 then
  523. registers32:=t1.registers32;
  524. if registersfpu<t1.registersfpu then
  525. registersfpu:=t1.registersfpu;
  526. {$ifdef SUPPORT_MMX}
  527. if registersmmx<t1.registersmmx then
  528. registersmmx:=t1.registersmmx;
  529. {$endif SUPPORT_MMX}
  530. end;
  531. { leave if we've got an error in one of the paths }
  532. if codegenerror then
  533. exit;
  534. if left.nodetype=ordconstn then
  535. begin
  536. { optimize }
  537. if tordconstnode(left).value=1 then
  538. begin
  539. hp:=right;
  540. right:=nil;
  541. { we cannot set p to nil !!! }
  542. if assigned(hp) then
  543. result:=hp
  544. else
  545. result:=cnothingnode.create;
  546. end
  547. else
  548. begin
  549. hp:=t1;
  550. t1:=nil;
  551. { we cannot set p to nil !!! }
  552. if assigned(hp) then
  553. result:=hp
  554. else
  555. result:=cnothingnode.create;
  556. end;
  557. end;
  558. rg.t_times:=old_t_times;
  559. end;
  560. {*****************************************************************************
  561. TFORNODE
  562. *****************************************************************************}
  563. constructor tfornode.create(l,r,_t1,_t2 : tnode;back : boolean);
  564. begin
  565. inherited create(forn,l,r,_t1,_t2);
  566. if back then
  567. include(loopflags,lnf_backward);
  568. include(loopflags,lnf_testatbegin);
  569. end;
  570. procedure Tfornode.loop_var_access(not_type:Tnotification_flag;
  571. symbol:Tsym);
  572. begin
  573. {If there is a read access, the value of the loop counter is important;
  574. at the end of the loop the loop variable should contain the value it
  575. had in the last iteration.}
  576. if not_type=vn_onwrite then
  577. begin
  578. writeln('Loopvar does not matter on exit');
  579. end
  580. else
  581. begin
  582. exclude(loopflags,lnf_dont_mind_loopvar_on_exit);
  583. writeln('Loopvar does matter on exit');
  584. end;
  585. Tvarsym(symbol).unregister_notification(loopvar_notid);
  586. end;
  587. function tfornode.det_resulttype:tnode;
  588. var
  589. hp : tnode;
  590. begin
  591. result:=nil;
  592. resulttype:=voidtype;
  593. if left.nodetype<>assignn then
  594. begin
  595. CGMessage(cg_e_illegal_expression);
  596. exit;
  597. end;
  598. {Can we spare the first comparision?}
  599. if (right.nodetype=ordconstn) and (Tassignmentnode(left).right.nodetype=ordconstn) then
  600. if (
  601. (lnf_backward in loopflags) and
  602. (Tordconstnode(Tassignmentnode(left).right).value>=Tordconstnode(right).value)
  603. )
  604. or not(
  605. (lnf_backward in loopflags) and
  606. (Tordconstnode(Tassignmentnode(left).right).value<=Tordconstnode(right).value)
  607. ) then
  608. exclude(loopflags,lnf_testatbegin);
  609. { save counter var }
  610. t2:=tassignmentnode(left).left.getcopy;
  611. resulttypepass(left);
  612. set_varstate(left,false);
  613. if assigned(t1) then
  614. begin
  615. resulttypepass(t1);
  616. if codegenerror then
  617. exit;
  618. end;
  619. { process count var }
  620. resulttypepass(t2);
  621. set_varstate(t2,true);
  622. if codegenerror then
  623. exit;
  624. { Check count var, record fields are also allowed in tp7 }
  625. hp:=t2;
  626. while (hp.nodetype=subscriptn) or
  627. ((hp.nodetype=vecn) and
  628. is_constintnode(tvecnode(hp).right)) do
  629. hp:=tunarynode(hp).left;
  630. { we need a simple loadn, but the load must be in a global symtable or
  631. in the same lexlevel }
  632. if (hp.nodetype=funcretn) or
  633. (
  634. (hp.nodetype=loadn) and
  635. (
  636. (tloadnode(hp).symtable.symtablelevel<=1) or
  637. (tloadnode(hp).symtable.symtablelevel=lexlevel)
  638. ) and
  639. not(
  640. (tloadnode(hp).symtableentry.typ=varsym) and
  641. ((tvarsym(tloadnode(hp).symtableentry).varspez in [vs_var,vs_out]) or
  642. (vo_is_thread_var in tvarsym(tloadnode(hp).symtableentry).varoptions))
  643. )
  644. ) then
  645. begin
  646. if (hp.nodetype=loadn) and
  647. (tloadnode(hp).symtableentry.typ=varsym) then
  648. tvarsym(tloadnode(hp).symtableentry).varstate:=vs_used;
  649. if (not(is_ordinal(t2.resulttype.def)) or is_64bitint(t2.resulttype.def)) then
  650. CGMessagePos(hp.fileinfo,type_e_ordinal_expr_expected);
  651. end
  652. else
  653. CGMessagePos(hp.fileinfo,cg_e_illegal_count_var);
  654. resulttypepass(right);
  655. set_varstate(right,true);
  656. inserttypeconv(right,t2.resulttype);
  657. end;
  658. function tfornode.pass_1 : tnode;
  659. var
  660. old_t_times : longint;
  661. {$ifdef loopvar_dont_mind}
  662. hp : Tnode;
  663. {$endif loopvar_dont_mind}
  664. begin
  665. result:=nil;
  666. expectloc:=LOC_VOID;
  667. { Calc register weight }
  668. old_t_times:=rg.t_times;
  669. if not(cs_littlesize in aktglobalswitches) then
  670. rg.t_times:=rg.t_times*8;
  671. rg.cleartempgen;
  672. firstpass(left);
  673. rg.cleartempgen;
  674. if assigned(t1) then
  675. begin
  676. firstpass(t1);
  677. if codegenerror then
  678. exit;
  679. end;
  680. registers32:=t1.registers32;
  681. registersfpu:=t1.registersfpu;
  682. {$ifdef SUPPORT_MMX}
  683. registersmmx:=left.registersmmx;
  684. {$endif SUPPORT_MMX}
  685. if left.registers32>registers32 then
  686. registers32:=left.registers32;
  687. if left.registersfpu>registersfpu then
  688. registersfpu:=left.registersfpu;
  689. {$ifdef SUPPORT_MMX}
  690. if left.registersmmx>registersmmx then
  691. registersmmx:=left.registersmmx;
  692. {$endif SUPPORT_MMX}
  693. { process count var }
  694. rg.cleartempgen;
  695. firstpass(t2);
  696. if codegenerror then
  697. exit;
  698. if t2.registers32>registers32 then
  699. registers32:=t2.registers32;
  700. if t2.registersfpu>registersfpu then
  701. registersfpu:=t2.registersfpu;
  702. {$ifdef SUPPORT_MMX}
  703. if t2.registersmmx>registersmmx then
  704. registersmmx:=t2.registersmmx;
  705. {$endif SUPPORT_MMX}
  706. rg.cleartempgen;
  707. firstpass(right);
  708. {$ifdef loopvar_dont_mind}
  709. { Check count var, record fields are also allowed in tp7 }
  710. include(loopflags,lnf_dont_mind_loopvar_on_exit);
  711. hp:=t2;
  712. while (hp.nodetype=subscriptn) or
  713. ((hp.nodetype=vecn) and
  714. is_constintnode(tvecnode(hp).right)) do
  715. hp:=tunarynode(hp).left;
  716. if (hp.nodetype=loadn) and (Tloadnode(hp).symtableentry.typ=varsym) then
  717. loopvar_notid:=Tvarsym(Tloadnode(hp).symtableentry).
  718. register_notification([vn_onread,vn_onwrite],@loop_var_access);
  719. {$endif}
  720. if right.registers32>registers32 then
  721. registers32:=right.registers32;
  722. if right.registersfpu>registersfpu then
  723. registersfpu:=right.registersfpu;
  724. {$ifdef SUPPORT_MMX}
  725. if right.registersmmx>registersmmx then
  726. registersmmx:=right.registersmmx;
  727. {$endif SUPPORT_MMX}
  728. { we need at least one register for comparisons PM }
  729. if registers32=0 then
  730. inc(registers32);
  731. rg.t_times:=old_t_times;
  732. end;
  733. {*****************************************************************************
  734. TEXITNODE
  735. *****************************************************************************}
  736. constructor texitnode.create(l:tnode);
  737. begin
  738. inherited create(exitn,l);
  739. onlyassign:=false;
  740. end;
  741. constructor texitnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  742. begin
  743. inherited ppuload(t,ppufile);
  744. onlyassign:=boolean(ppufile.getbyte);
  745. end;
  746. procedure texitnode.ppuwrite(ppufile:tcompilerppufile);
  747. begin
  748. inherited ppuwrite(ppufile);
  749. ppufile.putbyte(byte(onlyassign));
  750. end;
  751. function texitnode.det_resulttype:tnode;
  752. var
  753. pt : tnode;
  754. begin
  755. result:=nil;
  756. { Check the 2 types }
  757. if not inlining_procedure then
  758. begin
  759. if assigned(left) then
  760. begin
  761. inserttypeconv(left,aktprocdef.rettype);
  762. if paramanager.ret_in_param(aktprocdef.rettype.def,aktprocdef.proccalloption) or
  763. (procinfo.no_fast_exit) or
  764. ((procinfo.flags and pi_uses_exceptions)<>0) then
  765. begin
  766. pt:=cfuncretnode.create(aktprocdef.funcretsym);
  767. left:=cassignmentnode.create(pt,left);
  768. onlyassign:=true;
  769. end;
  770. tfuncretsym(aktprocdef.funcretsym).funcretstate:=vs_assigned;
  771. end;
  772. end;
  773. if assigned(left) then
  774. begin
  775. resulttypepass(left);
  776. set_varstate(left,true);
  777. end;
  778. resulttype:=voidtype;
  779. end;
  780. function texitnode.pass_1 : tnode;
  781. begin
  782. result:=nil;
  783. expectloc:=LOC_VOID;
  784. if assigned(left) then
  785. begin
  786. firstpass(left);
  787. if codegenerror then
  788. exit;
  789. registers32:=left.registers32;
  790. registersfpu:=left.registersfpu;
  791. {$ifdef SUPPORT_MMX}
  792. registersmmx:=left.registersmmx;
  793. {$endif SUPPORT_MMX}
  794. end;
  795. end;
  796. {*****************************************************************************
  797. TBREAKNODE
  798. *****************************************************************************}
  799. constructor tbreaknode.create;
  800. begin
  801. inherited create(breakn);
  802. end;
  803. function tbreaknode.det_resulttype:tnode;
  804. begin
  805. result:=nil;
  806. resulttype:=voidtype;
  807. end;
  808. function tbreaknode.pass_1 : tnode;
  809. begin
  810. result:=nil;
  811. expectloc:=LOC_VOID;
  812. end;
  813. {*****************************************************************************
  814. TCONTINUENODE
  815. *****************************************************************************}
  816. constructor tcontinuenode.create;
  817. begin
  818. inherited create(continuen);
  819. end;
  820. function tcontinuenode.det_resulttype:tnode;
  821. begin
  822. result:=nil;
  823. resulttype:=voidtype;
  824. end;
  825. function tcontinuenode.pass_1 : tnode;
  826. begin
  827. result:=nil;
  828. expectloc:=LOC_VOID;
  829. end;
  830. {*****************************************************************************
  831. TGOTONODE
  832. *****************************************************************************}
  833. constructor tgotonode.create(p : tlabelsym);
  834. begin
  835. inherited create(goton);
  836. exceptionblock:=aktexceptblock;
  837. labsym:=p;
  838. end;
  839. constructor tgotonode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  840. begin
  841. inherited ppuload(t,ppufile);
  842. labsym:=tlabelsym(ppufile.getderef);
  843. exceptionblock:=ppufile.getbyte;
  844. end;
  845. procedure tgotonode.ppuwrite(ppufile:tcompilerppufile);
  846. begin
  847. inherited ppuwrite(ppufile);
  848. ppufile.putderef(labsym);
  849. ppufile.putbyte(exceptionblock);
  850. end;
  851. procedure tgotonode.derefimpl;
  852. begin
  853. inherited derefimpl;
  854. resolvesym(pointer(labsym));
  855. end;
  856. function tgotonode.det_resulttype:tnode;
  857. begin
  858. result:=nil;
  859. resulttype:=voidtype;
  860. end;
  861. function tgotonode.pass_1 : tnode;
  862. begin
  863. result:=nil;
  864. expectloc:=LOC_VOID;
  865. { check if }
  866. if assigned(labsym) and
  867. assigned(labsym.code) and
  868. (exceptionblock<>tlabelnode(labsym.code).exceptionblock) then
  869. begin
  870. writeln('goto exceptblock: ',exceptionblock);
  871. writeln('label exceptblock: ',tlabelnode(labsym.code).exceptionblock);
  872. CGMessage(cg_e_goto_inout_of_exception_block);
  873. end;
  874. end;
  875. function tgotonode.getcopy : tnode;
  876. var
  877. p : tgotonode;
  878. begin
  879. p:=tgotonode(inherited getcopy);
  880. p.labsym:=labsym;
  881. p.exceptionblock:=exceptionblock;
  882. result:=p;
  883. end;
  884. function tgotonode.docompare(p: tnode): boolean;
  885. begin
  886. docompare := false;
  887. end;
  888. {*****************************************************************************
  889. TLABELNODE
  890. *****************************************************************************}
  891. constructor tlabelnode.createcase(p : tasmlabel;l:tnode);
  892. begin
  893. inherited create(labeln,l);
  894. { it shouldn't be possible to jump to case labels using goto }
  895. exceptionblock:=-1;
  896. labsym:=nil;
  897. labelnr:=p;
  898. end;
  899. constructor tlabelnode.create(p : tlabelsym;l:tnode);
  900. begin
  901. inherited create(labeln,l);
  902. exceptionblock:=aktexceptblock;
  903. labsym:=p;
  904. labelnr:=p.lab;
  905. { save the current labelnode in the labelsym }
  906. p.code:=self;
  907. end;
  908. constructor tlabelnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  909. begin
  910. inherited ppuload(t,ppufile);
  911. labsym:=tlabelsym(ppufile.getderef);
  912. labelnr:=tasmlabel(ppufile.getasmsymbol);
  913. exceptionblock:=ppufile.getbyte;
  914. end;
  915. procedure tlabelnode.ppuwrite(ppufile:tcompilerppufile);
  916. begin
  917. inherited ppuwrite(ppufile);
  918. ppufile.putderef(labsym);
  919. ppufile.putasmsymbol(labelnr);
  920. ppufile.putbyte(exceptionblock);
  921. end;
  922. procedure tlabelnode.derefimpl;
  923. begin
  924. inherited derefimpl;
  925. resolvesym(pointer(labsym));
  926. objectlibrary.derefasmsymbol(tasmsymbol(labelnr));
  927. end;
  928. function tlabelnode.det_resulttype:tnode;
  929. begin
  930. result:=nil;
  931. { left could still be unassigned }
  932. if assigned(left) then
  933. resulttypepass(left);
  934. resulttype:=voidtype;
  935. end;
  936. function tlabelnode.pass_1 : tnode;
  937. begin
  938. result:=nil;
  939. expectloc:=LOC_VOID;
  940. if assigned(left) then
  941. begin
  942. rg.cleartempgen;
  943. firstpass(left);
  944. registers32:=left.registers32;
  945. registersfpu:=left.registersfpu;
  946. {$ifdef SUPPORT_MMX}
  947. registersmmx:=left.registersmmx;
  948. {$endif SUPPORT_MMX}
  949. end;
  950. end;
  951. function tlabelnode.getcopy : tnode;
  952. var
  953. p : tlabelnode;
  954. begin
  955. p:=tlabelnode(inherited getcopy);
  956. p.labelnr:=labelnr;
  957. p.exceptionblock:=exceptionblock;
  958. p.labsym:=labsym;
  959. result:=p;
  960. end;
  961. function tlabelnode.docompare(p: tnode): boolean;
  962. begin
  963. docompare := false;
  964. end;
  965. {*****************************************************************************
  966. TRAISENODE
  967. *****************************************************************************}
  968. constructor traisenode.create(l,taddr,tframe:tnode);
  969. begin
  970. inherited create(raisen,l,taddr);
  971. frametree:=tframe;
  972. end;
  973. constructor traisenode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  974. begin
  975. inherited ppuload(t,ppufile);
  976. frametree:=ppuloadnode(ppufile);
  977. end;
  978. procedure traisenode.ppuwrite(ppufile:tcompilerppufile);
  979. begin
  980. inherited ppuwrite(ppufile);
  981. ppuwritenode(ppufile,frametree);
  982. end;
  983. procedure traisenode.derefimpl;
  984. begin
  985. inherited derefimpl;
  986. if assigned(frametree) then
  987. frametree.derefimpl;
  988. end;
  989. function traisenode.getcopy : tnode;
  990. var
  991. n : traisenode;
  992. begin
  993. n:=traisenode(inherited getcopy);
  994. if assigned(frametree) then
  995. n.frametree:=frametree.getcopy
  996. else
  997. n.frametree:=nil;
  998. getcopy:=n;
  999. end;
  1000. procedure traisenode.insertintolist(l : tnodelist);
  1001. begin
  1002. end;
  1003. function traisenode.det_resulttype:tnode;
  1004. begin
  1005. result:=nil;
  1006. resulttype:=voidtype;
  1007. if assigned(left) then
  1008. begin
  1009. { first para must be a _class_ }
  1010. resulttypepass(left);
  1011. set_varstate(left,true);
  1012. if codegenerror then
  1013. exit;
  1014. if not(is_class(left.resulttype.def)) then
  1015. CGMessage(type_e_mismatch);
  1016. { insert needed typeconvs for addr,frame }
  1017. if assigned(right) then
  1018. begin
  1019. { addr }
  1020. resulttypepass(right);
  1021. inserttypeconv(right,voidpointertype);
  1022. { frame }
  1023. if assigned(frametree) then
  1024. begin
  1025. resulttypepass(frametree);
  1026. inserttypeconv(frametree,voidpointertype);
  1027. end;
  1028. end;
  1029. end;
  1030. end;
  1031. function traisenode.pass_1 : tnode;
  1032. begin
  1033. result:=nil;
  1034. expectloc:=LOC_VOID;
  1035. if assigned(left) then
  1036. begin
  1037. { first para must be a _class_ }
  1038. firstpass(left);
  1039. { insert needed typeconvs for addr,frame }
  1040. if assigned(right) then
  1041. begin
  1042. { addr }
  1043. firstpass(right);
  1044. { frame }
  1045. if assigned(frametree) then
  1046. firstpass(frametree);
  1047. end;
  1048. left_right_max;
  1049. end;
  1050. end;
  1051. function traisenode.docompare(p: tnode): boolean;
  1052. begin
  1053. docompare := false;
  1054. end;
  1055. {*****************************************************************************
  1056. TTRYEXCEPTNODE
  1057. *****************************************************************************}
  1058. constructor ttryexceptnode.create(l,r,_t1 : tnode);
  1059. begin
  1060. inherited create(tryexceptn,l,r,_t1,nil);
  1061. end;
  1062. function ttryexceptnode.det_resulttype:tnode;
  1063. begin
  1064. result:=nil;
  1065. resulttypepass(left);
  1066. { on statements }
  1067. if assigned(right) then
  1068. resulttypepass(right);
  1069. { else block }
  1070. if assigned(t1) then
  1071. resulttypepass(t1);
  1072. resulttype:=voidtype;
  1073. end;
  1074. function ttryexceptnode.pass_1 : tnode;
  1075. begin
  1076. result:=nil;
  1077. expectloc:=LOC_VOID;
  1078. rg.cleartempgen;
  1079. firstpass(left);
  1080. { on statements }
  1081. if assigned(right) then
  1082. begin
  1083. rg.cleartempgen;
  1084. firstpass(right);
  1085. registers32:=max(registers32,right.registers32);
  1086. registersfpu:=max(registersfpu,right.registersfpu);
  1087. {$ifdef SUPPORT_MMX}
  1088. registersmmx:=max(registersmmx,right.registersmmx);
  1089. {$endif SUPPORT_MMX}
  1090. end;
  1091. { else block }
  1092. if assigned(t1) then
  1093. begin
  1094. firstpass(t1);
  1095. registers32:=max(registers32,t1.registers32);
  1096. registersfpu:=max(registersfpu,t1.registersfpu);
  1097. {$ifdef SUPPORT_MMX}
  1098. registersmmx:=max(registersmmx,t1.registersmmx);
  1099. {$endif SUPPORT_MMX}
  1100. end;
  1101. end;
  1102. {*****************************************************************************
  1103. TTRYFINALLYNODE
  1104. *****************************************************************************}
  1105. constructor ttryfinallynode.create(l,r:tnode);
  1106. begin
  1107. inherited create(tryfinallyn,l,r);
  1108. end;
  1109. function ttryfinallynode.det_resulttype:tnode;
  1110. begin
  1111. result:=nil;
  1112. resulttype:=voidtype;
  1113. resulttypepass(left);
  1114. set_varstate(left,true);
  1115. resulttypepass(right);
  1116. set_varstate(right,true);
  1117. end;
  1118. function ttryfinallynode.pass_1 : tnode;
  1119. begin
  1120. result:=nil;
  1121. expectloc:=LOC_VOID;
  1122. rg.cleartempgen;
  1123. firstpass(left);
  1124. rg.cleartempgen;
  1125. firstpass(right);
  1126. left_right_max;
  1127. end;
  1128. {*****************************************************************************
  1129. TONNODE
  1130. *****************************************************************************}
  1131. constructor tonnode.create(l,r:tnode);
  1132. begin
  1133. inherited create(onn,l,r);
  1134. exceptsymtable:=nil;
  1135. excepttype:=nil;
  1136. end;
  1137. destructor tonnode.destroy;
  1138. begin
  1139. if assigned(exceptsymtable) then
  1140. exceptsymtable.free;
  1141. inherited destroy;
  1142. end;
  1143. constructor tonnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  1144. begin
  1145. inherited ppuload(t,ppufile);
  1146. exceptsymtable:=nil;
  1147. excepttype:=nil;
  1148. end;
  1149. function tonnode.getcopy : tnode;
  1150. var
  1151. n : tonnode;
  1152. begin
  1153. n:=tonnode(inherited getcopy);
  1154. n.exceptsymtable:=exceptsymtable;
  1155. n.excepttype:=excepttype;
  1156. result:=n;
  1157. end;
  1158. function tonnode.det_resulttype:tnode;
  1159. begin
  1160. result:=nil;
  1161. resulttype:=voidtype;
  1162. if not(is_class(excepttype)) then
  1163. CGMessage(type_e_mismatch);
  1164. if assigned(left) then
  1165. resulttypepass(left);
  1166. if assigned(right) then
  1167. resulttypepass(right);
  1168. end;
  1169. function tonnode.pass_1 : tnode;
  1170. begin
  1171. result:=nil;
  1172. expectloc:=LOC_VOID;
  1173. rg.cleartempgen;
  1174. registers32:=0;
  1175. registersfpu:=0;
  1176. {$ifdef SUPPORT_MMX}
  1177. registersmmx:=0;
  1178. {$endif SUPPORT_MMX}
  1179. if assigned(left) then
  1180. begin
  1181. firstpass(left);
  1182. registers32:=left.registers32;
  1183. registersfpu:=left.registersfpu;
  1184. {$ifdef SUPPORT_MMX}
  1185. registersmmx:=left.registersmmx;
  1186. {$endif SUPPORT_MMX}
  1187. end;
  1188. rg.cleartempgen;
  1189. if assigned(right) then
  1190. begin
  1191. firstpass(right);
  1192. registers32:=max(registers32,right.registers32);
  1193. registersfpu:=max(registersfpu,right.registersfpu);
  1194. {$ifdef SUPPORT_MMX}
  1195. registersmmx:=max(registersmmx,right.registersmmx);
  1196. {$endif SUPPORT_MMX}
  1197. end;
  1198. end;
  1199. function tonnode.docompare(p: tnode): boolean;
  1200. begin
  1201. docompare := false;
  1202. end;
  1203. {*****************************************************************************
  1204. TFAILNODE
  1205. *****************************************************************************}
  1206. constructor tfailnode.create;
  1207. begin
  1208. inherited create(failn);
  1209. end;
  1210. function tfailnode.det_resulttype:tnode;
  1211. begin
  1212. result:=nil;
  1213. resulttype:=voidtype;
  1214. end;
  1215. function tfailnode.pass_1 : tnode;
  1216. begin
  1217. result:=nil;
  1218. expectloc:=LOC_VOID;
  1219. end;
  1220. function tfailnode.docompare(p: tnode): boolean;
  1221. begin
  1222. docompare := false;
  1223. end;
  1224. begin
  1225. cwhilerepeatnode:=twhilerepeatnode;
  1226. cifnode:=tifnode;
  1227. cfornode:=tfornode;
  1228. cexitnode:=texitnode;
  1229. cgotonode:=tgotonode;
  1230. clabelnode:=tlabelnode;
  1231. craisenode:=traisenode;
  1232. ctryexceptnode:=ttryexceptnode;
  1233. ctryfinallynode:=ttryfinallynode;
  1234. connode:=tonnode;
  1235. cfailnode:=tfailnode;
  1236. end.
  1237. {
  1238. $Log$
  1239. Revision 1.66 2003-04-22 23:50:23 peter
  1240. * firstpass uses expectloc
  1241. * checks if there are differences between the expectloc and
  1242. location.loc from secondpass in EXTDEBUG
  1243. Revision 1.65 2003/03/20 15:54:46 peter
  1244. * don't allow var and out parameters as for loop counter
  1245. Revision 1.64 2003/01/09 21:52:37 peter
  1246. * merged some verbosity options.
  1247. * V_LineInfo is a verbosity flag to include line info
  1248. Revision 1.63 2003/01/04 08:08:47 daniel
  1249. * Readded missing variable
  1250. Revision 1.62 2003/01/03 17:16:57 peter
  1251. * fixed warning about unset funcret
  1252. Revision 1.61 2003/01/03 12:15:56 daniel
  1253. * Removed ifdefs around notifications
  1254. ifdefs around for loop optimizations remain
  1255. Revision 1.60 2002/12/31 09:55:58 daniel
  1256. + Notification implementation complete
  1257. + Add for loop code optimization using notifications
  1258. results in 1.5-1.9% speed improvement in nestloop benchmark
  1259. Optimization incomplete, compiler does not cycle yet with
  1260. notifications enabled.
  1261. Revision 1.59 2002/12/30 22:44:53 daniel
  1262. * Some work on notifications
  1263. Revision 1.58 2002/12/27 15:25:40 peter
  1264. * do not allow threadvar as loop counter
  1265. Revision 1.57 2002/11/28 11:17:02 florian
  1266. * loop node flags from node flags splitted
  1267. Revision 1.56 2002/11/25 17:43:18 peter
  1268. * splitted defbase in defutil,symutil,defcmp
  1269. * merged isconvertable and is_equal into compare_defs(_ext)
  1270. * made operator search faster by walking the list only once
  1271. Revision 1.55 2002/11/18 17:31:56 peter
  1272. * pass proccalloption to ret_in_xxx and push_xxx functions
  1273. Revision 1.54 2002/10/20 15:31:49 peter
  1274. * set funcret state for exit(0)
  1275. Revision 1.53 2002/10/05 12:43:25 carl
  1276. * fixes for Delphi 6 compilation
  1277. (warning : Some features do not work under Delphi)
  1278. Revision 1.52 2002/09/07 15:25:03 peter
  1279. * old logs removed and tabs fixed
  1280. Revision 1.51 2002/09/07 12:16:04 carl
  1281. * second part bug report 1996 fix, testrange in cordconstnode
  1282. only called if option is set (also make parsing a tiny faster)
  1283. Revision 1.50 2002/09/01 18:47:00 peter
  1284. * assignn check in exitnode changed to use a separate boolean as the
  1285. assignn can be changed to a calln
  1286. Revision 1.49 2002/09/01 08:01:16 daniel
  1287. * Removed sets from Tcallnode.det_resulttype
  1288. + Added read/write notifications of variables. These will be usefull
  1289. for providing information for several optimizations. For example
  1290. the value of the loop variable of a for loop does matter is the
  1291. variable is read after the for loop, but if it's no longer used
  1292. or written, it doesn't matter and this can be used to optimize
  1293. the loop code generation.
  1294. Revision 1.48 2002/08/22 15:15:20 daniel
  1295. * Fixed the detection wether the first check of a for loop can be skipped
  1296. Revision 1.47 2002/08/19 19:36:43 peter
  1297. * More fixes for cross unit inlining, all tnodes are now implemented
  1298. * Moved pocall_internconst to po_internconst because it is not a
  1299. calling type at all and it conflicted when inlining of these small
  1300. functions was requested
  1301. Revision 1.46 2002/08/17 22:09:46 florian
  1302. * result type handling in tcgcal.pass_2 overhauled
  1303. * better tnode.dowrite
  1304. * some ppc stuff fixed
  1305. Revision 1.45 2002/08/17 09:23:37 florian
  1306. * first part of procinfo rewrite
  1307. Revision 1.44 2002/07/21 06:58:49 daniel
  1308. * Changed booleans into flags
  1309. Revision 1.43 2002/07/20 11:57:54 florian
  1310. * types.pas renamed to defbase.pas because D6 contains a types
  1311. unit so this would conflicts if D6 programms are compiled
  1312. + Willamette/SSE2 instructions to assembler added
  1313. Revision 1.42 2002/07/20 11:18:18 daniel
  1314. * Small mistake fixed; the skip test was done before we know the for node
  1315. is correct.
  1316. Revision 1.40 2002/07/20 08:19:31 daniel
  1317. * State tracker automatically changes while loops into repeat loops
  1318. Revision 1.39 2002/07/19 12:55:27 daniel
  1319. * Further developed state tracking in whilerepeatn
  1320. Revision 1.38 2002/07/19 11:41:35 daniel
  1321. * State tracker work
  1322. * The whilen and repeatn are now completely unified into whilerepeatn. This
  1323. allows the state tracker to change while nodes automatically into
  1324. repeat nodes.
  1325. * Resulttypepass improvements to the notn. 'not not a' is optimized away and
  1326. 'not(a>b)' is optimized into 'a<=b'.
  1327. * Resulttypepass improvements to the whilerepeatn. 'while not a' is optimized
  1328. by removing the notn and later switchting the true and falselabels. The
  1329. same is done with 'repeat until not a'.
  1330. Revision 1.37 2002/07/16 13:57:02 florian
  1331. * raise takes now a void pointer as at and frame address
  1332. instead of a longint
  1333. Revision 1.36 2002/07/15 18:03:15 florian
  1334. * readded removed changes
  1335. Revision 1.35 2002/07/14 18:00:44 daniel
  1336. + Added the beginning of a state tracker. This will track the values of
  1337. variables through procedures and optimize things away.
  1338. Revision 1.34 2002/07/11 14:41:28 florian
  1339. * start of the new generic parameter handling
  1340. Revision 1.33 2002/07/01 18:46:23 peter
  1341. * internal linker
  1342. * reorganized aasm layer
  1343. Revision 1.32 2002/05/18 13:34:10 peter
  1344. * readded missing revisions
  1345. Revision 1.31 2002/05/16 19:46:38 carl
  1346. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  1347. + try to fix temp allocation (still in ifdef)
  1348. + generic constructor calls
  1349. + start of tassembler / tmodulebase class cleanup
  1350. }