Next batch
This commit is contained in:
parent
bd3e7b87e6
commit
452127650a
@ -224,7 +224,7 @@ void iconvert(char* buf, char* str, char* fmt)
|
||||
int last, i ;
|
||||
uint32_t value ;
|
||||
ni=buf ; no=str ; nf=fmt ;
|
||||
while ( last = *nf++ ) {
|
||||
while (( last = *nf++ )) {
|
||||
last -= '0' ;
|
||||
if ( last<1 || last >9 ) fatal("illegal out.h format string\n");
|
||||
value=0 ;
|
||||
|
||||
@ -35,8 +35,10 @@ long s_base[S_MAX]; /* for specially encoded bases */
|
||||
char *filename;
|
||||
int narg;
|
||||
|
||||
main(argc, argv)
|
||||
char **argv;
|
||||
void process(int fd);
|
||||
void do_file(int fd);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
if (--argc>0 && argv[1][0]=='-' && argv[1][1]!=0) {
|
||||
@ -96,10 +98,9 @@ char **argv;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
extern int rd_unsigned2();
|
||||
int rd_unsigned2(int fd);
|
||||
|
||||
process(fd)
|
||||
int fd;
|
||||
void process(int fd)
|
||||
{
|
||||
unsigned int magic;
|
||||
long nextpos;
|
||||
@ -134,8 +135,7 @@ process(fd)
|
||||
}
|
||||
}
|
||||
|
||||
do_file(fd)
|
||||
int fd;
|
||||
void do_file(int fd)
|
||||
{
|
||||
struct outname *nbufp = NULL;
|
||||
struct outname nbuf;
|
||||
@ -295,8 +295,7 @@ do_file(fd)
|
||||
free((char *)cbufp);
|
||||
}
|
||||
|
||||
compare(p1, p2)
|
||||
struct outname *p1, *p2;
|
||||
int compare(struct outname *p1, struct outname *p2)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -330,7 +329,7 @@ struct outname *p1, *p2;
|
||||
return(0);
|
||||
}
|
||||
|
||||
rd_fatal()
|
||||
void rd_fatal()
|
||||
{
|
||||
fprintf(stderr,"read error on %s\n", filename);
|
||||
read_error = 1;
|
||||
|
||||
@ -12,13 +12,21 @@ static char rcsid[] = "$Id$";
|
||||
#define OK 0 /* Return value of gethead if Orl Korekt. */
|
||||
#define BMASK 0xFF /* To extract least significant 8 bits from an int. */
|
||||
|
||||
|
||||
void show(struct outhead *headp);
|
||||
void showflags(unsigned int flagword);
|
||||
void showsect();
|
||||
void showname(struct outname *namep);
|
||||
void error(char *format, ...);
|
||||
void showrelo();
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
# define prog argv[0]
|
||||
#define prog argv[0]
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
register char **arg = argv;
|
||||
char **arg = argv;
|
||||
struct outhead header;
|
||||
|
||||
while (*++arg) {
|
||||
@ -42,13 +50,12 @@ main(argc, argv)
|
||||
* NB. The header has already been read and is in the struct outhead `headp'
|
||||
* points to.
|
||||
*/
|
||||
show(headp)
|
||||
register struct outhead *headp;
|
||||
void show(struct outhead *headp)
|
||||
{
|
||||
register int i;
|
||||
register struct outname *np;
|
||||
register struct outname *name; /* Dynamically allocated name-array. */
|
||||
register char *string;/* Base of string area. */
|
||||
int i;
|
||||
struct outname *np;
|
||||
struct outname *name; /* Dynamically allocated name-array. */
|
||||
char *string;/* Base of string area. */
|
||||
extern char *myalloc();
|
||||
|
||||
printf("Version %d\n", headp->oh_stamp);
|
||||
@ -98,8 +105,7 @@ show(headp)
|
||||
/*
|
||||
* Show flags from header.
|
||||
*/
|
||||
showflags(flagword)
|
||||
unsigned flagword;
|
||||
void showflags(unsigned int flagword)
|
||||
{
|
||||
if (flagword & HF_LINK) printf("unresolved references left\n");
|
||||
}
|
||||
@ -107,7 +113,7 @@ showflags(flagword)
|
||||
/*
|
||||
* Show a section.
|
||||
*/
|
||||
showsect()
|
||||
void showsect()
|
||||
{
|
||||
struct outsect section;
|
||||
|
||||
@ -122,7 +128,7 @@ showsect()
|
||||
/*
|
||||
* Show a relocation record.
|
||||
*/
|
||||
showrelo()
|
||||
void showrelo()
|
||||
{
|
||||
struct outrelo relrec;
|
||||
|
||||
@ -152,8 +158,7 @@ showrelo()
|
||||
/*
|
||||
* Show the name in the struct `namep' points to.
|
||||
*/
|
||||
showname(namep)
|
||||
struct outname *namep;
|
||||
void showname(struct outname *namep)
|
||||
{
|
||||
if (namep->on_mptr)
|
||||
printf("\t%s\n", namep->on_mptr);
|
||||
@ -200,9 +205,7 @@ showname(namep)
|
||||
/*
|
||||
* Core allocation via malloc() but fatal if no core.
|
||||
*/
|
||||
char *
|
||||
myalloc(u)
|
||||
unsigned int u;
|
||||
char *myalloc(unsigned int u)
|
||||
{
|
||||
register char *rcp;
|
||||
|
||||
@ -215,14 +218,16 @@ myalloc(u)
|
||||
}
|
||||
|
||||
/* VARARGS1 */
|
||||
error(s, a1, a2, a3, a4)
|
||||
char *s;
|
||||
void error(char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
fflush(stdout);
|
||||
fprintf(stderr, s, a1, a2, a3, a4);
|
||||
va_start(ap, format);
|
||||
vfprintf(stderr, format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
rd_fatal()
|
||||
void rd_fatal()
|
||||
{
|
||||
error("Error in reading the object file\n");
|
||||
exit(1);
|
||||
|
||||
@ -23,8 +23,7 @@ FILE *tf;
|
||||
struct outhead buf;
|
||||
int readerror, writeerror;
|
||||
|
||||
main(argc, argv)
|
||||
char **argv;
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int status;
|
||||
|
||||
@ -40,8 +39,7 @@ char **argv;
|
||||
exit(status);
|
||||
}
|
||||
|
||||
strip(name)
|
||||
char *name;
|
||||
int strip(char *name)
|
||||
{
|
||||
long size;
|
||||
int fw;
|
||||
@ -113,12 +111,9 @@ char *name;
|
||||
return(0);
|
||||
}
|
||||
|
||||
copy(fnam, tnam, size, fr, fw)
|
||||
char *fnam;
|
||||
char *tnam;
|
||||
long size;
|
||||
int copy(char *fnam, char *tnam, long size, int fr, int fw)
|
||||
{
|
||||
register s, n;
|
||||
int s, n;
|
||||
char lbuf[512];
|
||||
|
||||
while(size != (long)0) {
|
||||
@ -140,12 +135,12 @@ long size;
|
||||
return(0);
|
||||
}
|
||||
|
||||
rd_fatal()
|
||||
void rd_fatal()
|
||||
{
|
||||
readerror = 1;
|
||||
}
|
||||
|
||||
wr_fatal()
|
||||
void wr_fatal()
|
||||
{
|
||||
writeerror = 1;
|
||||
}
|
||||
|
||||
@ -4,6 +4,9 @@
|
||||
optimizer itself one day ...
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <em_path.h>
|
||||
#include <signal.h>
|
||||
#include <system.h>
|
||||
@ -42,10 +45,6 @@ static char *phnames[] = {
|
||||
#define MAXARGS 1024 /* mar # of args */
|
||||
#define NTEMPS 4 /* # of temporary files; not tunable */
|
||||
|
||||
extern char *mktemp();
|
||||
extern char *strcpy(), *strcat();
|
||||
extern char *strrchr();
|
||||
|
||||
static char ddump[128] = TMP_DIR; /* data label dump file */
|
||||
static char pdump[128] = TMP_DIR; /* procedure name dump file */
|
||||
static char tmpbufs[NTEMPS*2][128] = {
|
||||
@ -82,8 +81,7 @@ static char *prog_name;
|
||||
|
||||
static int v_flag;
|
||||
|
||||
static void
|
||||
cleanup()
|
||||
static void cleanup()
|
||||
{
|
||||
/* Cleanup temporaries */
|
||||
|
||||
@ -100,10 +98,7 @@ cleanup()
|
||||
}
|
||||
|
||||
/*VARARGS1*/
|
||||
static void
|
||||
fatal(s, s2)
|
||||
char *s;
|
||||
char *s2;
|
||||
static void fatal(char *s, char *s2)
|
||||
{
|
||||
/* A fatal error occurred; exit gracefully */
|
||||
|
||||
@ -115,28 +110,23 @@ fatal(s, s2)
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
static void
|
||||
add_file(s)
|
||||
char *s;
|
||||
static void add_file(char *s)
|
||||
{
|
||||
/* Add an input file to the list */
|
||||
|
||||
if (nfiles >= MAXARGS) fatal("too many files");
|
||||
if (nfiles >= MAXARGS) fatal("too many files", NULL);
|
||||
phargs[nfiles++] = s;
|
||||
}
|
||||
|
||||
static void
|
||||
add_uphase(p)
|
||||
int p;
|
||||
static void add_uphase(int p)
|
||||
{
|
||||
/* Add an optimizer phase to the list of phases to run */
|
||||
|
||||
if (nuphases >= MAXUPHASES) fatal("too many phases");
|
||||
if (nuphases >= MAXUPHASES) fatal("too many phases", NULL);
|
||||
uphases[nuphases++] = p;
|
||||
}
|
||||
|
||||
static void
|
||||
catch()
|
||||
static void catch()
|
||||
{
|
||||
/* Catch interrupts and exit gracefully */
|
||||
|
||||
@ -144,8 +134,7 @@ catch()
|
||||
sys_stop(S_EXIT);
|
||||
}
|
||||
|
||||
static void
|
||||
old_infiles()
|
||||
static void old_infiles()
|
||||
{
|
||||
/* Remove old input files unless we have to keep them around. */
|
||||
|
||||
@ -156,8 +145,7 @@ old_infiles()
|
||||
for (i = 1; i <= NTEMPS; i++) (void) unlink(phargs[i]);
|
||||
}
|
||||
|
||||
static void
|
||||
get_infiles()
|
||||
static void get_infiles()
|
||||
{
|
||||
/* Make output temps from previous phase input temps of next phase. */
|
||||
|
||||
@ -170,8 +158,7 @@ get_infiles()
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
new_outfiles()
|
||||
static void new_outfiles()
|
||||
{
|
||||
static int tmpindex = 0;
|
||||
static int Bindex = 0;
|
||||
@ -197,9 +184,7 @@ new_outfiles()
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
run_phase(phase)
|
||||
int phase;
|
||||
static void run_phase(int phase)
|
||||
{
|
||||
/* Run one phase of the global optimizer; special cases are
|
||||
IC and CA.
|
||||
@ -250,7 +235,7 @@ run_phase(phase)
|
||||
break;
|
||||
}
|
||||
if ((pid = fork()) < 0) {
|
||||
fatal("Could not fork");
|
||||
fatal("Could not fork", NULL);
|
||||
}
|
||||
else if (pid == 0) {
|
||||
if (v_flag) {
|
||||
@ -278,18 +263,16 @@ run_phase(phase)
|
||||
}
|
||||
}
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
register int i = 0;
|
||||
int i = 0;
|
||||
|
||||
if (signal(SIGHUP, catch) == SIG_IGN) (void) signal(SIGHUP, SIG_IGN);
|
||||
if (signal(SIGQUIT, catch) == SIG_IGN) (void) signal(SIGQUIT, SIG_IGN);
|
||||
if (signal(SIGINT, catch) == SIG_IGN) (void) signal(SIGINT, SIG_IGN);
|
||||
prog_name = argv[0];
|
||||
phase_args = &argv[1];
|
||||
while (--argc > 0) {
|
||||
if (signal(SIGHUP, catch) == SIG_IGN) (void) signal(SIGHUP, SIG_IGN);
|
||||
if (signal(SIGQUIT, catch) == SIG_IGN) (void) signal(SIGQUIT, SIG_IGN);
|
||||
if (signal(SIGINT, catch) == SIG_IGN) (void) signal(SIGINT, SIG_IGN);
|
||||
prog_name = argv[0];
|
||||
phase_args = &argv[1];
|
||||
while (--argc > 0) {
|
||||
argv++;
|
||||
if (argv[0][0] == '-') {
|
||||
switch(argv[0][1]) {
|
||||
@ -386,7 +369,7 @@ main(argc, argv)
|
||||
}
|
||||
|
||||
if (! opt_dir) {
|
||||
fatal("no correct -P flag given");
|
||||
fatal("no correct -P flag given", NULL);
|
||||
}
|
||||
|
||||
if (keeptemps) {
|
||||
@ -418,4 +401,5 @@ main(argc, argv)
|
||||
cleanup();
|
||||
sys_stop(S_END);
|
||||
/*NOTREACHED*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* MAKE ITEMS TABLE
|
||||
*
|
||||
@ -22,8 +23,9 @@
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
convert(mnemfile,itemfile)
|
||||
FILE *mnemfile, *itemfile;
|
||||
void error(char *s);
|
||||
|
||||
void convert(FILE *mnemfile, FILE *itemfile)
|
||||
{
|
||||
char mnem1[20], mnem2[20],def[20],itemtype[20];
|
||||
int newcl,opc,index;
|
||||
@ -57,17 +59,14 @@ convert(mnemfile,itemfile)
|
||||
|
||||
|
||||
|
||||
error(s)
|
||||
char *s;
|
||||
void error(char *s)
|
||||
{
|
||||
fprintf(stderr,"%s\n",s);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FILE *f1,*f2;
|
||||
|
||||
|
||||
@ -35,6 +35,8 @@
|
||||
#define oldrabx(x) oldstruct(bext_ra,x)
|
||||
#define oldralpx(x) oldstruct(lpext_ra,x)
|
||||
|
||||
void stat_regusage(alloc_p list);
|
||||
|
||||
short alloc_id;
|
||||
static item_p items[NRITEMTYPES];
|
||||
int nrinstrs;
|
||||
@ -100,10 +102,11 @@ void get_otab(FILE *f, cond_p tab[NRREGTYPES])
|
||||
|
||||
|
||||
|
||||
static void ra_machinit(FILE *f)
|
||||
static int ra_machinit(void *param)
|
||||
{
|
||||
/* Read target machine dependent information for this phase */
|
||||
char s[100];
|
||||
FILE *f = (FILE *)param;
|
||||
|
||||
for (;;) {
|
||||
while(getc(f) != '\n');
|
||||
@ -127,6 +130,8 @@ static void ra_machinit(FILE *f)
|
||||
oglobaltab = getcondtab(f);
|
||||
oproctab = getcondtab(f);
|
||||
regsav_cost = getcondtab(f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -171,10 +176,10 @@ static void ra_extproc(proc_p p)
|
||||
|
||||
|
||||
|
||||
static void ra_cleanproc(proc_p p)
|
||||
static int ra_cleanproc(void *param)
|
||||
{
|
||||
/* Allocate the extended data structures for procedure p */
|
||||
|
||||
proc_p p = (proc_p)param;
|
||||
loop_p lp;
|
||||
Lindex pi;
|
||||
bblock_p b;
|
||||
@ -187,6 +192,8 @@ static void ra_cleanproc(proc_p p)
|
||||
for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) {
|
||||
oldrabx(b->b_extend);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -325,20 +332,22 @@ static void cleanitems(item_p list)
|
||||
}
|
||||
|
||||
|
||||
void ra_initialize()
|
||||
int ra_initialize(void *dummy)
|
||||
{
|
||||
init_replacements(ps,ws);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void ra_optimize(proc_p p)
|
||||
int ra_optimize(void *param)
|
||||
{
|
||||
proc_p p = (proc_p)param;
|
||||
item_p itemlist;
|
||||
alloc_p alloclist,packed,unpacked;
|
||||
offset locls;
|
||||
bool time_opt = (time_space_ratio == 100);
|
||||
|
||||
if (IS_ENTERED_WITH_GTO(p)) return;
|
||||
if (IS_ENTERED_WITH_GTO(p)) return 0;
|
||||
ra_extproc(p);
|
||||
loop_blocks(p);
|
||||
alloc_id =0;
|
||||
@ -369,8 +378,9 @@ void ra_optimize(proc_p p)
|
||||
clean_allocs(unpacked);
|
||||
clean_allocs(packed);
|
||||
cleanitems(itemlist);
|
||||
oldmap(instrmap,nrinstrs-1);
|
||||
oldmap((short **)instrmap,nrinstrs-1);
|
||||
ra_cleanproc(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -27,10 +27,7 @@
|
||||
#include "ra_allocl.h"
|
||||
#include "ra_interv.h"
|
||||
|
||||
STATIC count_usage(p,item,nrloops,sloopcnt,dloopcnt)
|
||||
proc_p p;
|
||||
item_p item;
|
||||
short nrloops, sloopcnt[], dloopcnt[];
|
||||
static void count_usage(proc_p p, item_p item, short nrloops, short sloopcnt[], short dloopcnt[])
|
||||
{
|
||||
/* Determine how many times the item is used in every loop.
|
||||
* We maintain a 'static' count and a 'dynamic' count. The dynamic
|
||||
@ -67,14 +64,8 @@ STATIC count_usage(p,item,nrloops,sloopcnt,dloopcnt)
|
||||
|
||||
|
||||
|
||||
STATIC alloc_p cons_alloc(item,timespan,stat_usecount,
|
||||
dyn_usecount,inits,wholeproc,isloop,iswholeproc)
|
||||
item_p item;
|
||||
interv_p timespan;
|
||||
short stat_usecount,dyn_usecount;
|
||||
lset inits;
|
||||
alloc_p wholeproc;
|
||||
bool isloop,iswholeproc;
|
||||
static alloc_p cons_alloc(item_p item, interv_p timespan, short stat_usecount,
|
||||
short dyn_usecount, lset inits, alloc_p wholeproc, bool isloop, bool iswholeproc)
|
||||
{
|
||||
alloc_p x;
|
||||
|
||||
@ -92,22 +83,16 @@ STATIC alloc_p cons_alloc(item,timespan,stat_usecount,
|
||||
}
|
||||
|
||||
|
||||
STATIC insert_alloc(alloc,list_p)
|
||||
alloc_p alloc, *list_p;
|
||||
static void insert_alloc(alloc_p alloc, alloc_p *list_p)
|
||||
{
|
||||
alloc->al_next = *list_p;
|
||||
*list_p = alloc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define MUST_INIT(i,b) (i->it_type!=LOCALVAR ||contains(b->B_BEGIN,i->it_lives))
|
||||
#define MUST_UPDATE(i,b) (i->it_type==LOCALVAR &&contains(b->B_BEGIN,i->it_lives))
|
||||
|
||||
STATIC lset loop_inits(lp,item,header)
|
||||
loop_p lp;
|
||||
item_p item;
|
||||
bblock_p header;
|
||||
static lset loop_inits(loop_p lp, item_p item, bblock_p header)
|
||||
{
|
||||
/* Build the set of entry points to loop lp where item
|
||||
* must be initialized
|
||||
@ -124,8 +109,7 @@ STATIC lset loop_inits(lp,item,header)
|
||||
|
||||
#define IN_LOOP(b) (Lnrelems(b->b_loops) > 0)
|
||||
|
||||
STATIC bblock_p init_point(item)
|
||||
item_p item;
|
||||
static bblock_p init_point(item_p item)
|
||||
{
|
||||
/* Find the most appropriate point to initialize any register
|
||||
* containing the item. We want to do the initialization as
|
||||
@ -157,10 +141,7 @@ STATIC bblock_p init_point(item)
|
||||
}
|
||||
|
||||
|
||||
STATIC add_blocks(b,s,span)
|
||||
bblock_p b;
|
||||
cset *s;
|
||||
interv_p *span;
|
||||
static void add_blocks(bblock_p b, cset *s, interv_p *span)
|
||||
{
|
||||
Lindex pi;
|
||||
|
||||
@ -176,10 +157,7 @@ STATIC add_blocks(b,s,span)
|
||||
|
||||
|
||||
|
||||
STATIC whole_lifetime(item,ini_out,span_out)
|
||||
item_p item;
|
||||
bblock_p *ini_out;
|
||||
interv_p *span_out;
|
||||
static void whole_lifetime(item_p item, bblock_p *ini_out, interv_p *span_out)
|
||||
{
|
||||
/* Find the initialization point and the time_span of the item, if
|
||||
* we put the item in a register during all its uses.
|
||||
@ -205,13 +183,7 @@ STATIC whole_lifetime(item,ini_out,span_out)
|
||||
*span_out = span;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
STATIC lset proc_inits(p,item,ini)
|
||||
proc_p p;
|
||||
item_p item;
|
||||
bblock_p ini;
|
||||
static lset proc_inits(proc_p p, item_p item, bblock_p ini)
|
||||
{
|
||||
lset s = Lempty_set();
|
||||
|
||||
@ -223,9 +195,7 @@ STATIC lset proc_inits(p,item,ini)
|
||||
}
|
||||
|
||||
|
||||
STATIC bool updates_needed(lp,item)
|
||||
loop_p lp;
|
||||
item_p item;
|
||||
static bool updates_needed(loop_p lp, item_p item)
|
||||
{
|
||||
/* See if the value of item is live after the loop has
|
||||
* been exited, i.e. must the item be updated after the loop?
|
||||
@ -250,9 +220,7 @@ STATIC bool updates_needed(lp,item)
|
||||
|
||||
|
||||
|
||||
STATIC short countuses(usage,b)
|
||||
lset usage;
|
||||
bblock_p b;
|
||||
static short countuses(lset usage, bblock_p b)
|
||||
{
|
||||
short cnt = 0;
|
||||
Lindex ti;
|
||||
@ -267,14 +235,9 @@ STATIC short countuses(usage,b)
|
||||
|
||||
|
||||
|
||||
STATIC allocs_of_item(p,item,loops,sloopcnt,dloopcnt,alloc_list_p)
|
||||
proc_p p;
|
||||
item_p item;
|
||||
lset loops;
|
||||
short *sloopcnt,*dloopcnt; /* dynamic arrays */
|
||||
alloc_p *alloc_list_p;
|
||||
static void allocs_of_item(proc_p p, item_p item, lset loops, short *sloopcnt, short *dloopcnt, alloc_p *alloc_list_p)
|
||||
{
|
||||
register Lindex li;
|
||||
Lindex li;
|
||||
loop_p lp;
|
||||
bblock_p header,ini;
|
||||
short susecount,dusecount;
|
||||
@ -328,13 +291,10 @@ STATIC allocs_of_item(p,item,loops,sloopcnt,dloopcnt,alloc_list_p)
|
||||
|
||||
|
||||
|
||||
alloc_p build_alloc_list(p,nrloops,itemlist)
|
||||
proc_p p;
|
||||
short nrloops;
|
||||
item_p itemlist;
|
||||
alloc_p build_alloc_list(proc_p p, short nrloops, item_p itemlist)
|
||||
{
|
||||
short *sloopcnt,*dloopcnt; /* dynamic arrays */
|
||||
register item_p item;
|
||||
item_p item;
|
||||
alloc_p alloc_list = (alloc_p) 0;
|
||||
|
||||
sloopcnt = (short *) newtable(nrloops);
|
||||
@ -344,15 +304,14 @@ alloc_p build_alloc_list(p,nrloops,itemlist)
|
||||
allocs_of_item(p,item,p->p_loops,sloopcnt,dloopcnt,
|
||||
&alloc_list);
|
||||
}
|
||||
oldtable(sloopcnt,nrloops);
|
||||
oldtable(dloopcnt,nrloops);
|
||||
oldtable((short **)sloopcnt,nrloops);
|
||||
oldtable((short **)dloopcnt,nrloops);
|
||||
return alloc_list;
|
||||
}
|
||||
|
||||
|
||||
|
||||
build_rivals_graph(alloclist)
|
||||
alloc_p alloclist;
|
||||
void build_rivals_graph(alloc_p alloclist)
|
||||
{
|
||||
/* See which allocations in the list are rivals of each other,
|
||||
* i.e. there is some point of time, falling in both
|
||||
@ -364,7 +323,7 @@ build_rivals_graph(alloclist)
|
||||
* allocation.
|
||||
*/
|
||||
|
||||
register alloc_p alloc,x;
|
||||
alloc_p alloc,x;
|
||||
|
||||
for (alloc = alloclist; alloc != (alloc_p) 0; alloc = alloc->al_next) {
|
||||
alloc->al_rivals = Cempty_set(alloc_id);
|
||||
|
||||
@ -9,13 +9,13 @@
|
||||
* R A _ A L L O C L I S T . H
|
||||
*/
|
||||
|
||||
extern alloc_p build_alloc_list(); /* (proc_p p; short nrloops;*/
|
||||
alloc_p build_alloc_list(proc_p p, short nrloops, item_p itemlist);
|
||||
/* item_p itemlist)
|
||||
* Build a list of possible allocations
|
||||
* for procedure p. An allocation
|
||||
* essentially is a pair (item,timespan)
|
||||
*/
|
||||
extern build_rivals_graph(); /* (alloc_p alloclist)*/
|
||||
void build_rivals_graph(alloc_p alloclist);
|
||||
/* See which allocations in the list are
|
||||
* rivals of each other, i.e. there is
|
||||
* some point of time, falling in both
|
||||
|
||||
@ -18,8 +18,7 @@
|
||||
#include "ra.h"
|
||||
#include "ra_interv.h"
|
||||
|
||||
interv_p cons_interval(t_start,t_stop)
|
||||
short t_start,t_stop;
|
||||
interv_p cons_interval(short t_start, short t_stop)
|
||||
{
|
||||
interv_p x;
|
||||
|
||||
@ -31,9 +30,7 @@ interv_p cons_interval(t_start,t_stop)
|
||||
|
||||
|
||||
|
||||
add_interval(t1,t2,list)
|
||||
short t1,t2;
|
||||
interv_p *list;
|
||||
void add_interval(short t1, short t2, interv_p *list)
|
||||
{
|
||||
/* Add interval (t1,t2) to the list of intervals (which is
|
||||
* an in-out parameter!). The list is sorted in 'chronological'
|
||||
@ -41,7 +38,7 @@ add_interval(t1,t2,list)
|
||||
* putting adjacent intervals in one interval.
|
||||
*/
|
||||
|
||||
register interv_p x1, x2, *q;
|
||||
interv_p x1, x2, *q;
|
||||
int adjacent = 0;
|
||||
interv_p x;
|
||||
|
||||
@ -82,16 +79,15 @@ add_interval(t1,t2,list)
|
||||
|
||||
|
||||
|
||||
interv_p loop_lifetime(lp)
|
||||
loop_p lp;
|
||||
interv_p loop_lifetime(loop_p lp)
|
||||
{
|
||||
/* Determine the timespan of the loop, expressed as a list
|
||||
* of intervals.
|
||||
*/
|
||||
|
||||
interv_p lt = 0;
|
||||
register bblock_p b;
|
||||
register Lindex bi;
|
||||
bblock_p b;
|
||||
Lindex bi;
|
||||
|
||||
for (bi = Lfirst(lp->LP_BLOCKS); bi != (Lindex) 0;
|
||||
bi = Lnext(bi,lp->LP_BLOCKS)) {
|
||||
@ -102,12 +98,11 @@ interv_p loop_lifetime(lp)
|
||||
}
|
||||
|
||||
|
||||
interv_p proc_lifetime(p)
|
||||
proc_p p;
|
||||
interv_p proc_lifetime(proc_p p)
|
||||
{
|
||||
/* Determine the lifetime of an entire procedure */
|
||||
|
||||
register bblock_p b;
|
||||
bblock_p b;
|
||||
|
||||
for (b = p->p_start; b->b_next != (bblock_p) 0; b = b->b_next) ;
|
||||
return cons_interval(0,b->B_END);
|
||||
@ -115,8 +110,7 @@ interv_p proc_lifetime(p)
|
||||
|
||||
|
||||
|
||||
STATIC set_min_max(iv1,iv2)
|
||||
interv_p *iv1,*iv2;
|
||||
static void set_min_max(interv_p *iv1, interv_p *iv2)
|
||||
{
|
||||
/* Auxiliary routine of intersect */
|
||||
|
||||
@ -133,8 +127,7 @@ STATIC set_min_max(iv1,iv2)
|
||||
|
||||
|
||||
|
||||
interv_p intersect(list1,list2)
|
||||
interv_p list1,list2;
|
||||
interv_p intersect(interv_p list1, interv_p list2)
|
||||
{
|
||||
/* Intersect two lifetimes, each denoted by a list of intervals.
|
||||
* We maintain two pointers, pmin and pmax, pointing to the
|
||||
@ -177,8 +170,7 @@ interv_p intersect(list1,list2)
|
||||
|
||||
|
||||
|
||||
bool not_disjoint(list1,list2)
|
||||
interv_p list1,list2;
|
||||
bool not_disjoint(interv_p list1, interv_p list2)
|
||||
{
|
||||
/* See if list1 and list2 do overlap somewhere */
|
||||
|
||||
@ -200,11 +192,9 @@ bool not_disjoint(list1,list2)
|
||||
|
||||
|
||||
|
||||
bool contains(t,timespan)
|
||||
short t;
|
||||
interv_p timespan;
|
||||
bool contains(short t, interv_p timespan)
|
||||
{
|
||||
register interv_p iv;
|
||||
interv_p iv;
|
||||
|
||||
for (iv = timespan; iv != (interv_p) 0; iv = iv->i_next) {
|
||||
if (t <= iv->i_stop) return (t >= iv->i_start);
|
||||
@ -214,8 +204,7 @@ bool contains(t,timespan)
|
||||
|
||||
|
||||
|
||||
interv_p copy_timespan(list)
|
||||
interv_p list;
|
||||
interv_p copy_timespan(interv_p list)
|
||||
{
|
||||
/* copy the time span */
|
||||
|
||||
|
||||
@ -10,31 +10,31 @@
|
||||
*/
|
||||
|
||||
|
||||
extern interv_p cons_interval();/* (short t_start,t_stop)
|
||||
* construct an interval
|
||||
interv_p cons_interval(short t_start, short t_stop);
|
||||
/* construct an interval
|
||||
*/
|
||||
extern add_interval(); /* (short t1,t2; interv_p *list)
|
||||
* Add interval (t1,t2) to the list of
|
||||
void add_interval(short t1, short t2, interv_p *list);
|
||||
/* Add interval (t1,t2) to the list of
|
||||
* intervals (which is an in-out parameter!).
|
||||
*/
|
||||
extern interv_p loop_lifetime();/* (loop_p lp)
|
||||
* Determine the timespan of the loop,
|
||||
interv_p loop_lifetime(loop_p lp);
|
||||
/* Determine the timespan of the loop,
|
||||
* expressed as a list of intervals.
|
||||
*/
|
||||
extern interv_p proc_lifetime();/* (proc_p p)
|
||||
* Determine the timespan of a procedure,
|
||||
interv_p proc_lifetime(proc_p p);
|
||||
/* Determine the timespan of a procedure,
|
||||
* expressed as an interval.
|
||||
*/
|
||||
extern interv_p intersect(); /* (interv_p list1,list2)
|
||||
* Intersect two lifetimes, each denoted
|
||||
interv_p intersect(interv_p list1, interv_p list2);
|
||||
/* Intersect two lifetimes, each denoted
|
||||
* by a list of intervals.
|
||||
*/
|
||||
extern bool not_disjoint(); /* (interv_p list1,list2)
|
||||
* See if list1 and list2 do overlap somewhere.
|
||||
bool not_disjoint(interv_p list1, interv_p list2);
|
||||
/* See if list1 and list2 do overlap somewhere.
|
||||
*/
|
||||
extern bool contains(); /* (short t;interv_p timespan)
|
||||
* See if t is part of the timespan.
|
||||
bool contains(short t, interv_p timespan);
|
||||
/* See if t is part of the timespan.
|
||||
*/
|
||||
extern interv_p copy_timespan();/* (interv_p list)
|
||||
* Make a copy of the timespan.
|
||||
interv_p copy_timespan(interv_p list);
|
||||
/* Make a copy of the timespan.
|
||||
*/
|
||||
|
||||
@ -33,8 +33,7 @@
|
||||
/* prevent small constants from being put in a register */
|
||||
|
||||
|
||||
clean_tab(items)
|
||||
item_p items[];
|
||||
static void clean_tab(item_p items[])
|
||||
{
|
||||
int t;
|
||||
|
||||
@ -46,8 +45,7 @@ clean_tab(items)
|
||||
|
||||
|
||||
|
||||
short item_type(l)
|
||||
line_p l;
|
||||
short item_type(line_p l)
|
||||
{
|
||||
int instr = INSTR(l);
|
||||
int t;
|
||||
@ -60,18 +58,15 @@ short item_type(l)
|
||||
|
||||
|
||||
|
||||
bool is_item(l)
|
||||
line_p l;
|
||||
bool is_item(line_p l)
|
||||
{
|
||||
return item_type(l) != NO_ITEM;
|
||||
}
|
||||
|
||||
|
||||
item_p item_of(off,items)
|
||||
offset off;
|
||||
item_p items[];
|
||||
item_p item_of(offset off, item_p items[])
|
||||
{
|
||||
register item_p x;
|
||||
item_p x;
|
||||
|
||||
for (x = items[LOCALVAR]; x != (item_p) 0; x = x->it_next) {
|
||||
if (off == x->i_t.it_off) {
|
||||
@ -85,9 +80,7 @@ item_p item_of(off,items)
|
||||
|
||||
|
||||
|
||||
fill_item(item,l)
|
||||
item_p item;
|
||||
line_p l;
|
||||
void fill_item(item_p item, line_p l)
|
||||
{
|
||||
item->it_type = item_type(l);
|
||||
item->it_desirable = TRUE;
|
||||
@ -105,8 +98,7 @@ fill_item(item,l)
|
||||
|
||||
|
||||
|
||||
STATIC bool desirable(l)
|
||||
line_p l;
|
||||
static bool desirable(line_p l)
|
||||
{
|
||||
/* See if it is really desirable to put the item of line l
|
||||
* in a register. We do not put an item in a register if it
|
||||
@ -127,8 +119,7 @@ STATIC bool desirable(l)
|
||||
|
||||
|
||||
|
||||
STATIC int cmp_items(a,b)
|
||||
item_p a,b;
|
||||
static int cmp_items(item_p a, item_p b)
|
||||
{
|
||||
/* This routine defines the <, = and > relations between items,
|
||||
* used to sort them for fast lookup.
|
||||
@ -156,15 +147,13 @@ STATIC int cmp_items(a,b)
|
||||
|
||||
|
||||
|
||||
bool same_item(a,b)
|
||||
item_p a,b;
|
||||
bool same_item(item_p a, item_p b)
|
||||
{
|
||||
return cmp_items(a,b) == 0;
|
||||
}
|
||||
|
||||
|
||||
STATIC bool lt_item(a,b)
|
||||
item_p a,b;
|
||||
static bool lt_item(item_p a, item_p b)
|
||||
{
|
||||
return cmp_items(a,b) == -1;
|
||||
}
|
||||
@ -191,8 +180,7 @@ static item_p items[NRITEMTYPES]; /* items[i] points to the list of type i */
|
||||
|
||||
|
||||
|
||||
STATIC short reg_type(item)
|
||||
item_p item;
|
||||
static short reg_type(item_p item)
|
||||
{
|
||||
/* See which type of register the item should best be assigned to */
|
||||
|
||||
@ -210,12 +198,12 @@ STATIC short reg_type(item)
|
||||
default: assert(FALSE);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
STATIC short item_size(item)
|
||||
item_p item;
|
||||
static short item_size(item_p item)
|
||||
{
|
||||
/* Determine the size of the item (in bytes) */
|
||||
|
||||
@ -234,12 +222,12 @@ STATIC short item_size(item)
|
||||
default: assert(FALSE);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
STATIC init_item(a,b)
|
||||
item_p a,b;
|
||||
static void init_item(item_p a, item_p b)
|
||||
{
|
||||
a->it_type = b->it_type;
|
||||
switch(a->it_type) {
|
||||
@ -260,16 +248,12 @@ STATIC init_item(a,b)
|
||||
|
||||
|
||||
|
||||
STATIC add_item(item,t,items)
|
||||
item_p item;
|
||||
time_p t;
|
||||
item_p items[];
|
||||
static void add_item(item_p item, time_p t, item_p items[])
|
||||
{
|
||||
/* See if there was already a list element for item. In any
|
||||
* case record the fact that item is used at 't'.
|
||||
*/
|
||||
|
||||
register item_p x, *q;
|
||||
item_p x, *q;
|
||||
|
||||
q = &items[item->it_type]; /* each type has its own list */
|
||||
for (x = *q; x != (item_p) 0; x = *q) {
|
||||
@ -296,10 +280,7 @@ STATIC add_item(item,t,items)
|
||||
|
||||
|
||||
|
||||
STATIC add_usage(l,b,items)
|
||||
line_p l;
|
||||
bblock_p b;
|
||||
item_p items[];
|
||||
static void add_usage(line_p l, bblock_p b, item_p items[])
|
||||
{
|
||||
/* An item is used at line l. Add it to the list of items.
|
||||
* A local variable is only considered to be an item, if
|
||||
@ -323,10 +304,7 @@ STATIC add_usage(l,b,items)
|
||||
|
||||
|
||||
|
||||
build_itemlist(p,items,nrinstr_out)
|
||||
proc_p p;
|
||||
item_p items[];
|
||||
int *nrinstr_out;
|
||||
void build_itemlist(proc_p p, item_p items[], int *nrinstr_out)
|
||||
{
|
||||
/* Make a list of all items used in procedure p.
|
||||
* An item is anything that can be put in a register,
|
||||
|
||||
@ -8,27 +8,27 @@
|
||||
* R A _ I T E M S . H
|
||||
*/
|
||||
|
||||
extern short item_type(); /* (line_p l)
|
||||
* Determine the type of item (constant,local
|
||||
short item_type(line_p l);
|
||||
/* Determine the type of item (constant,local
|
||||
* variable etc.) accessed by l.
|
||||
*/
|
||||
extern bool is_item(); /* (line_p l)
|
||||
* See if l accesses an item
|
||||
bool is_item(line_p l);
|
||||
/* See if l accesses an item
|
||||
*/
|
||||
extern item_p item_of(); /* (offset off;item_p items)
|
||||
* Determine the descriptor of the item
|
||||
item_p item_of(offset off, item_p items[]);
|
||||
/* Determine the descriptor of the item
|
||||
* accessed by l; return 0 if not found
|
||||
*/
|
||||
extern fill_item(); /* (item_p item;line_p l)
|
||||
* Compute the type and obj/off attributes
|
||||
void fill_item(item_p item, line_p l);
|
||||
/* Compute the type and obj/off attributes
|
||||
* of the item accessed by l and put them
|
||||
* in the given item descriptor.
|
||||
*/
|
||||
extern bool same_item(); /* (item_p a,b)
|
||||
* See if a and b are the same items.
|
||||
bool same_item(item_p a, item_p b);
|
||||
/* See if a and b are the same items.
|
||||
*/
|
||||
extern build_itemlist(); /* (proc_p p;item_p items[]; int *nrinstr_out)
|
||||
* Determine all items accessed by procedure p
|
||||
void build_itemlist(proc_p p, item_p items[], int *nrinstr_out);
|
||||
/* Determine all items accessed by procedure p
|
||||
* and put them in the items lists. All items
|
||||
* of type T must be put in list items[T].
|
||||
* Also determine the number of instructions
|
||||
|
||||
@ -33,8 +33,7 @@
|
||||
#define is_deadmsg(l) (INSTR(l) == ps_mes && aoff(ARG(l),0) == ms_ego && \
|
||||
aoff(ARG(l),1) == ego_dead)
|
||||
|
||||
build_lifetimes(items)
|
||||
item_p items[];
|
||||
void build_lifetimes(item_p items[])
|
||||
{
|
||||
/* compute the it_lives attribute of every item; this is
|
||||
* a list of intervals during which the item is live,
|
||||
@ -52,8 +51,8 @@ build_lifetimes(items)
|
||||
* dead-message that is not a live -or dead message.
|
||||
*/
|
||||
|
||||
register line_p l;
|
||||
register short now;
|
||||
line_p l;
|
||||
short now;
|
||||
item_p item;
|
||||
short last_code;
|
||||
|
||||
|
||||
@ -9,8 +9,8 @@
|
||||
*/
|
||||
|
||||
|
||||
extern build_lifetimes(); /* item_p items[];
|
||||
* compute the it_lives attribute of every
|
||||
void build_lifetimes(item_p items[]);
|
||||
/* compute the it_lives attribute of every
|
||||
* item; this is a list of intervals
|
||||
* during which the item is live,
|
||||
* i.e. its current value may be used.
|
||||
|
||||
@ -27,7 +27,7 @@ short regs_occupied[NRREGTYPES]; /* #occupied registers for reg_pointer,
|
||||
*/
|
||||
#define reg_available(t) (regs_available[t] > regs_occupied[t])
|
||||
|
||||
STATIC initregcount()
|
||||
static void initregcount()
|
||||
{
|
||||
int t;
|
||||
|
||||
@ -36,7 +36,7 @@ STATIC initregcount()
|
||||
}
|
||||
}
|
||||
|
||||
STATIC alloc_p make_dummy()
|
||||
static alloc_p make_dummy()
|
||||
{
|
||||
alloc_p x;
|
||||
|
||||
@ -46,9 +46,7 @@ STATIC alloc_p make_dummy()
|
||||
}
|
||||
|
||||
|
||||
STATIC bool fits_in(a,b,cont_item)
|
||||
alloc_p a,b;
|
||||
bool *cont_item;
|
||||
static bool fits_in(alloc_p a, alloc_p b, bool *cont_item)
|
||||
{
|
||||
/* See if allocation a can be assigned the same register as b.
|
||||
* Both allocations should be of the same register-type.
|
||||
@ -72,15 +70,14 @@ STATIC bool fits_in(a,b,cont_item)
|
||||
}
|
||||
|
||||
|
||||
STATIC alloc_p find_fitting_alloc(alloc,packed)
|
||||
alloc_p alloc,packed;
|
||||
static alloc_p find_fitting_alloc(alloc_p alloc, alloc_p packed)
|
||||
{
|
||||
/* Try to find and already packed allocation that is assigned
|
||||
* a register that may also be used for alloc.
|
||||
* We prefer allocations that have the same item as alloc.
|
||||
*/
|
||||
|
||||
register alloc_p x;
|
||||
alloc_p x;
|
||||
alloc_p cand = (alloc_p) 0;
|
||||
bool cont_item;
|
||||
|
||||
@ -94,8 +91,7 @@ STATIC alloc_p find_fitting_alloc(alloc,packed)
|
||||
}
|
||||
|
||||
|
||||
STATIC bool room_for(alloc,packed)
|
||||
alloc_p alloc,packed;
|
||||
static bool room_for(alloc_p alloc, alloc_p packed)
|
||||
{
|
||||
/* See if there is any register available for alloc */
|
||||
|
||||
@ -105,13 +101,11 @@ STATIC bool room_for(alloc,packed)
|
||||
|
||||
|
||||
|
||||
STATIC alloc_p best_alloc(unpacked,packed,time_opt)
|
||||
alloc_p unpacked,packed;
|
||||
bool time_opt; /* now unused */
|
||||
static alloc_p best_alloc(alloc_p unpacked, alloc_p packed, bool time_opt)
|
||||
{
|
||||
/* Find the next best candidate */
|
||||
|
||||
register alloc_p x,best;
|
||||
alloc_p x,best;
|
||||
|
||||
best = unpacked; /* dummy */
|
||||
|
||||
@ -127,9 +121,7 @@ STATIC alloc_p best_alloc(unpacked,packed,time_opt)
|
||||
|
||||
|
||||
|
||||
STATIC alloc_p choose_location(alloc,packed,p)
|
||||
alloc_p alloc,packed;
|
||||
proc_p p;
|
||||
static alloc_p choose_location(alloc_p alloc, alloc_p packed, proc_p p)
|
||||
{
|
||||
/* Decide in which register to put alloc */
|
||||
|
||||
@ -151,8 +143,7 @@ STATIC alloc_p choose_location(alloc,packed,p)
|
||||
|
||||
|
||||
|
||||
STATIC update_lists(alloc,unpacked,packed,fit)
|
||||
alloc_p alloc,unpacked,packed,fit;
|
||||
static void update_lists(alloc_p alloc, alloc_p unpacked, alloc_p packed, alloc_p fit)
|
||||
{
|
||||
/* 'alloc' has been granted a register; move it from the 'unpacked'
|
||||
* list to the 'packed' list. Also remove any allocation from 'unpacked'
|
||||
@ -161,7 +152,7 @@ STATIC update_lists(alloc,unpacked,packed,fit)
|
||||
* 2. a timespan that overlaps the timespan of alloc.
|
||||
*/
|
||||
|
||||
register alloc_p x,q,next;
|
||||
alloc_p x,q,next;
|
||||
|
||||
q = unpacked; /* dummy element at head of list */
|
||||
for (x = unpacked->al_next; x != (alloc_p) 0; x = next) {
|
||||
@ -191,8 +182,7 @@ STATIC update_lists(alloc,unpacked,packed,fit)
|
||||
|
||||
|
||||
|
||||
STATIC short cum_profits(alloc)
|
||||
alloc_p alloc;
|
||||
static short cum_profits(alloc_p alloc)
|
||||
{
|
||||
/* Add the profits of all allocations packed in the same
|
||||
* register as alloc (i.e. alloc and all its 'mates').
|
||||
@ -209,12 +199,11 @@ STATIC short cum_profits(alloc)
|
||||
|
||||
|
||||
|
||||
STATIC alloc_p best_cumprofits(list,x_out,prev_out)
|
||||
alloc_p list, *x_out, *prev_out;
|
||||
static void best_cumprofits(alloc_p list, alloc_p *x_out, alloc_p *prev_out)
|
||||
{
|
||||
/* Find the allocation with the best cummulative profits */
|
||||
|
||||
register alloc_p x,prev,best_prev;
|
||||
alloc_p x,prev,best_prev;
|
||||
short best = 0, cum;
|
||||
|
||||
prev = list;
|
||||
@ -232,12 +221,12 @@ STATIC alloc_p best_cumprofits(list,x_out,prev_out)
|
||||
*x_out = best_prev->al_next;
|
||||
*prev_out = best_prev;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
STATIC account_regsave(packed,unpacked)
|
||||
alloc_p packed,unpacked;
|
||||
static void account_regsave(alloc_p packed, alloc_p unpacked)
|
||||
{
|
||||
/* After all packing has been done, we check for every allocated
|
||||
* register whether it is really advantageous to use this
|
||||
@ -283,15 +272,13 @@ STATIC account_regsave(packed,unpacked)
|
||||
|
||||
|
||||
|
||||
STATIC bool in_single_reg(item,packed)
|
||||
item_p item;
|
||||
alloc_p packed;
|
||||
static bool in_single_reg(item_p item, alloc_p packed)
|
||||
{
|
||||
/* See if item is allocated in only one register (i.e. not in
|
||||
* several different registers during several parts of its lifetime.
|
||||
*/
|
||||
|
||||
register alloc_p x,m;
|
||||
alloc_p x,m;
|
||||
bool seen = FALSE;
|
||||
|
||||
for (x = packed->al_next; x != (alloc_p) 0; x = x->al_next) {
|
||||
@ -308,10 +295,9 @@ STATIC bool in_single_reg(item,packed)
|
||||
|
||||
|
||||
|
||||
STATIC alloc_p find_prev(alloc,list)
|
||||
alloc_p alloc,list;
|
||||
static alloc_p find_prev(alloc_p alloc, alloc_p list)
|
||||
{
|
||||
register alloc_p x;
|
||||
alloc_p x;
|
||||
|
||||
assert ( alloc != (alloc_p) 0);
|
||||
for (x = list; x->al_next != alloc ; x = x->al_next)
|
||||
@ -326,8 +312,7 @@ STATIC alloc_p find_prev(alloc,list)
|
||||
* account_regsave from rejecting it.
|
||||
*/
|
||||
|
||||
STATIC repl_allocs(new,old,packed)
|
||||
alloc_p new,old,packed;
|
||||
static void repl_allocs(alloc_p new, alloc_p old, alloc_p packed)
|
||||
{
|
||||
alloc_p x,next,prev,*p;
|
||||
short prof = 0;
|
||||
@ -355,10 +340,9 @@ STATIC repl_allocs(new,old,packed)
|
||||
|
||||
|
||||
|
||||
STATIC assemble_allocs(packed)
|
||||
alloc_p packed;
|
||||
static void assemble_allocs(alloc_p packed)
|
||||
{
|
||||
register alloc_p x,m,next;
|
||||
alloc_p x,m,next;
|
||||
alloc_p e;
|
||||
bool voidb;
|
||||
|
||||
@ -376,10 +360,7 @@ STATIC assemble_allocs(packed)
|
||||
}
|
||||
}
|
||||
|
||||
pack(alloclist,time_opt,packed_out,not_packed_out,p)
|
||||
alloc_p alloclist, *packed_out,*not_packed_out;
|
||||
bool time_opt;
|
||||
proc_p p;
|
||||
void pack(alloc_p alloclist, bool time_opt, alloc_p *packed_out, alloc_p *not_packed_out, proc_p p)
|
||||
{
|
||||
/* This is the packing system. It decides which allations
|
||||
* to grant a register.
|
||||
@ -391,7 +372,7 @@ pack(alloclist,time_opt,packed_out,not_packed_out,p)
|
||||
* the same registers (i.e. these allocations fit together).
|
||||
*/
|
||||
|
||||
register alloc_p x;
|
||||
alloc_p x;
|
||||
alloc_p packed,unpacked,fit;
|
||||
|
||||
initregcount();
|
||||
|
||||
@ -9,8 +9,7 @@
|
||||
* R A _ P A C K . H
|
||||
*/
|
||||
|
||||
extern pack(); /* ( alloc_p alloclist, *packed_out,*not_packed_out;
|
||||
* bool time_opt; proc_p p)
|
||||
* This is the packing system. It decides which
|
||||
void pack(alloc_p alloclist, bool time_opt, alloc_p *packed_out, alloc_p *not_packed_out, proc_p p);
|
||||
/* This is the packing system. It decides which
|
||||
* allations to grant a register.
|
||||
*/
|
||||
|
||||
@ -18,9 +18,7 @@
|
||||
#include "ra_aux.h"
|
||||
#include "ra_profits.h"
|
||||
|
||||
STATIC bool test_cond(cond,val)
|
||||
short cond;
|
||||
offset val;
|
||||
static bool test_cond(short cond, offset val)
|
||||
{
|
||||
switch(cond) {
|
||||
case DEFAULT:
|
||||
@ -32,12 +30,10 @@ STATIC bool test_cond(cond,val)
|
||||
case IN_0_8:
|
||||
return val >= 0 && val <= 8;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
STATIC short map_value(tab,val,time)
|
||||
struct cond_tab tab[];
|
||||
offset val;
|
||||
bool time;
|
||||
static short map_value(struct cond_tab tab[], offset val, bool time)
|
||||
{
|
||||
cond_p p;
|
||||
|
||||
@ -46,13 +42,11 @@ STATIC short map_value(tab,val,time)
|
||||
return (time ? p->mc_tval : p->mc_sval);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
STATIC short index_value(tab,n,time)
|
||||
struct cond_tab tab[];
|
||||
short n;
|
||||
bool time;
|
||||
static short index_value(struct cond_tab tab[], short n, bool time)
|
||||
{
|
||||
cond_p p;
|
||||
|
||||
@ -61,15 +55,13 @@ STATIC short index_value(tab,n,time)
|
||||
}
|
||||
|
||||
|
||||
allocscore(itemtyp,localtyp,size,off,totyp,time_out,space_out)
|
||||
short itemtyp, localtyp,totyp,size;
|
||||
offset off;
|
||||
short *time_out, *space_out;
|
||||
static void allocscore(short itemtyp, short localtyp, short size, offset off, short totyp,
|
||||
short *time_out, short *space_out)
|
||||
{
|
||||
cond_p m = (cond_p) 0;
|
||||
|
||||
if (localtyp == reg_loop) localtyp = reg_any;
|
||||
if (size == ws || size ==ps && totyp == reg_pointer) {
|
||||
if ( ( (size == ws) || (size ==ps) ) && (totyp == reg_pointer) ) {
|
||||
switch(itemtyp) {
|
||||
case LOCALVAR:
|
||||
m = alocaltab[localtyp][totyp];
|
||||
@ -102,10 +94,8 @@ allocscore(itemtyp,localtyp,size,off,totyp,time_out,space_out)
|
||||
*/
|
||||
}
|
||||
|
||||
opening_cost(itemtyp,localtyp,off,time_out,space_out)
|
||||
short itemtyp, localtyp;
|
||||
offset off;
|
||||
short *time_out, *space_out;
|
||||
static void opening_cost(short itemtyp, short localtyp, offset off,
|
||||
short *time_out, short *space_out)
|
||||
{
|
||||
cond_p m;
|
||||
|
||||
@ -138,11 +128,7 @@ opening_cost(itemtyp,localtyp,off,time_out,space_out)
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
regsave_cost(regs,time_out,space_out)
|
||||
short regs[], *time_out, *space_out;
|
||||
void regsave_cost(short regs[], short *time_out, short *space_out)
|
||||
{
|
||||
/* Estimate the costs of saving and restoring the registers
|
||||
* The array regs contains the number of registers of every
|
||||
@ -161,8 +147,7 @@ regsave_cost(regs,time_out,space_out)
|
||||
|
||||
|
||||
|
||||
STATIC short dyn_inits(inits)
|
||||
lset inits;
|
||||
static short dyn_inits(lset inits)
|
||||
{
|
||||
Lindex i;
|
||||
short sum = 0;
|
||||
@ -177,16 +162,14 @@ STATIC short dyn_inits(inits)
|
||||
|
||||
|
||||
|
||||
compute_profits(alloclist,time_opt)
|
||||
alloc_p alloclist;
|
||||
bool time_opt;
|
||||
void compute_profits(alloc_p alloclist, bool time_opt)
|
||||
{
|
||||
/* Compute the profits attribute of every allocation.
|
||||
* If the item of an allocation may be put in several types
|
||||
* of register, we choose only the most advanteagous one.
|
||||
*/
|
||||
|
||||
register alloc_p alloc;
|
||||
alloc_p alloc;
|
||||
short s,t,rtyp,maxsc;
|
||||
item_p item;
|
||||
short time,space,sc;
|
||||
|
||||
@ -9,8 +9,7 @@
|
||||
* R A _ P R O F I T S . H
|
||||
*/
|
||||
|
||||
extern compute_profits();/* (alloc_p alloclist)
|
||||
* Compute the profits attribute of every allocation.
|
||||
*/
|
||||
extern regsave_cost(); /* (short regs[], *time_out, *space_out)
|
||||
void compute_profits(alloc_p alloclist, bool time_opt);
|
||||
/* Compute the profits attribute of every allocation.
|
||||
*/
|
||||
void regsave_cost(short regs[], short *time_out, short *space_out);
|
||||
|
||||
@ -77,8 +77,7 @@ struct repl repl_tab[NRREPLACEMENTS][REPL_LENGTH] = {
|
||||
|
||||
|
||||
|
||||
init_replacements(psize,wsize)
|
||||
short psize,wsize;
|
||||
void init_replacements(short psize, short wsize)
|
||||
{
|
||||
/* The replacement code to be generated depends on the
|
||||
* wordsize and pointer size of the target machine.
|
||||
@ -88,7 +87,7 @@ init_replacements(psize,wsize)
|
||||
* as a 'Load pointer' instruction.
|
||||
*/
|
||||
|
||||
register int i,j;
|
||||
int i,j;
|
||||
short load_pointer;
|
||||
struct repl *r;
|
||||
|
||||
@ -129,27 +128,21 @@ init_replacements(psize,wsize)
|
||||
|
||||
|
||||
|
||||
STATIC int repl_index(l)
|
||||
line_p l;
|
||||
static int repl_index(line_p l)
|
||||
{
|
||||
return itemtab[INSTR(l) - sp_fmnem].id_replindex;
|
||||
}
|
||||
|
||||
|
||||
|
||||
STATIC bool is_current(alloc,t)
|
||||
alloc_p alloc;
|
||||
short t;
|
||||
static bool is_current(alloc_p alloc, short t)
|
||||
{
|
||||
/* Is time t part of alloc's timespan? */
|
||||
|
||||
return contains(t,alloc->al_timespan);
|
||||
}
|
||||
|
||||
|
||||
STATIC match_item(item,l)
|
||||
item_p item;
|
||||
line_p l;
|
||||
static int match_item(item_p item, line_p l)
|
||||
{
|
||||
/* See if the item used by l is the same one as 'item' */
|
||||
struct item thisitem;
|
||||
@ -161,21 +154,17 @@ STATIC match_item(item,l)
|
||||
*/
|
||||
thisitem.it_type = LOCAL_ADDR;
|
||||
}
|
||||
return item->it_type == thisitem.it_type && same_item(item,&thisitem);
|
||||
return (item->it_type == thisitem.it_type) && same_item(item,&thisitem);
|
||||
}
|
||||
|
||||
|
||||
|
||||
STATIC alloc_p find_alloc(alloclist,l,t)
|
||||
alloc_p alloclist;
|
||||
line_p l;
|
||||
short t;
|
||||
static alloc_p find_alloc(alloc_p alloclist, line_p l, short t)
|
||||
{
|
||||
/* See if any of the allocations of the list applies to instruction
|
||||
* l at time t.
|
||||
*/
|
||||
|
||||
register alloc_p alloc,m;
|
||||
alloc_p alloc,m;
|
||||
|
||||
for (alloc = alloclist; alloc != (alloc_p) 0; alloc = alloc->al_next) {
|
||||
for (m = alloc; m != (alloc_p) 0; m = m->al_mates) {
|
||||
@ -188,9 +177,7 @@ STATIC alloc_p find_alloc(alloclist,l,t)
|
||||
}
|
||||
|
||||
|
||||
STATIC replace_line(l,b,list)
|
||||
line_p l,list;
|
||||
bblock_p b;
|
||||
static void replace_line(line_p l, bblock_p b, line_p list)
|
||||
{
|
||||
if (b->b_start == l) {
|
||||
b->b_start = list;
|
||||
@ -209,9 +196,7 @@ STATIC replace_line(l,b,list)
|
||||
}
|
||||
|
||||
|
||||
STATIC line_p repl_code(lnp,regnr)
|
||||
line_p lnp;
|
||||
offset regnr;
|
||||
static line_p repl_code(line_p lnp, offset regnr)
|
||||
{
|
||||
line_p head,*q,l,prev = (line_p) 0;
|
||||
int i,index;
|
||||
@ -245,10 +230,7 @@ STATIC line_p repl_code(lnp,regnr)
|
||||
|
||||
|
||||
|
||||
STATIC apply_alloc(b,l,alloc)
|
||||
bblock_p b;
|
||||
line_p l;
|
||||
alloc_p alloc;
|
||||
static void apply_alloc(bblock_p b, line_p l, alloc_p alloc)
|
||||
{
|
||||
/* 'l' is an EM instruction using an item that will be put in
|
||||
* a register. Generate new code that uses the register instead
|
||||
@ -284,7 +266,7 @@ STATIC apply_alloc(b,l,alloc)
|
||||
|
||||
|
||||
|
||||
STATIC int loaditem_tab[NRITEMTYPES][2] =
|
||||
static int loaditem_tab[NRITEMTYPES][2] =
|
||||
{ /* WS 2 * WS */
|
||||
/*LOCALVAR*/ op_lol, op_ldl,
|
||||
/*LOCAL_ADDR*/ op_lal, op_lal,
|
||||
@ -295,8 +277,7 @@ STATIC int loaditem_tab[NRITEMTYPES][2] =
|
||||
};
|
||||
|
||||
|
||||
STATIC line_p load_item(item)
|
||||
item_p item;
|
||||
static line_p load_item(item_p item)
|
||||
{
|
||||
/* Generate an EM instruction that loads the item on the stack */
|
||||
|
||||
@ -320,9 +301,7 @@ STATIC line_p load_item(item)
|
||||
}
|
||||
|
||||
|
||||
STATIC line_p store_local(size,off)
|
||||
short size;
|
||||
offset off;
|
||||
static line_p store_local(short size, offset off)
|
||||
{
|
||||
line_p l = int_line(off);
|
||||
|
||||
@ -332,11 +311,9 @@ STATIC line_p store_local(size,off)
|
||||
|
||||
|
||||
|
||||
STATIC line_p init_place(b)
|
||||
bblock_p b;
|
||||
static line_p init_place(bblock_p b)
|
||||
{
|
||||
|
||||
register line_p l,prev;
|
||||
line_p l,prev;
|
||||
|
||||
prev = (line_p) 0;
|
||||
for (l = b->b_start; l != (line_p) 0; l = l->l_next) {
|
||||
@ -355,12 +332,9 @@ STATIC line_p init_place(b)
|
||||
|
||||
|
||||
|
||||
STATIC append_code(l1,l2,b)
|
||||
line_p l1,l2;
|
||||
bblock_p b;
|
||||
static void append_code(line_p l1, line_p l2, bblock_p b)
|
||||
{
|
||||
/* Append instruction l1 and l2 at begin of block b */
|
||||
|
||||
line_p l;
|
||||
|
||||
DLINK(l1,l2);
|
||||
@ -380,15 +354,14 @@ STATIC append_code(l1,l2,b)
|
||||
|
||||
|
||||
|
||||
STATIC emit_init_code(list)
|
||||
alloc_p list;
|
||||
static void emit_init_code(alloc_p list)
|
||||
{
|
||||
/* Emit initialization code for all packed allocations.
|
||||
* This code looks like "dummy_local := item", e.g.
|
||||
* "LOC 25 ; STL -10" in EM terminology.
|
||||
*/
|
||||
|
||||
register alloc_p alloc,m;
|
||||
alloc_p alloc,m;
|
||||
Lindex bi;
|
||||
bblock_p b;
|
||||
|
||||
@ -409,9 +382,7 @@ STATIC emit_init_code(list)
|
||||
|
||||
|
||||
|
||||
STATIC emit_mesregs(p,alloclist)
|
||||
proc_p p;
|
||||
alloc_p alloclist;
|
||||
static void emit_mesregs(proc_p p, alloc_p alloclist)
|
||||
{
|
||||
line_p l,m,x;
|
||||
alloc_p alloc;
|
||||
@ -432,11 +403,10 @@ STATIC emit_mesregs(p,alloclist)
|
||||
|
||||
|
||||
|
||||
rem_mes(p)
|
||||
proc_p p;
|
||||
static void rem_mes(proc_p p)
|
||||
{
|
||||
register bblock_p b;
|
||||
register line_p l,next;
|
||||
bblock_p b;
|
||||
line_p l,next;
|
||||
offset m;
|
||||
|
||||
for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) {
|
||||
@ -455,19 +425,15 @@ rem_mes(p)
|
||||
|
||||
|
||||
|
||||
xform_proc(p,alloclist,nrinstrs,instrmap)
|
||||
proc_p p;
|
||||
alloc_p alloclist;
|
||||
short nrinstrs;
|
||||
line_p instrmap[];
|
||||
void xform_proc(proc_p p, alloc_p alloclist, short nrinstrs, line_p instrmap[])
|
||||
{
|
||||
/* Transform every instruction of procedure p that uses an item
|
||||
* at a point where the item is kept in a register.
|
||||
*/
|
||||
|
||||
register short now = 0;
|
||||
register line_p l,next;
|
||||
register bblock_p b;
|
||||
short now = 0;
|
||||
line_p l,next;
|
||||
bblock_p b;
|
||||
alloc_p alloc;
|
||||
|
||||
for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) {
|
||||
@ -498,10 +464,7 @@ xform_proc(p,alloclist,nrinstrs,instrmap)
|
||||
|
||||
|
||||
|
||||
bool always_in_reg(off,allocs,size_out)
|
||||
offset off;
|
||||
alloc_p allocs;
|
||||
short *size_out;
|
||||
bool always_in_reg(offset off, alloc_p allocs, short *size_out)
|
||||
{
|
||||
/* See if the local variable with the given offset is stored
|
||||
* in a register during its entire lifetime. As a side effect,
|
||||
@ -526,9 +489,7 @@ bool always_in_reg(off,allocs,size_out)
|
||||
}
|
||||
|
||||
|
||||
rem_locals(p,allocs)
|
||||
proc_p p;
|
||||
alloc_p allocs;
|
||||
void rem_locals(proc_p p, alloc_p allocs)
|
||||
{
|
||||
/* Try to decrease the number of locals of procedure p, by
|
||||
* looking at which locals are always stored in a register.
|
||||
@ -551,9 +512,8 @@ rem_locals(p,allocs)
|
||||
}
|
||||
p->p_localbytes = nrlocals;
|
||||
}
|
||||
rem_formals(p,allocs)
|
||||
proc_p p;
|
||||
alloc_p allocs;
|
||||
|
||||
void rem_formals(proc_p p, alloc_p allocs)
|
||||
{
|
||||
/* Try to decrease the number of formals of procedure p, by
|
||||
* looking at which formals are always stored in a register.
|
||||
|
||||
@ -9,21 +9,23 @@
|
||||
* R A _ X F O R M . H
|
||||
*/
|
||||
|
||||
extern init_replacements(); /* (short psize,wsize)
|
||||
* This routine must be called once, before
|
||||
void init_replacements(short psize, short wsize);
|
||||
/* This routine must be called once, before
|
||||
* any call to xform_proc. It initializes
|
||||
* a machine dependent table.
|
||||
*/
|
||||
extern xform_proc(); /* (proc_p p; alloc_p alloclist;
|
||||
* short nrinstrs; line_p instrmap[])
|
||||
* Transform a procedure. Alloclist must
|
||||
void xform_proc(proc_p p, alloc_p alloclist, short nrinstrs, line_p instrmap[]);
|
||||
/* Transform a procedure. Alloclist must
|
||||
* contain the packed allocations (i.e. those
|
||||
* allocations that are assigned a register).
|
||||
*/
|
||||
bool always_in_reg(); /* ( offset off; alloc_p allocs;
|
||||
* short *size_out;)
|
||||
* See if the local variable with the given
|
||||
bool always_in_reg(offset off, alloc_p allocs, short *size_out);
|
||||
/* See if the local variable with the given
|
||||
* offset is stored in a register during its
|
||||
* entire lifetime. As a side effect,
|
||||
* return the size of the local.
|
||||
*/
|
||||
|
||||
void rem_locals(proc_p p, alloc_p allocs);
|
||||
|
||||
void rem_formals(proc_p p, alloc_p allocs);
|
||||
@ -11,6 +11,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <em_mnem.h>
|
||||
#include <em_spec.h>
|
||||
#include "../share/types.h"
|
||||
@ -37,7 +38,7 @@
|
||||
#define NOT_MARKED(b) (!(b->b_flags&BF_MARK))
|
||||
#define IN_LOOP(b) (Lnrelems(b->b_loops) > 0)
|
||||
|
||||
STATIC int Ssp; /* number of optimizations */
|
||||
static int Ssp; /* number of optimizations */
|
||||
|
||||
/* According to the EM definition, the stack must be cleaned up
|
||||
* before any return. However, for some backends it causes no harm
|
||||
@ -45,17 +46,17 @@ STATIC int Ssp; /* number of optimizations */
|
||||
* more globally.
|
||||
*/
|
||||
|
||||
STATIC int globl_sp_allowed;
|
||||
static int globl_sp_allowed;
|
||||
|
||||
|
||||
#define IS_ASP(l) (INSTR(l) == op_asp && TYPE(l) == OPSHORT && SHORT(l) > 0)
|
||||
|
||||
|
||||
STATIC sp_machinit(f)
|
||||
FILE *f;
|
||||
static int sp_machinit(void *param)
|
||||
{
|
||||
/* Read target machine dependent information for this phase */
|
||||
char s[100];
|
||||
FILE *f = (FILE*)param;
|
||||
|
||||
for (;;) {
|
||||
while(getc(f) != '\n');
|
||||
@ -63,10 +64,11 @@ STATIC sp_machinit(f)
|
||||
if (strcmp(s,"%%SP") == 0)break;
|
||||
}
|
||||
fscanf(f,"%d",&globl_sp_allowed);
|
||||
|
||||
return 0;
|
||||
}
|
||||
comb_asps(l1,l2,b)
|
||||
line_p l1,l2;
|
||||
bblock_p b;
|
||||
|
||||
void comb_asps(line_p l1, line_p l2, bblock_p b)
|
||||
{
|
||||
assert(INSTR(l1) == op_asp);
|
||||
assert(INSTR(l2) == op_asp);
|
||||
@ -76,18 +78,17 @@ comb_asps(l1,l2,b)
|
||||
SHORT(l2) += SHORT(l1);
|
||||
rm_line(l1,b);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
stack_pollution(b)
|
||||
bblock_p b;
|
||||
|
||||
static void stack_pollution(bblock_p b)
|
||||
{
|
||||
/* For every pair of successive ASP instructions in basic
|
||||
* block b, try to combine the two into one ASP.
|
||||
*/
|
||||
|
||||
register line_p l;
|
||||
line_p l;
|
||||
line_p asp,next = b->b_start;
|
||||
bool asp_seen = FALSE;
|
||||
int stack_diff,pop,push;
|
||||
@ -133,11 +134,10 @@ stack_pollution(b)
|
||||
} while (asp != (line_p) 0);
|
||||
}
|
||||
|
||||
STATIC bool block_save(b)
|
||||
bblock_p b;
|
||||
static bool block_save(bblock_p b)
|
||||
{
|
||||
|
||||
register line_p l;
|
||||
line_p l;
|
||||
int stack_diff,pop,push;
|
||||
bool ok;
|
||||
|
||||
@ -160,8 +160,7 @@ STATIC bool block_save(b)
|
||||
|
||||
|
||||
|
||||
STATIC mark_pred(b)
|
||||
bblock_p b;
|
||||
static void mark_pred(bblock_p b)
|
||||
{
|
||||
Lindex i;
|
||||
bblock_p x;
|
||||
@ -179,10 +178,9 @@ STATIC mark_pred(b)
|
||||
|
||||
|
||||
|
||||
STATIC mark_unsave_blocks(p)
|
||||
proc_p p;
|
||||
static void mark_unsave_blocks(proc_p p)
|
||||
{
|
||||
register bblock_p b;
|
||||
bblock_p b;
|
||||
|
||||
for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) {
|
||||
if (NOT_MARKED(b) && !block_save(b)) {
|
||||
@ -193,24 +191,23 @@ STATIC mark_unsave_blocks(p)
|
||||
}
|
||||
|
||||
|
||||
sp_optimize(p)
|
||||
proc_p p;
|
||||
static int sp_optimize(void *param)
|
||||
{
|
||||
register bblock_p b;
|
||||
bblock_p b;
|
||||
proc_p p = (proc_p)param;
|
||||
|
||||
if (IS_ENTERED_WITH_GTO(p)) return;
|
||||
if (IS_ENTERED_WITH_GTO(p)) return 0;
|
||||
mark_unsave_blocks(p);
|
||||
for (b = p->p_start; b != 0; b = b->b_next) {
|
||||
stack_pollution(b);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
go(argc,argv,no_action,sp_optimize,sp_machinit,no_action);
|
||||
report("stack adjustments deleted",Ssp);
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "../share/types.h"
|
||||
#include "sr.h"
|
||||
#include "../share/debug.h"
|
||||
@ -51,12 +52,11 @@ int sli_threshold;
|
||||
|
||||
int Ssr; /* #optimizations found */
|
||||
|
||||
sr_machinit(f)
|
||||
FILE *f;
|
||||
static int sr_machinit(void *param)
|
||||
{
|
||||
/* Read target machine dependent information */
|
||||
char s[100];
|
||||
|
||||
FILE *f = (FILE*)param;
|
||||
|
||||
for (;;) {
|
||||
while(getc(f) != '\n');
|
||||
@ -66,10 +66,11 @@ sr_machinit(f)
|
||||
fscanf(f,"%d",&ovfl_harmful);
|
||||
fscanf(f,"%d",&arrbound_harmful);
|
||||
fscanf(f,"%d",&sli_threshold);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC del_ivs(ivs)
|
||||
lset ivs;
|
||||
static void del_ivs(lset ivs)
|
||||
{
|
||||
/* Delete the set of iv structs */
|
||||
|
||||
@ -82,8 +83,7 @@ STATIC del_ivs(ivs)
|
||||
}
|
||||
|
||||
|
||||
STATIC do_loop(loop)
|
||||
loop_p loop;
|
||||
static void do_loop(loop_p loop)
|
||||
{
|
||||
lset ivs, vars;
|
||||
|
||||
@ -110,13 +110,12 @@ STATIC do_loop(loop)
|
||||
|
||||
|
||||
|
||||
STATIC loopblocks(p)
|
||||
proc_p p;
|
||||
static void loopblocks(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;
|
||||
@ -128,8 +127,7 @@ STATIC loopblocks(p)
|
||||
|
||||
|
||||
|
||||
STATIC opt_proc(p)
|
||||
proc_p p;
|
||||
static void opt_proc(proc_p p)
|
||||
{
|
||||
/* Optimize all loops of one procedure. We first do all
|
||||
* outer loops at the lowest nesting level and proceed
|
||||
@ -160,8 +158,7 @@ STATIC opt_proc(p)
|
||||
|
||||
|
||||
|
||||
STATIC bblock_p header(lp)
|
||||
loop_p lp;
|
||||
static bblock_p header(loop_p lp)
|
||||
{
|
||||
/* Try to determine the 'header' block of loop lp.
|
||||
* If 'e' is the entry block of loop L, then block 'b' is
|
||||
@ -172,22 +169,21 @@ STATIC bblock_p header(lp)
|
||||
|
||||
bblock_p x = lp->lp_entry->b_idom;
|
||||
|
||||
if (x != (bblock_p) 0 && Lnrelems(x->b_succ) == 1 &&
|
||||
(bblock_p) Lelem(Lfirst(x->b_succ)) == lp->lp_entry) {
|
||||
if ( (x != NULL) && (Lnrelems(x->b_succ) == 1) &&
|
||||
((bblock_p) Lelem(Lfirst(x->b_succ)) == lp->lp_entry) ) {
|
||||
return x;
|
||||
}
|
||||
return (bblock_p) 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
STATIC sr_extproc(p)
|
||||
proc_p p;
|
||||
static void sr_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)) {
|
||||
@ -201,13 +197,12 @@ STATIC sr_extproc(p)
|
||||
}
|
||||
|
||||
|
||||
STATIC sr_cleanproc(p)
|
||||
proc_p p;
|
||||
static void sr_cleanproc(proc_p p)
|
||||
{
|
||||
/* Remove 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;
|
||||
@ -218,21 +213,21 @@ STATIC sr_cleanproc(p)
|
||||
}
|
||||
|
||||
|
||||
sr_optimize(p)
|
||||
proc_p p;
|
||||
static int sr_optimize(void *param)
|
||||
{
|
||||
if (IS_ENTERED_WITH_GTO(p)) return;
|
||||
proc_p p = (proc_p)param;
|
||||
if (IS_ENTERED_WITH_GTO(p)) return 0;
|
||||
sr_extproc(p);
|
||||
loopblocks(p);
|
||||
opt_proc(p);
|
||||
sr_cleanproc(p);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
go(argc,argv,no_action,sr_optimize,sr_machinit,no_action);
|
||||
report("strength reductions",Ssr);
|
||||
|
||||
@ -24,9 +24,7 @@
|
||||
#define INSIDE_LOOP(b,lp) Lis_elem(b,lp->LP_BLOCKS)
|
||||
|
||||
|
||||
bool is_loopconst(lnp,vars)
|
||||
line_p lnp;
|
||||
lset vars;
|
||||
bool is_loopconst(line_p lnp, lset vars)
|
||||
{
|
||||
Lindex i;
|
||||
|
||||
@ -41,9 +39,7 @@ bool is_loopconst(lnp,vars)
|
||||
}
|
||||
|
||||
|
||||
bool is_caddress(lnp,vars)
|
||||
line_p lnp;
|
||||
lset vars; /* variables changed in loop */
|
||||
bool is_caddress(line_p lnp, lset vars)
|
||||
{
|
||||
/* See if lnp is a single instruction (i.e. without arguments)
|
||||
* that pushes a loop-invariant entity of size pointer-size (ps)
|
||||
@ -63,13 +59,12 @@ bool is_caddress(lnp,vars)
|
||||
return FALSE;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
STATIC arg_p find_arg(n,list)
|
||||
int n;
|
||||
arg_p list;
|
||||
static arg_p find_arg(int n, arg_p list)
|
||||
{
|
||||
/* Find the n-th element of the list */
|
||||
|
||||
@ -81,8 +76,7 @@ STATIC arg_p find_arg(n,list)
|
||||
}
|
||||
|
||||
|
||||
int elemsize(lnp)
|
||||
line_p lnp;
|
||||
int elemsize(line_p lnp)
|
||||
{
|
||||
/* lnp is an instruction that loads the address of an array
|
||||
* descriptor. Find the size of the elements of the array.
|
||||
@ -107,12 +101,11 @@ int elemsize(lnp)
|
||||
|
||||
|
||||
|
||||
concatenate(list1,list2)
|
||||
line_p list1,list2;
|
||||
void concatenate(line_p list1, line_p list2)
|
||||
{
|
||||
/* Append list2 to the end of list1. list1 may not be empty. */
|
||||
|
||||
register line_p l;
|
||||
line_p l;
|
||||
|
||||
assert(list1 != (line_p) 0);
|
||||
for (l =list1; l->l_next != (line_p) 0; l = l->l_next);
|
||||
|
||||
@ -6,20 +6,20 @@
|
||||
/* S R _ A U X . H */
|
||||
|
||||
|
||||
extern bool is_loopconst(); /* (line_p l; lset vars)
|
||||
* See if l is a loop-constant. vars is the
|
||||
bool is_loopconst(line_p lnp, lset vars);
|
||||
/* See if l is a loop-constant. vars is the
|
||||
* set of variables changed in the loop.
|
||||
*/
|
||||
extern bool is_caddress(); /* (line_p l)
|
||||
* See if l loads a loop-invariant entity of
|
||||
bool is_caddress(line_p lnp, lset vars);
|
||||
/* See if l loads a loop-invariant entity of
|
||||
* size pointer-size.
|
||||
*/
|
||||
extern int elemsize(); /* (line_p l)
|
||||
* l is an instruction that loads an array
|
||||
int elemsize(line_p lnp);
|
||||
/* l is an instruction that loads an array
|
||||
* descriptor. Try to determine the size
|
||||
* of the array elements.
|
||||
*/
|
||||
extern concatenate(); /* (line_p list1,list2)
|
||||
* Append list2 to the end of list1
|
||||
void concatenate(line_p list1, line_p list2);
|
||||
/* Append list2 to the end of list1
|
||||
*/
|
||||
#define is_const(l) (INSTR(l) == op_loc)
|
||||
|
||||
@ -41,7 +41,7 @@
|
||||
*/
|
||||
|
||||
|
||||
STATIC lset cand, /* set of candidates */
|
||||
static lset cand, /* set of candidates */
|
||||
dism; /* set of dismissed variables */
|
||||
|
||||
|
||||
@ -49,8 +49,7 @@ STATIC lset cand, /* set of candidates */
|
||||
|
||||
|
||||
|
||||
STATIC un_cand(lnp)
|
||||
line_p lnp;
|
||||
static void un_cand(line_p lnp)
|
||||
{
|
||||
/* remove the variable stored into by lnp from the list of
|
||||
* candidates (if it was there anyway).
|
||||
@ -68,8 +67,7 @@ STATIC un_cand(lnp)
|
||||
}
|
||||
|
||||
|
||||
STATIC bool is_cand(lnp)
|
||||
line_p lnp;
|
||||
static bool is_cand(line_p lnp)
|
||||
{
|
||||
/* see if the variable stored into by lnp is a candate */
|
||||
|
||||
@ -84,8 +82,7 @@ STATIC bool is_cand(lnp)
|
||||
}
|
||||
|
||||
|
||||
STATIC make_cand(lnp)
|
||||
line_p lnp;
|
||||
static void make_cand(line_p lnp)
|
||||
{
|
||||
/* make the variable stored into by lnp a candidate */
|
||||
|
||||
@ -96,15 +93,13 @@ STATIC make_cand(lnp)
|
||||
|
||||
|
||||
|
||||
STATIC do_dismiss(lnp)
|
||||
line_p lnp;
|
||||
static void do_dismiss(line_p lnp)
|
||||
{
|
||||
Ladd(lnp,&dism);
|
||||
}
|
||||
|
||||
|
||||
STATIC dismiss(lnp)
|
||||
line_p lnp;
|
||||
static void dismiss(line_p lnp)
|
||||
{
|
||||
/* The variable referenced by lnp is turned definitely into
|
||||
* a non-candidate.
|
||||
@ -117,8 +112,7 @@ STATIC dismiss(lnp)
|
||||
}
|
||||
|
||||
|
||||
STATIC bool not_dismissed(lnp)
|
||||
line_p lnp;
|
||||
static bool not_dismissed(line_p lnp)
|
||||
{
|
||||
Lindex i;
|
||||
|
||||
@ -131,9 +125,7 @@ STATIC bool not_dismissed(lnp)
|
||||
}
|
||||
|
||||
|
||||
STATIC try_cand(lnp,b)
|
||||
line_p lnp;
|
||||
bblock_p b;
|
||||
static void try_cand(line_p lnp, bblock_p b)
|
||||
{
|
||||
/* If the variable stored into by lnp was not already a candidate
|
||||
* and was not dismissed, then it is made a candidate
|
||||
@ -151,9 +143,7 @@ STATIC try_cand(lnp,b)
|
||||
}
|
||||
|
||||
|
||||
candidates(lp,cand_out,vars_out)
|
||||
loop_p lp;
|
||||
lset *cand_out, *vars_out;
|
||||
void candidates(loop_p lp, lset *cand_out, lset *vars_out)
|
||||
{
|
||||
/* Find the candidate induction variables.
|
||||
*/
|
||||
|
||||
@ -9,8 +9,8 @@
|
||||
*/
|
||||
|
||||
|
||||
extern candidates(); /* (loop_p lp; lset *iv_cand, *vars)
|
||||
* Find candidate induction variables,
|
||||
void candidates(loop_p lp, lset *cand_out, lset *vars_out);
|
||||
/* Find candidate induction variables,
|
||||
* i.e. local variables that are assigned
|
||||
* a value precisely once within the loop,
|
||||
* within a strong block. Also find the
|
||||
|
||||
@ -26,10 +26,9 @@
|
||||
|
||||
|
||||
|
||||
STATIC lset ivvars; /* set of induction variables */
|
||||
static lset ivvars; /* set of induction variables */
|
||||
|
||||
STATIC short nature(lnp)
|
||||
line_p lnp;
|
||||
static short nature(line_p lnp)
|
||||
{
|
||||
/* Auxiliary routine used by inc_or_dec, is_add and plus_or_min.
|
||||
* Determine if lnp had INCREMENT/DECREMENT-nature (1),
|
||||
@ -62,8 +61,7 @@ STATIC short nature(lnp)
|
||||
#define inc_or_dec(l) (nature(l) == 1)
|
||||
|
||||
|
||||
STATIC bool is_same(l,lnp)
|
||||
line_p l, lnp;
|
||||
static bool is_same(line_p l, line_p lnp)
|
||||
{
|
||||
/* lnp is a STL x , where x is a candidate
|
||||
* induction variable. See if l is a LOL x
|
||||
@ -76,9 +74,7 @@ STATIC bool is_same(l,lnp)
|
||||
}
|
||||
|
||||
|
||||
STATIC ivar(lnp,step)
|
||||
line_p lnp;
|
||||
int step;
|
||||
static void ivar(line_p lnp, int step)
|
||||
{
|
||||
/* Record the fact that we've found a new induction variable.
|
||||
* lnp points to the last instruction of the code that
|
||||
@ -95,8 +91,7 @@ STATIC ivar(lnp,step)
|
||||
}
|
||||
|
||||
|
||||
STATIC int sign(lnp)
|
||||
line_p lnp;
|
||||
static int sign(line_p lnp)
|
||||
{
|
||||
switch(INSTR(lnp)) {
|
||||
case op_inc:
|
||||
@ -113,11 +108,11 @@ STATIC int sign(lnp)
|
||||
assert(FALSE);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
STATIC try_patterns(lnp)
|
||||
line_p lnp;
|
||||
static void try_patterns(line_p lnp)
|
||||
{
|
||||
/* lnp is a STL x; try to recognize
|
||||
* one of the patterns:
|
||||
@ -153,9 +148,7 @@ STATIC try_patterns(lnp)
|
||||
}
|
||||
|
||||
|
||||
induc_vars(loop,ivar_out, vars_out)
|
||||
loop_p loop;
|
||||
lset *ivar_out, *vars_out;
|
||||
void induc_vars(loop_p loop, lset *ivar_out, lset *vars_out)
|
||||
{
|
||||
/* Construct the set of induction variables. We use several
|
||||
* global variables computed by 'candidates'.
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
*/
|
||||
/* S R _ I V . H */
|
||||
|
||||
extern induc_vars(); /* (loop_p loop; lset *ivars, *vars)
|
||||
* Find the set of induction variables
|
||||
void induc_vars(loop_p loop, lset *ivar_out, lset *vars_out);
|
||||
/* Find the set of induction variables
|
||||
* of the loop. Also find the set of (local)
|
||||
* variables that are changed.
|
||||
*/
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
|
||||
|
||||
|
||||
STATIC lset avail;
|
||||
static lset avail;
|
||||
/* If an expression such as "iv * const" or "A[iv]" is
|
||||
* used more than once in a loop, we only use one temporary
|
||||
* local for it and reuse this local each time.
|
||||
@ -38,8 +38,7 @@ STATIC lset avail;
|
||||
* be available.
|
||||
*/
|
||||
|
||||
STATIC int regtyp(code)
|
||||
code_p code;
|
||||
static int regtyp(code_p code)
|
||||
{
|
||||
switch(code->co_instr) {
|
||||
case op_mli:
|
||||
@ -51,14 +50,11 @@ STATIC int regtyp(code)
|
||||
return reg_pointer;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return reg_pointer;
|
||||
}
|
||||
|
||||
|
||||
STATIC gen_regmes(tmp,score,code,p)
|
||||
offset tmp;
|
||||
int score;
|
||||
code_p code;
|
||||
proc_p p;
|
||||
static void gen_regmes(offset tmp, int score, code_p code, proc_p p)
|
||||
{
|
||||
/* generate a register message for the temporary variable and
|
||||
* insert it at the start of the procedure.
|
||||
@ -75,9 +71,7 @@ STATIC gen_regmes(tmp,score,code,p)
|
||||
}
|
||||
|
||||
|
||||
STATIC line_p newcode(code,tmp)
|
||||
code_p code;
|
||||
offset tmp;
|
||||
static line_p newcode(code_p code, offset tmp)
|
||||
{
|
||||
/* Construct the EM code that will replace the reducible code,
|
||||
* e.g. iv * c -> tmp
|
||||
@ -120,9 +114,7 @@ STATIC line_p newcode(code,tmp)
|
||||
|
||||
|
||||
|
||||
STATIC replcode(code,text)
|
||||
code_p code;
|
||||
line_p text;
|
||||
static void replcode(code_p code, line_p text)
|
||||
{
|
||||
/* Replace old code (extending from code->co_lfirst to
|
||||
* code->co_llast) by new code (headed by 'text').
|
||||
@ -149,8 +141,7 @@ STATIC replcode(code,text)
|
||||
/* Note that the old code is still accessible via code->co_lfirst */
|
||||
}
|
||||
|
||||
STATIC line_p add_code(pl, l)
|
||||
line_p pl, l;
|
||||
static line_p add_code(line_p pl, line_p l)
|
||||
{
|
||||
if (! pl) {
|
||||
PREV(l) = 0;
|
||||
@ -170,9 +161,7 @@ STATIC line_p add_code(pl, l)
|
||||
|
||||
|
||||
|
||||
STATIC init_code(code,tmp)
|
||||
code_p code;
|
||||
offset tmp;
|
||||
static void init_code(code_p code, offset tmp)
|
||||
{
|
||||
/* Generate code to set up the temporary local.
|
||||
* For multiplication, its initial value is const*iv_expr,
|
||||
@ -238,9 +227,7 @@ STATIC init_code(code,tmp)
|
||||
*p = l; /* new last instruction */
|
||||
}
|
||||
|
||||
STATIC incr_code(code,tmp)
|
||||
code_p code;
|
||||
offset tmp;
|
||||
static void incr_code(code_p code, offset tmp)
|
||||
{
|
||||
/* Generate code to increment the temporary local variable.
|
||||
* The variable is incremented by
|
||||
@ -321,8 +308,7 @@ STATIC incr_code(code,tmp)
|
||||
}
|
||||
|
||||
|
||||
STATIC remcode(c)
|
||||
code_p c;
|
||||
static void remcode(code_p c)
|
||||
{
|
||||
line_p l, next;
|
||||
|
||||
@ -334,9 +320,7 @@ STATIC remcode(c)
|
||||
}
|
||||
|
||||
|
||||
STATIC bool same_address(l1,l2,vars)
|
||||
line_p l1,l2;
|
||||
lset vars;
|
||||
static bool same_address(line_p l1, line_p l2, lset vars)
|
||||
{
|
||||
/* See if l1 and l2 load the same address */
|
||||
|
||||
@ -357,18 +341,17 @@ STATIC bool same_address(l1,l2,vars)
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
STATIC bool same_expr(lb1,le1,lb2,le2)
|
||||
line_p lb1,le1,lb2,le2;
|
||||
static bool same_expr(line_p lb1, line_p le1, line_p lb2, line_p le2)
|
||||
{
|
||||
/* See if the code from lb1 to le1 is the same
|
||||
* expression as the code from lb2 to le2.
|
||||
*/
|
||||
|
||||
|
||||
register line_p l1,l2;
|
||||
line_p l1,l2;
|
||||
|
||||
l1 = lb1;
|
||||
l2 = lb2;
|
||||
@ -395,9 +378,7 @@ STATIC bool same_expr(lb1,le1,lb2,le2)
|
||||
}
|
||||
}
|
||||
|
||||
STATIC bool same_code(c1,c2,vars)
|
||||
code_p c1,c2;
|
||||
lset vars;
|
||||
static bool same_code(code_p c1, code_p c2, lset vars)
|
||||
{
|
||||
/* See if c1 and c2 compute the same expression. Two array
|
||||
* references can be the same even if one is e.g a fetch
|
||||
@ -428,12 +409,11 @@ STATIC bool same_code(c1,c2,vars)
|
||||
assert(FALSE);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
STATIC code_p available(c,vars)
|
||||
code_p c;
|
||||
lset vars;
|
||||
static code_p available(code_p c, lset vars)
|
||||
{
|
||||
/* See if the code is already available.
|
||||
* If so, return a pointer to the first occurrence
|
||||
@ -452,8 +432,7 @@ STATIC code_p available(c,vars)
|
||||
return (code_p) 0;
|
||||
}
|
||||
|
||||
STATIC fix_header(lp)
|
||||
loop_p lp;
|
||||
static void fix_header(loop_p lp)
|
||||
{
|
||||
/* Check if a header block was added, and if so, add a branch to
|
||||
* the entry block.
|
||||
@ -486,21 +465,19 @@ STATIC fix_header(lp)
|
||||
}
|
||||
}
|
||||
|
||||
STATIC reduce(code,vars)
|
||||
code_p code;
|
||||
lset vars;
|
||||
static void reduce(code_p code, lset vars)
|
||||
{
|
||||
/* Perform the actual transformations. The code on the left
|
||||
* gets transformed into the code on the right. Note that
|
||||
* each piece of code is assigned a name, that will be
|
||||
* used to describe the whole process.
|
||||
*
|
||||
* t = iv * 118; (init_code)
|
||||
* do ---> do
|
||||
* .. iv * 118 .. .. t .. (new_code)
|
||||
* iv++; iv++;
|
||||
* t += 118; (incr_code)
|
||||
* od od
|
||||
* t = iv * 118; (init_code)
|
||||
* do ---> do
|
||||
* .. iv * 118 .. .. t .. (new_code)
|
||||
* iv++; iv++;
|
||||
* t += 118; (incr_code)
|
||||
* od od
|
||||
*/
|
||||
|
||||
offset tmp;
|
||||
@ -543,11 +520,7 @@ STATIC reduce(code,vars)
|
||||
|
||||
|
||||
|
||||
STATIC try_multiply(lp,ivs,vars,b,mul)
|
||||
loop_p lp;
|
||||
lset ivs,vars;
|
||||
bblock_p b;
|
||||
line_p mul;
|
||||
static void try_multiply(loop_p lp, lset ivs, lset vars, bblock_p b, line_p mul)
|
||||
{
|
||||
/* See if we can reduce the strength of the multiply
|
||||
* instruction. If so, then set up the global common
|
||||
@ -605,11 +578,7 @@ STATIC try_multiply(lp,ivs,vars,b,mul)
|
||||
|
||||
|
||||
|
||||
STATIC try_leftshift(lp,ivs,vars,b,shft)
|
||||
loop_p lp;
|
||||
lset ivs,vars;
|
||||
bblock_p b;
|
||||
line_p shft;
|
||||
static void try_leftshift(loop_p lp, lset ivs, lset vars, bblock_p b, line_p shft)
|
||||
{
|
||||
/* See if we can reduce the strength of the leftshift
|
||||
* instruction. If so, then set up the global common
|
||||
@ -656,11 +625,7 @@ STATIC try_leftshift(lp,ivs,vars,b,shft)
|
||||
}
|
||||
|
||||
|
||||
STATIC try_array(lp,ivs,vars,b,arr)
|
||||
loop_p lp;
|
||||
lset ivs,vars;
|
||||
bblock_p b;
|
||||
line_p arr;
|
||||
static void try_array(loop_p lp, lset ivs, lset vars, bblock_p b, line_p arr)
|
||||
{
|
||||
/* See if we can reduce the strength of the array reference
|
||||
* instruction 'arr'.
|
||||
@ -710,7 +675,7 @@ STATIC try_array(lp,ivs,vars,b,arr)
|
||||
|
||||
|
||||
|
||||
STATIC clean_avail()
|
||||
static void clean_avail()
|
||||
{
|
||||
Lindex i;
|
||||
|
||||
@ -721,11 +686,12 @@ STATIC clean_avail()
|
||||
}
|
||||
|
||||
|
||||
|
||||
strength_reduction(lp,ivs,vars)
|
||||
loop_p lp; /* description of the loop */
|
||||
lset ivs; /* set of induction variables of the loop */
|
||||
lset vars; /* set of local variables changed in loop */
|
||||
/*
|
||||
* lp ==> description of the loop
|
||||
* ivs ==> set of induction variables of the loop
|
||||
* vars ==> set of local variables changed in loop
|
||||
*/
|
||||
void strength_reduction(loop_p lp, lset ivs, lset vars)
|
||||
{
|
||||
/* Find all expensive instructions (leftshift, multiply, array) and see
|
||||
* if they can be reduced. We branch to several instruction-specific
|
||||
|
||||
@ -5,6 +5,6 @@
|
||||
*/
|
||||
/* S R _ R E D U C E . H */
|
||||
|
||||
extern strength_reduction(); /* (loop_p loop; lset ivs, vars)
|
||||
* Perform streength reduction.
|
||||
void strength_reduction(loop_p lp, lset ivs, lset vars);
|
||||
/* Perform streength reduction.
|
||||
*/
|
||||
|
||||
@ -29,9 +29,7 @@
|
||||
|
||||
/* Transformations on EM texts */
|
||||
|
||||
line_p move_pointer(tmp,dir)
|
||||
offset tmp;
|
||||
int dir;
|
||||
line_p move_pointer(offset tmp, int dir)
|
||||
{
|
||||
/* Generate EM code to load/store a pointer variable
|
||||
* onto/from the stack, depending on dir(ection).
|
||||
@ -66,9 +64,7 @@ line_p move_pointer(tmp,dir)
|
||||
|
||||
/* make_header */
|
||||
|
||||
STATIC copy_loops(b1,b2,except)
|
||||
bblock_p b1,b2;
|
||||
loop_p except;
|
||||
static void copy_loops(bblock_p b1, bblock_p b2, loop_p except)
|
||||
{
|
||||
/* Copy the loopset of b2 to b1, except for 'except' */
|
||||
|
||||
@ -84,8 +80,7 @@ STATIC copy_loops(b1,b2,except)
|
||||
}
|
||||
|
||||
|
||||
STATIC lab_id label(b)
|
||||
bblock_p b;
|
||||
static lab_id label(bblock_p b)
|
||||
{
|
||||
/* Find the label at the head of block b. If there is
|
||||
* no such label yet, create one.
|
||||
@ -108,8 +103,7 @@ STATIC lab_id label(b)
|
||||
}
|
||||
|
||||
|
||||
STATIC adjust_jump(newtarg,oldtarg,c)
|
||||
bblock_p newtarg,oldtarg,c;
|
||||
static void adjust_jump(bblock_p newtarg, bblock_p oldtarg, bblock_p c)
|
||||
{
|
||||
/* If the last instruction of c is a jump to the
|
||||
* old target, then change it into a jump to the
|
||||
@ -138,8 +132,7 @@ STATIC adjust_jump(newtarg,oldtarg,c)
|
||||
}
|
||||
|
||||
|
||||
make_header(lp)
|
||||
loop_p lp;
|
||||
void make_header(loop_p lp)
|
||||
{
|
||||
/* Make sure that the loop has a header block, i.e. a block
|
||||
* has the loop entry block as its only successor and
|
||||
|
||||
@ -11,12 +11,12 @@
|
||||
|
||||
|
||||
|
||||
extern line_p move_pointer(); /* (offset tmp; int dir ) */
|
||||
line_p move_pointer(offset tmp, int dir);
|
||||
/* Generate EM code to load/store a pointer variable
|
||||
* onto/from the stack, depending on dir(ection).
|
||||
* We accept all kinds of pointer sizes.
|
||||
*/
|
||||
extern make_header() ; /* (loop_p lp) */
|
||||
void make_header(loop_p lp);
|
||||
/* Make sure that the loop has a header block, i.e. a block
|
||||
* has the loop entry block as its only successor and
|
||||
* that dominates the loop entry block.
|
||||
|
||||
101
util/ego/ud/ud.c
101
util/ego/ud/ud.c
@ -7,6 +7,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <em_spec.h>
|
||||
#include "../share/types.h"
|
||||
#include "ud.h"
|
||||
@ -39,8 +40,7 @@ int Svalue,Svariable;
|
||||
|
||||
cond_p globl_cond_tab,local_cond_tab;
|
||||
|
||||
STATIC cond_p getcondtab(f)
|
||||
FILE *f;
|
||||
static cond_p getcondtab(FILE *f)
|
||||
{
|
||||
int l,i;
|
||||
cond_p tab;
|
||||
@ -56,11 +56,10 @@ STATIC cond_p getcondtab(f)
|
||||
}
|
||||
|
||||
|
||||
STATIC ud_machinit(f)
|
||||
FILE *f;
|
||||
static int ud_machinit(void *param)
|
||||
{
|
||||
char s[100];
|
||||
|
||||
FILE *f = (FILE *)param;
|
||||
for (;;) {
|
||||
while(getc(f) != '\n');
|
||||
fscanf(f,"%s",s);
|
||||
@ -68,13 +67,13 @@ STATIC ud_machinit(f)
|
||||
}
|
||||
globl_cond_tab = getcondtab(f);
|
||||
local_cond_tab = getcondtab(f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
STATIC bool test_cond(cond,val)
|
||||
short cond;
|
||||
offset val;
|
||||
static bool test_cond(short cond, offset val)
|
||||
{
|
||||
switch(cond) {
|
||||
case DEFAULT:
|
||||
@ -84,13 +83,11 @@ STATIC bool test_cond(cond,val)
|
||||
}
|
||||
assert(FALSE);
|
||||
/* NOTREACHED */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
STATIC short map_value(tab,val,time)
|
||||
struct cond_tab tab[];
|
||||
offset val;
|
||||
bool time;
|
||||
static short map_value(struct cond_tab tab[], offset val, bool time)
|
||||
{
|
||||
cond_p p;
|
||||
|
||||
@ -102,8 +99,7 @@ STATIC short map_value(tab,val,time)
|
||||
}
|
||||
|
||||
|
||||
STATIC init_root(root)
|
||||
bblock_p root;
|
||||
static int init_root(void *param)
|
||||
{
|
||||
/* Initialise the IN OUT sets of the entry block of the
|
||||
* current procedure. Global variables and parameters
|
||||
@ -112,7 +108,7 @@ STATIC init_root(root)
|
||||
* to all global variables and parameters are
|
||||
* put in IN.
|
||||
*/
|
||||
|
||||
bblock_p root = (bblock_p)param;
|
||||
short v;
|
||||
|
||||
for (v = 1; v <= nrglobals; v++) {
|
||||
@ -127,14 +123,14 @@ STATIC init_root(root)
|
||||
Ccopy_set(IN(root),&OUT(root));
|
||||
Csubtract(KILL(root),&OUT(root));
|
||||
Cjoin(GEN(root),&OUT(root));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
STATIC unite_outs(bbset,setp)
|
||||
lset bbset;
|
||||
cset *setp;
|
||||
static void unite_outs(lset bbset, cset *setp)
|
||||
{
|
||||
/* Take the union of OUT(b), for all b in bbset,
|
||||
* and put the result in setp.
|
||||
@ -150,8 +146,7 @@ STATIC unite_outs(bbset,setp)
|
||||
|
||||
|
||||
|
||||
STATIC solve_equations(p)
|
||||
proc_p p;
|
||||
static void solve_equations(proc_p p)
|
||||
{
|
||||
/* Solve the data flow equations for reaching
|
||||
* definitions of procedure p.
|
||||
@ -163,7 +158,7 @@ STATIC solve_equations(p)
|
||||
* solve the equations.
|
||||
*/
|
||||
|
||||
register bblock_p b;
|
||||
bblock_p b;
|
||||
bool change;
|
||||
cset newin;
|
||||
|
||||
@ -203,14 +198,13 @@ STATIC solve_equations(p)
|
||||
|
||||
|
||||
|
||||
short global_addr_cost()
|
||||
static short global_addr_cost()
|
||||
{
|
||||
return add_timespace(map_value(globl_cond_tab,(offset) 0,TRUE),
|
||||
map_value(globl_cond_tab,(offset) 0,FALSE));
|
||||
}
|
||||
|
||||
short local_addr_cost(off)
|
||||
offset off;
|
||||
short local_addr_cost(offset off)
|
||||
{
|
||||
return add_timespace(map_value(local_cond_tab,off,TRUE),
|
||||
map_value(local_cond_tab,off,FALSE));
|
||||
@ -218,8 +212,7 @@ short local_addr_cost(off)
|
||||
|
||||
|
||||
|
||||
STATIC bool fold_is_desirable(old,new)
|
||||
line_p old,new;
|
||||
static bool fold_is_desirable(line_p old, line_p new)
|
||||
{
|
||||
/* See if it is desirable to replace the variable used by the
|
||||
* EM instruction 'old' by the variable used by 'new'.
|
||||
@ -264,7 +257,8 @@ STATIC bool fold_is_desirable(old,new)
|
||||
#ifdef TRACE
|
||||
/*********** TRACING ROUTINES ***********/
|
||||
|
||||
pr_localtab() {
|
||||
static void pr_localtab()
|
||||
{
|
||||
short i;
|
||||
local_p lc;
|
||||
|
||||
@ -278,7 +272,7 @@ pr_localtab() {
|
||||
}
|
||||
}
|
||||
|
||||
pr_globals()
|
||||
void pr_globals()
|
||||
{
|
||||
dblock_p d;
|
||||
obj_p obj;
|
||||
@ -296,7 +290,7 @@ pr_globals()
|
||||
|
||||
extern char em_mnem[];
|
||||
|
||||
pr_defs()
|
||||
static void pr_defs()
|
||||
{
|
||||
short i;
|
||||
line_p l;
|
||||
@ -323,10 +317,7 @@ pr_defs()
|
||||
}
|
||||
|
||||
|
||||
pr_set(name,k,s,n)
|
||||
char *name;
|
||||
cset s;
|
||||
short k,n;
|
||||
static void pr_set(char *name, short k, cset s, short n)
|
||||
{
|
||||
short i;
|
||||
|
||||
@ -339,8 +330,7 @@ pr_set(name,k,s,n)
|
||||
printf ("}\n");
|
||||
}
|
||||
|
||||
pr_blocks(p)
|
||||
proc_p p;
|
||||
static void pr_blocks(proc_p p)
|
||||
{
|
||||
bblock_p b;
|
||||
short n;
|
||||
@ -356,7 +346,7 @@ pr_blocks(p)
|
||||
}
|
||||
}
|
||||
|
||||
pr_copies()
|
||||
static void pr_copies()
|
||||
{
|
||||
short i;
|
||||
|
||||
@ -368,8 +358,7 @@ pr_copies()
|
||||
}
|
||||
}
|
||||
|
||||
pr_cblocks(p)
|
||||
proc_p p;
|
||||
static void pr_cblocks(proc_p p)
|
||||
{
|
||||
bblock_p b;
|
||||
short n;
|
||||
@ -388,8 +377,7 @@ pr_cblocks(p)
|
||||
|
||||
#endif
|
||||
|
||||
STATIC ud_analysis(p)
|
||||
proc_p p;
|
||||
static void ud_analysis(proc_p p)
|
||||
{
|
||||
/* Perform use-definition analysis on procedure p */
|
||||
|
||||
@ -413,27 +401,25 @@ STATIC ud_analysis(p)
|
||||
|
||||
|
||||
|
||||
STATIC clean_maps()
|
||||
static void clean_maps()
|
||||
{
|
||||
local_p *p;
|
||||
cset *v;
|
||||
|
||||
oldmap(defs,nrexpldefs);
|
||||
oldmap((short **)defs,nrexpldefs);
|
||||
for (p = &locals[1]; p <= &locals[nrlocals]; p++) {
|
||||
oldlocal(*p);
|
||||
}
|
||||
oldmap(locals,nrlocals);
|
||||
oldmap((short **)locals,nrlocals);
|
||||
for (v = &vardefs[1]; v <= &vardefs[nrvars]; v++) {
|
||||
Cdeleteset(*v);
|
||||
}
|
||||
oldmap(vardefs,nrvars);
|
||||
oldmap((short **)vardefs,nrvars);
|
||||
}
|
||||
|
||||
|
||||
|
||||
STATIC bool try_optim(l,b)
|
||||
line_p l;
|
||||
bblock_p b;
|
||||
static bool try_optim(line_p l, bblock_p b)
|
||||
{
|
||||
/* Try copy propagation and constant propagation */
|
||||
|
||||
@ -467,8 +453,7 @@ STATIC bool try_optim(l,b)
|
||||
|
||||
|
||||
|
||||
value_propagation(p)
|
||||
proc_p p;
|
||||
void value_propagation(proc_p p)
|
||||
{
|
||||
/* Apply value propagation to procedure p */
|
||||
|
||||
@ -493,13 +478,12 @@ value_propagation(p)
|
||||
}
|
||||
}
|
||||
}
|
||||
oldmap(copies,nrcopies);
|
||||
oldtable(def_to_copynr,nrdefs);
|
||||
oldmap((short **)copies,nrcopies);
|
||||
oldtable((short **)def_to_copynr,nrdefs);
|
||||
}
|
||||
|
||||
|
||||
STATIC ud_extend(p)
|
||||
proc_p p;
|
||||
static void ud_extend(proc_p p)
|
||||
{
|
||||
/* Allocate extended data structures for Use Definition analysis */
|
||||
|
||||
@ -511,8 +495,7 @@ STATIC ud_extend(p)
|
||||
}
|
||||
|
||||
|
||||
STATIC ud_cleanup(p)
|
||||
proc_p p;
|
||||
static void ud_cleanup(proc_p p)
|
||||
{
|
||||
/* Deallocate extended data structures for Use Definition analysis */
|
||||
|
||||
@ -531,10 +514,10 @@ STATIC ud_cleanup(p)
|
||||
}
|
||||
|
||||
|
||||
ud_optimize(p)
|
||||
proc_p p;
|
||||
static int ud_optimize(void *param)
|
||||
{
|
||||
if (IS_ENTERED_WITH_GTO(p)) return;
|
||||
proc_p p = (proc_p)param;
|
||||
if (IS_ENTERED_WITH_GTO(p)) return 0;
|
||||
ud_extend(p);
|
||||
locals = (local_p *) 0;
|
||||
vardefs = (cset *) 0;
|
||||
@ -548,6 +531,8 @@ ud_optimize(p)
|
||||
value_propagation(p);
|
||||
ud_cleanup(p);
|
||||
clean_maps();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
main(argc,argv)
|
||||
|
||||
@ -24,9 +24,7 @@
|
||||
#include "../share/aux.h"
|
||||
#include "ud_defs.h"
|
||||
|
||||
repl_line(old,new,b)
|
||||
line_p old,new;
|
||||
bblock_p b;
|
||||
void repl_line(line_p old, line_p new, bblock_p b)
|
||||
{
|
||||
/* Replace 'old' by 'new' */
|
||||
|
||||
@ -44,8 +42,7 @@ repl_line(old,new,b)
|
||||
|
||||
|
||||
|
||||
bool same_var(use,def)
|
||||
line_p use,def;
|
||||
bool same_var(line_p use, line_p def)
|
||||
{
|
||||
/* 'use' is an instruction that uses a variable
|
||||
* for which we maintain ud-info (e.g. a LOL).
|
||||
|
||||
@ -10,13 +10,13 @@
|
||||
*/
|
||||
|
||||
|
||||
extern repl_line(); /* (line_p old,new; bblock_p b)
|
||||
* Replace EM instruction 'old' by a
|
||||
void repl_line(line_p old, line_p new, bblock_p b);
|
||||
/* Replace EM instruction 'old' by a
|
||||
* copy of 'new'. Update doubly-linked
|
||||
* list.
|
||||
*/
|
||||
extern bool same_var(); /* (line_p use,def)
|
||||
* 'use' is an instruction that uses a variable
|
||||
bool same_var(line_p use, line_p def);
|
||||
/* 'use' is an instruction that uses a variable
|
||||
* for which we maintain ud-info (e.g. a LOL).
|
||||
* See if 'def' references the same variable.
|
||||
*/
|
||||
|
||||
@ -27,8 +27,7 @@
|
||||
#define CALLS_UNKNOWN(p) (p->p_flags1 & (byte) PF_CALUNKNOWN)
|
||||
|
||||
|
||||
bool is_use(l)
|
||||
line_p l;
|
||||
bool is_use(line_p l)
|
||||
{
|
||||
/* See if 'l' is a use of a variable */
|
||||
|
||||
@ -42,14 +41,13 @@ bool is_use(l)
|
||||
return FALSE;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool value_known(def,val_out)
|
||||
line_p def;
|
||||
offset *val_out;
|
||||
bool value_known(line_p def, offset *val_out)
|
||||
{
|
||||
/* See if the value stored by definition 'def'
|
||||
* is known statically (i.e. is a constant).
|
||||
@ -109,9 +107,7 @@ bool value_known(def,val_out)
|
||||
|
||||
|
||||
|
||||
bool affected(use,v,l)
|
||||
line_p use,l;
|
||||
short v;
|
||||
bool affected(line_p use, short v, line_p l)
|
||||
{
|
||||
/* See if the variable referenced by 'use' may be
|
||||
* changed by instruction l, which is either a cal, cai or
|
||||
@ -131,10 +127,7 @@ bool affected(use,v,l)
|
||||
|
||||
|
||||
|
||||
STATIC search_backwards(use,v,found,def)
|
||||
line_p use, *def;
|
||||
short v;
|
||||
bool *found;
|
||||
static void search_backwards(line_p use, short v, bool *found, line_p *def)
|
||||
{
|
||||
/* Search backwards in the current basic block,
|
||||
* starting at 'use', trying to find a definition
|
||||
@ -163,8 +156,7 @@ STATIC search_backwards(use,v,found,def)
|
||||
|
||||
|
||||
|
||||
STATIC short outer_def(vdefs,in)
|
||||
cset vdefs, in;
|
||||
static short outer_def(cset vdefs, cset in)
|
||||
{
|
||||
/* See if there is a unique definition of variable
|
||||
* v reaching the beginning of block b.
|
||||
@ -188,10 +180,7 @@ STATIC short outer_def(vdefs,in)
|
||||
|
||||
|
||||
|
||||
line_p unique_def(use,b,defnr_out)
|
||||
line_p use;
|
||||
bblock_p b;
|
||||
short *defnr_out;
|
||||
line_p unique_def(line_p use, bblock_p b, short *defnr_out)
|
||||
{
|
||||
/* See if there is one unique explicit definition
|
||||
* of the variable used by 'use', that reaches 'use'.
|
||||
@ -223,10 +212,7 @@ line_p unique_def(use,b,defnr_out)
|
||||
|
||||
|
||||
|
||||
fold_const(l,b,val)
|
||||
line_p l;
|
||||
bblock_p b;
|
||||
offset val;
|
||||
void fold_const(line_p l, bblock_p b, offset val)
|
||||
{
|
||||
/* Perform the substitutions required for constant folding */
|
||||
|
||||
|
||||
@ -6,24 +6,24 @@
|
||||
|
||||
/* C O N S T A N T P R O P A G A T I O N */
|
||||
|
||||
extern line_p unique_def(); /* ( line_p use; bblock_p b; short *defnr_out;)
|
||||
* See if there is a unique explicit definition
|
||||
line_p unique_def(line_p use, bblock_p b, short *defnr_out);
|
||||
/* See if there is a unique explicit definition
|
||||
* of the variable used by 'use' that
|
||||
* reaches 'use'.
|
||||
*/
|
||||
extern bool value_known(); /* (line_p def; offset *val_out)
|
||||
* See if the value stored by definition 'def'
|
||||
bool value_known(line_p def, offset *val_out);
|
||||
/* See if the value stored by definition 'def'
|
||||
* is known statically (i.e. is a constant).
|
||||
*/
|
||||
extern fold_const(); /* (line_p l; bblock_p b; offset val)
|
||||
* Perform the substitutions required for
|
||||
void fold_const(line_p l, bblock_p b, offset val);
|
||||
/* Perform the substitutions required for
|
||||
* constant folding.
|
||||
*/
|
||||
extern bool is_use(); /* (line_p l)
|
||||
* See if 'l' is a use of a variable.
|
||||
bool is_use(line_p l);
|
||||
/* See if 'l' is a use of a variable.
|
||||
*/
|
||||
extern bool affected(); /* (line_p use,l; short v)
|
||||
* See if the variable referenced by 'use' may
|
||||
bool affected(line_p use, short v, line_p l);
|
||||
/* See if the variable referenced by 'use' may
|
||||
* be changed by instruction l, which is
|
||||
* either a cal, cai or an indirect assignment.
|
||||
*/
|
||||
|
||||
@ -42,9 +42,7 @@ short nrcopies; /* number of copies in the current procedure
|
||||
#define COUNT 0
|
||||
#define MAP 1
|
||||
|
||||
STATIC traverse_defs(p,action)
|
||||
proc_p p;
|
||||
int action;
|
||||
static void traverse_defs(proc_p p, int action)
|
||||
{
|
||||
bblock_p b;
|
||||
line_p l;
|
||||
@ -83,8 +81,7 @@ STATIC traverse_defs(p,action)
|
||||
|
||||
|
||||
|
||||
STATIC make_copytab(p)
|
||||
proc_p p;
|
||||
static void make_copytab(proc_p p)
|
||||
{
|
||||
/* Make a table of all copies appearing in procedure p.
|
||||
* We first count how many there are, because we
|
||||
@ -97,14 +94,13 @@ STATIC make_copytab(p)
|
||||
|
||||
|
||||
|
||||
STATIC bool is_changed(varl,start,stop)
|
||||
line_p varl, start, stop;
|
||||
static bool is_changed(line_p varl, line_p start, line_p stop)
|
||||
{
|
||||
/* See if the variable used by instruction varl
|
||||
* is changed anywhere between 'start' and 'stop'
|
||||
*/
|
||||
|
||||
register line_p l;
|
||||
line_p l;
|
||||
short v;
|
||||
bool found;
|
||||
|
||||
@ -121,15 +117,14 @@ STATIC bool is_changed(varl,start,stop)
|
||||
|
||||
|
||||
|
||||
STATIC gen_kill_copies(p)
|
||||
proc_p p;
|
||||
static void gen_kill_copies(proc_p p)
|
||||
{
|
||||
/* Compute C_GEN and C_KILL for every basic block
|
||||
* of p.
|
||||
*/
|
||||
|
||||
register line_p l;
|
||||
register bblock_p b,n;
|
||||
line_p l;
|
||||
bblock_p b,n;
|
||||
short v;
|
||||
bool found;
|
||||
short copycnt = 1, defcnt = 1;
|
||||
@ -165,9 +160,7 @@ STATIC gen_kill_copies(p)
|
||||
|
||||
|
||||
|
||||
STATIC intersect_outs(bbset,setp,full_set)
|
||||
lset bbset;
|
||||
cset *setp,full_set;
|
||||
static void intersect_outs(lset bbset, cset *setp, cset full_set)
|
||||
{
|
||||
/* Take the intersection of C_OUT(b), for all b in bbset,
|
||||
* and put the result in setp.
|
||||
@ -183,9 +176,7 @@ STATIC intersect_outs(bbset,setp,full_set)
|
||||
|
||||
|
||||
|
||||
STATIC init_cin(p,full_set)
|
||||
proc_p p;
|
||||
cset full_set;
|
||||
static void init_cin(proc_p p, cset full_set)
|
||||
{
|
||||
/* Initialize C_IN(b) and C_OUT(b), for every basic block b.
|
||||
* C_IN of the root of the CFG (i.e. the procedure entry block)
|
||||
@ -218,8 +209,7 @@ STATIC init_cin(p,full_set)
|
||||
|
||||
|
||||
|
||||
STATIC solve_cin(p)
|
||||
proc_p p;
|
||||
static void solve_cin(proc_p p)
|
||||
{
|
||||
/* Solve the data flow equations for reaching
|
||||
* definitions of procedure p.
|
||||
@ -233,7 +223,7 @@ STATIC solve_cin(p)
|
||||
* solve the equations.
|
||||
*/
|
||||
|
||||
register bblock_p b;
|
||||
bblock_p b;
|
||||
bool change;
|
||||
cset newin,full_set;
|
||||
short n;
|
||||
@ -267,8 +257,7 @@ STATIC solve_cin(p)
|
||||
|
||||
|
||||
|
||||
copy_analysis(p)
|
||||
proc_p p;
|
||||
void copy_analysis(proc_p p)
|
||||
{
|
||||
/* Determine which copies procedure p has. Compute C_IN(b),
|
||||
* for every basic block b.
|
||||
@ -281,8 +270,7 @@ copy_analysis(p)
|
||||
|
||||
|
||||
|
||||
bool is_copy(def)
|
||||
line_p def;
|
||||
bool is_copy(line_p def)
|
||||
{
|
||||
/* See if the definition def is also a 'copy', i.e. an
|
||||
* statement of the form 'A := B' (or, in EM terminology:
|
||||
@ -311,9 +299,7 @@ bool is_copy(def)
|
||||
|
||||
|
||||
|
||||
fold_var(old,new,b)
|
||||
line_p old, new;
|
||||
bblock_p b;
|
||||
void fold_var(line_p old, line_p new, bblock_p b)
|
||||
{
|
||||
/* The variable referenced by the EM instruction 'old'
|
||||
* must be replaced by the variable referenced by 'new'.
|
||||
@ -369,10 +355,7 @@ END DEBUG */
|
||||
|
||||
|
||||
|
||||
bool value_retained(copy,defnr,use,b)
|
||||
line_p copy,use;
|
||||
short defnr;
|
||||
bblock_p b;
|
||||
bool value_retained(line_p copy, short defnr, line_p use, bblock_p b)
|
||||
{
|
||||
/* See if the right hand side variable of the
|
||||
* copy still has the same value at 'use'.
|
||||
|
||||
@ -16,23 +16,23 @@ extern short nrcopies; /* number of copies in the current procedure
|
||||
* (length of copies-table)
|
||||
*/
|
||||
|
||||
extern copy_analysis(); /* (proc_p p)
|
||||
* Determine which copies procedure p has.
|
||||
void copy_analysis(proc_p p);
|
||||
/* Determine which copies procedure p has.
|
||||
* Compute C_IN(b), for every basic block b.
|
||||
*/
|
||||
extern bool is_copy(); /* (line_p def)
|
||||
* See if the definition def is also a 'copy',
|
||||
bool is_copy(line_p def);
|
||||
/* See if the definition def is also a 'copy',
|
||||
* i.e. an statement of the form
|
||||
* 'A := B' (or, in EM terminology:
|
||||
* a sequence 'Load Variable; Store Variable').
|
||||
*/
|
||||
extern fold_var(); /* (line_p old,new; bblock_p b)
|
||||
* The variable referenced by the
|
||||
void fold_var(line_p old, line_p new, bblock_p b);
|
||||
/* The variable referenced by the
|
||||
* EM instruction 'old' must be replaced
|
||||
* by the variable referenced by 'new'.
|
||||
*/
|
||||
extern bool value_retained(); /* (line_p copy; short defnr; line_p use;
|
||||
* bblock_p b)
|
||||
bool value_retained(line_p copy, short defnr, line_p use, bblock_p b);
|
||||
/* bblock_p b)
|
||||
* See if the right hand side variable of the
|
||||
* copy still has the same value at 'use'.
|
||||
* If the copy and the use are in the same
|
||||
|
||||
@ -27,12 +27,11 @@ short nrexpldefs; /* number of explicit definitions */
|
||||
line_p *defs;
|
||||
cset *vardefs;
|
||||
|
||||
STATIC cset all_globl_defs, all_indir_defs;
|
||||
static cset all_globl_defs, all_indir_defs;
|
||||
/* auxiliary sets, used by gen_sets */
|
||||
|
||||
|
||||
bool does_expl_def(l)
|
||||
line_p l;
|
||||
bool does_expl_def(line_p l)
|
||||
{
|
||||
/* See if instruction l does an explicit definition */
|
||||
|
||||
@ -52,12 +51,12 @@ bool does_expl_def(l)
|
||||
return FALSE;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool does_impl_def(l)
|
||||
line_p l;
|
||||
bool does_impl_def(line_p l)
|
||||
{
|
||||
/* See if instruction l does an implicit definition */
|
||||
|
||||
@ -77,11 +76,11 @@ bool does_impl_def(l)
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
make_defs(p)
|
||||
proc_p p;
|
||||
void make_defs(proc_p p)
|
||||
{
|
||||
/* Make a map of all explicit definitions
|
||||
* occurring in p.
|
||||
@ -93,8 +92,8 @@ make_defs(p)
|
||||
* explicit definition.
|
||||
*/
|
||||
|
||||
register bblock_p b;
|
||||
register line_p l;
|
||||
bblock_p b;
|
||||
line_p l;
|
||||
short v, i, cnt = 0;
|
||||
bool found;
|
||||
|
||||
@ -134,8 +133,7 @@ make_defs(p)
|
||||
|
||||
|
||||
|
||||
STATIC init_gen(nrdefs)
|
||||
short nrdefs;
|
||||
static void init_gen(short nrdefs)
|
||||
{
|
||||
/* Initializing routine of gen_sets. Compute the set
|
||||
* of all implicit definitions to global variables
|
||||
@ -161,7 +159,7 @@ STATIC init_gen(nrdefs)
|
||||
|
||||
|
||||
|
||||
STATIC clean_gen()
|
||||
static void clean_gen()
|
||||
{
|
||||
Cdeleteset(all_globl_defs);
|
||||
Cdeleteset(all_indir_defs);
|
||||
@ -169,9 +167,7 @@ STATIC clean_gen()
|
||||
|
||||
|
||||
|
||||
STATIC bool same_target(l,defnr)
|
||||
line_p l;
|
||||
short defnr;
|
||||
static bool same_target(line_p l, short defnr)
|
||||
{
|
||||
/* See if l defines the same variable as def */
|
||||
|
||||
@ -200,9 +196,7 @@ STATIC bool same_target(l,defnr)
|
||||
|
||||
|
||||
|
||||
STATIC rem_prev_defs(l,gen_p)
|
||||
line_p l;
|
||||
cset *gen_p;
|
||||
static void rem_prev_defs(line_p l, cset *gen_p)
|
||||
{
|
||||
/* Remove all definitions in gen that define the
|
||||
* same variable as l.
|
||||
@ -223,9 +217,7 @@ STATIC rem_prev_defs(l,gen_p)
|
||||
|
||||
|
||||
|
||||
STATIC impl_globl_defs(p,gen_p)
|
||||
proc_p p;
|
||||
cset *gen_p;
|
||||
static void impl_globl_defs(proc_p p, cset *gen_p)
|
||||
{
|
||||
/* Add all definitions of global variables
|
||||
* that are generated implicitly by a call
|
||||
@ -249,9 +241,7 @@ STATIC impl_globl_defs(p,gen_p)
|
||||
|
||||
|
||||
|
||||
STATIC impl_gen_defs(l,gen_p)
|
||||
line_p l;
|
||||
cset *gen_p;
|
||||
static void impl_gen_defs(line_p l, cset *gen_p)
|
||||
{
|
||||
/* Add all definitions generated implicitly by instruction l
|
||||
* to gen_p. l may be a call or some kind of indirect
|
||||
@ -287,16 +277,15 @@ STATIC impl_gen_defs(l,gen_p)
|
||||
|
||||
|
||||
|
||||
gen_sets(p)
|
||||
proc_p p;
|
||||
void gen_sets(proc_p p)
|
||||
{
|
||||
/* Compute for every basic block b of p the
|
||||
* set GEN(b) of definitions in b (explicit as
|
||||
* well as implicit) that reach the end of b.
|
||||
*/
|
||||
|
||||
register bblock_p b;
|
||||
register line_p l;
|
||||
bblock_p b;
|
||||
line_p l;
|
||||
short defnr = 1;
|
||||
|
||||
init_gen(nrdefs); /* compute all_globl_defs and all_indir_defs */
|
||||
@ -329,9 +318,7 @@ gen_sets(p)
|
||||
|
||||
|
||||
|
||||
STATIC killed_defs(v,b)
|
||||
short v;
|
||||
bblock_p b;
|
||||
static void killed_defs(short v, bblock_p b)
|
||||
{
|
||||
/* Put all definitions of v occurring outside b
|
||||
* in KILL(b). In fact, we also put explicit
|
||||
@ -355,8 +342,7 @@ STATIC killed_defs(v,b)
|
||||
|
||||
|
||||
|
||||
kill_sets(p)
|
||||
proc_p p;
|
||||
void kill_sets(proc_p p)
|
||||
{
|
||||
/* For every basic block b of p compute the set
|
||||
* KILL(b) of definitions outside b that define
|
||||
@ -365,7 +351,7 @@ kill_sets(p)
|
||||
* definitions.
|
||||
*/
|
||||
|
||||
register bblock_p b;
|
||||
bblock_p b;
|
||||
Cindex i;
|
||||
short v;
|
||||
|
||||
|
||||
@ -13,22 +13,22 @@ extern short nrexpldefs; /* number of explicit definitions */
|
||||
extern line_p *defs; /* map of explicit definitions */
|
||||
extern cset *vardefs; /* set of explicit defs. of all variables */
|
||||
|
||||
extern make_defs(); /* (proc_p p)
|
||||
* Compute defs[], vardefs[]
|
||||
void make_defs(proc_p p);
|
||||
/* Compute defs[], vardefs[]
|
||||
* and CHGVARS(b) (for every b).
|
||||
*/
|
||||
extern gen_sets(); /* (proc_p p)
|
||||
* Compute GEN(b) (for every b).
|
||||
void gen_sets(proc_p p);
|
||||
/* Compute GEN(b) (for every b).
|
||||
*/
|
||||
extern kill_sets(); /* (proc_p p)
|
||||
*Compute KILL(b) (for every b).
|
||||
void kill_sets(proc_p p);
|
||||
/*Compute KILL(b) (for every b).
|
||||
*/
|
||||
extern bool does_expl_def(); /* (line_p l)
|
||||
* See if instruction l does an explicit
|
||||
bool does_expl_def(line_p l);
|
||||
/* See if instruction l does an explicit
|
||||
* definition (e.g. a STL).
|
||||
*/
|
||||
extern bool does_impl_def(); /* (line_p l)
|
||||
* See if instruction l does an implicit
|
||||
bool does_impl_def(line_p l);
|
||||
/* See if instruction l does an implicit
|
||||
* definition (e.g. a CAL).
|
||||
*/
|
||||
|
||||
|
||||
@ -13,15 +13,15 @@ static char rcsid[] = "$Id$";
|
||||
#include "ranlib.h"
|
||||
#include "const.h"
|
||||
#include "debug.h"
|
||||
#include "defs.h"
|
||||
#include "memory.h"
|
||||
#include "defs.h"
|
||||
|
||||
#define ENDLIB ((long)0)
|
||||
|
||||
extern ind_t hard_alloc();
|
||||
|
||||
static struct ar_hdr arhdr;
|
||||
|
||||
static void notelib(long pos);
|
||||
|
||||
/*
|
||||
* First read a long telling how many ranlib structs there are, then
|
||||
* the structs themselves. Second read a long telling how many chars there are
|
||||
@ -29,25 +29,24 @@ static struct ar_hdr arhdr;
|
||||
* We keep only one ranlib table in core, so this table always starts at offset
|
||||
* (ind_t)0 from its base.
|
||||
*/
|
||||
static long
|
||||
getsymdeftable()
|
||||
static long getsymdeftable()
|
||||
{
|
||||
register ind_t off;
|
||||
register struct ranlib *ran;
|
||||
register long count;
|
||||
register long nran, nchar;
|
||||
ind_t off;
|
||||
struct ranlib *ran;
|
||||
long count;
|
||||
long nran, nchar;
|
||||
extern long rd_long();
|
||||
extern int infile;
|
||||
|
||||
count = nran = rd_long(infile);
|
||||
debug("%ld ranlib structs, ", nran, 0, 0, 0);
|
||||
debug("%ld ranlib structs, ", nran);
|
||||
off = hard_alloc(ALLORANL, nran * sizeof(struct ranlib));
|
||||
if (off == BADOFF)
|
||||
fatal("no space for ranlib structs");
|
||||
ran = (struct ranlib *)address(ALLORANL, off);
|
||||
rd_ranlib(infile, ran, count);
|
||||
nchar = rd_long(infile);
|
||||
debug("%ld ranlib chars\n", nchar, 0, 0, 0);
|
||||
debug("%ld ranlib chars\n", nchar);
|
||||
if ((off = hard_alloc(ALLORANL, nchar)) == BADOFF)
|
||||
fatal("no space for ranlib strings");
|
||||
rd_bytes(infile, address(ALLORANL, off), nchar);
|
||||
@ -77,7 +76,7 @@ extern char *modulname;
|
||||
* scan the table again. We perform these actions as long as new symbols
|
||||
* are defined.
|
||||
*/
|
||||
arch()
|
||||
void arch()
|
||||
{
|
||||
long nran;
|
||||
bool resolved;
|
||||
@ -89,7 +88,7 @@ arch()
|
||||
register ind_t ranindex;
|
||||
register long count;
|
||||
|
||||
debug("(re)scan ranlib table\n", 0, 0, 0, 0);
|
||||
debug("(re)scan ranlib table\n");
|
||||
ranindex = (ind_t)0;
|
||||
count = nran;
|
||||
resolved = FALSE;
|
||||
@ -112,7 +111,7 @@ arch()
|
||||
seek(ran->ran_pos);
|
||||
get_archive_header(&arhdr);
|
||||
modulname = arhdr.ar_name;
|
||||
verbose("defines %s", string, 0, 0, 0);
|
||||
verbose("defines %s", string);
|
||||
resolved = TRUE;
|
||||
/*
|
||||
* This archive member is going to be linked,
|
||||
@ -139,10 +138,9 @@ arch()
|
||||
* An archive member that will be loaded is remembered by storing its position
|
||||
* in the archive into the table of positions.
|
||||
*/
|
||||
notelib(pos)
|
||||
long pos;
|
||||
static void notelib(long pos)
|
||||
{
|
||||
register ind_t off;
|
||||
ind_t off;
|
||||
|
||||
if ((off = hard_alloc(ALLOARCH, (long)sizeof(long))) == BADOFF)
|
||||
fatal("no space for archive position");
|
||||
@ -161,10 +159,10 @@ static ind_t posindex = (ind_t)0;
|
||||
* that we've processed all needed modules in this archive. Each group of
|
||||
* positions of an archive is terminated with ENDLIB.
|
||||
*/
|
||||
arch2()
|
||||
void arch2()
|
||||
{
|
||||
register long *pos;
|
||||
register ind_t localpos;
|
||||
long *pos;
|
||||
ind_t localpos;
|
||||
|
||||
localpos = posindex;
|
||||
for ( pos = (long *)address(ALLOARCH, localpos);
|
||||
@ -174,7 +172,7 @@ arch2()
|
||||
seek(*pos);
|
||||
get_archive_header(&arhdr);
|
||||
modulname = arhdr.ar_name;
|
||||
debug("%s: archive member\n", modulname, 0, 0, 0);
|
||||
debug("%s: archive member\n", modulname);
|
||||
finish();
|
||||
}
|
||||
localpos += sizeof(long); /* Skip ENDLIB. */
|
||||
|
||||
@ -6,14 +6,14 @@
|
||||
|
||||
#ifdef NDEBUG
|
||||
|
||||
#define debug(s, a1, a2, a3, a4)
|
||||
#define debug(s)
|
||||
|
||||
#else
|
||||
extern int DEB;
|
||||
|
||||
#define debug(s, a1, a2, a3, a4) (DEB && printf(s, a1, a2, a3, a4))
|
||||
#define debug(s...) (DEB && printf(s))
|
||||
|
||||
#endif
|
||||
|
||||
extern int Verbose;
|
||||
#define verbose(s, a1, a2, a3, a4) (Verbose && do_verbose(s, a1, a2, a3, a4))
|
||||
#define verbose(s...) (Verbose && do_verbose(s))
|
||||
|
||||
@ -12,3 +12,73 @@
|
||||
#define ISCOMMON(n) (((n)->on_type & (S_COM | S_EXT)) == (S_COM | S_EXT))
|
||||
|
||||
#define mustsavelocal(name) (!((name)->on_type & S_SCT))
|
||||
|
||||
/* archive.c */
|
||||
void arch();
|
||||
void arch2();
|
||||
|
||||
/* extract.c */
|
||||
void extract();
|
||||
void namerelocate(struct outname *name);
|
||||
|
||||
/* finish.c */
|
||||
void finish();
|
||||
void do_crs(struct outname *base, unsigned int count);
|
||||
|
||||
|
||||
/* main.c */
|
||||
bool setbit(int indx, char *string);
|
||||
void addbase(struct outname *name);
|
||||
|
||||
/* output.c */
|
||||
void endoutput();
|
||||
void beginoutput();
|
||||
|
||||
/* error.c */
|
||||
void stop();
|
||||
void fatal(char *format, ...);
|
||||
void warning(char *format, ...);
|
||||
void error(char *format, ...);
|
||||
int do_verbose(char *format, ...);
|
||||
|
||||
/* read.c */
|
||||
void rd_fatal();
|
||||
|
||||
/* write.c */
|
||||
void wr_fatal();
|
||||
void begin_write();
|
||||
void end_write();
|
||||
void wrt_emit(char *emit, int sectindex, long cnt);
|
||||
void wrt_nulls(int sectindex, long cnt);
|
||||
void wrt_name(struct outname *name, int writename);
|
||||
|
||||
/* sym.c */
|
||||
void init_symboltable();
|
||||
struct outname *searchname(char *string, int hashval);
|
||||
void entername(struct outname *name, int hashval);
|
||||
unsigned int indexof(struct outname *name);
|
||||
int hash(char *p);
|
||||
|
||||
/* save.c */
|
||||
void savemagic();
|
||||
void savehdr(struct ar_hdr * hdr);
|
||||
ind_t savechar(int piece, ind_t off);
|
||||
void savelocal(struct outname *name);
|
||||
|
||||
/* relocate.c */
|
||||
void relocate(struct outhead *head, char *emit, struct outname names[], struct outrelo *relo, long off);
|
||||
|
||||
/* scan.c */
|
||||
int getfile(char *filename);
|
||||
void closefile(char *filename);
|
||||
void get_archive_header(struct ar_hdr *archive_header);
|
||||
void get_modul();
|
||||
void seek(long pos);
|
||||
void skip_modul(struct outhead *head);
|
||||
void startrelo(struct outhead *head);
|
||||
struct outrelo *nextrelo();
|
||||
char *getemit(struct outhead *head, struct outsect *sects, int sectindex);
|
||||
char *getblk(long totalsz, long *pblksz, int sectindex);
|
||||
void endemit(char *emit);
|
||||
|
||||
/* --- */
|
||||
|
||||
@ -15,7 +15,7 @@ static char rcsid[] = "$Id$";
|
||||
static short nerrors = 0;
|
||||
static void diag(char *, char *, va_list);
|
||||
|
||||
stop()
|
||||
void stop()
|
||||
{
|
||||
extern char *outputname;
|
||||
extern int exitstatus;
|
||||
@ -29,8 +29,7 @@ stop()
|
||||
}
|
||||
|
||||
/* VARARGS1 */
|
||||
void
|
||||
fatal(char *format, ...)
|
||||
void fatal(char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
@ -40,8 +39,7 @@ fatal(char *format, ...)
|
||||
}
|
||||
|
||||
/* VARARGS1 */
|
||||
void
|
||||
warning(char *format, ...)
|
||||
void warning(char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
@ -50,8 +48,7 @@ warning(char *format, ...)
|
||||
}
|
||||
|
||||
/* VARARGS1 */
|
||||
void
|
||||
error(char *format, ...)
|
||||
void error(char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
@ -61,17 +58,16 @@ error(char *format, ...)
|
||||
}
|
||||
|
||||
/* VARARGS1 */
|
||||
void
|
||||
do_verbose(char *format, ...)
|
||||
int do_verbose(char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
diag((char *) 0, format, ap);
|
||||
va_end(ap);
|
||||
return (0==0);
|
||||
}
|
||||
|
||||
static void
|
||||
diag(char *tail, char *format, va_list ap)
|
||||
static void diag(char *tail, char *format, va_list ap)
|
||||
{
|
||||
extern char *progname, *archname, *modulname;
|
||||
|
||||
|
||||
@ -8,25 +8,25 @@ static char rcsid[] = "$Id$";
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "arch.h"
|
||||
#include "out.h"
|
||||
#include "const.h"
|
||||
#include "debug.h"
|
||||
#include "defs.h"
|
||||
#include "memory.h"
|
||||
#include "orig.h"
|
||||
#include "scan.h"
|
||||
#include "defs.h"
|
||||
|
||||
static get_names();
|
||||
static process();
|
||||
static getexternal();
|
||||
static redefine();
|
||||
static transfer();
|
||||
static void get_names(struct outhead *head);
|
||||
static void process(struct outhead *head);
|
||||
static void getexternal(struct outname *name);
|
||||
static void redefine(struct outname *new, struct outname *old);
|
||||
static void transfer(struct outname *src, struct outname *dst);
|
||||
|
||||
extern ind_t savechar();
|
||||
/*
|
||||
* Get section sizes and symboltable information from present module.
|
||||
*/
|
||||
extract()
|
||||
void extract()
|
||||
{
|
||||
struct outhead head;
|
||||
|
||||
@ -49,9 +49,7 @@ unsigned short NGlobals = 0; /* Number of global names. */
|
||||
* appear in the final output file if this module is linked.
|
||||
* That number will be returned.
|
||||
*/
|
||||
static
|
||||
get_names(head)
|
||||
register struct outhead *head;
|
||||
static void get_names(struct outhead *head)
|
||||
{
|
||||
register int nnames;
|
||||
register ind_t nameindex, charindex;
|
||||
@ -105,14 +103,12 @@ get_names(head)
|
||||
|
||||
extern struct orig relorig[];
|
||||
|
||||
static
|
||||
process(head)
|
||||
register struct outhead *head;
|
||||
static void process(struct outhead *head)
|
||||
{
|
||||
register struct outsect *sects;
|
||||
register struct outsect *outsp;
|
||||
register int nsect;
|
||||
register struct orig *orig = relorig;
|
||||
struct outsect *sects;
|
||||
struct outsect *outsp;
|
||||
int nsect;
|
||||
struct orig *orig = relorig;
|
||||
extern struct outhead outhead;
|
||||
extern struct outsect outsect[];
|
||||
|
||||
@ -149,11 +145,10 @@ process(head)
|
||||
* Otherwise we just add the accumulated size of all normal parts in preceding
|
||||
* sections with the same size.
|
||||
*/
|
||||
namerelocate(name)
|
||||
register struct outname *name;
|
||||
void namerelocate(struct outname *name)
|
||||
{
|
||||
register int type = name->on_type;
|
||||
register int sct = type & S_TYP;
|
||||
int type = name->on_type;
|
||||
int sct = type & S_TYP;
|
||||
|
||||
if (sct == S_UND || sct == S_ABS || sct == S_CRS)
|
||||
return;
|
||||
@ -170,9 +165,7 @@ namerelocate(name)
|
||||
* we might need it later on. Otherwise it must confirm to what we already
|
||||
* know about it, and eventually add to that knowledge.
|
||||
*/
|
||||
static
|
||||
getexternal(name)
|
||||
register struct outname *name;
|
||||
static void getexternal(struct outname *name)
|
||||
{
|
||||
register char *string;
|
||||
register int h;
|
||||
@ -213,9 +206,7 @@ getexternal(name)
|
||||
* greatest value so that the common declared name always has enough space.
|
||||
* If a common is defined as a not-common, the old definition is ignored.
|
||||
*/
|
||||
static
|
||||
redefine(new, old)
|
||||
register struct outname *new, *old;
|
||||
static void redefine(struct outname *new, struct outname *old)
|
||||
{
|
||||
if (!ISCOMMON(old)) {
|
||||
if (!ISCOMMON(new))
|
||||
@ -241,11 +232,9 @@ redefine(new, old)
|
||||
/*
|
||||
* Transfer things we want to know from `src' to `dst'.
|
||||
*/
|
||||
static
|
||||
transfer(src, dst)
|
||||
register struct outname *src, *dst;
|
||||
static void transfer(struct outname *src, struct outname *dst)
|
||||
{
|
||||
debug("%s defined here\n", src->on_mptr, 0, 0, 0);
|
||||
debug("%s defined here\n", src->on_mptr);
|
||||
dst->on_valu = src->on_valu;
|
||||
dst->on_type = src->on_type;
|
||||
dst->on_desc = src->on_desc;
|
||||
|
||||
@ -8,28 +8,29 @@ static char rcsid[] = "$Id$";
|
||||
|
||||
#include <out.h>
|
||||
#include "const.h"
|
||||
#include "defs.h"
|
||||
#include "arch.h"
|
||||
#include "memory.h"
|
||||
#include "defs.h"
|
||||
#include "orig.h"
|
||||
#include "scan.h"
|
||||
|
||||
extern bool incore;
|
||||
extern unsigned short NLocals;
|
||||
extern int flagword;
|
||||
extern struct outname *searchname();
|
||||
|
||||
static adjust_names();
|
||||
static handle_relos();
|
||||
static put_locals();
|
||||
static compute_origins();
|
||||
static void adjust_names(struct outname *name, struct outhead *head, char *chars);
|
||||
static void handle_relos(struct outhead *head, struct outsect *sects, struct outname *names);
|
||||
static void put_locals(struct outname *name, unsigned int nnames);
|
||||
static void compute_origins(struct outsect *sect, unsigned int nsect);
|
||||
|
||||
static put_dbug(long offdbug);
|
||||
/*
|
||||
* We know all there is to know about the current module.
|
||||
* Now we relocate the values in the emitted bytes and write
|
||||
* those to the final output file. Then we compute the relative origins
|
||||
* for the next module.
|
||||
*/
|
||||
finish()
|
||||
void finish()
|
||||
{
|
||||
struct outhead *head;
|
||||
struct outsect *sects;
|
||||
@ -56,14 +57,10 @@ finish()
|
||||
/*
|
||||
* Adjust all local names for the move into core.
|
||||
*/
|
||||
static
|
||||
adjust_names(name, head, chars)
|
||||
register struct outname *name;
|
||||
struct outhead *head;
|
||||
register char *chars;
|
||||
static void adjust_names(struct outname *name, struct outhead *head, char *chars)
|
||||
{
|
||||
register int cnt;
|
||||
register long charoff;
|
||||
int cnt;
|
||||
long charoff;
|
||||
struct outname *base = name;
|
||||
|
||||
cnt = head->oh_nname;
|
||||
@ -78,11 +75,9 @@ adjust_names(name, head, chars)
|
||||
}
|
||||
}
|
||||
|
||||
do_crs(base, count)
|
||||
struct outname *base;
|
||||
unsigned count;
|
||||
void do_crs(struct outname *base, unsigned int count)
|
||||
{
|
||||
register struct outname *name = base;
|
||||
struct outname *name = base;
|
||||
|
||||
while (count--) {
|
||||
if ((name->on_type & S_TYP) == S_CRS) {
|
||||
@ -113,16 +108,12 @@ do_crs(base, count)
|
||||
* the relocation table again, because the relocation entries of one section
|
||||
* need not be consecutive.
|
||||
*/
|
||||
static
|
||||
handle_relos(head, sects, names)
|
||||
struct outhead *head;
|
||||
struct outsect *sects;
|
||||
struct outname *names;
|
||||
static void handle_relos(struct outhead *head, struct outsect *sects, struct outname *names)
|
||||
{
|
||||
register struct outrelo *relo;
|
||||
register int sectindex;
|
||||
register int nrelo;
|
||||
register char *emit;
|
||||
struct outrelo *relo;
|
||||
int sectindex;
|
||||
int nrelo;
|
||||
char *emit;
|
||||
extern char *getemit();
|
||||
extern struct outrelo *nextrelo();
|
||||
static long zeros[MAXSECT];
|
||||
@ -206,10 +197,7 @@ handle_relos(head, sects, names)
|
||||
/*
|
||||
* Write out the local names that must be saved.
|
||||
*/
|
||||
static
|
||||
put_locals(name, nnames)
|
||||
struct outname *name;
|
||||
register unsigned nnames;
|
||||
static void put_locals(struct outname *name, unsigned int nnames)
|
||||
{
|
||||
register struct outname *oname = name;
|
||||
register struct outname *iname = oname;
|
||||
@ -230,10 +218,7 @@ put_locals(name, nnames)
|
||||
* Add all flen's and all (size - flen == zero)'s of preceding sections
|
||||
* with the same number.
|
||||
*/
|
||||
static
|
||||
compute_origins(sect, nsect)
|
||||
register struct outsect *sect;
|
||||
register unsigned nsect;
|
||||
static void compute_origins(struct outsect *sect, unsigned int nsect)
|
||||
{
|
||||
extern struct orig relorig[];
|
||||
register struct orig *orig = relorig;
|
||||
@ -250,13 +235,11 @@ compute_origins(sect, nsect)
|
||||
* Write out what is after the string area. This is likely to be
|
||||
* debugging information.
|
||||
*/
|
||||
static
|
||||
put_dbug(offdbug)
|
||||
long offdbug;
|
||||
static put_dbug(long offdbug)
|
||||
{
|
||||
char buf[512];
|
||||
register int nbytes;
|
||||
register long dbugsize;
|
||||
int nbytes;
|
||||
long dbugsize;
|
||||
extern long objectsize;
|
||||
|
||||
dbugsize = objectsize - offdbug;
|
||||
|
||||
154
util/led/main.c
154
util/led/main.c
@ -14,8 +14,9 @@ static char rcsid[] = "$Id$";
|
||||
#include <out.h>
|
||||
#include "const.h"
|
||||
#include "debug.h"
|
||||
#include "defs.h"
|
||||
#include "arch.h"
|
||||
#include "memory.h"
|
||||
#include "defs.h"
|
||||
#include "orig.h"
|
||||
|
||||
extern bool incore;
|
||||
@ -27,27 +28,26 @@ int DEB = 0;
|
||||
#endif
|
||||
int Verbose = 0;
|
||||
|
||||
static initializations();
|
||||
static first_pass();
|
||||
static long number();
|
||||
static setlign();
|
||||
static setbase();
|
||||
static struct outname *makename();
|
||||
static pass1();
|
||||
static evaluate();
|
||||
static norm_commons();
|
||||
static complete_sections();
|
||||
static change_names();
|
||||
static bool tstbit();
|
||||
static second_pass();
|
||||
static pass2();
|
||||
static void initializations(int argc, char *argv[]);
|
||||
static void first_pass(char *argv[]);
|
||||
static long number(char *s);
|
||||
static void setlign(int sectno, bool lign);
|
||||
static void setbase(int sectno, long base);
|
||||
static struct outname *makename(char *string);
|
||||
static void pass1(char *file);
|
||||
static void evaluate();
|
||||
static void norm_commons();
|
||||
static void complete_sections();
|
||||
static void change_names();
|
||||
static bool tstbit(int indx, char *string);
|
||||
static void second_pass(char *argv[]);
|
||||
static void pass2(char *file);
|
||||
#ifndef NOSTATISTICS
|
||||
static do_statistics();
|
||||
static void do_statistics();
|
||||
#endif
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
initializations(argc, argv);
|
||||
first_pass(argv);
|
||||
@ -60,13 +60,14 @@ main(argc, argv)
|
||||
second_pass(argv);
|
||||
endoutput();
|
||||
stop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef NOSTATISTICS
|
||||
static
|
||||
do_statistics()
|
||||
static void do_statistics()
|
||||
{
|
||||
register struct memory *m = mems;
|
||||
struct memory *m = mems;
|
||||
|
||||
while (m <= &mems[NMEMS-1]) {
|
||||
fprintf(stderr, "mem %d: full %lx, free %lx\n",
|
||||
@ -84,10 +85,7 @@ struct outhead outhead; /* Header of final output file. */
|
||||
struct outsect outsect[MAXSECT];/* Its section table. */
|
||||
|
||||
/* ARGSUSED */
|
||||
static
|
||||
initializations(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
static void initializations(int argc, char *argv[])
|
||||
{
|
||||
/*
|
||||
* Avoid malloc()s.
|
||||
@ -115,11 +113,9 @@ int exitstatus = 0;
|
||||
* If the argument starts with a '-', it's a flag, else it is either
|
||||
* a plain file to be loaded, or an archive.
|
||||
*/
|
||||
static
|
||||
first_pass(argv)
|
||||
register char **argv;
|
||||
static void first_pass(char *argv[])
|
||||
{
|
||||
register char *argp;
|
||||
char *argp;
|
||||
int sectno;
|
||||
int h;
|
||||
extern int atoi();
|
||||
@ -249,13 +245,11 @@ first_pass(argv)
|
||||
* else if it starts with 0, it's octal,
|
||||
* else it's decimal.
|
||||
*/
|
||||
static long
|
||||
number(s)
|
||||
register char *s;
|
||||
static long number(char *s)
|
||||
{
|
||||
register int digit;
|
||||
register long value = 0;
|
||||
register int radix = 10;
|
||||
int digit;
|
||||
long value = 0;
|
||||
int radix = 10;
|
||||
|
||||
if (*s == '0') {
|
||||
radix = 8;
|
||||
@ -268,7 +262,7 @@ number(s)
|
||||
s++;
|
||||
}
|
||||
}
|
||||
while (digit = *s++) {
|
||||
while ((digit = *s++)) {
|
||||
if (digit >= 'A' && digit <= 'F')
|
||||
digit = digit - 'A' + 10;
|
||||
else if (digit >= 'a' && digit <= 'f')
|
||||
@ -293,18 +287,12 @@ static long sect_base[MAXSECT];
|
||||
static char lignmap[MAXSECT / WIDTH];
|
||||
static long sect_lign[MAXSECT];
|
||||
|
||||
/*
|
||||
/*
|
||||
* Set the alignment of section `sectno' to `lign', if this doesn't
|
||||
* conflict with earlier alignment.
|
||||
*/
|
||||
static
|
||||
setlign(sectno, lign)
|
||||
register int sectno;
|
||||
register long lign;
|
||||
static void setlign(int sectno, bool lign)
|
||||
{
|
||||
extern bool setbit();
|
||||
|
||||
if (setbit(sectno, lignmap) && sect_lign[sectno] != lign)
|
||||
fatal("section has different alignments");
|
||||
if (lign == (long)0)
|
||||
@ -316,10 +304,7 @@ setlign(sectno, lign)
|
||||
* Set the base of section `sectno' to `base', if no other base has been
|
||||
* given yet.
|
||||
*/
|
||||
static
|
||||
setbase(sectno, base)
|
||||
register int sectno;
|
||||
register long base;
|
||||
static void setbase(int sectno, long base)
|
||||
{
|
||||
extern bool setbit();
|
||||
|
||||
@ -328,9 +313,7 @@ setbase(sectno, base)
|
||||
sect_base[sectno] = base;
|
||||
}
|
||||
|
||||
static struct outname *
|
||||
makename(string)
|
||||
char *string;
|
||||
static struct outname *makename(char *string)
|
||||
{
|
||||
static struct outname namebuf;
|
||||
|
||||
@ -346,16 +329,14 @@ makename(string)
|
||||
* extracted. If it is an archive it is examined to see if it defines any
|
||||
* undefined symbols.
|
||||
*/
|
||||
static
|
||||
pass1(file)
|
||||
char *file;
|
||||
static void pass1(char *file)
|
||||
{
|
||||
if (getfile(file) == PLAIN) {
|
||||
debug("%s: plain file\n", file, 0, 0, 0);
|
||||
debug("%s: plain file\n", file);
|
||||
extract();
|
||||
} else {
|
||||
/* It must be an archive. */
|
||||
debug("%s: archive\n", file, 0, 0, 0);
|
||||
debug("%s: archive\n", file);
|
||||
arch();
|
||||
}
|
||||
closefile(file);
|
||||
@ -370,8 +351,7 @@ pass1(file)
|
||||
* sections. We then add the section bases to the values of names in
|
||||
* corresponding sections.
|
||||
*/
|
||||
static
|
||||
evaluate()
|
||||
static void evaluate()
|
||||
{
|
||||
norm_commons();
|
||||
complete_sections();
|
||||
@ -395,12 +375,11 @@ long sect_comm[MAXSECT];
|
||||
* just like "normal" names. We also count the total size of common names
|
||||
* within each section to be able to compute the final size in the machine.
|
||||
*/
|
||||
static
|
||||
norm_commons()
|
||||
static void norm_commons()
|
||||
{
|
||||
register struct outname *name;
|
||||
register int cnt;
|
||||
register int und = FALSE;
|
||||
struct outname *name;
|
||||
int cnt;
|
||||
int und = FALSE;
|
||||
|
||||
name = (struct outname *)address(ALLOGLOB, (ind_t)0);
|
||||
cnt = NGlobals;
|
||||
@ -433,8 +412,8 @@ norm_commons()
|
||||
cnt = NGlobals;
|
||||
while (cnt-- > 0) {
|
||||
if (!ISABSOLUTE(name) && ISCOMMON(name)) {
|
||||
register long size;
|
||||
register int sectindex;
|
||||
long size;
|
||||
int sectindex;
|
||||
|
||||
size = name->on_valu; /* XXX rounding? */
|
||||
sectindex = (name->on_type & S_TYP) - S_MIN;
|
||||
@ -454,13 +433,12 @@ struct orig relorig[MAXSECT];
|
||||
* Compute the offsets in file and machine that the sections will have.
|
||||
* Also set the origins to 0.
|
||||
*/
|
||||
static
|
||||
complete_sections()
|
||||
static void complete_sections()
|
||||
{
|
||||
register long base = 0;
|
||||
register long foff;
|
||||
register struct outsect *sc;
|
||||
register int sectindex;
|
||||
long base = 0;
|
||||
long foff;
|
||||
struct outsect *sc;
|
||||
int sectindex;
|
||||
|
||||
foff = SZ_HEAD + outhead.oh_nsect * SZ_SECT;
|
||||
for (sectindex = 0; sectindex < outhead.oh_nsect; sectindex++) {
|
||||
@ -492,11 +470,10 @@ complete_sections()
|
||||
* For each name we add the base of its section to its value, unless
|
||||
* the output has to be able to be linked again, as indicated by RFLAG.
|
||||
*/
|
||||
static
|
||||
change_names()
|
||||
static void change_names()
|
||||
{
|
||||
register int cnt;
|
||||
register struct outname *name;
|
||||
int cnt;
|
||||
struct outname *name;
|
||||
|
||||
name = (struct outname *)address(ALLOGLOB, (ind_t)0);
|
||||
cnt = NGlobals;
|
||||
@ -523,10 +500,7 @@ change_names()
|
||||
* This function sets a bit with index `indx' in string.
|
||||
* It returns whether it was already set.
|
||||
*/
|
||||
bool
|
||||
setbit(indx, string)
|
||||
int indx;
|
||||
char string[];
|
||||
bool setbit(int indx, char *string)
|
||||
{
|
||||
register int byte_index, bit_index;
|
||||
register int byte;
|
||||
@ -546,10 +520,7 @@ setbit(indx, string)
|
||||
/*
|
||||
* This function returns whether the bit given by `indx' is set in `string'.
|
||||
*/
|
||||
static bool
|
||||
tstbit(indx, string)
|
||||
int indx;
|
||||
char string[];
|
||||
static bool tstbit(int indx, char *string)
|
||||
{
|
||||
register int byte_index, bit_index;
|
||||
register int byte;
|
||||
@ -565,8 +536,7 @@ tstbit(indx, string)
|
||||
/*
|
||||
* Add the base of the section of a name to its value.
|
||||
*/
|
||||
addbase(name)
|
||||
struct outname *name;
|
||||
void addbase(struct outname *name)
|
||||
{
|
||||
register int type = name->on_type & S_TYP;
|
||||
register int sectindex = type - S_MIN;
|
||||
@ -581,7 +551,7 @@ addbase(name)
|
||||
address((name->on_type & S_EXT) ? ALLOGCHR : ALLOLCHR,
|
||||
(ind_t)name->on_foff
|
||||
),
|
||||
name->on_type, name->on_valu, 0
|
||||
name->on_type, name->on_valu
|
||||
);
|
||||
}
|
||||
|
||||
@ -590,9 +560,7 @@ addbase(name)
|
||||
/*
|
||||
* Flags have already been processed, so we ignore them here.
|
||||
*/
|
||||
static
|
||||
second_pass(argv)
|
||||
char **argv;
|
||||
static void second_pass(char *argv[])
|
||||
{
|
||||
passnumber = SECOND;
|
||||
while (*++argv) {
|
||||
@ -611,16 +579,14 @@ second_pass(argv)
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
pass2(file)
|
||||
char *file;
|
||||
static void pass2(char *file)
|
||||
{
|
||||
if (getfile(file) == PLAIN) {
|
||||
debug("%s: plain file\n", file, 0, 0, 0);
|
||||
debug("%s: plain file\n", file);
|
||||
finish();
|
||||
} else {
|
||||
/* It must be an archive. */
|
||||
debug("%s: archive\n", file, 0, 0, 0);
|
||||
debug("%s: archive\n", file);
|
||||
arch2();
|
||||
}
|
||||
closefile(file);
|
||||
|
||||
@ -26,11 +26,15 @@ static char rcsid[] = "$Id$";
|
||||
#include "const.h"
|
||||
#include "assert.h"
|
||||
#include "debug.h"
|
||||
#include "arch.h"
|
||||
#include "memory.h"
|
||||
#include "defs.h"
|
||||
|
||||
static copy_down();
|
||||
static copy_up();
|
||||
static free_saved_moduls();
|
||||
static ind_t move_up(int piece, ind_t incr);
|
||||
static bool compact(int piece, ind_t incr, int flag);
|
||||
static void copy_down(struct memory *mem, ind_t dist);
|
||||
static void copy_up(struct memory *mem, ind_t dist);
|
||||
static void free_saved_moduls();
|
||||
|
||||
struct memory mems[NMEMS];
|
||||
|
||||
@ -42,10 +46,9 @@ ind_t core_position = (ind_t)0; /* Index of current module. */
|
||||
static char *BASE;
|
||||
static ind_t refused;
|
||||
|
||||
sbreak(incr)
|
||||
ind_t incr;
|
||||
int sbreak(ind_t incr)
|
||||
{
|
||||
unsigned int inc;
|
||||
unsigned int inc;
|
||||
|
||||
incr = (incr + (GRANULE - 1)) & ~(GRANULE - 1);
|
||||
|
||||
@ -66,11 +69,11 @@ sbreak(incr)
|
||||
* Initialize some pieces of core. We hope that this will be our last
|
||||
* real allocation, meaning we've made the right choices.
|
||||
*/
|
||||
init_core()
|
||||
void init_core()
|
||||
{
|
||||
register char *base;
|
||||
register ind_t total_size;
|
||||
register struct memory *mem;
|
||||
char *base;
|
||||
ind_t total_size;
|
||||
struct memory *mem;
|
||||
extern char *sbrk();
|
||||
|
||||
#include "mach.c"
|
||||
@ -134,17 +137,14 @@ init_core()
|
||||
* higher than `piece' up with the size of the block.
|
||||
* Move up as much as possible, if "incr" fails.
|
||||
*/
|
||||
static ind_t
|
||||
move_up(piece, incr)
|
||||
register int piece;
|
||||
register ind_t incr;
|
||||
static ind_t move_up(int piece, ind_t incr)
|
||||
{
|
||||
register struct memory *mem;
|
||||
#ifndef NOSTATISTICS
|
||||
extern int statistics;
|
||||
#endif
|
||||
|
||||
debug("move_up(%d, %d)\n", piece, (int)incr, 0, 0);
|
||||
debug("move_up(%d, %d)\n", piece, (int)incr);
|
||||
while (incr > 0 && sbreak(incr) == -1)
|
||||
incr -= INCRSIZE;
|
||||
|
||||
@ -171,23 +171,20 @@ extern int passnumber;
|
||||
* bytes of all higher pieces and move them up. We return whether we have
|
||||
* enough bytes, the first or the second time.
|
||||
*/
|
||||
static bool
|
||||
compact(piece, incr, flag)
|
||||
register int piece;
|
||||
register ind_t incr;
|
||||
#define NORMAL 0
|
||||
#define FREEZE 1
|
||||
#define FORCED 2
|
||||
static bool compact(int piece, ind_t incr, int flag)
|
||||
{
|
||||
register ind_t gain, size;
|
||||
register struct memory *mem;
|
||||
ind_t gain, size;
|
||||
struct memory *mem;
|
||||
int min = piece, max = piece;
|
||||
#define SHIFT_COUNT 2 /* let pieces only contribute if their free
|
||||
memory is more than 1/2**SHIFT_COUNT * 100 %
|
||||
of its occupied memory
|
||||
*/
|
||||
|
||||
debug("compact(%d, %d, %d)\n", piece, (int)incr, flag, 0);
|
||||
debug("compact(%d, %d, %d)\n", piece, (int)incr, flag);
|
||||
for (mem = &mems[0]; mem < &mems[NMEMS - 1]; mem++) {
|
||||
assert(mem->mem_base + mem->mem_full + mem->mem_left == (mem+1)->mem_base);
|
||||
}
|
||||
@ -278,7 +275,7 @@ compact(piece, incr, flag)
|
||||
mem->mem_left = 0;
|
||||
|
||||
if (gain < incr) {
|
||||
register ind_t up = (ind_t)0;
|
||||
ind_t up = (ind_t)0;
|
||||
|
||||
for (mem = &mems[max]; mem > &mems[piece]; mem--) {
|
||||
/* Here memory is appended after a piece. */
|
||||
@ -312,14 +309,11 @@ compact(piece, incr, flag)
|
||||
* overlap with the old area, but we do not want to overwrite them before they
|
||||
* are copied.
|
||||
*/
|
||||
static
|
||||
copy_down(mem, dist)
|
||||
register struct memory *mem;
|
||||
ind_t dist;
|
||||
static void copy_down(struct memory *mem, ind_t dist)
|
||||
{
|
||||
register char *old;
|
||||
register char *new;
|
||||
register ind_t size;
|
||||
char *old;
|
||||
char *new;
|
||||
ind_t size;
|
||||
|
||||
size = mem->mem_full;
|
||||
old = mem->mem_base;
|
||||
@ -335,14 +329,11 @@ copy_down(mem, dist)
|
||||
* overlap with the old area, but we do not want to overwrite them before they
|
||||
* are copied.
|
||||
*/
|
||||
static
|
||||
copy_up(mem, dist)
|
||||
register struct memory *mem;
|
||||
ind_t dist;
|
||||
static void copy_up(struct memory *mem, ind_t dist)
|
||||
{
|
||||
register char *old;
|
||||
register char *new;
|
||||
register ind_t size;
|
||||
char *old;
|
||||
char *new;
|
||||
ind_t size;
|
||||
|
||||
size = mem->mem_full;
|
||||
old = mem->mem_base + size;
|
||||
@ -361,14 +352,11 @@ static int alloctype = NORMAL;
|
||||
* how many times the area is moved, because of another allocate, this offset
|
||||
* remains valid.
|
||||
*/
|
||||
ind_t
|
||||
alloc(piece, size)
|
||||
int piece;
|
||||
register long size;
|
||||
ind_t alloc(int piece, long size)
|
||||
{
|
||||
register ind_t incr = 0;
|
||||
ind_t left = mems[piece].mem_left;
|
||||
register ind_t full = mems[piece].mem_full;
|
||||
ind_t incr = 0;
|
||||
ind_t left = mems[piece].mem_left;
|
||||
ind_t full = mems[piece].mem_full;
|
||||
|
||||
assert(passnumber == FIRST || (!incore && piece == ALLOMODL));
|
||||
if (size == (long)0)
|
||||
@ -401,13 +389,10 @@ alloc(piece, size)
|
||||
* Same as alloc() but for a piece which really needs it. If the first
|
||||
* attempt fails, release the space occupied by other pieces and try again.
|
||||
*/
|
||||
ind_t
|
||||
hard_alloc(piece, size)
|
||||
register int piece;
|
||||
register long size;
|
||||
ind_t hard_alloc(int piece, long size)
|
||||
{
|
||||
register ind_t ret;
|
||||
register int i;
|
||||
ind_t ret;
|
||||
int i;
|
||||
|
||||
if (size != (ind_t)size)
|
||||
return BADOFF;
|
||||
@ -449,12 +434,11 @@ hard_alloc(piece, size)
|
||||
* at the start of the piece allocated for module contents, thereby
|
||||
* overwriting the saved modules, and release its space.
|
||||
*/
|
||||
static
|
||||
free_saved_moduls()
|
||||
static void free_saved_moduls()
|
||||
{
|
||||
register ind_t size;
|
||||
register char *old, *new;
|
||||
register struct memory *mem = &mems[ALLOMODL];
|
||||
ind_t size;
|
||||
char *old, *new;
|
||||
struct memory *mem = &mems[ALLOMODL];
|
||||
|
||||
size = mem->mem_full - core_position;
|
||||
new = mem->mem_base;
|
||||
@ -470,8 +454,7 @@ free_saved_moduls()
|
||||
* The piece of memory with index `piece' is no longer needed.
|
||||
* We take care that it can be used by compact() later, if needed.
|
||||
*/
|
||||
dealloc(piece)
|
||||
register int piece;
|
||||
void dealloc(int piece)
|
||||
{
|
||||
/*
|
||||
* Some pieces need their memory throughout the program.
|
||||
@ -484,10 +467,7 @@ dealloc(piece)
|
||||
mems[piece].mem_full = (ind_t)0;
|
||||
}
|
||||
|
||||
char *
|
||||
core_alloc(piece, size)
|
||||
register int piece;
|
||||
register long size;
|
||||
char *core_alloc(int piece, long size)
|
||||
{
|
||||
register ind_t off;
|
||||
|
||||
@ -496,22 +476,20 @@ core_alloc(piece, size)
|
||||
return address(piece, off);
|
||||
}
|
||||
|
||||
core_free(piece, p)
|
||||
int piece;
|
||||
char *p;
|
||||
void core_free(int piece, char *p)
|
||||
{
|
||||
char *q = address(piece, mems[piece].mem_full);
|
||||
|
||||
assert(p < q);
|
||||
switch(sizeof(unsigned) == sizeof(char *)) {
|
||||
case 1:
|
||||
if (sizeof(unsigned) == sizeof(char *))
|
||||
{
|
||||
mems[piece].mem_full -= (unsigned) (q - p);
|
||||
mems[piece].mem_left += (unsigned) (q - p);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
else
|
||||
{
|
||||
mems[piece].mem_full -= (ind_t) q - (ind_t) p;
|
||||
mems[piece].mem_left += (ind_t) q - (ind_t) p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -519,9 +497,9 @@ core_free(piece, p)
|
||||
* Reset index into piece of memory for modules and
|
||||
* take care that the allocated pieces will not be moved.
|
||||
*/
|
||||
freeze_core()
|
||||
void freeze_core()
|
||||
{
|
||||
register int i;
|
||||
int i;
|
||||
|
||||
core_position = (ind_t)0;
|
||||
|
||||
@ -549,11 +527,11 @@ freeze_core()
|
||||
* To transform the various pieces of the output in core to the file format,
|
||||
* we must order the bytes in the unsigned shorts and longs as ACK prescribes.
|
||||
*/
|
||||
write_bytes()
|
||||
void write_bytes()
|
||||
{
|
||||
unsigned short nsect;
|
||||
long offchar;
|
||||
register struct memory *mem;
|
||||
struct memory *mem;
|
||||
extern unsigned short NLocals, NGlobals;
|
||||
extern long NLChars, NGChars;
|
||||
extern int flagword;
|
||||
@ -607,10 +585,7 @@ write_bytes()
|
||||
}
|
||||
}
|
||||
|
||||
namecpy(name, nname, offchar)
|
||||
register struct outname *name;
|
||||
register unsigned nname;
|
||||
register long offchar;
|
||||
void namecpy(struct outname *name, unsigned int nname, long offchar)
|
||||
{
|
||||
while (nname--) {
|
||||
if (name->on_foff)
|
||||
|
||||
@ -38,5 +38,13 @@ extern struct memory mems[];
|
||||
#define int_align(sz) (((sz)+(sizeof(int)-1))&~(int)(sizeof(int)-1))
|
||||
|
||||
extern ind_t core_position;
|
||||
extern ind_t hard_alloc();
|
||||
extern ind_t alloc();
|
||||
|
||||
void init_core();
|
||||
ind_t hard_alloc(int piece, long size);
|
||||
ind_t alloc(int piece, long size);
|
||||
void dealloc(int piece);
|
||||
char *core_alloc(int piece, long size);
|
||||
void core_free(int piece, char *p);
|
||||
void freeze_core();
|
||||
void write_bytes();
|
||||
void namecpy(struct outname *name, unsigned int nname, long offchar);
|
||||
|
||||
@ -10,7 +10,7 @@ static char rcsid[] = "$Id$";
|
||||
#include "const.h"
|
||||
#include "memory.h"
|
||||
|
||||
static generate_section_names();
|
||||
static void generate_section_names();
|
||||
|
||||
extern struct outhead outhead;
|
||||
extern bool incore;
|
||||
@ -22,7 +22,7 @@ extern int flagword;
|
||||
* flag was given.
|
||||
* If this flag is given we don't need the string table either.
|
||||
*/
|
||||
beginoutput()
|
||||
void beginoutput()
|
||||
{
|
||||
extern unsigned short NLocals, NGlobals;
|
||||
extern long NLChars, NGChars;
|
||||
@ -51,12 +51,11 @@ beginoutput()
|
||||
* Generate names for all sections and put them after the global names.
|
||||
* Section names are used for relocation.
|
||||
*/
|
||||
static
|
||||
generate_section_names()
|
||||
static void generate_section_names()
|
||||
{
|
||||
register struct outname *name;
|
||||
register int sectindex;
|
||||
register long size;
|
||||
struct outname *name;
|
||||
int sectindex;
|
||||
long size;
|
||||
extern struct outsect outsect[];
|
||||
extern char *core_alloc();
|
||||
|
||||
@ -78,7 +77,7 @@ generate_section_names()
|
||||
* written out, and we just finish that.
|
||||
* If we did, we write out our pieces of core.
|
||||
*/
|
||||
endoutput()
|
||||
void endoutput()
|
||||
{
|
||||
if (!incore) {
|
||||
if (!(flagword & SFLAG))
|
||||
|
||||
@ -6,9 +6,18 @@
|
||||
static char rcsid[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <out.h>
|
||||
#include "const.h"
|
||||
#include "assert.h"
|
||||
#include "debug.h"
|
||||
#include "arch.h"
|
||||
#include "memory.h"
|
||||
#include "defs.h"
|
||||
|
||||
int infile; /* The current input file. */
|
||||
|
||||
rd_fatal()
|
||||
void rd_fatal()
|
||||
{
|
||||
fatal("read error");
|
||||
}
|
||||
|
||||
@ -11,19 +11,22 @@ static char rcsid[] = "$Id$";
|
||||
#include "out.h"
|
||||
#include "const.h"
|
||||
#include "debug.h"
|
||||
#include "memory.h"
|
||||
#include "arch.h"
|
||||
#include "defs.h"
|
||||
#include "orig.h"
|
||||
|
||||
#define UBYTE(x) ((x) & BYTEMASK)
|
||||
|
||||
static long getvalu(char addr[], char type);
|
||||
static void putvalu(long valu, char addr[], char type);
|
||||
static unsigned int addrelo(struct outrelo *relo, struct outname *names, long *valu_out);
|
||||
|
||||
/*
|
||||
* The bits in type indicate how many bytes the value occupies and what
|
||||
* significance should be attributed to each byte.
|
||||
*/
|
||||
static long
|
||||
getvalu(addr, type)
|
||||
char addr[];
|
||||
char type;
|
||||
static long getvalu(char addr[], char type)
|
||||
{
|
||||
unsigned short word0, word1;
|
||||
|
||||
@ -51,6 +54,7 @@ getvalu(addr, type)
|
||||
fatal("bad relocation size");
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -58,11 +62,7 @@ getvalu(addr, type)
|
||||
* significance should be attributed to each byte.
|
||||
* We do not check for overflow.
|
||||
*/
|
||||
static
|
||||
putvalu(valu, addr, type)
|
||||
long valu;
|
||||
char addr[];
|
||||
char type;
|
||||
static void putvalu(long valu, char addr[], char type)
|
||||
{
|
||||
unsigned short word0, word1;
|
||||
|
||||
@ -120,24 +120,20 @@ extern struct orig relorig[];
|
||||
* Second case: we must update the value by the change
|
||||
* in position of the section of local.
|
||||
*/
|
||||
static unsigned
|
||||
addrelo(relo, names, valu_out)
|
||||
struct outrelo *relo;
|
||||
struct outname *names;
|
||||
long *valu_out; /* Out variable. */
|
||||
static unsigned int addrelo(struct outrelo *relo, struct outname *names, long *valu_out)
|
||||
{
|
||||
register struct outname *local = &names[relo->or_nami];
|
||||
register unsigned short index = NLocals;
|
||||
register long valu = *valu_out;
|
||||
struct outname *local = &names[relo->or_nami];
|
||||
unsigned short index = NLocals;
|
||||
long valu = *valu_out;
|
||||
|
||||
if ((local->on_type & S_SCT)) {
|
||||
register int sectindex = (local->on_type & S_TYP) - S_MIN;
|
||||
int sectindex = (local->on_type & S_TYP) - S_MIN;
|
||||
|
||||
valu += relorig[sectindex].org_size;
|
||||
valu += outsect[sectindex].os_base;
|
||||
index += NGlobals + sectindex;
|
||||
} else {
|
||||
register struct outname *name;
|
||||
struct outname *name;
|
||||
extern int hash();
|
||||
extern struct outname *searchname();
|
||||
extern unsigned indexof();
|
||||
@ -147,7 +143,7 @@ addrelo(relo, names, valu_out)
|
||||
if (name == (struct outname *)0)
|
||||
fatal("name %s not found in pass 2", local->on_mptr);
|
||||
if (ISCOMMON(name) || ISUNDEFINED(name)) {
|
||||
debug("can't relocate from %s\n",local->on_mptr,0,0,0);
|
||||
debug("can't relocate from %s\n",local->on_mptr);
|
||||
index += indexof(name);
|
||||
} else {
|
||||
valu += name->on_valu;
|
||||
@ -167,12 +163,7 @@ addrelo(relo, names, valu_out)
|
||||
* which the header is pointed to by `head'. Relocation is relative to the
|
||||
* names in `names'; `relo' tells how to relocate.
|
||||
*/
|
||||
relocate(head, emit, names, relo, off)
|
||||
struct outhead *head;
|
||||
char *emit;
|
||||
struct outname names[];
|
||||
struct outrelo *relo;
|
||||
long off;
|
||||
void relocate(struct outhead *head, char *emit, struct outname names[], struct outrelo *relo, long off)
|
||||
{
|
||||
long valu;
|
||||
int sectindex = relo->or_sect - S_MIN;
|
||||
|
||||
@ -18,13 +18,13 @@ static char rcsid[] = "$Id$";
|
||||
#include "const.h"
|
||||
#include "assert.h"
|
||||
#include "memory.h"
|
||||
#include "defs.h"
|
||||
|
||||
extern bool incore;
|
||||
extern char *core_alloc();
|
||||
|
||||
savemagic()
|
||||
void savemagic()
|
||||
{
|
||||
register char *p;
|
||||
char *p;
|
||||
|
||||
if (!incore)
|
||||
return;
|
||||
@ -35,10 +35,9 @@ savemagic()
|
||||
}
|
||||
}
|
||||
|
||||
savehdr(hdr)
|
||||
struct ar_hdr *hdr;
|
||||
void savehdr(struct ar_hdr * hdr)
|
||||
{
|
||||
register char *p;
|
||||
char *p;
|
||||
|
||||
if (!incore)
|
||||
return;
|
||||
@ -57,15 +56,10 @@ long NGChars = 0; /* Idem for global names. */
|
||||
* Return its offset in this area. We don't use the first char of the string
|
||||
* area, so that empty strings can be distinguished from the first string.
|
||||
*/
|
||||
ind_t
|
||||
savechar(piece, off)
|
||||
register int piece;
|
||||
register ind_t off;
|
||||
ind_t savechar(int piece, ind_t off)
|
||||
{
|
||||
register long len;
|
||||
register ind_t newoff;
|
||||
extern ind_t alloc();
|
||||
extern ind_t hard_alloc();
|
||||
long len;
|
||||
ind_t newoff;
|
||||
|
||||
if (off == (ind_t)0)
|
||||
return 0;
|
||||
@ -91,8 +85,7 @@ savechar(piece, off)
|
||||
* allocation, but the string of which name->on_foff is the offset may be
|
||||
* destroyed, so we save that first.
|
||||
*/
|
||||
savelocal(name)
|
||||
struct outname *name;
|
||||
void savelocal(struct outname *name)
|
||||
{
|
||||
ind_t savindex;
|
||||
struct outname *new;
|
||||
|
||||
135
util/led/scan.c
135
util/led/scan.c
@ -8,6 +8,7 @@ static char rcsid[] = "$Id$";
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#ifdef SYMDBUG
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
@ -20,6 +21,7 @@ static char rcsid[] = "$Id$";
|
||||
#include "memory.h"
|
||||
#include "scan.h"
|
||||
#include "debug.h"
|
||||
#include "defs.h"
|
||||
|
||||
#define READ 0
|
||||
|
||||
@ -40,20 +42,21 @@ char *modulname; /* Name of object module. */
|
||||
long objectsize;
|
||||
#endif /* SYMDBUG */
|
||||
|
||||
static long align();
|
||||
static long align(long size);
|
||||
static char *modulbase;
|
||||
static long modulsize();
|
||||
static scan_modul();
|
||||
static bool all_alloc();
|
||||
static bool direct_alloc();
|
||||
static bool indirect_alloc();
|
||||
static bool putemitindex();
|
||||
static bool putreloindex();
|
||||
static long modulsize(struct outhead *head);
|
||||
|
||||
static void scan_modul();
|
||||
static bool all_alloc();
|
||||
static bool direct_alloc(struct outhead *head);
|
||||
static bool indirect_alloc(struct outhead *head);
|
||||
static bool putemitindex(ind_t sectindex, ind_t emitoff, int allopiece);
|
||||
static bool putreloindex(ind_t relooff, long nrelobytes);
|
||||
#ifdef SYMDBUG
|
||||
static bool putdbugindex();
|
||||
static bool putdbugindex(ind_t dbugoff, long ndbugbytes);
|
||||
#endif /* SYMDBUG */
|
||||
static get_indirect();
|
||||
static read_modul();
|
||||
static void get_indirect(struct outhead *head, struct outsect *sect);
|
||||
static void read_modul();
|
||||
|
||||
/*
|
||||
* Open the file with name `filename' (if necessary) and examine the first
|
||||
@ -61,9 +64,7 @@ static read_modul();
|
||||
* In case of a plain file, the file pointer is repositioned after the
|
||||
* examination. Otherwise it is at the beginning of the table of contents.
|
||||
*/
|
||||
int
|
||||
getfile(filename)
|
||||
char *filename;
|
||||
int getfile(char *filename)
|
||||
{
|
||||
unsigned int rd_unsigned2();
|
||||
struct ar_hdr archive_header;
|
||||
@ -113,18 +114,17 @@ getfile(filename)
|
||||
fatal("%s: wrong magic number", filename);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
closefile(filename)
|
||||
char *filename;
|
||||
void closefile(char *filename)
|
||||
{
|
||||
if (passnumber == FIRST || !incore)
|
||||
close(infile);
|
||||
}
|
||||
|
||||
get_archive_header(archive_header)
|
||||
register struct ar_hdr *archive_header;
|
||||
void get_archive_header(struct ar_hdr *archive_header)
|
||||
{
|
||||
if (passnumber == FIRST || !incore) {
|
||||
rd_arhdr(infile, archive_header);
|
||||
@ -139,7 +139,7 @@ get_archive_header(archive_header)
|
||||
#endif /* SYMDBUG */
|
||||
}
|
||||
|
||||
get_modul()
|
||||
void get_modul()
|
||||
{
|
||||
if (passnumber == FIRST) {
|
||||
rd_fdopen(infile);
|
||||
@ -155,8 +155,7 @@ get_modul()
|
||||
* to keep everything in core is abandoned, but we will always put the header,
|
||||
* the section table, and the name and string table into core.
|
||||
*/
|
||||
static
|
||||
scan_modul()
|
||||
static void scan_modul()
|
||||
{
|
||||
bool space;
|
||||
struct outhead *head;
|
||||
@ -187,8 +186,7 @@ scan_modul()
|
||||
* If possible, allocate space for the rest of the module. Return whether
|
||||
* this was possible.
|
||||
*/
|
||||
static bool
|
||||
all_alloc()
|
||||
static bool all_alloc()
|
||||
{
|
||||
struct outhead head;
|
||||
extern ind_t hard_alloc();
|
||||
@ -208,12 +206,10 @@ all_alloc()
|
||||
* First allocate the section table and read it in, then allocate the rest
|
||||
* and return whether this succeeded.
|
||||
*/
|
||||
static bool
|
||||
direct_alloc(head)
|
||||
struct outhead *head;
|
||||
static bool direct_alloc(struct outhead *head)
|
||||
{
|
||||
ind_t sectindex = IND_SECT(*head);
|
||||
register struct outsect *sects;
|
||||
struct outsect *sects;
|
||||
unsigned short nsect = head->oh_nsect;
|
||||
long size, rest;
|
||||
extern ind_t hard_alloc();
|
||||
@ -247,11 +243,9 @@ direct_alloc(head)
|
||||
* Allocate space for the indirectly accessed pieces: the section contents and
|
||||
* the relocation table, and put their indices in the right place.
|
||||
*/
|
||||
static bool
|
||||
indirect_alloc(head)
|
||||
struct outhead *head;
|
||||
static bool indirect_alloc(struct outhead *head)
|
||||
{
|
||||
register int allopiece;
|
||||
int allopiece;
|
||||
unsigned short nsect = head->oh_nsect;
|
||||
unsigned short nrelo = head->oh_nrelo;
|
||||
ind_t sectindex = IND_SECT(*head);
|
||||
@ -284,17 +278,13 @@ indirect_alloc(head)
|
||||
* at offset `sectindex'. Put the offset of the allocated piece at offset
|
||||
* `emitoff'.
|
||||
*/
|
||||
static bool
|
||||
putemitindex(sectindex, emitoff, allopiece)
|
||||
ind_t sectindex;
|
||||
ind_t emitoff;
|
||||
int allopiece;
|
||||
static bool putemitindex(ind_t sectindex, ind_t emitoff, int allopiece)
|
||||
{
|
||||
long flen;
|
||||
ind_t emitindex;
|
||||
extern ind_t alloc();
|
||||
static long zeros[MAXSECT];
|
||||
register long zero = zeros[allopiece - ALLOEMIT];
|
||||
long zero = zeros[allopiece - ALLOEMIT];
|
||||
|
||||
/*
|
||||
* Notice that "sectindex" is not a section number!
|
||||
@ -306,9 +296,9 @@ putemitindex(sectindex, emitoff, allopiece)
|
||||
flen = ((struct outsect *)modulptr(sectindex))->os_flen;
|
||||
if (flen && zero) {
|
||||
if ((emitindex = alloc(allopiece, zero)) != BADOFF){
|
||||
register char *p = address(allopiece, emitindex);
|
||||
char *p = address(allopiece, emitindex);
|
||||
|
||||
debug("Zeros %ld\n", zero, 0,0,0);
|
||||
debug("Zeros %ld\n", zero);
|
||||
while (zero--) *p++ = 0;
|
||||
}
|
||||
else return FALSE;
|
||||
@ -327,10 +317,7 @@ putemitindex(sectindex, emitoff, allopiece)
|
||||
* Allocate space for a relocation table with `nrelobytes' bytes, and put the
|
||||
* offset at `relooff'.
|
||||
*/
|
||||
static bool
|
||||
putreloindex(relooff, nrelobytes)
|
||||
ind_t relooff;
|
||||
long nrelobytes;
|
||||
static bool putreloindex(ind_t relooff, long nrelobytes)
|
||||
{
|
||||
ind_t reloindex;
|
||||
extern ind_t alloc();
|
||||
@ -345,10 +332,7 @@ putreloindex(relooff, nrelobytes)
|
||||
/*
|
||||
* Allocate space for debugging information and put the offset at `dbugoff'.
|
||||
*/
|
||||
static bool
|
||||
putdbugindex(dbugoff, ndbugbytes)
|
||||
ind_t relooff;
|
||||
long ndbugbytes;
|
||||
static bool putdbugindex(ind_t dbugoff, long ndbugbytes)
|
||||
{
|
||||
ind_t dbugindex;
|
||||
extern ind_t alloc();
|
||||
@ -365,16 +349,11 @@ putdbugindex(dbugoff, ndbugbytes)
|
||||
* Compute addresses and read in. Remember that the contents of the sections
|
||||
* and also the relocation table are accessed indirectly.
|
||||
*/
|
||||
static
|
||||
get_indirect(head, sect)
|
||||
struct outhead *head; /* not register! Won't compile on
|
||||
SCO Xenix 386 if it is!
|
||||
*/
|
||||
register struct outsect *sect;
|
||||
static void get_indirect(struct outhead *head, struct outsect *sect)
|
||||
{
|
||||
register ind_t *emitindex;
|
||||
register int nsect;
|
||||
register int piece;
|
||||
ind_t *emitindex;
|
||||
int nsect;
|
||||
int piece;
|
||||
ind_t *reloindex;
|
||||
|
||||
emitindex = (ind_t *)modulptr(IND_EMIT(*head));
|
||||
@ -393,8 +372,7 @@ get_indirect(head, sect)
|
||||
/*
|
||||
* Set the file pointer at `pos'.
|
||||
*/
|
||||
seek(pos)
|
||||
long pos;
|
||||
void seek(long pos)
|
||||
{
|
||||
if (passnumber == FIRST || !incore)
|
||||
lseek(infile, pos, 0);
|
||||
@ -405,10 +383,9 @@ seek(pos)
|
||||
* is not. That's why we do it here. If we don't keep everything in core,
|
||||
* we give the space allocated for a module back.
|
||||
*/
|
||||
skip_modul(head)
|
||||
struct outhead *head;
|
||||
void skip_modul(struct outhead *head)
|
||||
{
|
||||
register ind_t skip = modulsize(head);
|
||||
ind_t skip = modulsize(head);
|
||||
|
||||
if (incore) {
|
||||
core_position += int_align(skip);
|
||||
@ -423,11 +400,10 @@ skip_modul(head)
|
||||
/*
|
||||
* Read in what we need in pass 2, because we couldn't keep it in core.
|
||||
*/
|
||||
static
|
||||
read_modul()
|
||||
static void read_modul()
|
||||
{
|
||||
struct outhead *head;
|
||||
register struct outsect *sects;
|
||||
struct outsect *sects;
|
||||
struct outname *names;
|
||||
char *chars;
|
||||
ind_t sectindex, nameindex, charindex;
|
||||
@ -473,9 +449,7 @@ read_modul()
|
||||
* Align `size' to a multiple of the size of a double.
|
||||
* This is assumed to be a power of 2.
|
||||
*/
|
||||
static long
|
||||
align(size)
|
||||
register long size;
|
||||
static long align(long size)
|
||||
{
|
||||
return (size + (sizeof(double) - 1)) & ~(int)(sizeof(double) - 1);
|
||||
}
|
||||
@ -493,9 +467,7 @@ align(size)
|
||||
* 6. the offset of the debugging information.
|
||||
#endif
|
||||
*/
|
||||
static long
|
||||
modulsize(head)
|
||||
register struct outhead *head;
|
||||
static long modulsize(struct outhead *head)
|
||||
{
|
||||
return sizeof(struct outhead) + /* 0 */
|
||||
head->oh_nsect * sizeof(struct outsect) + /* 1 */
|
||||
@ -522,10 +494,9 @@ static unsigned short cnt_relos;
|
||||
static unsigned short relind;
|
||||
#define _RELSIZ 64
|
||||
|
||||
startrelo(head)
|
||||
register struct outhead *head;
|
||||
void startrelo(struct outhead *head)
|
||||
{
|
||||
ind_t reloindex;
|
||||
ind_t reloindex;
|
||||
|
||||
if (incore) {
|
||||
reloindex = *(ind_t *)(modulbase + IND_RELO(*head));
|
||||
@ -538,8 +509,7 @@ startrelo(head)
|
||||
}
|
||||
}
|
||||
|
||||
struct outrelo *
|
||||
nextrelo()
|
||||
struct outrelo *nextrelo()
|
||||
{
|
||||
static struct outrelo relobuf[_RELSIZ];
|
||||
|
||||
@ -562,11 +532,7 @@ nextrelo()
|
||||
* Get the section contents in core of which the describing struct has index
|
||||
* `sectindex'. `Head' points to the header of the module.
|
||||
*/
|
||||
char *
|
||||
getemit(head, sects, sectindex)
|
||||
struct outhead *head;
|
||||
struct outsect *sects;
|
||||
int sectindex;
|
||||
char *getemit(struct outhead *head, struct outsect *sects, int sectindex)
|
||||
{
|
||||
char *ret;
|
||||
ind_t off;
|
||||
@ -588,11 +554,7 @@ getemit(head, sects, sectindex)
|
||||
return address(ALLOEMIT + sectindex, off);
|
||||
}
|
||||
|
||||
char *
|
||||
getblk(totalsz, pblksz, sectindex)
|
||||
long totalsz;
|
||||
long *pblksz;
|
||||
int sectindex;
|
||||
char *getblk(long totalsz, long *pblksz, int sectindex)
|
||||
{
|
||||
char *ret;
|
||||
long sz = (1L << 30);
|
||||
@ -613,8 +575,7 @@ getblk(totalsz, pblksz, sectindex)
|
||||
return (char *) 0;
|
||||
}
|
||||
|
||||
endemit(emit)
|
||||
char *emit;
|
||||
void endemit(char *emit)
|
||||
{
|
||||
core_free(ALLOMODL, emit);
|
||||
}
|
||||
|
||||
@ -14,8 +14,10 @@ static char rcsid[] = "$Id$";
|
||||
#include <stdio.h>
|
||||
#include "out.h"
|
||||
#include "const.h"
|
||||
#include "arch.h"
|
||||
#include "memory.h"
|
||||
#include "debug.h"
|
||||
#include "defs.h"
|
||||
|
||||
/*
|
||||
* Symbol table types. Each hash table entry contains the offset of a symbol
|
||||
@ -35,9 +37,9 @@ static ind_t hashtable[NHASH];
|
||||
/*
|
||||
* Initialize the symbol table. All indices should be noticeably invalid.
|
||||
*/
|
||||
init_symboltable()
|
||||
void init_symboltable()
|
||||
{
|
||||
register ind_t *rap;
|
||||
ind_t *rap;
|
||||
|
||||
for (rap = hashtable; rap < &hashtable[NHASH]; rap++)
|
||||
*rap = BADOFF;
|
||||
@ -50,35 +52,32 @@ init_symboltable()
|
||||
* in this element of the list is returned. When a match cannot be found,
|
||||
* NIL is returned.
|
||||
*/
|
||||
struct outname *
|
||||
searchname(string, hashval)
|
||||
char *string;
|
||||
int hashval;
|
||||
struct outname *searchname(char *string, int hashval)
|
||||
{
|
||||
register char *rcp;
|
||||
register char *namestring;
|
||||
register ind_t symindex;
|
||||
register struct outname *name;
|
||||
register struct symbol *sym;
|
||||
char *rcp;
|
||||
char *namestring;
|
||||
ind_t symindex;
|
||||
struct outname *name;
|
||||
struct symbol *sym;
|
||||
|
||||
symindex = hashtable[hashval];
|
||||
debug("looking for %s %d %ld:", string, hashval, hashtable[hashval], 0);
|
||||
debug("looking for %s %d %ld:", string, hashval, hashtable[hashval]);
|
||||
while (symindex != BADOFF) {
|
||||
sym = (struct symbol *)address(ALLOSYMB, symindex);
|
||||
name = (struct outname *)address(ALLOGLOB, sym->sy_name);
|
||||
namestring = address(ALLOGCHR, (ind_t)name->on_foff);
|
||||
rcp = string;
|
||||
debug("comp %s;", namestring, 0, 0, 0);
|
||||
debug("comp %s;", namestring);
|
||||
while (*rcp == *namestring++)
|
||||
if (*rcp++ == '\0') {
|
||||
debug("found %x, %x, %lx\n",
|
||||
name->on_type, name->on_desc, name->on_valu, 0);
|
||||
name->on_type, name->on_desc, name->on_valu);
|
||||
return name;
|
||||
}
|
||||
symindex = sym->sy_next;
|
||||
}
|
||||
/* Not found. */
|
||||
debug("not found\n", 0, 0, 0, 0);
|
||||
debug("not found\n");
|
||||
return (struct outname *)0;
|
||||
}
|
||||
|
||||
@ -88,22 +87,18 @@ searchname(string, hashval)
|
||||
* destroyed by allocation. However, the string of which name->on_foff is the
|
||||
* offset can be destroyed, so we save it first.
|
||||
*/
|
||||
entername(name, hashval)
|
||||
struct outname *name;
|
||||
int hashval;
|
||||
void entername(struct outname *name, int hashval)
|
||||
{
|
||||
ind_t savindex;
|
||||
ind_t symindex;
|
||||
ind_t namindex;
|
||||
register struct symbol *sym;
|
||||
struct symbol *sym;
|
||||
struct outname *newname;
|
||||
extern ind_t savechar();
|
||||
extern ind_t hard_alloc();
|
||||
|
||||
debug("entername %s %d %x %x", modulptr((ind_t)name->on_foff), hashval, name->on_type, name->on_desc);
|
||||
savindex = savechar(ALLOGCHR, (ind_t)name->on_foff);
|
||||
symindex = hard_alloc(ALLOSYMB, (long)sizeof(struct symbol));
|
||||
debug("; %ld\n", symindex, 0, 0, 0);
|
||||
debug("; %ld\n", symindex);
|
||||
namindex = hard_alloc(ALLOGLOB, (long)sizeof(struct outname));
|
||||
if (savindex == BADOFF || symindex == BADOFF || namindex == BADOFF)
|
||||
fatal("symbol table overflow");
|
||||
@ -120,9 +115,7 @@ entername(name, hashval)
|
||||
* Return the index of `name' in the symbol table in the order in which
|
||||
* it was entered. We need a REAL index, not a byte offset.
|
||||
*/
|
||||
unsigned
|
||||
indexof(name)
|
||||
struct outname *name;
|
||||
unsigned int indexof(struct outname *name)
|
||||
{
|
||||
return name - (struct outname *)address(ALLOGLOB, (ind_t)0);
|
||||
}
|
||||
@ -132,14 +125,12 @@ indexof(name)
|
||||
* 0 <= hash(p) < NHASH, so it can - and will - be used
|
||||
* as index in a hash table.
|
||||
*/
|
||||
int
|
||||
hash(p)
|
||||
register char *p;
|
||||
int hash(char *p)
|
||||
{
|
||||
register unsigned short h = 0;
|
||||
register int c;
|
||||
unsigned short h = 0;
|
||||
int c;
|
||||
|
||||
while (c = *p++) {
|
||||
while ((c = *p++)) {
|
||||
h <<= 2;
|
||||
h += c;
|
||||
}
|
||||
|
||||
@ -13,13 +13,16 @@ static char rcsid[] = "$Id$";
|
||||
#include "const.h"
|
||||
#include "assert.h"
|
||||
#include "memory.h"
|
||||
|
||||
#include "arch.h"
|
||||
#include "defs.h"
|
||||
extern struct outhead outhead;
|
||||
extern struct outsect outsect[];
|
||||
extern int flagword;
|
||||
extern bool incore;
|
||||
|
||||
wr_fatal()
|
||||
static struct outname *sectname(int sectindex);
|
||||
|
||||
void wr_fatal()
|
||||
{
|
||||
fatal("write error");
|
||||
}
|
||||
@ -30,7 +33,7 @@ static long off_char;
|
||||
* Open the output file according to the chosen strategy.
|
||||
* Write away the header and section table: they will not change anymore.
|
||||
*/
|
||||
begin_write()
|
||||
void begin_write()
|
||||
{
|
||||
register struct outhead *hd = &outhead;
|
||||
|
||||
@ -40,9 +43,7 @@ begin_write()
|
||||
off_char = OFF_CHAR(*hd);
|
||||
}
|
||||
|
||||
static struct outname *
|
||||
sectname(sectindex)
|
||||
int sectindex;
|
||||
static struct outname *sectname(int sectindex)
|
||||
{
|
||||
static struct outname namebuf;
|
||||
|
||||
@ -57,10 +58,10 @@ sectname(sectindex)
|
||||
/*
|
||||
* Write out the symbol table and the section names.
|
||||
*/
|
||||
end_write()
|
||||
void end_write()
|
||||
{
|
||||
register struct outname *name;
|
||||
register int sectindex;
|
||||
struct outname *name;
|
||||
int sectindex;
|
||||
extern unsigned short NGlobals;
|
||||
extern long NGChars;
|
||||
|
||||
@ -75,37 +76,31 @@ end_write()
|
||||
for (sectindex = 0; sectindex < outhead.oh_nsect; sectindex++)
|
||||
wrt_name(sectname(sectindex), 1);
|
||||
}
|
||||
|
||||
wrt_emit(emit, sectindex, cnt)
|
||||
char *emit;
|
||||
int sectindex;
|
||||
long cnt;
|
||||
{
|
||||
|
||||
void wrt_emit(char *emit, int sectindex, long cnt)
|
||||
{
|
||||
wr_outsect(sectindex);
|
||||
wr_emit(emit, cnt);
|
||||
}
|
||||
|
||||
wrt_nulls(sectindex, cnt)
|
||||
register long cnt;
|
||||
void wrt_nulls(int sectindex, long cnt)
|
||||
{
|
||||
static char nullbuf[BUFSIZ];
|
||||
|
||||
wr_outsect(sectindex);
|
||||
while (cnt) {
|
||||
register int n = cnt >= BUFSIZ ? BUFSIZ : cnt;
|
||||
int n = cnt >= BUFSIZ ? BUFSIZ : cnt;
|
||||
wr_emit(nullbuf, (long)n);
|
||||
cnt -= n;
|
||||
}
|
||||
}
|
||||
|
||||
wrt_name(name, writename)
|
||||
register struct outname *name;
|
||||
void wrt_name(struct outname *name, int writename)
|
||||
{
|
||||
assert(!incore);
|
||||
assert(!(flagword & SFLAG));
|
||||
if (name->on_mptr != (char *)0) {
|
||||
register long len = strlen(name->on_mptr) + 1;
|
||||
long len = strlen(name->on_mptr) + 1;
|
||||
|
||||
wr_string(name->on_mptr, len);
|
||||
name->on_foff = off_char;
|
||||
|
||||
@ -21,8 +21,9 @@ static struct token aside; /* to put currrent token aside, when a token
|
||||
int newline, lineno; /* To keep track of linenumbers */
|
||||
extern FILE *input; /* file descriptor of machine table */
|
||||
|
||||
LLlex() {
|
||||
register c;
|
||||
int LLlex()
|
||||
{
|
||||
int c;
|
||||
|
||||
if (aside.t_tokno) { /* A token was pushed aside, return it now */
|
||||
dot = aside;
|
||||
@ -116,7 +117,8 @@ LLlex() {
|
||||
}
|
||||
}
|
||||
|
||||
LLmessage(d) {
|
||||
void LLmessage(int d)
|
||||
{
|
||||
static int savlineno;
|
||||
|
||||
if (savlineno != lineno) {
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "misc.h"
|
||||
|
||||
struct hlist { /* linear list of pattern numbers */
|
||||
@ -23,10 +24,10 @@ static struct hlist *hashtable[129]; /* an array of ptr's to these lists,
|
||||
* result of hashing
|
||||
*/
|
||||
|
||||
static unsigned
|
||||
hash(string) char *string; {
|
||||
register char *p;
|
||||
register unsigned i,sum;
|
||||
static unsigned hash(char *string)
|
||||
{
|
||||
char *p;
|
||||
unsigned int i,sum;
|
||||
|
||||
if (strcmp(string,"ANY") == 0) return 128;
|
||||
for (sum=i=0,p=string;*p;i += 3)
|
||||
@ -35,7 +36,8 @@ hash(string) char *string; {
|
||||
}
|
||||
|
||||
|
||||
addtohashtable(s,n) char *s; {
|
||||
void addtohashtable(char *s, int n)
|
||||
{
|
||||
/*
|
||||
* Add a new pattern number to the hashtable.
|
||||
* s is the key, n the pattern number
|
||||
@ -55,8 +57,8 @@ addtohashtable(s,n) char *s; {
|
||||
hashtable[hval] = p;
|
||||
}
|
||||
|
||||
static
|
||||
prhlist(p) struct hlist *p; {
|
||||
static void prhlist(struct hlist *p)
|
||||
{
|
||||
/*
|
||||
* Print a list in reversed order (see comment above)
|
||||
*/
|
||||
@ -67,13 +69,14 @@ prhlist(p) struct hlist *p; {
|
||||
}
|
||||
}
|
||||
|
||||
printhashtable() {
|
||||
void printhashtable()
|
||||
{
|
||||
/*
|
||||
* Print the linear lists, and also output an array of
|
||||
* pointers to them
|
||||
*/
|
||||
register i;
|
||||
register struct hlist *p;
|
||||
int i;
|
||||
struct hlist *p;
|
||||
|
||||
for (i = 1; i <= 128; i++) {
|
||||
fprintf(genc,"int hash%d[] = { ",i);
|
||||
|
||||
@ -19,8 +19,8 @@ static int nerrors;
|
||||
char *linedir = "#line %d \"%s\"\n"; /* format of line directive */
|
||||
char *inpfile;
|
||||
|
||||
main(argc,argv) char *argv[]; {
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
newline = 1;
|
||||
if (argc != 2) {
|
||||
fprintf(stderr,"Usage : %s targetoptimizerdescription\n",argv[0]);
|
||||
@ -44,16 +44,16 @@ main(argc,argv) char *argv[]; {
|
||||
}
|
||||
|
||||
/* VARARGS1 */
|
||||
error(s, s1) char *s, *s1; {
|
||||
|
||||
void error(char *s, char *s1)
|
||||
{
|
||||
nerrors++;
|
||||
fprintf(stderr,"\"%s\", line %d: ",inpfile,lineno);
|
||||
fprintf(stderr,s,s1);
|
||||
putc('\n',stderr);
|
||||
}
|
||||
|
||||
onlyspace(s) register char *s; {
|
||||
|
||||
int onlyspace(char *s)
|
||||
{
|
||||
while (*s) {
|
||||
if (*s != ' ' && *s != '\t' && *s != '\n') return 0;
|
||||
s++;
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "misc.h"
|
||||
#include "symtab.h"
|
||||
@ -31,7 +32,8 @@ static struct pattern *pattable, /* ptr to pattern array */
|
||||
* be allocated
|
||||
*/
|
||||
|
||||
addpattern(str,l,np,nr) char *str; {
|
||||
void addpattern(char *str, int l, int np, int nr)
|
||||
{
|
||||
/*
|
||||
* Just add a pattern to the list.
|
||||
* "str" is the constraint, "l" is the line number,
|
||||
@ -39,7 +41,7 @@ addpattern(str,l,np,nr) char *str; {
|
||||
* "nr" is the number of instructions in the replacement
|
||||
* Space is allocated in chunks of 50
|
||||
*/
|
||||
register struct pattern *p;
|
||||
struct pattern *p;
|
||||
|
||||
if (!pattable) { /* No space allocated yet */
|
||||
pattable = (struct pattern *) malloc(50 * sizeof *pattable);
|
||||
@ -61,13 +63,13 @@ addpattern(str,l,np,nr) char *str; {
|
||||
p->p_nrepl = nr;
|
||||
}
|
||||
|
||||
static
|
||||
prconstraint(str) char *str; {
|
||||
static void prconstraint(char *str)
|
||||
{
|
||||
/*
|
||||
* prints a constraint, with variable names replaced
|
||||
*/
|
||||
char c;
|
||||
register char *p, *q;
|
||||
char *p, *q;
|
||||
struct symtab *name;
|
||||
|
||||
p = str;
|
||||
@ -103,13 +105,14 @@ prconstraint(str) char *str; {
|
||||
}
|
||||
}
|
||||
|
||||
printpatterns() {
|
||||
void printpatterns()
|
||||
{
|
||||
/*
|
||||
* Prints the pattern_descr table and generates the routine
|
||||
* "check_constraint"
|
||||
*/
|
||||
register struct pattern *p;
|
||||
register i;
|
||||
struct pattern *p;
|
||||
int i;
|
||||
|
||||
p = pattable;
|
||||
i = 1;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user