optutils.pas 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. {
  2. Helper routines for the optimizer
  3. Copyright (c) 2007 by Florian Klaempfl
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. unit optutils;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. cclasses,
  22. node;
  23. type
  24. { this implementation should be really improved,
  25. its purpose is to find equal nodes }
  26. TIndexedNodeSet = class(TFPList)
  27. function Add(node : tnode) : boolean;
  28. function Includes(node : tnode) : tnode;
  29. function Remove(node : tnode) : boolean;
  30. end;
  31. procedure SetNodeSucessors(p : tnode);
  32. procedure PrintDFAInfo(var f : text;p : tnode);
  33. procedure PrintIndexedNodeSet(var f : text;s : TIndexedNodeSet);
  34. implementation
  35. uses
  36. verbose,
  37. optbase,
  38. nbas,nflw,nutils,nset;
  39. function TIndexedNodeSet.Add(node : tnode) : boolean;
  40. var
  41. i : Integer;
  42. p : tnode;
  43. begin
  44. node.allocoptinfo;
  45. p:=Includes(node);
  46. if assigned(p) then
  47. begin
  48. result:=false;
  49. node.optinfo^.index:=p.optinfo^.index;
  50. end
  51. else
  52. begin
  53. i:=inherited Add(node);
  54. node.optinfo^.index:=i;
  55. result:=true;
  56. end
  57. end;
  58. function TIndexedNodeSet.Includes(node : tnode) : tnode;
  59. var
  60. i : longint;
  61. begin
  62. for i:=0 to Count-1 do
  63. if tnode(List^[i]).isequal(node) then
  64. begin
  65. result:=tnode(List^[i]);
  66. exit;
  67. end;
  68. result:=nil;
  69. end;
  70. function TIndexedNodeSet.Remove(node : tnode) : boolean;
  71. var
  72. p : tnode;
  73. begin
  74. result:=false;
  75. p:=Includes(node);
  76. if assigned(p) then
  77. begin
  78. if inherited Remove(p)<>-1 then
  79. result:=true;
  80. end;
  81. end;
  82. procedure PrintIndexedNodeSet(var f : text;s : TIndexedNodeSet);
  83. var
  84. i : integer;
  85. begin
  86. for i:=0 to s.count-1 do
  87. begin
  88. writeln(f,'=============================== Node ',i,' ===============================');
  89. printnode(f,tnode(s[i]));
  90. writeln(f);
  91. end;
  92. end;
  93. function PrintNodeDFA(var n: tnode; arg: pointer): foreachnoderesult;
  94. begin
  95. if assigned(n.optinfo) and ((n.optinfo^.life<>nil) or (n.optinfo^.use<>nil) or (n.optinfo^.def<>nil)) then
  96. begin
  97. write(text(arg^),nodetype2str[n.nodetype],'(',n.fileinfo.line,',',n.fileinfo.column,') Life: ');
  98. PrintDFASet(text(arg^),n.optinfo^.life);
  99. write(text(arg^),' Def: ');
  100. PrintDFASet(text(arg^),n.optinfo^.def);
  101. write(text(arg^),' Use: ');
  102. PrintDFASet(text(arg^),n.optinfo^.use);
  103. writeln(text(arg^));
  104. end;
  105. result:=fen_false;
  106. end;
  107. procedure PrintDFAInfo(var f : text;p : tnode);
  108. begin
  109. foreachnodestatic(pm_postprocess,p,@PrintNodeDFA,@f);
  110. end;
  111. procedure SetNodeSucessors(p : tnode);
  112. var
  113. Continuestack : TFPList;
  114. Breakstack : TFPList;
  115. { sets the successor nodes of a node tree block
  116. returns the first node of the tree if it's a controll flow node }
  117. function DoSet(p : tnode;succ : tnode) : tnode;
  118. var
  119. hp1,hp2 : tnode;
  120. i : longint;
  121. begin
  122. result:=nil;
  123. if p=nil then
  124. exit;
  125. case p.nodetype of
  126. statementn:
  127. begin
  128. hp1:=p;
  129. result:=p;
  130. while assigned(hp1) do
  131. begin
  132. { does another statement follow? }
  133. if assigned(tstatementnode(hp1).next) then
  134. begin
  135. hp2:=DoSet(tstatementnode(hp1).statement,tstatementnode(hp1).next);
  136. if assigned(hp2) then
  137. tstatementnode(hp1).successor:=hp2
  138. else
  139. tstatementnode(hp1).successor:=tstatementnode(hp1).next;
  140. end
  141. else
  142. begin
  143. hp2:=DoSet(tstatementnode(hp1).statement,succ);
  144. if assigned(hp2) then
  145. tstatementnode(hp1).successor:=hp2
  146. else
  147. tstatementnode(hp1).successor:=succ;
  148. end;
  149. hp1:=tstatementnode(hp1).next;
  150. end;
  151. end;
  152. blockn:
  153. begin
  154. result:=p;
  155. DoSet(tblocknode(p).statements,succ);
  156. p.successor:=succ;
  157. end;
  158. forn:
  159. begin
  160. Breakstack.Add(succ);
  161. Continuestack.Add(p);
  162. result:=p;
  163. { the successor of the last node of the for body is the for node itself }
  164. DoSet(tfornode(p).t2,p);
  165. Breakstack.Delete(Breakstack.Count-1);
  166. Continuestack.Delete(Continuestack.Count-1);
  167. end;
  168. breakn:
  169. begin
  170. result:=p;
  171. p.successor:=tnode(Breakstack.Last);
  172. end;
  173. continuen:
  174. begin
  175. result:=p;
  176. p.successor:=tnode(Continuestack.Last);
  177. end;
  178. whilerepeatn:
  179. begin
  180. Breakstack.Add(succ);
  181. Continuestack.Add(p);
  182. result:=p;
  183. { the successor of the last node of the for body is the while node itself }
  184. DoSet(twhilerepeatnode(p).right,p);
  185. p.successor:=succ;
  186. Breakstack.Delete(Breakstack.Count-1);
  187. Continuestack.Delete(Continuestack.Count-1);
  188. end;
  189. ifn:
  190. begin
  191. result:=p;
  192. DoSet(tifnode(p).right,succ);
  193. DoSet(tifnode(p).t1,succ);
  194. p.successor:=succ;
  195. end;
  196. labeln:
  197. begin
  198. result:=p;
  199. if assigned(tlabelnode(p).left) then
  200. begin
  201. DoSet(tlabelnode(p).left,succ);
  202. p.successor:=tlabelnode(p).left;
  203. end
  204. else
  205. p.successor:=succ;
  206. end;
  207. assignn:
  208. begin
  209. result:=p;
  210. p.successor:=succ;
  211. end;
  212. goton:
  213. begin
  214. result:=p;
  215. if not(assigned(tgotonode(p).labelnode)) then
  216. internalerror(2007050701);
  217. p.successor:=tgotonode(p).labelnode;
  218. end;
  219. exitn:
  220. begin
  221. result:=p;
  222. p.successor:=nil;
  223. end;
  224. casen:
  225. begin
  226. result:=p;
  227. DoSet(tcasenode(p).elseblock,succ);
  228. for i:=0 to tcasenode(p).blocks.count-1 do
  229. DoSet(pcaseblock(tcasenode(p).blocks[i])^.statement,succ);
  230. p.successor:=succ;
  231. end;
  232. calln:
  233. begin
  234. { not sure if this is enough (FK) }
  235. result:=p;
  236. p.successor:=succ;
  237. end;
  238. inlinen:
  239. begin
  240. { not sure if this is enough (FK) }
  241. result:=p;
  242. p.successor:=succ;
  243. end;
  244. tempcreaten,
  245. tempdeleten,
  246. nothingn:
  247. begin
  248. result:=p;
  249. p.successor:=succ;
  250. end;
  251. raisen:
  252. begin
  253. result:=p;
  254. { raise never returns }
  255. p.successor:=nil;
  256. end;
  257. withn,
  258. tryexceptn,
  259. tryfinallyn,
  260. onn:
  261. internalerror(2007050501);
  262. end;
  263. end;
  264. begin
  265. Breakstack:=TFPList.Create;
  266. Continuestack:=TFPList.Create;
  267. DoSet(p,nil);
  268. Continuestack.Free;
  269. Breakstack.Free;
  270. end;
  271. end.