diff: handling of --grade options

Fergus Henderson fjh at murlibobo.cs.mu.OZ.AU
Wed Oct 8 22:17:05 AEST 1997


I wrote:

>Tyson Richard DOWD, you wrote:
>
> > >  convert_grade_option(Grade0) -->
>...
> > If this gets any longer, I'd recommend redesigning it to use some
> > sort of table
>
>That is a good suggestion.

But on second thoughts it seems to be easier said than done ;-)

Anyway here's a new diff that addresses the other points you raised.

--------------------------------------------------

Change mgnuc and ml to support the same
compilation model options as mmc.
Allow the user to mix `--grade foo' options with
other options that affect the grade such as `--profiling'.
Compute the final grade to link with from the options.

Also add a few new options and grade modifiers.

compiler/options.m:
compiler/mercury_compile.m:
	Add `--profile-time' and `--profile-calls' options.
	Change `--profiling' to now just imply both of those.
	Add `--pic-reg' option (just implies `-DPIC_REG' in cflags).

compiler/handle_options.m:
	Add support for grade modifiers `.proftime' and `.profcalls'.
	Make `.debug' a grade modifier, rather than having a base
	grade `debug'.

scripts/init_grade_options.sh-subr:
scripts/parse_grade_options.sh-subr:
	New files containing sh subroutines for parsing grade-related
	options.

configure.in:
bindist/bindist.configure.in:
	Use AC_SUBST_FILE to allow #inclusion of the above-mentioned
	`.sh-subr' files.

scripts/ml.in:
scripts/mgnuc.in:
	Use the above-mentioned sh subroutines.

scripts/ml.in:
compiler/mercury_compile.m:
compiler/handle_options.m:
	Compute the final grade to link with from the various
	grade-related options.

scripts/mgnuc.in:
	Support the `--inline-alloc' option.
	
doc/user_guide.texi:
README.Linux:
	Document the above changes.

cvs diff -N README.Linux bindist/bindist.configure.in compiler/handle_options.m compiler/mercury_compile.m compiler/options.m configure.in doc/user_guide.texi scripts/init_grade_options.sh-subr scripts/mgnuc.in scripts/ml.in scripts/parse_grade_options.sh-subr
Index: README.Linux
===================================================================
RCS file: /home/staff/zs/imp/mercury/README.Linux,v
retrieving revision 1.4
diff -u -r1.4 README.Linux
--- README.Linux	1997/08/08 20:14:16	1.4
+++ README.Linux	1997/10/07 16:22:22
@@ -26,17 +26,18 @@
 a future release.)
 
 To use the shared libraries, you must compile your program with
-`mmc --cflags -DPIC_REG' and link with `ml --mercury-libs shared'
-or add `MGNUCFLAGS=-DPIC_REG' and `MLFLAGS=--mercury-libs shared'
+`mmc --pic-reg' and link with `ml --mercury-libs shared'
+or add `MGNUCFLAGS=--pic-reg' and `MLFLAGS=--mercury-libs shared'
 to your Mmake file.
 
-Mercury code compiled with `-DPIC_REG' or `-fpic' has what we shall call
-"PIC linkage", whereas Mercury code compiled without these options has
-"non-PIC linkage".  The static version of the Mercury libraries has
-non-PIC linkage, while the shared version has PIC linkage.
-Be very careful that you do not try to link Mercury code
-with PIC linkage and Mercury code with non-PIC linkage into the same
-executable, otherwise your code will *almost certainly crash*.
+Mercury code compiled with `--pic-reg' or with gcc's `-fpic' option has
+what we shall call "PIC linkage", whereas Mercury code compiled without
+these options has "non-PIC linkage".  The static version of the Mercury
+libraries has non-PIC linkage, while the shared version has PIC linkage.
+Be careful that you do not try to link Mercury code with PIC linkage and
+Mercury code with non-PIC linkage into the same executable, otherwise you
+will probably get an obscure link error about `MR_grade_...' undefined
+or `MR_runtime_grade' multiply defined.
 (The reason for this is that standard non-PIC Mercury code uses the
 `ebx' register in ways that are incompatible with its uses as the global
 offset table pointer register in PIC code.  If only the Intel
Index: configure.in
===================================================================
RCS file: /home/staff/zs/imp/mercury/configure.in,v
retrieving revision 1.111
diff -u -r1.111 configure.in
--- configure.in	1997/10/07 17:29:12	1.111
+++ configure.in	1997/10/08 09:07:46
@@ -1463,6 +1463,16 @@
 AC_SUBST(BOOTSTRAP_MC)
 #-----------------------------------------------------------------------------#
 
+# The following allows us to share some subroutines between the
+# `ml' and `mgnuc' scripts.
+
+top=`pwd`
+INIT_GRADE_OPTIONS=$top/scripts/init_grade_options.sh-subr
+PARSE_GRADE_OPTIONS=$top/scripts/parse_grade_options.sh-subr
+AC_SUBST_FILE(INIT_GRADE_OPTIONS)
+AC_SUBST_FILE(PARSE_GRADE_OPTIONS)
+
+#-----------------------------------------------------------------------------#
 AC_OUTPUT(Mmake.common scripts/Mmake.vars scripts/mmc scripts/mprof
 scripts/mercury_update_interface scripts/mgnuc scripts/mint scripts/ml
 scripts/mmake scripts/mnc scripts/mnl scripts/mnp scripts/c2init
Index: bindist/bindist.configure.in
===================================================================
RCS file: /home/staff/zs/imp/mercury/bindist/bindist.configure.in,v
retrieving revision 1.12
diff -u -r1.12 bindist.configure.in
--- bindist.configure.in	1997/08/14 11:59:25	1.12
+++ bindist.configure.in	1997/10/08 09:07:34
@@ -161,6 +161,17 @@
 AC_SUBST(CC)
 #-----------------------------------------------------------------------------#
 
+# The following allows us to share some subroutines between the
+# `ml' and `mgnuc' scripts.
+
+top=`pwd`/..
+INIT_GRADE_OPTIONS=$top/scripts/init_grade_options.sh-subr
+PARSE_GRADE_OPTIONS=$top/scripts/parse_grade_options.sh-subr
+AC_SUBST_FILE(INIT_GRADE_OPTIONS)
+AC_SUBST_FILE(PARSE_GRADE_OPTIONS)
+
+#-----------------------------------------------------------------------------#
+
 AC_OUTPUT(Makefile scripts/mmc scripts/mprof
 scripts/mercury_update_interface scripts/mgnuc scripts/mint scripts/ml
 scripts/mmake scripts/mnc scripts/mnl scripts/mnp scripts/c2init
Index: compiler/handle_options.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/handle_options.m,v
retrieving revision 1.29
diff -u -r1.29 handle_options.m
--- handle_options.m	1997/09/02 07:03:39	1.29
+++ handle_options.m	1997/10/08 09:42:03
@@ -10,12 +10,15 @@
 % This module does post-procesing on the command-line options, after
 % getopt has done its stuff.
 
+% It also contains code for handling the --grade option.
+
 %-----------------------------------------------------------------------------%
 
 :- module handle_options.
 
 :- interface.
 :- import_module list, bool, std_util, io.
+:- import_module globals, options.
 
 :- pred handle_options(maybe(string), list(string), bool, io__state, io__state).
 :- mode handle_options(out, out, out, di, uo) is det.
@@ -29,6 +32,16 @@
 	% Display long usage message for help
 :- pred long_usage(io__state::di, io__state::uo) is det.
 
+
+	% Given the current set of options, figure out
+	% which grade to use.
+:- pred compute_grade(globals::in, string::out) is det.
+
+	% The inverse of compute_grade: given a grade,
+	% set the appropriate options.
+:- pred convert_grade_option(string::in, option_table::in, option_table::out)
+	is semidet.
+
 %-----------------------------------------------------------------------------%
 
 :- implementation.
@@ -94,12 +107,7 @@
 :- mode postprocess_options(in, out, di, uo) is det.
 
 postprocess_options(error(ErrorMessage), yes(ErrorMessage)) --> [].
-postprocess_options(ok(OptionTable0), Error) -->
-        { map__lookup(OptionTable0, grade, GradeOpt) },
-        (
-            { GradeOpt = string(GradeStr) },
-            { convert_grade_option(GradeStr, OptionTable0, OptionTable) }
-        ->
+postprocess_options(ok(OptionTable), Error) -->
             { map__lookup(OptionTable, gc, GC_Method0) },
             (
                 { GC_Method0 = string(GC_MethodStr) },
@@ -158,10 +166,7 @@
                 )
             ;
                 { Error = yes("Invalid GC option (must be `none', `conservative' or `accurate')") }
-            )
-        ;
-            { Error = yes("Invalid grade option") }
-        ).
+            ).
 
 :- pred postprocess_options_2(option_table, gc_method, tags_method, args_method,
 	type_info_method, prolog_dialect, io__state, io__state).
@@ -219,7 +224,8 @@
 		io__progname_base("mercury_compile", ProgName),
 		io__stderr_stream(StdErr),
 		report_warning(ProgName),
-		report_warning(": warning: --num-tag-bits invalid or unspecified\n"),
+		report_warning(
+			": warning: --num-tag-bits invalid or unspecified\n"),
 		io__write_string(StdErr, ProgName),
 		report_warning(": using --num-tag-bits 0 (tags disabled)\n"),
 		{ NumTagBits = 0 }
@@ -248,7 +254,8 @@
 	% -D all is really -D "abcdefghijklmnopqrstuvwxyz"
 	globals__io_lookup_string_option(verbose_dump_hlds, VerboseDump),
 	( { VerboseDump = "all" } ->
-		globals__io_set_option(verbose_dump_hlds, string("abcdefghijklmnopqrstuvwxyz"))
+		globals__io_set_option(verbose_dump_hlds,
+			string("abcdefghijklmnopqrstuvwxyz"))
 	;	
 		[]
 	),
@@ -304,32 +311,184 @@
 		[]
 	).
 
-:- pred convert_grade_option(string::in, option_table::in, option_table::out)
-	is semidet.
+	% IMPORTANT: any changes here may require similar changes to
+	%	runtime/mercury_grade.h
+	%	scripts/ml.in
+
+compute_grade(Globals, Grade) :-
+	globals__lookup_bool_option(Globals, asm_labels, AsmLabels),
+	globals__lookup_bool_option(Globals, gcc_non_local_gotos,
+						NonLocalGotos),
+	globals__lookup_bool_option(Globals, gcc_global_registers, GlobalRegs),
+	globals__get_gc_method(Globals, GC_Method),
+	globals__lookup_bool_option(Globals, profile_time, ProfileTime),
+	globals__lookup_bool_option(Globals, profile_calls, ProfileCalls),
+	globals__lookup_bool_option(Globals, use_trail, UseTrail),
+/*
+% These vary from machine to machine, and (for backwards compatibility,
+% if nothing else) we want examples such as "GRADE = asm_fast.gc.prof"
+% to continue to work, so we can't include these in the grade.
+	globals__get_tags_method(Globals, TagsMethod),
+	globals__lookup_int_option(Globals, tag_bits, TagBits),
+	globals__lookup_bool_option(Globals, unboxed_float, UnboxedFloat),
+*/
+	globals__get_args_method(Globals, ArgsMethod),
+	globals__lookup_bool_option(Globals, debug, Debug),
+/*
+	globals__lookup_bool_option(Globals, pic_reg, PIC_Reg),
+*/
+
+	( AsmLabels = yes ->
+		Part1 = "asm_"
+	;
+		Part1 = ""
+	),
+	( NonLocalGotos = yes ->
+		( GlobalRegs = yes ->
+			Part2 = "fast"
+		;
+			Part2 = "jump"
+		)
+	;
+		( GlobalRegs = yes ->
+			Part2 = "reg"
+		;
+			Part2 = "none"
+		)
+	),
+	( GC_Method = conservative, Part3 = ".gc"
+	; GC_Method = accurate, Part3 = ".agc"
+	; GC_Method = none, Part3 = ""
+	),
+	( ProfileTime = yes ->
+		( ProfileCalls = yes ->
+			Part4 = ".prof"
+		; 
+			Part4 = ".proftime"
+		)
+	;
+		( ProfileCalls = yes ->
+			Part4 = ".profcalls"
+		; 
+			Part4 = ""
+		)
+	),
+	( UseTrail = yes ->
+		Part5 = ".tr"
+	;
+		Part5 = ""
+	),
+
+/*
+% These vary from machine to machine, and (for backwards compatibility,
+% if nothing else) we want examples such as "GRADE = asm_fast.gc.prof"
+% to continue to work, so we can't include these in the grade.
+	( HighTags = yes ->
+		string__format(".hightags%d", [i(TagBits)], Part6)
+	;
+		string__format(".tags%d", [i(TagBits)], Part6)
+	;
+		
+	),
+	( UnboxedFloat = yes ->
+		Part7 = ".ubf"
+	;
+		Part7 = ""
+	),
+*/
+	Part6 = "",
+	Part7 = "",
+
+	( ArgsMethod = compact, Part8 = ""
+	; ArgsMethod = simple, Part8 = ".sa"
+	),
+
+	( Debug = yes ->
+		Part9 = ".debug"
+	;
+		Part9 = ""
+	),
+
+/*******
+	% This can't be part of the grade, due to the way
+	% we handle things on Linux.  See README.Linux.
+	( PIC_Reg = yes ->
+		Part10 = ".picreg"
+	;
+		Part10 = ""
+	),
+*******/
+	Part10 = "",
+
+	string__append_list( [Part1, Part2, Part3, Part4, Part5,
+				Part6, Part7, Part8, Part9, Part10], Grade).
+
+	% IMPORTANT: any changes here may require similar changes to
+	%	runtime/mercury_grade.h
+	%	scripts/parse_grade_options.sh-subr
 
 convert_grade_option(Grade0) -->
-	( { string__remove_suffix(Grade0, ".tr", Grade1) } ->
+	% part10
+	( { string__remove_suffix(Grade0, ".picreg", Grade1) } ->
 		{ Grade2 = Grade1 },
-		set_bool_opt(use_trail, yes)
+		set_bool_opt(pic_reg, yes)
 	;
 		{ Grade2 = Grade0 },
-		set_bool_opt(use_trail, no)
+		set_bool_opt(pic_reg, no)
 	),
-	( { string__remove_suffix(Grade2, ".prof", Grade3) } ->
+	% part9
+	( { string__remove_suffix(Grade2, ".debug", Grade3) } ->
 		{ Grade4 = Grade3 },
-		set_bool_opt(profiling, yes)
+		set_bool_opt(debug, yes)
 	;
 		{ Grade4 = Grade2 },
-		set_bool_opt(profiling, no)
+		set_bool_opt(debug, no)
+	),
+	% part8
+	( { string__remove_suffix(Grade4, ".sa", Grade5) } ->
+		{ Grade6 = Grade5 },
+		set_string_opt(args, "simple")
+	;
+		{ Grade6 = Grade4 },
+		set_string_opt(args, "compact")
+	),
+	% part6 & 7
+	{ Grade10 = Grade6 },
+	% part5
+	( { string__remove_suffix(Grade10, ".tr", Grade11) } ->
+		{ Grade12 = Grade11 },
+		set_bool_opt(use_trail, yes)
+	;
+		{ Grade12 = Grade10 },
+		set_bool_opt(use_trail, no)
 	),
-	( { string__remove_suffix(Grade4, ".gc", Grade5) } ->
-		{ Grade = Grade5 },
+	% part 4
+	( { string__remove_suffix(Grade12, ".prof", Grade13) } ->
+		{ Grade14 = Grade13 },
+		set_bool_opt(profile_time, yes),
+		set_bool_opt(profile_calls, yes)
+	; { string__remove_suffix(Grade12, ".proftime", Grade13) } ->
+		{ Grade14 = Grade13 },
+		set_bool_opt(profile_time, yes),
+		set_bool_opt(profile_calls, no)
+	; { string__remove_suffix(Grade12, ".profcalls", Grade13) } ->
+		{ Grade14 = Grade13 },
+		set_bool_opt(profile_time, no),
+		set_bool_opt(profile_calls, yes)
+	;
+		{ Grade14 = Grade12 },
+		set_bool_opt(profile_time, no),
+		set_bool_opt(profile_calls, no)
+	),
+	% part 3
+	( { string__remove_suffix(Grade14, ".gc", Grade15) } ->
+		{ Grade = Grade15 },
 		{ GC = conservative }
-	; { string__remove_suffix(Grade4, ".agc", Grade5) } ->
-		{ Grade = Grade5 },
+	; { string__remove_suffix(Grade14, ".agc", Grade15) } ->
+		{ Grade = Grade15 },
 		{ GC = accurate }
 	;
-		{ Grade = Grade4 },
+		{ Grade = Grade14 },
 		{ GC = none }
 	),
 	% Set the type of gc that the grade option implies.
@@ -344,6 +503,7 @@
 		{ GC = none },
 		set_string_opt(gc, "none")
 	),
+	% parts 2 & 1
 	convert_grade_option_2(Grade).
 
 :- pred convert_grade_option_2(string::in, option_table::in, option_table::out)
Index: compiler/mercury_compile.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/mercury_compile.m,v
retrieving revision 1.54
diff -u -r1.54 mercury_compile.m
--- mercury_compile.m	1997/09/25 03:34:51	1.54
+++ mercury_compile.m	1997/10/02 01:01:33
@@ -1027,9 +1027,10 @@
 
 mercury_compile__maybe_output_prof_call_graph(ModuleInfo0, Verbose, Stats,
 		ModuleInfo) -->
-	globals__io_lookup_bool_option(profiling, Profiling),
+	globals__io_lookup_bool_option(profile_calls, ProfileCalls),
+	globals__io_lookup_bool_option(profile_time, ProfileTime),
 	(
-		{ Profiling = yes }
+		{ ProfileCalls = yes ; ProfileTime = yes }
 	->
 		maybe_write_string(Verbose, "% Outputing profiling call graph..."),
 		maybe_flush_output(Verbose),
@@ -1656,11 +1657,23 @@
 	;
 		GC_Opt = ""
 	},
-	globals__io_lookup_bool_option(profiling, Profiling),
-	{ Profiling = yes ->
-		ProfileOpt = "-DPROFILE_CALLS -DPROFILE_TIME "
+	globals__io_lookup_bool_option(profile_calls, ProfileCalls),
+	{ ProfileCalls = yes ->
+		ProfileCallsOpt = "-DPROFILE_CALLS "
 	;
-		ProfileOpt = ""
+		ProfileCallsOpt = ""
+	},
+	globals__io_lookup_bool_option(profile_time, ProfileTime),
+	{ ProfileTime = yes ->
+		ProfileTimeOpt = "-DPROFILE_TIME "
+	;
+		ProfileTimeOpt = ""
+	},
+	globals__io_lookup_bool_option(pic_reg, PIC_Reg),
+	{ PIC_Reg = yes ->
+		PIC_Reg_Opt = "-DPIC_REG "
+	;
+		PIC_Reg_Opt = ""
 	},
 	globals__io_get_tags_method(Tags_Method),
 	{ Tags_Method = high ->
@@ -1746,7 +1759,8 @@
 	{ string__append_list([CC, " ", InclOpt, SplitOpt, OptimizeOpt,
 		RegOpt, GotoOpt, AsmOpt,
 		CFLAGS_FOR_REGS, " ", CFLAGS_FOR_GOTOS, " ",
-		GC_Opt, ProfileOpt, TagsOpt, NumTagBitsOpt, DebugOpt,
+		GC_Opt, ProfileCallsOpt, ProfileTimeOpt, PIC_Reg_Opt,
+		TagsOpt, NumTagBitsOpt, DebugOpt,
 		UseTrailOpt, ArgsOpt, TypeInfoOpt, TypeLayoutOpt,
 		InlineAllocOpt, WarningOpt, CFLAGS,
 		" -c ", C_File, " -o ", O_File], Command) },
@@ -1815,7 +1829,8 @@
 		    report_error("compilation of init file failed.")
 		;
 		    maybe_write_string(Verbose, "% Linking...\n"),
-		    globals__io_lookup_string_option(grade, Grade),
+		    globals__io_get_globals(Globals),
+		    { compute_grade(Globals, Grade) },
 		    globals__io_lookup_accumulating_option(link_flags,
 				LinkFlagsList),
 		    { join_string_list(LinkFlagsList, "", "", " ", LinkFlags) },
Index: compiler/options.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/options.m,v
retrieving revision 1.203
diff -u -r1.203 options.m
--- options.m	1997/08/25 02:24:46	1.203
+++ options.m	1997/10/08 11:22:44
@@ -93,7 +93,10 @@
 		;	asm_labels
 		;	gc
 		;	profiling
+		;	profile_calls
+		;	profile_time
 		;	use_trail
+		;	pic_reg
 		;	debug
 		;	debug_data
 		;	tags
@@ -220,7 +223,8 @@
 
 :- implementation.
 
-:- import_module bool, int, map, std_util, assoc_list, require, list.
+:- import_module string, bool, int, map, std_util, assoc_list, require, list.
+:- import_module handle_options.
 
 :- type option_category
 	--->	warning_option
@@ -312,16 +316,19 @@
 option_defaults_2(compilation_model_option, [
 		% Compilation model options (ones that affect binary
 		% compatibility).
-	grade			-	string("asm_fast.gc"),
-					% the `mc' script will override the
-					% above default with a value determined
+	grade			-	string_special,
+					% the `mc' script will pass the
+					% default grade determined
 					% at configuration time
 	gcc_non_local_gotos	-	bool(yes),
 	gcc_global_registers	-	bool(yes),
 	asm_labels		-	bool(yes),
 	gc			-	string("conservative"),
-	profiling		-	bool(no),
+	profiling		-	bool_special,
+	profile_calls		-	bool(no),
+	profile_time		-	bool(no),
 	use_trail		-	bool(no),
+	pic_reg			-	bool(no),
 	debug			-	bool(no),
 	tags			-	string("low"),
 	num_tag_bits		-	int(-1),
@@ -594,6 +601,10 @@
 long_option("gc",			gc).
 long_option("garbage-collection",	gc).
 long_option("profiling",		profiling).
+long_option("profile-calls",		profile_calls).
+long_option("profile-time",		profile_time).
+long_option("use-trail",		use_trail).
+long_option("pic-reg",			pic_reg).
 long_option("debug",			debug).
 long_option("tags",			tags).
 long_option("num-tag-bits",		num_tag_bits).
@@ -750,6 +761,16 @@
 
 %-----------------------------------------------------------------------------%
 
+special_handler(grade, string(Grade), OptionTable0, Result) :-
+	( convert_grade_option(Grade, OptionTable0, OptionTable) ->
+		Result = ok(OptionTable)
+	;
+		string__append_list(["invalid Grade `", Grade, "'"], Msg),
+		Result = error(Msg)
+	).
+special_handler(profiling, bool(Value), OptionTable0, ok(OptionTable)) :-
+	map__set(OptionTable0, profile_time, bool(Value), OptionTable1),
+	map__set(OptionTable1, profile_calls, bool(Value), OptionTable).
 special_handler(inlining, bool(Value), OptionTable0, ok(OptionTable)) :-
 	map__set(OptionTable0, inline_simple, bool(Value), OptionTable1),
 	map__set(OptionTable1, inline_single_use, bool(Value), OptionTable2),
@@ -984,6 +1005,7 @@
 	options_help_hlds_llds_optimization,
 	options_help_llds_llds_optimization,
 	options_help_output_optimization,
+	options_help_object_optimization,
 	options_help_link,
 	options_help_misc.
 
@@ -1168,13 +1190,12 @@
 	io__write_string("\tcompiled with the same setting of these options,\n"),
 	io__write_string("\tand it must be linked to a version of the Mercury\n"),
 	io__write_string("\tlibrary which has been compiled with the same setting.\n"),
-	io__write_string("\tRather than setting them individually, you must\n"),
-	io__write_string("\tspecify them all at once by selecting a particular\n"),
-	io__write_string("\tcompilation model (""grade"").\n\n"),
 	io__write_string("\t-s <grade>, --grade <grade>\n"),
 	io__write_string("\t\tSelect the compilation model. The <grade> should be one of\n"),
-	io__write_string("\t\t`debug', `none', `reg', `jump', `asm_jump', `fast', `asm_fast',\n"),
-	io__write_string("\t\tor one of those with `.gc', `.prof' or `.gc.prof' appended.\n"),
+	io__write_string("\t\t`none', `reg', `jump', `asm_jump', `fast', `asm_fast',\n"),
+	io__write_string("\t\tor one of those with `.gc', `.prof', `.proftime',\n"),
+	io__write_string("\t\t`.profcalls', `.tr', `.sa', `.debug', and/or `.pic_reg'\n"),
+	io__write_string("\t\tappended (in that order).\n"),
 	io__write_string("\t\tDepending on your particular installation, only a subset\n"),
 	io__write_string("\t\tof these possible grades will have been installed.\n"),
 	io__write_string("\t\tAttempting to use a grade which has not been installed\n"),
@@ -1182,19 +1203,19 @@
 	io__write_string("\t--gcc-global-registers\t"),
 	io__write_string("\t(grades: reg, fast, asm_fast)\n"),
 	io__write_string("\t--no-gcc-global-registers"),
-	io__write_string("\t(grades: debug, none, jump, asm_jump)\n"),
+	io__write_string("\t(grades: none, jump, asm_jump)\n"),
 	io__write_string("\t\tSpecify whether or not to use GNU C's\n"),
 	io__write_string("\t\tglobal register variables extension.\n"),
 	io__write_string("\t--gcc-non-local-gotos\t"),
 	io__write_string("\t(grades: jump, fast, asm_jump, asm_fast)\n"),
 	io__write_string("\t--no-gcc-non-local-gotos"),
-	io__write_string("\t(grades: debug, none, reg)\n"),
+	io__write_string("\t(grades: none, reg)\n"),
 	io__write_string("\t\tSpecify whether or not to use GNU C's\n"),
 	io__write_string("\t\t""labels as values"" extension.\n"),
 	io__write_string("\t--asm-labels\t\t"),
 	io__write_string("\t(grades: asm_jump, asm_fast)\n"),
 	io__write_string("\t--no-asm-labels\t\t"),
-	io__write_string("\t(grades: debug, none, reg, jump, fast)\n"),
+	io__write_string("\t(grades: none, reg, jump, fast)\n"),
 	io__write_string("\t\tSpecify whether or not to use GNU C's\n"),
 	io__write_string("\t\tasm extensions for inline assembler labels.\n"),
 	io__write_string("\t--gc {none, conservative, accurate}\n"),
@@ -1204,22 +1225,39 @@
 	io__write_string("\t\tSpecify which method of garbage collection to use\n"),
 	io__write_string("\t\t(default: conservative).  `accurate' GC is not yet implemented.\n"),
 	io__write_string("\t--use-trail\n"),
-	io__write_string("\t(grades: any grade ending in `.tr')\n"),
+	io__write_string("\t(grades: any grade containing `.tr')\n"),
 	io__write_string("\t\tEnable use of a trail.\n"),
 	io__write_string("\t\tThis is necessary for interfacing with constraint solvers,\n"),
 	io__write_string("\t\tor for backtrackable destructive update.\n"),
 	io__write_string("\t--profiling\t\t"),
-	io__write_string("\t(grades: any grade ending in `.prof')\n"),
+	io__write_string("\t(grades: any grade containing `.prof')\n"),
 	io__write_string("\t\tEnable profiling.  Insert profiling hooks in the\n"),
 	io__write_string("\t\tgenerated code, and also output some profiling\n"),
 	io__write_string("\t\tinformation (the static call graph) to the file\n"),
 	io__write_string("\t\t`<module>.prof'.\n"),
+	io__write_string("\t--profile-calls\t\t"),
+	io__write_string("\t(grades: any grade containing `.profcalls')\n"),
+	io__write_string("\t\tSimilar to --profiling, except that only gathers\n"),
+	io__write_string("\t\tcall counts, not timing information.\n"),
+	io__write_string("\t\tUseful on systems where time profiling is not supported\n"),
+	io__write_string("\t\t(e.g. MS Windows).\n"),
+	io__write_string("\t--profile-time\t\t"),
+	io__write_string("\t(grades: any grade containing `.profcalls')\n"),
+	io__write_string("\t\tSimilar to --profiling, except that only gathers\n"),
+	io__write_string("\t\ttiming information, not call counts.\n"),
 	io__write_string("\t--debug\t\t\t"),
-	io__write_string("\t(grades: debug)\n"),
+	io__write_string("\t(grades: any grade containing `.debug')\n"),
 	io__write_string("\t\tEnable debugging.\n"),
 	io__write_string("\t\tDebugging support is currently extremely primitive.\n"),
 	io__write_string("\t\tWe recommend that you use instead use `mnp' or `msp'.\n"),
 	io__write_string("\t\tSee the Mercury User's Guide for details.\n"),
+	io__write_string("\t--pic-reg\n"),
+	io__write_string("\t(grades: any grade containing `.pic_reg')\n"),
+	io__write_string("\t[For Unix with intel x86 architecture only]\n"),
+	io__write_string("\t\tSelect a register usage convention that is compatible,\n"),
+	io__write_string("\t\twith position-independent code (gcc's `-fpic' option).\n"),
+	io__write_string("\t\tThis is necessary when using shared libraries on Intel x86 systems\n"),
+	io__write_string("\t\trunning Unix.  On other systems it has no effect.\n"),
 	io__write_string("\t--tags {none, low, high}"),
 	io__write_string("\t(This option is not for general use.)\n"),
 	io__write_string("\t\tSpecify whether to use the low bits or the high bits of \n"),
@@ -1320,10 +1358,6 @@
 	io__write_string("\t--cflags <options>\n"),
 	io__write_string("\t\tSpecify options to be passed to the C compiler.\n").
 
-/*************
- % XXX documentation on `pragma fact_table' options should be uncommented when
- % fact tables are ready for public release.
-
 	io__write_string("\t--fact-table-max-array-size <n>\n"),
 	io__write_string("\t\tSpecify the maximum number of elements in a single\n"),
 	io__write_string("\t\t`pragma fact_table' data array (default: 1024).\n"),
@@ -1331,7 +1365,6 @@
 	io__write_string("\t\tSpecify how full the `pragma fact_table' hash tables should be\n"),
 	io__write_string("\t\tallowed to get.  Given as an integer percentage\n"),
 	io__write_string("\t\t(valid range: 1 to 100, default: 90).\n").
-**************/
 
 :- pred options_help_optimization(io__state::di, io__state::uo) is det.
 
@@ -1364,7 +1397,7 @@
 	is det.
 
 options_help_hlds_hlds_optimization -->
-	io__write_string("\n    High-level (HLDS->HLDS) optimizations:\n"),
+	io__write_string("\n    High-level (HLDS -> HLDS) optimizations:\n"),
 	io__write_string("\t--no-inlining\n"),
 	io__write_string("\t\tDisable all forms of inlining.\n"),
 	io__write_string("\t--no-inline-simple\n"),
@@ -1425,7 +1458,7 @@
 :- pred options_help_hlds_llds_optimization(io__state::di, io__state::uo) is det.
 
 options_help_hlds_llds_optimization -->
-	io__write_string("\n    Medium-level (HLDS->LLDS) optimizations:\n"),
+	io__write_string("\n    Medium-level (HLDS -> LLDS) optimizations:\n"),
 	io__write_string("\t--no-smart-indexing\n"),
 	io__write_string("\t\tGenerate switches as a simple if-then-else chains;\n"),
 	io__write_string("\t\tdisable string hashing and integer table-lookup indexing.\n"),
@@ -1464,7 +1497,7 @@
 :- pred options_help_llds_llds_optimization(io__state::di, io__state::uo) is det.
 
 options_help_llds_llds_optimization -->
-	io__write_string("\n    Low-level (LLDS->LLDS) optimizations:\n"),
+	io__write_string("\n    Low-level (LLDS -> LLDS) optimizations:\n"),
 	io__write_string("\t--no-llds-optimize\n"),
 	io__write_string("\t\tDisable the low-level optimization passes.\n"),
 	io__write_string("\t--optimize-dead-procs\n"),
@@ -1491,16 +1524,17 @@
 	io__write_string("\t\tIterate most optimizations at most <n> times (default: 3).\n"),
 	io__write_string("\t--optimize-vnrepeat <n>\n"),
 	io__write_string("\t\tIterate value numbering at most <n> times (default: 1).\n").
-	% io__write_string("\t--pred-value-number\n"),
-	% io__write_string("\t\tExtend value numbering to entire predicates\n").
+	io__write_string("\t--pred-value-number\n"),
+	io__write_string("\t\tExtend value numbering to entire predicates.\n").
 
 :- pred options_help_output_optimization(io__state::di, io__state::uo) is det.
 
 options_help_output_optimization -->
-	io__write_string("\n    Output-level (LLDS->C) optimizations:\n"),
+	io__write_string("\n    Output-level (LLDS -> C) optimizations:\n"),
 	io__write_string("\t--use-macro-for-redo-fail\n"),
 	io__write_string("\t\tEmit the fail or redo macro instead of a branch\n"),
 	io__write_string("\t\tto the fail or redo code in the runtime system.\n"),
+	io__write_string("\t\tThis produces slightly bigger but slightly faster code.\n"),
 	io__write_string("\t--no-emit-c-loops\n"),
 	io__write_string("\t\tUse only gotos, don't emit C loop constructs.\n"),
 	io__write_string("\t--procs-per-c-function <n>\n"),
@@ -1512,7 +1546,14 @@
 	io__write_string("\t\tThis option has the effect of putting the code for all\n"),
 	io__write_string("\t\tthe Mercury procedures in a single C function,\n"),
 	io__write_string("\t\twhich produces the most efficient code but tends to\n"),
-	io__write_string("\t\tseverely stress the C compiler on large modules.\n"),
+	io__write_string("\t\tseverely stress the C compiler on large modules.\n").
+
+:- pred options_help_object_optimization(io__state::di, io__state::uo) is det.
+
+options_help_object_optimization -->
+	io__write_string("\n    Object-level (C -> object code) optimizations:\n"),
+	io__write_string("\t\tNote that if you are using Mmake, you need to pass these\n"),
+	io__write_string("\t\toptions to `mgnuc' rather than to `mmc'.\n").
 	io__write_string("\t--no-c-optimize\n"),
 	io__write_string("\t\tDon't enable the C compiler's optimizations.\n"),
 	io__write_string("\t--inline-alloc\n"),
Index: doc/user_guide.texi
===================================================================
RCS file: /home/staff/zs/imp/mercury/doc/user_guide.texi,v
retrieving revision 1.98
diff -u -r1.98 user_guide.texi
--- user_guide.texi	1997/10/03 04:56:13	1.98
+++ user_guide.texi	1997/10/08 12:14:32
@@ -569,7 +569,7 @@
 @item @var{main-module}.split
 Compiles and links @var{main-module} using the Mercury compiler,
 with the Mercury compiler's @samp{--split-c-files} option enabled.
- at xref{Output-level (LLDS->C) optimization options} for more information
+ at xref{Output-level (LLDS -> C) optimization options} for more information
 about @samp{--split-c-files}.
 
 @item @var{main-module}.nu
@@ -913,9 +913,8 @@
 any way to do that.
 
 Due to a known timing-related bug in our code, you may occasionally get
-segmentation violations when running your program with profiling enabled.
-If this happens, just run it again --- the problem does not occur frequently.
-This bug will hopefully be fixed soon.
+segmentation violations when running your program with time profiling enabled.
+If this happens, just run it again --- the problem occurs only very rarely.
 
 @node Displaying the profile
 @section Displaying the profile
@@ -1474,17 +1473,29 @@
 compiled with the same setting of these options,
 and it must be linked to a version of the Mercury
 library which has been compiled with the same setting.
-Rather than setting them individually, you must
-specify them all at once by selecting a particular
-compilation model ("grade").
+(Attempting to link object files compiled with different
+settings of these options will generally result in an error at
+link time, typically of the form @samp{undefined symbol MR_grade_ at dots{}}
+or @samp{symbol MR_runtime_grade multiply defined}.)
+
+The options below must be passed to @samp{mgnuc} and @samp{ml} as well
+as to @samp{mmc}.
 
 @table @asis
 @item @code{-s @var{grade}}
 @itemx @code{--grade @var{grade}}
-Select the compilation model. The @var{grade} should be one of
- at samp{debug}, @samp{none}, @samp{reg}, @samp{jump}, @samp{asm_jump},
- at samp{fast}, @samp{asm_fast},
-or one of those with @samp{.gc}, @samp{.prof} or @samp{.gc.prof} appended.
+Select the compilation model. The @var{grade} should be a base
+grade with zero or more grade modifiers appended.
+The base grades are @samp{none}, @samp{reg}, @samp{jump}, @samp{asm_jump},
+ at samp{fast}, and @samp{asm_fast}.
+The grade modifiers are @samp{.gc}, @samp{.prof}, @samp{.proftime},
+ at samp{.profcalls}, @samp{.tr}, and @samp{.debug}.  The @samp{.prof},
+ at samp{.proftime}, and @samp{.profcalls} grade modifiers are mutually
+exclusive; only one of those three may be specified.
+If a grade includes more than one grade modifier,
+the grade modifiers must be given in the same order as the
+order they are listed here.
+
 The default grade is system-dependent; it is chosen at installation time
 by @samp{configure}, the auto-configuration script, but can be overridden
 with the @samp{MERCURY_DEFAULT_GRADE} environment variable if desired.
@@ -1492,17 +1503,16 @@
 of these possible grades will have been installed.
 Attempting to use a grade which has not been installed
 will result in an error at link time.
+(The error message will typically be something like
+ at samp{ld: can't find library for -lmercury}.)
 
-The following table shows the options that are selected by each grade; it
-is followed by descriptions of those options.
+The tables below show the options that are selected by each base grade
+and grade modifier; they are followed by descriptions of those options.
 
 @table @asis
 @item @var{Grade}
 @var{Options implied}.
 
- at item @samp{debug}
- at code{--debug --no-c-optimize}.
-
 @item @samp{none}
 None.
 
@@ -1521,32 +1531,45 @@
 @item @samp{asm_fast}
 @code{--gcc-global-registers --gcc-nonlocal_gotos --asm-labels}.
 
- at item Any of the above followed by @samp{.gc}
-As above, plus @code{--gc conservative}.
+ at end table
+
+ at table @asis
+ at item @var{Grade modifier}
+ at var{Options implied}.
 
- at item Any of the above followed by @samp{.prof}
-As above, plus @code{--profiling}.
+ at item @samp{.gc}
+ at code{--gc conservative}.
 
- at end table
+ at item @samp{.prof}
+ at code{--profiling}.
 
- at sp 1
-Reminder: the following optimizations should not be set individually.
-Instead, you should use the @samp{--grade} option to change the setting of
-these options.
+ at item @samp{.proftime}
+ at code{--profile-time}.
+
+ at item @samp{.profcalls}
+ at code{--profile-calls}.
+
+ at item @samp{.tr}
+ at code{--use-trail}.
+
+ at item @samp{.debug}
+ at code{--debug}.
+
+ at end table
 
 @sp 1
 @item @code{--gcc-global-registers} (grades: reg, fast, asm_fast)
- at itemx @code{--no-gcc-global-registers} (grades: debug, none, jump, asm_jump)
+ at itemx @code{--no-gcc-global-registers} (grades: none, jump, asm_jump)
 Specify whether or not to use GNU C's global register variables extension.
 
 @sp 1
 @item @code{--gcc-non-local-gotos} (grades: jump, fast, asm_jump, asm_fast)
- at item @code{--no-gcc-non-local-gotos} (grades: debug, none, reg)
+ at item @code{--no-gcc-non-local-gotos} (grades: none, reg)
 Specify whether or not to use GNU C's ``labels as values'' extension.
 
 @sp 1
 @item @code{--asm-labels} (grades: asm_jump, asm_fast)
- at itemx @code{--no-asm-labels} (grades: debug, none, reg, jump, fast)
+ at itemx @code{--no-asm-labels} (grades: none, reg, jump, fast)
 Specify whether or not to use GNU C's asm extensions
 for inline assembler labels.
 
@@ -1573,39 +1596,33 @@
 is determined by the auto-configuration script.
 
 @sp 1
- at item @code{--have-delay-slot}
-(This option is not intended for general use.)
-Assume that branch instructions have a delay slot.
-
- at sp 1
- at item @code{--num-real-r-regs @var{n}}
-(This option is not intended for general use.)
-Assume r1 up to r at var{n} are real general purpose registers.
-
- at sp 1
- at item @code{--num-real-f-regs @var{n}}
-(This option is not intended for general use.)
-Assume f1 up to f at var{n} are real floating point registers.
-
- at sp 1
- at item @code{--num-real-r-temps @var{n}}
-(This option is not intended for general use.)
-Assume that @var{n} non-float temporaries will fit into real machine registers.
-
- at sp 1
- at item @code{--num-real-f-temps @var{n}}
-(This option is not intended for general use.)
-Assume that @var{n} float temporaries will fit into real machine registers.
-
- at sp 1
- at item @code{--profiling} (grades: any grade ending in @samp{.prof})
+ at item @code{--profiling} (grades: any grade containing @samp{.prof})
 Enable profiling.  Insert profiling hooks in the
 generated code, and also output some profiling
 information (the static call graph) to the file
 @samp{@var{module}.prof}.  @xref{Profiling}.
 
 @sp 1
- at item @code{--debug} (grades: debug)
+ at item @code{--profile-calls} (grades: any grade containing @samp{.profcalls})
+Similar to @samp{--profiling}, except that this option only gathers
+call counts, not timing information.  Useful on systems where time
+profiling is not supported (e.g. MS Windows).
+
+ at sp 1
+ at item @code{--profile-time} (grades: any grade containing @samp{.proftime})
+Similar to @samp{--profiling}, except that this option only gathers
+timing information, not call counts.  For the results to be useful,
+call counts for an identical run of your program need to be gathered
+using @samp{--profiling} or @samp{--profile-calls}. 
+The only advantage of using @samp{--profile-time} and @samp{--profile-calls}
+to gather timing information and call counts in seperate runs,
+rather than just using @samp{--profiling} to gather them both at once,
+is that the former method can give slightly more accurate timing results.
+because with the latter method the code inserted to record call counts
+has a small effect on the execution speed.
+
+ at sp 1
+ at item @code{--debug} (grades: any grade containing @samp{.debug})
 Enable debugging.
 Pass the @samp{-g} flag to the C compiler, instead of @samp{-DSPEED},
 to enable debugging of the generated C code. 
@@ -1626,8 +1643,8 @@
 With the @samp{compact} convention,
 the @var{n}th input argument is passed using register r at var{n}
 and the @var{n}th output argument is returned using register r at var{n}.
-The @samp{compact} convention generally leads to more efficient code.
-However, currently only the @samp{simple} convention is supported.
+The @samp{compact} convention, which is the default,
+generally leads to more efficient code.
 
 @sp 1
 @item @code{--no-type-layout}
@@ -1639,6 +1656,14 @@
 runtime. The C code also needs to be compiled with
 @samp{-DNO_TYPE_LAYOUT}.
 
+ at sp 1
+ at item @code{--pic-reg} (grades: any grade containing `.pic_reg')
+[For Unix with intel x86 architecture only.]
+Select a register usage convention that is compatible
+with position-independent code (gcc's `-fpic' option).
+This is necessary when using shared libraries on Intel x86 systems
+running Unix.  On other systems it has no effect.
+
 @end table
 
 @node Code generation options
@@ -1694,6 +1719,31 @@
 larger tables, but there will generally be less hash collisions,
 so it may result in faster lookups.
 
+ at sp 1
+ at item @code{--have-delay-slot}
+(This option is not intended for general use.)
+Assume that branch instructions have a delay slot.
+
+ at sp 1
+ at item @code{--num-real-r-regs @var{n}}
+(This option is not intended for general use.)
+Assume r1 up to r at var{n} are real general purpose registers.
+
+ at sp 1
+ at item @code{--num-real-f-regs @var{n}}
+(This option is not intended for general use.)
+Assume f1 up to f at var{n} are real floating point registers.
+
+ at sp 1
+ at item @code{--num-real-r-temps @var{n}}
+(This option is not intended for general use.)
+Assume that @var{n} non-float temporaries will fit into real machine registers.
+
+ at sp 1
+ at item @code{--num-real-f-temps @var{n}}
+(This option is not intended for general use.)
+Assume that @var{n} float temporaries will fit into real machine registers.
+
 @end table
 
 @node Optimization options
@@ -1701,10 +1751,11 @@
 
 @menu
 * Overall optimization options::
-* High-level (HLDS->HLDS) optimization options::
-* Medium-level (HLDS->LLDS) optimization options::
-* Low-level (LLDS->LLDS) optimization options::
-* Output-level (LLDS->C) optimization options::
+* High-level (HLDS -> HLDS) optimization options::
+* Medium-level (HLDS -> LLDS) optimization options::
+* Low-level (LLDS -> LLDS) optimization options::
+* Output-level (LLDS -> C) optimization options::
+* Object-level (C -> object code) optimization options::
 @end menu
 
 @node Overall optimization options
@@ -1771,8 +1822,8 @@
 
 @end table
 
- at node High-level (HLDS->HLDS) optimization options
- at subsection High-level (HLDS->HLDS) optimization options
+ at node High-level (HLDS -> HLDS) optimization options
+ at subsection High-level (HLDS -> HLDS) optimization options
 
 These optimizations are high-level transformations on our HLDS (high-level
 data structure).
@@ -1874,8 +1925,8 @@
 
 @end table
 
- at node Medium-level (HLDS->LLDS) optimization options
- at subsection Medium-level (HLDS->LLDS) optimization options
+ at node Medium-level (HLDS -> LLDS) optimization options
+ at subsection Medium-level (HLDS -> LLDS) optimization options
 
 These optimizations are applied during the process of generating
 low-level intermediate code from our high-level data structure.
@@ -1941,8 +1992,8 @@
 
 @end table
 
- at node Low-level (LLDS->LLDS) optimization options
- at subsection Low-level (LLDS->LLDS) optimization options
+ at node Low-level (LLDS -> LLDS) optimization options
+ at subsection Low-level (LLDS -> LLDS) optimization options
 
 These optimizations are transformations that are applied to our
 low-level intermediate code before emitting C code.
@@ -1979,9 +2030,9 @@
 @item --optimize-value-number
 Perform value numbering on extended basic blocks.
 
- at c @sp 1
- at c @item --pred-value-number
- at c Extend value numbering to whole procedures, rather than just basic blocks.
+ at sp 1
+ at item --pred-value-number
+Extend value numbering to whole procedures, rather than just basic blocks.
 
 @sp 1
 @item --no-optimize-frames
@@ -2001,8 +2052,8 @@
 
 @end table
 
- at node Output-level (LLDS->C) optimization options
- at subsection Output-level (LLDS->C) optimization options
+ at node Output-level (LLDS -> C) optimization options
+ at subsection Output-level (LLDS -> C) optimization options
 
 These optimizations are applied during the process of generating
 C intermediate code from our low-level data structure.
@@ -2027,9 +2078,28 @@
 which produces the most efficient code
 but tends to severely stress the C compiler.
 
- at sp 1
+ at end table
+
+ at node Object-level (C -> object code) optimization options
+ at subsection Object-level (C -> object code) optimization options
+
+These optimizations are applied during the process of compiling
+the generated C code to machine code object files.
+
+If you are using Mmake, you need to pass these options
+to @samp{mgnuc} rather than to @samp{mmc}.
+
+ at table @code
 @item --no-c-optimize
 Don't enable the C compiler's optimizations.
+
+ at sp 1
+ at item --inline-alloc
+Inline calls to @samp{GC_malloc()}.
+This can improve performance a fair bit,
+but may significantly increase code size.
+This option has no effect if @samp{--gc conservative}
+is not set or if the C compiler is not GNU C.
 
 @end table
 
Index: scripts/init_grade_options.sh-subr
===================================================================
RCS file: init_grade_options.sh-subr
diff -N init_grade_options.sh-subr
--- /dev/null	Wed Oct  8 22:02:19 1997
+++ init_grade_options.sh-subr	Wed Oct  8 19:03:42 1997
@@ -0,0 +1,31 @@
+#---------------------------------------------------------------------------#
+# Copyright (C) 1997 The University of Melbourne.
+# This file may only be copied under the terms of the GNU General
+# Public License - see the file COPYING in the Mercury distribution.
+#---------------------------------------------------------------------------#
+#
+# parse_grade_options.sh-subr:
+#	An `sh' subroutine for initializing grade-related options.
+#	Used by the `ml' and `mgnuc' scripts.
+#
+#	The code here should be inserted before a script's option-parsing
+#	loop.  The invoking script must define a DEFAULT_GRADE option.
+#
+#---------------------------------------------------------------------------#
+
+asm_labels=true
+non_local_gotos=true
+global_regs=true
+gc_method=conservative
+profile_time=false
+profile_calls=false
+use_trail=false
+args_method=compact
+debug=false
+
+case $# in
+	0) set - "--grade $DEFAULT_GRADE" ;;
+	0) set - "--grade $DEFAULT_GRADE" "$@" ;;
+esac
+
+#---------------------------------------------------------------------------#
Index: scripts/mgnuc.in
===================================================================
RCS file: /home/staff/zs/imp/mercury/scripts/mgnuc.in,v
retrieving revision 1.43
diff -u -r1.43 mgnuc.in
--- mgnuc.in	1997/08/28 16:04:10	1.43
+++ mgnuc.in	1997/10/08 11:14:14
@@ -13,19 +13,31 @@
 Name:	mgnuc - Mercury front-end to GNU C
 Usage:	mgnuc [<options>] [-- <gcc options>] files...
 Options:
-	-s <grade>, --grade <grade>
-		Select optimization/debug/gc options according to <grade>,
-		which must be one of debug, none, jump, asm_jump, reg, fast,
-		or asm_fast, or one of those with .gc and/or .prof appended.
 	-v, --verbose
 		Echo gcc command before executing it.
 	--no-ansi
 		Don't pass \`-ansi' to gcc.
 	--no-check
 		Don't enable any of gcc's warnings.
+	-s <grade>, --grade <grade>
+	--asm-labels
+	--gcc-non-local-gotos
+	--gcc-global-registers
+	-p, --profiling
+	--profile-calls
+	--profile-time
+	--debug
+	--use-trail
+	--args {simple, compact}
+	--pic-reg
+	--inline-alloc
+	--split-c-files
+		See the documentation in the \"Invocation\" section
+		of the Mercury User's Guide.
+		
 Description:
 	This runs gcc with the appropriate options for compiling Mercury
-	programs in the specified grade.
+	programs.
 	Normally it invokes gcc in ANSI mode with almost all warnings enabled,
 	but this can be changed using the \`--no-ansi' or \`--no-check'
 	options.
@@ -35,7 +47,7 @@
 
 # *************************************************************************
 # *** IMPORTANT NOTE: any changes to this file may also require similar ***
-# *** changes to compiler/mercury_compile.pp                            ***
+# *** changes to compiler/mercury_compile.m                             ***
 # *************************************************************************
 
 FULLARCH=@FULLARCH@
@@ -47,8 +59,6 @@
 CFLAGS_FOR_GOTOS="@CFLAGS_FOR_GOTOS@"
 AS=as
 
-ARG_OPTS=-DCOMPACT_ARGS
-
 case "$CC" in
     *gcc*)
 	ANSI_OPTS="-ansi"
@@ -68,70 +78,80 @@
 # -Wenum-clash 		is for C++ only
 # -Wunused		causes various spurious warnings
 
-	OPT_OPTS="-O2 -fomit-frame-pointer -DSPEED"
+	OPT_OPTS="-O2 -fomit-frame-pointer"
 	COMPILER=gcc
 	;;
     *lcc*)
 	ANSI_OPTS=
 	CHECK_OPTS=
-	OPT_OPTS="-DSPEED"
+	OPT_OPTS=""
 	COMPILER=lcc
 	;;
     *)
 	ANSI_OPTS=
 	CHECK_OPTS=
-	OPT_OPTS="-O -DSPEED"
+	OPT_OPTS="-O"
 	COMPILER=unknown
 	;;
 esac
 
-DEBUG_OPTS="-g"
 AS_OPTS=""
 SPLIT_OPTS=""
+INLINE_ALLOC_OPTS=""
 
-grade=$DEFAULT_GRADE
 verbose=false
 assemble=false
 
+# include the file `init_grade_options.sh-subr'
+ at INIT_GRADE_OPTIONS@
+
 while : ; do
     case "$1" in
 	-h|--help|"-?")
 		echo "$Help"
 		exit 0
 		;;
+
+	-v|--verbose)
+		verbose=true
+		;;
+	-v-|--no-verbose)
+		verbose=false
+		;;
+
 	--assemble)
 		assemble=true
-		shift
 		;;
+
 	--no-ansi)
 		ANSI_OPTS=
-		shift
 		;;
+
 	--no-check)
 		CHECK_OPTS=
-		shift
 		;;
+
 	--split-c-files)
 		SPLIT_OPTS=-DSPLIT_C_FILES
-		shift
 		;;
 	--no-split-c-files)
 		SPLIT_OPTS=
-		shift
 		;;
-	-v|--verbose)
-		verbose=true
-		shift
+
+	--inline-alloc)
+		INLINE_ALLOC_OPTS="-DINLINE_ALLOC -DSILENT"
 		;;
-	-s|--grade)
-		shift
-		grade="$1";
-		shift
+	--no-inline-alloc)
+		INLINE_ALLOC_OPTS=""
 		;;
-	-s*)
-		grade="` expr $1 : '-s\(.*\)' `"
-		shift
+
+	--no-c-optimize)
+		OPT_OPTS=""
 		;;
+
+	# include the file `parse_grade_options.sh-subr'
+	@PARSE_GRADE_OPTIONS@
+
 	--)
 		shift
 		break
@@ -140,98 +160,91 @@
 		break
 		;;
     esac
+    shift
 done
 
-case "$grade" in
-	*.tr)	TRAIL_OPTS="-DMR_USE_TRAIL"
-		grade="` expr $grade : '\(.*\).tr' `"
-		;;
-	*)
-		TRAIL_OPTS=""
-		;;
+#
+# convert mgnuc options into gcc options
+#
+# IMPORTANT: any changes here will require similar changes to
+# compiler/mercury_compile.m.
+#
+
+case $asm_labels in
+	true)		ASM_OPTS="-DUSE_ASM_LABELS" ;;
+	false)		ASM_OPTS="" ;;
 esac
 
-case "$grade" in
-	*.prof)	PROF_OPTS="-DPROFILE_TIME -DPROFILE_CALLS"
-		grade="` expr $grade : '\(.*\).prof' `"
-		;;
-	*)
-		PROF_OPTS="-DNO_SIGNALS"
-		;;
+case $non_local_gotos in
+	true)		GOTO_OPTS="-DUSE_GCC_NONLOCAL_GOTOS" ;;
+	false)		GOTO_OPTS="" ;;
 esac
 
-case "$grade" in
-	*.agc)	GC_OPTS="-DNATIVE_GC"
-		grade="` expr $grade : '\(.*\).agc' `"
-		;;
-	*.gc)	GC_OPTS="-DCONSERVATIVE_GC"
-		grade="` expr $grade : '\(.*\).gc' `"
-		;;
-	*)
-		GC_OPTS=""
-		;;
+case $global_regs in
+	true)		REG_OPTS="-DUSE_GCC_GLOBAL_REGISTERS" ;;
+	false)		REG_OPTS="" ;;
 esac
 
-case "$grade" in
-	asm_fast)
-		GRADE_OPTS="$OPT_OPTS -DUSE_GCC_GLOBAL_REGISTERS
-				-DUSE_ASM_LABELS -DUSE_GCC_NONLOCAL_GOTOS"
-		;;
-	fast)
-		GRADE_OPTS="$OPT_OPTS
-			-DUSE_GCC_GLOBAL_REGISTERS -DUSE_GCC_NONLOCAL_GOTOS"
-		;;
-	reg)
-		GRADE_OPTS="$OPT_OPTS
-			-DUSE_GCC_GLOBAL_REGISTERS"
-		;;
-	asm_jump)
-		GRADE_OPTS="$OPT_OPTS
-			-DUSE_ASM_LABELS -DUSE_GCC_NONLOCAL_GOTOS"
-		;;
-	jump)
-		GRADE_OPTS="$OPT_OPTS
-			-DUSE_GCC_NONLOCAL_GOTOS"
-		;;
-	none)
-		GRADE_OPTS="$OPT_OPTS"
-		;;
-	init)
-		echo "$0: the \`-s init' option is no longer supported" 1>&2
-		exit 1
-		;;
-	debug)
-		GRADE_OPTS="$DEBUG_OPTS"
-		;;
-	*)
-		echo "$0: invalid grade \`$grade'" 1>&2;
-		exit 1
+case $debug in
+	true)		DEBUG_OPTS="-g" ;;
+	false)		DEBUG_OPTS="$OPT_OPTS -DSPEED" ;;
 esac
 
+case $gc_method in
+	accurate)	GC_OPTS="-DNATIVE_GC" ;;
+	conservative)	GC_OPTS="-DCONSERVATIVE_GC" ;;
+	none)		GC_OPTS="" ;;
+esac
+
+case $profile_time in
+	true)		PROF_TIME_OPTS="-DPROFILE_TIME" ;;
+	false)		PROF_TIME_OPTS="-DNO_SIGNALS" ;;
+esac
+
+case $profile_calls in
+	true)		PROF_CALLS_OPTS="-DPROFILE_CALLS" ;;
+	false)		PROF_CALLS_OPTS="" ;;
+esac
+
+case $use_trail in
+	true)		TRAIL_OPTS="-DMR_USE_TRAIL" ;;
+	false)		TRAIL_OPTS="" ;;
+esac
+
+case $args_method in
+	simple)		ARG_OPTS="" ;;
+	compact)	ARG_OPTS="-DCOMPACT_ARGS" ;;
+esac
+
+case $pic_reg in
+	true)		PICREG_OPTS="-DPIC_REG" ;;
+	false)		PICREG_OPTS="" ;;
+esac
+
+
 # check that special grades are only used with gcc
 case $COMPILER in
 	gcc)	;;
-	*)	case $grade in
-			debug|none)	;;
-			*)
+	*)	case "$GRADE_OPTS" in
+			*USE_GCC*)
 		echo "$0: For compilers other than GNU C, the only" 1>&2
 		echo "$0: grades allowed are \`debug' and \`none'" 1>&2
 					;;
 		esac
 esac
 
+GRADE_OPTS="$DEBUG_OPTS $ASM_OPTS $GOTO_OPTS $REG_OPTS"
+
 # if we're using global registers, add CFLAGS_FOR_REGS
-case "$GRADE_OPTS" in
-	*-DUSE_GCC_GLOBAL_REGISTERS*)
-		GRADE_OPTS="$GRADE_OPTS $CFLAGS_FOR_REGS"
-		;;
+case $global_regs in
+	true)	GRADE_OPTS="$GRADE_OPTS $CFLAGS_FOR_REGS" ;;
+	false)	;;
 esac
 
 # if we're using non-local gotos, add CFLAGS_FOR_GOTOS
-case "$GRADE_OPTS" in
-	*-DUSE_GCC_NONLOCAL_GOTOS*)
-		GRADE_OPTS="$GRADE_OPTS $CFLAGS_FOR_GOTOS"
-		;;
+case $non_local_gotos in
+	true)	GRADE_OPTS="$GRADE_OPTS $CFLAGS_FOR_GOTOS" ;;
+	false)	;;
 esac
 
 #
@@ -245,8 +258,8 @@
 		# nonlocal gotos don't work with PIC, which is the
 		# default for Irix 5, so if nonlocal gotos are enabled
 		# we need to disable the use of shared libraries.
-		case "$GRADE_OPTS" in
-			*-DUSE_GCC_NONLOCAL_GOTOS*)
+		case $non_local_gotos in
+			true)
 LIBRARY_PATH="$NONSHARED_LIB_DIR:/usr/lib/nonshared:$LIBRARY_PATH"
 				export LIBRARY_PATH
 				AS_OPTS="-non_shared"
@@ -325,14 +338,17 @@
 
 case $verbose in true)
 	echo $CC -I$C_INCL_DIR $ANSI_OPTS $CHECK_OPTS \
-		$GRADE_OPTS $GC_OPTS $PROF_OPTS $TRAIL_OPTS $SPLIT_OPTS \
-		$ARCH_OPTS $ARG_OPTS "$@" $OVERRIDE_OPTS ;;
+		$GRADE_OPTS $GC_OPTS $PROF_TIME_OPTS $PROF_CALLS_OPTS \
+		$INLINE_ALLOC_OPTS $TRAIL_OPTS $SPLIT_OPTS \
+		$PICREG_OPTS $ARCH_OPTS $ARG_OPTS "$@" $OVERRIDE_OPTS ;;
 esac
 case $# in
 	0) exec $CC -I$C_INCL_DIR $ANSI_OPTS $CHECK_OPTS \
-		$GRADE_OPTS $GC_OPTS $PROF_OPTS $TRAIL_OPTS $SPLIT_OPTS \
-		$ARCH_OPTS $OVERRIDE_OPTS ;;
+		$GRADE_OPTS $GC_OPTS $PROF_TIME_OPTS $PROF_CALLS_OPTS \
+		$INLINE_ALLOC_OPTS $TRAIL_OPTS $SPLIT_OPTS \
+		$PICREG_OPTS $ARCH_OPTS $OVERRIDE_OPTS ;;
 	*) exec $CC -I$C_INCL_DIR $ANSI_OPTS $CHECK_OPTS \
-		$GRADE_OPTS $GC_OPTS $PROF_OPTS $TRAIL_OPTS $SPLIT_OPTS \
-		$ARCH_OPTS $ARG_OPTS "$@" $OVERRIDE_OPTS ;;
+		$GRADE_OPTS $GC_OPTS $PROF_TIME_OPTS $PROF_CALLS_OPTS \
+		$INLINE_ALLOC_OPTS $TRAIL_OPTS $SPLIT_OPTS \
+		$PICREG_OPTS $ARCH_OPTS $ARG_OPTS "$@" $OVERRIDE_OPTS ;;
 esac
Index: scripts/ml.in
===================================================================
RCS file: /home/staff/zs/imp/mercury/scripts/ml.in,v
retrieving revision 1.33
diff -u -r1.33 ml.in
--- ml.in	1997/10/07 17:50:53	1.33
+++ ml.in	1997/10/08 08:57:22
@@ -49,8 +49,18 @@
 	-g, --no-strip
 		Do not strip debugging information.
 	-s <grade>, --grade <grade>
-		Specify which grade of the Mercury library to link with.
-		(The default grade is determined by ``configure'.)"
+	--asm-labels
+	--gcc-non-local-gotos
+	--gcc-global-registers
+	-p, --profiling
+	--profile-calls
+	--profile-time
+	--debug
+	--use-trail
+	--args {simple, compact}
+	--pic-reg
+		See the documentation in the \"Invocation\" section
+		of the Mercury User's Guide."
 
 FULLARCH=@FULLARCH@
 NONSHARED_LIB_DIR=${MERCURY_NONSHARED_LIB_DIR=@NONSHARED_LIB_DIR@}
@@ -81,12 +91,14 @@
 esac
 mercury_libs=default
 demangle=true
-GRADE=$DEFAULT_GRADE
 MAYBE_STATIC_OPT=""
 make_shared_lib=false
 user_shlib_dirs=""
 
-while true; do
+# include the file `init_grade_options.sh-subr'
+ at INIT_GRADE_OPTIONS@
+
+while : ; do
     case "$1" in
 	-h|--help|"-?")
 		echo "$Help"
@@ -94,29 +106,25 @@
 		;;
 	-v|--verbose)
 		verbose=true
-		shift ;;
+		;;
 	--demangle)
 		demangle=true
-		shift ;;
+		;;
 	--no-demangle)
 		demangle=false
-		shift ;;
-	-s|--grade)
-		shift
-		GRADE="$1"
-		shift ;;
+		;;
 	--strip)
 		strip=true
-		shift ;;
+		;;
 	-g|--no-strip)
 		strip=false
-		shift ;;
+		;;
 	--make-shared-lib)
 		make_shared_lib=true
 		# on some targets, stripping shared libraries will
 		# make them unusable, I think, so don't strip
 		strip=false
-		shift ;;
+		;;
 	--no-libs)
 		progname=`basename $0`
 		cat 1>&2 << EOF
@@ -125,12 +133,12 @@
 $progname:   Support for \`--no-libs' may be removed in a future release.
 EOF
 		mercury_libs=none
-		shift ;;
+		;;
 	--mercury-libs)
 		case "$2" in
 			shared|static|none|default)
 				mercury_libs="$2"
-				shift; shift ;;
+				shift ;;
 			*)
 				progname=`basename $0`
 				cat 1>&2 << EOF
@@ -147,7 +155,6 @@
 		case $mercury_libs in static|default)
 			mercury_libs=shared ;;
 		esac
-		shift
 		;;
 	-static|--static)
 		case $FULLARCH in
@@ -167,27 +174,27 @@
 		case $mercury_libs in shared|default)
 			mercury_libs=static ;;
 		esac
-		shift
 		;;
 	-R|--shared-lib-dir)
 		dir="$2"
 		user_shlib_dirs="$user_shlib_dirs $dir"
-		shift; shift
+		shift
 		;;
 	-R*)
 		dir="` expr $1 : '-R\(.*\)' `"
 		user_shlib_dirs="$user_shlib_dirs $dir"
-		shift
 		;;
+
+	# include the file `parse_grade_options.sh-subr'
+	@PARSE_GRADE_OPTIONS@
+
 	--)
 		shift
 		break ;;
-	-s*)
-		GRADE="` expr $1 : '-s\(.*\)' `"
-		shift ;;
 	*)
 		break ;;
     esac
+    shift
 done
 
 case $mercury_libs in default)
@@ -204,6 +211,43 @@
 	;;
 esac
 
+#
+# compute the grade from the options settings
+#
+
+case $non_local_gotos,$global_regs in
+	true,true) 	GRADE="fast" ;;
+	true,false)  	GRADE="jump" ;;
+	false,true)  	GRADE="reg" ;;
+	false,false)   	GRADE="none" ;;
+esac
+case $asm_labels in
+	true)		GRADE="asm_$GRADE" ;;
+	false)		;;
+esac
+case $gc_method in
+	conservative)	GRADE="$GRADE.gc" ;;
+	accurate)	GRADE="$GRADE.agc" ;;
+esac
+case $profile_time,$profile_calls in
+	true,true)	GRADE="$GRADE.prof" ;;
+	true,false)	GRADE="$GRADE.proftime" ;;
+	false,true)	GRADE="$GRADE.profcalls" ;;
+	false,false)	;;
+esac
+case $use_trail in
+	true)		GRADE="$GRADE.tr" ;;
+	false)		;;
+esac
+case $args_method in
+	simple)		GRADE="$GRADE.sa" ;;
+	compact)	;;
+esac
+case $debug in
+	true)		GRADE="$GRADE.debug" ;;
+	false)		;;
+esac
+
 case "$GRADE" in
 	*.gc.prof*)
 		LIBGC="-lgc_prof"
@@ -286,8 +330,8 @@
 # On Irix 5, grades `fast' and `jump' only work in non_shared mode.
 case $FULLARCH in
     *-sgi-irix5*)
-	case "$GRADE" in
-	    *fast*|*jump*)
+	case $non_local_gotos in
+	    true)
 		ARCH_OPTS=-non_shared
 		NONSHARED_PATH="$NONSHARED_LIB_DIR:/usr/lib/nonshared"
 		LIBRARY_PATH="$NONSHARED_PATH:$LIBRARY_PATH"
@@ -303,6 +347,7 @@
 
 case $verbose in
     true)
+	echo "ml: using grade \`$GRADE'"
 	case $demangle in
 	    false)
 		echo $LINKER $STRIP_OPTS $MAYBE_STATIC_OPT $ARCH_OPTS \
Index: scripts/parse_grade_options.sh-subr
===================================================================
RCS file: parse_grade_options.sh-subr
diff -N parse_grade_options.sh-subr
--- /dev/null	Wed Oct  8 22:02:19 1997
+++ parse_grade_options.sh-subr	Wed Oct  8 18:43:11 1997
@@ -0,0 +1,208 @@
+#---------------------------------------------------------------------------#
+# Copyright (C) 1997 The University of Melbourne.
+# This file may only be copied under the terms of the GNU General
+# Public License - see the file COPYING in the Mercury distribution.
+#---------------------------------------------------------------------------#
+#
+# parse_grade_options.sh-subr:
+#	An `sh' subroutine for parsing grade-related options.
+#	Used by the `ml' and `mgnuc' scripts.
+#
+#	The code here should be inserted in the case statement in a scripts
+#	option-parsing loop.
+#
+#---------------------------------------------------------------------------#
+
+	--asm-labels)
+		asm_labels=true ;;
+	--no-asm-labels)
+		asm_labels=false ;;
+
+	--gcc-non-local-gotos)
+		non_local_gotos=true ;;
+	--no-gcc-non-local-gotos)
+		non_local_gotos=false ;;
+
+	--gcc-global-registers)
+		global_regs=true ;;
+	--no-gcc-global-registers)
+		global_regs=false ;;
+
+	--debug)
+		debug=true ;;
+	--no-debug)
+		debug=false ;;
+
+	--gc)
+		shift
+		case "$1" in
+			accurate|conservative|none)
+				gc_method=$1 ;;
+			*)
+				echo "$0: invalid gc method \`$1'" 1>&2
+				exit 1
+				;;
+		esac
+		;;
+
+	-p|--profiling)
+		profile_time=true
+		profile_calls=true
+		;;
+	-p-|--no-profiling)
+		profile_time=false
+		profile_calls=false
+		;;
+	--profile-time)
+		profile_time=true ;;
+	--no-profile-time)
+		profile_time=false ;;
+	--profile-calls)
+		profile_calls=true ;;
+	--no-profile-calls)
+		profile_calls=false ;;
+
+	--use-trail)
+		use_trail=true ;;
+	--no-use-trail)
+		use_trail=false ;;
+
+	--args)
+		shift
+		case "$1" in
+			simple|compact)
+				args_method=$1;;
+			*)
+				echo "$0: invalid arg method \`$1'" 1>&2
+				exit 1
+				;;
+		esac
+		;;
+
+	--pic-reg)
+		pic_reg=true ;;
+	--no-pic-reg)
+		pic_reg=false ;;
+
+	-s|--grade)
+		shift
+		grade="$1";
+
+		# Convert a grade to a set of options.
+		#
+		# IMPORTANT: any changes to the handling of grades here
+		# may also require changes to
+		#	runtime/mercury_grade.h
+		#	compiler/handle_options.m
+		#	scripts/ml.in
+
+		case "$grade" in
+			*.debug)
+				debug=true
+				grade="` expr $grade : '\(.*\).debug' `"
+				;;
+			*)	debug=false
+				;;
+		esac
+
+		case "$grade" in
+			*.sa)
+				args_method=simple
+				grade="` expr $grade : '\(.*\).sa' `"
+				;;
+			*)	args_method=compact
+				;;
+		esac
+
+		case "$grade" in
+			*.tr)	use_trail=true
+				grade="` expr $grade : '\(.*\).tr' `"
+				;;
+			*)	use_trail=false
+				;;
+		esac
+
+		case "$grade" in
+			*.prof)
+				profile_time=true
+				profile_calls=true
+				grade="` expr $grade : '\(.*\).prof' `"
+				;;
+			*.proftime)	
+				profile_time=true
+				profile_calls=false
+				grade="` expr $grade : '\(.*\).proftime' `"
+				;;
+			*.profcalls)	
+				profile_time=false
+				profile_calls=true
+				grade="` expr $grade : '\(.*\).profcalls' `"
+				;;
+			*)
+				profile_time=false
+				profile_calls=false
+				;;
+		esac
+
+		case "$grade" in
+			*.agc)	gc_method=accurate
+				grade="` expr $grade : '\(.*\).agc' `"
+				;;
+			*.gc)	gc_method=conservative
+				grade="` expr $grade : '\(.*\).gc' `"
+				;;
+			*)	gc_method=none
+				;;
+		esac
+
+		case "$grade" in
+			asm_fast)
+				global_regs=true
+				non_local_gotos=true
+				asm_labels=true
+				;;
+			fast)
+				global_regs=true
+				non_local_gotos=true
+				asm_labels=false
+				;;
+			reg)
+				global_regs=true
+				non_local_gotos=false
+				asm_labels=false
+				;;
+			asm_jump)
+				global_regs=false
+				non_local_gotos=true
+				asm_labels=true
+				;;
+			jump)
+				global_regs=false
+				asm_labels=false
+				non_local_gotos=true
+				;;
+			none)
+				global_regs=false
+				asm_labels=false
+				non_local_gotos=false
+				;;
+			debug)
+				debug=true
+				global_regs=false
+				asm_labels=false
+				non_local_gotos=false
+				;;
+			*)
+				echo "$0: invalid grade \`$grade'" 1>&2;
+				exit 1
+				;;
+		esac
+		;;
+	-s*)
+		grade="` expr $1 : '-s\(.*\)' `"
+		# just insert it as `--grade $grade' and then reparse it
+		case $# in
+			0) set - "x --grade $grade" ;;
+			0) set - "x --grade $grade" "$@" ;;
+		esac
+		;;

--
Fergus Henderson <fjh at cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3         |     -- the last words of T. S. Garp.



More information about the developers mailing list