il_aux.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. /* $Id$ */
  2. /*
  3. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  4. * See the copyright notice in the ACK home directory, in the file "Copyright".
  5. */
  6. /* I N L I N E S U B S T I T U T I O N
  7. *
  8. * I L _ A U X . C
  9. */
  10. #include <stdio.h>
  11. #include <em_spec.h>
  12. #include <em_mnem.h>
  13. #include <em_pseu.h>
  14. #include "../share/types.h"
  15. #include "il.h"
  16. #include "../share/debug.h"
  17. #include "../share/get.h"
  18. #include "../share/put.h"
  19. #include "../share/alloc.h"
  20. #include "../share/global.h"
  21. #include "../share/lset.h"
  22. #include "../share/map.h"
  23. #include "il_aux.h"
  24. int tsize(type)
  25. int type;
  26. {
  27. /* Determine the size of a variable of the
  28. * given type.
  29. */
  30. switch(type) {
  31. case SINGLE: return ws;
  32. case DOUBLE: return 2*ws;
  33. case POINTER: return ps;
  34. default: assert(FALSE);
  35. }
  36. /* NOTREACHED */
  37. }
  38. line_p duplicate(lnp)
  39. line_p lnp;
  40. {
  41. /* Make a duplicate of an EM instruction.
  42. * Pseudos may not be passed as argument.
  43. */
  44. line_p l;
  45. l = newline(TYPE(lnp));
  46. l->l_instr = INSTR(lnp);
  47. switch(TYPE(l)) {
  48. case OPNO:
  49. break;
  50. case OPSHORT:
  51. SHORT(l) = SHORT(lnp);
  52. break;
  53. case OPOFFSET:
  54. OFFSET(l) = OFFSET(lnp);
  55. break;
  56. case OPINSTRLAB:
  57. INSTRLAB(l) = INSTRLAB(lnp);
  58. break;
  59. case OPOBJECT:
  60. OBJ(l) = OBJ(lnp);
  61. break;
  62. case OPPROC:
  63. PROC(l) = PROC(lnp);
  64. break;
  65. default:
  66. assert(FALSE); /* cannot copy pseudo */
  67. }
  68. return l;
  69. }
  70. line_p copy_expr(l1)
  71. line_p l1;
  72. {
  73. /* copy the expression */
  74. line_p head, tail, l, lnp;
  75. head = (line_p) 0;
  76. for (lnp = l1; lnp != (line_p) 0; lnp = lnp->l_next) {
  77. l = duplicate(lnp);
  78. if (head == (line_p) 0) {
  79. head = tail = l;
  80. PREV(l) = (line_p) 0;
  81. } else {
  82. tail->l_next = l;
  83. PREV(l) = tail;
  84. tail = l;
  85. }
  86. }
  87. return head;
  88. }
  89. rem_call(c)
  90. call_p c;
  91. {
  92. actual_p act, nexta;
  93. call_p nc,nextc;
  94. line_p l, nextl;
  95. for (act = c->cl_actuals; act != (actual_p) 0; act = nexta) {
  96. nexta = act->ac_next;
  97. for (l = act->ac_exp; l != (line_p) 0; l = nextl) {
  98. nextl = l->l_next;
  99. oldline(l);
  100. }
  101. oldactual(act);
  102. }
  103. nc = c->cl_car;
  104. oldcall(c);
  105. for (; nc != (call_p) 0; nc = nextc) {
  106. /* Take care of nested calls */
  107. nextc = nc->cl_cdr;
  108. rem_call(nc);
  109. }
  110. }
  111. /* rem_graph */
  112. STATIC short remlines(l)
  113. line_p l;
  114. {
  115. register line_p lnp;
  116. line_p next;
  117. for (lnp = l; lnp != (line_p) 0; lnp = next) {
  118. next = lnp->l_next;
  119. oldline(lnp);
  120. }
  121. }
  122. remunit(kind,p,l)
  123. short kind;
  124. proc_p p;
  125. line_p l;
  126. {
  127. register bblock_p b;
  128. bblock_p next;
  129. Lindex pi;
  130. if (kind == LDATA) {
  131. remlines(l);
  132. return;
  133. }
  134. for (b = p->p_start; b != (bblock_p) 0; b = next) {
  135. next = b->b_next;
  136. remlines(b->b_start);
  137. Ldeleteset(b->b_loops);
  138. Ldeleteset(b->b_succ);
  139. Ldeleteset(b->b_pred);
  140. oldbblock(b);
  141. }
  142. for (pi = Lfirst(p->p_loops); pi != (Lindex) 0;
  143. pi = Lnext(pi,p->p_loops)) {
  144. oldloop(Lelem(pi));
  145. }
  146. Ldeleteset(p->p_loops);
  147. oldmap(lmap,llength);
  148. oldmap(lbmap,llength);
  149. oldmap(bmap,blength);
  150. oldmap(lpmap,lplength);
  151. }
  152. remcc(head)
  153. calcnt_p head;
  154. {
  155. calcnt_p cc, next;
  156. for (cc = head; cc != (calcnt_p) 0; cc = next) {
  157. next = cc->cc_next;
  158. oldcalcnt(cc);
  159. }
  160. }
  161. /* Extra I/O routines */
  162. call_p getcall(cf)
  163. FILE *cf;
  164. {
  165. /* read a call from the call-file */
  166. call_p c;
  167. proc_p voided;
  168. actual_p act,*app;
  169. short n,m;
  170. curinp = cf;
  171. c = newcall();
  172. n = getshort(); /* void nesting level */
  173. if (feof(curinp)) return (call_p) 0;
  174. c->cl_caller = pmap[getshort()];
  175. c->cl_id = getshort();
  176. c->cl_proc = pmap[getshort()];
  177. c->cl_looplevel = getbyte();
  178. c->cl_flags = getbyte();
  179. c->cl_ratio = getshort();
  180. app = &c->cl_actuals;
  181. n = getshort();
  182. while(n--) {
  183. act = newactual();
  184. m = getshort();
  185. act->ac_size = getoff();
  186. act->ac_inl = getbyte();
  187. act->ac_exp = getlines(cf,m,&voided);
  188. *app = act;
  189. app = &act->ac_next;
  190. }
  191. *app = (actual_p) 0;
  192. return c;
  193. }
  194. line_p get_text(lf,p_out)
  195. FILE *lf;
  196. proc_p *p_out;
  197. {
  198. /* Read the EM text of one unit
  199. * If it is a procedure, set p_out to
  200. * the proc. just read. Else set p_out
  201. * to 0.
  202. */
  203. line_p dumhead, l, lprev;
  204. loop_p *oldlpmap = lpmap;
  205. line_p *oldlmap = lmap;
  206. short oldllength = llength;
  207. short oldlastlabid = lastlabid;
  208. curinp = lf;
  209. *p_out = (proc_p) 0;
  210. dumhead = newline(OPNO);
  211. /* The list of instructions is preceeded by a dummy
  212. * line, to simplify list manipulation
  213. */
  214. dumhead->l_instr = op_nop; /* just for fun */
  215. lprev = dumhead;
  216. for (;;) {
  217. l = read_line(p_out);
  218. if (feof(curinp)) return (line_p) 0;
  219. lprev->l_next = l;
  220. PREV(l) = lprev;
  221. if (INSTR(l) == ps_end) break;
  222. if (INSTR(l) == ps_mes) {
  223. message(l);
  224. }
  225. lprev = l;
  226. }
  227. /* The tables that map labels to instructions
  228. * and labels to basic blocks are not used.
  229. */
  230. if (*p_out != (proc_p) 0) {
  231. oldmap(lmap,llength);
  232. oldmap(lbmap,llength);
  233. lmap = oldlmap;
  234. lpmap = oldlpmap;
  235. }
  236. llength = oldllength;
  237. lastlabid = oldlastlabid;
  238. return dumhead;
  239. }
  240. calcnt_p getcc(ccf,p)
  241. FILE *ccf;
  242. proc_p p;
  243. {
  244. /* Get call-count info of procedure p */
  245. calcnt_p head,cc,*ccp;
  246. short i;
  247. fseek(ccf,p->p_extend->px_il.p_ccaddr,0);
  248. curinp = ccf;
  249. head = (calcnt_p) 0;
  250. ccp = &head;
  251. for (i = getshort(); i != (short) 0; i--) {
  252. cc = *ccp = newcalcnt();
  253. cc->cc_proc = pmap[getshort()];
  254. cc->cc_count = getshort();
  255. ccp = &cc->cc_next;
  256. }
  257. return head;
  258. }
  259. /* The following routines are only used by the Inline Substitution phase */
  260. STATIC putactuals(alist,cfile)
  261. actual_p alist;
  262. FILE *cfile;
  263. {
  264. /* output a list of actual parameters */
  265. actual_p a,next;
  266. line_p l;
  267. int count;
  268. count = 0;
  269. for (a = alist; a != (actual_p) 0; a = a->ac_next) count++;
  270. outshort(count); /* number of actuals */
  271. for (a = alist; a != (actual_p) 0; a = next) {
  272. next = a->ac_next;
  273. count = 0;
  274. for (l = a->ac_exp; l != (line_p) 0; l= l->l_next) count++;
  275. outshort(count); /* length of actual */
  276. outoff(a->ac_size);
  277. outbyte(a->ac_inl);
  278. count = putlines(a->ac_exp,cfile);
  279. oldactual(a);
  280. }
  281. }
  282. putcall(c,cfile,level)
  283. call_p c;
  284. FILE *cfile;
  285. short level;
  286. {
  287. /* output a call */
  288. call_p nc,nextc;
  289. curoutp = cfile;
  290. outshort(level); /* nesting level */
  291. outshort(c->cl_caller->p_id); /* calling proc */
  292. outshort(c->cl_id);
  293. outshort(c->cl_proc->p_id); /* called proc */
  294. outbyte(c->cl_looplevel);
  295. outbyte(c->cl_flags);
  296. outshort(c->cl_ratio);
  297. putactuals(c->cl_actuals,cfile);
  298. nc = c->cl_car;
  299. oldcall(c);
  300. for (; nc != (call_p) 0; nc = nextc) {
  301. /* take care of nested calls */
  302. nextc = nc->cl_cdr;
  303. putcall(nc,cfile,level+1);
  304. }
  305. }
  306. long putcc(head,ccf)
  307. calcnt_p head;
  308. FILE *ccf;
  309. {
  310. /* Write call-count information to file ccf.
  311. * Return the disk address of the info written.
  312. */
  313. calcnt_p cc;
  314. long addr;
  315. short cnt;
  316. addr = ftell(ccf);
  317. curoutp = ccf;
  318. cnt = 0;
  319. for (cc = head; cc != (calcnt_p) 0;cc = cc->cc_next) cnt++;
  320. outshort(cnt);
  321. for (cc = head; cc != (calcnt_p) 0; cc = cc->cc_next) {
  322. outproc(cc->cc_proc);
  323. outshort(cc->cc_count);
  324. }
  325. return addr;
  326. }