em_ego.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  1. /* $Id$ */
  2. /* Driver program for the global optimizer. It might even become the global
  3. optimizer itself one day ...
  4. */
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include <stdbool.h>
  8. #include <unistd.h>
  9. #include <signal.h>
  10. #include <sys/types.h>
  11. #include <sys/wait.h>
  12. #include <string.h>
  13. #include "em_path.h"
  14. #include "system.h"
  15. #include "print.h"
  16. enum
  17. {
  18. NONE = 0,
  19. IC,
  20. CF,
  21. IL,
  22. CS,
  23. SR,
  24. UD,
  25. LV,
  26. RA,
  27. SP,
  28. BO,
  29. CJ,
  30. CA
  31. };
  32. static const struct
  33. {
  34. const char* name;
  35. bool needsdescr;
  36. } phase_data[] = {
  37. {},
  38. { "ic" },
  39. { "cf" },
  40. { "il" },
  41. { "cs", true },
  42. { "sr" },
  43. { "ud", true },
  44. { "lv" },
  45. { "ra" },
  46. { "sp" },
  47. { "bo" },
  48. { "cj" },
  49. { "ca" },
  50. };
  51. #define MAXUPHASES 64 /* max # of phases to be run */
  52. #define MAXARGS 1024 /* mar # of args */
  53. #define NTEMPS 4 /* # of temporary files; not tunable */
  54. extern char* mktemp();
  55. extern char* strcpy(), *strcat();
  56. extern char* strrchr();
  57. static char ddump[128] = TMP_DIR; /* data label dump file */
  58. static char pdump[128] = TMP_DIR; /* procedure name dump file */
  59. static char tmpbufs[NTEMPS * 2][128] = {
  60. TMP_DIR
  61. };
  62. static int O2phases[] = { /* Passes for -O2 */
  63. CJ, BO, SP, 0
  64. };
  65. static int O3phases[] = { /* Passes for -O3 */
  66. CS, SR, CJ, BO, SP, UD, LV, RA, 0
  67. };
  68. static int O4phases[] = { /* Passes for -O4 */
  69. IL, CF, CS, SR, CJ, BO, SP, UD, LV, RA, 0
  70. };
  71. static int* Ophase = &O2phases[0]; /* default : -O2 */
  72. static int nuphases; /* # of phases specified by user */
  73. static int uphases[MAXUPHASES + 1]; /* phases to be run */
  74. static int nfiles = NTEMPS * 2 + 1; /* leave space for tempfilenames */
  75. static char* phargs[MAXARGS + 1];
  76. static int keeptemps = 0;
  77. static char** phase_args;
  78. static int nphase_args;
  79. static const char* descr_file;
  80. static const char* opt_dir;
  81. static const char* prog_name;
  82. static int v_flag;
  83. static void
  84. cleanup()
  85. {
  86. /* Cleanup temporaries */
  87. if (!keeptemps)
  88. {
  89. register int i;
  90. for (i = NTEMPS * 2; i > 0; i--)
  91. {
  92. const char* f = phargs[i];
  93. if (f != 0 && *f != '\0' && *f != '-')
  94. (void)unlink(f);
  95. }
  96. if (ddump[0] != '\0')
  97. (void)unlink(ddump);
  98. if (pdump[0] != '\0')
  99. (void)unlink(pdump);
  100. }
  101. }
  102. /*VARARGS1*/
  103. static void
  104. fatal(s, s2) char* s;
  105. char* s2;
  106. {
  107. /* A fatal error occurred; exit gracefully */
  108. fprint(STDERR, "%s: ", prog_name);
  109. fprint(STDERR, s, s2);
  110. fprint(STDERR, "\n");
  111. cleanup();
  112. sys_stop(S_EXIT);
  113. /*NOTREACHED*/
  114. }
  115. static void
  116. add_file(s) char* s;
  117. {
  118. /* Add an input file to the list */
  119. if (nfiles >= MAXARGS)
  120. fatal("too many files");
  121. phargs[nfiles++] = s;
  122. }
  123. static void
  124. add_uphase(p) int p;
  125. {
  126. /* Add an optimizer phase to the list of phases to run */
  127. if (nuphases >= MAXUPHASES)
  128. fatal("too many phases");
  129. uphases[nuphases++] = p;
  130. }
  131. static void catch ()
  132. {
  133. /* Catch interrupts and exit gracefully */
  134. cleanup();
  135. sys_stop(S_EXIT);
  136. }
  137. static void
  138. old_infiles()
  139. {
  140. /* Remove old input files unless we have to keep them around. */
  141. register int i;
  142. if (phargs[1] == pdump || keeptemps)
  143. return;
  144. for (i = 1; i <= NTEMPS; i++)
  145. (void)unlink(phargs[i]);
  146. }
  147. static void
  148. get_infiles()
  149. {
  150. /* Make output temps from previous phase input temps of next phase. */
  151. register int i;
  152. char** dst = &phargs[1];
  153. char** src = &phargs[NTEMPS + 1];
  154. for (i = 1; i <= NTEMPS; i++)
  155. {
  156. *dst++ = *src++;
  157. }
  158. }
  159. static void
  160. new_outfiles()
  161. {
  162. static int tmpindex = 0;
  163. static int Bindex = 0;
  164. static char dig1 = '1';
  165. static char dig2 = '0';
  166. register int i;
  167. char** dst = &phargs[NTEMPS + 1];
  168. if (!Bindex)
  169. {
  170. Bindex = strrchr(tmpbufs[0], 'B') - tmpbufs[0];
  171. }
  172. for (i = 1; i <= NTEMPS; i++)
  173. {
  174. *dst = tmpbufs[tmpindex];
  175. (*dst)[Bindex - 1] = dig2;
  176. (*dst)[Bindex] = dig1;
  177. tmpindex++;
  178. dst++;
  179. }
  180. if (tmpindex >= 2 * NTEMPS)
  181. tmpindex = 0;
  182. if (++dig1 > '9')
  183. {
  184. ++dig2;
  185. dig1 = '0';
  186. }
  187. }
  188. static void
  189. run_phase(phase) int phase;
  190. {
  191. /* Run one phase of the global optimizer; special cases are
  192. IC and CA.
  193. */
  194. static int flags_added;
  195. register int argc;
  196. register int i;
  197. char buf[256];
  198. int pid, status;
  199. /* Skip this phase if it requires a descr file and one hasn't been
  200. * provided. */
  201. if (phase_data[phase].needsdescr && !descr_file)
  202. return;
  203. phargs[0] = buf;
  204. (void)strcpy(buf, opt_dir);
  205. (void)strcat(buf, "/");
  206. (void)strcat(buf, phase_data[phase].name);
  207. switch (phase)
  208. {
  209. case IC:
  210. /* always first */
  211. phargs[1] = pdump;
  212. phargs[2] = ddump;
  213. for (i = 3; i <= NTEMPS; i++)
  214. phargs[i] = "-";
  215. new_outfiles();
  216. argc = nfiles;
  217. phargs[argc] = 0;
  218. break;
  219. case CA:
  220. /* always last */
  221. old_infiles();
  222. get_infiles();
  223. phargs[NTEMPS + 1] = pdump;
  224. phargs[NTEMPS + 2] = ddump;
  225. for (i = NTEMPS + 3; i <= 2 * NTEMPS; i++)
  226. phargs[i] = "-";
  227. argc = 2 * NTEMPS + 1;
  228. phargs[argc] = 0;
  229. break;
  230. default:
  231. {
  232. old_infiles();
  233. get_infiles();
  234. new_outfiles();
  235. argc = 2 * NTEMPS + 1;
  236. if (descr_file)
  237. {
  238. phargs[argc++] = "-M";
  239. phargs[argc++] = descr_file;
  240. }
  241. for (i=0; i<nphase_args; i++)
  242. phargs[argc++] = phase_args[i];
  243. phargs[argc] = NULL;
  244. break;
  245. }
  246. }
  247. if ((pid = fork()) < 0)
  248. {
  249. fatal("Could not fork");
  250. }
  251. else if (pid == 0)
  252. {
  253. if (v_flag)
  254. {
  255. register int i = 0;
  256. while (phargs[i])
  257. {
  258. fprint(STDERR, "%s ", phargs[i]);
  259. i++;
  260. }
  261. fprint(STDERR, "\n");
  262. }
  263. (void)execv(phargs[0], phargs);
  264. fatal("Could not exec %s", phargs[0]);
  265. sys_stop(S_EXIT);
  266. }
  267. else
  268. {
  269. while (wait(&status) != pid) /* nothing */
  270. ;
  271. if ((status & 0177) != 0)
  272. {
  273. fatal("%s got a unix signal", phargs[0]);
  274. }
  275. if (((status >> 8) & 0377) != 0)
  276. {
  277. cleanup();
  278. sys_stop(S_EXIT);
  279. }
  280. }
  281. }
  282. int main(int argc, char* argv[])
  283. {
  284. int opt;
  285. int i;
  286. if (signal(SIGHUP, catch) == SIG_IGN)
  287. (void)signal(SIGHUP, SIG_IGN);
  288. if (signal(SIGQUIT, catch) == SIG_IGN)
  289. (void)signal(SIGQUIT, SIG_IGN);
  290. if (signal(SIGINT, catch) == SIG_IGN)
  291. (void)signal(SIGINT, SIG_IGN);
  292. prog_name = argv[0];
  293. nphase_args = 0;
  294. phase_args = &argv[1];
  295. opterr = 0;
  296. for (;;)
  297. {
  298. int opt = getopt(argc, argv, "-M:P:O:vt");
  299. if (opt == -1)
  300. break;
  301. switch (opt)
  302. {
  303. case 'M':
  304. descr_file = optarg;
  305. break;
  306. case 'P':
  307. opt_dir = optarg;
  308. break;
  309. case 'O':
  310. {
  311. int o = atoi(optarg);
  312. if (o <= 2)
  313. break;
  314. if (o <= 3)
  315. Ophase = &O3phases[0];
  316. Ophase = &O4phases[0];
  317. break;
  318. }
  319. case 1:
  320. add_file(optarg);
  321. break;
  322. case 't':
  323. keeptemps = 1;
  324. goto addopt;
  325. case 'v':
  326. v_flag = 1;
  327. goto addopt;
  328. case '?':
  329. addopt:
  330. phase_args[nphase_args++] = argv[optind - 1];
  331. break;
  332. }
  333. }
  334. phase_args[nphase_args] = 0;
  335. if (nuphases)
  336. Ophase = uphases;
  337. if (nfiles == 2 * NTEMPS + 1)
  338. {
  339. /* 2*NTEMPS+1 was the starting value; nothing to do */
  340. sys_stop(S_END);
  341. }
  342. if (!opt_dir)
  343. {
  344. fatal("no correct -P flag given");
  345. }
  346. if (keeptemps)
  347. {
  348. (void)strcpy(ddump, ".");
  349. (void)strcpy(pdump, ".");
  350. (void)strcpy(tmpbufs[0], ".");
  351. }
  352. (void)strcat(ddump, "/ego.dd.XXXXXX");
  353. (void)mktemp(ddump);
  354. (void)strcat(pdump, "/ego.pd.XXXXXX");
  355. (void)mktemp(pdump);
  356. (void)strcat(tmpbufs[0], "/ego.A.BB.XXXXXX");
  357. (void)mktemp(tmpbufs[0]);
  358. for (i = 2 * NTEMPS - 1; i >= 1; i--)
  359. {
  360. (void)strcpy(tmpbufs[i], tmpbufs[0]);
  361. }
  362. i = strrchr(tmpbufs[0], 'A') - tmpbufs[0];
  363. tmpbufs[0][i] = 'p';
  364. tmpbufs[NTEMPS + 0][i] = 'p';
  365. tmpbufs[1][i] = 'd';
  366. tmpbufs[NTEMPS + 1][i] = 'd';
  367. tmpbufs[2][i] = 'l';
  368. tmpbufs[NTEMPS + 2][i] = 'l';
  369. tmpbufs[3][i] = 'b';
  370. tmpbufs[NTEMPS + 3][i] = 'b';
  371. run_phase(IC);
  372. run_phase(CF);
  373. while (*Ophase)
  374. {
  375. run_phase(*Ophase++);
  376. }
  377. run_phase(CA);
  378. cleanup();
  379. sys_stop(S_END);
  380. /*NOTREACHED*/
  381. }