Browse Source

ego now builds and is used.

This needed lots of refactoring to ego --- not all platforms have ego descr
files, and ego will just crash if you invoke it without one. I think originally
it was never intended that these platforms would be used at -O2 or above.

Plats now only specify the ego descr file if they have one.
David Given 7 years ago
parent
commit
5bae29a00c

+ 2 - 1
build.lua

@@ -2,7 +2,7 @@ vars.cflags = {
 	"-g", "-O"
 }
 vars.ackcflags = {
-	"-O"
+	"-O6"
 }
 vars.plats = {
 	"cpm",
@@ -27,6 +27,7 @@ installable {
 		"util/ack+pkg",
 		"util/amisc+pkg",
 		"util/arch+pkg",
+		"util/ego+pkg",
 		"util/led+pkg",
 		"util/misc+pkg",
 		"util/opt+pkg",

+ 1 - 14
lib/descr/fe

@@ -206,19 +206,6 @@ name ego
 	to .gk
 	program {EM}/lib/ack/em_ego
 	mapflag -EGO-* EGO_F={EGO_F?} -*
-# The following lines are obsolete, but here for backwards compatibility.
-# They should be removed some day.
-	mapflag -IL* EGO_F={EGO_F?} -IL*
-	mapflag -CS* EGO_F={EGO_F?} -CS*
-	mapflag -SR* EGO_F={EGO_F?} -SR*
-	mapflag -UD* EGO_F={EGO_F?} -UD*
-	mapflag -LV* EGO_F={EGO_F?} -LV*
-	mapflag -SA* EGO_F={EGO_F?} -RA*
-	mapflag -SP* EGO_F={EGO_F?} -SP*
-	mapflag -BO* EGO_F={EGO_F?} -BO*
-	mapflag -CJ* EGO_F={EGO_F?} -CJ*
-	mapflag -EV EGO_F={EGO_F?} -V
-# End of obsolete lines
 	mapflag -Q* EGO_F={EGO_F?} -Q*
 	mapflag -T* EGO_F={EGO_F?} -T*
 	mapflag -S* EGO_F={EGO_F?} -S*
@@ -227,7 +214,7 @@ name ego
 	mapflag -O* EGO_F={EGO_F?} -O*
 	args \
 		{EGO_F?} -P {EM}/lib/ack/ego \
-		-M{EM}/share/ack/ego/{ARCH}.descr <
+		{EGO_PLAT_FLAGS?} <
 	optimizer 2
 	stdout
 	combiner

+ 1 - 1
plat/build.lua

@@ -20,6 +20,7 @@ definerule("ackfile",
 				"lang/pc/comp+pkg",
 				"plat/"..plat.."+tools",
 				"util/ack+pkg",
+				"util/ego+pkg",
 				"util/misc+pkg",
 				e.deps
 			},
@@ -67,7 +68,6 @@ definerule("ackprogram",
 				"plat/"..e.vars.plat.."+pkg",
 				"util/ack+pkg",
 				"util/led+pkg",
-				"util/amisc+pkg",
 				e.deps
 			},
 			_clibrary = acklibrary,

+ 1 - 0
plat/linux386/descr

@@ -26,6 +26,7 @@ var C_LIB={PLATFORMDIR}/libc-ansi.a
 var CC_ALIGN=-Vr
 var OLD_C_LIB={C_LIB}
 var MACHOPT_F=-m10
+var EGO_PLAT_FLAGS=-M{EM}/share/ack/ego/{ARCH}.descr
 
 # Override the setting in fe so that files compiled for linux386 can see
 # the platform-specific headers.

+ 1 - 0
plat/linux68k/descr

@@ -26,6 +26,7 @@ var C_LIB={PLATFORMDIR}/libc-ansi.a
 var CC_ALIGN=-Vr
 var OLD_C_LIB={C_LIB}
 var MACHOPT_F=-ml10
+var EGO_PLAT_FLAGS=-M{EM}/share/ack/ego/{ARCH}.descr
 
 # Override the setting in fe so that files compiled for linux68k can see
 # the platform-specific headers.

+ 1 - 0
plat/pc86/descr

@@ -22,6 +22,7 @@ var PLATFORMDIR={EM}/share/ack/{PLATFORM}
 var CPP_F=-D__unix
 var ALIGN=-a0:1 -a1:1 -a2:1 -a3:1
 var MACHOPT_F=-m8
+var EGO_PLAT_FLAGS=-M{EM}/share/ack/ego/{ARCH}.descr
 
 # Override the setting in fe so that files compiled for this platform can see
 # the platform-specific headers.

+ 58 - 0
util/ego/build.lua

@@ -0,0 +1,58 @@
+local function build_ego(name)
+	cprogram {
+		name = name,
+		srcs = { "./"..name.."/*.c" },
+		deps = {
+			"util/ego/share+lib",
+			"modules/src/em_data+lib",
+			"h+emheaders",
+		},
+		vars = {
+			["+cflags"] = {"-DVERBOSE", "-DNOTCOMPACT"}
+		}
+	}
+end
+
+build_ego("bo")
+build_ego("ca")
+build_ego("cf")
+build_ego("cj")
+build_ego("cs")
+build_ego("ic")
+build_ego("il")
+build_ego("lv")
+build_ego("sp")
+build_ego("sr")
+build_ego("ud")
+
+cprogram {
+	name = "em_ego",
+	srcs = { "./em_ego/em_ego.c" },
+	deps = {
+		"modules/src/print+lib",
+		"modules/src/string+lib",
+		"modules/src/system+lib",
+		"modules+headers",
+		"h+emheaders",
+	}
+}
+
+installable {
+	name = "pkg",
+	map = {
+		["$(PLATDEP)/em_ego"] = "+em_ego",
+		["$(PLATDEP)/ego/bo"] = "+bo",
+		["$(PLATDEP)/ego/ca"] = "+ca",
+		["$(PLATDEP)/ego/cf"] = "+cf",
+		["$(PLATDEP)/ego/cj"] = "+cj",
+		["$(PLATDEP)/ego/cs"] = "+cs",
+		["$(PLATDEP)/ego/ic"] = "+ic",
+		["$(PLATDEP)/ego/il"] = "+il",
+		["$(PLATDEP)/ego/lv"] = "+lv",
+		["$(PLATDEP)/ego/ra"] = "./ra+ra",
+		["$(PLATDEP)/ego/sp"] = "+sp",
+		["$(PLATDEP)/ego/sr"] = "+sr",
+		["$(PLATDEP)/ego/ud"] = "+ud",
+		"./descr+pkg",
+	}
+}

+ 32 - 6
util/ego/ca/ca.c

@@ -220,24 +220,50 @@ main(argc, argv) int argc;
 char* argv[];
 {
 	/* CA does not output proctable etc. files. Instead, its
-	 * pname2 and dname2 arguments contain the names of the
+	 * pname_out and dname_out arguments contain the names of the
 	 * dump files created by IC.
 	 */
+	struct files* files = findfiles(argc, argv);
+
 	FILE* f, *f2; /* The EM input and output. */
 	FILE* df, *pf; /* The dump files */
 	line_p lnp;
 
-	fproc = getptable(pname); /* proc table */
-	fdblock = getdtable(dname); /* data block table */
+	/* The names of the input files of every phase are passed as
+	 * arguments to the phase. First come the input file names,
+	 * then the output file names. We use a one-letter convention
+	 * to denote the type of file:
+	 *  p: procedure table file
+	 *  d: data table file
+	 *  l: EM text file (lines of EM instructions)
+	 *  b: basic block file (Control Flow Graph file)
+	 */
+
+	/* The input file names */
+
+	char* pname_in = argv[1];
+	char* dname_in = argv[2];
+	char* lname_in = argv[3];
+	char* bname_in = argv[4];
+
+	/* The output file names */
+
+	char* pname_out = argv[5];
+	char* dname_out = argv[6];
+	char* lname_out = argv[7];
+	char* bname_out = argv[8];
+
+	fproc = getptable(pname_in); /* proc table */
+	fdblock = getdtable(dname_in); /* data block table */
 	dlength = makedmap(fdblock); /* allocate dmap table */
-	df = openfile(dname2, "r");
+	df = openfile(dname_out, "r");
 	getdnames(df);
 	fclose(df);
-	pf = openfile(pname2, "r");
+	pf = openfile(pname_out, "r");
 	getpnames(pf);
 	fclose(pf);
 	uniq_names();
-	f = openfile(lname, "r");
+	f = openfile(lname_in, "r");
 	f2 = stdout;
 	cputmagic(f2); /* write magic number */
 	while ((lnp = get_ca_lines(f, &curproc)) != (line_p)0)

+ 36 - 12
util/ego/cf/cf.c

@@ -530,22 +530,46 @@ char* argv[];
 	short n, kind;
 	line_p l;
 
+	/* The names of the input files of every phase are passed as
+	 * arguments to the phase. First come the input file names,
+	 * then the output file names. We use a one-letter convention
+	 * to denote the type of file:
+	 *  p: procedure table file
+	 *  d: data table file
+	 *  l: EM text file (lines of EM instructions)
+	 *  b: basic block file (Control Flow Graph file)
+	 */
+
+	/* The input file names */
+
+	char* pname_in = argv[1];
+	char* dname_in = argv[2];
+	char* lname_in = argv[3];
+	char* bname_in = argv[4];
+
+	/* The output file names */
+
+	char* pname_out = argv[5];
+	char* dname_out = argv[6];
+	char* lname_out = argv[7];
+	char* bname_out = argv[8];
+
 	linecount = 0;
-	fproc = getptable(pname); /* proc table */
-	fdblock = getdtable(dname); /* data block table */
+	fproc = getptable(pname_in); /* proc table */
+	fdblock = getdtable(dname_in); /* data block table */
 	lpi_set = Cempty_set(plength);
 	cai_set = Cempty_set(plength);
-	if ((f = fopen(lname, "r")) == NULL)
+	if ((f = fopen(lname_in, "r")) == NULL)
 	{
-		error("cannot open %s", lname);
+		error("cannot open %s", lname_in);
 	}
-	if ((f2 = fopen(lname2, "w")) == NULL)
+	if ((f2 = fopen(lname_out, "w")) == NULL)
 	{
-		error("cannot open %s", lname2);
+		error("cannot open %s", lname_out);
 	}
-	if ((gf2 = fopen(bname2, "w")) == NULL)
+	if ((gf2 = fopen(bname_out, "w")) == NULL)
 	{
-		error("cannot open %s", bname2);
+		error("cannot open %s", bname_out);
 	}
 	while (getbblocks(f, &kind, &n, &g, &l))
 	{
@@ -581,14 +605,14 @@ char* argv[];
 	/* Compute transitive closure of used/changed
 	 * variables information for every procedure.
 	 */
-	if ((f = fopen(dname2, "w")) == NULL)
+	if ((f = fopen(dname_out, "w")) == NULL)
 	{
-		error("cannot open %s", dname2);
+		error("cannot open %s", dname_out);
 	}
 	putdtable(fdblock, f);
-	if ((f = fopen(pname2, "w")) == NULL)
+	if ((f = fopen(pname_out, "w")) == NULL)
 	{
-		error("cannot open %s", pname2);
+		error("cannot open %s", pname_out);
 	}
 	putptable(fproc, f, TRUE);
 	exit(0);

+ 30 - 0
util/ego/descr/build.lua

@@ -0,0 +1,30 @@
+local installmap = {}
+
+local function build_descr(name)
+	local descr = normalrule {
+		name = name,
+		ins = {
+			"lang/cem/cpp.ansi+cpp",
+			"./"..name..".descr",
+			"./descr.sed",
+			matching(filenamesof("modules/src/em_data+lib"), "em_mnem%.h$"),
+		},
+		outleaves = { name..".descr" },
+		commands = {
+			"%{ins[1]} -P -I%{dirname(ins[4])} %{ins[2]} > %{dir}/temp",
+			"sed -f %{ins[3]} < %{dir}/temp > %{outs}"
+		}
+	}
+
+	installmap["$(PLATIND)/ego/"..name..".descr"] = descr
+end
+
+build_descr("i386")
+build_descr("i86")
+build_descr("m68020")
+
+installable {
+	name = "pkg",
+	map = installmap
+}
+

+ 122 - 148
util/ego/em_ego/em_ego.c

@@ -4,38 +4,54 @@
    optimizer itself one day ...
 */
 
-#include <em_path.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <unistd.h>
 #include <signal.h>
-#include <system.h>
-
-#define IC 1
-#define CF 2
-#define IL 3
-#define CS 4
-#define SR 5
-#define UD 6
-#define LV 7
-#define RA 8
-#define SP 9
-#define BO 10
-#define CJ 11
-#define CA 12
-
-static char* phnames[] = {
-	0,
-	"ic",
-	"cf",
-	"il",
-	"cs",
-	"sr",
-	"ud",
-	"lv",
-	"ra",
-	"sp",
-	"bo",
-	"cj",
-	"ca",
-	0
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <string.h>
+#include "em_path.h"
+#include "system.h"
+#include "print.h"
+
+enum
+{
+	NONE = 0,
+	IC,
+	CF,
+	IL,
+	CS,
+	SR,
+	UD,
+	LV,
+	RA,
+	SP,
+	BO,
+	CJ,
+	CA
+};
+
+static const struct
+{
+	const char* name;
+	bool needsdescr;
+
+} phase_data[] = {
+	{},
+	{ "ic" },
+	{ "cf" },
+	{ "il" },
+	{ "cs", true },
+	{ "sr" },
+	{ "ud", true },
+	{ "lv" },
+	{ "ra" },
+	{ "sp" },
+	{ "bo" },
+	{ "cj" },
+	{ "ca" },
 };
 
 #define MAXUPHASES 64 /* max # of phases to be run */
@@ -77,8 +93,9 @@ static int keeptemps = 0;
 static char** phase_args;
 static int nphase_args;
 
-static char* opt_dir;
-static char* prog_name;
+static const char* descr_file;
+static const char* opt_dir;
+static const char* prog_name;
 
 static int v_flag;
 
@@ -93,7 +110,7 @@ cleanup()
 
 		for (i = NTEMPS * 2; i > 0; i--)
 		{
-			register char* f = phargs[i];
+			const char* f = phargs[i];
 			if (f != 0 && *f != '\0' && *f != '-')
 				(void)unlink(f);
 		}
@@ -167,8 +184,8 @@ get_infiles()
 	/*	Make output temps from previous phase input temps of next phase. */
 
 	register int i;
-	register char** dst = &phargs[1];
-	register char** src = &phargs[NTEMPS + 1];
+	char** dst = &phargs[1];
+	char** src = &phargs[NTEMPS + 1];
 
 	for (i = 1; i <= NTEMPS; i++)
 	{
@@ -184,7 +201,7 @@ new_outfiles()
 	static char dig1 = '1';
 	static char dig2 = '0';
 	register int i;
-	register char** dst = &phargs[NTEMPS + 1];
+	char** dst = &phargs[NTEMPS + 1];
 
 	if (!Bindex)
 	{
@@ -219,14 +236,21 @@ static void
 	char buf[256];
 	int pid, status;
 
+	/* Skip this phase if it requires a descr file and one hasn't been
+	 * provided. */
+
+	if (phase_data[phase].needsdescr && !descr_file)
+		return;
+
 	phargs[0] = buf;
 	(void)strcpy(buf, opt_dir);
 	(void)strcat(buf, "/");
-	(void)strcat(buf, phnames[phase]);
+	(void)strcat(buf, phase_data[phase].name);
 
 	switch (phase)
 	{
 		case IC:
+			/* always first */
 			phargs[1] = pdump;
 			phargs[2] = ddump;
 			for (i = 3; i <= NTEMPS; i++)
@@ -237,6 +261,7 @@ static void
 			break;
 
 		case CA:
+			/* always last */
 			old_infiles();
 			get_infiles();
 			phargs[NTEMPS + 1] = pdump;
@@ -248,20 +273,24 @@ static void
 			break;
 
 		default:
+		{
 			old_infiles();
 			get_infiles();
 			new_outfiles();
-			if (!flags_added)
+
+			argc = 2 * NTEMPS + 1;
+			if (descr_file)
 			{
-				flags_added = 1;
-				argc = 2 * NTEMPS + 1;
-				while (--nphase_args >= 0)
-				{
-					phargs[argc++] = *phase_args++;
-				}
-				phargs[argc] = 0;
+				phargs[argc++] = "-M";
+				phargs[argc++] = descr_file;
 			}
+			
+			for (i=0; i<nphase_args; i++)
+				phargs[argc++] = phase_args[i];
+
+			phargs[argc] = NULL;
 			break;
+		}
 	}
 	if ((pid = fork()) < 0)
 	{
@@ -300,10 +329,10 @@ static void
 	}
 }
 
-main(argc, argv) int argc;
-char* argv[];
+int main(int argc, char* argv[])
 {
-	register int i = 0;
+	int opt;
+	int i;
 
 	if (signal(SIGHUP, catch) == SIG_IGN)
 		(void)signal(SIGHUP, SIG_IGN);
@@ -312,113 +341,58 @@ char* argv[];
 	if (signal(SIGINT, catch) == SIG_IGN)
 		(void)signal(SIGINT, SIG_IGN);
 	prog_name = argv[0];
+
+	nphase_args = 0;
 	phase_args = &argv[1];
-	while (--argc > 0)
+
+	opterr = 0;
+	for (;;)
 	{
-		argv++;
-		if (argv[0][0] == '-')
+		int opt = getopt(argc, argv, "-M:P:O:vt");
+		if (opt == -1)
+			break;
+
+		switch (opt)
 		{
-			switch (argv[0][1])
+			case 'M':
+				descr_file = optarg;
+				break;
+
+			case 'P':
+				opt_dir = optarg;
+				break;
+
+			case 'O':
 			{
-				case 'P':
-					if (argv[0][2] == '\0')
-					{
-						opt_dir = argv[1];
-						argc--;
-						argv++;
-						continue;
-					}
-					break;
-				case 't':
-					if (argv[0][2] == '\0')
-					{
-						keeptemps = 1;
-						/* no continue; IL also needs this */
-					}
-					break;
-				case 'v':
-					v_flag = 1;
-					break;
-				case 'O':
-					if (argv[0][2] == '2' || argv[0][2] == '\0')
-						continue;
-					if (argv[0][2] == '3')
-					{
-						Ophase = &O3phases[0];
-						continue;
-					}
-					Ophase = &O4phases[0];
-					continue;
-				case 'I':
-					if (!strcmp(&argv[0][1], "IL"))
-					{
-						add_uphase(IL);
-						add_uphase(CF);
-						continue;
-					}
-					break;
-				case 'B':
-					if (!strcmp(&argv[0][1], "BO"))
-					{
-						add_uphase(BO);
-						continue;
-					}
-					break;
-				case 'R':
-					if (!strcmp(&argv[0][1], "RA"))
-					{
-						add_uphase(RA);
-						continue;
-					}
-					break;
-				case 'U':
-					if (!strcmp(&argv[0][1], "UD"))
-					{
-						add_uphase(UD);
-						continue;
-					}
-					break;
-				case 'L':
-					if (!strcmp(&argv[0][1], "LV"))
-					{
-						add_uphase(LV);
-						continue;
-					}
-					break;
-				case 'C':
-					if (!strcmp(&argv[0][1], "CS"))
-					{
-						add_uphase(CS);
-						continue;
-					}
-					if (!strcmp(&argv[0][1], "CJ"))
-					{
-						add_uphase(CJ);
-						continue;
-					}
-					break;
-				case 'S':
-					if (!strcmp(&argv[0][1], "SR"))
-					{
-						add_uphase(SR);
-						continue;
-					}
-					if (!strcmp(&argv[0][1], "SP"))
-					{
-						add_uphase(SP);
-						continue;
-					}
+				int o = atoi(optarg);
+				if (o <= 2)
 					break;
+				if (o <= 3)
+					Ophase = &O3phases[0];
+				Ophase = &O4phases[0];
+				break;
 			}
-			phase_args[i++] = argv[0];
-		}
-		else
-		{
-			add_file(argv[0]);
+
+			case 1:
+				add_file(optarg);
+				break;
+
+			case 't':
+				keeptemps = 1;
+				goto addopt;
+
+			case 'v':
+				v_flag = 1;
+				goto addopt;
+
+			case '?':
+			addopt:
+				phase_args[nphase_args++] = argv[optind - 1];
+				break;
 		}
 	}
-	phase_args[i] = 0;
-	nphase_args = i;
+
+	phase_args[nphase_args] = 0;
 	if (nuphases)
 		Ophase = uphases;
 

+ 20 - 7
util/ego/ic/ic.c

@@ -72,13 +72,26 @@ char* argv[];
 	 *  - ddump: the names of all data blocks
 	 */
 
-	FILE* lfile, *dfile, *pfile, *pdump, *ddump;
+	/* The input file names */
+
+	const char* pdump_out = argv[1];
+	const char* ddump_out = argv[2];
+
+	/* The output file names */
+
+	const char* pname_out = argv[5];
+	const char* dname_out = argv[6];
+	const char* lname_out = argv[7];
+
+	FILE* lfile = openfile(lname_out, "w");
+	FILE* pdump = openfile(pdump_out, "w");
+	FILE* ddump = openfile(ddump_out, "w");
+
+	FILE* dfile;
+	FILE* pfile;
 
-	lfile = openfile(lname2, "w");
-	pdump = openfile(argv[1], "w");
-	ddump = openfile(argv[2], "w");
 	hol0_db = block_of_lab((char*)0);
-	while (next_file(argc, argv) != NULL)
+	while (next_file(argc-8, argv+8) != NULL)
 	{
 		/* Read all EM input files, process the code
 		 * and concatenate all output.
@@ -104,9 +117,9 @@ char* argv[];
 	cleanprocs(prochash, NPROCHASH, 0);
 	cleandblocks(symhash, NSYMHASH, 0);
 	/* Now write the datablock table and the proctable */
-	dfile = openfile(dname2, "w");
+	dfile = openfile(dname_out, "w");
 	putdtable(fdblock, dfile);
-	pfile = openfile(pname2, "w");
+	pfile = openfile(pname_out, "w");
 	putptable(fproc, pfile, FALSE);
 	exit(0);
 }

+ 1 - 1
util/ego/ic/ic_lib.c

@@ -224,7 +224,7 @@ STATIC bool read_hdr()
 	return 1;
 }
 
-STATIC int argcnt = ARGSTART - 1;
+STATIC int argcnt = 0;
 STATIC short arstate = NO_ARCHIVE;
 
 FILE* next_file(argc, argv) int argc;

+ 5 - 4
util/ego/il/il.c

@@ -325,6 +325,7 @@ il_flags(p) char* p;
 main(argc, argv) int argc;
 char* argv[];
 {
+	struct files* files = findfiles(argc, argv);
 	FILE* f;
 
 	go(argc, argv, no_action, no_action, no_action, il_flags);
@@ -337,14 +338,14 @@ char* argv[];
 	mktemp(ccname);
 	mktemp(sname);
 	mktemp(cname2);
-	pass1(lname, bname, cname); /* grep calls, analyse procedures */
+	pass1(files->lname_in, files->bname_in, cname); /* grep calls, analyse procedures */
 	space = total_size * space / 100;
 	pass2(cname, space); /* select calls to be expanded */
-	pass3(lname, lname2); /* do substitutions */
-	f = openfile(dname2, "w");
+	pass3(files->lname_in, files->lname_out); /* do substitutions */
+	f = openfile(files->dname_out, "w");
 	il_cleanptab(fproc); /* remove extended data structures */
 	putdtable(fdblock, f);
-	f = openfile(pname2, "w");
+	f = openfile(files->pname_out, "w");
 	putptable(fproc, f, FALSE);
 	report("inline substitutions", Ssubst);
 #ifdef VERBOSE

+ 32 - 0
util/ego/ra/build.lua

@@ -0,0 +1,32 @@
+cprogram {
+	name = "makeitems",
+	srcs = { "./makeitems.c" }
+}
+
+normalrule {
+	name = "itemtab_h",
+	ins = {
+		"+makeitems",
+		matching(filenamesof("modules/src/em_data+lib"), "em_mnem%.h$"),
+		"./itemtab.src"
+	},
+	outleaves = { "itemtab.h" },
+	commands = {
+		"%{ins} > %{outs}"
+	}
+}
+
+cprogram {
+	name = "ra",
+	srcs = { "./ra*.c" },
+	deps = {
+		"util/ego/share+lib",
+		"modules/src/em_data+lib",
+		"h+emheaders",
+		"+itemtab_h",
+	},
+	vars = {
+		["+cflags"] = {"-DVERBOSE", "-DNOTCOMPACT"}
+	}
+}
+

+ 38 - 2
util/ego/share/files.c

@@ -9,9 +9,45 @@
  */
 
 #include <stdio.h>
+#include "files.h"
 
-FILE *openfile(name,mode)
-	char *name,*mode;
+struct files* findfiles(int argc, const char** argv)
+{
+	static struct files files;
+
+	/* The names of the input files of every phase are passed as
+	 * arguments to the phase. First come the input file names,
+	 * then the output file names. We use a one-letter convention
+	 * to denote the type of file:
+	 *  p: procedure table file
+	 *  d: data table file
+	 *  l: EM text file (lines of EM instructions)
+	 *  b: basic block file (Control Flow Graph file)
+	 */
+
+	/* The input file names */
+
+	files.pname_in = argv[1];
+	files.dname_in = argv[2];
+	files.lname_in = argv[3];
+	files.bname_in = argv[4];
+
+	/* The output file names */
+
+	files.pname_out = argv[5];
+	files.dname_out = argv[6];
+	files.lname_out = argv[7];
+	files.bname_out = argv[8];
+
+	/* The rest of the arguments. */
+
+	files.argv = argv + 8;
+	files.argc = argc - 8;
+
+	return &files;
+}
+
+FILE *openfile(char* name, char* mode)
 {
 	FILE *f;
 

+ 19 - 11
util/ego/share/files.h

@@ -15,21 +15,29 @@
  *  b: basic block file (Control Flow Graph file)
  */
 
-/* The input file names */
+struct files
+{
+	/* Input files */
 
-#define pname argv[1]
-#define dname argv[2]
-#define lname argv[3]
-#define bname argv[4]
+	const char* pname_in;
+	const char* dname_in;
+	const char* lname_in;
+	const char* bname_in;
 
-/* The output file names */
+	/* Output files */
 
-#define pname2 argv[5]
-#define dname2 argv[6]
-#define lname2 argv[7]
-#define bname2 argv[8]
+	const char* pname_out;
+	const char* dname_out;
+	const char* lname_out;
+	const char* bname_out;
 
-#define ARGSTART 9
+	/* The rest of the arguments. */
+
+	const char** argv;
+	int argc;
+};
+
+extern struct files* findfiles(int argc, const char** argv);
 
 extern FILE *openfile();	/* (char *name, *mode)
 				 * Open a file with the given name

+ 33 - 30
util/ego/share/go.c

@@ -10,24 +10,24 @@
  */
 
 #include <stdio.h>
+#include <unistd.h>
 #include "types.h"
 #include "debug.h"
 #include "global.h"
-#include "files.h"
 #include "get.h"
 #include "put.h"
 #include "lset.h"
 #include "map.h"
 #include "alloc.h"
 #include "go.h"
+#include "files.h"
 
 STATIC bool report_flag = FALSE; /* report #optimizations found? */
 #ifdef DEBUG
 STATIC bool core_flag = FALSE; /* report core usage? */
 #endif
 
-STATIC mach_init(machfile, phase_machinit) char* machfile;
-int (*phase_machinit)();
+static mach_init(char* machfile, int (*phase_machinit)())
 {
 	/* Read target machine dependent information */
 
@@ -42,13 +42,10 @@ int (*phase_machinit)();
 	fclose(f);
 }
 
-go(argc, argv, initialize, optimize, phase_machinit, proc_flag) int argc;
-char* argv[];
-int (*initialize)();
-int (*optimize)();
-int (*phase_machinit)();
-int (*proc_flag)();
+void go(int argc, const char** argv,
+	int (*initialize)(), int (*optimize)(), int (*phase_machinit)(), int (*proc_flag)())
 {
+	struct files* files = findfiles(argc, argv);
 	FILE* f, *gf, *f2, *gf2; /* The EM input and output and
 				 * the basic block graphs input and output
 				 */
@@ -60,49 +57,56 @@ int (*proc_flag)();
 	bool time_opt = TRUE;
 
 	linecount = 0;
-	for (i = ARGSTART; i < argc; i++)
+	opterr = 0;
+	for (;;)
 	{
-		p = argv[i];
-		if (*p++ != '-')
-			error("illegal argument");
-		switch (*p)
+		int opt = getopt(files->argc, files->argv, "STM:CQV");
+		if (opt == -1)
+			break;
+
+		switch (opt)
 		{
 			case 'S':
 				time_opt = FALSE;
 				break;
+
 			case 'T':
 				time_opt = TRUE;
 				break;
+
 			case 'M':
-				p++;
-				mach_init(p, phase_machinit);
+				mach_init(optarg, phase_machinit);
 				break;
+
 			case 'C':
 #ifdef DEBUG
 				core_flag = TRUE;
 #endif
 				break;
+
 			case 'Q':
 				report_flag = TRUE;
 				break;
+
 			case 'V':
 				verbose_flag = TRUE;
 				break;
-			default:
-				(*proc_flag)(p);
+
+			case '?':
+				proc_flag(argv[optind - 1]);
 				break;
 		}
 	}
 	time_space_ratio = (time_opt ? 100 : 0);
-	fproc = getptable(pname); /* proc table */
-	fdblock = getdtable(dname); /* data block table */
+	fproc = getptable(files->pname_in); /* proc table */
+	fdblock = getdtable(files->dname_in); /* data block table */
 	(*initialize)();
 	if (optimize == no_action)
 		return;
-	f = openfile(lname, "r");
-	gf = openfile(bname, "r");
-	f2 = openfile(lname2, "w");
-	gf2 = openfile(bname2, "w");
+	f = openfile(files->lname_in, "r");
+	gf = openfile(files->bname_in, "r");
+	f2 = openfile(files->lname_out, "w");
+	gf2 = openfile(files->bname_out, "w");
 	mesregs = Lempty_set();
 	while (getunit(gf, f, &kind, &g, &l, &curproc, TRUE))
 	{
@@ -130,18 +134,18 @@ int (*proc_flag)();
 	fclose(f2);
 	fclose(gf);
 	fclose(gf2);
-	f = openfile(dname2, "w");
+	f = openfile(files->dname_out, "w");
 	putdtable(fdblock, f);
 	/* fclose(f); done by putdtable */
-	f = openfile(pname2, "w");
+	f = openfile(files->pname_out, "w");
 	putptable(fproc, f, TRUE);
 	/* fclose(f); done by putptable */
 	core_usage();
 }
 
-no_action() {}
+int no_action() {}
 
-core_usage()
+void core_usage(void)
 {
 #ifdef DEBUG
 	if (core_flag)
@@ -151,8 +155,7 @@ core_usage()
 #endif
 }
 
-report(s, n) char* s;
-int n;
+void report(char* s, int n)
 {
 	/* Report number of optimizations found, if report_flag is set */
 

+ 30 - 27
util/ego/share/go.h

@@ -9,30 +9,33 @@
  *
  */
 
-extern go(); /* ( int argc; char *argv[];
-			 *   int (*initialize)(); int (*optimize)(); 
-			 *   int (*phase_machinit)(); int (*proc_flag)()  )
-			 * This is the main driving routine of the optimizer.
-			 * It first processes the flags given as argument;
-			 * for every flag it does not recognize itself, it
-			 * calls 'proc_flag'; as soon as the -M flag is seen,
-			 * it opens the machine descriptor file and
-			 * reads phase-independend information (notably the
-			 * wordsize and pointersize of the target machine);
-			 * next it calls 'phase_machinit' with this file as
-			 * parameter. Subsequently it calls 'initialize'.
-			 * Finally, all procedures are read, one at a time,
-			 * and 'optimize' is called with the current procedure
-			 * as parameter.
-			 */
-extern no_action(); /* ()
-			 * Parameter to be supplied for e.g. 'initialize' if
-			 * no action is required.
-			 */
-extern core_usage(); /* ()
-			 * Report core usage, if core_flag is set.
-			 */
-extern report(); /* ( char *s; int n)
-			 * Report number of optimizations found, if 
-			 * report_flag is set
-			 */
+/* This is the main driving routine of the optimizer.
+ * It first processes the flags given as argument;
+ * for every flag it does not recognize itself, it
+ * calls 'proc_flag'; as soon as the -M flag is seen,
+ * it opens the machine descriptor file and
+ * reads phase-independend information (notably the
+ * wordsize and pointersize of the target machine);
+ * next it calls 'phase_machinit' with this file as
+ * parameter. Subsequently it calls 'initialize'.
+ * Finally, all procedures are read, one at a time,
+ * and 'optimize' is called with the current procedure
+ * as parameter.
+ */
+extern void go(int argc, const char** argv,
+    int (*initialize)(), int (*optimize)(),
+    int (*phase_machinit)(), int (*proc_flag)());
+
+/*
+ * Parameter to be supplied for e.g. 'initialize' if
+ * no action is required.
+ */
+extern int no_action();
+
+/* Report core usage, if core_flag is set. */
+extern void core_usage(void);
+
+/* Report number of optimizations found, if 
+ * report_flag is set
+ */
+extern void report(char* s, int n);