nflw.pas 49 KB

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