nflw.pas 48 KB

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