[m-dev.] diff: MLDS back-end bug fixes
Fergus Henderson
fjh at cs.mu.OZ.AU
Fri May 12 07:09:48 AEST 2000
Estimated hours taken: 12
Fix several bugs in the MLDS back-end:
- a bug in tail recursion optimization
- a bug that lead to duplicate field names in environment structs
- a few miscellaneous fixes for runtime/mercury.{h,c}.
compiler/mlds_to_c.m:
Fix a bug with tail recursion optimization:
for the tail recursive call `p(H1, H2) :- ... p(H2, H1) ...',
it was generating code of the form
void p(MR_Word H1, MR_Word H2) {
for(;;) {
...
{
H1 = H2;
H2 = H1;
continue;
}
...
}
}
which clobbered the value of H1. The fix was to change
it to generate code which assigns the new arguments to
temporary local variables before assigning them to the
headvars:
void p(MR_Word H1, MR_Word H2) {
for(;;) {
...
{
MR_Word H1__tmp_copy = H2;
MR_Word H2__tmp_copy = H1;
H1 = H1__tmp_copy;
H2 = H2__tmp_copy;
continue;
...
}
}
compiler/ml_code_util.m:
Add a new function ml_gen_mlds_var_decl/4, for use by
mlds_to_c.m for the tempoaries it now generates when handling
tail recursion.
compiler/ml_call_gen.m:
Ensure that the temporary conversion variables generated by
ml_gen_box_or_unbox_lval all have distinct names, by including
a sequence number in the name. This is needed because
ml_elim_nested.m assumes that all variables defined in a
function have different names; if two variables are defined in
different scopes with the same name, then when ml_elim_nested
hoists them out, this leads to a duplicate field name in the
environment struct.
compiler/ml_code_util.m:
Add a new counter field to the ml_gen_info and a new predicate
ml_gen_info_new_conv_var for accessing it, for use by
ml_gen_box_or_unbox_lval in ml_call_gen.m.
runtime/mercury.c:
Add definitions for some functions declared `extern inline'
in runtime/mercury_heap.h.
runtime/mercury.h:
- Delete some unnecessary `#ifdef ... #define ... #endif' guards;
everything in this file is already protected by the
`#ifndef MERCURY_H' guard at the top of the file.
- Increase the fixed limit here on the arity of types from 5 to 10,
since some files in the compiler directory use higher-order
types with arities greater than 5.
- Add a macro version of MR_box_float(), using gcc's `({...})'
extension.
Workspace: /home/pgrad/fjh/ws/hg
Index: compiler/ml_call_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_call_gen.m,v
retrieving revision 1.8
diff -u -d -r1.8 ml_call_gen.m
--- compiler/ml_call_gen.m 2000/05/10 18:06:51 1.8
+++ compiler/ml_call_gen.m 2000/05/11 04:45:08
@@ -564,7 +564,9 @@
%
% generate a declaration for the fresh variable
- { ArgVarName = string__append("conv_", VarName) },
+ ml_gen_info_new_conv_var(ConvVarNum),
+ { string__format("conv%d_%s", [i(ConvVarNum), s(VarName)],
+ ArgVarName) },
{ ArgVarDecl = ml_gen_var_decl(ArgVarName, CalleeType,
mlds__make_context(Context)) },
{ ConvDecls = [ArgVarDecl] },
Index: compiler/ml_code_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_code_util.m,v
retrieving revision 1.10
diff -u -d -r1.10 ml_code_util.m
--- compiler/ml_code_util.m 2000/05/10 18:06:52 1.10
+++ compiler/ml_code_util.m 2000/05/11 18:52:19
@@ -197,6 +197,12 @@
:- func ml_gen_mlds_var_decl(mlds__data_name, mlds__type, mlds__context) =
mlds__defn.
+ % Generate a declaration for an MLDS variable, given its MLDS type
+ % and initializer.
+ %
+:- func ml_gen_mlds_var_decl(mlds__data_name, mlds__type, mlds__initializer,
+ mlds__context) = mlds__defn.
+
%-----------------------------------------------------------------------------%
%
% Routines for handling success and failure
@@ -412,6 +418,16 @@
ml_gen_info, ml_gen_info).
:- mode ml_gen_info_new_cond_var(out, in, out) is det.
+ % Generate a new `conv' variable number.
+ % This is used to give unique names to the local
+ % variables generated by ml_gen_box_or_unbox_lval,
+ % which are used to handle boxing/unboxing
+ % argument conversions.
+:- type conv_seq == int.
+:- pred ml_gen_info_new_conv_var(conv_seq,
+ ml_gen_info, ml_gen_info).
+:- mode ml_gen_info_new_conv_var(out, in, out) is det.
+
%
% A success continuation specifies the (rval for the variable
% holding the address of the) function that a nondet procedure
@@ -1000,9 +1016,16 @@
% Generate a declaration for an MLDS variable, given its MLDS type.
%
-ml_gen_mlds_var_decl(DataName, MLDS_Type, Context) = MLDS_Defn :-
+ml_gen_mlds_var_decl(DataName, MLDS_Type, Context) =
+ ml_gen_mlds_var_decl(DataName, MLDS_Type, no_initializer, Context).
+
+
+ % Generate a declaration for an MLDS variable, given its MLDS type
+ % and initializer.
+ %
+ml_gen_mlds_var_decl(DataName, MLDS_Type, Initializer, Context) = MLDS_Defn :-
Name = data(DataName),
- Defn = data(MLDS_Type, no_initializer),
+ Defn = data(MLDS_Type, Initializer),
DeclFlags = ml_gen_var_decl_flags,
MLDS_Defn = mlds__defn(Name, Context, DeclFlags, Defn).
@@ -1241,6 +1264,7 @@
func_label :: mlds__func_sequence_num,
commit_label :: commit_sequence_num,
cond_var :: cond_seq,
+ conv_var :: conv_seq,
success_cont_stack :: stack(success_cont),
% definitions of functions or global
% constants which should be inserted
@@ -1260,7 +1284,8 @@
VarTypes),
FuncLabelCounter = 0,
CommitLabelCounter = 0,
- SucceededVarCounter = 0,
+ CondVarCounter = 0,
+ ConvVarCounter = 0,
stack__init(SuccContStack),
ExtraDefns = [],
MLDSGenInfo = ml_gen_info(
@@ -1272,7 +1297,8 @@
OutputVars,
FuncLabelCounter,
CommitLabelCounter,
- SucceededVarCounter,
+ CondVarCounter,
+ ConvVarCounter,
SuccContStack,
ExtraDefns
).
@@ -1308,6 +1334,9 @@
ml_gen_info_new_cond_var(CondVar, Info, Info^cond_var := CondVar) :-
CondVar = Info^cond_var + 1.
+
+ml_gen_info_new_conv_var(ConvVar, Info, Info^conv_var := ConvVar) :-
+ ConvVar = Info^conv_var + 1.
ml_gen_info_push_success_cont(SuccCont, Info,
Info^success_cont_stack :=
Index: compiler/mlds_to_c.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_c.m,v
retrieving revision 1.30
diff -u -d -r1.30 mlds_to_c.m
--- compiler/mlds_to_c.m 2000/05/10 18:06:55 1.30
+++ compiler/mlds_to_c.m 2000/05/11 21:01:51
@@ -36,7 +36,9 @@
% llds_out__make_base_typeclass_info_name.
:- import_module rtti. % for rtti__addr_to_string.
:- import_module rtti_to_mlds. % for mlds_rtti_type_name.
-:- import_module hlds_pred. % for `pred_proc_id'.
+:- import_module hlds_pred. % for pred_proc_id.
+:- import_module ml_code_util. % for ml_gen_mlds_var_decl, which is used by
+ % the code that handles tail recursion.
:- import_module globals, options, passes_aux.
:- import_module builtin_ops, c_util, modules.
:- import_module prog_data, prog_out.
@@ -1350,24 +1352,54 @@
{ error("mlds_output_assign_args: length mismatch") }.
mlds_output_assign_args(_, _, _, [], []) --> [].
mlds_output_assign_args(Indent, ModuleName, Context,
- [Name - _Type | Rest], [Arg | Args]) -->
+ [Name - Type | Rest], [Arg | Args]) -->
+ %
+ % extract the variable name
+ %
+ { Name = data(var(VarName1)) ->
+ VarName = VarName1
+ ;
+ error("mlds_output_assign_args: arg is not a variable!")
+ },
(
%
% don't bother assigning a variable to itself
%
- { Name = data(var(VarName)) },
- { QualVarName = qual(ModuleName, VarName) },
- { Arg = lval(var(QualVarName)) }
+ { Arg = lval(var(qual(ModuleName, VarName))) }
->
- []
+ mlds_output_assign_args(Indent, ModuleName, Context, Rest, Args)
;
+ % Declare a temporary variable, initialized it to the arg,
+ % recursively process the remaining args,
+ % and then assign the temporary to the parameter:
+ %
+ % SomeType argN__tmp_copy = new_argN_value;
+ % ...
+ % new_argN_value = argN_tmp_copy;
+ %
+ % The temporaries are needed for the case where
+ % we are e.g. assigning v1, v2 to v2, v1;
+ % they ensure that we don't try to reference the old value of
+ % a parameter after it has already been clobbered by the
+ % new value.
+
+ { string__append(VarName, "__tmp_copy", TempName) },
+ { QualTempName = qual(ModuleName, data(var(TempName))) },
+ { Initializer = init_obj(Arg) },
+ { TempDefn = ml_gen_mlds_var_decl(var(TempName), Type,
+ Initializer, Context) },
+ mlds_output_defn(Indent, ModuleName, TempDefn),
+
+ mlds_output_assign_args(Indent, ModuleName, Context, Rest, Args),
+
mlds_indent(Context, Indent),
mlds_output_fully_qualified_name(qual(ModuleName, Name)),
io__write_string(" = "),
- mlds_output_rval(Arg),
+ mlds_output_fully_qualified_name(QualTempName),
io__write_string(";\n")
- ),
- mlds_output_assign_args(Indent, ModuleName, Context, Rest, Args).
+ ).
+
+%-----------------------------------------------------------------------------%
%
% exception handling
Index: runtime/mercury.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury.c,v
retrieving revision 1.4
diff -u -d -r1.4 mercury.c
--- runtime/mercury.c 2000/05/08 16:11:05 1.4
+++ runtime/mercury.c 2000/05/11 16:50:32
@@ -770,6 +770,41 @@
/*---------------------------------------------------------------------------*/
+#ifdef __GNUC__
+
+/* provide definitions for functions declared `extern inline' */
+
+Word
+create1(Word w1)
+{
+ Word *p = (Word *) MR_new_object(Word, 1 * sizeof(Word), "create1");
+ p[0] = w1;
+ return (Word) p;
+}
+
+Word
+create2(Word w1, Word w2)
+{
+ Word *p = (Word *) MR_new_object(Word, 2 * sizeof(Word), "create2");
+ p[0] = w1;
+ p[1] = w2;
+ return (Word) p;
+}
+
+Word
+create3(Word w1, Word w2, Word w3)
+{
+ Word *p = (Word *) MR_new_object(Word, 3 * sizeof(Word), "create3");
+ p[0] = w1;
+ p[1] = w2;
+ p[2] = w3;
+ return (Word) p;
+}
+
+#endif
+
+/*---------------------------------------------------------------------------*/
+
/*
** XXX this is a hack to work-around the current lack of
** support for `pragma export'.
Index: runtime/mercury.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury.h,v
retrieving revision 1.8
diff -u -d -r1.8 mercury.h
--- runtime/mercury.h 2000/05/10 18:09:45 1.8
+++ runtime/mercury.h 2000/05/11 05:14:41
@@ -96,75 +96,58 @@
/*
** XXX Currently we hard-code the declarations of the first
** five of these type-info struct types; this imposes a fixed
-** limit of 5 on the arity of types. (If this is exceeded,
-** you'll get an undeclared type error in the generated C code.)
+** limit of 10 on the arity of types. (If this is exceeded,
+** you'll get a parse error in the generated C code, due to
+** an undeclared type.)
** Note that the code for compare and unify in runtime/mercury.c
** also has a fixed limit of 5 on the arity of types.
** Fortunately types with a high arity tend not to be used very
** often, so this is probably OK for now...
*/
-#ifndef MR_HO_PseudoTypeInfo_Struct1_GUARD
-#define MR_HO_PseudoTypeInfo_Struct1_GUARD
MR_HIGHER_ORDER_PSEUDOTYPEINFO_STRUCT(MR_HO_PseudoTypeInfo_Struct1, 1);
-#endif
-
-#ifndef MR_HO_PseudoTypeInfo_Struct2_GUARD
-#define MR_HO_PseudoTypeInfo_Struct2_GUARD
MR_HIGHER_ORDER_PSEUDOTYPEINFO_STRUCT(MR_HO_PseudoTypeInfo_Struct2, 2);
-#endif
-
-#ifndef MR_HO_PseudoTypeInfo_Struct3_GUARD
-#define MR_HO_PseudoTypeInfo_Struct3_GUARD
MR_HIGHER_ORDER_PSEUDOTYPEINFO_STRUCT(MR_HO_PseudoTypeInfo_Struct3, 3);
-#endif
-
-#ifndef MR_HO_PseudoTypeInfo_Struct4_GUARD
-#define MR_HO_PseudoTypeInfo_Struct4_GUARD
MR_HIGHER_ORDER_PSEUDOTYPEINFO_STRUCT(MR_HO_PseudoTypeInfo_Struct4, 4);
-#endif
-
-#ifndef MR_HO_PseudoTypeInfo_Struct5_GUARD
-#define MR_HO_PseudoTypeInfo_Struct5_GUARD
MR_HIGHER_ORDER_PSEUDOTYPEINFO_STRUCT(MR_HO_PseudoTypeInfo_Struct5, 5);
-#endif
+MR_HIGHER_ORDER_PSEUDOTYPEINFO_STRUCT(MR_HO_PseudoTypeInfo_Struct6, 6);
+MR_HIGHER_ORDER_PSEUDOTYPEINFO_STRUCT(MR_HO_PseudoTypeInfo_Struct7, 7);
+MR_HIGHER_ORDER_PSEUDOTYPEINFO_STRUCT(MR_HO_PseudoTypeInfo_Struct8, 8);
+MR_HIGHER_ORDER_PSEUDOTYPEINFO_STRUCT(MR_HO_PseudoTypeInfo_Struct9, 9);
+MR_HIGHER_ORDER_PSEUDOTYPEINFO_STRUCT(MR_HO_PseudoTypeInfo_Struct10, 10);
-#ifndef MR_FO_PseudoTypeInfo_Struct1_GUARD
-#define MR_FO_PseudoTypeInfo_Struct1_GUARD
MR_FIRST_ORDER_PSEUDOTYPEINFO_STRUCT(MR_FO_PseudoTypeInfo_Struct1, 1);
-#endif
-
-#ifndef MR_FO_PseudoTypeInfo_Struct2_GUARD
-#define MR_FO_PseudoTypeInfo_Struct2_GUARD
MR_FIRST_ORDER_PSEUDOTYPEINFO_STRUCT(MR_FO_PseudoTypeInfo_Struct2, 2);
-#endif
-
-#ifndef MR_FO_PseudoTypeInfo_Struct3_GUARD
-#define MR_FO_PseudoTypeInfo_Struct3_GUARD
MR_FIRST_ORDER_PSEUDOTYPEINFO_STRUCT(MR_FO_PseudoTypeInfo_Struct3, 3);
-#endif
-
-#ifndef MR_FO_PseudoTypeInfo_Struct4_GUARD
-#define MR_FO_PseudoTypeInfo_Struct4_GUARD
MR_FIRST_ORDER_PSEUDOTYPEINFO_STRUCT(MR_FO_PseudoTypeInfo_Struct4, 4);
-#endif
-
-#ifndef MR_FO_PseudoTypeInfo_Struct5_GUARD
-#define MR_FO_PseudoTypeInfo_Struct5_GUARD
MR_FIRST_ORDER_PSEUDOTYPEINFO_STRUCT(MR_FO_PseudoTypeInfo_Struct5, 5);
-#endif
+MR_FIRST_ORDER_PSEUDOTYPEINFO_STRUCT(MR_FO_PseudoTypeInfo_Struct6, 6);
+MR_FIRST_ORDER_PSEUDOTYPEINFO_STRUCT(MR_FO_PseudoTypeInfo_Struct7, 7);
+MR_FIRST_ORDER_PSEUDOTYPEINFO_STRUCT(MR_FO_PseudoTypeInfo_Struct8, 8);
+MR_FIRST_ORDER_PSEUDOTYPEINFO_STRUCT(MR_FO_PseudoTypeInfo_Struct9, 9);
+MR_FIRST_ORDER_PSEUDOTYPEINFO_STRUCT(MR_FO_PseudoTypeInfo_Struct10, 10);
typedef struct MR_HO_PseudoTypeInfo_Struct1 MR_HO_PseudoTypeInfo_Struct1;
typedef struct MR_HO_PseudoTypeInfo_Struct2 MR_HO_PseudoTypeInfo_Struct2;
typedef struct MR_HO_PseudoTypeInfo_Struct3 MR_HO_PseudoTypeInfo_Struct3;
typedef struct MR_HO_PseudoTypeInfo_Struct4 MR_HO_PseudoTypeInfo_Struct4;
typedef struct MR_HO_PseudoTypeInfo_Struct5 MR_HO_PseudoTypeInfo_Struct5;
+typedef struct MR_HO_PseudoTypeInfo_Struct6 MR_HO_PseudoTypeInfo_Struct6;
+typedef struct MR_HO_PseudoTypeInfo_Struct7 MR_HO_PseudoTypeInfo_Struct7;
+typedef struct MR_HO_PseudoTypeInfo_Struct8 MR_HO_PseudoTypeInfo_Struct8;
+typedef struct MR_HO_PseudoTypeInfo_Struct9 MR_HO_PseudoTypeInfo_Struct9;
+typedef struct MR_HO_PseudoTypeInfo_Struct10 MR_HO_PseudoTypeInfo_Struct10;
typedef struct MR_FO_PseudoTypeInfo_Struct1 MR_FO_PseudoTypeInfo_Struct1;
typedef struct MR_FO_PseudoTypeInfo_Struct2 MR_FO_PseudoTypeInfo_Struct2;
typedef struct MR_FO_PseudoTypeInfo_Struct3 MR_FO_PseudoTypeInfo_Struct3;
typedef struct MR_FO_PseudoTypeInfo_Struct4 MR_FO_PseudoTypeInfo_Struct4;
typedef struct MR_FO_PseudoTypeInfo_Struct5 MR_FO_PseudoTypeInfo_Struct5;
+typedef struct MR_FO_PseudoTypeInfo_Struct6 MR_FO_PseudoTypeInfo_Struct6;
+typedef struct MR_FO_PseudoTypeInfo_Struct7 MR_FO_PseudoTypeInfo_Struct7;
+typedef struct MR_FO_PseudoTypeInfo_Struct8 MR_FO_PseudoTypeInfo_Struct8;
+typedef struct MR_FO_PseudoTypeInfo_Struct9 MR_FO_PseudoTypeInfo_Struct9;
+typedef struct MR_FO_PseudoTypeInfo_Struct10 MR_FO_PseudoTypeInfo_Struct10;
/*---------------------------------------------------------------------------*/
/*
@@ -290,15 +273,24 @@
** XXX we should optimize the case where sizeof(MR_Float) == sizeof(MR_Box)
*/
-MR_EXTERN_INLINE MR_Box MR_box_float(MR_Float f);
+#if defined(__GNUC__) && !defined(MR_AVOID_MACROS)
+ #define MR_box_float(f) ({ \
+ MR_Float *MR_box_float_ptr = (MR_Float *) \
+ MR_new_object(MR_Float, sizeof(MR_Float), "float"); \
+ *MR_box_float_ptr = (f); \
+ /* return */ (MR_Box) MR_box_float_ptr; \
+ })
+#else
+ MR_EXTERN_INLINE MR_Box MR_box_float(MR_Float f);
-MR_EXTERN_INLINE MR_Box
-MR_box_float(MR_Float f) {
+ MR_EXTERN_INLINE MR_Box
+ MR_box_float(MR_Float f) {
MR_Float *ptr = (MR_Float *)
MR_new_object(MR_Float, sizeof(MR_Float), "float");
*ptr = f;
return (MR_Box) ptr;
-}
+ }
+#endif
#ifdef MR_AVOID_MACROS
MR_EXTERN_INLINE MR_Float MR_unbox_float(MR_Box b);
--
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.
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to: mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions: mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------
More information about the developers
mailing list