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