noop.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. #include "l.h"
  2. void
  3. noops(void)
  4. {
  5. Prog *p, *q, *q1;
  6. int o, curframe, curbecome, maxbecome;
  7. /*
  8. * find leaf subroutines
  9. * become sizes
  10. * frame sizes
  11. * strip NOPs
  12. * expand RET
  13. * expand BECOME pseudo
  14. */
  15. if(debug['v'])
  16. Bprint(&bso, "%5.2f noops\n", cputime());
  17. Bflush(&bso);
  18. curframe = 0;
  19. curbecome = 0;
  20. maxbecome = 0;
  21. curtext = 0;
  22. q = P;
  23. for(p = firstp; p != P; p = p->link) {
  24. /* find out how much arg space is used in this TEXT */
  25. if(p->to.type == D_OREG && p->to.reg == REGSP)
  26. if(p->to.offset > curframe)
  27. curframe = p->to.offset;
  28. switch(p->as) {
  29. case ATEXT:
  30. if(curtext && curtext->from.sym) {
  31. curtext->from.sym->frame = curframe;
  32. curtext->from.sym->become = curbecome;
  33. if(curbecome > maxbecome)
  34. maxbecome = curbecome;
  35. }
  36. curframe = 0;
  37. curbecome = 0;
  38. p->mark |= LABEL|LEAF|SYNC;
  39. if(p->link)
  40. p->link->mark |= LABEL;
  41. curtext = p;
  42. break;
  43. /* too hard, just leave alone */
  44. case AMOVW:
  45. case AMOV:
  46. if(p->to.type == D_CTLREG) {
  47. p->mark |= LABEL|SYNC;
  48. break;
  49. }
  50. if(p->from.type == D_CTLREG) {
  51. p->mark |= LABEL|SYNC;
  52. break;
  53. }
  54. break;
  55. /* too hard, just leave alone */
  56. case ASYS:
  57. case AWORD:
  58. p->mark |= LABEL|SYNC;
  59. break;
  60. case ARET:
  61. /* special form of RET is BECOME */
  62. if(p->from.type == D_CONST)
  63. if(p->from.offset > curbecome)
  64. curbecome = p->from.offset;
  65. if(p->link != P)
  66. p->link->mark |= LABEL;
  67. break;
  68. case ANOP:
  69. q1 = p->link;
  70. q->link = q1; /* q is non-nop */
  71. q1->mark |= p->mark;
  72. continue;
  73. case AJAL:
  74. if(curtext != P)
  75. curtext->mark &= ~LEAF;
  76. case AJMP:
  77. case ABEQ:
  78. case ABGE:
  79. case ABGEU:
  80. case ABLT:
  81. case ABLTU:
  82. case ABNE:
  83. p->mark |= BRANCH;
  84. q1 = p->cond;
  85. if(q1 != P) {
  86. while(q1->as == ANOP) {
  87. q1 = q1->link;
  88. p->cond = q1;
  89. }
  90. if(!(q1->mark & LEAF))
  91. q1->mark |= LABEL;
  92. } else
  93. p->mark |= LABEL;
  94. q1 = p->link;
  95. if(q1 != P)
  96. q1->mark |= LABEL;
  97. break;
  98. }
  99. q = p;
  100. }
  101. if(curtext && curtext->from.sym) {
  102. curtext->from.sym->frame = curframe;
  103. curtext->from.sym->become = curbecome;
  104. if(curbecome > maxbecome)
  105. maxbecome = curbecome;
  106. }
  107. if(debug['b'])
  108. print("max become = %d\n", maxbecome);
  109. xdefine("ALEFbecome", STEXT, maxbecome);
  110. curtext = 0;
  111. for(p = firstp; p != P; p = p->link) {
  112. switch(p->as) {
  113. case ATEXT:
  114. curtext = p;
  115. break;
  116. case AJAL:
  117. if(curtext != P && curtext->from.sym != S && curtext->to.offset >= 0) {
  118. o = maxbecome - curtext->from.sym->frame;
  119. if(o <= 0)
  120. break;
  121. /* calling a become or calling a variable */
  122. if(p->to.sym == S || p->to.sym->become) {
  123. curtext->to.offset += o;
  124. if(debug['b']) {
  125. curp = p;
  126. print("%D calling %D increase %d\n",
  127. &curtext->from, &p->to, o);
  128. }
  129. }
  130. }
  131. break;
  132. }
  133. }
  134. for(p = firstp; p != P; p = p->link) {
  135. o = p->as;
  136. switch(o) {
  137. case ATEXT:
  138. curtext = p;
  139. autosize = p->to.offset + ptrsize;
  140. if(autosize <= ptrsize) {
  141. if(curtext->mark & LEAF || autosize <= 0) {
  142. p->to.offset = -ptrsize;
  143. autosize = 0;
  144. } else if(ptrsize == 4) {
  145. p->to.offset = 4;
  146. autosize = 8;
  147. }
  148. }
  149. q = p;
  150. if(autosize) {
  151. q = prg();
  152. q->as = AADD;
  153. q->line = p->line;
  154. q->from.type = D_CONST;
  155. q->from.offset = -autosize;
  156. q->to.type = D_REG;
  157. q->to.reg = REGSP;
  158. q->link = p->link;
  159. p->link = q;
  160. } else
  161. if(!(curtext->mark & LEAF)) {
  162. if(debug['v'])
  163. Bprint(&bso, "save suppressed in: %s\n",
  164. curtext->from.sym->name);
  165. Bflush(&bso);
  166. curtext->mark |= LEAF;
  167. }
  168. if(curtext->mark & LEAF) {
  169. if(curtext->from.sym)
  170. curtext->from.sym->type = SLEAF;
  171. break;
  172. }
  173. q1 = prg();
  174. q1->as = thechar == 'j' ? AMOV : AMOVW;
  175. q1->line = p->line;
  176. q1->from.type = D_REG;
  177. q1->from.reg = REGLINK;
  178. q1->to.type = D_OREG;
  179. q1->from.offset = 0;
  180. q1->to.reg = REGSP;
  181. q1->link = q->link;
  182. q->link = q1;
  183. break;
  184. case ARET:
  185. nocache(p);
  186. if(p->from.type == D_CONST)
  187. goto become;
  188. if(curtext->mark & LEAF) {
  189. if(!autosize) {
  190. p->as = AJMP;
  191. p->from = zprg.from;
  192. p->to.type = D_OREG;
  193. p->to.offset = 0;
  194. p->to.reg = REGLINK;
  195. p->mark |= BRANCH;
  196. break;
  197. }
  198. p->as = AADD;
  199. p->from.type = D_CONST;
  200. p->from.offset = autosize;
  201. p->to.type = D_REG;
  202. p->to.reg = REGSP;
  203. q = prg();
  204. q->as = AJMP;
  205. q->line = p->line;
  206. q->to.type = D_OREG;
  207. q->to.offset = 0;
  208. q->to.reg = REGLINK;
  209. q->mark |= BRANCH;
  210. q->link = p->link;
  211. p->link = q;
  212. break;
  213. }
  214. p->as = thechar == 'j' ? AMOV : AMOVW;
  215. p->from.type = D_OREG;
  216. p->from.offset = 0;
  217. p->from.reg = REGSP;
  218. p->to.type = D_REG;
  219. p->to.reg = REGLINK;
  220. q = p;
  221. if(autosize) {
  222. q = prg();
  223. q->as = AADD;
  224. q->line = p->line;
  225. q->from.type = D_CONST;
  226. q->from.offset = autosize;
  227. q->to.type = D_REG;
  228. q->to.reg = REGSP;
  229. q->link = p->link;
  230. p->link = q;
  231. }
  232. q1 = prg();
  233. q1->as = AJMP;
  234. q1->line = p->line;
  235. q1->to.type = D_OREG;
  236. q1->to.offset = 0;
  237. q1->to.reg = REGLINK;
  238. q1->mark |= BRANCH;
  239. q1->link = q->link;
  240. q->link = q1;
  241. break;
  242. become:
  243. if(curtext->mark & LEAF) {
  244. q = prg();
  245. q->line = p->line;
  246. q->as = AJMP;
  247. q->from = zprg.from;
  248. q->to = p->to;
  249. q->cond = p->cond;
  250. q->link = p->link;
  251. q->mark |= BRANCH;
  252. p->link = q;
  253. p->as = AADD;
  254. p->from = zprg.from;
  255. p->from.type = D_CONST;
  256. p->from.offset = autosize;
  257. p->to = zprg.to;
  258. p->to.type = D_REG;
  259. p->to.reg = REGSP;
  260. break;
  261. }
  262. q = prg();
  263. q->line = p->line;
  264. q->as = AJMP;
  265. q->from = zprg.from;
  266. q->to = p->to;
  267. q->cond = p->cond;
  268. q->link = p->link;
  269. q->mark |= BRANCH;
  270. p->link = q;
  271. q = prg();
  272. q->line = p->line;
  273. q->as = AADD;
  274. q->from.type = D_CONST;
  275. q->from.offset = autosize;
  276. q->to.type = D_REG;
  277. q->to.reg = REGSP;
  278. q->link = p->link;
  279. p->link = q;
  280. p->as = thechar == 'j' ? AMOV : AMOVW;
  281. p->from = zprg.from;
  282. p->from.type = D_OREG;
  283. p->from.offset = 0;
  284. p->from.reg = REGSP;
  285. p->to = zprg.to;
  286. p->to.type = D_REG;
  287. p->to.reg = REGLINK;
  288. break;
  289. }
  290. }
  291. curtext = P;
  292. }
  293. void
  294. nocache(Prog *p)
  295. {
  296. p->optab = 0;
  297. p->from.class = 0;
  298. p->to.class = 0;
  299. }