[m-dev.] diff: GCC back-end: fix --static-ground-terms

Fergus Henderson fjh at cs.mu.OZ.AU
Fri Jan 19 02:42:46 AEDT 2001


Estimated hours taken: 5

Fix the handling of --static-ground-terms for the GCC back-end.

gcc/mercury/mercury-gcc.h:
gcc/mercury/mercury-gcc.c:
mercury/compiler/gcc.m:
mercury/compiler/mlds_to_gcc.m:
	Generalize (merc_)build_global_var_decl to handle local
	statics too, and rename it as (merc_)build_static_var_decl.
	Split the call to rest_of_decl_compilation() into a
	separate procedure (merc_)finish_static_var_decl.
	This is needed because we need to set the declaration
	flags before calling rest_of_decl_compilation().

mercury/compiler/mlds_to_gcc.m:
	Build local static variables with build_static_var_decl and
	finish_static_var_decl rather than build_local_var_decl.
	Local variables with automatic storage duration (i.e.
	per_instance rather than one_copy) are still built with
	build_local_var_decl.  Call set_var_decl_flags before calling
	finish_static_var_decl (for statics) and before assigning
	to the variable (for automatics).

mercury/compiler/mlds_to_gcc.m:
mercury/compiler/gcc.m:
	Delete set_var_decl_static, since this is now handled
	by calling build_static_var_decl.

cvs diff: Diffing .
Index: gcc.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/gcc.m,v
retrieving revision 1.15
diff -u -d -u -r1.15 gcc.m
--- gcc.m	2001/01/18 12:07:56	1.15
+++ gcc.m	2001/01/18 14:38:55
@@ -156,17 +156,26 @@
 :- pred build_extern_var_decl(var_name::in, gcc__type::in, gcc__var_decl::out,
 		io__state::di, io__state::uo) is det.
 
-	% build an initialized global variable definition
-:- pred build_global_var_decl(var_name::in, gcc__type::in, gcc__expr::in,
+	% build an initialized static variable definition
+	% This can be used for either global variables
+	% or local static variables.
+	%
+	% After calling this, the caller should call set_var_decl_public
+	% and/or set_var_decl_readonly, if appropriate,
+	% and then finish_static_var_decl.
+:- pred build_static_var_decl(var_name::in, gcc__type::in, gcc__expr::in,
 		gcc__var_decl::out, io__state::di, io__state::uo) is det.
 
-	% build a local variable definition
+	% Finish off the definition of a static variable that
+	% was begun with build_static_var_decl, above.
+:- pred finish_static_var_decl(gcc__var_decl::in, io__state::di, io__state::uo)
+		is det.
+
+	% build an ordinary local variable definition
+	% i.e. one with automatic (rather than static) storage duration
 :- pred build_local_var_decl(var_name::in, gcc__type::in, gcc__var_decl::out,
 		io__state::di, io__state::uo) is det.
 
-	% mark a variable as being allocated in static storage
-:- pred set_var_decl_static(gcc__var_decl::in, io__state::di, io__state::uo) is det.
-
 	% mark a variable as being accessible from outside this
 	% translation unit
 :- pred set_var_decl_public(gcc__var_decl::in, io__state::di, io__state::uo) is det.
@@ -744,13 +753,19 @@
 	Decl = (MR_Word) merc_build_extern_var_decl(Name, (tree) Type);
 ").
 
-:- pragma c_code(build_global_var_decl(Name::in, Type::in, Init::in, Decl::out,
+:- pragma c_code(build_static_var_decl(Name::in, Type::in, Init::in, Decl::out,
 	_IO0::di, _IO::uo), [will_not_call_mercury],
 "
-	Decl = (MR_Word) merc_build_global_var_decl(Name, (tree) Type,
+	Decl = (MR_Word) merc_build_static_var_decl(Name, (tree) Type,
 		(tree) Init);
 ").
 
+:- pragma c_code(finish_static_var_decl(Decl::in, _IO0::di, _IO::uo),
+	[will_not_call_mercury],
+"
+	merc_finish_static_var_decl((tree) Decl);
+").
+
 :- pragma c_code(build_local_var_decl(Name::in, Type::in, Decl::out,
 	_IO0::di, _IO::uo), [will_not_call_mercury],
 "
@@ -763,12 +778,6 @@
 	TREE_PUBLIC((tree) Decl) = 1;
 ").
 
-:- pragma c_code(set_var_decl_static(Decl::in,
-	_IO0::di, _IO::uo), [will_not_call_mercury],
-"
-	TREE_STATIC((tree) Decl) = 1;
-").
-
 :- pragma c_code(set_var_decl_readonly(Decl::in,
 	_IO0::di, _IO::uo), [will_not_call_mercury],
 "
@@ -1186,14 +1195,6 @@
 "
 	Expr = (MR_Word) build(CONSTRUCTOR, (tree) Type, NULL_TREE,
 		(tree) InitList);
-#if 0
-	/* XXX do we need this?
-	** Are MLDS initializers only used for static initializers?
-	** Does GCC require initializers for static variables to be
-	** marked with TREE_STATIC() = 1?
-	*/
-	TREE_STATIC ((tree) Expr) = 1;
-#endif
 ").
 
 %-----------------------------------------------------------------------------%
Index: mlds_to_gcc.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_gcc.m,v
retrieving revision 1.20
diff -u -d -u -r1.20 mlds_to_gcc.m
--- mlds_to_gcc.m	2001/01/18 12:07:56	1.20
+++ mlds_to_gcc.m	2001/01/18 14:38:23
@@ -34,10 +34,6 @@
 % it will end up compiling everything via C.
 
 % TODO:
-%	Fix bugs:
-%	- calling convention for semidet code not binary compatible
-%	  with C; need to promote boolean return type to int
-%
 %	Fix configuration issues:
 %	- mmake support for foreign code
 %	- document installation procedure
@@ -56,6 +52,8 @@
 %	Implement implementation-specific features that are supported
 %	by other gcc front-ends:
 %	- generate gcc trees rather than expanding as we go
+%		This should probably wait until the GCC back-end
+%		has a language-independent representation for switches.
 %	- support gdb
 %		- improve accuracy of line numbers (e.g. for decls).
 %		- make variable names match what's in the original source
@@ -864,9 +862,10 @@
 			GlobalInfo0, GCC_Type),
 		build_initializer(Initializer, GCC_Type, DefnInfo,
 			GCC_Initializer),
-		gcc__build_global_var_decl(GCC_Name, GCC_Type, GCC_Initializer,
+		gcc__build_static_var_decl(GCC_Name, GCC_Type, GCC_Initializer,
 			GCC_Defn),
 		add_var_decl_flags(Flags, GCC_Defn),
+		gcc__finish_static_var_decl(GCC_Defn),
 		%
 		% insert the definition in our symbol table
 		%
@@ -892,8 +891,8 @@
 build_local_defn_body(Name, DefnInfo, _Context, Flags, DefnBody, GCC_Defn) -->
 	(
 		{ DefnBody = mlds__data(Type, Initializer) },
-		build_local_data_defn(Name, Type, Initializer, DefnInfo, GCC_Defn),
-		add_var_decl_flags(Flags, GCC_Defn)
+		build_local_data_defn(Name, Flags, Type,
+			Initializer, DefnInfo, GCC_Defn)
 	;
 		{ DefnBody = mlds__function(_, _, _) },
 		% nested functions should get eliminated by ml_elim_nested,
@@ -943,7 +942,8 @@
 
 add_var_decl_flags(Flags, GCC_Defn) -->
 	add_var_access_flag(		access(Flags),		GCC_Defn),
-	add_var_per_instance_flag(	per_instance(Flags),	GCC_Defn),
+	% note that the per_instance flag is handled separately,
+	% by calling build_local_var or build_static_var
 	add_var_virtuality_flag(	virtuality(Flags),	GCC_Defn),
 	add_var_finality_flag(		finality(Flags),	GCC_Defn),
 	add_var_constness_flag(		constness(Flags),	GCC_Defn),
@@ -962,16 +962,6 @@
 add_var_access_flag(default, _GCC_Defn) -->
 	{ sorry(this_file, "`default' access") }.
 
-:- pred add_var_per_instance_flag(mlds__per_instance, gcc__var_decl,
-	io__state, io__state).
-:- mode add_var_per_instance_flag(in, in, di, uo) is det.
-
-add_var_per_instance_flag(per_instance, _GCC_Defn) -->
-	% this is the default
-	[].
-add_var_per_instance_flag(one_copy, GCC_Defn) -->
-	gcc__set_var_decl_static(GCC_Defn).
-
 :- pred add_var_virtuality_flag(mlds__virtuality, gcc__var_decl,
 	io__state, io__state).
 :- mode add_var_virtuality_flag(in, in, di, uo) is det.
@@ -1183,28 +1173,46 @@
 	% Handle an MLDS data definition that is nested inside a
 	% function definition (or inside a block within a function),
 	% and which is hence local to that function.
-:- pred build_local_data_defn(mlds__qualified_entity_name, mlds__type,
-		mlds__initializer, defn_info, gcc__var_decl,
+:- pred build_local_data_defn(mlds__qualified_entity_name, mlds__decl_flags,
+		mlds__type, mlds__initializer, defn_info, gcc__var_decl,
 		io__state, io__state).
-:- mode build_local_data_defn(in, in, in, in, out, di, uo) is det.
+:- mode build_local_data_defn(in, in, in, in, in, out, di, uo) is det.
 
-build_local_data_defn(Name, Type, Initializer, DefnInfo, GCC_Defn) -->
+build_local_data_defn(Name, Flags, Type, Initializer, DefnInfo, GCC_Defn) -->
 	build_type(Type, initializer_array_size(Initializer),
 		DefnInfo ^ global_info, GCC_Type),
 	{ Name = qual(_ModuleName, UnqualName) },
-	( { UnqualName = data(var(VarName)) } ->
-		gcc__build_local_var_decl(VarName, GCC_Type, GCC_Defn)
+	( { UnqualName = data(var(VarName0)) } ->
+		{ VarName = VarName0 }
 	;
 		% var/1 should be the only kind of mlds__data_name for which
 		% the MLDS code generator generates local definitions
 		% (within functions)
 		{ unexpected(this_file, "build_local_data_defn: non-var") }
 	),
-	( { Initializer = no_initializer } ->
-		[]
+	{ PerInstance = per_instance(Flags) },
+	(
+		{ PerInstance = per_instance },
+		% an ordinary local variable
+		gcc__build_local_var_decl(VarName, GCC_Type, GCC_Defn),
+		add_var_decl_flags(Flags, GCC_Defn),
+		( { Initializer = no_initializer } ->
+			[]
+		;
+			build_initializer(Initializer, GCC_Type, DefnInfo,
+				GCC_InitExpr),
+			gcc__gen_assign(gcc__var_expr(GCC_Defn), GCC_InitExpr)
+		)
 	;
-		build_initializer(Initializer, GCC_Type, DefnInfo, GCC_Expr),
-		gcc__gen_assign(gcc__var_expr(GCC_Defn), GCC_Expr)
+		{ PerInstance = one_copy },
+		% a local static variable
+		% these must always have initializers
+		build_initializer(Initializer, GCC_Type, DefnInfo,
+			GCC_InitExpr),
+		gcc__build_static_var_decl(VarName, GCC_Type, GCC_InitExpr,
+			GCC_Defn),
+		add_var_decl_flags(Flags, GCC_Defn),
+		gcc__finish_static_var_decl(GCC_Defn)
 	).
 
 	% Handle an MLDS data definition that is nested inside a type,

Index: mercury-gcc.c
===================================================================
RCS file: /home/mercury1/repository/gcc/mercury/mercury-gcc.c,v
retrieving revision 1.22
diff -u -d -u -r1.22 mercury-gcc.c
--- mercury-gcc.c	2001/01/18 11:59:22	1.22
+++ mercury-gcc.c	2001/01/18 14:45:38
@@ -158,8 +158,9 @@
   return parm_decl;
 }
 
-/* Make a VAR_DECL for an extern variable whose name is VAR_NAME,
-   and whose type is VAR_TYPE.  */
+/* Make a VAR_DECL for an extern variable, i.e. a global variable defined in
+   some other compilation unit, whose name is VAR_NAME, and whose type is
+   VAR_TYPE.  */
 
 tree
 merc_build_extern_var_decl (var_name, var_type)
@@ -175,11 +176,17 @@
   return var_decl;
 }
 
-/* Make a VAR_DECL for an extern variable whose name is VAR_NAME,
-   and whose type is VAR_TYPE.  */
+/* Make a VAR_DECL for a variable with static storage duration,
+   whose name is VAR_NAME, whose type is VAR_TYPE, and whose
+   initial value is INITIALIZER.  This can be used for both
+   global variables and local static variables.
+
+   After calling this function, the caller should set the
+   appropriate flags (TREE_PUBLIC, TREE_READONLY, etc.) on the
+   VAR_DECL node returned, and then call merc_finish_static_var_decl().  */
 
 tree
-merc_build_global_var_decl (var_name, var_type, initializer)
+merc_build_static_var_decl (var_name, var_type, initializer)
      const char *var_name;
      tree var_type;
      tree initializer;
@@ -187,16 +194,27 @@
   tree var_decl = build_decl (VAR_DECL, get_identifier (var_name),
 			      var_type);
   DECL_INITIAL (var_decl) = fold (initializer);
-  TREE_PUBLIC (var_decl) = 1;
   TREE_STATIC (var_decl) = 1;
+  DECL_CONTEXT (var_decl) = current_function_decl;
+  return var_decl;
+}
+
+/* Finish off the definition of a variable with static storage duration
+   that was started with merc_build_static_var_decl(), above.  */
+
+void
+merc_finish_static_var_decl (var_decl)
+     tree var_decl;
+{
+  /* toplevel is nonzero iff this is a global variable declaration.  */
+  int toplevel = (current_function_decl == NULL);
   layout_decl (var_decl, /*known_align=*/0);
   rest_of_decl_compilation (var_decl, /*asm_spec=*/NULL_PTR,
-  			    /*toplevel=*/1, /*at_end=*/0);
-  return var_decl;
+  			    toplevel, /*at_end=*/0);
 }
 
-/* Make a VAR_DECL for a local variable whose name is VAR_NAME,
-   and whose type is VAR_TYPE.  */
+/* Make a VAR_DECL for a local variable with automatic storage
+   duration, whose name is VAR_NAME, and whose type is VAR_TYPE.  */
 
 tree
 merc_build_local_var_decl (var_name, var_type)
@@ -289,7 +307,7 @@
   fndecl = build_decl (FUNCTION_DECL, get_identifier (name), fntype);
   DECL_ASSEMBLER_NAME (fndecl) = get_identifier (asm_name);
   DECL_EXTERNAL (fndecl) = 0;
-  TREE_PUBLIC (fndecl) = 1;
+  TREE_PUBLIC (fndecl) = 1; /* XXX */
   TREE_STATIC (fndecl) = 1;
   DECL_ARGUMENTS (fndecl) = param_list;
   DECL_RESULT (fndecl)
Index: mercury-gcc.h
===================================================================
RCS file: /home/mercury1/repository/gcc/mercury/mercury-gcc.h,v
retrieving revision 1.14
diff -u -d -u -r1.14 mercury-gcc.h
--- mercury-gcc.h	2001/01/18 11:50:46	1.14
+++ mercury-gcc.h	2001/01/18 14:37:00
@@ -50,8 +50,10 @@
 merc_build_extern_var_decl	PARAMS((const char *name, tree type));
 
 extern tree
-merc_build_global_var_decl	PARAMS((const char *name, tree type,
+merc_build_static_var_decl	PARAMS((const char *name, tree type,
 					tree initializer));
+extern void
+merc_finish_static_var_decl	PARAMS((tree decl));
 
 extern tree
 merc_build_local_var_decl	PARAMS((const char *name, tree type));
-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
                                    |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- 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