ack/util/ego/il/il_aux.c
George Koehler 9037d137f5 Add prototypes, void in util/ego/share
This uncovers a problem in il/il_aux.c: it passes 3 arguments to
getlines(), but the function expects 4 arguments.  I add FALSE as the
4th argument.  TRUE would fill in the list of mesregs.  IL uses
mesregs during phase 1, but this call to getlines() is in phase 2.
TRUE would leak memory unless I added a call to Ldeleteset(mesregs).
So I pass FALSE.

Functions passed to go() now have a `void *` parameter because
no_action() now takes a `void *`.
2017-11-15 17:19:56 -05:00

390 lines
6.8 KiB
C

/* $Id$ */
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* I N L I N E S U B S T I T U T I O N
*
* I L _ A U X . C
*/
#include <stdlib.h>
#include <stdio.h>
#include <em_spec.h>
#include <em_mnem.h>
#include <em_pseu.h>
#include "../share/types.h"
#include "il.h"
#include "../share/debug.h"
#include "../share/get.h"
#include "../share/put.h"
#include "../share/alloc.h"
#include "../share/global.h"
#include "../share/lset.h"
#include "../share/map.h"
#include "il_aux.h"
int tsize(type)
int type;
{
/* Determine the size of a variable of the
* given type.
*/
switch(type) {
case SINGLE: return ws;
case DOUBLE: return 2*ws;
case POINTER: return ps;
default: assert(FALSE);
}
/* NOTREACHED */
}
line_p duplicate(lnp)
line_p lnp;
{
/* Make a duplicate of an EM instruction.
* Pseudos may not be passed as argument.
*/
line_p l;
l = newline(TYPE(lnp));
l->l_instr = INSTR(lnp);
switch(TYPE(l)) {
case OPNO:
break;
case OPSHORT:
SHORT(l) = SHORT(lnp);
break;
case OPOFFSET:
OFFSET(l) = OFFSET(lnp);
break;
case OPINSTRLAB:
INSTRLAB(l) = INSTRLAB(lnp);
break;
case OPOBJECT:
OBJ(l) = OBJ(lnp);
break;
case OPPROC:
PROC(l) = PROC(lnp);
break;
default:
assert(FALSE); /* cannot copy pseudo */
}
return l;
}
line_p copy_expr(l1)
line_p l1;
{
/* copy the expression */
line_p head, tail, l, lnp;
head = (line_p) 0;
for (lnp = l1; lnp != (line_p) 0; lnp = lnp->l_next) {
l = duplicate(lnp);
if (head == (line_p) 0) {
head = tail = l;
PREV(l) = (line_p) 0;
} else {
tail->l_next = l;
PREV(l) = tail;
tail = l;
}
}
return head;
}
rem_call(c)
call_p c;
{
actual_p act, nexta;
call_p nc,nextc;
line_p l, nextl;
for (act = c->cl_actuals; act != (actual_p) 0; act = nexta) {
nexta = act->ac_next;
for (l = act->ac_exp; l != (line_p) 0; l = nextl) {
nextl = l->l_next;
oldline(l);
}
oldactual(act);
}
nc = c->cl_car;
oldcall(c);
for (; nc != (call_p) 0; nc = nextc) {
/* Take care of nested calls */
nextc = nc->cl_cdr;
rem_call(nc);
}
}
/* rem_graph */
STATIC short remlines(l)
line_p l;
{
register line_p lnp;
line_p next;
for (lnp = l; lnp != (line_p) 0; lnp = next) {
next = lnp->l_next;
oldline(lnp);
}
}
void
remunit(kind,p,l)
short kind;
proc_p p;
line_p l;
{
register bblock_p b;
bblock_p next;
Lindex pi;
if (kind == LDATA) {
remlines(l);
return;
}
for (b = p->p_start; b != (bblock_p) 0; b = next) {
next = b->b_next;
remlines(b->b_start);
Ldeleteset(b->b_loops);
Ldeleteset(b->b_succ);
Ldeleteset(b->b_pred);
oldbblock(b);
}
for (pi = Lfirst(p->p_loops); pi != (Lindex) 0;
pi = Lnext(pi,p->p_loops)) {
oldloop(Lelem(pi));
}
Ldeleteset(p->p_loops);
oldmap(lmap,llength);
oldmap(lbmap,llength);
oldmap(bmap,blength);
oldmap(lpmap,lplength);
}
remcc(head)
calcnt_p head;
{
calcnt_p cc, next;
for (cc = head; cc != (calcnt_p) 0; cc = next) {
next = cc->cc_next;
oldcalcnt(cc);
}
}
/* Extra I/O routines */
call_p getcall(cf)
FILE *cf;
{
/* read a call from the call-file */
call_p c;
proc_p voided;
actual_p act,*app;
short n,m;
curinp = cf;
c = newcall();
n = getshort(); /* void nesting level */
if (feof(curinp)) return (call_p) 0;
c->cl_caller = pmap[getshort()];
c->cl_id = getshort();
c->cl_proc = pmap[getshort()];
c->cl_looplevel = getbyte();
c->cl_flags = getbyte();
c->cl_ratio = getshort();
app = &c->cl_actuals;
n = getshort();
while(n--) {
act = newactual();
m = getshort();
act->ac_size = getoff();
act->ac_inl = getbyte();
act->ac_exp = getlines(cf,m,&voided,FALSE);
*app = act;
app = &act->ac_next;
}
*app = (actual_p) 0;
return c;
}
line_p get_text(lf,p_out)
FILE *lf;
proc_p *p_out;
{
/* Read the EM text of one unit
* If it is a procedure, set p_out to
* the proc. just read. Else set p_out
* to 0.
*/
line_p dumhead, l, lprev;
loop_p *oldlpmap = lpmap;
line_p *oldlmap = lmap;
short oldllength = llength;
short oldlastlabid = lastlabid;
curinp = lf;
*p_out = (proc_p) 0;
dumhead = newline(OPNO);
/* The list of instructions is preceeded by a dummy
* line, to simplify list manipulation
*/
dumhead->l_instr = op_nop; /* just for fun */
lprev = dumhead;
for (;;) {
l = read_line(p_out);
if (feof(curinp)) return (line_p) 0;
lprev->l_next = l;
PREV(l) = lprev;
if (INSTR(l) == ps_end) break;
if (INSTR(l) == ps_mes) {
message(l);
}
lprev = l;
}
/* The tables that map labels to instructions
* and labels to basic blocks are not used.
*/
if (*p_out != (proc_p) 0) {
oldmap(lmap,llength);
oldmap(lbmap,llength);
lmap = oldlmap;
lpmap = oldlpmap;
}
llength = oldllength;
lastlabid = oldlastlabid;
return dumhead;
}
calcnt_p getcc(ccf,p)
FILE *ccf;
proc_p p;
{
/* Get call-count info of procedure p */
calcnt_p head,cc,*ccp;
short i;
fseek(ccf,p->p_extend->px_il.p_ccaddr,0);
curinp = ccf;
head = (calcnt_p) 0;
ccp = &head;
for (i = getshort(); i != (short) 0; i--) {
cc = *ccp = newcalcnt();
cc->cc_proc = pmap[getshort()];
cc->cc_count = getshort();
ccp = &cc->cc_next;
}
return head;
}
/* The following routines are only used by the Inline Substitution phase */
STATIC putactuals(alist,cfile)
actual_p alist;
FILE *cfile;
{
/* output a list of actual parameters */
actual_p a,next;
line_p l;
int count;
count = 0;
for (a = alist; a != (actual_p) 0; a = a->ac_next) count++;
outshort(count); /* number of actuals */
for (a = alist; a != (actual_p) 0; a = next) {
next = a->ac_next;
count = 0;
for (l = a->ac_exp; l != (line_p) 0; l= l->l_next) count++;
outshort(count); /* length of actual */
outoff(a->ac_size);
outbyte(a->ac_inl);
count = putlines(a->ac_exp,cfile);
oldactual(a);
}
}
putcall(c,cfile,level)
call_p c;
FILE *cfile;
short level;
{
/* output a call */
call_p nc,nextc;
curoutp = cfile;
outshort(level); /* nesting level */
outshort(c->cl_caller->p_id); /* calling proc */
outshort(c->cl_id);
outshort(c->cl_proc->p_id); /* called proc */
outbyte(c->cl_looplevel);
outbyte(c->cl_flags);
outshort(c->cl_ratio);
putactuals(c->cl_actuals,cfile);
nc = c->cl_car;
oldcall(c);
for (; nc != (call_p) 0; nc = nextc) {
/* take care of nested calls */
nextc = nc->cl_cdr;
putcall(nc,cfile,level+1);
}
}
long putcc(head,ccf)
calcnt_p head;
FILE *ccf;
{
/* Write call-count information to file ccf.
* Return the disk address of the info written.
*/
calcnt_p cc;
long addr;
short cnt;
addr = ftell(ccf);
curoutp = ccf;
cnt = 0;
for (cc = head; cc != (calcnt_p) 0;cc = cc->cc_next) cnt++;
outshort(cnt);
for (cc = head; cc != (calcnt_p) 0; cc = cc->cc_next) {
outproc(cc->cc_proc);
outshort(cc->cc_count);
}
return addr;
}