diff options
Diffstat (limited to 'ghc/misc/spat-analysers/spatmain.c')
-rw-r--r-- | ghc/misc/spat-analysers/spatmain.c | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/ghc/misc/spat-analysers/spatmain.c b/ghc/misc/spat-analysers/spatmain.c new file mode 100644 index 0000000000..2c6ec1912a --- /dev/null +++ b/ghc/misc/spat-analysers/spatmain.c @@ -0,0 +1,243 @@ +#include <stdio.h> +#include <varargs.h> +#include <sys/time.h> +#include <sys/resource.h> + +#define TVTIME(tv) ((tv).tv_sec + (tv).tv_usec / 1e6) + + +extern char *anal_usage, *anal_version, + *shade_bench_path, *shade_ego, *shade_version, + *shade_argtrange(); + +extern char *ctime(); +extern int analyze(); +extern long time(); +extern void exit(), initialize(), terminate(); + + +FILE *statsfp; /* output stats file */ +double nina; /* # non-annulled instructions executed */ + + +static double usr, sys, real; +static int t_flag, + main_stats_analyze(); +static void main_stats_start(), + main_stats_stop(); + + +int +shade_main (argc, argv, envp) + int argc; + char **argv, **envp; +{ + int aargc, ec, i, j, pid = getpid(); + char **aargv, *cmd = 0, *x; + + argc = shade_splitargs (argv, &aargv, &aargc); + + for (i = j = 1; i < argc; i++) + if (argv[i][0] == '-' || + argv[i][0] == '+' && argv[i][1] == 't') + switch (argv[i][1]) { + case 'c': + if (cmd) + usage ("too many -c options"); + if (aargc > 0) + usage ("-c not allowed with --"); + if (argv[i][2] || ++i >= argc) + usage + ("-c: missing/misplaced command"); + cmd = argv[i]; + break; + case 'o': + if (statsfp) + shade_fatal ("too many -o's"); + if (argv[i][2] || ++i >= argc) + usage + ("-o: missing/misplaced file name"); + statsfp = fopen (argv[i], "w"); + if (!statsfp) + usage ("%s: can't open", argv[i]); + break; + case 't': + if (!t_flag++) + (void) shade_argtrange (argv[i][0] == + '-' ? "+t," : "-t,"); + if (x = shade_argtrange (argv[i])) + usage ("%s: %s", argv[i], x); + /* should print tranges */ + break; + case 'U': + usage (""); + return (0); + case 'V': + fprintf (stderr, "%s: version: %s\n", + argv[0], anal_version); + fprintf (stderr, "shade version: %s\n", + shade_version); + return (0); + default: + argv[j++] = argv[i]; + break; + } + else argv[j++] = argv[i]; + + if (!statsfp) + statsfp = stdout; + + argv[argc = j] = 0; + initialize (argc, argv, envp); + + main_stats_start(); + + if (cmd) + ec = shade_sshell (cmd, main_stats_analyze); + else if (aargc <= 0) + ec = shade_shell (main_stats_analyze); + else if (0 > shade_loadp (*aargv, aargv, envp)) + ec = 1; + else ec = main_stats_analyze (aargc, aargv, envp, (char **) 0); + + if (pid == getpid()) { + main_stats_stop(); + terminate(); + } + return (ec); +} + + +usage (va_alist) + va_dcl +{ + char *fmt; + va_list ap; + + va_start (ap); + fmt = va_arg (ap, char *); + if (fmt && *fmt) { + fprintf (stderr, "%s: ", shade_ego); + vfprintf (stderr, fmt, ap); + fprintf (stderr, "\n\n"); + } + va_end (ap); + + fprintf (stderr, "usage: %s [-U] [-V] [-o outfile] [+/-t[from],[to]] ", + shade_ego); + if (anal_usage && *anal_usage) + fprintf (stderr, "\\\n\t%s ", anal_usage); + fprintf (stderr, "\\\n\t[-c \"command\" | -- bench benchargs]\n"); + + exit (1); +} + + +static void +getcputime (usr, sys) + double *usr, *sys; +{ + struct rusage ru; + + if (-1 == getrusage (RUSAGE_SELF, &ru)) + *usr = *sys = 0.0; + else { + *usr = TVTIME (ru.ru_utime) - *usr; + *sys = TVTIME (ru.ru_stime) - *sys; + } +} + + +static void +getrealtime (real) + double *real; +{ + struct timeval tv; + struct timezone tz; + + tz.tz_dsttime = DST_NONE; + tz.tz_minuteswest = 0; + + (void) gettimeofday (&tv, &tz); + + *real = TVTIME (tv) - *real; +} + + +static void +main_stats_start() +{ + long start; + + if (statsfp == 0) + return; + + fprintf (statsfp, "Analyzer: %s\n", shade_ego); + fprintf (statsfp, "Version: %s (shade version: %s)\n", + anal_version, shade_version); + + { + char host[64]; + + if (-1 != gethostname (host, sizeof host)) + fprintf (statsfp, "Hostname: %s\n", host); + } + + (void) time (&start); + getrealtime (&real); + getcputime (&usr, &sys); + + fprintf (statsfp, "Start: %s", ctime (&start)); + fflush (statsfp); +} + + +static int +main_stats_analyze (argc, argv, envp, iov) + int argc; + char **argv, **envp, **iov; +{ + int i; + + /* BUG: if t_flag, shouldn't change application program */ + + if (statsfp) { + fprintf (statsfp, "Application: %s", shade_bench_path); + for (i = 1; i < argc; i++) + fprintf (statsfp, " %s", argv[i]); + if (iov) + for (i = 0; iov[i]; i += 2) { + fprintf (statsfp, " %s", iov[i]); + if (iov[i+1]) + fprintf (statsfp, " %s", iov[i+1]); + } + fprintf (statsfp, "\n"); + fflush (statsfp); + } + + return (analyze()); +} + + +static void +main_stats_stop() +{ + long stop; + + if (statsfp == 0) + return; + + (void) time (&stop); + getcputime (&usr, &sys); + getrealtime (&real); + + fprintf (statsfp, "Stop: %s", ctime (&stop)); + if (nina > 0) + fprintf (statsfp, "Instructions: %.0f\n", nina); + fprintf (statsfp, "Time: %.3f usr %.3f sys %.3f real %.3f%%\n", + usr, sys, real, + real > 0 ? 100. * (usr + sys) / real : 100.); + if (usr + sys > 0 && nina > 0) + fprintf (statsfp, "Speed: %.3f KIPS\n", + nina / (usr + sys) / 1000.); +} |