il_aux.c 6.7 KB

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