Next batch...
This commit is contained in:
parent
c5bfc89269
commit
41f96d5169
@ -35,7 +35,7 @@ extern char em_flag[];
|
||||
#define newbolpx() (lpext_p) newstruct(lpext_ra)
|
||||
#define oldbolpx(x) oldstruct(lpext_ra,x)
|
||||
|
||||
STATIC int Sbo; /* #optimizations found */
|
||||
static int Sbo; /* #optimizations found */
|
||||
|
||||
#define DLINK(l1,l2) l1->l_next=l2; l2->l_prev=l1
|
||||
|
||||
@ -62,13 +62,10 @@ STATIC int Sbo; /* #optimizations found */
|
||||
|
||||
|
||||
|
||||
STATIC line_p last_code(lines,skip_pseu)
|
||||
line_p lines;
|
||||
bool skip_pseu;
|
||||
static line_p last_code(line_p lines, bool skip_pseu)
|
||||
{
|
||||
/* Determine the last line of a list */
|
||||
|
||||
register line_p l;
|
||||
line_p l;
|
||||
|
||||
for (l = lines; l->l_next != (line_p) 0; l = l->l_next);
|
||||
if (skip_pseu) {
|
||||
@ -77,15 +74,14 @@ STATIC line_p last_code(lines,skip_pseu)
|
||||
return l;
|
||||
}
|
||||
|
||||
STATIC short cc_tab[12] =
|
||||
static short cc_tab[12] =
|
||||
{op_blt,op_zlt,op_ble,op_zle,op_beq,op_zeq,
|
||||
op_zne,op_bne,op_zgt,op_bgt,op_zge,op_bge};
|
||||
|
||||
|
||||
STATIC short rev_cond(cond)
|
||||
short cond;
|
||||
static short rev_cond(short cond)
|
||||
{
|
||||
register i;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 12; i++) {
|
||||
if (cond == cc_tab[i]) return cc_tab[11-i];
|
||||
@ -93,17 +89,13 @@ STATIC short rev_cond(cond)
|
||||
return op_nop;
|
||||
}
|
||||
|
||||
STATIC bool is_bcc(l)
|
||||
line_p l;
|
||||
static bool is_bcc(line_p l)
|
||||
{
|
||||
return rev_cond(INSTR(l)) != op_nop;
|
||||
}
|
||||
|
||||
|
||||
STATIC bo_optloop(p,b,x,bra,bcc)
|
||||
proc_p p;
|
||||
bblock_p b,x;
|
||||
line_p bra,bcc;
|
||||
static void bo_optloop(proc_p p, bblock_p b, bblock_p x, line_p bra, line_p bcc)
|
||||
{
|
||||
bblock_p prevb,n;
|
||||
line_p l;
|
||||
@ -150,9 +142,7 @@ STATIC bo_optloop(p,b,x,bra,bcc)
|
||||
|
||||
|
||||
|
||||
STATIC bo_tryloop(p,loop)
|
||||
proc_p p;
|
||||
lset loop;
|
||||
static void bo_tryloop(proc_p p, lset loop)
|
||||
{
|
||||
Lindex i,j;
|
||||
bblock_p b,x;
|
||||
@ -180,8 +170,7 @@ OUTVERBOSE("branch optimization proc %d block %d\n", curproc->p_id,x->b_id);
|
||||
|
||||
|
||||
|
||||
STATIC bo_loops(p)
|
||||
proc_p p;
|
||||
static void bo_loops(proc_p p)
|
||||
{
|
||||
Lindex i;
|
||||
loop_p lp;
|
||||
@ -192,8 +181,7 @@ STATIC bo_loops(p)
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mv_code(b1,b2)
|
||||
bblock_p b1,b2;
|
||||
static void mv_code(bblock_p b1, bblock_p b2)
|
||||
{
|
||||
line_p l,x;
|
||||
|
||||
@ -207,8 +195,7 @@ STATIC mv_code(b1,b2)
|
||||
}
|
||||
}
|
||||
|
||||
bo_switch(b)
|
||||
bblock_p b;
|
||||
void bo_switch(bblock_p b)
|
||||
{
|
||||
bblock_p s,x;
|
||||
Lindex i;
|
||||
@ -255,13 +242,12 @@ OUTVERBOSE("branch optimization in proc %d, block %d",curproc->p_id,b->b_id);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC bo_extproc(p)
|
||||
proc_p p;
|
||||
static void bo_extproc(proc_p p)
|
||||
{
|
||||
/* Allocate the extended data structures for procedure p */
|
||||
|
||||
register loop_p lp;
|
||||
register Lindex pi;
|
||||
loop_p lp;
|
||||
Lindex pi;
|
||||
|
||||
for (pi = Lfirst(p->p_loops); pi != (Lindex) 0;
|
||||
pi = Lnext(pi,p->p_loops)) {
|
||||
@ -271,13 +257,12 @@ STATIC bo_extproc(p)
|
||||
}
|
||||
|
||||
|
||||
STATIC loop_blocks(p)
|
||||
proc_p p;
|
||||
static void loop_blocks(proc_p p)
|
||||
{
|
||||
/* Compute the LP_BLOCKS sets for all loops of p */
|
||||
|
||||
register bblock_p b;
|
||||
register Lindex i;
|
||||
bblock_p b;
|
||||
Lindex i;
|
||||
|
||||
for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) {
|
||||
for (i = Lfirst(b->b_loops); i != (Lindex) 0;
|
||||
@ -287,14 +272,13 @@ STATIC loop_blocks(p)
|
||||
}
|
||||
}
|
||||
|
||||
STATIC bo_cleanproc(p)
|
||||
proc_p p;
|
||||
static void bo_cleanproc(proc_p p)
|
||||
{
|
||||
/* Allocate the extended data structures for procedure p */
|
||||
|
||||
register loop_p lp;
|
||||
register Lindex pi;
|
||||
register bblock_p b;
|
||||
loop_p lp;
|
||||
Lindex pi;
|
||||
bblock_p b;
|
||||
|
||||
for (pi = Lfirst(p->p_loops); pi != (Lindex) 0;
|
||||
pi = Lnext(pi,p->p_loops)) {
|
||||
@ -303,12 +287,12 @@ STATIC bo_cleanproc(p)
|
||||
}
|
||||
}
|
||||
|
||||
bo_optimize(p)
|
||||
proc_p p;
|
||||
int bo_optimize(void *param)
|
||||
{
|
||||
proc_p p = (proc_p)param;
|
||||
bblock_p b;
|
||||
|
||||
if (IS_ENTERED_WITH_GTO(p)) return;
|
||||
if (IS_ENTERED_WITH_GTO(p)) return 0;
|
||||
bo_extproc(p);
|
||||
loop_blocks(p);
|
||||
bo_loops(p);
|
||||
@ -316,15 +300,15 @@ bo_optimize(p)
|
||||
bo_switch(b);
|
||||
}
|
||||
bo_cleanproc(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
go(argc,argv,no_action,bo_optimize,no_action,no_action);
|
||||
go(argc, argv, no_action, bo_optimize, no_action, no_action);
|
||||
report("branch optimizations", Sbo);
|
||||
exit(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -42,9 +42,7 @@ char **dnames, **pnames; /* Dynamically allocated arrays of strings.
|
||||
|
||||
|
||||
|
||||
STATIC line_p get_ca_lines(lf,p_out)
|
||||
FILE *lf;
|
||||
proc_p *p_out;
|
||||
static line_p get_ca_lines(FILE *lf, proc_p *p_out)
|
||||
{
|
||||
/* Read lines of EM text and link them.
|
||||
* Register messages are outputted immediately after the PRO.
|
||||
@ -100,8 +98,7 @@ STATIC line_p get_ca_lines(lf,p_out)
|
||||
return head;
|
||||
}
|
||||
|
||||
STATIC int makedmap(dbl)
|
||||
dblock_p dbl;
|
||||
static int makedmap(dblock_p dbl)
|
||||
{
|
||||
/* construct the dmap table */
|
||||
|
||||
@ -122,8 +119,7 @@ STATIC int makedmap(dbl)
|
||||
|
||||
|
||||
|
||||
STATIC getdnames(dumpd)
|
||||
FILE *dumpd;
|
||||
static void getdnames(FILE *dumpd)
|
||||
{
|
||||
/* Read the names of the datalabels from
|
||||
* the dump file.
|
||||
@ -141,8 +137,7 @@ STATIC getdnames(dumpd)
|
||||
}
|
||||
}
|
||||
|
||||
STATIC getpnames(dumpp)
|
||||
FILE *dumpp;
|
||||
static void getpnames(FILE *dumpp)
|
||||
{
|
||||
/* Read the names of the procedures from
|
||||
* the dump file.
|
||||
@ -162,8 +157,7 @@ STATIC getpnames(dumpp)
|
||||
|
||||
|
||||
|
||||
STATIC new_name(s)
|
||||
char **s;
|
||||
static void new_name(char **s)
|
||||
{
|
||||
static int nn = 0;
|
||||
char buf[20];
|
||||
@ -181,7 +175,7 @@ STATIC new_name(s)
|
||||
|
||||
|
||||
|
||||
STATIC uniq_names()
|
||||
static void uniq_names()
|
||||
{
|
||||
/* The names of all internal procedures and data blocks
|
||||
* are made different. As the optimizer combines several
|
||||
@ -206,9 +200,7 @@ STATIC uniq_names()
|
||||
}
|
||||
|
||||
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
/* CA does not output proctable etc. files. Instead, its
|
||||
* pname2 and dname2 arguments contain the names of the
|
||||
@ -218,8 +210,8 @@ main(argc,argv)
|
||||
FILE *df, *pf; /* The dump files */
|
||||
line_p lnp;
|
||||
|
||||
fproc = getptable(pname); /* proc table */
|
||||
fdblock = getdtable(dname); /* data block table */
|
||||
fproc = getptable(&pname); /* proc table */
|
||||
fdblock = getdtable(&dname); /* data block table */
|
||||
dlength = makedmap(fdblock); /* allocate dmap table */
|
||||
df = openfile(dname2,"r");
|
||||
getdnames(df);
|
||||
|
||||
@ -20,21 +20,21 @@
|
||||
|
||||
FILE *outfile;
|
||||
|
||||
STATIC proc_p thispro;
|
||||
|
||||
STATIC outinst(m) {
|
||||
static proc_p thispro;
|
||||
|
||||
static void outinst(int m)
|
||||
{
|
||||
outbyte( (byte) m );
|
||||
}
|
||||
|
||||
STATIC coutshort(i) short i; {
|
||||
|
||||
static void coutshort(short i)
|
||||
{
|
||||
outbyte( (byte) (i&BMASK) );
|
||||
outbyte( (byte) (i>>8) );
|
||||
}
|
||||
|
||||
STATIC coutint(i) short i; {
|
||||
|
||||
static void coutint(short i)
|
||||
{
|
||||
if (i>= -sp_zcst0 && i< sp_ncst0-sp_zcst0)
|
||||
outbyte( (byte) (i+sp_zcst0+sp_fcst0) );
|
||||
else {
|
||||
@ -43,8 +43,8 @@ STATIC coutint(i) short i; {
|
||||
}
|
||||
}
|
||||
|
||||
STATIC coutoff(off) offset off; {
|
||||
|
||||
static void coutoff(offset off)
|
||||
{
|
||||
if ((short) off == off)
|
||||
coutint((short) off);
|
||||
else {
|
||||
@ -55,12 +55,10 @@ STATIC coutoff(off) offset off; {
|
||||
}
|
||||
|
||||
|
||||
STATIC outsym(s,t)
|
||||
char *s;
|
||||
int t;
|
||||
static void outsym(char *s, int t)
|
||||
{
|
||||
register byte *p;
|
||||
register unsigned num;
|
||||
byte *p;
|
||||
unsigned int num;
|
||||
|
||||
if (s[0] == '.') {
|
||||
num = atoi(&s[1]);
|
||||
@ -85,22 +83,20 @@ STATIC outsym(s,t)
|
||||
}
|
||||
|
||||
|
||||
STATIC outdsym(dbl)
|
||||
dblock_p dbl;
|
||||
static void outdsym(dblock_p dbl)
|
||||
{
|
||||
if (dnames[dbl->d_id]) outsym(dnames[dbl->d_id],sp_dnam);
|
||||
}
|
||||
|
||||
|
||||
STATIC outpsym(p)
|
||||
proc_p p;
|
||||
static void outpsym(proc_p p)
|
||||
{
|
||||
outsym(pnames[p->p_id],sp_pnam);
|
||||
}
|
||||
|
||||
|
||||
STATIC outddef(id) short id; {
|
||||
|
||||
static void outddef(short id)
|
||||
{
|
||||
dblock_p dbl;
|
||||
|
||||
dbl = dmap[id];
|
||||
@ -111,7 +107,8 @@ STATIC outddef(id) short id; {
|
||||
}
|
||||
}
|
||||
|
||||
STATIC outpdef(p) proc_p p; {
|
||||
static void outpdef(proc_p p)
|
||||
{
|
||||
p->p_flags2 |= PF_SYMOUT;
|
||||
if (p->p_flags1 & PF_EXTERNAL) {
|
||||
outinst(ps_exp);
|
||||
@ -120,7 +117,8 @@ STATIC outpdef(p) proc_p p; {
|
||||
}
|
||||
|
||||
|
||||
STATIC outdocc(obj) obj_p obj; {
|
||||
static void outdocc(obj_p obj)
|
||||
{
|
||||
dblock_p dbl;
|
||||
|
||||
dbl = obj->o_dblock;
|
||||
@ -135,7 +133,8 @@ STATIC outdocc(obj) obj_p obj; {
|
||||
}
|
||||
|
||||
|
||||
STATIC outpocc(p) proc_p p; {
|
||||
static void outpocc(proc_p p)
|
||||
{
|
||||
if ((p->p_flags2 & PF_SYMOUT) == 0) {
|
||||
p->p_flags2 |= PF_SYMOUT;
|
||||
if ((p->p_flags1 & PF_EXTERNAL) == 0) {
|
||||
@ -146,8 +145,7 @@ STATIC outpocc(p) proc_p p; {
|
||||
}
|
||||
|
||||
|
||||
STATIC coutobject(obj)
|
||||
obj_p obj;
|
||||
static void coutobject(obj_p obj)
|
||||
{
|
||||
/* In general, an object is defined by a global data
|
||||
* label and an offset. There are two special cases:
|
||||
@ -169,9 +167,10 @@ STATIC coutobject(obj)
|
||||
}
|
||||
|
||||
|
||||
STATIC cputstr(abp) register argb_p abp; {
|
||||
register argb_p tbp;
|
||||
register length;
|
||||
static void cputstr(argb_p abp)
|
||||
{
|
||||
argb_p tbp;
|
||||
int length;
|
||||
|
||||
length = 0;
|
||||
tbp = abp;
|
||||
@ -188,8 +187,7 @@ STATIC cputstr(abp) register argb_p abp; {
|
||||
}
|
||||
|
||||
|
||||
STATIC outnum(n)
|
||||
int n;
|
||||
static void outnum(int n)
|
||||
{
|
||||
if (n < 256) {
|
||||
outbyte((byte) sp_ilb1);
|
||||
@ -201,8 +199,7 @@ STATIC outnum(n)
|
||||
}
|
||||
|
||||
|
||||
STATIC numlab(n)
|
||||
int n;
|
||||
static void numlab(int n)
|
||||
{
|
||||
if (n < sp_nilb0) {
|
||||
outbyte((byte) (n + sp_filb0));
|
||||
@ -212,10 +209,9 @@ STATIC numlab(n)
|
||||
}
|
||||
|
||||
|
||||
STATIC cputargs(lnp)
|
||||
line_p lnp;
|
||||
static void cputargs(line_p lnp)
|
||||
{
|
||||
register arg_p ap;
|
||||
arg_p ap;
|
||||
int cnt = 0;
|
||||
ap = ARG(lnp);
|
||||
while (ap != (arg_p) 0) {
|
||||
@ -264,8 +260,7 @@ STATIC cputargs(lnp)
|
||||
|
||||
|
||||
|
||||
STATIC outoperand(lnp)
|
||||
line_p lnp;
|
||||
static void outoperand(line_p lnp)
|
||||
{
|
||||
/* Output the operand of instruction lnp */
|
||||
|
||||
@ -320,8 +315,7 @@ STATIC outoperand(lnp)
|
||||
}
|
||||
|
||||
|
||||
STATIC outvisibility(lnp)
|
||||
line_p lnp;
|
||||
static void outvisibility(line_p lnp)
|
||||
{
|
||||
/* In EM names of datalabels and procedures can be made
|
||||
* externally visible, so they can be used in other files.
|
||||
@ -377,9 +371,7 @@ STATIC outvisibility(lnp)
|
||||
}
|
||||
|
||||
|
||||
cputlines(l,lf)
|
||||
line_p l;
|
||||
FILE *lf;
|
||||
void cputlines(line_p l, FILE *lf)
|
||||
{
|
||||
/* Output the lines in Campact assembly language
|
||||
* format.
|
||||
@ -405,13 +397,12 @@ cputlines(l,lf)
|
||||
oldline(lnp);
|
||||
}
|
||||
if (lmap != (line_p *) 0) {
|
||||
oldmap(lmap,llength);
|
||||
oldmap((short **)lmap,llength);
|
||||
lmap = (line_p *) 0;
|
||||
}
|
||||
}
|
||||
|
||||
cputmagic(lf)
|
||||
FILE *lf;
|
||||
void cputmagic(FILE *lf)
|
||||
{
|
||||
/* write the magic number */
|
||||
|
||||
|
||||
@ -10,5 +10,5 @@
|
||||
*/
|
||||
|
||||
|
||||
extern cputlines();
|
||||
extern cputmagic();
|
||||
void cputlines(line_p l, FILE *lf);
|
||||
void cputmagic(FILE *lf);
|
||||
|
||||
@ -36,8 +36,8 @@
|
||||
|
||||
extern char em_flag[];
|
||||
|
||||
STATIC cset lpi_set; /* set of procedures used in LPI instruction */
|
||||
STATIC cset cai_set; /* set of all procedures doing a CAI */
|
||||
static cset lpi_set; /* set of procedures used in LPI instruction */
|
||||
static cset cai_set; /* set of all procedures doing a CAI */
|
||||
|
||||
|
||||
/* The procedure getbblocks reads the EM textfile and
|
||||
@ -55,15 +55,15 @@ STATIC cset cai_set; /* set of all procedures doing a CAI */
|
||||
|
||||
/* These global variables are used by getbblocks and nextblock. */
|
||||
|
||||
STATIC bblock_p b, *bp; /* b is the current basic block, bp is
|
||||
static bblock_p b, *bp; /* b is the current basic block, bp is
|
||||
* the address where the next block has
|
||||
* to be linked.
|
||||
*/
|
||||
STATIC line_p lnp, *lp; /* lnp is the current line, lp is
|
||||
static line_p lnp, *lp; /* lnp is the current line, lp is
|
||||
* the address where the next line
|
||||
* has to be linked.
|
||||
*/
|
||||
STATIC short state; /* We use a finite state machine with the
|
||||
static short state; /* We use a finite state machine with the
|
||||
* following states:
|
||||
* LABEL0: after the first (successive)
|
||||
* instruction label.
|
||||
@ -78,7 +78,7 @@ STATIC short state; /* We use a finite state machine with the
|
||||
*/
|
||||
|
||||
|
||||
STATIC nextblock()
|
||||
static void nextblock()
|
||||
{
|
||||
/* allocate a new basic block structure and
|
||||
* set b, bp and lp.
|
||||
@ -99,8 +99,7 @@ STATIC nextblock()
|
||||
}
|
||||
|
||||
|
||||
STATIC short kind(lnp)
|
||||
line_p lnp;
|
||||
static short kind(line_p lnp)
|
||||
{
|
||||
/* determine if lnp is a label, branch, end or otherwise */
|
||||
|
||||
@ -116,15 +115,14 @@ STATIC short kind(lnp)
|
||||
}
|
||||
|
||||
|
||||
STATIC line_p doread_line(p_out)
|
||||
proc_p *p_out;
|
||||
static line_p doread_line(proc_p *p_out)
|
||||
{
|
||||
/* read a line, and check pseudos for procedure addresses */
|
||||
|
||||
register line_p lnp = read_line(p_out);
|
||||
line_p lnp = read_line(p_out);
|
||||
|
||||
if (lnp && TYPE(lnp) == OPLIST && INSTR(lnp) != ps_mes) {
|
||||
register arg_p arg = ARG(lnp);
|
||||
arg_p arg = ARG(lnp);
|
||||
|
||||
while (arg) {
|
||||
if (arg->a_type == ARGPROC) {
|
||||
@ -137,12 +135,7 @@ STATIC line_p doread_line(p_out)
|
||||
return lnp;
|
||||
}
|
||||
|
||||
STATIC bool getbblocks(fp,kind_out,n_out,g_out,l_out)
|
||||
FILE *fp;
|
||||
short *kind_out;
|
||||
short *n_out;
|
||||
bblock_p *g_out;
|
||||
line_p *l_out;
|
||||
static bool getbblocks(FILE *fp, short *kind_out, short *n_out, bblock_p *g_out, line_p *l_out)
|
||||
{
|
||||
bblock_p head = (bblock_p) 0;
|
||||
line_p headl = (line_p) 0;
|
||||
@ -237,8 +230,7 @@ STATIC bool getbblocks(fp,kind_out,n_out,g_out,l_out)
|
||||
}
|
||||
|
||||
|
||||
STATIC interproc_analysis(p)
|
||||
proc_p p;
|
||||
static void interproc_analysis(proc_p p)
|
||||
{
|
||||
/* Interprocedural analysis of a procedure p determines:
|
||||
* - all procedures called by p (the 'call graph')
|
||||
@ -342,8 +334,7 @@ STATIC interproc_analysis(p)
|
||||
}
|
||||
|
||||
|
||||
STATIC cf_cleanproc(p)
|
||||
proc_p p;
|
||||
static void cf_cleanproc(proc_p p)
|
||||
{
|
||||
/* Remove the extended data structures of p */
|
||||
|
||||
@ -369,8 +360,7 @@ STATIC cf_cleanproc(p)
|
||||
#define ENVIRON(p) (p->p_flags1 & (byte) PF_ENVIRON)
|
||||
|
||||
|
||||
STATIC bool add_info(q,p)
|
||||
proc_p q,p;
|
||||
static bool add_info(proc_p q, proc_p p)
|
||||
{
|
||||
/* Determine the consequences for used/changed variables info
|
||||
* of the fact that p calls q. If e.g. q changes a variable X
|
||||
@ -448,14 +438,12 @@ STATIC bool add_info(q,p)
|
||||
|
||||
|
||||
|
||||
STATIC trans_clos(head)
|
||||
proc_p head;
|
||||
static void trans_clos(proc_p head)
|
||||
{
|
||||
/* Compute the transitive closure of the used/changed
|
||||
* variable information.
|
||||
*/
|
||||
|
||||
register proc_p p,q;
|
||||
proc_p p,q;
|
||||
Cindex i;
|
||||
bool changes = TRUE;
|
||||
|
||||
@ -477,7 +465,7 @@ STATIC trans_clos(head)
|
||||
|
||||
|
||||
|
||||
indir_calls()
|
||||
void indir_calls()
|
||||
{
|
||||
Cindex i;
|
||||
proc_p p;
|
||||
@ -492,9 +480,7 @@ indir_calls()
|
||||
|
||||
|
||||
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FILE *f, *f2, *gf2; /* The EM input, EM output, basic block output */
|
||||
bblock_p g;
|
||||
@ -502,8 +488,8 @@ main(argc,argv)
|
||||
line_p l;
|
||||
|
||||
linecount = 0;
|
||||
fproc = getptable(pname); /* proc table */
|
||||
fdblock = getdtable(dname); /* data block table */
|
||||
fproc = getptable(&pname); /* proc table */
|
||||
fdblock = getdtable(&dname); /* data block table */
|
||||
lpi_set = Cempty_set(plength);
|
||||
cai_set = Cempty_set(plength);
|
||||
if ((f = fopen(lname,"r")) == NULL) {
|
||||
@ -554,4 +540,5 @@ main(argc,argv)
|
||||
}
|
||||
putptable(fproc,f,TRUE);
|
||||
exit(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -34,8 +34,7 @@ short dfs_nr;
|
||||
bblock_p *vertex; /* dynamically allocated array */
|
||||
|
||||
|
||||
STATIC dfs(v)
|
||||
bblock_p v;
|
||||
static void dfs(bblock_p v)
|
||||
{
|
||||
/* Depth First Search */
|
||||
|
||||
@ -56,8 +55,7 @@ STATIC dfs(v)
|
||||
|
||||
|
||||
|
||||
STATIC compress(v)
|
||||
bblock_p v;
|
||||
static void compress(bblock_p v)
|
||||
{
|
||||
if (v->B_ANCESTOR->B_ANCESTOR != (bblock_p) 0) {
|
||||
compress(v->B_ANCESTOR);
|
||||
@ -70,7 +68,7 @@ STATIC compress(v)
|
||||
|
||||
|
||||
|
||||
STATIC bblock_p eval(v)
|
||||
static bblock_p eval(v)
|
||||
bblock_p v;
|
||||
{
|
||||
if (v->B_ANCESTOR == (bblock_p) 0) {
|
||||
@ -83,23 +81,20 @@ STATIC bblock_p eval(v)
|
||||
|
||||
|
||||
|
||||
STATIC linkblocks(v,w)
|
||||
bblock_p v,w;
|
||||
static void linkblocks(bblock_p v, bblock_p w)
|
||||
{
|
||||
w->B_ANCESTOR = v;
|
||||
}
|
||||
|
||||
|
||||
|
||||
dominators(r,n)
|
||||
bblock_p r;
|
||||
short n;
|
||||
void dominators(bblock_p r, short n)
|
||||
{
|
||||
/* Compute the immediate dominator of every basic
|
||||
* block in the control flow graph rooted by r.
|
||||
*/
|
||||
|
||||
register short i;
|
||||
short i;
|
||||
Lindex ind, next;
|
||||
bblock_p v,w,u;
|
||||
|
||||
@ -139,5 +134,5 @@ dominators(r,n)
|
||||
}
|
||||
}
|
||||
r->b_idom = (bblock_p) 0;
|
||||
oldmap(vertex,n); /* release memory for dynamic array vertex */
|
||||
oldmap((short **)vertex,n); /* release memory for dynamic array vertex */
|
||||
}
|
||||
|
||||
@ -9,8 +9,8 @@
|
||||
*/
|
||||
|
||||
|
||||
extern dominator(); /* (bblock_p head, short n)
|
||||
* Compute for every basic block its immediate
|
||||
void dominators(bblock_p r, short n);
|
||||
/* Compute for every basic block its immediate
|
||||
* dominator. The dominator relation is hence
|
||||
* recorded as a tree in which every node contains
|
||||
* a pointer to its parent, which is its
|
||||
|
||||
@ -45,8 +45,7 @@
|
||||
|
||||
|
||||
|
||||
STATIC bool same_loop(l1,l2)
|
||||
loop_p l1,l2;
|
||||
static bool same_loop(loop_p l1, loop_p l2)
|
||||
{
|
||||
/* Two loops are the same if:
|
||||
* (1) they have the same number of basic blocks, and
|
||||
@ -63,8 +62,7 @@ STATIC bool same_loop(l1,l2)
|
||||
|
||||
|
||||
|
||||
STATIC bool inner_loop(l1,l2)
|
||||
loop_p l1,l2;
|
||||
static bool inner_loop(loop_p l1, loop_p l2)
|
||||
{
|
||||
/* Loop l1 is an inner loop of l2 if:
|
||||
* (1) the first loop has fewer basic blocks than
|
||||
@ -82,10 +80,7 @@ STATIC bool inner_loop(l1,l2)
|
||||
|
||||
|
||||
|
||||
STATIC insrt(b,lpb,s_p)
|
||||
bblock_p b;
|
||||
lset *lpb;
|
||||
lset *s_p;
|
||||
static void insrt(bblock_p b, lset *lpb, lset *s_p)
|
||||
{
|
||||
/* Auxiliary routine used by 'natural_loop'.
|
||||
* Note that we use a set rather than a stack,
|
||||
@ -99,8 +94,7 @@ STATIC insrt(b,lpb,s_p)
|
||||
}
|
||||
|
||||
|
||||
STATIC loop_p natural_loop(d,n)
|
||||
bblock_p d,n;
|
||||
static loop_p natural_loop(bblock_p d, bblock_p n)
|
||||
{
|
||||
/* Find the basic blocks of the natural loop of the
|
||||
* back edge 'n->d' (i.e. n->d is an edge in the control
|
||||
@ -138,15 +132,12 @@ STATIC loop_p natural_loop(d,n)
|
||||
}
|
||||
|
||||
|
||||
STATIC loop_p org_loop(lp,loops)
|
||||
loop_p lp;
|
||||
lset loops;
|
||||
static loop_p org_loop(loop_p lp, lset loops)
|
||||
{
|
||||
/* See if the loop lp was already found via another
|
||||
* back edge; if so return this loop; else return 0.
|
||||
*/
|
||||
|
||||
register Lindex li;
|
||||
Lindex li;
|
||||
|
||||
for (li = Lfirst(loops); li != (Lindex) 0; li = Lnext(li,loops)) {
|
||||
if (same_loop((loop_p) Lelem(li), lp)) {
|
||||
@ -161,11 +152,10 @@ STATIC loop_p org_loop(lp,loops)
|
||||
|
||||
|
||||
|
||||
STATIC collapse_loops(loops_p)
|
||||
lset *loops_p;
|
||||
static void collapse_loops(lset *loops_p)
|
||||
{
|
||||
register Lindex li1, li2;
|
||||
register loop_p lp1,lp2;
|
||||
Lindex li1, li2;
|
||||
loop_p lp1,lp2;
|
||||
|
||||
for (li1 = Lfirst(*loops_p); li1 != (Lindex) 0; li1 = Lnext(li1,*loops_p)) {
|
||||
lp1 = (loop_p) Lelem(li1);
|
||||
@ -183,8 +173,7 @@ STATIC collapse_loops(loops_p)
|
||||
}
|
||||
|
||||
|
||||
STATIC loop_per_block(lp)
|
||||
loop_p lp;
|
||||
static void loop_per_block(loop_p lp)
|
||||
{
|
||||
bblock_p b;
|
||||
|
||||
@ -201,13 +190,12 @@ STATIC loop_per_block(lp)
|
||||
|
||||
|
||||
|
||||
STATIC loop_attrib(loops)
|
||||
lset loops;
|
||||
static void loop_attrib(lset loops)
|
||||
{
|
||||
/* Compute several attributes */
|
||||
|
||||
register Lindex li;
|
||||
register loop_p lp;
|
||||
Lindex li;
|
||||
loop_p lp;
|
||||
loop_id lastlpid = 0;
|
||||
|
||||
for (li = Lfirst(loops); li != (Lindex) 0; li = Lnext(li,loops)) {
|
||||
@ -219,8 +207,7 @@ STATIC loop_attrib(loops)
|
||||
|
||||
|
||||
|
||||
STATIC nest_levels(loops)
|
||||
lset loops;
|
||||
static void nest_levels(lset loops)
|
||||
{
|
||||
/* Compute the nesting levels of all loops of
|
||||
* the current procedure. For every loop we just count
|
||||
@ -229,9 +216,8 @@ STATIC nest_levels(loops)
|
||||
* of the current procedure. As this number tends to be
|
||||
* very small, there is no cause for alarm.
|
||||
*/
|
||||
|
||||
register Lindex li1, li2;
|
||||
register loop_p lp;
|
||||
Lindex li1, li2;
|
||||
loop_p lp;
|
||||
|
||||
for (li1 = Lfirst(loops); li1 != (Lindex) 0; li1 = Lnext(li1,loops)) {
|
||||
lp = (loop_p) Lelem(li1);
|
||||
@ -246,8 +232,7 @@ STATIC nest_levels(loops)
|
||||
}
|
||||
|
||||
|
||||
STATIC cleanup(loops)
|
||||
lset loops;
|
||||
static void cleanup(lset loops)
|
||||
{
|
||||
/* Throw away the LP_BLOCKS sets */
|
||||
|
||||
@ -259,14 +244,11 @@ STATIC cleanup(loops)
|
||||
}
|
||||
|
||||
|
||||
STATIC bool does_exit(b,lp)
|
||||
bblock_p b;
|
||||
loop_p lp;
|
||||
static bool does_exit(bblock_p b, loop_p lp)
|
||||
{
|
||||
/* See if b may exit the loop, i.e. if it
|
||||
* has a successor outside the loop
|
||||
*/
|
||||
|
||||
Lindex i;
|
||||
|
||||
for (i = Lfirst(b->b_succ); i != (Lindex) 0; i = Lnext(i,b->b_succ)) {
|
||||
@ -276,9 +258,7 @@ STATIC bool does_exit(b,lp)
|
||||
}
|
||||
|
||||
|
||||
STATIC mark_succ(b,lp)
|
||||
bblock_p b;
|
||||
loop_p lp;
|
||||
static void mark_succ(bblock_p b, loop_p lp)
|
||||
{
|
||||
Lindex i;
|
||||
bblock_p succ;
|
||||
@ -294,8 +274,7 @@ STATIC mark_succ(b,lp)
|
||||
}
|
||||
|
||||
|
||||
STATIC mark_blocks(lp)
|
||||
loop_p lp;
|
||||
static void mark_blocks(loop_p lp)
|
||||
{
|
||||
/* Mark the strong and firm blocks of a loop.
|
||||
* The last set of blocks consists of the end-block
|
||||
@ -335,8 +314,7 @@ STATIC mark_blocks(lp)
|
||||
|
||||
|
||||
|
||||
STATIC mark_loopblocks(loops)
|
||||
lset loops;
|
||||
static void mark_loopblocks(lset loops)
|
||||
{
|
||||
/* Determine for all loops which basic blocks
|
||||
* of the loop are strong (i.e. are executed
|
||||
@ -356,8 +334,7 @@ STATIC mark_loopblocks(loops)
|
||||
|
||||
|
||||
|
||||
loop_detection(p)
|
||||
proc_p p;
|
||||
void loop_detection(proc_p p)
|
||||
{
|
||||
/* Find all natural loops of procedure p. Every loop is
|
||||
* assigned a unique identifying number, a set of basic
|
||||
|
||||
@ -8,8 +8,8 @@
|
||||
* L O O P D E T E C T I O N
|
||||
*/
|
||||
|
||||
extern loop_detection(); /* (proc_p p)
|
||||
* Detect all loops of procedure p.
|
||||
void loop_detection(proc_p p);
|
||||
/* Detect all loops of procedure p.
|
||||
* Every basic block of p is assigned
|
||||
* a set of all loops it is part of.
|
||||
* For every loop we record the number
|
||||
|
||||
@ -26,8 +26,7 @@
|
||||
extern char em_flag[];
|
||||
|
||||
|
||||
STATIC succeeds(succ,pred)
|
||||
bblock_p succ, pred;
|
||||
static void succeeds(bblock_p succ, bblock_p pred)
|
||||
{
|
||||
assert(pred != (bblock_p) 0);
|
||||
if (succ != (bblock_p) 0) {
|
||||
@ -36,7 +35,6 @@ STATIC succeeds(succ,pred)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define IS_RETURN(i) (i == op_ret || i == op_rtt)
|
||||
#define IS_CASE_JUMP(i) (i == op_csa || i == op_csb)
|
||||
#define IS_UNCOND_JUMP(i) (i <= sp_lmnem && (em_flag[i-sp_fmnem] & EM_FLO) == FLO_T)
|
||||
@ -44,10 +42,7 @@ STATIC succeeds(succ,pred)
|
||||
#define TARGET(lnp) (lbmap[INSTRLAB(lnp)])
|
||||
#define ATARGET(arg) (lbmap[arg->a_a.a_instrlab])
|
||||
|
||||
|
||||
|
||||
STATIC arg_p skip_const(arg)
|
||||
arg_p arg;
|
||||
static arg_p skip_const(arg_p arg)
|
||||
{
|
||||
assert(arg != (arg_p) 0);
|
||||
switch(arg->a_type) {
|
||||
@ -62,9 +57,7 @@ STATIC arg_p skip_const(arg)
|
||||
}
|
||||
|
||||
|
||||
STATIC arg_p use_label(arg,b)
|
||||
arg_p arg;
|
||||
bblock_p b;
|
||||
static arg_p use_label(arg_p arg, bblock_p b)
|
||||
{
|
||||
if (arg->a_type == ARGINSTRLAB) {
|
||||
/* arg is a non-null label */
|
||||
@ -75,18 +68,14 @@ STATIC arg_p use_label(arg,b)
|
||||
|
||||
|
||||
|
||||
STATIC case_flow(instr,desc,b)
|
||||
short instr;
|
||||
line_p desc;
|
||||
bblock_p b;
|
||||
static void case_flow(short instr, line_p desc, bblock_p b)
|
||||
{
|
||||
/* Analyse the case descriptor (given as a ROM pseudo instruction).
|
||||
* Every instruction label appearing in the descriptor
|
||||
* heads a basic block that is a successor of the block
|
||||
* in which the case instruction appears (b).
|
||||
*/
|
||||
|
||||
register arg_p arg;
|
||||
arg_p arg;
|
||||
|
||||
assert(instr == op_csa || instr == op_csb);
|
||||
assert(TYPE(desc) == OPLIST);
|
||||
@ -120,8 +109,7 @@ STATIC case_flow(instr,desc,b)
|
||||
|
||||
|
||||
|
||||
STATIC line_p case_descr(lnp)
|
||||
line_p lnp;
|
||||
static line_p case_descr(line_p lnp)
|
||||
{
|
||||
/* lnp is the instruction just before a csa or csb,
|
||||
* so it is the instruction that pushes the address
|
||||
@ -130,8 +118,7 @@ STATIC line_p case_descr(lnp)
|
||||
* Note that this instruction will always be part
|
||||
* of the procedure in which the csa/csb occurs.
|
||||
*/
|
||||
|
||||
register line_p l;
|
||||
line_p l;
|
||||
dblock_p d;
|
||||
obj_p obj;
|
||||
dblock_id id;
|
||||
@ -172,13 +159,12 @@ STATIC line_p case_descr(lnp)
|
||||
}
|
||||
error("cannot find rom pseudo for case descriptor");
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
STATIC last2_instrs(b,last_out,prev_out)
|
||||
bblock_p b;
|
||||
line_p *last_out,*prev_out;
|
||||
static void last2_instrs(bblock_p b, line_p *last_out, line_p *prev_out)
|
||||
{
|
||||
/* Determine the last and one-but-last instruction
|
||||
* of basic block b. An end-pseudo is not regarded
|
||||
@ -186,7 +172,7 @@ STATIC last2_instrs(b,last_out,prev_out)
|
||||
* instruction, prev_out is 0.
|
||||
*/
|
||||
|
||||
register line_p l1,l2;
|
||||
line_p l1,l2;
|
||||
|
||||
l2 = b->b_start; /* first instruction of b */
|
||||
assert(l2 != (line_p) 0); /* block can not be empty */
|
||||
@ -203,16 +189,13 @@ STATIC last2_instrs(b,last_out,prev_out)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
control_flow(head)
|
||||
bblock_p head;
|
||||
void control_flow(bblock_p head)
|
||||
{
|
||||
/* compute the successor and predecessor relation
|
||||
* for every basic block.
|
||||
*/
|
||||
|
||||
register bblock_p b;
|
||||
bblock_p b;
|
||||
line_p lnp, prev;
|
||||
short instr;
|
||||
|
||||
|
||||
@ -8,8 +8,8 @@
|
||||
* S U C C E S S O R / P R E D E C E S S O R R E L A T I O N S
|
||||
*/
|
||||
|
||||
extern control_flow(); /* (bblock_p head)
|
||||
* Compute for every basic block
|
||||
void control_flow(bblock_p head);
|
||||
/* Compute for every basic block
|
||||
* its successors and predecessors
|
||||
* in the control flow graph.
|
||||
*/
|
||||
|
||||
@ -54,17 +54,14 @@
|
||||
*/
|
||||
|
||||
|
||||
STATIC int Scj; /* number of optimizations found */
|
||||
|
||||
STATIC showinstr();
|
||||
|
||||
static int Scj; /* number of optimizations found */
|
||||
|
||||
static void showinstr(line_p lnp);
|
||||
|
||||
#define DLINK(l1,l2) l1->l_next=l2; l2->l_prev=l1
|
||||
|
||||
|
||||
STATIC bool same_instr(l1,l2)
|
||||
line_p l1,l2;
|
||||
static bool same_instr(line_p l1, line_p l2)
|
||||
{
|
||||
/* See if l1 and l2 are the same instruction */
|
||||
|
||||
@ -83,12 +80,11 @@ STATIC bool same_instr(l1,l2)
|
||||
|
||||
|
||||
|
||||
STATIC line_p last_mnem(b)
|
||||
bblock_p b;
|
||||
static line_p last_mnem(bblock_p b)
|
||||
{
|
||||
/* Determine the last line of a list */
|
||||
|
||||
register line_p l;
|
||||
line_p l;
|
||||
|
||||
for (l = b->b_start; l->l_next != (line_p) 0; l = l->l_next);
|
||||
while (l != (line_p) 0 && (INSTR(l) < sp_fmnem || INSTR(l) > sp_lmnem)) {
|
||||
@ -98,8 +94,7 @@ STATIC line_p last_mnem(b)
|
||||
}
|
||||
|
||||
|
||||
STATIC bool is_desirable(text)
|
||||
line_p text;
|
||||
static bool is_desirable(line_p text)
|
||||
{
|
||||
/* We avoid to generate a BRAnch in the middle of some expression,
|
||||
* as the code generator will write the contents of the fakestack
|
||||
@ -134,11 +129,9 @@ STATIC bool is_desirable(text)
|
||||
}
|
||||
|
||||
|
||||
STATIC cp_loops(b1,b2)
|
||||
bblock_p b1,b2;
|
||||
static void cp_loops(bblock_p b1, bblock_p b2)
|
||||
{
|
||||
/* Copy the loopset of b2 to b1 */
|
||||
|
||||
Lindex i;
|
||||
loop_p lp;
|
||||
for (i = Lfirst(b2->b_loops); i != (Lindex) 0;
|
||||
@ -149,9 +142,7 @@ STATIC cp_loops(b1,b2)
|
||||
}
|
||||
|
||||
|
||||
STATIC jump_cross(l1,l2,b1,b2)
|
||||
line_p l1,l2;
|
||||
bblock_p b1,b2;
|
||||
static void jump_cross(line_p l1, line_p l2, bblock_p b1, bblock_p b2)
|
||||
{
|
||||
/* A cross-jump from block b2 to block b1 is found; the code in
|
||||
* block b2 from line l2 up to the BRAnch is removed; block b1 is
|
||||
@ -214,8 +205,7 @@ STATIC jump_cross(l1,l2,b1,b2)
|
||||
}
|
||||
|
||||
|
||||
STATIC bool try_tail(b1,b2)
|
||||
bblock_p b1,b2;
|
||||
static bool try_tail(bblock_p b1, bblock_p b2)
|
||||
{
|
||||
/* See if b1 and b2 end on the same sequence of instructions */
|
||||
|
||||
@ -263,8 +253,7 @@ STATIC bool try_tail(b1,b2)
|
||||
|
||||
|
||||
|
||||
STATIC bool try_pred(b)
|
||||
bblock_p b;
|
||||
static bool try_pred(bblock_p b)
|
||||
{
|
||||
/* See if there is any pair (b1,b2), both in PRED(b) for
|
||||
* which we can perform cross jumping.
|
||||
@ -289,8 +278,7 @@ STATIC bool try_pred(b)
|
||||
|
||||
|
||||
|
||||
cj_optimize(p)
|
||||
proc_p p;
|
||||
int cj_optimize(void *param)
|
||||
{
|
||||
/* Perform cross jumping for procedure p.
|
||||
* In case cases a cross-jumping optimization which give
|
||||
@ -299,10 +287,12 @@ cj_optimize(p)
|
||||
* untill we find no further optimizations.
|
||||
*/
|
||||
|
||||
proc_p p = (proc_p)param;
|
||||
|
||||
bblock_p b;
|
||||
bool changes = TRUE;
|
||||
|
||||
if (IS_ENTERED_WITH_GTO(p)) return;
|
||||
if (IS_ENTERED_WITH_GTO(p)) return 0;
|
||||
while(changes) {
|
||||
changes = FALSE;
|
||||
b = p->p_start;
|
||||
@ -314,12 +304,11 @@ cj_optimize(p)
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
go(argc,argv,no_action,cj_optimize,no_action,no_action);
|
||||
report("cross jumps",Scj);
|
||||
@ -334,8 +323,8 @@ main(argc,argv)
|
||||
|
||||
extern char em_mnem[]; /* The mnemonics of the EM instructions. */
|
||||
|
||||
STATIC showinstr(lnp) line_p lnp; {
|
||||
|
||||
static void showinstr(line_p lnp)
|
||||
{
|
||||
/* Makes the instruction in `lnp' human readable. Only lines that
|
||||
* can occur in expressions that are going to be eliminated are
|
||||
* properly handled.
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
|
||||
int Scs; /* Number of optimizations found. */
|
||||
|
||||
STATIC cs_clear()
|
||||
static void cs_clear()
|
||||
{
|
||||
clr_avails();
|
||||
clr_entities();
|
||||
@ -34,14 +34,13 @@ STATIC cs_clear()
|
||||
start_valnum();
|
||||
}
|
||||
|
||||
STATIC cs_optimize(p)
|
||||
proc_p p;
|
||||
static int cs_optimize(void *param)
|
||||
{
|
||||
/* Optimize all basic blocks of one procedure. */
|
||||
bblock_p rbp, bdone;
|
||||
proc_p p = (proc_p)param;
|
||||
|
||||
register bblock_p rbp, bdone;
|
||||
|
||||
if (IS_ENTERED_WITH_GTO(p)) return;
|
||||
if (IS_ENTERED_WITH_GTO(p)) return 0;
|
||||
avails = (avail_p) 0;
|
||||
entities = Lempty_set();
|
||||
cs_clear();
|
||||
@ -72,11 +71,10 @@ STATIC cs_optimize(p)
|
||||
eliminate(p);
|
||||
cs_clear();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
Scs = 0;
|
||||
go(argc, argv, no_action, cs_optimize, cs_machinit, no_action);
|
||||
|
||||
@ -7,21 +7,17 @@
|
||||
#include "../share/alloc.h"
|
||||
#include "cs.h"
|
||||
|
||||
occur_p newoccur(l1, l2, b)
|
||||
line_p l1, l2;
|
||||
bblock_p b;
|
||||
occur_p newoccur(line_p l1, line_p l2, bblock_p b)
|
||||
{
|
||||
/* Allocate a new struct occur and initialize it. */
|
||||
|
||||
register occur_p rop;
|
||||
occur_p rop;
|
||||
|
||||
rop = (occur_p) newcore(sizeof(struct occur));
|
||||
rop->oc_lfirst = l1; rop->oc_llast = l2; rop->oc_belongs = b;
|
||||
return rop;
|
||||
}
|
||||
|
||||
oldoccur(ocp)
|
||||
occur_p ocp;
|
||||
void oldoccur(occur_p ocp)
|
||||
{
|
||||
oldcore((char *) ocp, sizeof(struct occur));
|
||||
}
|
||||
@ -31,8 +27,7 @@ avail_p newavail()
|
||||
return (avail_p) newcore(sizeof(struct avail));
|
||||
}
|
||||
|
||||
oldavail(avp)
|
||||
avail_p avp;
|
||||
void oldavail(avail_p avp)
|
||||
{
|
||||
oldcore((char *) avp, sizeof(struct avail));
|
||||
}
|
||||
@ -42,8 +37,7 @@ entity_p newentity()
|
||||
return (entity_p) newcore(sizeof(struct entity));
|
||||
}
|
||||
|
||||
oldentity(enp)
|
||||
entity_p enp;
|
||||
void oldentity(entity_p enp)
|
||||
{
|
||||
oldcore((char *) enp, sizeof(struct entity));
|
||||
}
|
||||
|
||||
@ -3,27 +3,28 @@
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
extern occur_p newoccur(); /* (line_p l1, l2; bblock_p b)
|
||||
* Returns a pointer to a new struct occur
|
||||
|
||||
occur_p newoccur(line_p l1, line_p l2, bblock_p b);
|
||||
/* Returns a pointer to a new struct occur
|
||||
* and initializes it.
|
||||
*/
|
||||
|
||||
extern oldoccur(); /* (occur_p ocp)
|
||||
* Release the struct occur ocp points to.
|
||||
void oldoccur(occur_p ocp);
|
||||
/* Release the struct occur ocp points to.
|
||||
*/
|
||||
|
||||
extern avail_p newavail(); /* ()
|
||||
* Return a pointer to a new struct avail.
|
||||
avail_p newavail();
|
||||
/* Return a pointer to a new struct avail.
|
||||
*/
|
||||
|
||||
extern oldavail(); /* (avail_p avp)
|
||||
* Release the struct avail avp points to.
|
||||
void oldavail(avail_p avp);
|
||||
/* Release the struct avail avp points to.
|
||||
*/
|
||||
|
||||
extern entity_p newentity(); /* ()
|
||||
* Return a pointer to a new struct entity.
|
||||
entity_p newentity();
|
||||
/* Return a pointer to a new struct entity.
|
||||
*/
|
||||
|
||||
extern oldentity(); /* (entity_p enp)
|
||||
* Release the struct entity enp points to.
|
||||
void oldentity(entity_p enp);
|
||||
/* Release the struct entity enp points to.
|
||||
*/
|
||||
|
||||
@ -11,8 +11,7 @@
|
||||
#include "cs.h"
|
||||
#include "cs_entity.h"
|
||||
|
||||
offset array_elemsize(vn)
|
||||
valnum vn;
|
||||
offset array_elemsize(valnum vn)
|
||||
{
|
||||
/* Vn is the valuenumber of an entity that points to
|
||||
* an array-descriptor. The third element of this descriptor holds
|
||||
@ -36,14 +35,12 @@ offset array_elemsize(vn)
|
||||
return aoff(enp->en_ext->o_dblock->d_values, 2);
|
||||
}
|
||||
|
||||
occur_p occ_elem(i)
|
||||
Lindex i;
|
||||
occur_p occ_elem(Lindex i)
|
||||
{
|
||||
return (occur_p) Lelem(i);
|
||||
}
|
||||
|
||||
entity_p en_elem(i)
|
||||
Lindex i;
|
||||
entity_p en_elem(Lindex i)
|
||||
{
|
||||
return (entity_p) Lelem(i);
|
||||
}
|
||||
@ -61,7 +58,7 @@ valnum newvalnum()
|
||||
return ++val_no;
|
||||
}
|
||||
|
||||
start_valnum()
|
||||
void start_valnum()
|
||||
{
|
||||
/* Restart value numbering. */
|
||||
|
||||
|
||||
@ -3,28 +3,28 @@
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
extern offset array_elemsize(); /* (valnum vm)
|
||||
* Returns the size of array-elements,
|
||||
offset array_elemsize(valnum vn);
|
||||
/* Returns the size of array-elements,
|
||||
* if vn is the valuenumber of the
|
||||
* address of an array-descriptor.
|
||||
*/
|
||||
|
||||
extern occur_p occ_elem(); /* (Lindex i)
|
||||
* Returns a pointer to the occurrence
|
||||
occur_p occ_elem(Lindex i);
|
||||
/* Returns a pointer to the occurrence
|
||||
* of which i is an index in a set.
|
||||
*/
|
||||
|
||||
extern entity_p en_elem(); /* (Lindex i)
|
||||
* Returns a pointer to the entity
|
||||
entity_p en_elem(Lindex i);
|
||||
/* Returns a pointer to the entity
|
||||
* of which i is an index in a set.
|
||||
*/
|
||||
|
||||
extern valnum newvalnum(); /* ()
|
||||
* Returns a completely new
|
||||
valnum newvalnum();
|
||||
/* Returns a completely new
|
||||
* value number.
|
||||
*/
|
||||
|
||||
extern start_valnum(); /* ()
|
||||
* Restart value numbering.
|
||||
void start_valnum();
|
||||
/* Restart value numbering.
|
||||
*/
|
||||
|
||||
|
||||
@ -22,8 +22,7 @@
|
||||
|
||||
avail_p avails; /* The list of available expressions. */
|
||||
|
||||
STATIC bool commutative(instr)
|
||||
int instr;
|
||||
static bool commutative(int instr)
|
||||
{
|
||||
/* Is instr a commutative operator? */
|
||||
|
||||
@ -37,9 +36,7 @@ STATIC bool commutative(instr)
|
||||
}
|
||||
}
|
||||
|
||||
STATIC bool same_avail(kind, avp1, avp2)
|
||||
byte kind;
|
||||
avail_p avp1, avp2;
|
||||
static bool same_avail(byte kind, avail_p avp1, avail_p avp2)
|
||||
{
|
||||
/* Two expressions are the same if they have the same operator,
|
||||
* the same size, and their operand(s) have the same value.
|
||||
@ -58,25 +55,25 @@ STATIC bool same_avail(kind, avp1, avp2)
|
||||
return avp1->av_operand == avp2->av_operand;
|
||||
case BINAIR_OP:
|
||||
if (commutative(avp1->av_instr & BMASK))
|
||||
return avp1->av_oleft == avp2->av_oleft &&
|
||||
avp1->av_oright == avp2->av_oright
|
||||
||
|
||||
avp1->av_oleft == avp2->av_oright &&
|
||||
avp1->av_oright == avp2->av_oleft
|
||||
return ( (avp1->av_oleft == avp2->av_oleft) &&
|
||||
(avp1->av_oright == avp2->av_oright) )
|
||||
||
|
||||
( (avp1->av_oleft == avp2->av_oright) &&
|
||||
(avp1->av_oright == avp2->av_oleft) )
|
||||
;
|
||||
else
|
||||
return avp1->av_oleft == avp2->av_oleft &&
|
||||
avp1->av_oright == avp2->av_oright;
|
||||
return (avp1->av_oleft == avp2->av_oleft) &&
|
||||
(avp1->av_oright == avp2->av_oright);
|
||||
case TERNAIR_OP:
|
||||
return avp1->av_ofirst == avp2->av_ofirst &&
|
||||
avp1->av_osecond == avp2->av_osecond &&
|
||||
avp1->av_othird == avp2->av_othird;
|
||||
return (avp1->av_ofirst == avp2->av_ofirst) &&
|
||||
(avp1->av_osecond == avp2->av_osecond) &&
|
||||
(avp1->av_othird == avp2->av_othird);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC check_local(avp)
|
||||
avail_p avp;
|
||||
static void check_local(avail_p avp)
|
||||
{
|
||||
/* Check if the local in which the result of avp was stored,
|
||||
* still holds this result. Update if not.
|
||||
@ -89,9 +86,7 @@ STATIC check_local(avp)
|
||||
}
|
||||
}
|
||||
|
||||
STATIC entity_p result_local(size, l)
|
||||
offset size;
|
||||
line_p l;
|
||||
static entity_p result_local(offset size, line_p l)
|
||||
{
|
||||
/* If the result of an expression of size bytes is stored into a
|
||||
* local for which a registermessage was generated, return a pointer
|
||||
@ -103,7 +98,7 @@ STATIC entity_p result_local(size, l)
|
||||
if (l == (line_p) 0)
|
||||
return (entity_p) 0;
|
||||
|
||||
if (INSTR(l)==op_stl && size==ws || INSTR(l)==op_sdl && size==2*ws) {
|
||||
if ( ((INSTR(l)==op_stl) && (size==ws)) || ((INSTR(l)==op_sdl) && (size==2*ws)) ) {
|
||||
enp = getentity(l, &dummy);
|
||||
if (is_regvar(enp->en_loc)) {
|
||||
OUTTRACE("save local found, %ld(LB)", enp->en_loc);
|
||||
@ -114,9 +109,7 @@ STATIC entity_p result_local(size, l)
|
||||
return (entity_p) 0;
|
||||
}
|
||||
|
||||
STATIC copy_avail(kind, src, dst)
|
||||
int kind;
|
||||
avail_p src, dst;
|
||||
static void copy_avail(int kind, avail_p src, avail_p dst)
|
||||
{
|
||||
/* Copy some attributes from src to dst. */
|
||||
|
||||
@ -143,16 +136,13 @@ STATIC copy_avail(kind, src, dst)
|
||||
}
|
||||
}
|
||||
|
||||
avail_p av_enter(avp, ocp, kind)
|
||||
avail_p avp;
|
||||
occur_p ocp;
|
||||
int kind;
|
||||
avail_p av_enter(avail_p avp, occur_p ocp, int kind)
|
||||
{
|
||||
/* Put the available expression avp in the list,
|
||||
* if it is not already there.
|
||||
* Add ocp to the set of occurrences of this expression.
|
||||
*/
|
||||
register avail_p ravp;
|
||||
avail_p ravp;
|
||||
line_p last = ocp->oc_llast;
|
||||
|
||||
for (ravp = avails; ravp != (avail_p) 0; ravp = ravp->av_before) {
|
||||
@ -186,13 +176,13 @@ avail_p av_enter(avp, ocp, kind)
|
||||
return ravp;
|
||||
}
|
||||
|
||||
clr_avails()
|
||||
void clr_avails()
|
||||
{
|
||||
/* Throw away the information about the available expressions. */
|
||||
|
||||
register avail_p ravp, next;
|
||||
register Lindex i;
|
||||
register lset s;
|
||||
avail_p ravp, next;
|
||||
Lindex i;
|
||||
lset s;
|
||||
|
||||
for (ravp = avails; ravp != (avail_p) 0; ravp = next) {
|
||||
next = ravp->av_before;
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
*/
|
||||
extern avail_p avails; /* The set of available expressions. */
|
||||
|
||||
extern avail_p av_enter(); /* (avail_p avp, occur_p ocp, byte kind)
|
||||
* Puts the available expression in avp
|
||||
avail_p av_enter(avail_p avp, occur_p ocp, int kind);
|
||||
/* Puts the available expression in avp
|
||||
* in the list of available expressions,
|
||||
* if it is not already there. Add ocp to set of
|
||||
* occurrences of this expression.
|
||||
@ -18,6 +18,6 @@ extern avail_p av_enter(); /* (avail_p avp, occur_p ocp, byte kind)
|
||||
* Returns a pointer into the list.
|
||||
*/
|
||||
|
||||
extern clr_avails(); /* Release all space occupied by the old list
|
||||
* of available expressions.
|
||||
*/
|
||||
void clr_avails(); /* Release all space occupied by the old list
|
||||
* of available expressions.
|
||||
*/
|
||||
|
||||
@ -17,8 +17,7 @@
|
||||
|
||||
extern char em_mnem[]; /* The mnemonics of the EM instructions. */
|
||||
|
||||
STATIC showinstr(lnp)
|
||||
line_p lnp;
|
||||
static void showinstr(line_p lnp)
|
||||
{
|
||||
/* Makes the instruction in `lnp' human readable. Only lines that
|
||||
* can occur in expressions that are going to be eliminated are
|
||||
@ -49,12 +48,11 @@ STATIC showinstr(lnp)
|
||||
fprintf(stderr,"\n");
|
||||
}
|
||||
|
||||
SHOWOCCUR(ocp)
|
||||
occur_p ocp;
|
||||
void SHOWOCCUR(occur_p ocp)
|
||||
{
|
||||
/* Shows all instructions in an occurrence. */
|
||||
|
||||
register line_p lnp, next;
|
||||
line_p lnp, next;
|
||||
|
||||
if (verbose_flag) {
|
||||
for (lnp = ocp->oc_lfirst; lnp != (line_p) 0; lnp = next) {
|
||||
@ -69,8 +67,7 @@ SHOWOCCUR(ocp)
|
||||
|
||||
#ifdef TRACE
|
||||
|
||||
SHOWAVAIL(avp)
|
||||
avail_p avp;
|
||||
void SHOWAVAIL(avail_p avp)
|
||||
{
|
||||
/* Shows an available expression. */
|
||||
showinstr(avp->av_found);
|
||||
@ -79,9 +76,9 @@ SHOWAVAIL(avp)
|
||||
|
||||
}
|
||||
|
||||
OUTAVAILS()
|
||||
void OUTAVAILS()
|
||||
{
|
||||
register avail_p ravp;
|
||||
avail_p ravp;
|
||||
|
||||
fprintf(stderr,"AVAILABLE EXPRESSIONS\n");
|
||||
|
||||
@ -91,7 +88,7 @@ OUTAVAILS()
|
||||
}
|
||||
}
|
||||
|
||||
STATIC char *enkinds[] = {
|
||||
static char *enkinds[] = {
|
||||
"constant",
|
||||
"local",
|
||||
"external",
|
||||
@ -110,13 +107,13 @@ STATIC char *enkinds[] = {
|
||||
"ignore mask"
|
||||
};
|
||||
|
||||
OUTENTITIES()
|
||||
void OUTENTITIES()
|
||||
{
|
||||
register Lindex i;
|
||||
Lindex i;
|
||||
|
||||
fprintf(stderr,"ENTITIES\n");
|
||||
for (i = Lfirst(entities); i != (Lindex) 0; i = Lnext(i, entities)) {
|
||||
register entity_p rep = en_elem(i);
|
||||
entity_p rep = en_elem(i);
|
||||
|
||||
fprintf(stderr,"%s,", enkinds[rep->en_kind]);
|
||||
fprintf(stderr,"size %ld,", rep->en_size);
|
||||
|
||||
@ -20,8 +20,7 @@
|
||||
#include "cs_partit.h"
|
||||
#include "cs_debug.h"
|
||||
|
||||
STATIC dlink(l1, l2)
|
||||
line_p l1, l2;
|
||||
static void dlink(line_p l1, line_p l2)
|
||||
{
|
||||
/* Doubly link the lines in l1 and l2. */
|
||||
|
||||
@ -31,13 +30,12 @@ STATIC dlink(l1, l2)
|
||||
l2->l_prev = l1;
|
||||
}
|
||||
|
||||
STATIC remove_lines(first, last)
|
||||
line_p first, last;
|
||||
static void remove_lines(line_p first, line_p last)
|
||||
{
|
||||
/* Throw away the lines between and including first and last.
|
||||
* Don't worry about any pointers; the (must) have been taken care of.
|
||||
*/
|
||||
register line_p lnp, next;
|
||||
line_p lnp, next;
|
||||
|
||||
last->l_next = (line_p) 0; /* Delimit the list. */
|
||||
for (lnp = first; lnp != (line_p) 0; lnp = next) {
|
||||
@ -46,12 +44,11 @@ STATIC remove_lines(first, last)
|
||||
}
|
||||
}
|
||||
|
||||
STATIC bool contained(ocp1, ocp2)
|
||||
occur_p ocp1, ocp2;
|
||||
static bool contained(occur_p ocp1, occur_p ocp2)
|
||||
{
|
||||
/* Determine whether ocp1 is contained within ocp2. */
|
||||
|
||||
register line_p lnp, next;
|
||||
line_p lnp, next;
|
||||
|
||||
for (lnp = ocp2->oc_lfirst; lnp != (line_p) 0; lnp = next) {
|
||||
next = lnp != ocp2->oc_llast ? lnp->l_next : (line_p) 0;
|
||||
@ -61,9 +58,7 @@ STATIC bool contained(ocp1, ocp2)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
STATIC delete(ocp, start)
|
||||
occur_p ocp;
|
||||
avail_p start;
|
||||
static void delete(occur_p ocp, avail_p start)
|
||||
{
|
||||
/* Delete all occurrences that are contained within ocp.
|
||||
* They must have been entered in the list before start:
|
||||
@ -71,8 +66,8 @@ STATIC delete(ocp, start)
|
||||
* appears before the operator line of the other because EM-expressions
|
||||
* are postfix.
|
||||
*/
|
||||
register avail_p ravp;
|
||||
register Lindex i, next;
|
||||
avail_p ravp;
|
||||
Lindex i, next;
|
||||
|
||||
for (ravp = start; ravp != (avail_p) 0; ravp = ravp->av_before) {
|
||||
for (i = Lfirst(ravp->av_occurs); i != (Lindex) 0; i = next) {
|
||||
@ -90,10 +85,7 @@ STATIC delete(ocp, start)
|
||||
}
|
||||
}
|
||||
|
||||
STATIC complete_aar(lnp, instr, descr_vn)
|
||||
line_p lnp;
|
||||
int instr;
|
||||
valnum descr_vn;
|
||||
static void complete_aar(line_p lnp, int instr, valnum descr_vn)
|
||||
{
|
||||
/* Lnp is an instruction that loads the address of an array-element.
|
||||
* Instr tells us what effect we should achieve; load (instr is op_lar)
|
||||
@ -101,7 +93,7 @@ STATIC complete_aar(lnp, instr, descr_vn)
|
||||
* valuenumber of the address of the descriptor of this array.
|
||||
* We append a loi or sti of the correct number of bytes.
|
||||
*/
|
||||
register line_p lindir;
|
||||
line_p lindir;
|
||||
|
||||
lindir = int_line(array_elemsize(descr_vn));
|
||||
lindir->l_instr = instr == op_lar ? op_loi : op_sti;
|
||||
@ -109,15 +101,12 @@ STATIC complete_aar(lnp, instr, descr_vn)
|
||||
dlink(lnp, lindir);
|
||||
}
|
||||
|
||||
STATIC replace(ocp, tmp, avp)
|
||||
occur_p ocp;
|
||||
offset tmp;
|
||||
avail_p avp;
|
||||
static void replace(occur_p ocp, offset tmp, avail_p avp)
|
||||
{
|
||||
/* Replace the lines in the occurrence in ocp by a load of the
|
||||
* temporary with offset tmp.
|
||||
*/
|
||||
register line_p lol, first, last;
|
||||
line_p lol, first, last;
|
||||
|
||||
assert(avp->av_size == ws || avp->av_size == 2*ws);
|
||||
|
||||
@ -134,7 +123,7 @@ STATIC replace(ocp, tmp, avp)
|
||||
/* There may actually be a LAR or a SAR instruction; in that
|
||||
* case we have to complete the array-instruction.
|
||||
*/
|
||||
register int instr = INSTR(last);
|
||||
int instr = INSTR(last);
|
||||
|
||||
if (instr != op_aar) complete_aar(lol, instr, avp->av_othird);
|
||||
}
|
||||
@ -143,9 +132,7 @@ STATIC replace(ocp, tmp, avp)
|
||||
remove_lines(first, last);
|
||||
}
|
||||
|
||||
STATIC append(avp, tmp)
|
||||
avail_p avp;
|
||||
offset tmp;
|
||||
static void append(avail_p avp, offset tmp)
|
||||
{
|
||||
/* Avp->av_found points to a line with an operator in it. This
|
||||
* routine emits a sequence of instructions that saves the result
|
||||
@ -154,7 +141,7 @@ STATIC append(avp, tmp)
|
||||
* avp->av_size. If however the operator is an aar contained
|
||||
* within a lar or sar, we must first generate the aar.
|
||||
*/
|
||||
register line_p stl, lol;
|
||||
line_p stl, lol;
|
||||
|
||||
assert(avp->av_size == ws || avp->av_size == 2*ws);
|
||||
|
||||
@ -168,7 +155,7 @@ STATIC append(avp, tmp)
|
||||
dlink(avp->av_found, stl);
|
||||
|
||||
if (avp->av_instr == (byte) op_aar) {
|
||||
register int instr = INSTR(avp->av_found);
|
||||
int instr = INSTR(avp->av_found);
|
||||
|
||||
if (instr != op_aar) {
|
||||
complete_aar(lol, instr, avp->av_othird);
|
||||
@ -177,9 +164,7 @@ STATIC append(avp, tmp)
|
||||
}
|
||||
}
|
||||
|
||||
STATIC set_replace(avp, tmp)
|
||||
avail_p avp;
|
||||
offset tmp;
|
||||
static void set_replace(avail_p avp, offset tmp)
|
||||
{
|
||||
/* Avp->av_occurs is now a set of occurrences, each of which will be
|
||||
* replaced by a reference to a local.
|
||||
@ -187,8 +172,8 @@ STATIC set_replace(avp, tmp)
|
||||
* list those expressions that are physically contained in them,
|
||||
* because we cannot eliminate them again.
|
||||
*/
|
||||
register Lindex i;
|
||||
register lset s = avp->av_occurs;
|
||||
Lindex i;
|
||||
lset s = avp->av_occurs;
|
||||
|
||||
for (i = Lfirst(s); i != (Lindex) 0; i = Lnext(i, s)) {
|
||||
OUTVERBOSE("eliminate duplicate", 0);
|
||||
@ -199,8 +184,7 @@ STATIC set_replace(avp, tmp)
|
||||
}
|
||||
}
|
||||
|
||||
STATIC int reg_score(enp)
|
||||
entity_p enp;
|
||||
static int reg_score(entity_p enp)
|
||||
{
|
||||
/* Enp is a local that will go into a register.
|
||||
* We return its score upto now.
|
||||
@ -209,16 +193,13 @@ STATIC int reg_score(enp)
|
||||
return regv_arg(enp->en_loc, 4);
|
||||
}
|
||||
|
||||
STATIC line_p gen_mesreg(off, avp, pp)
|
||||
offset off;
|
||||
avail_p avp;
|
||||
proc_p pp;
|
||||
static line_p gen_mesreg(offset off, avail_p avp, proc_p pp)
|
||||
{
|
||||
/* Generate a register message for the local that will hold the
|
||||
* result of the expression in avp, at the appropriate place in
|
||||
* the procedure in pp.
|
||||
*/
|
||||
register line_p reg;
|
||||
line_p reg;
|
||||
|
||||
reg = reg_mes(off, (short) avp->av_size, regtype(avp->av_instr), 0);
|
||||
appnd_line(reg, pp->p_start->b_start);
|
||||
@ -226,13 +207,11 @@ STATIC line_p gen_mesreg(off, avp, pp)
|
||||
return reg;
|
||||
}
|
||||
|
||||
STATIC change_score(mes, score)
|
||||
line_p mes;
|
||||
int score;
|
||||
static void change_score(line_p mes, int score)
|
||||
{
|
||||
/* Change the score in the register message in mes to score. */
|
||||
|
||||
register arg_p ap = ARG(mes);
|
||||
arg_p ap = ARG(mes);
|
||||
|
||||
ap = ap->a_next; /* Offset. */
|
||||
ap = ap->a_next; /* Size. */
|
||||
@ -242,8 +221,7 @@ STATIC change_score(mes, score)
|
||||
ap->a_a.a_offset = score;
|
||||
}
|
||||
|
||||
eliminate(pp)
|
||||
proc_p pp;
|
||||
void eliminate(proc_p pp)
|
||||
{
|
||||
/* Eliminate costly common subexpressions within procedure pp.
|
||||
* We scan the available expressions in - with respect to time found -
|
||||
@ -254,10 +232,10 @@ eliminate(pp)
|
||||
* Code is appended to the first occurrence of the expression
|
||||
* to store the result into a local.
|
||||
*/
|
||||
register avail_p ravp;
|
||||
register int score;
|
||||
register offset tmp;
|
||||
register line_p mes;
|
||||
avail_p ravp;
|
||||
int score;
|
||||
offset tmp;
|
||||
line_p mes;
|
||||
|
||||
for (ravp = avails; ravp != (avail_p) 0; ravp = ravp->av_before) {
|
||||
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
extern eliminate(); /* (proc_p pp)
|
||||
* Eliminate some of the recurrences of expressions
|
||||
void eliminate(proc_p pp);
|
||||
/* Eliminate some of the recurrences of expressions
|
||||
* that were found by the valuenumbering
|
||||
* algorithm.
|
||||
*/
|
||||
|
||||
@ -18,12 +18,10 @@
|
||||
|
||||
lset entities; /* Our pseudo symbol-table. */
|
||||
|
||||
entity_p find_entity(vn)
|
||||
valnum vn;
|
||||
entity_p find_entity(valnum vn)
|
||||
{
|
||||
/* Try to find the entity with valuenumber vn. */
|
||||
|
||||
register Lindex i;
|
||||
Lindex i;
|
||||
|
||||
for (i = Lfirst(entities); i != (Lindex) 0; i = Lnext(i, entities)) {
|
||||
if (en_elem(i)->en_vn == vn)
|
||||
@ -33,8 +31,7 @@ entity_p find_entity(vn)
|
||||
return (entity_p) 0;
|
||||
}
|
||||
|
||||
STATIC bool same_entity(enp1, enp2)
|
||||
entity_p enp1, enp2;
|
||||
static bool same_entity(entity_p enp1, entity_p enp2)
|
||||
{
|
||||
if (enp1->en_kind != enp2->en_kind) return FALSE;
|
||||
if (enp1->en_size != enp2->en_size) return FALSE;
|
||||
@ -69,8 +66,7 @@ STATIC bool same_entity(enp1, enp2)
|
||||
}
|
||||
}
|
||||
|
||||
STATIC copy_entity(src, dst)
|
||||
entity_p src, dst;
|
||||
static void copy_entity(entity_p src, entity_p dst)
|
||||
{
|
||||
dst->en_static = src->en_static;
|
||||
dst->en_kind = src->en_kind;
|
||||
@ -111,14 +107,13 @@ STATIC copy_entity(src, dst)
|
||||
}
|
||||
}
|
||||
|
||||
entity_p en_enter(enp)
|
||||
register entity_p enp;
|
||||
entity_p en_enter(entity_p enp)
|
||||
{
|
||||
/* Put the entity in enp in the entity set, if it is not already there.
|
||||
* Return pointer to stored entity.
|
||||
*/
|
||||
register Lindex i;
|
||||
register entity_p new;
|
||||
Lindex i;
|
||||
entity_p new;
|
||||
|
||||
for (i = Lfirst(entities); i != (Lindex) 0; i = Lnext(i, entities)) {
|
||||
if (same_entity(en_elem(i), enp))
|
||||
@ -133,11 +128,10 @@ entity_p en_enter(enp)
|
||||
return new;
|
||||
}
|
||||
|
||||
clr_entities()
|
||||
void clr_entities()
|
||||
{
|
||||
/* Throw away all pseudo-symboltable information. */
|
||||
|
||||
register Lindex i;
|
||||
Lindex i;
|
||||
|
||||
for (i = Lfirst(entities); i != (Lindex) 0; i = Lnext(i, entities)) {
|
||||
oldentity(en_elem(i));
|
||||
|
||||
@ -5,16 +5,16 @@
|
||||
*/
|
||||
extern lset entities; /* The pseudo-symboltable. */
|
||||
|
||||
extern entity_p find_entity(); /* (valnum vn)
|
||||
* Tries to find an entity with value number vn.
|
||||
entity_p find_entity(valnum vn);
|
||||
/* Tries to find an entity with value number vn.
|
||||
*/
|
||||
|
||||
extern entity_p en_enter(); /* (entity_p enp)
|
||||
* Enter the entity in enp in the set of
|
||||
entity_p en_enter(entity_p enp);
|
||||
/* Enter the entity in enp in the set of
|
||||
* entities if it was not already there.
|
||||
*/
|
||||
|
||||
extern clr_entities(); /* ()
|
||||
* Release all space occupied by our
|
||||
void clr_entities();
|
||||
/* Release all space occupied by our
|
||||
* pseudo-symboltable.
|
||||
*/
|
||||
|
||||
@ -17,8 +17,9 @@
|
||||
#include "cs_avail.h"
|
||||
#include "cs_entity.h"
|
||||
|
||||
STATIC base_valno(enp)
|
||||
entity_p enp;
|
||||
#include "cs_kill.h"
|
||||
|
||||
static int base_valno(entity_p enp)
|
||||
{
|
||||
/* Return the value number of the (base) address of an indirectly
|
||||
* accessed entity.
|
||||
@ -35,17 +36,17 @@ STATIC base_valno(enp)
|
||||
return enp->en_arbase;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC entity_p find_base(vn)
|
||||
valnum vn;
|
||||
static entity_p find_base(valnum vn)
|
||||
{
|
||||
/* Vn is the valuenumber of the (base) address of an indirectly
|
||||
* accessed entity. Return the entity that holds this address
|
||||
* recursively.
|
||||
*/
|
||||
register Lindex i;
|
||||
register avail_p ravp;
|
||||
Lindex i;
|
||||
avail_p ravp;
|
||||
|
||||
for (i = Lfirst(entities); i != (Lindex) 0; i = Lnext(i, entities)) {
|
||||
register entity_p renp = en_elem(i);
|
||||
@ -79,8 +80,7 @@ STATIC entity_p find_base(vn)
|
||||
return (entity_p) 0;
|
||||
}
|
||||
|
||||
STATIC bool obj_overlap(op1, op2)
|
||||
obj_p op1, op2;
|
||||
static bool obj_overlap(obj_p op1, obj_p op2)
|
||||
{
|
||||
/* Op1 and op2 point to two objects in the same datablock.
|
||||
* Obj_overlap returns whether these objects might overlap.
|
||||
@ -97,8 +97,7 @@ STATIC bool obj_overlap(op1, op2)
|
||||
|
||||
#define same_datablock(o1, o2) ((o1)->o_dblock == (o2)->o_dblock)
|
||||
|
||||
STATIC bool addr_local(enp)
|
||||
entity_p enp;
|
||||
static bool addr_local(entity_p enp)
|
||||
{
|
||||
/* Is enp the address of a stack item. */
|
||||
|
||||
@ -108,17 +107,14 @@ STATIC bool addr_local(enp)
|
||||
enp->en_kind == ENAARGBASE;
|
||||
}
|
||||
|
||||
STATIC bool addr_external(enp)
|
||||
entity_p enp;
|
||||
static bool addr_external(entity_p enp)
|
||||
{
|
||||
/* Is enp the address of an external. */
|
||||
|
||||
return enp != (entity_p) 0 && enp->en_kind == ENAEXTERNAL;
|
||||
}
|
||||
|
||||
STATIC kill_external(obp, indir)
|
||||
obj_p obp;
|
||||
int indir;
|
||||
static void kill_external(obj_p obp, int indir)
|
||||
{
|
||||
/* A store is done via the object in obp. If this store is direct
|
||||
* we kill directly accessed entities in the same data block only
|
||||
@ -127,7 +123,7 @@ STATIC kill_external(obp, indir)
|
||||
* proven taht they are not in the same data block, are killed in
|
||||
* both cases.
|
||||
*/
|
||||
register Lindex i;
|
||||
Lindex i;
|
||||
|
||||
OUTTRACE("kill external", 0);
|
||||
for (i = Lfirst(entities); i != (Lindex) 0; i = Lnext(i, entities)) {
|
||||
@ -164,8 +160,7 @@ STATIC kill_external(obp, indir)
|
||||
}
|
||||
}
|
||||
|
||||
STATIC bool loc_overlap(enp1, enp2)
|
||||
entity_p enp1, enp2;
|
||||
static bool loc_overlap(entity_p enp1, entity_p enp2)
|
||||
{
|
||||
/* Enp1 and enp2 point to two locals. Loc_overlap returns whether
|
||||
* they overlap.
|
||||
@ -184,13 +179,10 @@ STATIC bool loc_overlap(enp1, enp2)
|
||||
enp1->en_loc + enp1->en_size > enp2->en_loc;
|
||||
}
|
||||
|
||||
STATIC kill_local(enp, indir)
|
||||
entity_p enp;
|
||||
bool indir;
|
||||
static void kill_local(entity_p enp, bool indir)
|
||||
{
|
||||
/* This time a store is done into an ENLOCAL. */
|
||||
|
||||
register Lindex i;
|
||||
Lindex i;
|
||||
|
||||
OUTTRACE("kill local", 0);
|
||||
for (i = Lfirst(entities); i != (Lindex) 0; i = Lnext(i, entities)) {
|
||||
@ -234,15 +226,14 @@ STATIC kill_local(enp, indir)
|
||||
}
|
||||
}
|
||||
|
||||
STATIC kill_sim()
|
||||
static void kill_sim()
|
||||
{
|
||||
/* A store is done into the ENIGNMASK. */
|
||||
|
||||
register Lindex i;
|
||||
Lindex i;
|
||||
|
||||
OUTTRACE("kill sim", 0);
|
||||
for (i = Lfirst(entities); i != (Lindex) 0; i = Lnext(i, entities)) {
|
||||
register entity_p rep = en_elem(i);
|
||||
entity_p rep = en_elem(i);
|
||||
|
||||
if (rep->en_kind == ENIGNMASK) {
|
||||
OUTTRACE("kill %d", rep->en_vn);
|
||||
@ -252,8 +243,7 @@ STATIC kill_sim()
|
||||
}
|
||||
}
|
||||
|
||||
kill_direct(enp)
|
||||
entity_p enp;
|
||||
void kill_direct(entity_p enp)
|
||||
{
|
||||
/* A store will be done into enp. We must forget the values of all the
|
||||
* entities this one may overlap with.
|
||||
@ -274,8 +264,7 @@ kill_direct(enp)
|
||||
}
|
||||
}
|
||||
|
||||
kill_indir(enp)
|
||||
entity_p enp;
|
||||
void kill_indir(entity_p enp)
|
||||
{
|
||||
/* An indirect store is done, in an ENINDIR,
|
||||
* an ENOFFSETTED or an ENARRELEM.
|
||||
@ -306,7 +295,7 @@ kill_indir(enp)
|
||||
}
|
||||
}
|
||||
|
||||
kill_much()
|
||||
void kill_much()
|
||||
{
|
||||
/* Kills all killable entities,
|
||||
* except the locals for which a registermessage was generated.
|
||||
@ -324,8 +313,7 @@ kill_much()
|
||||
}
|
||||
}
|
||||
|
||||
STATIC bool bad_procflags(pp)
|
||||
proc_p pp;
|
||||
static bool bad_procflags(proc_p pp)
|
||||
{
|
||||
/* Return whether the flags about the procedure in pp indicate
|
||||
* that we have little information about it. It might be that
|
||||
@ -335,13 +323,12 @@ STATIC bool bad_procflags(pp)
|
||||
return !(pp->p_flags1 & PF_BODYSEEN) || (pp->p_flags1 & PF_CALUNKNOWN);
|
||||
}
|
||||
|
||||
STATIC kill_globset(s)
|
||||
cset s;
|
||||
static void kill_globset(cset s)
|
||||
{
|
||||
/* S is a set of global variables that might be changed.
|
||||
* We act as if a direct store is done into each of them.
|
||||
*/
|
||||
register Cindex i;
|
||||
Cindex i;
|
||||
|
||||
OUTTRACE("kill globset", 0);
|
||||
for (i = Cfirst(s); i != (Cindex) 0; i = Cnext(i,s)) {
|
||||
@ -349,8 +336,7 @@ STATIC kill_globset(s)
|
||||
}
|
||||
}
|
||||
|
||||
kill_call(pp)
|
||||
proc_p pp;
|
||||
void kill_call(proc_p pp)
|
||||
{
|
||||
/* Kill everything that might be destroyed by calling
|
||||
* the procedure in pp.
|
||||
@ -367,11 +353,10 @@ kill_call(pp)
|
||||
}
|
||||
}
|
||||
|
||||
kill_all()
|
||||
void kill_all()
|
||||
{
|
||||
/* Kills all entities. */
|
||||
|
||||
register Lindex i;
|
||||
Lindex i;
|
||||
|
||||
OUTTRACE("kill all entities", 0);
|
||||
for (i = Lfirst(entities); i != (Lindex) i; i = Lnext(i, entities)) {
|
||||
|
||||
@ -3,27 +3,27 @@
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
extern kill_call(); /* (proc_p pp)
|
||||
* Kill all entities that might have an other value
|
||||
void kill_call(proc_p pp);
|
||||
/* Kill all entities that might have an other value
|
||||
* after execution of the procedure in pp.
|
||||
*/
|
||||
|
||||
extern kill_much(); /* ()
|
||||
* Kill all killable entities except those for which
|
||||
void kill_much();
|
||||
/* Kill all killable entities except those for which
|
||||
* a register message was generated.
|
||||
* Constants, addresses, etc are not killable.
|
||||
*/
|
||||
|
||||
extern kill_indir(); /* (entity_p enp)
|
||||
* Kill all entities that might have an other value
|
||||
void kill_indir(entity_p enp);
|
||||
/* Kill all entities that might have an other value
|
||||
* after indirect assignment to the entity in enp.
|
||||
*/
|
||||
|
||||
extern kill_direct(); /* (entity_p enp)
|
||||
* Kill all entities that might have an other value
|
||||
void kill_direct(entity_p enp);
|
||||
/* Kill all entities that might have an other value
|
||||
* after direct assignment to the entity in enp.
|
||||
*/
|
||||
|
||||
extern kill_all(); /* ()
|
||||
* Kill all entities.
|
||||
void kill_all();
|
||||
/* Kill all entities.
|
||||
*/
|
||||
|
||||
@ -16,6 +16,8 @@
|
||||
#include "cs.h"
|
||||
#include "cs_stack.h"
|
||||
|
||||
#include "cs_partit.h"
|
||||
|
||||
#define XXX (-1)
|
||||
#define ARGW 0
|
||||
#define WS 1
|
||||
@ -28,7 +30,7 @@
|
||||
#define PTR 1
|
||||
#define FLT 2
|
||||
|
||||
STATIC struct {
|
||||
static struct {
|
||||
byte i_group; /* Group of instruction. */
|
||||
byte i_op1; /* Indication of size of operand of unary operator. */
|
||||
/* Idem for 1st operand of binary operator. */
|
||||
@ -178,8 +180,7 @@ STATIC struct {
|
||||
#define AVSIZE(l) (info[INSTR(l)].i_av)
|
||||
#define REGTYPE(n) (info[n].i_regtype)
|
||||
|
||||
int instrgroup(lnp)
|
||||
line_p lnp;
|
||||
int instrgroup(line_p lnp)
|
||||
{
|
||||
if (INSTR(lnp) == op_lor && SHORT(lnp) == 1) {
|
||||
/* We can't do anything with the stackpointer. */
|
||||
@ -192,8 +193,7 @@ int instrgroup(lnp)
|
||||
return GROUP(INSTR(lnp));
|
||||
}
|
||||
|
||||
bool stack_group(instr)
|
||||
int instr;
|
||||
bool stack_group(int instr)
|
||||
{
|
||||
/* Is this an instruction that only does something to the top of
|
||||
* the stack?
|
||||
@ -209,10 +209,10 @@ bool stack_group(instr)
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC offset argw(lnp)
|
||||
line_p lnp;
|
||||
static offset argw(line_p lnp)
|
||||
{
|
||||
/* Some EM-instructions have their argument either on the same line,
|
||||
* or on top of the stack. We give up when the argument is on top of
|
||||
@ -226,10 +226,10 @@ STATIC offset argw(lnp)
|
||||
Pop(&dummy, (offset) ws);
|
||||
return UNKNOWN_SIZE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
offset op11size(lnp)
|
||||
line_p lnp;
|
||||
offset op11size(line_p lnp)
|
||||
{
|
||||
/* Returns the size of the first argument of
|
||||
* the unary operator in lnp.
|
||||
@ -246,10 +246,10 @@ offset op11size(lnp)
|
||||
assert(FALSE);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
offset op12size(lnp)
|
||||
line_p lnp;
|
||||
offset op12size(line_p lnp)
|
||||
{
|
||||
/* Same for first of binary. */
|
||||
|
||||
@ -262,10 +262,10 @@ offset op12size(lnp)
|
||||
assert(FALSE);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
offset op22size(lnp)
|
||||
line_p lnp;
|
||||
offset op22size(line_p lnp)
|
||||
{
|
||||
switch (OP2SIZE(lnp)) {
|
||||
case ARGW:
|
||||
@ -278,12 +278,12 @@ offset op22size(lnp)
|
||||
assert(FALSE);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Ternary operators are op_aar and conversions between types and/or sizes. */
|
||||
|
||||
offset op13size(lnp)
|
||||
line_p lnp;
|
||||
offset op13size(line_p lnp)
|
||||
{
|
||||
/* When the instruction is a conversion, the size of the first
|
||||
* operand is the value of the second operand.
|
||||
@ -301,8 +301,7 @@ offset op13size(lnp)
|
||||
return UNKNOWN_SIZE;
|
||||
}
|
||||
|
||||
offset op23size(lnp)
|
||||
line_p lnp;
|
||||
offset op23size(line_p lnp)
|
||||
{
|
||||
if (INSTR(lnp) == op_aar)
|
||||
return argw(lnp);
|
||||
@ -310,8 +309,7 @@ offset op23size(lnp)
|
||||
return ws;
|
||||
}
|
||||
|
||||
offset op33size(lnp)
|
||||
line_p lnp;
|
||||
offset op33size(line_p lnp)
|
||||
{
|
||||
if (INSTR(lnp) == op_aar)
|
||||
return ps;
|
||||
@ -319,8 +317,7 @@ offset op33size(lnp)
|
||||
return ws;
|
||||
}
|
||||
|
||||
offset avsize(lnp)
|
||||
line_p lnp;
|
||||
offset avsize(line_p lnp)
|
||||
{
|
||||
/* Returns the size of the result of the instruction in lnp.
|
||||
* If the instruction is a conversion this size is given on the stack.
|
||||
@ -357,10 +354,10 @@ offset avsize(lnp)
|
||||
break;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int regtype(instr)
|
||||
byte instr;
|
||||
int regtype(byte instr)
|
||||
{
|
||||
switch (REGTYPE(instr & BMASK)) {
|
||||
case ANY:
|
||||
@ -373,4 +370,5 @@ int regtype(instr)
|
||||
assert(FALSE);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -7,54 +7,54 @@
|
||||
* "manageable chunks.
|
||||
*/
|
||||
|
||||
extern int instrgroup(); /* (line_p lnp)
|
||||
* Return the group into which the instruction
|
||||
int instrgroup(line_p lnp);
|
||||
/* Return the group into which the instruction
|
||||
* in lnp belongs to.
|
||||
*/
|
||||
|
||||
extern bool stack_group(); /* (int instr)
|
||||
* Return whether instr is an instruction that
|
||||
bool stack_group(int instr);
|
||||
/* Return whether instr is an instruction that
|
||||
* only changes the state of the stack, i.e.
|
||||
* is a "true" operator.
|
||||
*/
|
||||
|
||||
extern offset op11size(); /* (line_p lnp)
|
||||
* Return the size of the operand of the unary
|
||||
offset op11size(line_p lnp);
|
||||
/* Return the size of the operand of the unary
|
||||
* operator in lnp.
|
||||
*/
|
||||
|
||||
extern offset op12size(); /* (line_p lnp)
|
||||
* Return the size of the first operand of the
|
||||
offset op12size(line_p lnp);
|
||||
/* Return the size of the first operand of the
|
||||
* binary operator in lnp.
|
||||
*/
|
||||
|
||||
extern offset op22size(); /* (line_p lnp)
|
||||
* Return the size of the second operand of the
|
||||
offset op22size(line_p lnp);
|
||||
/* Return the size of the second operand of the
|
||||
* binary operator in lnp.
|
||||
*/
|
||||
|
||||
extern offset op13size(); /* (line_p lnp)
|
||||
* Return the size of the first operand of the
|
||||
offset op13size(line_p lnp);
|
||||
/* Return the size of the first operand of the
|
||||
* ternary operator in lnp.
|
||||
*/
|
||||
|
||||
extern offset op23size(); /* (line_p lnp)
|
||||
* Return the size of the second operand of the
|
||||
offset op23size(line_p lnp);
|
||||
/* Return the size of the second operand of the
|
||||
* ternary operator in lnp.
|
||||
*/
|
||||
|
||||
extern offset op33size(); /* (line_p lnp)
|
||||
* Return the size of the third operand of the
|
||||
offset op33size(line_p lnp);
|
||||
/* Return the size of the third operand of the
|
||||
* ternary operator in lnp.
|
||||
*/
|
||||
|
||||
extern offset avsize(); /* (line_p lnp)
|
||||
* Return the size of the result of the
|
||||
offset avsize(line_p lnp);
|
||||
/* Return the size of the result of the
|
||||
* operator in lnp.
|
||||
*/
|
||||
|
||||
extern int regtype(); /* (byte instr)
|
||||
* Return in what kind of machine-register
|
||||
int regtype(byte instr);
|
||||
/* Return in what kind of machine-register
|
||||
* the result of instr should be stored:
|
||||
* pointer, float, or any.
|
||||
*/
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <em_mnem.h>
|
||||
#include <em_spec.h>
|
||||
#include "../share/types.h"
|
||||
@ -18,16 +19,14 @@
|
||||
#include "cs_avail.h"
|
||||
#include "cs_partit.h"
|
||||
|
||||
STATIC cset addr_modes;
|
||||
STATIC cset cheaps;
|
||||
STATIC cset forbidden;
|
||||
STATIC cset sli_counts;
|
||||
STATIC short LX_threshold;
|
||||
STATIC short AR_limit;
|
||||
static cset addr_modes;
|
||||
static cset cheaps;
|
||||
static cset forbidden;
|
||||
static cset sli_counts;
|
||||
static short LX_threshold;
|
||||
static short AR_limit;
|
||||
|
||||
STATIC get_instrs(f, s_p)
|
||||
FILE *f;
|
||||
cset *s_p;
|
||||
static void get_instrs(FILE *f, cset *s_p)
|
||||
{
|
||||
/* Read a set of integers from inputfile f into *s_p.
|
||||
* Such a set must be delimited by a negative number.
|
||||
@ -41,9 +40,7 @@ STATIC get_instrs(f, s_p)
|
||||
}
|
||||
}
|
||||
|
||||
STATIC choose_cset(f, s_p, max)
|
||||
FILE *f;
|
||||
cset *s_p;
|
||||
static void choose_cset(FILE *f, cset *s_p, int max)
|
||||
{
|
||||
/* Read two compact sets of integers from inputfile f.
|
||||
* Choose the first if we optimize with respect to time,
|
||||
@ -64,11 +61,11 @@ STATIC choose_cset(f, s_p, max)
|
||||
Cdeleteset(cs1); Cdeleteset(cs2);
|
||||
}
|
||||
|
||||
cs_machinit(f)
|
||||
FILE *f;
|
||||
void cs_machinit(void *param)
|
||||
{
|
||||
char s[100];
|
||||
int time, space;
|
||||
FILE *f = (FILE*)param;
|
||||
|
||||
/* Find piece that is relevant for this phase. */
|
||||
do {
|
||||
@ -114,8 +111,7 @@ cs_machinit(f)
|
||||
choose_cset(f, &forbidden, sp_lmnem);
|
||||
}
|
||||
|
||||
STATIC bool sli_no_eliminate(lnp)
|
||||
line_p lnp;
|
||||
static bool sli_no_eliminate(line_p lnp)
|
||||
{
|
||||
/* Return whether the SLI-instruction in lnp is part of
|
||||
* an array-index computation, and should not be eliminated.
|
||||
@ -129,8 +125,7 @@ STATIC bool sli_no_eliminate(lnp)
|
||||
;
|
||||
}
|
||||
|
||||
STATIC bool gains(avp)
|
||||
avail_p avp;
|
||||
static bool gains(avail_p avp)
|
||||
{
|
||||
/* Return whether we can gain something, when we eliminate
|
||||
* an expression such as in avp. We just glue together some
|
||||
@ -160,11 +155,9 @@ STATIC bool gains(avp)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
STATIC bool okay_lines(avp, ocp)
|
||||
avail_p avp;
|
||||
occur_p ocp;
|
||||
static bool okay_lines(avail_p avp, occur_p ocp)
|
||||
{
|
||||
register line_p lnp, next;
|
||||
line_p lnp, next;
|
||||
offset sz;
|
||||
|
||||
for (lnp = ocp->oc_lfirst; lnp != (line_p) 0; lnp = next) {
|
||||
@ -193,10 +186,9 @@ STATIC bool okay_lines(avp, ocp)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool desirable(avp)
|
||||
avail_p avp;
|
||||
bool desirable(avail_p avp)
|
||||
{
|
||||
register Lindex i, next;
|
||||
Lindex i, next;
|
||||
|
||||
if (!gains(avp)) {
|
||||
OUTTRACE("no gain", 0);
|
||||
|
||||
@ -3,12 +3,12 @@
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
extern cs_machinit(); /* (FILE *f)
|
||||
* Read phase-specific information from f.
|
||||
int cs_machinit(void *param);
|
||||
/* Read phase-specific information from f.
|
||||
*/
|
||||
|
||||
extern bool desirable(); /* (avail_p avp)
|
||||
* Return whether it is desirable to eliminate
|
||||
bool desirable(avail_p avp);
|
||||
/* Return whether it is desirable to eliminate
|
||||
* the recurrences of the expression in avp.
|
||||
* At the same time delete the recurrences
|
||||
* for which it is not allowed.
|
||||
|
||||
@ -23,8 +23,7 @@ STATIC token_p free_token;
|
||||
#define Stack_empty() (free_token == &Stack[0])
|
||||
#define Top (free_token - 1)
|
||||
|
||||
Push(tkp)
|
||||
token_p tkp;
|
||||
void Push(token_p tkp)
|
||||
{
|
||||
if (tkp->tk_size == UNKNOWN_SIZE) {
|
||||
Empty_stack(); /* The contents of the Stack is useless. */
|
||||
@ -39,9 +38,7 @@ Push(tkp)
|
||||
|
||||
#define WORD_MULTIPLE(n) ((n / ws) * ws + ( n % ws ? ws : 0 ))
|
||||
|
||||
Pop(tkp, size)
|
||||
token_p tkp;
|
||||
offset size;
|
||||
void Pop(token_p tkp, offset size)
|
||||
{
|
||||
/* Pop a token with given size from the valuenumber stack into tkp. */
|
||||
|
||||
@ -84,8 +81,7 @@ Pop(tkp, size)
|
||||
}
|
||||
}
|
||||
|
||||
Dup(lnp)
|
||||
line_p lnp;
|
||||
void Dup(line_p lnp)
|
||||
{
|
||||
/* Duplicate top bytes on the Stack. */
|
||||
|
||||
@ -131,7 +127,7 @@ Dup(lnp)
|
||||
}
|
||||
}
|
||||
|
||||
clr_stack()
|
||||
void clr_stack()
|
||||
{
|
||||
free_token = &Stack[0];
|
||||
}
|
||||
|
||||
@ -3,21 +3,21 @@
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
extern Push(); /* (token_p tkp)
|
||||
* Push the token in tkp on the fake-stack.
|
||||
void Push(token_p tkp);
|
||||
/* Push the token in tkp on the fake-stack.
|
||||
*/
|
||||
|
||||
extern Pop(); /* (token_p tkp; offset size)
|
||||
* Pop a token of size bytes from the fake-stack
|
||||
void Pop(token_p tkp, offset size);
|
||||
/* Pop a token of size bytes from the fake-stack
|
||||
* into tkp. If such a token is not there
|
||||
* we put a dummy in tkp and adjust the fake-stack.
|
||||
*/
|
||||
|
||||
extern Dup(); /* (line_p lnp)
|
||||
* Reflect the changes made by the dup-instruction
|
||||
void Dup(line_p lnp);
|
||||
/* Reflect the changes made by the dup-instruction
|
||||
* in lnp to the EM-stack into the fake-stack.
|
||||
*/
|
||||
|
||||
extern clr_stack(); /* ()
|
||||
* Clear the fake-stack.
|
||||
void clr_stack();
|
||||
/* Clear the fake-stack.
|
||||
*/
|
||||
|
||||
@ -21,9 +21,7 @@
|
||||
#include "cs_partit.h"
|
||||
#include "cs_getent.h"
|
||||
|
||||
STATIC push_entity(enp, lfirst)
|
||||
entity_p enp;
|
||||
line_p lfirst;
|
||||
static void push_entity(entity_p enp, line_p lfirst)
|
||||
{
|
||||
/* Build token and Push it. */
|
||||
|
||||
@ -35,10 +33,7 @@ STATIC push_entity(enp, lfirst)
|
||||
Push(&tk);
|
||||
}
|
||||
|
||||
STATIC put_expensive_load(bp, lnp, lfirst, enp)
|
||||
bblock_p bp;
|
||||
line_p lnp, lfirst;
|
||||
entity_p enp;
|
||||
static void put_expensive_load(bblock_p bp, line_p lnp, line_p lfirst, entity_p enp)
|
||||
{
|
||||
struct avail av;
|
||||
occur_p ocp;
|
||||
@ -52,10 +47,7 @@ STATIC put_expensive_load(bp, lnp, lfirst, enp)
|
||||
av_enter(&av, ocp, EXPENSIVE_LOAD);
|
||||
}
|
||||
|
||||
STATIC put_aar(bp, lnp, lfirst, enp)
|
||||
bblock_p bp;
|
||||
line_p lnp, lfirst;
|
||||
entity_p enp;
|
||||
static void put_aar(bblock_p bp, line_p lnp, line_p lfirst, entity_p enp)
|
||||
{
|
||||
/* Enp points to an ENARRELEM. We do as if its address was computed. */
|
||||
|
||||
@ -74,9 +66,7 @@ STATIC put_aar(bp, lnp, lfirst, enp)
|
||||
av_enter(&av, ocp, TERNAIR_OP);
|
||||
}
|
||||
|
||||
STATIC push_avail(avp, lfirst)
|
||||
avail_p avp;
|
||||
line_p lfirst;
|
||||
static void push_avail(avail_p avp, line_p lfirst)
|
||||
{
|
||||
struct token tk;
|
||||
|
||||
@ -86,10 +76,7 @@ STATIC push_avail(avp, lfirst)
|
||||
Push(&tk);
|
||||
}
|
||||
|
||||
STATIC push_unair_op(bp, lnp, tkp1)
|
||||
bblock_p bp;
|
||||
line_p lnp;
|
||||
token_p tkp1;
|
||||
static void push_unair_op(bblock_p bp, line_p lnp, token_p tkp1)
|
||||
{
|
||||
struct avail av;
|
||||
occur_p ocp;
|
||||
@ -103,10 +90,7 @@ STATIC push_unair_op(bp, lnp, tkp1)
|
||||
push_avail(av_enter(&av, ocp, UNAIR_OP), tkp1->tk_lfirst);
|
||||
}
|
||||
|
||||
STATIC push_binair_op(bp, lnp, tkp1, tkp2)
|
||||
bblock_p bp;
|
||||
line_p lnp;
|
||||
token_p tkp1, tkp2;
|
||||
static void push_binair_op(bblock_p bp, line_p lnp, token_p tkp1, token_p tkp2)
|
||||
{
|
||||
struct avail av;
|
||||
occur_p ocp;
|
||||
@ -121,10 +105,7 @@ STATIC push_binair_op(bp, lnp, tkp1, tkp2)
|
||||
push_avail(av_enter(&av, ocp, BINAIR_OP), tkp1->tk_lfirst);
|
||||
}
|
||||
|
||||
STATIC push_ternair_op(bp, lnp, tkp1, tkp2, tkp3)
|
||||
bblock_p bp;
|
||||
line_p lnp;
|
||||
token_p tkp1, tkp2, tkp3;
|
||||
static void push_ternair_op(bblock_p bp, line_p lnp, token_p tkp1, token_p tkp2, token_p tkp3)
|
||||
{
|
||||
struct avail av;
|
||||
occur_p ocp;
|
||||
@ -140,8 +121,7 @@ STATIC push_ternair_op(bp, lnp, tkp1, tkp2, tkp3)
|
||||
push_avail(av_enter(&av, ocp, TERNAIR_OP), tkp1->tk_lfirst);
|
||||
}
|
||||
|
||||
STATIC fiddle_stack(lnp)
|
||||
line_p lnp;
|
||||
static void fiddle_stack(line_p lnp)
|
||||
{
|
||||
/* The instruction in lnp does something to the valuenumber-stack. */
|
||||
|
||||
@ -217,8 +197,7 @@ STATIC fiddle_stack(lnp)
|
||||
}
|
||||
}
|
||||
|
||||
STATIC proc_p find_proc(vn)
|
||||
valnum vn;
|
||||
static proc_p find_proc(valnum vn)
|
||||
{
|
||||
/* Find the procedure-identifier with valuenumber vn. */
|
||||
|
||||
@ -232,8 +211,7 @@ STATIC proc_p find_proc(vn)
|
||||
return (proc_p) 0;
|
||||
}
|
||||
|
||||
STATIC side_effects(lnp)
|
||||
line_p lnp;
|
||||
static void side_effects(line_p lnp)
|
||||
{
|
||||
/* Lnp contains a cai or cal instruction. We try to find the callee
|
||||
* and see what side-effects it has.
|
||||
@ -255,8 +233,7 @@ STATIC side_effects(lnp)
|
||||
}
|
||||
}
|
||||
|
||||
hopeless(instr)
|
||||
int instr;
|
||||
void hopeless(int instr)
|
||||
{
|
||||
/* The effect of `instr' is too difficult to
|
||||
* compute. We assume worst case behaviour.
|
||||
@ -281,11 +258,10 @@ hopeless(instr)
|
||||
}
|
||||
}
|
||||
|
||||
vnm(bp)
|
||||
bblock_p bp;
|
||||
void vnm(bblock_p bp)
|
||||
{
|
||||
register line_p lnp;
|
||||
register entity_p rep;
|
||||
line_p lnp;
|
||||
entity_p rep;
|
||||
line_p lfirst;
|
||||
struct token tk, tk1, tk2, tk3;
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
extern vnm(); /* (bblock_p bp)
|
||||
* Performs the valuenumbering algorithm on the basic
|
||||
void vnm(bblock_p bp);
|
||||
/* Performs the valuenumbering algorithm on the basic
|
||||
* block in bp.
|
||||
*/
|
||||
|
||||
@ -55,15 +55,13 @@ offset mespar = UNKNOWN_SIZE;
|
||||
/* argumument of ps_par message of current procedure */
|
||||
|
||||
|
||||
extern process_lines();
|
||||
extern int readline();
|
||||
extern line_p readoperand();
|
||||
extern line_p inpseudo();
|
||||
void process_lines(FILE *fout);
|
||||
int readline(short *instr_out, line_p *lnp_out);
|
||||
line_p readoperand(short instr);
|
||||
line_p inpseudo(short n);
|
||||
|
||||
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
/* The input files must be legal EM Compact
|
||||
* Assembly Language files, as produced by the EM Peephole
|
||||
@ -128,7 +126,7 @@ main(argc,argv)
|
||||
#define DELETED_INSTR 5
|
||||
|
||||
|
||||
STATIC add_end()
|
||||
static void add_end()
|
||||
{
|
||||
/* Add an end-pseudo to the current instruction list */
|
||||
|
||||
@ -138,8 +136,7 @@ STATIC add_end()
|
||||
}
|
||||
|
||||
|
||||
process_lines(fout)
|
||||
FILE *fout;
|
||||
void process_lines(FILE *fout)
|
||||
{
|
||||
line_p lnp;
|
||||
short instr;
|
||||
@ -228,11 +225,9 @@ process_lines(fout)
|
||||
|
||||
|
||||
|
||||
int readline(instr_out, lnp_out)
|
||||
short *instr_out;
|
||||
line_p *lnp_out;
|
||||
int readline(short *instr_out, line_p *lnp_out)
|
||||
{
|
||||
register line_p lnp;
|
||||
line_p lnp;
|
||||
short n;
|
||||
|
||||
/* Read one line. If it is a normal EM instruction without
|
||||
@ -295,18 +290,16 @@ int readline(instr_out, lnp_out)
|
||||
return NORMAL;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
line_p readoperand(instr)
|
||||
short instr;
|
||||
line_p readoperand(short instr)
|
||||
{
|
||||
/* Read the operand of the given instruction.
|
||||
* Create a line struct and return a pointer to it.
|
||||
*/
|
||||
|
||||
|
||||
register line_p lnp;
|
||||
line_p lnp;
|
||||
short flag;
|
||||
|
||||
VI(instr);
|
||||
@ -420,8 +413,7 @@ static char *hol_label()
|
||||
}
|
||||
|
||||
|
||||
line_p inpseudo(n)
|
||||
short n;
|
||||
line_p inpseudo(short n)
|
||||
{
|
||||
int m;
|
||||
line_p lnp;
|
||||
@ -454,7 +446,7 @@ line_p inpseudo(n)
|
||||
curhol = hol_label();
|
||||
}
|
||||
n = ps_bss;
|
||||
/* fall through */
|
||||
/* fall through */
|
||||
case ps_bss:
|
||||
case ps_rom:
|
||||
case ps_con:
|
||||
@ -570,4 +562,6 @@ line_p inpseudo(n)
|
||||
assert(FALSE);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -8,8 +8,8 @@
|
||||
* I C _ A U X . C
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <em_pseu.h>
|
||||
#include <em_spec.h>
|
||||
#include <em_mnem.h>
|
||||
@ -24,12 +24,9 @@
|
||||
#include "../share/alloc.h"
|
||||
#include "ic_aux.h"
|
||||
|
||||
|
||||
|
||||
/* opr_size */
|
||||
|
||||
offset opr_size(instr)
|
||||
short instr;
|
||||
offset opr_size(short instr)
|
||||
{
|
||||
switch(instr) {
|
||||
case op_loe:
|
||||
@ -49,14 +46,14 @@ offset opr_size(instr)
|
||||
error("illegal operand of opr_size: %d", instr);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* dblockdef */
|
||||
|
||||
STATIC offset argsize(arg)
|
||||
arg_p arg;
|
||||
static offset argsize(arg_p arg)
|
||||
{
|
||||
/* Compute the size (in bytes) that the given initializer
|
||||
* will occupy.
|
||||
@ -93,12 +90,11 @@ STATIC offset argsize(arg)
|
||||
assert(FALSE);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
STATIC offset blocksize(pseudo,args)
|
||||
byte pseudo;
|
||||
arg_p args;
|
||||
static offset blocksize(byte pseudo, arg_p args)
|
||||
{
|
||||
/* Determine the number of bytes of a datablock */
|
||||
|
||||
@ -124,11 +120,11 @@ STATIC offset blocksize(pseudo,args)
|
||||
assert(FALSE);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
STATIC arg_p copy_arg(arg)
|
||||
arg_p arg;
|
||||
static arg_p copy_arg(arg_p arg)
|
||||
{
|
||||
/* Copy one argument */
|
||||
|
||||
@ -142,8 +138,7 @@ STATIC arg_p copy_arg(arg)
|
||||
|
||||
|
||||
|
||||
STATIC arg_p copy_rom(args)
|
||||
arg_p args;
|
||||
static arg_p copy_rom(arg_p args)
|
||||
{
|
||||
/* Make a copy of the values of a rom,
|
||||
* provided that the rom contains only integer values,
|
||||
@ -167,10 +162,7 @@ STATIC arg_p copy_rom(args)
|
||||
|
||||
|
||||
|
||||
dblockdef(db,n,lnp)
|
||||
dblock_p db;
|
||||
int n;
|
||||
line_p lnp;
|
||||
void dblockdef(dblock_p db, int n, line_p lnp)
|
||||
{
|
||||
/* Process a data block defining occurrence */
|
||||
|
||||
@ -206,10 +198,7 @@ dblockdef(db,n,lnp)
|
||||
|
||||
/* combine */
|
||||
|
||||
combine(db,l1,l2,pseu)
|
||||
dblock_p db;
|
||||
line_p l1,l2;
|
||||
byte pseu;
|
||||
void combine(dblock_p db, line_p l1, line_p l2, byte pseu)
|
||||
{
|
||||
/* Combine two successive ROMs/CONs (without a data label
|
||||
* in between into a single ROM. E.g.:
|
||||
@ -258,11 +247,8 @@ combine(db,l1,l2,pseu)
|
||||
|
||||
/* arglist */
|
||||
|
||||
STATIC arg_string(length,abp)
|
||||
offset length;
|
||||
register argb_p abp;
|
||||
static void arg_string(offset length, argb_p abp)
|
||||
{
|
||||
|
||||
while (length--) {
|
||||
if (abp->ab_index == NARGBYTES)
|
||||
abp = abp->ab_next = newargb();
|
||||
@ -271,8 +257,7 @@ STATIC arg_string(length,abp)
|
||||
}
|
||||
|
||||
|
||||
line_p arglist(n)
|
||||
int n;
|
||||
line_p arglist(int n)
|
||||
{
|
||||
line_p lnp;
|
||||
register arg_p ap,*app;
|
||||
@ -355,8 +340,7 @@ line_p arglist(n)
|
||||
|
||||
/* is_datalabel */
|
||||
|
||||
bool is_datalabel(l)
|
||||
line_p l;
|
||||
bool is_datalabel(line_p l)
|
||||
{
|
||||
VL(l);
|
||||
return (l->l_instr == (byte) ps_sym);
|
||||
@ -366,8 +350,7 @@ bool is_datalabel(l)
|
||||
|
||||
/* block_of_lab */
|
||||
|
||||
dblock_p block_of_lab(ident)
|
||||
char *ident;
|
||||
dblock_p block_of_lab(char *ident)
|
||||
{
|
||||
dblock_p dbl;
|
||||
|
||||
@ -387,10 +370,7 @@ dblock_p block_of_lab(ident)
|
||||
|
||||
/* object */
|
||||
|
||||
STATIC obj_p make_object(dbl,off,size)
|
||||
dblock_p dbl;
|
||||
offset off;
|
||||
offset size;
|
||||
static obj_p make_object(dblock_p dbl, offset off, offset size)
|
||||
{
|
||||
/* Allocate an obj struct with the given attributes
|
||||
* (if it did not exist already).
|
||||
@ -447,10 +427,7 @@ STATIC obj_p make_object(dbl,off,size)
|
||||
|
||||
|
||||
|
||||
obj_p object(ident,off,size)
|
||||
char *ident;
|
||||
offset off;
|
||||
offset size;
|
||||
obj_p object(char *ident, offset off, offset size)
|
||||
{
|
||||
dblock_p dbl;
|
||||
|
||||
|
||||
@ -10,35 +10,35 @@
|
||||
|
||||
|
||||
|
||||
extern offset opr_size(); /* ( short instr )
|
||||
* size of operand of given instruction.
|
||||
offset opr_size(short instr);
|
||||
/* size of operand of given instruction.
|
||||
* The operand is an object , so the
|
||||
* instruction can be loe, zre etc..
|
||||
*/
|
||||
extern dblockdef(); /* (dblock_p db, int n, line_p lnp)
|
||||
* Fill in d_pseudo, d_size and
|
||||
void dblockdef(dblock_p db, int n, line_p lnp);
|
||||
/* Fill in d_pseudo, d_size and
|
||||
* d_values fields of db.
|
||||
*/
|
||||
extern combine(); /* (dblock_p db;line_p l1,l2;byte pseu)
|
||||
* Combine two successive ROMs or CONs
|
||||
void combine(dblock_p db, line_p l1, line_p l2, byte pseu);
|
||||
/* Combine two successive ROMs or CONs
|
||||
* (with no data label in between)
|
||||
* into one ROM or CON.
|
||||
*/
|
||||
extern line_p arglist(); /* ( int m)
|
||||
* Read a list of m arguments. If m
|
||||
line_p arglist(int n);
|
||||
/* Read a list of m arguments. If m
|
||||
* is 0, then the list is of
|
||||
* undetermined length; it is
|
||||
* then terminated by a cend symbol.
|
||||
*/
|
||||
extern bool is_datalabel(); /* ( line_p l)
|
||||
* TRUE if l is a data label defining
|
||||
bool is_datalabel(line_p l);
|
||||
/* TRUE if l is a data label defining
|
||||
* occurrence (i.e. its l_instr
|
||||
* field is ps_sym).
|
||||
*/
|
||||
extern dblock_p block_of_lab(); /* (char *ident)
|
||||
* Find the datablock with
|
||||
dblock_p block_of_lab(char *ident);
|
||||
/* Find the datablock with
|
||||
* the given name.
|
||||
*/
|
||||
extern obj_p object(); /* (char *ident,offset off,short size)
|
||||
* Create an object struct.
|
||||
obj_p object(char *ident, offset off, offset size);
|
||||
/* Create an object struct.
|
||||
*/
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <em_pseu.h>
|
||||
#include <em_spec.h>
|
||||
#include <arch.h>
|
||||
@ -22,12 +23,12 @@
|
||||
#include "ic_io.h"
|
||||
|
||||
|
||||
STATIC short libstate;
|
||||
STATIC long bytecnt;
|
||||
static short libstate;
|
||||
static long bytecnt;
|
||||
|
||||
STATIC FILE *infile; /* The current EM input file */
|
||||
static FILE *infile; /* The current EM input file */
|
||||
|
||||
STATIC int readbyte()
|
||||
static int readbyte()
|
||||
{
|
||||
if (libstate == ARCHIVE && bytecnt-- == 0L) {
|
||||
/* If we're reading from an archive file, we'll
|
||||
@ -42,8 +43,9 @@ STATIC int readbyte()
|
||||
|
||||
|
||||
|
||||
short readshort() {
|
||||
register int l_byte, h_byte;
|
||||
short readshort()
|
||||
{
|
||||
int l_byte, h_byte;
|
||||
|
||||
l_byte = readbyte();
|
||||
h_byte = readbyte();
|
||||
@ -52,9 +54,10 @@ short readshort() {
|
||||
}
|
||||
|
||||
#ifdef LONGOFF
|
||||
offset readoffset() {
|
||||
register long l;
|
||||
register int h_byte;
|
||||
offset readoffset()
|
||||
{
|
||||
long l;
|
||||
int h_byte;
|
||||
|
||||
l = readbyte();
|
||||
l |= ((unsigned) readbyte())*256 ;
|
||||
@ -66,8 +69,8 @@ offset readoffset() {
|
||||
#endif
|
||||
|
||||
|
||||
short get_int() {
|
||||
|
||||
short get_int()
|
||||
{
|
||||
switch(table2()) {
|
||||
default: error("int expected");
|
||||
case CSTX1:
|
||||
@ -82,8 +85,8 @@ char readchar()
|
||||
|
||||
|
||||
|
||||
offset get_off() {
|
||||
|
||||
offset get_off()
|
||||
{
|
||||
switch (table2()) {
|
||||
default: error("offset expected");
|
||||
case CSTX1:
|
||||
@ -95,15 +98,16 @@ offset get_off() {
|
||||
}
|
||||
}
|
||||
|
||||
STATIC make_string(n) int n; {
|
||||
|
||||
static void make_string(int n)
|
||||
{
|
||||
sprintf(string,".%u",n);
|
||||
}
|
||||
|
||||
STATIC inident() {
|
||||
register n;
|
||||
register char *p = string;
|
||||
register c;
|
||||
static void inident()
|
||||
{
|
||||
int n;
|
||||
char *p = string;
|
||||
int c;
|
||||
|
||||
n = get_int();
|
||||
while (n--) {
|
||||
@ -114,8 +118,8 @@ STATIC inident() {
|
||||
*p++ = 0;
|
||||
}
|
||||
|
||||
int table3(n) int n; {
|
||||
|
||||
int table3(int n)
|
||||
{
|
||||
switch (n) {
|
||||
case sp_ilb1: tabval = readbyte(); return(ILBX);
|
||||
case sp_ilb2: tabval = readshort(); return(ILBX);
|
||||
@ -139,8 +143,9 @@ int table3(n) int n; {
|
||||
}
|
||||
}
|
||||
|
||||
int table1() {
|
||||
register n;
|
||||
int table1()
|
||||
{
|
||||
int n;
|
||||
|
||||
n = readbyte();
|
||||
if (n == EOF)
|
||||
@ -160,8 +165,9 @@ int table1() {
|
||||
return(table3(n));
|
||||
}
|
||||
|
||||
int table2() {
|
||||
register n;
|
||||
int table2()
|
||||
{
|
||||
int n;
|
||||
|
||||
n = readbyte();
|
||||
if ((n < sp_fcst0 + sp_ncst0) && (n >= sp_fcst0)) {
|
||||
@ -174,10 +180,7 @@ int table2() {
|
||||
|
||||
|
||||
|
||||
file_init(f,state,length)
|
||||
FILE *f;
|
||||
short state;
|
||||
long length;
|
||||
void file_init(FILE *f, short state, long length)
|
||||
{
|
||||
short n;
|
||||
|
||||
@ -193,8 +196,7 @@ file_init(f,state,length)
|
||||
|
||||
|
||||
|
||||
arch_init(arch)
|
||||
FILE *arch;
|
||||
void arch_init(FILE *arch)
|
||||
{
|
||||
short n;
|
||||
|
||||
|
||||
@ -9,22 +9,22 @@
|
||||
*/
|
||||
|
||||
|
||||
extern int table1(); /* ( )
|
||||
* Read an instruction from the
|
||||
int table1();
|
||||
/* Read an instruction from the
|
||||
* Compact Assembly Language input
|
||||
* file (in 'neutral state').
|
||||
*/
|
||||
extern int table2(); /* ( )
|
||||
* Read an instruction argument.
|
||||
int table2();
|
||||
/* Read an instruction argument.
|
||||
*/
|
||||
extern int table3(); /* ( int )
|
||||
* Read 'Common Table' item.
|
||||
int table3(int n);
|
||||
/* Read 'Common Table' item.
|
||||
*/
|
||||
extern short get_int(); /* ( ) */
|
||||
extern offset get_off(); /* ( ) */
|
||||
extern char readchar(); /* ( ) */
|
||||
extern file_init(); /* (FILE *f, short state, long length)
|
||||
* Input file initialization. All
|
||||
short get_int();
|
||||
offset get_off();
|
||||
char readchar();
|
||||
void file_init(FILE *f, short state, long length);
|
||||
/* Input file initialization. All
|
||||
* following read operations will read
|
||||
* from the given file f. Also checks
|
||||
* the magic number and sets global
|
||||
@ -32,8 +32,8 @@ extern file_init(); /* (FILE *f, short state, long length)
|
||||
* If the state is ARCHIVE, length
|
||||
* specifies the length of the module.
|
||||
*/
|
||||
extern arch_init(); /* (FILE *arch)
|
||||
* Same as file_init,but opens an
|
||||
void arch_init(FILE *arch);
|
||||
/* Same as file_init,but opens an
|
||||
* archive file. So it checks the
|
||||
* magic number for archives.
|
||||
*/
|
||||
|
||||
@ -24,18 +24,16 @@
|
||||
#include "ic_lib.h"
|
||||
|
||||
|
||||
STATIC skip_string(n)
|
||||
offset n;
|
||||
static void skip_string(offset n)
|
||||
{
|
||||
/* Read a string of length n and void it */
|
||||
|
||||
while (n--) {
|
||||
readchar();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
STATIC skip_arguments()
|
||||
static void skip_arguments()
|
||||
{
|
||||
/* Skip the arguments of a MES pseudo. The argument
|
||||
* list is terminated by a sp_cend byte.
|
||||
@ -62,8 +60,7 @@ STATIC skip_arguments()
|
||||
|
||||
|
||||
|
||||
STATIC bool proc_wanted(name)
|
||||
char *name;
|
||||
static bool proc_wanted(char *name)
|
||||
{
|
||||
/* See if 'name' is the name of an external procedure
|
||||
* that has been used before, but for which no body
|
||||
@ -82,8 +79,7 @@ STATIC bool proc_wanted(name)
|
||||
|
||||
|
||||
|
||||
STATIC bool data_wanted(name)
|
||||
char *name;
|
||||
static bool data_wanted(char *name)
|
||||
{
|
||||
/* See if 'name' is the name of an externally visible
|
||||
* data block that has been used before, but for which
|
||||
@ -102,7 +98,7 @@ STATIC bool data_wanted(name)
|
||||
|
||||
|
||||
|
||||
STATIC bool wanted_names()
|
||||
static bool wanted_names()
|
||||
{
|
||||
/* Read the names of procedures and data labels,
|
||||
* appearing in a 'MES ms_ext' pseudo. Those are
|
||||
@ -139,8 +135,8 @@ STATIC bool wanted_names()
|
||||
|
||||
|
||||
|
||||
STATIC FILE *curfile = NULL;
|
||||
STATIC bool useful()
|
||||
static FILE *curfile = NULL;
|
||||
static bool useful()
|
||||
{
|
||||
/* Determine if any entity imported by the current
|
||||
* compact EM assembly file (which will usually be
|
||||
@ -171,8 +167,7 @@ STATIC bool useful()
|
||||
|
||||
|
||||
|
||||
STATIC bool is_archive(name)
|
||||
char *name;
|
||||
static bool is_archive(char *name)
|
||||
{
|
||||
/* See if 'name' is the name of an archive file, i.e. it
|
||||
* should end on ".ma" and should at least be four characters
|
||||
@ -187,9 +182,9 @@ STATIC bool is_archive(name)
|
||||
|
||||
|
||||
|
||||
STATIC struct ar_hdr hdr;
|
||||
static struct ar_hdr hdr;
|
||||
|
||||
STATIC bool read_hdr()
|
||||
static bool read_hdr()
|
||||
{
|
||||
/* Read the header of an archive module */
|
||||
|
||||
@ -220,13 +215,11 @@ STATIC bool read_hdr()
|
||||
|
||||
|
||||
|
||||
STATIC int argcnt = ARGSTART - 1;
|
||||
STATIC short arstate = NO_ARCHIVE;
|
||||
static int argcnt = ARGSTART - 1;
|
||||
static short arstate = NO_ARCHIVE;
|
||||
|
||||
|
||||
FILE *next_file(argc,argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
FILE *next_file(int argc, char *argv[])
|
||||
{
|
||||
/* See if there are more EM input files. The file names
|
||||
* are given via argv. If a file is an archive file
|
||||
|
||||
@ -9,8 +9,8 @@
|
||||
*/
|
||||
|
||||
|
||||
extern FILE *next_file(); /* (int argc, char *argv[])
|
||||
* See if there are any more EM input files.
|
||||
FILE *next_file(int argc, char *argv[]);
|
||||
/* See if there are any more EM input files.
|
||||
* 'argv' contains the names of the files
|
||||
* that are passed as arguments to ic.
|
||||
* If an argument is a library (archive
|
||||
|
||||
@ -26,8 +26,6 @@ prc_p prochash[NPROCHASH];
|
||||
num_p numhash[NNUMHASH];
|
||||
char *lastname;
|
||||
|
||||
//extern char *strcpy();
|
||||
|
||||
#define newsym() (sym_p) newstruct(sym)
|
||||
#define newprc() (prc_p) newstruct(prc)
|
||||
#define newnum() (num_p) newstruct(num)
|
||||
@ -41,14 +39,9 @@ char *lastname;
|
||||
|
||||
/* instr_lab */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
lab_id instr_lab(number)
|
||||
short number;
|
||||
lab_id instr_lab(short number)
|
||||
{
|
||||
register num_p *npp, np;
|
||||
num_p *npp, np;
|
||||
|
||||
/* In EM assembly language, a label is an unsigned number,
|
||||
* e.g. 120 in 'BRA *120'. In IC the labels of a procedure
|
||||
@ -84,18 +77,17 @@ lab_id instr_lab(number)
|
||||
|
||||
/* symlookup */
|
||||
|
||||
STATIC unsigned hash(string) char *string; {
|
||||
register char *p;
|
||||
register unsigned i,sum;
|
||||
STATIC unsigned hash(char *string)
|
||||
{
|
||||
char *p;
|
||||
unsigned i,sum;
|
||||
|
||||
for (sum=i=0,p=string;*p;i += 3)
|
||||
sum ^= (*p++)<<(i&07);
|
||||
return(sum);
|
||||
}
|
||||
|
||||
dblock_p symlookup(name, status)
|
||||
char *name;
|
||||
int status;
|
||||
dblock_p symlookup(char *name, int status)
|
||||
{
|
||||
/* Look up the name of a data block. The name can appear
|
||||
* in either a defining or applied occurrence (status is
|
||||
@ -107,8 +99,8 @@ dblock_p symlookup(name, status)
|
||||
*/
|
||||
|
||||
|
||||
register sym_p *spp, sp;
|
||||
register dblock_p dp;
|
||||
sym_p *spp, sp;
|
||||
dblock_p dp;
|
||||
|
||||
if (name == (char *) 0) {
|
||||
assert(status == DEFINING);
|
||||
@ -182,8 +174,7 @@ dblock_p symlookup(name, status)
|
||||
|
||||
/* getsym */
|
||||
|
||||
dblock_p getsym(status)
|
||||
int status;
|
||||
dblock_p getsym(int status)
|
||||
{
|
||||
if (table2() != DLBX) {
|
||||
error("symbol expected");
|
||||
@ -195,8 +186,7 @@ dblock_p getsym(status)
|
||||
|
||||
/* getproc */
|
||||
|
||||
proc_p getproc(status)
|
||||
int status;
|
||||
proc_p getproc(int status)
|
||||
{
|
||||
if (table2() != sp_pnam) {
|
||||
error("proc name expected");
|
||||
@ -208,12 +198,10 @@ proc_p getproc(status)
|
||||
|
||||
/* proclookup */
|
||||
|
||||
proc_p proclookup(name, status)
|
||||
char *name;
|
||||
int status;
|
||||
proc_p proclookup(char *name, int status)
|
||||
{
|
||||
register prc_p *ppp, pp;
|
||||
register proc_p dp;
|
||||
prc_p *ppp, pp;
|
||||
proc_p dp;
|
||||
|
||||
ppp = &prochash[hash(name)%NPROCHASH];
|
||||
while (*ppp != (prc_p) 0) {
|
||||
@ -273,7 +261,7 @@ proc_p proclookup(name, status)
|
||||
|
||||
/* cleaninstrlabs */
|
||||
|
||||
cleaninstrlabs()
|
||||
void cleaninstrlabs()
|
||||
{
|
||||
register num_p *npp, np, next;
|
||||
|
||||
@ -292,10 +280,7 @@ cleaninstrlabs()
|
||||
|
||||
/* dump_procnames */
|
||||
|
||||
dump_procnames(hash,n,f)
|
||||
prc_p hash[];
|
||||
int n;
|
||||
FILE *f;
|
||||
void dump_procnames(prc_p hash[], int n, FILE *f)
|
||||
{
|
||||
/* Save the names of the EM procedures in file f.
|
||||
* Note that the Optimizer Intermediate Code does not
|
||||
@ -308,7 +293,7 @@ dump_procnames(hash,n,f)
|
||||
* more than once, the PF_WRITTEN flag is used.
|
||||
*/
|
||||
|
||||
register prc_p *pp, ph;
|
||||
prc_p *pp, ph;
|
||||
proc_p p;
|
||||
|
||||
#define PF_WRITTEN 01
|
||||
@ -330,9 +315,7 @@ dump_procnames(hash,n,f)
|
||||
|
||||
/* cleanprocs */
|
||||
|
||||
cleanprocs(hash,n,mask)
|
||||
prc_p hash[];
|
||||
int n,mask;
|
||||
void cleanprocs(prc_p hash[], int n, int mask)
|
||||
{
|
||||
/* After an EM input file has been processed, the names
|
||||
* of those procedures that are internal (i.e. not visible
|
||||
@ -343,7 +326,7 @@ cleanprocs(hash,n,mask)
|
||||
* remaining prc structs are also removed.
|
||||
*/
|
||||
|
||||
register prc_p *pp, ph, x, next;
|
||||
prc_p *pp, ph, x, next;
|
||||
|
||||
for (pp = &hash[0]; pp < &hash[n]; pp++) {
|
||||
/* Traverse the hash table */
|
||||
@ -374,17 +357,14 @@ cleanprocs(hash,n,mask)
|
||||
|
||||
/* dump_dblocknames */
|
||||
|
||||
dump_dblocknames(hash,n,f)
|
||||
sym_p hash[];
|
||||
int n;
|
||||
FILE *f;
|
||||
void dump_dblocknames(sym_p hash[], int n, FILE *f)
|
||||
{
|
||||
/* Save the names of the EM data blocks in file f.
|
||||
* The output consists of tuples (dblock_id, name).
|
||||
* This routine is called once for every input file.
|
||||
*/
|
||||
|
||||
register sym_p *sp, sh;
|
||||
sym_p *sp, sh;
|
||||
dblock_p d;
|
||||
|
||||
#define DF_WRITTEN 01
|
||||
@ -406,15 +386,13 @@ dump_dblocknames(hash,n,f)
|
||||
|
||||
/* cleandblocks */
|
||||
|
||||
cleandblocks(hash,n,mask)
|
||||
sym_p hash[];
|
||||
int n,mask;
|
||||
void cleandblocks(sym_p hash[], int n, int mask)
|
||||
{
|
||||
/* After an EM input file has been processed, the names
|
||||
* of those data blocks that are internal must be removed.
|
||||
*/
|
||||
|
||||
register sym_p *sp, sh, x, next;
|
||||
sym_p *sp, sh, x, next;
|
||||
|
||||
for (sp = &hash[0]; sp < &hash[n]; sp++) {
|
||||
x = (sym_p) 0;
|
||||
|
||||
@ -35,42 +35,42 @@ extern sym_p symhash[];
|
||||
extern prc_p prochash[];
|
||||
extern num_p numhash[];
|
||||
|
||||
extern lab_id instr_lab(); /* ( short number)
|
||||
* Maps EM labels to sequential
|
||||
lab_id instr_lab(short number);
|
||||
/* Maps EM labels to sequential
|
||||
* integers.
|
||||
*/
|
||||
extern dblock_p symlookup(); /* (char *ident, int status)
|
||||
* Look up the data block with
|
||||
dblock_p symlookup(char *name, int status);
|
||||
/* Look up the data block with
|
||||
* the given name.
|
||||
*/
|
||||
extern dblock_p getsym(); /* ( int status)
|
||||
* Read and look up a symbol.
|
||||
dblock_p getsym(int status);
|
||||
/* Read and look up a symbol.
|
||||
* If this is the first occurrence
|
||||
* of it, then make it external
|
||||
* (if status=OCCURRING) or
|
||||
* internal (if DEFINING).
|
||||
*/
|
||||
extern proc_p getproc(); /* (int status)
|
||||
* Same as getsym, but for procedure
|
||||
proc_p getproc(int status);
|
||||
/* Same as getsym, but for procedure
|
||||
* names.
|
||||
*/
|
||||
extern proc_p proclookup(); /* ( char *ident, int status)
|
||||
* Find (in the hashtable) the
|
||||
proc_p proclookup(char *name, int status);
|
||||
/* Find (in the hashtable) the
|
||||
* procedure with the given name.
|
||||
*/
|
||||
extern cleaninstrlabs(); /* ( )
|
||||
* Forget about all instruction labels.
|
||||
void cleaninstrlabs();
|
||||
/* Forget about all instruction labels.
|
||||
*/
|
||||
extern dump_procnames(); /* (prc_p hash[], int n, FILE *f)
|
||||
* Save the names of the procedures
|
||||
void dump_procnames(prc_p hash[], int n, FILE *f);
|
||||
/* Save the names of the procedures
|
||||
* in file f; hash is the hashtable
|
||||
* used and n is its length.
|
||||
*/
|
||||
extern cleanprocs(); /* (prc_p hash[], int n,mask)
|
||||
* Make the names of all procedures
|
||||
void cleanprocs(prc_p hash[], int n, int mask);
|
||||
/* Make the names of all procedures
|
||||
* for which p_flags1&mask = 0 invisible
|
||||
*/
|
||||
extern cleandblocks(); /* (sym_p hash[], int n)
|
||||
* Make the names of all data blocks
|
||||
void cleandblocks(sym_p hash[], int n, int mask);
|
||||
/* Make the names of all data blocks
|
||||
* for which d_flags1&mask = 0 invisible
|
||||
*/
|
||||
|
||||
@ -30,15 +30,15 @@
|
||||
int calnr;
|
||||
int complete_program;
|
||||
calcnt_p cchead; /* call-count info of current proc */
|
||||
STATIC long space = 0;
|
||||
STATIC long total_size = 0;
|
||||
static long space = 0;
|
||||
static long total_size = 0;
|
||||
|
||||
STATIC char cname[128] = TMP_DIR;
|
||||
STATIC char ccname[128] = TMP_DIR;
|
||||
static char cname[128] = TMP_DIR;
|
||||
static char ccname[128] = TMP_DIR;
|
||||
|
||||
/* For debugging only */
|
||||
STATIC char sname[128] = TMP_DIR;
|
||||
STATIC int kp_temps = 0;
|
||||
static char sname[128] = TMP_DIR;
|
||||
static int kp_temps = 0;
|
||||
|
||||
int Ssubst;
|
||||
#ifdef VERBOSE
|
||||
@ -56,8 +56,7 @@ int Sbig_caller,Sdispensable,Schangedcallee,Sbigcallee,Sspace,Szeroratio;
|
||||
* The call descriptors are put in a file (calfile).
|
||||
*/
|
||||
|
||||
pass1(lnam,bnam,cnam)
|
||||
char *lnam, *bnam, *cnam;
|
||||
void pass1(char *lnam, char *bnam, char *cnam)
|
||||
{
|
||||
FILE *f, *gf, *cf, *ccf; /* The EM input, the basic block graph,
|
||||
* the call-list file and the calcnt file.
|
||||
@ -123,11 +122,9 @@ pass1(lnam,bnam,cnam)
|
||||
|
||||
|
||||
|
||||
STATIC char cname2[128] = TMP_DIR;
|
||||
static char cname2[128] = TMP_DIR;
|
||||
|
||||
pass2(cnam,space)
|
||||
char *cnam;
|
||||
long space;
|
||||
void pass2(char *cnam, long space)
|
||||
{
|
||||
FILE *cf, *cf2, *ccf;
|
||||
call_p c,a;
|
||||
@ -171,8 +168,7 @@ pass2(cnam,space)
|
||||
*/
|
||||
|
||||
|
||||
pass3(lnam,lnam2)
|
||||
char *lnam,*lnam2;
|
||||
void pass3(char *lnam, char *lnam2)
|
||||
{
|
||||
bool verbose = TRUE;
|
||||
FILE *lfile, *lfilerand, *lfile2, *sfile;
|
||||
@ -229,8 +225,7 @@ pass3(lnam,lnam2)
|
||||
}
|
||||
|
||||
|
||||
STATIC il_extptab(ptab)
|
||||
proc_p ptab;
|
||||
static void il_extptab(proc_p ptab)
|
||||
{
|
||||
/* Allocate space for extension of proctable entries.
|
||||
* Also, initialise some of the fields just allocated.
|
||||
@ -245,8 +240,7 @@ STATIC il_extptab(ptab)
|
||||
}
|
||||
}
|
||||
|
||||
STATIC il_cleanptab(ptab)
|
||||
proc_p ptab;
|
||||
static void il_cleanptab(proc_p ptab)
|
||||
{
|
||||
/* De-allocate space for extensions */
|
||||
|
||||
@ -258,7 +252,7 @@ STATIC il_cleanptab(ptab)
|
||||
}
|
||||
|
||||
#ifdef VERBOSE
|
||||
Sdiagnostics()
|
||||
void Sdiagnostics()
|
||||
{
|
||||
/* print statictical information */
|
||||
|
||||
@ -282,9 +276,9 @@ Sdiagnostics()
|
||||
}
|
||||
#endif
|
||||
|
||||
il_flags(p)
|
||||
char *p;
|
||||
int il_flags(void *param)
|
||||
{
|
||||
char *p = (char *)param;
|
||||
switch(*p++) {
|
||||
case 's':
|
||||
while (*p != '\0') {
|
||||
@ -302,11 +296,10 @@ il_flags(p)
|
||||
kp_temps = 1;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
|
||||
@ -38,8 +38,7 @@
|
||||
|
||||
|
||||
|
||||
apriori(proctab)
|
||||
proc_p proctab;
|
||||
void apriori(proc_p proctab)
|
||||
{
|
||||
/* For every procedure, see if we can determine
|
||||
* from the information provided by the previous
|
||||
@ -47,8 +46,7 @@ apriori(proctab)
|
||||
* be expanded in line. This will reduce the length
|
||||
* of the call list.
|
||||
*/
|
||||
|
||||
register proc_p p;
|
||||
proc_p p;
|
||||
|
||||
for (p = proctab; p != (proc_p) 0; p = p->p_next) {
|
||||
if (!BODY_KNOWN(p) ||
|
||||
@ -68,9 +66,7 @@ apriori(proctab)
|
||||
}
|
||||
|
||||
|
||||
STATIC check_labels(p,arglist)
|
||||
proc_p p;
|
||||
arg_p arglist;
|
||||
static void check_labels(proc_p p, arg_p arglist)
|
||||
{
|
||||
/* Check if any of the arguments contains an instruction
|
||||
* label; if so, make p unsuitable.
|
||||
@ -91,10 +87,7 @@ STATIC check_labels(p,arglist)
|
||||
|
||||
|
||||
|
||||
STATIC anal_instr(p,b,cf)
|
||||
proc_p p;
|
||||
bblock_p b;
|
||||
FILE *cf;
|
||||
static void anal_instr(proc_p p, bblock_p b, FILE *cf)
|
||||
{
|
||||
/* Analyze the instructions of block b
|
||||
* within procedure p.
|
||||
@ -103,8 +96,7 @@ STATIC anal_instr(p,b,cf)
|
||||
* the actual parameter expressions of
|
||||
* the CAL instructions.
|
||||
*/
|
||||
|
||||
register line_p l;
|
||||
line_p l;
|
||||
|
||||
for (l = b->b_start; l != (line_p) 0; l = l->l_next) {
|
||||
switch(INSTR(l)) {
|
||||
@ -152,16 +144,14 @@ STATIC anal_instr(p,b,cf)
|
||||
|
||||
|
||||
|
||||
anal_proc(p,cf,ccf)
|
||||
proc_p p;
|
||||
FILE *cf,*ccf;
|
||||
void anal_proc(proc_p p, FILE *cf, FILE *ccf)
|
||||
{
|
||||
/* Analyze a procedure; use information
|
||||
* stored in its basic blocks or in
|
||||
* its instructions.
|
||||
*/
|
||||
|
||||
register bblock_p b;
|
||||
bblock_p b;
|
||||
bool fallthrough = TRUE;
|
||||
|
||||
cchead = (calcnt_p) 0;
|
||||
|
||||
@ -8,15 +8,15 @@
|
||||
* I L 1 _ A N A L . H
|
||||
*/
|
||||
|
||||
extern apriori(); /* (proc_p proctab)
|
||||
* For every procedure, see if we can determine
|
||||
* from the information provided by the previous
|
||||
* phases of the optimizer that it cannot or should not
|
||||
* be expanded in line. This will reduce the length
|
||||
* of the call list.
|
||||
*/
|
||||
extern anal_proc(); /* (proc_p p, FILE *cf, *cff)
|
||||
* Analyse a procedure. See which formal parameters
|
||||
* it uses and which procedures it calls.
|
||||
* cf and ccf are the call-file and the call-count file.
|
||||
*/
|
||||
void apriori(proc_p proctab);
|
||||
/* For every procedure, see if we can determine
|
||||
* from the information provided by the previous
|
||||
* phases of the optimizer that it cannot or should not
|
||||
* be expanded in line. This will reduce the length
|
||||
* of the call list.
|
||||
*/
|
||||
void anal_proc(proc_p p, FILE *cf, FILE *ccf);
|
||||
/* Analyse a procedure. See which formal parameters
|
||||
* it uses and which procedures it calls.
|
||||
* cf and ccf are the call-file and the call-count file.
|
||||
*/
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
* I L 1 _ A U X . C
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <em_spec.h>
|
||||
#include "../share/types.h"
|
||||
#include "il.h"
|
||||
@ -23,8 +24,7 @@
|
||||
#define IS_INSTR(c) (c >= sp_fmnem && c <= sp_lmnem)
|
||||
|
||||
|
||||
bool same_size(t1,t2)
|
||||
int t1, t2;
|
||||
bool same_size(int t1, int t2)
|
||||
{
|
||||
/* See if the two types have the same size */
|
||||
|
||||
@ -33,9 +33,7 @@ bool same_size(t1,t2)
|
||||
|
||||
|
||||
|
||||
STATIC bool is_reg(off,s)
|
||||
offset off;
|
||||
int s;
|
||||
static bool is_reg(offset off, int s)
|
||||
{
|
||||
/* See if there is a register message
|
||||
* for the local or parameter at offset off
|
||||
@ -56,8 +54,7 @@ STATIC bool is_reg(off,s)
|
||||
}
|
||||
|
||||
|
||||
rem_actuals(acts)
|
||||
actual_p acts;
|
||||
void rem_actuals(actual_p acts)
|
||||
{
|
||||
/* remove the actual-list */
|
||||
|
||||
@ -72,8 +69,7 @@ rem_actuals(acts)
|
||||
|
||||
|
||||
|
||||
remov_formals(p)
|
||||
proc_p p;
|
||||
void remov_formals(proc_p p)
|
||||
{
|
||||
/* Remove the list of formals of p */
|
||||
|
||||
@ -88,8 +84,7 @@ remov_formals(p)
|
||||
|
||||
|
||||
|
||||
rem_indir_acc(p)
|
||||
proc_p p;
|
||||
void rem_indir_acc(proc_p p)
|
||||
{
|
||||
/* Formals that may be accessed indirectly
|
||||
* cannot be expanded in line, so they are
|
||||
@ -118,9 +113,7 @@ rem_indir_acc(p)
|
||||
|
||||
|
||||
|
||||
bool par_overlap(off1,t1,off2,t2)
|
||||
offset off1,off2;
|
||||
int t1,t2;
|
||||
bool par_overlap(offset off1, int t1, offset off2, int t2)
|
||||
{
|
||||
/* See if the parameter at offset off1 and type t1
|
||||
* overlaps the paramete at offset off2 and type t2.
|
||||
@ -139,8 +132,7 @@ bool par_overlap(off1,t1,off2,t2)
|
||||
|
||||
|
||||
|
||||
short looplevel(b)
|
||||
bblock_p b;
|
||||
short looplevel(bblock_p b)
|
||||
{
|
||||
/* determine the loop nesting level of basic block b;
|
||||
* this is the highest nesting level of all blocks
|
||||
@ -163,14 +155,13 @@ short looplevel(b)
|
||||
|
||||
|
||||
|
||||
int proclength(p)
|
||||
proc_p p;
|
||||
int proclength(proc_p p)
|
||||
{
|
||||
/* count the number of EM instructions of p */
|
||||
|
||||
register int cnt;
|
||||
register bblock_p b;
|
||||
register line_p l;
|
||||
int cnt;
|
||||
bblock_p b;
|
||||
line_p l;
|
||||
|
||||
cnt = 0;
|
||||
for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) {
|
||||
@ -188,8 +179,7 @@ int proclength(p)
|
||||
|
||||
|
||||
|
||||
line_p copy_code(l1,l2)
|
||||
line_p l1,l2;
|
||||
line_p copy_code(line_p l1, line_p l2)
|
||||
{
|
||||
/* copy the code between l1 and l2 */
|
||||
|
||||
|
||||
@ -8,35 +8,35 @@
|
||||
* I L 1 _ A U X . H
|
||||
*/
|
||||
|
||||
extern bool same_size(); /* (int t1,t2)
|
||||
* See if the two types t1 and t2 have
|
||||
bool same_size(int t1, int t2);
|
||||
/* See if the two types t1 and t2 have
|
||||
* the same size.
|
||||
*/
|
||||
extern rem_actuals(); /* (actual_p atcs)
|
||||
* remove an actual-list from core.
|
||||
void rem_actuals(actual_p acts);
|
||||
/* remove an actual-list from core.
|
||||
*/
|
||||
extern remov_formals(); /* (proc_p p)
|
||||
* Remove the formals-list of p from core.
|
||||
void remov_formals(proc_p p);
|
||||
/* Remove the formals-list of p from core.
|
||||
*/
|
||||
extern rem_indir_acc(); /* (proc_p p)
|
||||
* Remove formal that may be accessed
|
||||
void rem_indir_acc(proc_p p);
|
||||
/* Remove formal that may be accessed
|
||||
* indirectly from formal lists of p
|
||||
*/
|
||||
extern bool par_overlap(); /* (offset off1, int t1, offset off2, int t2)
|
||||
* See if the formal at offset off1 and type t1
|
||||
bool par_overlap(offset off1, int t1, offset off2, int t2);
|
||||
/* See if the formal at offset off1 and type t1
|
||||
* overlaps the formal at offset off2
|
||||
* and type t2.
|
||||
*/
|
||||
extern short looplevel(); /* (bblock_p b)
|
||||
* Determine the loop nesting level of b.
|
||||
short looplevel(bblock_p b);
|
||||
/* Determine the loop nesting level of b.
|
||||
*/
|
||||
extern int proclength(); /* (proc_p p)
|
||||
* Determine the number of EM instructions
|
||||
int proclength(proc_p p);
|
||||
/* Determine the number of EM instructions
|
||||
* in p. Do not count pseudos.
|
||||
*/
|
||||
|
||||
extern line_p copy_code(); /* (line_p l1,l2)
|
||||
* copy the code between l1 and l2.
|
||||
line_p copy_code(line_p l1, line_p l2);
|
||||
/* copy the code between l1 and l2.
|
||||
* Pseudos may not be contained in
|
||||
* the list of instructions. If l1==l2
|
||||
* the result is only one instruction.
|
||||
|
||||
@ -21,14 +21,12 @@
|
||||
#include "il1_aux.h"
|
||||
#include "../share/parser.h"
|
||||
|
||||
STATIC actual_p acts, *app;
|
||||
static actual_p acts, *app;
|
||||
|
||||
#define INIT_ACTS() {acts = (actual_p) 0; app = &acts;}
|
||||
#define APPEND_ACTUAL(a) {*app = a; app = &a->ac_next;}
|
||||
|
||||
STATIC make_actual(l1,l2,size)
|
||||
line_p l1,l2;
|
||||
offset size;
|
||||
static void make_actual(line_p l1, line_p l2, offset size)
|
||||
{
|
||||
/* Allocate a struct for a new actual parameter
|
||||
* expression, the code of which extends from
|
||||
@ -45,9 +43,7 @@ STATIC make_actual(l1,l2,size)
|
||||
|
||||
|
||||
|
||||
STATIC bool chck_asp(p,l)
|
||||
proc_p p;
|
||||
line_p l;
|
||||
static bool chck_asp(proc_p p, line_p l)
|
||||
{
|
||||
/* We require a call to a procedure p that has n formal
|
||||
* parameters to be followed by an 'asp n' instruction
|
||||
@ -60,8 +56,7 @@ STATIC bool chck_asp(p,l)
|
||||
|
||||
|
||||
|
||||
STATIC inc_count(caller,callee)
|
||||
proc_p caller, callee;
|
||||
static void inc_count(proc_p caller, proc_p callee)
|
||||
{
|
||||
/* Update the call-count information.
|
||||
* Record the fact that there is one more call
|
||||
@ -93,11 +88,7 @@ STATIC inc_count(caller,callee)
|
||||
|
||||
|
||||
|
||||
anal_cal(p,call,b,cf)
|
||||
proc_p p;
|
||||
line_p call;
|
||||
bblock_p b;
|
||||
FILE *cf;
|
||||
void anal_cal(proc_p p, line_p call, bblock_p b, FILE *cf)
|
||||
{
|
||||
/* Analyze a call instruction. If the called
|
||||
* routine may be expanded in line, try to
|
||||
|
||||
@ -29,8 +29,8 @@ extern struct class classtab[];
|
||||
#define CLASS9 9
|
||||
|
||||
|
||||
extern anal_cal(); /* (line_p call, bblock_p b)
|
||||
* analyze a call instruction;
|
||||
void anal_cal(proc_p p, line_p call, bblock_p b, FILE *cf);
|
||||
/* analyze a call instruction;
|
||||
* try to recognize the actual parameter
|
||||
* expressions.
|
||||
*/
|
||||
|
||||
@ -27,10 +27,7 @@
|
||||
|
||||
|
||||
|
||||
formal_p find_formal(p,type,off)
|
||||
proc_p p;
|
||||
int type;
|
||||
offset off;
|
||||
formal_p find_formal(proc_p p, int type, offset off)
|
||||
{
|
||||
/* Find a formal parameter of p
|
||||
* If the formal overlaps with an existing formal
|
||||
@ -70,8 +67,7 @@ formal_p find_formal(p,type,off)
|
||||
|
||||
|
||||
|
||||
STATIC no_inl_pars(p)
|
||||
proc_p p;
|
||||
static void no_inl_pars(proc_p p)
|
||||
{
|
||||
/* p may not have any in line parameters */
|
||||
|
||||
@ -81,9 +77,7 @@ STATIC no_inl_pars(p)
|
||||
|
||||
|
||||
|
||||
STATIC inc_use(f,b)
|
||||
formal_p f;
|
||||
bblock_p b;
|
||||
static void inc_use(formal_p f, bblock_p b)
|
||||
{
|
||||
/* Increment the use count of formal f.
|
||||
* The counter has only three states: not used,
|
||||
@ -103,12 +97,7 @@ STATIC inc_use(f,b)
|
||||
|
||||
|
||||
|
||||
formal(p,b,off,type,usage)
|
||||
proc_p p;
|
||||
bblock_p b;
|
||||
offset off;
|
||||
int type,
|
||||
usage;
|
||||
void formal(proc_p p, bblock_p b, offset off, int type, int usage)
|
||||
{
|
||||
/* Analyze a reference to a parameter of p
|
||||
* (occurring within basic block b).
|
||||
|
||||
@ -8,8 +8,8 @@
|
||||
* I L 1 _ F O R M A L . C
|
||||
*/
|
||||
|
||||
extern formal(); /* (proc_p p; bblock_p b; offset off;
|
||||
* int type, usage)
|
||||
void formal(proc_p p, bblock_p b, offset off, int type, int usage);
|
||||
/* int type, usage)
|
||||
* Analyze a reference to a parameter of p.
|
||||
* The type denotes its size (single,double,
|
||||
* pointer).
|
||||
|
||||
@ -33,11 +33,9 @@
|
||||
#define CHANGED(p) p->p_flags2 |= PF_CHANGED
|
||||
#define IS_CHANGED(p) (p->p_flags2 & PF_CHANGED)
|
||||
|
||||
void Sstat(proc_p proclist, long space);
|
||||
|
||||
|
||||
STATIC bool match_pars(fm,act)
|
||||
formal_p fm;
|
||||
actual_p act;
|
||||
static bool match_pars(formal_p fm, actual_p act)
|
||||
{
|
||||
/* Check if every actual parameter has the same
|
||||
* size as its corresponding formal. If not, the
|
||||
@ -55,9 +53,7 @@ STATIC bool match_pars(fm,act)
|
||||
}
|
||||
|
||||
|
||||
STATIC bool change_act(p,act)
|
||||
proc_p p;
|
||||
actual_p act;
|
||||
static bool change_act(proc_p p, actual_p act)
|
||||
{
|
||||
/* See if a call to p migth change any of the
|
||||
* operands of the actual parameter expression.
|
||||
@ -97,8 +93,7 @@ STATIC bool change_act(p,act)
|
||||
|
||||
|
||||
|
||||
STATIC bool is_simple(expr)
|
||||
line_p expr;
|
||||
static bool is_simple(line_p expr)
|
||||
{
|
||||
/* See if expr is something simple, i.e. a constant or
|
||||
* a variable. So the expression must consist of
|
||||
@ -122,9 +117,7 @@ STATIC bool is_simple(expr)
|
||||
|
||||
|
||||
|
||||
STATIC bool too_expensive(fm,act)
|
||||
formal_p fm;
|
||||
actual_p act;
|
||||
static bool too_expensive(formal_p fm, actual_p act)
|
||||
{
|
||||
/* If the formal parameter is used often and the
|
||||
* actual parameter is not something simple
|
||||
@ -135,8 +128,8 @@ STATIC bool too_expensive(fm,act)
|
||||
|
||||
return (OFTEN_USED(fm) && !is_simple(act->ac_exp));
|
||||
}
|
||||
bool anal_params(c)
|
||||
call_p c;
|
||||
|
||||
bool anal_params(call_p c)
|
||||
{
|
||||
/* Determine which of the actual parameters of a
|
||||
* call may be expanded in line.
|
||||
@ -172,8 +165,7 @@ bool anal_params(c)
|
||||
}
|
||||
|
||||
|
||||
STATIC short space_saved(c)
|
||||
call_p c;
|
||||
static short space_saved(call_p c)
|
||||
{
|
||||
/* When a call gets expanded in line, the total size of the
|
||||
* code usually gets incremented, because we have to
|
||||
@ -189,8 +181,7 @@ STATIC short space_saved(c)
|
||||
return (1 + (c->cl_flags & CLF_INLPARS) + (c->cl_proc->p_nrformals>0));
|
||||
}
|
||||
|
||||
STATIC short param_score(c)
|
||||
call_p c;
|
||||
static short param_score(call_p c)
|
||||
{
|
||||
/* If a call has an inline parameter that is a constant,
|
||||
* chances are high that other optimization techniques
|
||||
@ -219,8 +210,7 @@ STATIC short param_score(c)
|
||||
|
||||
|
||||
|
||||
assign_ratio(c)
|
||||
call_p c;
|
||||
void assign_ratio(call_p c)
|
||||
{
|
||||
/* This routine is one of the most important ones
|
||||
* of the inline substitution phase. It assigns a number
|
||||
@ -266,8 +256,7 @@ assign_ratio(c)
|
||||
}
|
||||
|
||||
|
||||
call_p abstract(c)
|
||||
call_p c;
|
||||
call_p abstract(call_p c)
|
||||
{
|
||||
/* Abstract information from the call that is essential
|
||||
* for choosing the calls that will be expanded.
|
||||
@ -288,9 +277,7 @@ call_p abstract(c)
|
||||
|
||||
|
||||
|
||||
STATIC adjust_counts(callee,ccf)
|
||||
proc_p callee;
|
||||
FILE *ccf;
|
||||
static void adjust_counts(proc_p callee, FILE *ccf)
|
||||
{
|
||||
/* A call to callee is expanded in line;
|
||||
* the text of callee is not removed, so
|
||||
@ -309,9 +296,7 @@ STATIC adjust_counts(callee,ccf)
|
||||
|
||||
|
||||
|
||||
STATIC bool is_dispensable(callee,ccf)
|
||||
proc_p callee;
|
||||
FILE *ccf;
|
||||
static bool is_dispensable(proc_p callee, FILE *ccf)
|
||||
{
|
||||
/* A call to callee is expanded in line.
|
||||
* Decrement its P_NRCALLED field and see if
|
||||
@ -339,8 +324,7 @@ STATIC bool is_dispensable(callee,ccf)
|
||||
|
||||
|
||||
|
||||
STATIC call_p nested_calls(a)
|
||||
call_p a;
|
||||
static call_p nested_calls(call_p a)
|
||||
{
|
||||
/* Get a list of all calls that will appear in the
|
||||
* EM text if the call 'a' is expanded in line.
|
||||
@ -369,8 +353,7 @@ STATIC call_p nested_calls(a)
|
||||
|
||||
|
||||
|
||||
STATIC call_p find_origin(c)
|
||||
call_p c;
|
||||
static call_p find_origin(call_p c)
|
||||
{
|
||||
/* c is a nested call. Find the original call.
|
||||
* This origional must be in the P_CALS list
|
||||
@ -384,12 +367,12 @@ STATIC call_p find_origin(c)
|
||||
}
|
||||
assert(FALSE);
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
STATIC selected(a)
|
||||
call_p a;
|
||||
static void selected(call_p a)
|
||||
{
|
||||
/* The call a is selected for in line expansion.
|
||||
* Mark the call as being selected and get the
|
||||
@ -405,9 +388,7 @@ STATIC selected(a)
|
||||
|
||||
|
||||
|
||||
STATIC compare(x,best,space)
|
||||
call_p x, *best;
|
||||
long space;
|
||||
static void compare(call_p x, call_p *best, long space)
|
||||
{
|
||||
/* See if x is better than the current best choice */
|
||||
|
||||
@ -423,9 +404,7 @@ STATIC compare(x,best,space)
|
||||
|
||||
|
||||
|
||||
STATIC call_p best_one(list,space)
|
||||
call_p list;
|
||||
long space;
|
||||
static call_p best_one(call_p list, long space)
|
||||
{
|
||||
/* Find the best candidate of the list
|
||||
* that has not already been selected. The
|
||||
@ -449,8 +428,7 @@ STATIC call_p best_one(list,space)
|
||||
|
||||
|
||||
|
||||
STATIC singles(cals)
|
||||
call_p cals;
|
||||
static void singles(call_p cals)
|
||||
{
|
||||
/* If a procedure is only called once, this call
|
||||
* will be expanded in line, because it costs
|
||||
@ -485,8 +463,7 @@ STATIC singles(cals)
|
||||
|
||||
|
||||
|
||||
STATIC single_calls(proclist)
|
||||
proc_p proclist;
|
||||
static void single_calls(proc_p proclist)
|
||||
{
|
||||
proc_p p;
|
||||
|
||||
@ -504,10 +481,7 @@ STATIC single_calls(proclist)
|
||||
|
||||
|
||||
|
||||
select_calls(proclist,ccf,space)
|
||||
proc_p proclist;
|
||||
FILE *ccf;
|
||||
long space ;
|
||||
void select_calls(proc_p proclist, FILE *ccf, long space)
|
||||
{
|
||||
/* Select all calls that are to be expanded in line. */
|
||||
|
||||
@ -548,16 +522,15 @@ select_calls(proclist,ccf,space)
|
||||
|
||||
|
||||
|
||||
STATIC nonnested_calls(cfile)
|
||||
FILE *cfile;
|
||||
static void nonnested_calls(FILE *cfile)
|
||||
{
|
||||
register call_p c,a;
|
||||
|
||||
while((c = getcall(cfile)) != (call_p) 0) {
|
||||
/* find the call in the call list of the caller */
|
||||
for (a = c->cl_caller->P_CALS;
|
||||
a != (call_p) 0 && c->cl_id != a->cl_id; a = a->cl_cdr);
|
||||
assert(a != (call_p) 0 && a->cl_proc == c->cl_proc);
|
||||
a != NULL && c->cl_id != a->cl_id; ) a = a->cl_cdr;
|
||||
assert(a != NULL && a->cl_proc == c->cl_proc);
|
||||
if (IS_EVER_EXPANDED(a)) {
|
||||
a->cl_actuals = c->cl_actuals;
|
||||
c->cl_actuals = (actual_p) 0;
|
||||
@ -568,8 +541,7 @@ STATIC nonnested_calls(cfile)
|
||||
|
||||
|
||||
|
||||
STATIC copy_pars(src,dest)
|
||||
call_p src, dest;
|
||||
static void copy_pars(call_p src, call_p dest)
|
||||
{
|
||||
/* Copy the actual parameters of src to dest. */
|
||||
|
||||
@ -588,8 +560,7 @@ STATIC copy_pars(src,dest)
|
||||
|
||||
|
||||
|
||||
STATIC nest_pars(cals)
|
||||
call_p cals;
|
||||
static void nest_pars(call_p cals)
|
||||
{
|
||||
/* Recursive auxiliary procedure of add_actuals. */
|
||||
|
||||
@ -606,9 +577,7 @@ STATIC nest_pars(cals)
|
||||
|
||||
|
||||
|
||||
add_actuals(proclist,cfile)
|
||||
proc_p proclist;
|
||||
FILE *cfile;
|
||||
void add_actuals(proc_p proclist, FILE *cfile)
|
||||
{
|
||||
/* Fetch the actual parameters of all selected calls.
|
||||
* For all non-nested calls (i.e. those calls that
|
||||
@ -632,8 +601,7 @@ add_actuals(proclist,cfile)
|
||||
|
||||
|
||||
|
||||
STATIC clean(cals)
|
||||
call_p *cals;
|
||||
static void clean(call_p *cals)
|
||||
{
|
||||
call_p c,next,*cpp;
|
||||
|
||||
@ -654,8 +622,7 @@ STATIC clean(cals)
|
||||
}
|
||||
|
||||
|
||||
cleancals(proclist)
|
||||
proc_p proclist;
|
||||
void cleancals(proc_p proclist)
|
||||
{
|
||||
/* Remove all calls in the P_CALS list of p
|
||||
* that were not selected for in line expansion.
|
||||
@ -671,9 +638,7 @@ cleancals(proclist)
|
||||
|
||||
|
||||
|
||||
append_abstract(a,p)
|
||||
call_p a;
|
||||
proc_p p;
|
||||
void append_abstract(call_p a, proc_p p)
|
||||
{
|
||||
/* Append an abstract of a call-descriptor to
|
||||
* the call-list of procedure p.
|
||||
@ -697,9 +662,7 @@ append_abstract(a,p)
|
||||
*/
|
||||
|
||||
|
||||
Sstatist(list,space)
|
||||
call_p list;
|
||||
long space;
|
||||
void Sstatist(call_p list, long space)
|
||||
{
|
||||
call_p c;
|
||||
|
||||
@ -716,9 +679,7 @@ Sstatist(list,space)
|
||||
}
|
||||
}
|
||||
|
||||
Sstat(proclist,space)
|
||||
proc_p proclist;
|
||||
long space;
|
||||
void Sstat(proc_p proclist, long space)
|
||||
{
|
||||
proc_p p;
|
||||
|
||||
|
||||
@ -3,41 +3,41 @@
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
extern bool anal_params(); /* (call_p c)
|
||||
* See which parameters of the call
|
||||
bool anal_params(call_p c);
|
||||
/* See which parameters of the call
|
||||
* may be expanded in line.
|
||||
* If the formals and actuals do not
|
||||
* match, return FALSE
|
||||
*/
|
||||
extern assign_ratio(); /* (call_p c)
|
||||
* Assigna ratio number to the call,
|
||||
void assign_ratio(call_p c);
|
||||
/* Assigna ratio number to the call,
|
||||
* indicating how desirable it is to
|
||||
* expand the call in line.
|
||||
*/
|
||||
extern call_p abstract(); /* (call_p c)
|
||||
* Abstract essential information from
|
||||
call_p abstract(call_p c);
|
||||
/* Abstract essential information from
|
||||
* the call.
|
||||
*/
|
||||
extern select_calls(); /* (call_p alist; FILE *ccf;short space)
|
||||
* Select the best calls to be expanded.
|
||||
void select_calls(proc_p proclist, FILE *ccf, long space);
|
||||
/* Select the best calls to be expanded.
|
||||
* Every procedure gets a list of
|
||||
* selected calls appearing in it.
|
||||
* space is the amount of space that the
|
||||
* program is allowed to grow
|
||||
* (expressed in number of EM instructions).
|
||||
*/
|
||||
extern cleancals(); /* (proc_p plist)
|
||||
* Remove all calls that were not selected.
|
||||
void cleancals(proc_p proclist);
|
||||
/* Remove all calls that were not selected.
|
||||
*/
|
||||
extern add_actuals(); /* (proc_p plist; FILE *cfile)
|
||||
* Add the actual parameters to the descriptor abstracts
|
||||
* of the selected calls.
|
||||
* the calfile contains the full descriptors of all
|
||||
* calls.
|
||||
* These two are combined to yield a file of full
|
||||
* descriptors of the selected calls.
|
||||
*/
|
||||
extern append_abstract(); /* (call_p a; proc_p p)
|
||||
* Put the call-descriptor abstract in the p_cals
|
||||
void add_actuals(proc_p proclist, FILE *cfile);
|
||||
/* Add the actual parameters to the descriptor abstracts
|
||||
* of the selected calls.
|
||||
* the calfile contains the full descriptors of all
|
||||
* calls.
|
||||
* These two are combined to yield a file of full
|
||||
* descriptors of the selected calls.
|
||||
*/
|
||||
void append_abstract(call_p a, proc_p p);
|
||||
/* Put the call-descriptor abstract in the p_cals
|
||||
* list of p.
|
||||
*/
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
* I L 3 _ A U X . C
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "../share/types.h"
|
||||
#include "il.h"
|
||||
#include "../share/debug.h"
|
||||
@ -19,8 +19,7 @@
|
||||
|
||||
|
||||
|
||||
line_p last_line(lines)
|
||||
line_p lines;
|
||||
line_p last_line(line_p lines)
|
||||
{
|
||||
/* Determine the last line of a list */
|
||||
|
||||
@ -33,8 +32,7 @@ line_p last_line(lines)
|
||||
|
||||
|
||||
|
||||
app_list(list,l)
|
||||
line_p list,l;
|
||||
void app_list(line_p list, line_p l)
|
||||
{
|
||||
/* Append the list after line l */
|
||||
|
||||
@ -53,8 +51,7 @@ app_list(list,l)
|
||||
|
||||
|
||||
|
||||
rem_line(l)
|
||||
line_p l;
|
||||
void rem_line(line_p l)
|
||||
{
|
||||
/* Remove a line from the list */
|
||||
|
||||
|
||||
@ -8,13 +8,13 @@
|
||||
* I L 3 _ A U X . H
|
||||
*/
|
||||
|
||||
extern line_p last_line(); /* (line_p list)
|
||||
* Find the last line of a list.
|
||||
line_p last_line(line_p lines);
|
||||
/* Find the last line of a list.
|
||||
*/
|
||||
extern app_list(); /* (line_p list,l)
|
||||
* Put list after l
|
||||
void app_list(line_p list, line_p l);
|
||||
/* Put list after l
|
||||
*/
|
||||
extern rem_line(); /* (line_p l)
|
||||
* Remove a line from a (doubly linked)
|
||||
void rem_line(line_p l);
|
||||
/* Remove a line from a (doubly linked)
|
||||
* list.
|
||||
*/
|
||||
|
||||
@ -33,8 +33,7 @@
|
||||
|
||||
|
||||
|
||||
STATIC line_p par_expr(l,expr)
|
||||
line_p l, expr;
|
||||
static line_p par_expr(line_p l, line_p expr)
|
||||
{
|
||||
/* Find the first line of the expression of which
|
||||
* l is the last line; expr contains a pointer
|
||||
@ -53,8 +52,7 @@ STATIC line_p par_expr(l,expr)
|
||||
|
||||
|
||||
|
||||
STATIC rem_text(l1,l2)
|
||||
line_p l1,l2;
|
||||
static void rem_text(line_p l1, line_p l2)
|
||||
{
|
||||
/* Remove the lines from l1 to l2 (inclusive) */
|
||||
|
||||
@ -68,10 +66,7 @@ STATIC rem_text(l1,l2)
|
||||
|
||||
|
||||
|
||||
STATIC store_tmp(p,l,size)
|
||||
proc_p p;
|
||||
line_p l;
|
||||
offset size;
|
||||
static void store_tmp(proc_p p, line_p l, offset size)
|
||||
{
|
||||
/* Emit code to store a 'size'-byte value in a new
|
||||
* temporary local variable in the stack frame of p.
|
||||
@ -102,9 +97,7 @@ STATIC store_tmp(p,l,size)
|
||||
|
||||
|
||||
|
||||
STATIC chg_actuals(c,cal)
|
||||
call_p c;
|
||||
line_p cal;
|
||||
static void chg_actuals(call_p c, line_p cal)
|
||||
{
|
||||
/* Change the actual parameter expressions of the call. */
|
||||
|
||||
@ -130,9 +123,7 @@ STATIC chg_actuals(c,cal)
|
||||
|
||||
|
||||
|
||||
STATIC rm_callpart(c,cal)
|
||||
call_p c;
|
||||
line_p cal;
|
||||
static void rm_callpart(call_p c, line_p cal)
|
||||
{
|
||||
/* Remove the call part, consisting of a CAL,
|
||||
* an optional ASP and an optional LFR.
|
||||
@ -154,9 +145,7 @@ STATIC rm_callpart(c,cal)
|
||||
|
||||
|
||||
|
||||
chg_callseq(c,cal,l_out)
|
||||
call_p c;
|
||||
line_p cal,*l_out;
|
||||
void chg_callseq(call_p c, line_p cal, line_p *l_out)
|
||||
{
|
||||
/* Change the calling sequence. The actual parameter
|
||||
* expressions are changed (in line parameters are
|
||||
@ -174,9 +163,7 @@ chg_callseq(c,cal,l_out)
|
||||
|
||||
/* make_label */
|
||||
|
||||
line_p make_label(l,p)
|
||||
line_p l;
|
||||
proc_p p;
|
||||
line_p make_label(line_p l, proc_p p)
|
||||
{
|
||||
/* Make sure that the instruction after l
|
||||
* contains an instruction label. If this is
|
||||
@ -200,9 +187,7 @@ line_p make_label(l,p)
|
||||
|
||||
/* modify */
|
||||
|
||||
STATIC act_info(off,acts,ab_off,act_out,off_out)
|
||||
offset off, ab_off, *off_out;
|
||||
actual_p acts, *act_out;
|
||||
static void act_info(offset off, actual_p acts, offset ab_off, actual_p *act_out, offset *off_out)
|
||||
{
|
||||
/* Find the actual parameter that corresponds to
|
||||
* the formal parameter with the given offset.
|
||||
@ -236,9 +221,7 @@ STATIC act_info(off,acts,ab_off,act_out,off_out)
|
||||
|
||||
|
||||
|
||||
STATIC store_off(off,l)
|
||||
offset off;
|
||||
line_p l;
|
||||
static void store_off(offset off, line_p l)
|
||||
{
|
||||
if (TYPE(l) == OPSHORT) {
|
||||
assert ((short) off == off);
|
||||
@ -250,8 +233,7 @@ STATIC store_off(off,l)
|
||||
|
||||
|
||||
|
||||
STATIC inl_actual(l,expr)
|
||||
line_p l, expr;
|
||||
static void inl_actual(line_p l, line_p expr)
|
||||
{
|
||||
/* Expand an actual parameter in line.
|
||||
* A LOL or LDL instruction is replaced
|
||||
@ -280,10 +262,7 @@ STATIC inl_actual(l,expr)
|
||||
|
||||
|
||||
|
||||
STATIC localref(l,c,ab_off,lb_off)
|
||||
line_p l;
|
||||
call_p c;
|
||||
offset ab_off, lb_off;
|
||||
static void localref(line_p l, call_p c, offset ab_off, offset lb_off)
|
||||
{
|
||||
/* Change a reference to a local variable or parameter
|
||||
* of the called procedure.
|
||||
@ -310,10 +289,7 @@ STATIC localref(l,c,ab_off,lb_off)
|
||||
|
||||
|
||||
|
||||
STATIC chg_mes(l,c,ab_off,lb_off)
|
||||
line_p l;
|
||||
call_p c;
|
||||
offset ab_off, lb_off;
|
||||
static void chg_mes(line_p l, call_p c, offset ab_off, offset lb_off)
|
||||
{
|
||||
/* The register messages of the called procedure
|
||||
* must be changed. If the message applies to a
|
||||
@ -354,9 +330,7 @@ STATIC chg_mes(l,c,ab_off,lb_off)
|
||||
|
||||
|
||||
|
||||
STATIC chg_ret(l,c,lab)
|
||||
line_p l,lab;
|
||||
call_p c;
|
||||
static void chg_ret(line_p l, call_p c, line_p lab)
|
||||
{
|
||||
/* Change the RET instruction appearing in the
|
||||
* expanded text of a call. If the called procedure
|
||||
@ -378,11 +352,7 @@ STATIC chg_ret(l,c,lab)
|
||||
|
||||
|
||||
|
||||
STATIC mod_instr(l,c,lab,ab_off,lb_off,lab_off)
|
||||
line_p l,lab;
|
||||
call_p c;
|
||||
offset ab_off,lb_off;
|
||||
int lab_off;
|
||||
static void mod_instr(line_p l, call_p c, line_p lab, offset ab_off, offset lb_off, int lab_off)
|
||||
{
|
||||
if (TYPE(l) == OPINSTRLAB) {
|
||||
INSTRLAB(l) += lab_off;
|
||||
@ -420,11 +390,7 @@ STATIC mod_instr(l,c,lab,ab_off,lb_off,lab_off)
|
||||
}
|
||||
|
||||
|
||||
modify(text,c,lab,ab_off,lb_off,lab_off)
|
||||
line_p text,lab;
|
||||
call_p c;
|
||||
offset ab_off,lb_off;
|
||||
int lab_off;
|
||||
void modify(line_p text, call_p c, line_p lab, offset ab_off, offset lb_off, int lab_off)
|
||||
{
|
||||
/* Modify the EM text of the called procedure.
|
||||
* References to locals and parameters are
|
||||
@ -436,7 +402,7 @@ modify(text,c,lab,ab_off,lb_off,lab_off)
|
||||
* Note that the first line of the text is a dummy instruction.
|
||||
*/
|
||||
|
||||
register line_p l;
|
||||
line_p l;
|
||||
line_p next;
|
||||
|
||||
for (l = text->l_next; l != (line_p) 0; l = next) {
|
||||
@ -452,11 +418,7 @@ modify(text,c,lab,ab_off,lb_off,lab_off)
|
||||
|
||||
|
||||
|
||||
mod_actuals(nc,c,lab,ab_off,lb_off,lab_off)
|
||||
call_p nc,c;
|
||||
line_p lab;
|
||||
offset ab_off,lb_off;
|
||||
int lab_off;
|
||||
void mod_actuals(call_p nc, call_p c, line_p lab, offset ab_off, offset lb_off, int lab_off)
|
||||
{
|
||||
actual_p act;
|
||||
line_p l, next, dum;
|
||||
@ -484,8 +446,7 @@ mod_actuals(nc,c,lab,ab_off,lb_off,lab_off)
|
||||
|
||||
/* insert */
|
||||
|
||||
STATIC line_p first_nonpseudo(l)
|
||||
line_p l;
|
||||
static line_p first_nonpseudo(line_p l)
|
||||
{
|
||||
/* Find the first non-pseudo instruction of
|
||||
* a list of instructions.
|
||||
@ -498,8 +459,7 @@ STATIC line_p first_nonpseudo(l)
|
||||
|
||||
|
||||
|
||||
insert(text,l,firstline)
|
||||
line_p text,l,firstline;
|
||||
void insert(line_p text, line_p l, line_p firstline)
|
||||
{
|
||||
/* Insert the modified EM text of the called
|
||||
* routine in the calling routine. Pseudos are
|
||||
@ -532,9 +492,7 @@ insert(text,l,firstline)
|
||||
|
||||
|
||||
|
||||
liquidate(p,text)
|
||||
proc_p p;
|
||||
line_p text;
|
||||
void liquidate(proc_p p, line_p text)
|
||||
{
|
||||
/* All calls to procedure p were expanded in line, so
|
||||
* p is no longer needed. However, we must not throw away
|
||||
|
||||
@ -9,8 +9,8 @@
|
||||
*/
|
||||
|
||||
|
||||
extern chg_callseq(); /* (call_p c; line_p cal, *l_out)
|
||||
* Change the calling sequence of
|
||||
void chg_callseq(call_p c, line_p cal, line_p *l_out);
|
||||
/* Change the calling sequence of
|
||||
* the call c. The parameters are
|
||||
* changed and the sequence
|
||||
* CAL - ASP - LFR is removed.
|
||||
@ -19,28 +19,26 @@ extern chg_callseq(); /* (call_p c; line_p cal, *l_out)
|
||||
* text of the called routine must
|
||||
* be put.
|
||||
*/
|
||||
extern line_p make_label(); /* (line_p l; proc_p p)
|
||||
* Make sure that the instruction after
|
||||
line_p make_label(line_p l, proc_p p);
|
||||
/* Make sure that the instruction after
|
||||
* l contains a label. If this is not
|
||||
* already the case, create a new label.
|
||||
*/
|
||||
extern modify(); /* (line_p text; call_p c; line_p lab;
|
||||
* offset ab_off, lb_off; int lab_off)
|
||||
* Modify the EM text of the called
|
||||
void modify(line_p text, call_p c, line_p lab, offset ab_off, offset lb_off, int lab_off);
|
||||
/* Modify the EM text of the called
|
||||
* procedure.
|
||||
*/
|
||||
extern mod_actuals(); /* (call_p nc,c; line_p lab;
|
||||
* offset ab_off, lb_off; int lab_off)
|
||||
* Modify the actual parameters of the
|
||||
void mod_actuals(call_p nc, call_p c, line_p lab, offset ab_off, offset lb_off, int lab_off);
|
||||
/* Modify the actual parameters of the
|
||||
* call nc the same way as the text of
|
||||
* call c would be modified.
|
||||
*/
|
||||
extern insert(); /* (line_p text,l,firstline)
|
||||
* Insert the modified EM text.
|
||||
void insert(line_p text, line_p l, line_p firstline);
|
||||
/* Insert the modified EM text.
|
||||
* Pseudos are put after the pseudos
|
||||
* of the caller.
|
||||
*/
|
||||
extern liquidate(); /* (proc_p p; line_p text)
|
||||
* All calls to p were expanded in line,
|
||||
void liquidate(proc_p p, line_p text);
|
||||
/* All calls to p were expanded in line,
|
||||
* so p is no longer needed.
|
||||
*/
|
||||
|
||||
@ -22,9 +22,7 @@
|
||||
#include "il3_change.h"
|
||||
#include "il3_subst.h"
|
||||
|
||||
STATIC line_p fetch_text(lf,c)
|
||||
FILE *lf;
|
||||
call_p c;
|
||||
static line_p fetch_text(FILE *lf, call_p c)
|
||||
{
|
||||
/* Read the EM text of the called procedure.
|
||||
* We use random access I/O here.
|
||||
@ -47,13 +45,10 @@ STATIC line_p fetch_text(lf,c)
|
||||
|
||||
|
||||
|
||||
line_p scan_to_cal(lines,n)
|
||||
line_p lines;
|
||||
short n;
|
||||
line_p scan_to_cal(line_p lines, short n)
|
||||
{
|
||||
/* Find the n-th CAL instruction */
|
||||
|
||||
register line_p l;
|
||||
line_p l;
|
||||
|
||||
for (l = lines; l != (line_p) 0; l = l->l_next) {
|
||||
if (INSTR(l) == op_cal) {
|
||||
@ -65,10 +60,7 @@ line_p scan_to_cal(lines,n)
|
||||
|
||||
|
||||
|
||||
substitute(lf,c,cal,firstline)
|
||||
FILE *lf;
|
||||
call_p c;
|
||||
line_p cal,firstline;
|
||||
void substitute(FILE *lf, call_p c, line_p cal, line_p firstline)
|
||||
{
|
||||
/* Perform in line substitution of the call described
|
||||
* by c. The EM text of the called routine is fetched
|
||||
|
||||
@ -9,11 +9,11 @@
|
||||
* I L 3 _ S U B S T . H
|
||||
*/
|
||||
|
||||
extern line_p scan_to_cal(); /* (line_p lines; short n)
|
||||
* Find the n-th cal instruction.
|
||||
line_p scan_to_cal(line_p lines, short n);
|
||||
/* Find the n-th cal instruction.
|
||||
*/
|
||||
extern substitute(); /* (FILE *lf;call_p c; line_ pcal,firstline)
|
||||
* Perform in line substitution of the call described
|
||||
void substitute(FILE *lf, call_p c, line_p cal, line_p firstline);
|
||||
/* Perform in line substitution of the call described
|
||||
* by c. The EM text of the called routine is fetched
|
||||
* and modified, the calling sequence is changed,
|
||||
* the modified routine is put at the place of the call
|
||||
|
||||
@ -25,8 +25,7 @@
|
||||
#include "il_aux.h"
|
||||
|
||||
|
||||
int tsize(type)
|
||||
int type;
|
||||
int tsize(int type)
|
||||
{
|
||||
/* Determine the size of a variable of the
|
||||
* given type.
|
||||
@ -39,12 +38,12 @@ int tsize(type)
|
||||
default: assert(FALSE);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
line_p duplicate(lnp)
|
||||
line_p lnp;
|
||||
line_p duplicate(line_p lnp)
|
||||
{
|
||||
/* Make a duplicate of an EM instruction.
|
||||
* Pseudos may not be passed as argument.
|
||||
@ -81,8 +80,7 @@ line_p duplicate(lnp)
|
||||
|
||||
|
||||
|
||||
line_p copy_expr(l1)
|
||||
line_p l1;
|
||||
line_p copy_expr(line_p l1)
|
||||
{
|
||||
/* copy the expression */
|
||||
|
||||
@ -105,8 +103,7 @@ line_p copy_expr(l1)
|
||||
|
||||
|
||||
|
||||
rem_call(c)
|
||||
call_p c;
|
||||
void rem_call(call_p c)
|
||||
{
|
||||
actual_p act, nexta;
|
||||
call_p nc,nextc;
|
||||
@ -133,11 +130,9 @@ rem_call(c)
|
||||
|
||||
/* rem_graph */
|
||||
|
||||
STATIC short remlines(l)
|
||||
line_p l;
|
||||
static void remlines(line_p l)
|
||||
{
|
||||
|
||||
register line_p lnp;
|
||||
line_p lnp;
|
||||
line_p next;
|
||||
|
||||
for (lnp = l; lnp != (line_p) 0; lnp = next) {
|
||||
@ -148,12 +143,9 @@ STATIC short remlines(l)
|
||||
|
||||
|
||||
|
||||
remunit(kind,p,l)
|
||||
short kind;
|
||||
proc_p p;
|
||||
line_p l;
|
||||
void remunit(short kind, proc_p p, line_p l)
|
||||
{
|
||||
register bblock_p b;
|
||||
bblock_p b;
|
||||
bblock_p next;
|
||||
Lindex pi;
|
||||
|
||||
@ -174,13 +166,13 @@ remunit(kind,p,l)
|
||||
oldloop(Lelem(pi));
|
||||
}
|
||||
Ldeleteset(p->p_loops);
|
||||
oldmap(lmap,llength);
|
||||
oldmap(lbmap,llength);
|
||||
oldmap(bmap,blength);
|
||||
oldmap(lpmap,lplength);
|
||||
oldmap((short **)lmap,llength);
|
||||
oldmap((short **)lbmap,llength);
|
||||
oldmap((short **)bmap,blength);
|
||||
oldmap((short **)lpmap,lplength);
|
||||
}
|
||||
remcc(head)
|
||||
calcnt_p head;
|
||||
|
||||
void remcc(calcnt_p head)
|
||||
{
|
||||
calcnt_p cc, next;
|
||||
|
||||
@ -193,8 +185,7 @@ remcc(head)
|
||||
|
||||
/* Extra I/O routines */
|
||||
|
||||
call_p getcall(cf)
|
||||
FILE *cf;
|
||||
call_p getcall(FILE *cf)
|
||||
{
|
||||
/* read a call from the call-file */
|
||||
|
||||
@ -220,7 +211,7 @@ call_p getcall(cf)
|
||||
m = getshort();
|
||||
act->ac_size = getoff();
|
||||
act->ac_inl = getbyte();
|
||||
act->ac_exp = getlines(cf,m,&voided);
|
||||
act->ac_exp = getlines(cf,m,&voided, 0); //WARN
|
||||
*app = act;
|
||||
app = &act->ac_next;
|
||||
}
|
||||
@ -230,9 +221,7 @@ call_p getcall(cf)
|
||||
|
||||
|
||||
|
||||
line_p get_text(lf,p_out)
|
||||
FILE *lf;
|
||||
proc_p *p_out;
|
||||
line_p get_text(FILE *lf, proc_p *p_out)
|
||||
{
|
||||
/* Read the EM text of one unit
|
||||
* If it is a procedure, set p_out to
|
||||
@ -269,8 +258,8 @@ line_p get_text(lf,p_out)
|
||||
* and labels to basic blocks are not used.
|
||||
*/
|
||||
if (*p_out != (proc_p) 0) {
|
||||
oldmap(lmap,llength);
|
||||
oldmap(lbmap,llength);
|
||||
oldmap((short **)lmap,llength);
|
||||
oldmap((short **)lbmap,llength);
|
||||
lmap = oldlmap;
|
||||
lpmap = oldlpmap;
|
||||
}
|
||||
@ -281,9 +270,7 @@ line_p get_text(lf,p_out)
|
||||
|
||||
|
||||
|
||||
calcnt_p getcc(ccf,p)
|
||||
FILE *ccf;
|
||||
proc_p p;
|
||||
calcnt_p getcc(FILE *ccf, proc_p p)
|
||||
{
|
||||
/* Get call-count info of procedure p */
|
||||
|
||||
@ -307,9 +294,7 @@ calcnt_p getcc(ccf,p)
|
||||
/* The following routines are only used by the Inline Substitution phase */
|
||||
|
||||
|
||||
STATIC putactuals(alist,cfile)
|
||||
actual_p alist;
|
||||
FILE *cfile;
|
||||
static void putactuals(actual_p alist, FILE *cfile)
|
||||
{
|
||||
/* output a list of actual parameters */
|
||||
|
||||
@ -334,10 +319,7 @@ STATIC putactuals(alist,cfile)
|
||||
|
||||
|
||||
|
||||
putcall(c,cfile,level)
|
||||
call_p c;
|
||||
FILE *cfile;
|
||||
short level;
|
||||
void putcall(call_p c, FILE *cfile, short level)
|
||||
{
|
||||
/* output a call */
|
||||
|
||||
@ -362,9 +344,7 @@ putcall(c,cfile,level)
|
||||
}
|
||||
}
|
||||
|
||||
long putcc(head,ccf)
|
||||
calcnt_p head;
|
||||
FILE *ccf;
|
||||
long putcc(calcnt_p head, FILE *ccf)
|
||||
{
|
||||
/* Write call-count information to file ccf.
|
||||
* Return the disk address of the info written.
|
||||
|
||||
@ -9,50 +9,46 @@
|
||||
* I L _ A U X . H
|
||||
*/
|
||||
|
||||
extern int tsize(); /* (int type)
|
||||
* Determine the size of a variable of
|
||||
int tsize(int type);
|
||||
/* Determine the size of a variable of
|
||||
* the given type.
|
||||
*/
|
||||
extern line_p duplicate(); /* (line_p lnp)
|
||||
* Make a duplicate of the given EM
|
||||
line_p duplicate(line_p lnp);
|
||||
/* Make a duplicate of the given EM
|
||||
* instruction. Pseudos may not be
|
||||
* passed as argumnets.
|
||||
*/
|
||||
extern line_p copy_expr(); /* (line_p l1)
|
||||
* copy the expression l1.
|
||||
line_p copy_expr(line_p l1);
|
||||
/* copy the expression l1.
|
||||
* Pseudos may not be contained in
|
||||
* the list of instructions.
|
||||
*/
|
||||
extern rem_call(); /* (call_p c)
|
||||
* Remove a call from main memory.
|
||||
void rem_call(call_p c);
|
||||
/* Remove a call from main memory.
|
||||
*/
|
||||
extern rem_graph(); /* (proc_p p)
|
||||
* Remove the CFG and EM text of
|
||||
* a procedure from core.
|
||||
void remcc(calcnt_p head);
|
||||
/* Remove call-count info from core.
|
||||
*/
|
||||
extern remcc(); /* (calcnt_p head)
|
||||
* Remove call-count info from core.
|
||||
call_p getcall(FILE *cf);
|
||||
/* Read a call from the call-file
|
||||
*/
|
||||
extern call_p getcall(); /* (FILE *cf)
|
||||
* Read a call from the call-file
|
||||
*/
|
||||
extern line_p get_text(); /* (FILE *lf; proc_p *p_out)
|
||||
* Read the EM text of one procedure.
|
||||
line_p get_text(FILE *lf, proc_p *p_out);
|
||||
/* Read the EM text of one procedure.
|
||||
* The procedure read is returned via
|
||||
* p_out.
|
||||
*/
|
||||
extern calcnt_p getcc(); /* (FILE *ccf; proc_p p)
|
||||
* Read the call-count information
|
||||
calcnt_p getcc(FILE *ccf, proc_p p);
|
||||
/* Read the call-count information
|
||||
* of procedure p.
|
||||
*/
|
||||
extern putcall(); /* (call_p call; FILE *cfile; short level)
|
||||
* Write the call
|
||||
void putcall(call_p c, FILE *cfile, short level);
|
||||
/* Write the call
|
||||
* with the given id to the given file.
|
||||
* The level is the nesting level, used by
|
||||
* putcall when it calls itself recurively.
|
||||
* It should be 0 on outer levels.
|
||||
*/
|
||||
extern long putcc(); /* (calcnt_p head; FILE *ccf)
|
||||
* Write call-count information to
|
||||
long putcc(calcnt_p head, FILE *ccf);
|
||||
/* Write call-count information to
|
||||
* file ccf.
|
||||
*/
|
||||
|
||||
111
util/ego/lv/lv.c
111
util/ego/lv/lv.c
@ -38,25 +38,24 @@
|
||||
short nrglobals;
|
||||
short nrvars;
|
||||
|
||||
STATIC int Slv;
|
||||
STATIC bool mesgflag = FALSE; /* Suppress generation of live/dead info */
|
||||
static int Slv;
|
||||
static bool mesgflag = FALSE; /* Suppress generation of live/dead info */
|
||||
|
||||
STATIC app_block();
|
||||
static void app_block(line_p l, bblock_p b);
|
||||
|
||||
STATIC clean_up()
|
||||
static void clean_up()
|
||||
{
|
||||
local_p *p;
|
||||
|
||||
for (p = &locals[1]; p <= &locals[nrlocals]; p++) {
|
||||
oldlocal(*p);
|
||||
}
|
||||
oldmap(locals,nrlocals);
|
||||
oldmap((short **)locals,nrlocals);
|
||||
}
|
||||
|
||||
|
||||
|
||||
STATIC bool is_dir_use(l)
|
||||
line_p l;
|
||||
static bool is_dir_use(line_p l)
|
||||
{
|
||||
/* See if l is a direct use of some variable
|
||||
* (i.e. not through a pointer). A LIL is a
|
||||
@ -89,8 +88,7 @@ STATIC bool is_dir_use(l)
|
||||
|
||||
|
||||
|
||||
STATIC bool is_indir_use(l)
|
||||
line_p l;
|
||||
static bool is_indir_use(line_p l)
|
||||
{
|
||||
/* See if instruction l uses some variable(s) indirectly,
|
||||
* i.e. through a pointer or via a procedure call.
|
||||
@ -113,12 +111,12 @@ STATIC bool is_indir_use(l)
|
||||
return FALSE;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
STATIC bool is_def(l)
|
||||
line_p l;
|
||||
static bool is_def(line_p l)
|
||||
{
|
||||
/* See if l does a direct definition */
|
||||
|
||||
@ -134,11 +132,11 @@ STATIC bool is_def(l)
|
||||
return FALSE;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
STATIC def_use(p)
|
||||
proc_p p;
|
||||
static void def_use(proc_p p)
|
||||
{
|
||||
/* Compute DEF(b) and USE(b), for every basic block b
|
||||
* of procedure p. DEF(b) contains the variables that
|
||||
@ -151,8 +149,8 @@ STATIC def_use(p)
|
||||
* the basic block from beginning till end.
|
||||
*/
|
||||
|
||||
register bblock_p b;
|
||||
register line_p l;
|
||||
bblock_p b;
|
||||
line_p l;
|
||||
short v;
|
||||
bool found;
|
||||
cset all_ind_uses;
|
||||
@ -200,14 +198,11 @@ STATIC def_use(p)
|
||||
|
||||
|
||||
|
||||
STATIC unite_ins(bbset,setp)
|
||||
lset bbset;
|
||||
cset *setp;
|
||||
static void unite_ins(lset bbset, cset *setp)
|
||||
{
|
||||
/* Take the union of L_IN(b), for all b in bbset,
|
||||
* and put the result in setp.
|
||||
*/
|
||||
|
||||
Lindex i;
|
||||
|
||||
Cclear_set(setp);
|
||||
@ -218,8 +213,7 @@ STATIC unite_ins(bbset,setp)
|
||||
|
||||
|
||||
|
||||
STATIC solve_lv(p)
|
||||
proc_p p;
|
||||
static void solve_lv(proc_p p)
|
||||
{
|
||||
/* Solve the data flow equations for Live Variables,
|
||||
* for procedure p. These equations are:
|
||||
@ -254,8 +248,7 @@ STATIC solve_lv(p)
|
||||
}
|
||||
|
||||
|
||||
STATIC live_variables_analysis(p)
|
||||
proc_p p;
|
||||
static void live_variables_analysis(proc_p p)
|
||||
{
|
||||
make_localtab(p);
|
||||
nrvars = nrglobals + nrlocals;
|
||||
@ -264,14 +257,13 @@ STATIC live_variables_analysis(p)
|
||||
}
|
||||
|
||||
|
||||
STATIC init_live_dead(b)
|
||||
bblock_p b;
|
||||
static void init_live_dead(bblock_p b)
|
||||
{
|
||||
/* For every register variable, see if it is
|
||||
* live or dead at the end of b.
|
||||
*/
|
||||
|
||||
register short v;
|
||||
short v;
|
||||
local_p loc;
|
||||
|
||||
for (v = 1; v <= nrlocals; v++) {
|
||||
@ -286,9 +278,7 @@ STATIC init_live_dead(b)
|
||||
|
||||
|
||||
|
||||
STATIC line_p make_mesg(mesg,loc)
|
||||
short mesg;
|
||||
local_p loc;
|
||||
static line_p make_mesg(short mesg,local_p loc)
|
||||
{
|
||||
/* Create a line for a message stating that
|
||||
* local variable loc is live/dead. This message
|
||||
@ -297,7 +287,7 @@ STATIC line_p make_mesg(mesg,loc)
|
||||
*/
|
||||
|
||||
line_p l = newline(OPLIST);
|
||||
register arg_p ap;
|
||||
arg_p ap;
|
||||
|
||||
l->l_instr = ps_mes;
|
||||
ap = ARG(l) = newarg(ARGOFF);
|
||||
@ -313,8 +303,7 @@ STATIC line_p make_mesg(mesg,loc)
|
||||
|
||||
|
||||
|
||||
STATIC block_entry(b,prev)
|
||||
bblock_p b,prev;
|
||||
static void block_entry(bblock_p b, bblock_p prev)
|
||||
{
|
||||
short v,vn;
|
||||
local_p loc;
|
||||
@ -345,9 +334,7 @@ STATIC block_entry(b,prev)
|
||||
|
||||
|
||||
|
||||
STATIC app_block(l,b)
|
||||
line_p l;
|
||||
bblock_p b;
|
||||
static void app_block(line_p l, bblock_p b)
|
||||
{
|
||||
line_p x = b->b_start;
|
||||
|
||||
@ -369,11 +356,7 @@ STATIC app_block(l,b)
|
||||
|
||||
|
||||
|
||||
STATIC definition(l,useless_out,v_out,mesgflag)
|
||||
line_p l;
|
||||
bool *useless_out;
|
||||
short *v_out;
|
||||
bool mesgflag;
|
||||
static void definition(line_p l, bool *useless_out, short *v_out, bool mesgflag)
|
||||
{
|
||||
/* Process a definition. If the defined (register-) variable
|
||||
* is live after 'l', then create a live-message and put
|
||||
@ -420,9 +403,7 @@ STATIC definition(l,useless_out,v_out,mesgflag)
|
||||
|
||||
|
||||
|
||||
STATIC use(l,mesgflag)
|
||||
line_p l;
|
||||
bool mesgflag;
|
||||
static void use(line_p l, bool mesgflag)
|
||||
{
|
||||
/* Process a use. If the defined (register-) variable
|
||||
* is dead after 'l', then create a dead-message and put
|
||||
@ -447,11 +428,9 @@ STATIC use(l,mesgflag)
|
||||
|
||||
|
||||
|
||||
STATIC nothing() { } /* No action to be undertaken at level 0 of parser */
|
||||
static void nothing() { } /* No action to be undertaken at level 0 of parser */
|
||||
|
||||
STATIC rem_code(l1,l2,b)
|
||||
line_p l1,l2;
|
||||
bblock_p b;
|
||||
static void rem_code(line_p l1, line_p l2, bblock_p b)
|
||||
{
|
||||
line_p l,x,y,next;
|
||||
|
||||
@ -479,9 +458,7 @@ STATIC rem_code(l1,l2,b)
|
||||
|
||||
|
||||
|
||||
lv_mesg(p,mesgflag)
|
||||
proc_p p;
|
||||
bool mesgflag;
|
||||
void lv_mesg(proc_p p, bool mesgflag)
|
||||
{
|
||||
/* Create live/dead messages for every possible register
|
||||
* variable of p. A dead-message is put after a "use" of
|
||||
@ -508,8 +485,8 @@ lv_mesg(p,mesgflag)
|
||||
* On the fly, useless assignments are removed.
|
||||
*/
|
||||
|
||||
register bblock_p b;
|
||||
register line_p l;
|
||||
bblock_p b;
|
||||
line_p l;
|
||||
line_p lnp, prev;
|
||||
bblock_p prevb = (bblock_p) 0;
|
||||
short v;
|
||||
@ -551,12 +528,10 @@ OUTVERBOSE("useless assignment ,proc %d,local %d", curproc->p_id,
|
||||
}
|
||||
|
||||
|
||||
STATIC lv_extend(p)
|
||||
proc_p p;
|
||||
static void lv_extend(proc_p p)
|
||||
{
|
||||
/* Allocate extended data structures for Use Definition analysis */
|
||||
|
||||
register bblock_p b;
|
||||
bblock_p b;
|
||||
|
||||
for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) {
|
||||
b->b_extend = newlvbx();
|
||||
@ -564,12 +539,10 @@ STATIC lv_extend(p)
|
||||
}
|
||||
|
||||
|
||||
STATIC lv_cleanup(p)
|
||||
proc_p p;
|
||||
static void lv_cleanup(proc_p p)
|
||||
{
|
||||
/* Deallocate extended data structures for Use Definition analysis */
|
||||
|
||||
register bblock_p b;
|
||||
bblock_p b;
|
||||
|
||||
for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) {
|
||||
Cdeleteset(USE(b));
|
||||
@ -580,21 +553,22 @@ STATIC lv_cleanup(p)
|
||||
}
|
||||
}
|
||||
|
||||
lv_flags(p)
|
||||
char *p;
|
||||
int lv_flags(void *param)
|
||||
{
|
||||
char *p = (char *)param;
|
||||
switch(*p) {
|
||||
case 'N':
|
||||
mesgflag = TRUE;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
lv_optimize(p)
|
||||
proc_p p;
|
||||
int lv_optimize(void *param)
|
||||
{
|
||||
if (IS_ENTERED_WITH_GTO(p)) return;
|
||||
proc_p p = (proc_p)param;
|
||||
if (IS_ENTERED_WITH_GTO(p)) return 0;
|
||||
locals = (local_p *) 0;
|
||||
lv_extend(p);
|
||||
live_variables_analysis(p);
|
||||
@ -602,13 +576,10 @@ lv_optimize(p)
|
||||
/* generate live-dead messages for regvars */
|
||||
lv_cleanup(p);
|
||||
clean_up();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
go(argc,argv,init_globals,lv_optimize,no_action,lv_flags);
|
||||
report("useless assignments deleted",Slv);
|
||||
|
||||
@ -17,28 +17,25 @@
|
||||
#include "alloc.h"
|
||||
|
||||
|
||||
char * myalloc();
|
||||
//char * myalloc();
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
STATIC unsigned maxuse, curruse;
|
||||
|
||||
char *newcore(size)
|
||||
int size;
|
||||
char *newcore(int size)
|
||||
{
|
||||
if ((curruse += (unsigned) (size+2)) > maxuse) maxuse = curruse;
|
||||
return myalloc(size);
|
||||
}
|
||||
|
||||
oldcore(p,size)
|
||||
char *p;
|
||||
int size;
|
||||
void oldcore(char *p, int size)
|
||||
{
|
||||
curruse -= (size+2);
|
||||
free(p);
|
||||
}
|
||||
|
||||
coreusage()
|
||||
void coreusage()
|
||||
{
|
||||
fprintf(stderr,"Maximal core usage (excl. buffers):%u\n",maxuse);
|
||||
}
|
||||
@ -115,24 +112,27 @@ int asizetab[] = {
|
||||
* PART 1
|
||||
*/
|
||||
|
||||
line_p newline(optyp) int optyp; {
|
||||
register line_p lnp;
|
||||
register kind=optyp;
|
||||
line_p newline(int optyp)
|
||||
{
|
||||
line_p lnp;
|
||||
int kind = optyp;
|
||||
|
||||
lnp = (line_p) newcore(lsizetab[kind]);
|
||||
TYPE(lnp) = optyp;
|
||||
return(lnp);
|
||||
}
|
||||
|
||||
oldline(lnp) register line_p lnp; {
|
||||
register kind=TYPE(lnp)&BMASK;
|
||||
void oldline(line_p lnp)
|
||||
{
|
||||
int kind=TYPE(lnp)&BMASK;
|
||||
|
||||
if (kind == OPLIST)
|
||||
oldargs(ARG(lnp));
|
||||
oldcore((char *) lnp,lsizetab[kind]);
|
||||
}
|
||||
|
||||
arg_p newarg(kind) int kind; {
|
||||
arg_p newarg(int kind)
|
||||
{
|
||||
register arg_p ap;
|
||||
|
||||
ap = (arg_p) newcore(asizetab[kind]);
|
||||
@ -140,8 +140,9 @@ arg_p newarg(kind) int kind; {
|
||||
return(ap);
|
||||
}
|
||||
|
||||
oldargs(ap) register arg_p ap; {
|
||||
register arg_p next;
|
||||
void oldargs(arg_p ap)
|
||||
{
|
||||
arg_p next;
|
||||
|
||||
while (ap != (arg_p) 0) {
|
||||
next = ap->a_next;
|
||||
@ -160,8 +161,9 @@ oldargs(ap) register arg_p ap; {
|
||||
}
|
||||
}
|
||||
|
||||
oldargb(abp) register argb_p abp; {
|
||||
register argb_p next;
|
||||
void oldargb(argb_p abp)
|
||||
{
|
||||
argb_p next;
|
||||
|
||||
while (abp != (argb_p) 0) {
|
||||
next = abp->ab_next;
|
||||
@ -170,8 +172,9 @@ oldargb(abp) register argb_p abp; {
|
||||
}
|
||||
}
|
||||
|
||||
oldobjects(op) register obj_p op; {
|
||||
register obj_p next;
|
||||
void oldobjects(obj_p op)
|
||||
{
|
||||
obj_p next;
|
||||
|
||||
while (op != (obj_p) 0) {
|
||||
next = op->o_next;
|
||||
@ -180,24 +183,28 @@ oldobjects(op) register obj_p op; {
|
||||
}
|
||||
}
|
||||
|
||||
olddblock(dbl) dblock_p dbl; {
|
||||
void olddblock(dblock_p dbl)
|
||||
{
|
||||
oldobjects(dbl->d_objlist);
|
||||
oldargs(dbl->d_values);
|
||||
oldcore((char *) dbl, sizeof(struct dblock));
|
||||
}
|
||||
|
||||
|
||||
short **newmap(length) short length; {
|
||||
short **newmap(short length)
|
||||
{
|
||||
return((short **) newcore((length+1) * sizeof(short *)));
|
||||
}
|
||||
|
||||
/*ARGSUSED1*/
|
||||
oldmap(mp,length) short **mp, length; {
|
||||
void oldmap(short **mp, short length)
|
||||
{
|
||||
oldcore((char *) mp, (length+1) * sizeof(short *));
|
||||
}
|
||||
|
||||
|
||||
cset newbitvect(n) short n; {
|
||||
cset newbitvect(short n)
|
||||
{
|
||||
return((cset) newcore((n-1)*sizeof(int) + sizeof(struct bitvector)));
|
||||
/* sizeof(struct bitvector) equals to the size of a struct with
|
||||
* one short, followed by one ALLIGNED int. So the above statement
|
||||
@ -206,26 +213,29 @@ cset newbitvect(n) short n; {
|
||||
}
|
||||
|
||||
/*ARGSUSED1*/
|
||||
oldbitvect(s,n) cset s; short n; {
|
||||
void oldbitvect(cset s, short n)
|
||||
{
|
||||
oldcore((char *) s, (n-1)*sizeof(int) + sizeof(struct bitvector));
|
||||
}
|
||||
|
||||
|
||||
short *newtable(length) short length; {
|
||||
short *newtable(short length)
|
||||
{
|
||||
return((short *) newcore((length+1) * sizeof(short)));
|
||||
}
|
||||
|
||||
/*ARGSUSED1*/
|
||||
oldtable(mp,length) short **mp, length; {
|
||||
void oldtable(short **mp, short length)
|
||||
{
|
||||
oldcore((char *) mp, (length+1) * sizeof(short));
|
||||
}
|
||||
|
||||
cond_p newcondtab(l) int l;
|
||||
cond_p newcondtab(int l)
|
||||
{
|
||||
return (cond_p) newcore(l * (sizeof (struct cond_tab)));
|
||||
}
|
||||
|
||||
oldcondtab(tab) cond_p tab;
|
||||
void oldcondtab(cond_p tab)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; tab[i].mc_cond != DEFAULT; i++);
|
||||
@ -233,8 +243,9 @@ oldcondtab(tab) cond_p tab;
|
||||
}
|
||||
|
||||
|
||||
char *myalloc(size) register size; {
|
||||
register char *p;
|
||||
char *myalloc(int size)
|
||||
{
|
||||
char *p;
|
||||
|
||||
p = calloc((unsigned) size, 1);
|
||||
if (p == 0)
|
||||
|
||||
@ -9,10 +9,11 @@
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
extern char *newcore();
|
||||
extern oldcore();
|
||||
char *newcore(int size);
|
||||
void oldcore(char *p, int size);
|
||||
void coreusage()
|
||||
#else
|
||||
extern char *myalloc();
|
||||
char *myalloc(int size);
|
||||
#define newcore(size) myalloc(size)
|
||||
#define oldcore(p,size) free((char *)p)
|
||||
#endif
|
||||
@ -20,24 +21,23 @@ extern char *myalloc();
|
||||
#define newstruct(t) ((struct t *) newcore (sizeof (struct t)))
|
||||
#define oldstruct(t,p) oldcore((char *) p,sizeof (struct t))
|
||||
|
||||
extern line_p newline(); /* (byte optype) */
|
||||
extern arg_p newarg(); /* (byte argtype) */
|
||||
extern short **newmap(); /* (short length) */
|
||||
extern cset newbitvect(); /* (short nrbytes) */
|
||||
extern cond_p newcondtab();
|
||||
line_p newline(int optyp);
|
||||
arg_p newarg(int kind);
|
||||
short **newmap(short length);
|
||||
cset newbitvect(short n);
|
||||
cond_p newcondtab(int l);
|
||||
|
||||
void oldline(line_p lnp);
|
||||
void oldargs(arg_p ap);
|
||||
void oldargb(argb_p abp);
|
||||
void oldobjects(obj_p op);
|
||||
void olddblock(dblock_p dbl);
|
||||
void oldmap(short **mp, short length);
|
||||
void oldbitvect(cset s, short n);
|
||||
void oldcondtab(cond_p tab);
|
||||
short *newtable(short length);
|
||||
void oldtable(short **mp, short length);
|
||||
|
||||
extern oldline() ;
|
||||
extern oldargs() ;
|
||||
extern oldargb() ;
|
||||
extern oldobjects() ;
|
||||
extern olddblock() ;
|
||||
extern oldmap();
|
||||
extern oldbitvect(); /* (cset s, short nrbytes) */
|
||||
extern oldcondtab();
|
||||
|
||||
extern short *newtable();
|
||||
extern oldtable();
|
||||
|
||||
#define newdblock() (dblock_p) newstruct(dblock)
|
||||
#define newobject() (obj_p) newstruct(obj)
|
||||
|
||||
@ -19,8 +19,7 @@
|
||||
#include "map.h"
|
||||
#include "lset.h"
|
||||
|
||||
offset off_set(lnp)
|
||||
line_p lnp;
|
||||
offset off_set(line_p lnp)
|
||||
{
|
||||
switch(lnp->l_optype) {
|
||||
case OPSHORT:
|
||||
@ -31,13 +30,10 @@ offset off_set(lnp)
|
||||
assert(FALSE);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
offset aoff(ap,n)
|
||||
register arg_p ap;
|
||||
offset aoff(arg_p ap, int n)
|
||||
{
|
||||
while (n>0) {
|
||||
if (ap != (arg_p) 0)
|
||||
@ -52,9 +48,7 @@ offset aoff(ap,n)
|
||||
}
|
||||
|
||||
|
||||
offset tmplocal(p,size)
|
||||
proc_p p;
|
||||
offset size;
|
||||
offset tmplocal(proc_p p, offset size)
|
||||
{
|
||||
/* Allocate a new local variable in the stack frame of p */
|
||||
|
||||
@ -65,8 +59,7 @@ offset tmplocal(p,size)
|
||||
|
||||
|
||||
|
||||
line_p int_line(off)
|
||||
offset off;
|
||||
line_p int_line(offset off)
|
||||
{
|
||||
/* Allocate a line struct of type OPSHORT or OPOFFSET,
|
||||
* whichever one fits best.
|
||||
@ -87,13 +80,9 @@ line_p int_line(off)
|
||||
|
||||
|
||||
|
||||
line_p reg_mes(tmp,size,typ,score)
|
||||
offset tmp;
|
||||
short size;
|
||||
int typ,score;
|
||||
line_p reg_mes(offset tmp, short size, int typ, int score)
|
||||
{
|
||||
/* Generate a register message */
|
||||
|
||||
line_p l;
|
||||
arg_p a;
|
||||
|
||||
@ -111,8 +100,7 @@ line_p reg_mes(tmp,size,typ,score)
|
||||
}
|
||||
|
||||
|
||||
bool dom(b1,b2)
|
||||
bblock_p b1,b2;
|
||||
bool dom(bblock_p b1, bblock_p b2)
|
||||
{
|
||||
/* See if b1 dominates b2. Note that a block always
|
||||
* dominates itself.
|
||||
@ -130,8 +118,7 @@ bool dom(b1,b2)
|
||||
}
|
||||
|
||||
|
||||
bblock_p common_dom(a,b)
|
||||
bblock_p a,b;
|
||||
bblock_p common_dom(bblock_p a, bblock_p b)
|
||||
{
|
||||
/* find a basic block that dominates a as well as b;
|
||||
* note that a basic block also dominates itself.
|
||||
@ -152,8 +139,7 @@ bblock_p common_dom(a,b)
|
||||
|
||||
#define R time_space_ratio
|
||||
|
||||
short add_timespace(time,space)
|
||||
short time,space;
|
||||
short add_timespace(short time, short space)
|
||||
{
|
||||
/* Add together a time and space, using the time_space_ratio
|
||||
* parameter that may be set by the user, indicating the need
|
||||
@ -165,9 +151,7 @@ short add_timespace(time,space)
|
||||
|
||||
|
||||
|
||||
rm_line(l,b)
|
||||
line_p l;
|
||||
bblock_p b;
|
||||
void rm_line(line_p l, bblock_p b)
|
||||
{
|
||||
if (b->b_start == l) {
|
||||
b->b_start = l->l_next;
|
||||
@ -183,8 +167,7 @@ rm_line(l,b)
|
||||
|
||||
|
||||
|
||||
appnd_line(l1,l2)
|
||||
line_p l1,l2;
|
||||
void appnd_line(line_p l1, line_p l2)
|
||||
{
|
||||
/* Put l1 after l2 */
|
||||
|
||||
@ -198,8 +181,7 @@ appnd_line(l1,l2)
|
||||
|
||||
|
||||
|
||||
line_p last_instr(b)
|
||||
bblock_p b;
|
||||
line_p last_instr(bblock_p b)
|
||||
{
|
||||
/* Determine the last line of a list */
|
||||
|
||||
@ -213,8 +195,7 @@ line_p last_instr(b)
|
||||
|
||||
|
||||
|
||||
line_p find_mesreg(off)
|
||||
offset off;
|
||||
line_p find_mesreg(offset off)
|
||||
{
|
||||
/* Find the register message for the local with the given offset */
|
||||
|
||||
@ -229,17 +210,14 @@ line_p find_mesreg(off)
|
||||
}
|
||||
|
||||
|
||||
bool is_regvar(off)
|
||||
offset off;
|
||||
bool is_regvar(offset off)
|
||||
{
|
||||
return find_mesreg(off) != (line_p) 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
offset regv_arg(off,n)
|
||||
offset off;
|
||||
int n;
|
||||
offset regv_arg(offset off, int n)
|
||||
{
|
||||
/* fetch the n'th argument of the register message of the
|
||||
* local variable at offset off;
|
||||
|
||||
@ -10,62 +10,62 @@
|
||||
*/
|
||||
|
||||
|
||||
extern offset off_set(); /* (line_p lnp)
|
||||
* lnp has a SHORT or OFFSET operand. Return
|
||||
offset off_set(line_p lnp);
|
||||
/* lnp has a SHORT or OFFSET operand. Return
|
||||
* the value of this operand as an offset.
|
||||
*/
|
||||
extern offset aoff(); /* (arg_p list; int n)
|
||||
* Determine the offset field of the
|
||||
extern offset aoff(arg_p list, int n);
|
||||
/* Determine the offset field of the
|
||||
* n'th argument in the list (this argument
|
||||
* must have type ARGOFF). Start counting at 0.
|
||||
*/
|
||||
extern offset tmplocal(); /* (proc_p p, offset size)
|
||||
* Allocate a new local variable in the
|
||||
extern offset tmplocal(proc_p p, offset size);
|
||||
/* Allocate a new local variable in the
|
||||
* stack frame of p.
|
||||
*/
|
||||
line_p int_line(); /* (offset off)
|
||||
* Allocate a line struct of type OPSHORT
|
||||
line_p int_line(offset off);
|
||||
/* Allocate a line struct of type OPSHORT
|
||||
* or OPOFFSET, whichever one fits best.
|
||||
*/
|
||||
extern line_p reg_mes(); /* (offset tmp; short size; int typ,score)
|
||||
* Generate a register message with the
|
||||
line_p reg_mes(offset tmp, short size, int typ, int score);
|
||||
/* Generate a register message with the
|
||||
* given arguments.
|
||||
*/
|
||||
extern bool dom(); /* (bblock_p b1,b2)
|
||||
* See if b1 dominates b2. Note that a
|
||||
bool dom(bblock_p b1, bblock_p b2);
|
||||
/* See if b1 dominates b2. Note that a
|
||||
* block always * dominates itself.
|
||||
*/
|
||||
extern bblock_p common_dom(); /* (bblock_p a,b)
|
||||
* find a basic block that dominates a as
|
||||
bblock_p common_dom(bblock_p a, bblock_p b);
|
||||
/* find a basic block that dominates a as
|
||||
* well as b; note that a basic block also
|
||||
* dominates itself.
|
||||
*/
|
||||
extern short add_timespace(); /* (short time,space)
|
||||
* Add together a time and space, using
|
||||
short add_timespace(short time, short space);
|
||||
/* Add together a time and space, using
|
||||
* the time_space_ratio parameter that
|
||||
* may be set by the user.
|
||||
*/
|
||||
extern rm_line(); /* ( line_p l; bblock_p b)
|
||||
* Remove line l from b basic block b.
|
||||
void rm_line(line_p l, bblock_p b);
|
||||
/* Remove line l from b basic block b.
|
||||
*/
|
||||
|
||||
extern appnd_line(); /* ( line_p l1,l2)
|
||||
* Put line l1 after l2.
|
||||
void appnd_line(line_p l1, line_p l2);
|
||||
/* Put line l1 after l2.
|
||||
*/
|
||||
extern line_p last_instr(); /* ( bblock_p b)
|
||||
* Determine the last line of a basic block.
|
||||
line_p last_instr(bblock_p b);
|
||||
/* Determine the last line of a basic block.
|
||||
*/
|
||||
extern line_p find_mesreg(); /* (offset off)
|
||||
* Find the register message for the local
|
||||
line_p find_mesreg(offset off);
|
||||
/* Find the register message for the local
|
||||
* with the given offset.
|
||||
*/
|
||||
extern bool is_regvar(); /* (offset off)
|
||||
* See if there is a 'register message'
|
||||
bool is_regvar(offset off);
|
||||
/* See if there is a 'register message'
|
||||
* for the local variable with the
|
||||
* given offset.
|
||||
*/
|
||||
extern offset regv_arg(); /* (offset off; int n)
|
||||
* Fetch the n'th argument of the
|
||||
offset regv_arg(offset off, int n);
|
||||
/* Fetch the n'th argument of the
|
||||
* register message of the local with
|
||||
* the given offset.
|
||||
*/
|
||||
|
||||
@ -34,11 +34,7 @@
|
||||
* if the word length (of the source machine) is 16.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
cset Cempty_set(n)
|
||||
short n;
|
||||
cset Cempty_set(short n)
|
||||
{
|
||||
cset s;
|
||||
|
||||
@ -48,9 +44,7 @@ cset Cempty_set(n)
|
||||
}
|
||||
|
||||
|
||||
bool Cis_elem(x,s)
|
||||
Celem_t x;
|
||||
cset s;
|
||||
bool Cis_elem(Celem_t x, cset s)
|
||||
{
|
||||
short n;
|
||||
int mask;
|
||||
@ -67,9 +61,7 @@ bool Cis_elem(x,s)
|
||||
|
||||
|
||||
|
||||
Cadd(x,s_p)
|
||||
Celem_t x;
|
||||
cset *s_p;
|
||||
void Cadd(Celem_t x, cset *s_p)
|
||||
{
|
||||
cset s;
|
||||
short n;
|
||||
@ -83,9 +75,7 @@ Cadd(x,s_p)
|
||||
}
|
||||
|
||||
|
||||
Cremove(x,s_p)
|
||||
Celem_t x;
|
||||
cset *s_p;
|
||||
void Cremove(Celem_t x, cset *s_p)
|
||||
{
|
||||
cset s;
|
||||
short n;
|
||||
@ -117,18 +107,15 @@ Cremove(x,s_p)
|
||||
* be used very often.
|
||||
*/
|
||||
|
||||
Cindex Cfirst(s)
|
||||
cset s;
|
||||
Cindex Cfirst(cset s)
|
||||
{
|
||||
return Cnext((Cindex) 0,s);
|
||||
}
|
||||
|
||||
|
||||
Cindex Cnext(i,s)
|
||||
Cindex i;
|
||||
cset s;
|
||||
Cindex Cnext(Cindex i, cset s)
|
||||
{
|
||||
register short n;
|
||||
short n;
|
||||
|
||||
for (n = i+1; n <= s->v_size; n++) {
|
||||
if (Cis_elem(n,s)) {
|
||||
@ -139,16 +126,14 @@ Cindex Cnext(i,s)
|
||||
}
|
||||
|
||||
|
||||
Celem_t Celem(i)
|
||||
Cindex i;
|
||||
Celem_t Celem(Cindex i)
|
||||
{
|
||||
return (Celem_t) i;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Cjoin(s1,s2_p)
|
||||
cset s1, *s2_p;
|
||||
void Cjoin(cset s1, cset *s2_p)
|
||||
{
|
||||
/* Two sets are joined by or-ing their bitvectors,
|
||||
* word by word.
|
||||
@ -156,7 +141,7 @@ Cjoin(s1,s2_p)
|
||||
|
||||
cset s2;
|
||||
short n;
|
||||
register short i;
|
||||
short i;
|
||||
|
||||
s2 = *s2_p;
|
||||
assert(s1->v_size == s2->v_size);
|
||||
@ -166,10 +151,7 @@ Cjoin(s1,s2_p)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Cintersect(s1,s2_p)
|
||||
cset s1, *s2_p;
|
||||
void Cintersect(cset s1, cset *s2_p)
|
||||
{
|
||||
/* Two sets are intersected by and-ing their bitvectors,
|
||||
* word by word.
|
||||
@ -188,15 +170,13 @@ Cintersect(s1,s2_p)
|
||||
}
|
||||
|
||||
|
||||
Cdeleteset(s)
|
||||
cset s;
|
||||
void Cdeleteset(cset s)
|
||||
{
|
||||
oldbitvect(s,DIVWL(s->v_size - 1) + 1);
|
||||
}
|
||||
|
||||
|
||||
bool Cis_subset(s1,s2)
|
||||
cset s1,s2;
|
||||
bool Cis_subset(cset s1, cset s2)
|
||||
{
|
||||
/* See if s1 is a subset of s2 */
|
||||
|
||||
@ -213,8 +193,7 @@ bool Cis_subset(s1,s2)
|
||||
}
|
||||
|
||||
|
||||
Cclear_set(s_p)
|
||||
cset *s_p;
|
||||
void Cclear_set(cset *s_p)
|
||||
{
|
||||
cset s;
|
||||
register short i;
|
||||
@ -227,8 +206,7 @@ Cclear_set(s_p)
|
||||
}
|
||||
|
||||
|
||||
Ccopy_set(s1,s2_p)
|
||||
cset s1, *s2_p;
|
||||
void Ccopy_set(cset s1, cset *s2_p)
|
||||
{
|
||||
cset s2;
|
||||
register short i;
|
||||
@ -241,8 +219,7 @@ Ccopy_set(s1,s2_p)
|
||||
}
|
||||
|
||||
|
||||
Csubtract(s1,s2_p)
|
||||
cset s1, *s2_p;
|
||||
void Csubtract(cset s1, cset *s2_p)
|
||||
{
|
||||
cset s2;
|
||||
register short i;
|
||||
@ -255,8 +232,7 @@ Csubtract(s1,s2_p)
|
||||
}
|
||||
|
||||
|
||||
bool Cequal(s1,s2)
|
||||
cset s1, s2;
|
||||
bool Cequal(cset s1, cset s2)
|
||||
{
|
||||
register short i;
|
||||
|
||||
@ -267,8 +243,7 @@ bool Cequal(s1,s2)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
short Cnrelems(s)
|
||||
cset s;
|
||||
short Cnrelems(cset s)
|
||||
{
|
||||
register short n, cnt;
|
||||
|
||||
|
||||
@ -7,20 +7,18 @@
|
||||
* C O M P A C T S E T S
|
||||
*/
|
||||
|
||||
|
||||
extern cset Cempty_set(); /* (short) */
|
||||
extern bool Cis_elem(); /* (Celem, cset) */
|
||||
extern Cadd(); /* (Celem, *cset) */
|
||||
extern Cremove(); /* (Celem, *cset) */
|
||||
extern Cindex Cfirst(); /* (cset) */
|
||||
extern Cindex Cnext(); /* (Cindex, cset) */
|
||||
extern Celem_t Celem(); /* (Cindex) */
|
||||
extern Cjoin(); /* (cset, *cset) */
|
||||
extern Cintersect(); /* (cset, *cset) */
|
||||
extern Cdeleteset(); /* (cset) */
|
||||
extern bool Cis_subset(); /* (cset, cset) */
|
||||
extern Cclearset(); /* (cset, *cset) */
|
||||
extern Ccopy_set(); /* (cset, *cset) */
|
||||
extern Csubtract(); /* (cset, *cset) */
|
||||
extern bool Cequal(); /* (cset, cset) */
|
||||
extern short Cnrelems(); /* (cset) */
|
||||
cset Cempty_set(short n);
|
||||
bool Cis_elem(Celem_t x, cset s);
|
||||
void Cadd(Celem_t x, cset *s_p);
|
||||
void Cremove(Celem_t x, cset *s_p);
|
||||
Cindex Cfirst(cset s);
|
||||
Cindex Cnext(Cindex i, cset s);
|
||||
Celem_t Celem(Cindex i);
|
||||
void Cjoin(cset s1, cset *s2_p);
|
||||
void Cintersect(cset s1, cset *s2_p);
|
||||
void Cdeleteset(cset s);
|
||||
bool Cis_subset(cset s1, cset s2);void Cclear_set(cset *s_p);
|
||||
void Ccopy_set(cset s1, cset *s2_p);
|
||||
void Csubtract(cset s1, cset *s2_p);
|
||||
bool Cequal(cset s1, cset s2);
|
||||
short Cnrelems(cset s);
|
||||
@ -31,8 +31,8 @@
|
||||
|
||||
#define ARGSTART 9
|
||||
|
||||
extern FILE *openfile(); /* (char *name, *mode)
|
||||
* Open a file with the given name
|
||||
FILE *openfile(char *name, char *mode);
|
||||
/* Open a file with the given name
|
||||
* and mode; aborts if the file
|
||||
* cannot be opened.
|
||||
*/
|
||||
|
||||
@ -73,7 +73,7 @@ offset getoff() {
|
||||
return l | (h_byte*256L*256*256L) ;
|
||||
}
|
||||
|
||||
STATIC int getint()
|
||||
static int getint()
|
||||
{
|
||||
/* Read an integer from the input file. This routine is
|
||||
* only used when reading a bitvector-set. We expect an
|
||||
@ -90,15 +90,15 @@ STATIC int getint()
|
||||
|
||||
/* getptable */
|
||||
|
||||
loop_p getloop(id)
|
||||
loop_id id;
|
||||
/* loop_p getloop(loop_id id) */
|
||||
void *getloop(short lid)
|
||||
{
|
||||
loop_id id = lid;
|
||||
/* Map a loop identifier onto a loop struct.
|
||||
* If no struct was alocated yet for this identifier then
|
||||
* allocate one now and update the loop-map table.
|
||||
*/
|
||||
|
||||
|
||||
assert (id > 0 && id <=lplength);
|
||||
if (lpmap[id] == (loop_p) 0) {
|
||||
lpmap[id] = newloop();
|
||||
@ -107,15 +107,15 @@ loop_p getloop(id)
|
||||
return (lpmap[id]);
|
||||
}
|
||||
|
||||
bblock_p getblock(id)
|
||||
block_id id;
|
||||
/* bblock_p getblock(block_id id) */
|
||||
void *getblock(short bid)
|
||||
{
|
||||
block_id id = bid;
|
||||
/* Map a basic block identifier onto a block struct
|
||||
* If no struct was alocated yet for this identifier then
|
||||
* allocate one now and update the block-map table.
|
||||
*/
|
||||
|
||||
|
||||
assert (id >= 0 && id <=blength);
|
||||
if (id == 0) return (bblock_p) 0;
|
||||
if (bmap[id] == (bblock_p) 0) {
|
||||
@ -126,8 +126,7 @@ bblock_p getblock(id)
|
||||
}
|
||||
|
||||
|
||||
lset getlset(p)
|
||||
char *((*p) ());
|
||||
lset getlset(void *(*p)(short))
|
||||
{
|
||||
/* Read a 'long' set. Such a set is represented externally
|
||||
* as a sequence of identifying numbers terminated by a 0.
|
||||
@ -139,7 +138,7 @@ lset getlset(p)
|
||||
int id;
|
||||
|
||||
s = Lempty_set();
|
||||
while (id = getshort()) {
|
||||
while ((id = getshort())) {
|
||||
Ladd( (*p) (id), &s);
|
||||
}
|
||||
return s;
|
||||
@ -163,8 +162,7 @@ cset getcset()
|
||||
}
|
||||
|
||||
|
||||
proc_p getptable(pname)
|
||||
char *pname;
|
||||
proc_p getptable(char *pname)
|
||||
{
|
||||
short i;
|
||||
proc_p head, p, *pp;
|
||||
@ -216,8 +214,7 @@ proc_p getptable(pname)
|
||||
|
||||
/* getdtable */
|
||||
|
||||
dblock_p getdtable(dname)
|
||||
char *dname;
|
||||
dblock_p getdtable(char *dname)
|
||||
{
|
||||
/* Read the data block table. Every data block may
|
||||
* have a list of objects and a list of values (arguments),
|
||||
@ -290,9 +287,7 @@ dblock_p getdtable(dname)
|
||||
|
||||
/* getbblocks */
|
||||
|
||||
STATIC argstring(length,abp)
|
||||
short length;
|
||||
register argb_p abp;
|
||||
static void argstring(short length, argb_p abp)
|
||||
{
|
||||
|
||||
while (length--) {
|
||||
@ -304,7 +299,7 @@ STATIC argstring(length,abp)
|
||||
|
||||
|
||||
|
||||
STATIC arg_p readargs()
|
||||
static arg_p readargs()
|
||||
{
|
||||
/* Read a list of arguments and allocate structures
|
||||
* for them. Return a pointer to the head of the list.
|
||||
@ -363,8 +358,7 @@ STATIC arg_p readargs()
|
||||
}
|
||||
|
||||
|
||||
line_p read_line(p_out)
|
||||
proc_p *p_out;
|
||||
line_p read_line(proc_p *p_out)
|
||||
{
|
||||
/* Read a line of EM code (i.e. one instruction)
|
||||
* and its arguments (if any).
|
||||
@ -426,8 +420,7 @@ line_p read_line(p_out)
|
||||
}
|
||||
|
||||
|
||||
message(lnp)
|
||||
line_p lnp;
|
||||
void message(line_p lnp)
|
||||
{
|
||||
/* See if lnp is some useful message.
|
||||
* (e.g. a message telling that a certain local variable
|
||||
@ -456,11 +449,7 @@ message(lnp)
|
||||
|
||||
|
||||
|
||||
line_p getlines(lf,n,p_out,collect_mes)
|
||||
FILE *lf;
|
||||
int n;
|
||||
proc_p *p_out;
|
||||
bool collect_mes;
|
||||
line_p getlines(FILE *lf, int n, proc_p *p_out, bool collect_mes)
|
||||
{
|
||||
/* Read n lines of EM text and doubly link them.
|
||||
* Also process messages.
|
||||
@ -486,13 +475,7 @@ line_p getlines(lf,n,p_out,collect_mes)
|
||||
|
||||
|
||||
|
||||
bool getunit(gf,lf,kind_out,g_out,l_out,p_out,collect_mes)
|
||||
FILE *gf,*lf;
|
||||
short *kind_out;
|
||||
bblock_p *g_out;
|
||||
line_p *l_out;
|
||||
proc_p *p_out;
|
||||
bool collect_mes;
|
||||
bool getunit(FILE *gf, FILE *lf, short *kind_out, bblock_p *g_out, line_p *l_out, proc_p *p_out, bool collect_mes)
|
||||
{
|
||||
/* Read control flow graph (gf) and EM text (lf) of the next procedure.
|
||||
* A pointer to the proctable entry of the read procedure is
|
||||
|
||||
@ -6,49 +6,47 @@
|
||||
/* I N P U T R O U T I N E S */
|
||||
|
||||
extern FILE *curinp; /* current input file */
|
||||
extern block_id lastbid; /* block identifying number */
|
||||
extern lab_id lastlabid; /* last label identifier */
|
||||
block_id lastbid; /* block identifying number */
|
||||
lab_id lastlabid; /* last label identifier */
|
||||
|
||||
#define getbyte() getc(curinp)
|
||||
extern short getshort(); /* ()
|
||||
short getshort(); /*
|
||||
* Read a short from curinp
|
||||
*/
|
||||
extern offset getoff(); /* ()
|
||||
offset getoff(); /*
|
||||
* Read an offset from curinp
|
||||
*/
|
||||
extern line_p read_line(); /* ( proc_p *p_out)
|
||||
* Read a line of EM code (i.e. one
|
||||
line_p read_line(proc_p *p_out);
|
||||
/* Read a line of EM code (i.e. one
|
||||
* instruction) and its arguments
|
||||
* (if any). If the instruction is a
|
||||
* 'pro' pseudo, set p_out.
|
||||
*/
|
||||
|
||||
extern line_p getlines(); /* ( FILE *lf; int n; proc_p *p_out;
|
||||
* bool collect_mes)
|
||||
line_p getlines(FILE *lf, int n, proc_p *p_out, bool collect_mes);
|
||||
/* bool collect_mes)
|
||||
* Read n lines of EM text and doubly
|
||||
* link them. Also process messages
|
||||
* if required.
|
||||
*/
|
||||
|
||||
extern bblock_p freshblock(); /* ()
|
||||
* Allocate a bblock struct and assign
|
||||
bblock_p freshblock();
|
||||
/* Allocate a bblock struct and assign
|
||||
* it a brand new block_id.
|
||||
*/
|
||||
extern lab_id freshlabel(); /* ()
|
||||
* Get a brand new lab_id.
|
||||
lab_id freshlabel();
|
||||
/* Get a brand new lab_id.
|
||||
*/
|
||||
extern dblock_p getdtable(); /* (char *dname)
|
||||
* Read the data block table from
|
||||
dblock_p getdtable(char *dname);
|
||||
/* Read the data block table from
|
||||
* the file with the given name.
|
||||
*/
|
||||
extern proc_p getptable(); /* (char *pname)
|
||||
* Read the proc table from
|
||||
proc_p getptable(char *pname);
|
||||
/* Read the proc table from
|
||||
* the file with the given name.
|
||||
*/
|
||||
extern bool getunit(); /* (FILE *gf,*lf; short kind_out;
|
||||
* bblock_p g_out; line_p l_out;
|
||||
* proc_p *p_out; bool collect_mes)
|
||||
* Read the control flow graph
|
||||
bool getunit(FILE *gf, FILE *lf, short *kind_out, bblock_p *g_out, line_p *l_out, proc_p *p_out, bool collect_mes);
|
||||
/* Read the control flow graph
|
||||
* (from file gf) and the EM text
|
||||
* (from lf). If collect_mes is TRUE,
|
||||
* all register messages will be
|
||||
@ -56,8 +54,8 @@ extern bool getunit(); /* (FILE *gf,*lf; short kind_out;
|
||||
* variable 'mesregs'. The proc read
|
||||
* is returned in p_out.
|
||||
*/
|
||||
extern message(); /* (line_p lnp)
|
||||
* See if lnp is some useful message.
|
||||
void message(line_p lnp);
|
||||
/* See if lnp is some useful message.
|
||||
* (e.g. a message telling that a
|
||||
* certain local variable will never be
|
||||
* referenced indirectly, so it may be
|
||||
|
||||
@ -23,13 +23,13 @@
|
||||
#include "go.h"
|
||||
|
||||
|
||||
STATIC bool report_flag = FALSE; /* report #optimizations found? */
|
||||
static bool report_flag = FALSE; /* report #optimizations found? */
|
||||
#ifdef DEBUG
|
||||
STATIC bool core_flag = FALSE; /* report core usage? */
|
||||
static bool core_flag = FALSE; /* report core usage? */
|
||||
#endif
|
||||
|
||||
|
||||
STATIC void mach_init(char *machfile, int (*phase_machinit)(FILE *))
|
||||
static void mach_init(char *machfile, int (*phase_machinit)(void *))
|
||||
{
|
||||
/* Read target machine dependent information */
|
||||
|
||||
@ -45,9 +45,9 @@ STATIC void mach_init(char *machfile, int (*phase_machinit)(FILE *))
|
||||
|
||||
|
||||
|
||||
void go(int argc, char *argv[], int (*initialize)(void),
|
||||
int (*optimize)(proc_p), int (*phase_machinit)(FILE *),
|
||||
int (*proc_flag)(char *))
|
||||
void go(int argc, char *argv[], int (*initialize)(void *),
|
||||
int (*optimize)(void *), int (*phase_machinit)(void *),
|
||||
int (*proc_flag)(void *))
|
||||
{
|
||||
FILE *f, *gf, *f2, *gf2; /* The EM input and output and
|
||||
* the basic block graphs input and output
|
||||
@ -91,9 +91,9 @@ void go(int argc, char *argv[], int (*initialize)(void),
|
||||
}
|
||||
}
|
||||
time_space_ratio = (time_opt ? 100 : 0);
|
||||
fproc = getptable(pname); /* proc table */
|
||||
fdblock = getdtable(dname); /* data block table */
|
||||
(*initialize)();
|
||||
fproc = getptable(&pname); /* proc table */
|
||||
fdblock = getdtable(&dname); /* data block table */
|
||||
(*initialize)(NULL);
|
||||
if (optimize == no_action) return;
|
||||
f = openfile(lname,"r");
|
||||
gf = openfile(bname,"r");
|
||||
@ -134,9 +134,9 @@ void go(int argc, char *argv[], int (*initialize)(void),
|
||||
}
|
||||
|
||||
|
||||
int no_action(proc_p dummy)
|
||||
int no_action(void *dummy)
|
||||
{
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void core_usage()
|
||||
|
||||
@ -11,11 +11,11 @@
|
||||
|
||||
#ifdef __STDC__
|
||||
|
||||
void go(int argc, char *argv[], int (*initialize)(void),
|
||||
int (*optimize)(proc_p), int (*phase_machinit)(FILE *),
|
||||
int (*proc_flag)(char *));
|
||||
|
||||
int no_action(proc_p dummy);
|
||||
void go(int argc, char *argv[], int (*initialize)(void *),
|
||||
int (*optimize)(void *), int (*phase_machinit)(void *),
|
||||
int (*proc_flag)(void *));
|
||||
|
||||
int no_action(void *dummy);
|
||||
|
||||
void core_usage();
|
||||
void report(char *s, int n);
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
|
||||
extern short nrglobals;
|
||||
|
||||
init_globals()
|
||||
int init_globals(void *dummy)
|
||||
{
|
||||
/* Assign a 'global variable number (o_globnr) to
|
||||
* every global variable for which we want to
|
||||
@ -59,4 +59,5 @@ init_globals()
|
||||
}
|
||||
}
|
||||
nrglobals = nr -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
extern init_globals(); /* Assign a 'global variable number (o_globnr)
|
||||
int init_globals(void *dummy);
|
||||
/* Assign a 'global variable number (o_globnr)
|
||||
* to every global variable.
|
||||
*/
|
||||
|
||||
@ -28,12 +28,7 @@ short nrglobals;
|
||||
short nrlocals;
|
||||
local_p *locals; /* dynamic array */
|
||||
|
||||
STATIC localvar(off,size,locs,reg,score)
|
||||
offset off;
|
||||
short size;
|
||||
local_p *locs;
|
||||
bool reg;
|
||||
offset score;
|
||||
static void localvar(offset off, short size, local_p *locs, bool reg, offset score)
|
||||
{
|
||||
/* process a reference to a local variable.
|
||||
* A local is characterized by a (offset,size) pair.
|
||||
@ -71,12 +66,9 @@ STATIC localvar(off,size,locs,reg,score)
|
||||
|
||||
|
||||
|
||||
STATIC check_message(l,locs)
|
||||
line_p l;
|
||||
local_p *locs;
|
||||
static void check_message(line_p l, local_p *locs)
|
||||
{
|
||||
/* See if l is a register message */
|
||||
|
||||
arg_p arg;
|
||||
|
||||
arg = ARG(l);
|
||||
@ -89,9 +81,7 @@ STATIC check_message(l,locs)
|
||||
|
||||
|
||||
|
||||
STATIC check_local_use(l,locs)
|
||||
line_p l;
|
||||
local_p *locs;
|
||||
static void check_local_use(line_p l, local_p *locs)
|
||||
{
|
||||
short sz;
|
||||
|
||||
@ -125,8 +115,7 @@ STATIC check_local_use(l,locs)
|
||||
}
|
||||
|
||||
|
||||
make_localtab(p)
|
||||
proc_p p;
|
||||
void make_localtab(proc_p p)
|
||||
{
|
||||
/* Make a table of local variables.
|
||||
* This table is used to associate a
|
||||
@ -140,8 +129,8 @@ make_localtab(p)
|
||||
local_p locallist = (local_p) 0;
|
||||
short cnt = 0;
|
||||
offset x, ill_zone = 0;
|
||||
register bblock_p b;
|
||||
register line_p l;
|
||||
bblock_p b;
|
||||
line_p l;
|
||||
|
||||
/* first make a list of all locals used */
|
||||
for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) {
|
||||
@ -185,15 +174,11 @@ make_localtab(p)
|
||||
|
||||
|
||||
|
||||
find_local(off,nr_out,found_out)
|
||||
offset off;
|
||||
short *nr_out;
|
||||
bool *found_out;
|
||||
void find_local(offset off, short *nr_out, bool *found_out)
|
||||
{
|
||||
/* Try to find the local variable at the given
|
||||
* offset. Return its local-number.
|
||||
*/
|
||||
|
||||
short v;
|
||||
|
||||
for (v = 1; v <= nrlocals; v++) {
|
||||
@ -207,13 +192,7 @@ find_local(off,nr_out,found_out)
|
||||
*found_out = FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
var_nr(l,nr_out,found_out)
|
||||
line_p l;
|
||||
short *nr_out;
|
||||
bool *found_out;
|
||||
void var_nr(line_p l, short *nr_out, bool *found_out)
|
||||
{
|
||||
/* Determine the number of the variable referenced
|
||||
* by EM instruction l.
|
||||
|
||||
@ -11,18 +11,18 @@
|
||||
extern local_p *locals; /* table of locals, index is local-number */
|
||||
extern short nrlocals; /* number of locals for which we keep ud-info */
|
||||
|
||||
extern make_localtab(); /* (proc_p p)
|
||||
* Analyse the text of procedure p to determine
|
||||
void make_localtab(proc_p p);
|
||||
/* Analyse the text of procedure p to determine
|
||||
* which local variable p has. Make a table of
|
||||
* these variables ('locals') and count them
|
||||
* ('nrlocals'). Also collect register messages.
|
||||
*/
|
||||
extern var_nr(); /* (line_p l; short *nr_out;bool *found_out)
|
||||
* Compute the 'variable number' of the
|
||||
void var_nr(line_p l, short *nr_out, bool *found_out);
|
||||
/* Compute the 'variable number' of the
|
||||
* variable referenced by EM instruction l.
|
||||
*/
|
||||
extern find_local(); /* (offset off; short *nr_out; bool *found_out)
|
||||
* Try to find the local variable at the given
|
||||
void find_local(offset off, short *nr_out, bool *found_out);
|
||||
/* Try to find the local variable at the given
|
||||
* offset. Return its local-number.
|
||||
*/
|
||||
|
||||
@ -45,5 +45,3 @@ extern find_local(); /* (offset off; short *nr_out; bool *found_out)
|
||||
#define IS_REGVAR(lc) (lc->lc_flags & LCF_REG)
|
||||
#define BADLC(lc) lc->lc_flags |= LCF_BAD
|
||||
#define IS_BADLC(lc) (lc->lc_flags & LCF_BAD)
|
||||
|
||||
|
||||
|
||||
@ -35,9 +35,7 @@ lset Lempty_set()
|
||||
}
|
||||
|
||||
|
||||
bool Lis_elem(x,s)
|
||||
register Lelem_t x;
|
||||
register lset s;
|
||||
bool Lis_elem(Lelem_t x, lset s)
|
||||
{
|
||||
|
||||
/* Search the list to see if x is an element of s */
|
||||
@ -51,9 +49,7 @@ bool Lis_elem(x,s)
|
||||
}
|
||||
|
||||
|
||||
Ladd(x,s_p)
|
||||
Lelem_t x;
|
||||
lset *s_p;
|
||||
void Ladd(Lelem_t x, lset *s_p)
|
||||
{
|
||||
/* add x to a set. Note that the set is given as in-out
|
||||
* parameter, because it may be changed.
|
||||
@ -70,9 +66,7 @@ Ladd(x,s_p)
|
||||
}
|
||||
|
||||
|
||||
Lremove(x,s_p)
|
||||
Lelem_t x;
|
||||
lset *s_p;
|
||||
void Lremove(Lelem_t x, lset *s_p)
|
||||
{
|
||||
/* Remove x from a set. If x was not an element of
|
||||
* the set, nothing happens.
|
||||
@ -108,8 +102,7 @@ Lremove(x,s_p)
|
||||
*/
|
||||
|
||||
|
||||
Lindex Lfirst(s)
|
||||
lset s;
|
||||
Lindex Lfirst(lset s)
|
||||
{
|
||||
return ((Lindex) s);
|
||||
/* Note that an index for long sets is just
|
||||
@ -119,32 +112,28 @@ Lindex Lfirst(s)
|
||||
|
||||
|
||||
/*ARGSUSED1*/
|
||||
Lindex Lnext(i,s)
|
||||
Lindex i;
|
||||
lset s;
|
||||
Lindex Lnext(Lindex i, lset s)
|
||||
{
|
||||
assert(i != (Lindex) 0);
|
||||
return (i->e_next);
|
||||
}
|
||||
|
||||
|
||||
Lelem_t Lelem(i)
|
||||
Lindex i;
|
||||
Lelem_t Lelem(Lindex i)
|
||||
{
|
||||
return (i->e_elem);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Ljoin(s1,s2_p)
|
||||
lset s1,*s2_p;
|
||||
void Ljoin(lset s1, lset *s2_p)
|
||||
{
|
||||
/* Join two sets, assign the result to the second set
|
||||
* and delete the first set (i.e. the value of the
|
||||
* first set becomes undefined).
|
||||
*/
|
||||
|
||||
register elem_p *epp, ep;
|
||||
elem_p *epp, ep;
|
||||
lset s2;
|
||||
|
||||
/* First all elements of s1 that are also an element of s2
|
||||
@ -172,10 +161,9 @@ Ljoin(s1,s2_p)
|
||||
}
|
||||
|
||||
|
||||
Ldeleteset(s)
|
||||
lset s;
|
||||
void Ldeleteset(lset s)
|
||||
{
|
||||
register elem_p ep, next;
|
||||
elem_p ep, next;
|
||||
|
||||
for (ep = s; ep != (elem_p) 0; ep = next) {
|
||||
next = ep->e_next;
|
||||
@ -184,12 +172,10 @@ Ldeleteset(s)
|
||||
}
|
||||
|
||||
|
||||
bool Lis_subset(s1,s2)
|
||||
lset s1,s2;
|
||||
bool Lis_subset(lset s1, lset s2)
|
||||
{
|
||||
/* See if s1 is a subset of s2 */
|
||||
|
||||
register Lindex i;
|
||||
Lindex i;
|
||||
|
||||
for (i = Lfirst(s1); i != (Lindex) 0; i = Lnext(i,s1)) {
|
||||
if (!Lis_elem(Lelem(i),s2)) return FALSE;
|
||||
@ -198,13 +184,11 @@ bool Lis_subset(s1,s2)
|
||||
}
|
||||
|
||||
|
||||
short Lnrelems(s)
|
||||
lset s;
|
||||
short Lnrelems(lset s)
|
||||
{
|
||||
/* Compute the number of elements of a set */
|
||||
|
||||
register elem_p ep;
|
||||
register short cnt;
|
||||
elem_p ep;
|
||||
short cnt;
|
||||
|
||||
cnt = 0;
|
||||
for (ep = s; ep != (elem_p) 0; ep = ep->e_next) {
|
||||
|
||||
@ -8,14 +8,14 @@
|
||||
*/
|
||||
|
||||
|
||||
extern lset Lempty_set(); /* () */
|
||||
extern bool Lis_elem(); /* (Lelem_t, lset) */
|
||||
extern Ladd(); /* (Lelem_t, *lset) */
|
||||
extern Lremove(); /* (Lelem_t, *lset) */
|
||||
extern Lindex Lfirst(); /* (lset) */
|
||||
extern Lindex Lnext(); /* (Lindex, lset) */
|
||||
extern Lelem_t Lelem(); /* (Lindex) */
|
||||
extern Ljoin(); /* (lset, *lset) */
|
||||
extern Ldeleteset(); /* (lset) */
|
||||
extern bool Lis_subset(); /* (lset, lset) */
|
||||
extern short Lnrelems(); /* (lset) */
|
||||
lset Lempty_set();
|
||||
bool Lis_elem(Lelem_t x, lset s);
|
||||
void Ladd(Lelem_t x, lset *s_p);
|
||||
void Lremove(Lelem_t x, lset *s_p);
|
||||
Lindex Lfirst(lset s);
|
||||
Lindex Lnext(Lindex i, lset s);
|
||||
Lelem_t Lelem(Lindex i);
|
||||
void Ljoin(lset s1, lset *s2_p);
|
||||
void Ldeleteset(lset s);
|
||||
bool Lis_subset(lset s1, lset s2);
|
||||
short Lnrelems(lset s);
|
||||
|
||||
@ -41,12 +41,9 @@ typedef struct class *class_p;
|
||||
* generated automatically from the file classdefs.src.
|
||||
*/
|
||||
|
||||
STATIC bool classes(instr,src_out,res_out)
|
||||
int instr;
|
||||
int *src_out, *res_out;
|
||||
static bool classes(int instr, int *src_out, int *res_out)
|
||||
{
|
||||
/* Determine the classes of the given instruction */
|
||||
|
||||
class_p c;
|
||||
|
||||
if (instr < sp_fmnem || instr > sp_lmnem) return FALSE;
|
||||
@ -59,8 +56,7 @@ STATIC bool classes(instr,src_out,res_out)
|
||||
|
||||
|
||||
|
||||
STATIC bool uses_arg(class)
|
||||
int class;
|
||||
static bool uses_arg(int class)
|
||||
{
|
||||
/* See if a member of the given class uses
|
||||
* an argument.
|
||||
@ -82,8 +78,7 @@ STATIC bool uses_arg(class)
|
||||
|
||||
|
||||
|
||||
STATIC bool uses_2args(class)
|
||||
int class;
|
||||
static bool uses_2args(int class)
|
||||
{
|
||||
/* See if a member of the given class uses
|
||||
* 2 arguments.
|
||||
@ -93,9 +88,7 @@ STATIC bool uses_2args(class)
|
||||
}
|
||||
|
||||
|
||||
STATIC bool parse_locs(l,c1_out,c2_out)
|
||||
line_p l;
|
||||
offset *c1_out, *c2_out;
|
||||
static bool parse_locs(line_p l, offset *c1_out, offset *c2_out)
|
||||
{
|
||||
if (INSTR(l) == op_loc && INSTR(PREV(l)) == op_loc) {
|
||||
*c1_out = off_set(l);
|
||||
@ -107,10 +100,7 @@ STATIC bool parse_locs(l,c1_out,c2_out)
|
||||
|
||||
|
||||
|
||||
STATIC bool check_args(l,src_class,res_class,arg1_out,arg2_out)
|
||||
line_p l;
|
||||
int src_class,res_class;
|
||||
offset *arg1_out, *arg2_out;
|
||||
static bool check_args(line_p l, int src_class, int res_class, offset *arg1_out, offset *arg2_out)
|
||||
{
|
||||
/* Several EM instructions have an argument
|
||||
* giving the size of the operand(s) of
|
||||
@ -144,9 +134,7 @@ STATIC bool check_args(l,src_class,res_class,arg1_out,arg2_out)
|
||||
|
||||
|
||||
|
||||
STATIC offset nrbytes(class,arg1,arg2)
|
||||
int class;
|
||||
offset arg1,arg2;
|
||||
static offset nrbytes(int class, offset arg1, offset arg2)
|
||||
{
|
||||
/* Determine the number of bytes of the given
|
||||
* arguments and class.
|
||||
@ -185,9 +173,7 @@ STATIC offset nrbytes(class,arg1,arg2)
|
||||
|
||||
|
||||
|
||||
STATIC attrib(l,expect_out,srcb_out,resb_out)
|
||||
line_p l;
|
||||
offset *expect_out, *srcb_out, *resb_out;
|
||||
static void attrib(line_p l, offset *expect_out, offset *srcb_out, offset *resb_out)
|
||||
{
|
||||
/* Determine a number of attributes of an EM
|
||||
* instruction appearing in an expression.
|
||||
@ -215,11 +201,7 @@ STATIC attrib(l,expect_out,srcb_out,resb_out)
|
||||
|
||||
|
||||
|
||||
bool parse(l,nbytes,l_out,level,action0)
|
||||
line_p l, *l_out;
|
||||
offset nbytes;
|
||||
int level;
|
||||
int (*action0) ();
|
||||
bool parse(line_p l, offset nbytes, line_p *l_out, int level, int (*action0)(line_p, line_p, offset))
|
||||
{
|
||||
/* This is a recursive descent parser for
|
||||
* EM expressions.
|
||||
|
||||
@ -30,12 +30,16 @@ FILE *curoutp;
|
||||
|
||||
/* putlines */
|
||||
|
||||
STATIC putstr();
|
||||
STATIC outlab();
|
||||
STATIC outobject();
|
||||
static void putstr(argb_p abp);
|
||||
static void outlab(lab_id lid);
|
||||
static void outobject(obj_p obj);
|
||||
static void putstr(argb_p abp);
|
||||
void outshort(short i);
|
||||
static void putstr(argb_p abp);
|
||||
|
||||
STATIC putargs(ap)
|
||||
register arg_p ap;
|
||||
|
||||
|
||||
static void putargs(arg_p ap)
|
||||
{
|
||||
while (ap != (arg_p) 0) {
|
||||
outbyte((byte) ap->a_type & BMASK);
|
||||
@ -69,9 +73,10 @@ STATIC putargs(ap)
|
||||
|
||||
|
||||
|
||||
STATIC putstr(abp) register argb_p abp; {
|
||||
register argb_p tbp;
|
||||
register length;
|
||||
static void putstr(argb_p abp)
|
||||
{
|
||||
argb_p tbp;
|
||||
int length;
|
||||
|
||||
length = 0;
|
||||
tbp = abp;
|
||||
@ -88,22 +93,21 @@ STATIC putstr(abp) register argb_p abp; {
|
||||
}
|
||||
|
||||
|
||||
outoff(off) offset off; {
|
||||
|
||||
void outoff(offset off)
|
||||
{
|
||||
outshort( (short) (off&0177777L) );
|
||||
outshort( (short) (off>>16) );
|
||||
}
|
||||
|
||||
|
||||
outshort(i) short i; {
|
||||
|
||||
void outshort(short i)
|
||||
{
|
||||
outbyte( (byte) (i&BMASK) );
|
||||
outbyte( (byte) (i>>8) );
|
||||
}
|
||||
|
||||
|
||||
STATIC outint(i)
|
||||
int i;
|
||||
static void outint(int i)
|
||||
{
|
||||
/* Write an integer to the output file. This routine is
|
||||
* only used when outputting a bitvector-set. We expect an
|
||||
@ -118,30 +122,31 @@ STATIC outint(i)
|
||||
}
|
||||
}
|
||||
|
||||
STATIC outlab(lid) lab_id lid; {
|
||||
static void outlab(lab_id lid)
|
||||
{
|
||||
outshort((short) lid);
|
||||
}
|
||||
|
||||
|
||||
STATIC outobject(obj) obj_p obj; {
|
||||
static void outobject(obj_p obj)
|
||||
{
|
||||
outshort((short) obj->o_id);
|
||||
}
|
||||
|
||||
|
||||
outproc(p) proc_p p; {
|
||||
void outproc(proc_p p)
|
||||
{
|
||||
outshort((short) p->p_id);
|
||||
}
|
||||
|
||||
|
||||
short putlines(l,lf)
|
||||
line_p l;
|
||||
FILE *lf;
|
||||
short putlines(line_p l, FILE *lf)
|
||||
{
|
||||
/* Output the list of em instructions headed by l.
|
||||
* Return the number of instruction written.
|
||||
*/
|
||||
|
||||
register line_p lnp;
|
||||
line_p lnp;
|
||||
line_p next;
|
||||
short instr;
|
||||
short count= 0;
|
||||
@ -180,16 +185,12 @@ short putlines(l,lf)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* putdtable */
|
||||
|
||||
#define outmark(m) outbyte((byte) m)
|
||||
|
||||
|
||||
STATIC putobjects(obj)
|
||||
register obj_p obj;
|
||||
static void putobjects(obj_p obj)
|
||||
{
|
||||
while (obj != (obj_p) 0) {
|
||||
outmark(MARK_OBJ);
|
||||
@ -202,8 +203,7 @@ STATIC putobjects(obj)
|
||||
|
||||
|
||||
|
||||
STATIC putvalues(arg)
|
||||
register arg_p arg;
|
||||
static void putvalues(arg_p arg)
|
||||
{
|
||||
while (arg != (arg_p) 0) {
|
||||
assert(arg->a_type == ARGOFF);
|
||||
@ -212,16 +212,15 @@ STATIC putvalues(arg)
|
||||
arg = arg->a_next;
|
||||
}
|
||||
}
|
||||
putdtable(head,df)
|
||||
dblock_p head;
|
||||
FILE *df;
|
||||
|
||||
void putdtable(dblock_p head, FILE *df)
|
||||
{
|
||||
/* Write the datablock table to the data block file df. */
|
||||
|
||||
register dblock_p dbl;
|
||||
register obj_p obj;
|
||||
dblock_p dbl;
|
||||
obj_p obj;
|
||||
dblock_p next;
|
||||
register short n = 0;
|
||||
short n = 0;
|
||||
|
||||
curoutp = df; /* set f to the data block output file */
|
||||
/* Count the number of objects */
|
||||
@ -253,17 +252,13 @@ putdtable(head,df)
|
||||
|
||||
|
||||
/* putptable */
|
||||
|
||||
|
||||
|
||||
STATIC outcset(s)
|
||||
cset s;
|
||||
static void outcset(cset s)
|
||||
{
|
||||
/* A 'compact' set is represented externally as a row of words
|
||||
* (its bitvector) preceded by its length.
|
||||
*/
|
||||
|
||||
register short i;
|
||||
short i;
|
||||
|
||||
outshort(s->v_size);
|
||||
for (i = 0; i <= DIVWL(s->v_size - 1); i++) {
|
||||
@ -273,14 +268,11 @@ STATIC outcset(s)
|
||||
|
||||
|
||||
|
||||
putptable(head,pf,all)
|
||||
proc_p head;
|
||||
FILE *pf;
|
||||
bool all;
|
||||
void putptable(proc_p head, FILE *pf, bool all)
|
||||
{
|
||||
register proc_p p;
|
||||
proc_p p;
|
||||
proc_p next;
|
||||
register short n = 0;
|
||||
short n = 0;
|
||||
/* Write the proc table */
|
||||
|
||||
curoutp = pf;
|
||||
@ -327,16 +319,17 @@ putptable(head,pf,all)
|
||||
|
||||
/* putunit */
|
||||
|
||||
STATIC outloop(l)
|
||||
loop_p l;
|
||||
static void outloop(Lelem_t param)
|
||||
{
|
||||
loop_p l = (loop_p)param;
|
||||
outshort((short) l->lp_id);
|
||||
}
|
||||
|
||||
|
||||
STATIC outblock(b)
|
||||
bblock_p b;
|
||||
static void outblock(Lelem_t param)
|
||||
{
|
||||
bblock_p b = (bblock_p)param;
|
||||
|
||||
if (b == (bblock_p) 0) {
|
||||
outshort((short) 0);
|
||||
} else {
|
||||
@ -345,9 +338,7 @@ STATIC outblock(b)
|
||||
}
|
||||
|
||||
|
||||
STATIC outid(e,p)
|
||||
Lelem_t e;
|
||||
int (*p) ();
|
||||
static void outid(Lelem_t e, void (*p)(Lelem_t))
|
||||
{
|
||||
/* Auxiliary routine used by outlset. */
|
||||
|
||||
@ -356,9 +347,7 @@ STATIC outid(e,p)
|
||||
}
|
||||
|
||||
|
||||
STATIC outlset(s,p)
|
||||
lset s;
|
||||
int (*p) ();
|
||||
static void outlset(lset s, void (*p)(Lelem_t))
|
||||
{
|
||||
/* A 'long' set is represented externally as a
|
||||
* a sequence of elements terminated by a 0 word.
|
||||
@ -366,7 +355,7 @@ STATIC outlset(s,p)
|
||||
* prints an id (proc_id, obj_id etc.).
|
||||
*/
|
||||
|
||||
register Lindex i;
|
||||
Lindex i;
|
||||
|
||||
for (i = Lfirst(s); i != (Lindex) 0; i = Lnext(i,s)) {
|
||||
outid(Lelem(i),p);
|
||||
@ -376,14 +365,10 @@ STATIC outlset(s,p)
|
||||
|
||||
|
||||
|
||||
putunit(kind,p,l,gf,lf)
|
||||
short kind;
|
||||
proc_p p;
|
||||
line_p l;
|
||||
FILE *gf, *lf;
|
||||
void putunit(short kind, proc_p p, line_p l, FILE *gf, FILE *lf)
|
||||
{
|
||||
register bblock_p b;
|
||||
register short n = 0;
|
||||
bblock_p b;
|
||||
short n = 0;
|
||||
Lindex pi;
|
||||
loop_p lp;
|
||||
|
||||
|
||||
@ -9,28 +9,27 @@
|
||||
extern FILE *curoutp; /* current output file */
|
||||
|
||||
#define outbyte(b) putc(b,curoutp)
|
||||
extern outshort(); /* (short i)
|
||||
* Write a short to curoutp
|
||||
void outshort(short i);
|
||||
/* Write a short to curoutp
|
||||
*/
|
||||
extern outoff(); /* (offset off)
|
||||
* Write an offset to curoutp
|
||||
void outoff(offset off);
|
||||
/* Write an offset to curoutp
|
||||
*/
|
||||
extern outproc(); /* (proc_p p)
|
||||
* Write a procid to curoutp
|
||||
void outproc(proc_p p);
|
||||
/* Write a procid to curoutp
|
||||
*/
|
||||
extern putdtable(); /* (dblock_p head, FILE *df)
|
||||
* Write the data block table to file df,
|
||||
void putdtable(dblock_p head, FILE *df);
|
||||
/* Write the data block table to file df,
|
||||
* preceded by its length.
|
||||
*/
|
||||
extern putptable(); /* (proc_p head, FILE *pf, bool all)
|
||||
* Write the proc table to file pf,
|
||||
void putptable(proc_p head, FILE *pf, bool all);
|
||||
/* Write the proc table to file pf,
|
||||
* preceded by its length. If all=false,
|
||||
* the fields computed by CF will not be
|
||||
* written (used by the IC phase).
|
||||
*/
|
||||
extern putunit(); /* (short kind; proc_p p; line_p l;
|
||||
* FILE *gf, *lf)
|
||||
* If kind = LTEXT, then write
|
||||
void putunit(short kind, proc_p p, line_p l, FILE *gf, FILE *lf);
|
||||
/* If kind = LTEXT, then write
|
||||
* the control flow graph to file gf,
|
||||
* preceded by its length (#basic blocks);
|
||||
* write the EM code of every basic block
|
||||
@ -40,8 +39,8 @@ extern putunit(); /* (short kind; proc_p p; line_p l;
|
||||
* list of instructions (data declarations)
|
||||
* to lf.
|
||||
*/
|
||||
extern short putlines(); /* (line_p l; FILE *lf)
|
||||
* Output the list of em instructions
|
||||
short putlines(line_p l, FILE *lf);
|
||||
/* Output the list of em instructions
|
||||
* headed by l. Return the number of
|
||||
* instructions written.
|
||||
*/
|
||||
|
||||
@ -17,9 +17,7 @@
|
||||
|
||||
#define IS_LOC(l) (l!=(line_p) 0 && INSTR(l)==op_loc && TYPE(l)==OPSHORT)
|
||||
|
||||
int stack_change(l,sign)
|
||||
line_p l;
|
||||
char sign;
|
||||
int stack_change(line_p l, char sign)
|
||||
{
|
||||
/* Interpret the string in the third column of the em_table file */
|
||||
|
||||
@ -91,10 +89,7 @@ int stack_change(l,sign)
|
||||
|
||||
|
||||
|
||||
line_change(l,ok_out,pop_out,push_out)
|
||||
line_p l;
|
||||
bool *ok_out;
|
||||
int *pop_out,*push_out;
|
||||
void line_change(line_p l, bool *ok_out, int *pop_out, int *push_out)
|
||||
{
|
||||
short pop,push;
|
||||
|
||||
|
||||
@ -46,7 +46,7 @@ typedef struct elemholder *lset;
|
||||
typedef struct bitvector *cset;
|
||||
typedef elem_p Lindex;
|
||||
typedef short Cindex;
|
||||
typedef char *Lelem_t;
|
||||
typedef void *Lelem_t;
|
||||
typedef short Celem_t;
|
||||
|
||||
typedef union pext_t *pext_p;
|
||||
@ -224,7 +224,7 @@ struct use {
|
||||
*/
|
||||
|
||||
|
||||
struct elemholder {
|
||||
struct elemholder {
|
||||
char *e_elem; /* pointer to the element */
|
||||
elem_p e_next; /* link */
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user