Notes on compiling the SPEC 92 benchmarks with SUIF --------------------------------------------------- The basic SUIF system is known to work on all the SPEC integer and floating point benchmarks. Problems in the SPEC source code requires changes of the SPEC code for two of the tests, wave5 and gcc. All other SPEC benchmarks work without modification. ****** WAVE5 ****** There is a bug in the SPEC 92 source code for wave5. In the subroutine PDIAG of the source file "wave5_data.f", the values of the variables LSKIP and LSKIPM must live across calls to PDIAG; otherwise they will be used uninitialized on some calls during the benchmark test run. Hence these two variables must be included in a SAVE statement. We added them to the SAVE statement for the variable IS to fix this bug. Here is a patch to fix the bug: *** wave5_data.f Fri Feb 14 19:14:30 1992 --- wave5_data.f.fixed Wed May 18 01:34:48 1994 *************** *** 3783,3789 **** 1 VZAV(NNS),VZRMSD(NNS) c specmod REAL XD1,XD2,YD1,YD2 ! SAVE IS DATA XD1,XD2,YD1,YD2/ 0., 0., 0., 0. / NFV = 0 C --- 3783,3789 ---- 1 VZAV(NNS),VZRMSD(NNS) c specmod REAL XD1,XD2,YD1,YD2 ! SAVE IS, LSKIP, LSKIPM DATA XD1,XD2,YD1,YD2/ 0., 0., 0., 0. / NFV = 0 C ****** GCC ****** The SPEC code for gcc relies upon a number of non-ANSI extensions to or assumptions about C, such as bit fields with enumerated type. SUIF can handle most of these, but not all. One of these kinds of extensions is not accepted by our ANSI C front end, one causes a type conflict with the standard system headers on our mips-dec-ultrix machines or any others that supply proper prototypes for the fprintf() function, and one is inconsistent with the "varargs.h" file we use to compile on mips-dec-ultrix machines. All of our changes to the gcc source code are to fix one of these three problems, and each individual change is minor. The problem for SUIF is that it does not handle is the use of bitfields with enumerated types. ANSI C specifies that bitfields have either ``signed int'' or ``unsigned int'' type. Since all the enumerated types used this way in gcc have members with all non-negative values and enumerated and integer types may be intermixed, we fixed this problem by changing structure definitions to use ``unsigned'' for every bitfield that had had enumerated type. This is the reason for the changes to "rtl.h", "tree.h", and "varasm.c". The second problem is that a proper prototype for the library fprintf() function in the standard headers is incompatible with the way this function is used in several files. Really, the problem is simply that someone forgot to declare a parameter type in the gcc code. Since it's not declared, the type defaults to ``int''. It's really a character pointer, though. The only use of this parameter is in a call to fprintf(), so if there is no prototype for fprintf() and ``int'' is the same size as a pointer, this bug will cause to problems. When there is a prototype for fprintf(), though, the type error will be discovered by the compiler. This is the case for SUIF on a mips-dec-ultrix machine. The fix is simply to declare the parameter ``s'' of the gcc fatal() function with type ``char *''. There are 8 nearly identical fatal() functions in the SPEC gcc code, and all need the same fix. There is also one error() function that needs this fix. That is the reason for the changes in "gencodes.c", "genconfig.c", "genemit.c", "genextract.c", "genflags.c", "genoutput.c", "genpeep.c", and "genrecog.c". The third problem is that enumerated types are used as the second argument to va_arg() macros in some places. Now the SPEC gcc code uses instead of the ANSI C , so strictly speaking ANSI guarantees nothing at all about the behavior in this case. It's perfectly ANSI-compatible to not have a at all. However, the ANSI va_arg() macro does have the same usage as the traditional version, and the ANSI standard explicitly says the behavior is undefined unless the type in the second parameter is compatible with the type of the actual argument after the default promotions. That can't be guaranteed for any enumerated type because enumerated types are allowed to be compatible with integer types smaller than int. In the case of the SUIF ANSI C front end, enumerated types are made compatible with the smallest possible integer type, so most enumerated types will not be compatible with their types after the default promotions. And it turns out that the file we use with mips-dec-ultrix compilation cannot properly handle types that are smaller than ``int'' as the second argument to a va_arg() macro. Our fix is to replace the enumerated type with ``int'' in the second argument to va_arg() in all these places. Then we only have to assume that whichever type the compiler makes the enumerated type compatible with, it is no larger than an ``int'' (i.e. it is not ``long'' or ``unsigned long''). It is difficult to imagine any reason a compiler would use a long for these enumerated types since the members all easily fit in an ``int'', so it is unlikely this assumption will ever fail to hold -- certainly it will not for SUIF. This is the reason for the changes to "emit-rtl.c", "expr.c", and "tree.c". In addition, for a mips-dec-ultrix machine we use the "stddef.h" from the "src.alt" directory instead of the default "stddef.h" in the gcc directory. Both are provided by SPEC and either is allowed by SPEC rules. This avoids a re-definition of size_t, which is declared in the mips-dec-ultrix system headers anyway. We also move the default "config.h" supplied by SPEC and link "config/xm-m68k.h" as our "config.h". Otherwise ``USG'' gets defined, which causes the inclusion of some conditional code that won't compile on a mips-dec-ultrix machine. Finally, note that when running gcc the output for one of the test input files, "optabs.i", does not exactly match that provided by SPEC in the "result.ref" directory (actually SPEC provides four input files, "1optabs.i", "2optabs.i", "3optabs.i", and "4optabs.i", and four corresponding output files, but they are exact duplicates -- SPEC just wants more work done for performance evaluation purposes). For this one test, two adjacent lines are switched. There are no other differences in this or any other output file; the SUIF-compiled gcc passes every other test perfectly. However, the output using SUIF to compile SPEC gcc (with the changes listed here) is exactly the same as that using gcc 2.5.8 on a mips-dec-ultrix machine to compile the original SPEC gcc -- the same two lines are switched around. So whatever the reason for the descrepency, it's not a problem caused by the SUIF system. Here is a patch to fix these problems and allow SUIF to successfully compile gcc on a mips-dec-ultrix machine: *** rtl.h.old Fri Feb 14 19:40:45 1992 --- rtl.h Fri May 13 22:29:38 1994 *************** *** 118,127 **** unsigned short code; #else /* The kind of expression this is. */ ! enum rtx_code code : 16; #endif /* The kind of value the expression has. */ ! enum machine_mode mode : 8; /* 1 in an INSN if it can alter flow of control within this function. Not yet used! */ unsigned int jump : 1; --- 118,127 ---- unsigned short code; #else /* The kind of expression this is. */ ! unsigned code : 16; #endif /* The kind of value the expression has. */ ! unsigned mode : 8; /* 1 in an INSN if it can alter flow of control within this function. Not yet used! */ unsigned int jump : 1; *** tree.h.old Fri Feb 14 19:44:41 1992 --- tree.h Thu May 12 18:39:16 1994 *************** *** 128,134 **** int uid; union tree_node *chain; union tree_node *type; ! enum tree_code code : 8; unsigned external_attr : 1; unsigned public_attr : 1; --- 128,134 ---- int uid; union tree_node *chain; union tree_node *type; ! unsigned code : 8; unsigned external_attr : 1; unsigned public_attr : 1; *************** *** 450,456 **** union tree_node *sep; union tree_node *size; ! enum machine_mode mode : 8; unsigned char size_unit; unsigned char align; unsigned char sep_unit; --- 450,456 ---- union tree_node *sep; union tree_node *size; ! unsigned mode : 8; unsigned char size_unit; unsigned char align; unsigned char sep_unit; *** emit-rtl.c.old Fri Feb 14 19:28:56 1992 --- emit-rtl.c Thu May 26 18:35:34 1994 *************** *** 183,190 **** register rtx rt_val; /* RTX to return to caller... */ va_start (p); ! code = va_arg (p, enum rtx_code); ! mode = va_arg (p, enum machine_mode); if (code == CONST_INT) { --- 183,190 ---- register rtx rt_val; /* RTX to return to caller... */ va_start (p); ! code = va_arg (p, int); ! mode = va_arg (p, int); if (code == CONST_INT) { *** expr.c.old Fri Feb 14 19:29:37 1992 --- expr.c Thu May 26 18:34:32 1994 *************** *** 1482,1488 **** va_start (p); orgfun = fun = va_arg (p, rtx); ! outmode = va_arg (p, enum machine_mode); nargs = va_arg (p, int); regvec = (rtx *) alloca (nargs * sizeof (rtx)); --- 1482,1488 ---- va_start (p); orgfun = fun = va_arg (p, rtx); ! outmode = va_arg (p, int); nargs = va_arg (p, int); regvec = (rtx *) alloca (nargs * sizeof (rtx)); *************** *** 1493,1499 **** for (count = 0; count < nargs; count++) { rtx val = va_arg (p, rtx); ! enum machine_mode mode = va_arg (p, enum machine_mode); argvec[count].value = val; --- 1493,1499 ---- for (count = 0; count < nargs; count++) { rtx val = va_arg (p, rtx); ! enum machine_mode mode = va_arg (p, int); argvec[count].value = val; *** gencodes.c.old Fri Feb 14 19:30:20 1992 --- gencodes.c Fri May 13 23:19:38 1994 *************** *** 72,77 **** --- 72,78 ---- void fatal (s, a1, a2) + char *s; { fprintf (stderr, "gencodes: "); fprintf (stderr, s, a1, a2); *** genconfig.c.old Fri Feb 14 19:30:20 1992 --- genconfig.c Fri May 13 23:21:08 1994 *************** *** 189,194 **** --- 189,195 ---- void fatal (s, a1, a2) + char *s; { fprintf (stderr, "genconfig: "); fprintf (stderr, s, a1, a2); *** genemit.c.old Fri Feb 14 19:30:20 1992 --- genemit.c Tue May 17 17:38:25 1994 *************** *** 387,392 **** --- 387,393 ---- void fatal (s, a1, a2) + char *s; { fprintf (stderr, "genemit: "); fprintf (stderr, s, a1, a2); *** genextract.c.old Fri Feb 14 19:30:20 1992 --- genextract.c Tue May 17 21:52:44 1994 *************** *** 235,240 **** --- 235,241 ---- void fatal (s, a1, a2) + char *s; { fprintf (stderr, "genextract: "); fprintf (stderr, s, a1, a2); *** genflags.c.old Fri Feb 14 19:30:20 1992 --- genflags.c Fri May 13 23:18:16 1994 *************** *** 74,79 **** --- 74,80 ---- void fatal (s, a1, a2) + char *s; { fprintf (stderr, "genflags: "); fprintf (stderr, s, a1, a2); *** genoutput.c.old Fri Feb 14 19:30:21 1992 --- genoutput.c Wed May 18 00:07:57 1994 *************** *** 694,699 **** --- 694,700 ---- void fatal (s, a1, a2) + char *s; { fprintf (stderr, "genoutput: "); fprintf (stderr, s, a1, a2); *************** *** 703,708 **** --- 704,710 ---- void error (s, a1, a2) + char *s; { fprintf (stderr, "genoutput: "); fprintf (stderr, s, a1, a2); *** genpeep.c.old Fri Feb 14 19:30:21 1992 --- genpeep.c Tue May 17 20:37:45 1994 *************** *** 332,337 **** --- 332,338 ---- void fatal (s, a1, a2) + char *s; { fprintf (stderr, "genpeep: "); fprintf (stderr, s, a1, a2); *** genrecog.c.old Fri Feb 14 19:30:31 1992 --- genrecog.c Tue May 17 21:07:31 1994 *************** *** 991,996 **** --- 991,997 ---- void fatal (s, a1, a2) + char *s; { fprintf (stderr, "genrecog: "); fprintf (stderr, s, a1, a2); No differences encountered *** tree.c.old Fri Feb 14 19:44:30 1992 --- tree.c Thu May 26 18:26:43 1994 *************** *** 1120,1126 **** va_start (p); ! code = va_arg (p, enum tree_code); t = make_node (code); length = tree_code_length[(int) code]; TREE_TYPE (t) = va_arg (p, tree); --- 1120,1126 ---- va_start (p); ! code = va_arg (p, int); t = make_node (code); length = tree_code_length[(int) code]; TREE_TYPE (t) = va_arg (p, tree); *************** *** 1166,1172 **** va_start (p); ! code = va_arg (p, enum tree_code); t = make_node (code); length = tree_code_length[(int) code]; --- 1166,1172 ---- va_start (p); ! code = va_arg (p, int); t = make_node (code); length = tree_code_length[(int) code]; *** varasm.c.old Fri Feb 14 19:44:41 1992 --- varasm.c Mon May 16 10:47:10 1994 *************** *** 1204,1213 **** bzero (const_rtx_hash_table, sizeof const_rtx_hash_table); } struct rtx_const { ! enum kind { RTX_DOUBLE, RTX_INT } kind : 16; ! enum machine_mode mode : 16; union { union real_extract du; struct addr_const addr; --- 1204,1215 ---- bzero (const_rtx_hash_table, sizeof const_rtx_hash_table); } + enum kind { RTX_DOUBLE, RTX_INT }; + struct rtx_const { ! unsigned kind : 16; ! unsigned mode : 16; union { union real_extract du; struct addr_const addr;