diff: fix fact_table inlining bug

Fergus Henderson fjh at cs.mu.OZ.AU
Tue Feb 9 09:17:33 AEDT 1999


Estimated hours taken: 1.5

Fix a bug where inlining of fact tables caused duplicate
labels in the generated C code.

compiler/make_hlds.m:
	Make `pragma fact_table' imply `pragma no_inline'.

compiler/fact_table.m:
	Update some old comments which said that nondet `pragma c_code'
	was not yet implemented.

doc/reference_manual.texi:
	Document that `pragma c_code' should not contain labels
	unless there is a matching `pragma no_inline'.

Index: compiler/fact_table.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/fact_table.m,v
retrieving revision 1.22
diff -u -r1.22 fact_table.m
--- fact_table.m	1998/11/20 04:07:38	1.22
+++ fact_table.m	1999/02/08 20:43:00
@@ -67,15 +67,15 @@
 	% C_ProcCode is the C code for the procedure,
 	% C_ExtraCode is extra C code that should be included in the module
 	%
-	% XXX   model_non pragma c is not completely supported by the compiler
-	% at the moment -- the programmer has no control over how the nondet
-	% stack frames are set up (e.g. how many framevars are used) or how
-	% many labels are declared.  To get around this, the C_ProcCode
+	% XXX   model_non pragma c was not supported by the compiler
+	% when this code was written.  To get around this, the C_ProcCode
 	% generated for model_non code pops off the stack frame that is
 	% automatically created by the compiler and jumps to the code contained
 	% in C_ExtraCode.  C_ExtraCode declares the required labels and creates
 	% a new stack frame with the required number of framevars.  It then 
 	% does all the work required to lookup the fact table.
+	% This should really be rewritten to work using model_non pragma c
+	% now that model_non pragma c is implemented.
 :- pred fact_table_generate_c_code(sym_name, list(pragma_var), proc_id,
 		proc_id, proc_info, list(type), module_info, string, string,
 		io__state, io__state).
@@ -2510,8 +2510,7 @@
 
 %---------------------------------------------------------------------------%
 
-	% XXX this should change to use the new model_non pragma c_code when
-	% it has been implemented.
+	% XXX this should be changed to use the new model_non pragma c_code
 :- pred generate_multidet_code(string, list(pragma_var), proc_id, 
 		list(type), args_method, module_info, int, string, string).
 :- mode generate_multidet_code(in, in, in, in, in, in, in, out, out) is det.
Index: compiler/make_hlds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/make_hlds.m,v
retrieving revision 1.280
diff -u -r1.280 make_hlds.m
--- make_hlds.m	1998/12/16 17:24:16	1.280
+++ make_hlds.m	1999/02/08 20:35:03
@@ -5099,10 +5099,19 @@
 	{
 		C_ExtraCode = ""
 	->
-		Module = Module1
+		Module2 = Module1
 	;
-		module_add_c_body_code(C_ExtraCode, Context, Module1, Module)
-	}.
+		module_add_c_body_code(C_ExtraCode, Context, Module1, Module2)
+	},
+	%
+	% The C code for fact tables includes C labels;
+	% we cannot inline this code, because if we try,
+	% the result may be duplicate labels in the generated code.
+	% So we must disable inlining for fact_table procedures.
+	%
+	add_pred_marker(Module2, "fact_table", SymName, Arity,
+		Status, Context, no_inline, [], Module).
+
 
 	% Create a list(pragma_var) that looks like the ones that are created
 	% for pragma c_code in prog_io.m.
Index: doc/reference_manual.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/reference_manual.texi,v
retrieving revision 1.119
diff -u -r1.119 reference_manual.texi
--- reference_manual.texi	1999/02/05 06:48:33	1.119
+++ reference_manual.texi	1999/02/08 20:48:15
@@ -3360,12 +3360,15 @@
 @xref{Passing data to and from C}.
 
 The C code fragment may declare local variables, but it should not
-declare any static variables unless there is also a Mercury
+declare any labels or static variables unless there is also a Mercury
 @samp{pragma no_inline} declaration (@pxref{Inlining}) for the procedure.
 The reason for this is that otherwise the Mercury implementation may
-inline the procedure by duplicating the C code fragment for each call,
-which would result in the program having multiple instances of the
-static variable, rather than a single shared instance.
+inline the procedure by duplicating the C code fragment for each call.
+If the C code fragment declared a static variable, inlining it in this
+way could result in the program having multiple instances of the static
+variable, rather than a single shared instance.  If the C code fragment
+declared a label, inlining it in this way could result in an error due
+to the same label being defined twice inside a single C function.
 
 If there is a @code{pragma import} or @code{pragma c_code} declaration for a
 mode of a predicate or function, then there must not be any clauses for that

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "Binaries may die
WWW: <http://www.cs.mu.oz.au/~fjh>  |   but source code lives forever"
PGP: finger fjh at 128.250.37.3        |     -- leaked Microsoft memo.



More information about the developers mailing list