nflw.pas 45 KB

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