il3_subst.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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 3 _ S U B S T . C
  9. */
  10. #include <stdio.h>
  11. #include <em_mnem.h>
  12. #include "../share/types.h"
  13. #include "il.h"
  14. #include "../share/debug.h"
  15. #include "../share/alloc.h"
  16. #include "../share/global.h"
  17. #include "../share/lset.h"
  18. #include "../share/get.h"
  19. #include "il_aux.h"
  20. #include "il3_aux.h"
  21. #include "il3_change.h"
  22. #include "il3_subst.h"
  23. static line_p fetch_text(FILE *lf, call_p c)
  24. {
  25. /* Read the EM text of the called procedure.
  26. * We use random access I/O here.
  27. */
  28. line_p l;
  29. proc_p p;
  30. lset savmes;
  31. savmes = mesregs;
  32. mesregs = Lempty_set();
  33. fseek(lf,c->cl_proc->P_LADDR,0);
  34. l = get_text(lf,&p);
  35. assert (p == c->cl_proc);
  36. Ldeleteset(mesregs);
  37. mesregs = savmes;
  38. return l;
  39. }
  40. line_p scan_to_cal(line_p lines, short n)
  41. {
  42. /* Find the n-th CAL instruction */
  43. line_p l;
  44. for (l = lines; l != (line_p) 0; l = l->l_next) {
  45. if (INSTR(l) == op_cal) {
  46. if (--n == 0) return l;
  47. }
  48. }
  49. return (line_p) 0; /* CAL not found */
  50. }
  51. void substitute(FILE *lf, call_p c, line_p cal, line_p firstline)
  52. {
  53. /* Perform in line substitution of the call described
  54. * by c. The EM text of the called routine is fetched
  55. * and modified, the calling sequence is changed,
  56. * the modified routine is put at the place of the call
  57. * and all global information (proctable etc.) is kept
  58. * up to date.
  59. */
  60. line_p l, text = NULL, lab = NULL;
  61. offset ab_off, lb_off;
  62. line_p startscan, ncal;
  63. short lastcid;
  64. call_p nc;
  65. Ssubst++;
  66. ab_off = - curproc->p_localbytes;
  67. /* offset of temporaries for parameters
  68. * that are not expanded in line.
  69. */
  70. chg_callseq(c,cal,&l);
  71. /* Change the calling sequence; l points to the place
  72. * where the expanded text must be put
  73. */
  74. text = fetch_text(lf,c); /* fetch EM text of called routine */
  75. lb_off = - curproc->p_localbytes;
  76. /* offset of temps. for locals of called proc. */
  77. curproc->p_localbytes += c->cl_proc->P_ORGLOCALS;
  78. /* locals of called routine are put in stack frame of caller */
  79. if (!FALLTHROUGH(c->cl_proc)) {
  80. /* The called proc contains one or more RETurns
  81. * somewhere in the middle of its text; these
  82. * should be changed into a jump to the end
  83. * of the text. We create a label for this
  84. * purpose (if there was no one already).
  85. */
  86. lab = make_label(l,curproc);
  87. }
  88. modify(text,c,lab,ab_off,lb_off,curproc->p_nrlabels);
  89. curproc->p_nrlabels += c->cl_proc->P_ORGLABELS;
  90. insert(text,l,firstline);
  91. /* insert text; instructions are put after l, pseudos
  92. * are put at beginning of caller.
  93. */
  94. /* Now take care of the nested calls */
  95. startscan = l->l_next;
  96. lastcid = 0;
  97. for (nc = c->cl_car; nc != (call_p) 0; nc = nc->cl_cdr) {
  98. mod_actuals(nc,c,lab,ab_off,lb_off,curproc->p_nrlabels);
  99. ncal = scan_to_cal(startscan,nc->cl_id - lastcid);
  100. assert(ncal != (line_p) 0);
  101. startscan = scan_to_cal(ncal->l_next,1);
  102. lastcid = nc->cl_id;
  103. substitute(lf,nc,ncal,firstline);
  104. }
  105. }