This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

inline functions and local labels


The following patch causes problems with an unusual, but until now
legal and otherwise quite harmless, construct in the Linux kernel.
Wherein the address of local labels are taken as a reliable method
of getting the pc for printing in debugging dumps.

Sat Jun 13 08:26:21 1998  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
 
        * integrate.c (function_cannot_inline_p): Can't if addresses labels.
        (initialize_for_inline): Save current_function_addresses_labels.
        (output_inline_function): Restore it.                                   
 
The problem this is addressing may alternately be solved by considering
that it is not the taking of the label's address that causes the problem,
but rather the later use of that address in a computed goto.

Please consider the following alternative patch.


r~


	* stmt.c (expand_computed_goto): Set current_function_has_computed_jump.
	* rtl.h (FUNCTION_FLAGS_HAS_COMPUTED_JUMP): New.
	* integrate.c (function_cannot_inline_p): Don't if computed jump.
	(initialize_for_inline): Save current_function_has_computed_jump.
	(output_inline_function): Restore it.

Index: stmt.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/stmt.c,v
retrieving revision 1.45
diff -u -p -r1.45 stmt.c
--- stmt.c	1998/07/13 22:21:01	1.45
+++ stmt.c	1998/07/28 08:40:20
@@ -589,6 +589,8 @@ expand_computed_goto (exp)
 
   do_pending_stack_adjust ();
   emit_indirect_jump (x);
+
+  current_function_has_computed_jump = 1;
 }
 
 /* Handle goto statements and the labels that they can go to.  */
Index: rtl.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/rtl.h,v
retrieving revision 1.45
diff -u -p -r1.45 rtl.h
--- rtl.h	1998/07/13 03:34:12	1.45
+++ rtl.h	1998/07/28 08:40:24
@@ -679,6 +679,7 @@ extern char *note_insn_name[];
 #define FUNCTION_FLAGS_USES_CONST_POOL 0200
 #define FUNCTION_FLAGS_CALLS_LONGJMP 0400
 #define FUNCTION_FLAGS_USES_PIC_OFFSET_TABLE 01000
+#define FUNCTION_FLAGS_HAS_COMPUTED_JUMP 02000
 
 /* Define a macro to look for REG_INC notes,
    but save time on machines where they never exist.  */
Index: integrate.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/integrate.c,v
retrieving revision 1.34
diff -u -p -r1.34 integrate.c
--- integrate.c	1998/06/25 15:14:38	1.34
+++ integrate.c	1998/07/28 08:40:32
@@ -194,6 +194,14 @@ function_cannot_inline_p (fndecl)
   if (forced_labels)
     return "function with label addresses used in initializers cannot inline";
 
+  /* We will not inline a function which uses computed goto.  The addresses
+     of its local labels, which may be tucked into global global storage,
+     are of course not constant across instantiations, which causes unexpected
+     behaviour.  */
+
+  if (current_function_has_computed_jump)
+    return "function with computed goto cannot be inline";
+
   /* We cannot inline a nested function that jumps to a nonlocal label.  */
   if (current_function_has_nonlocal_goto)
     return "function with nonlocal goto cannot be inline";
@@ -290,7 +298,8 @@ initialize_for_inline (fndecl, min_label
        + current_function_has_nonlocal_label * FUNCTION_FLAGS_HAS_NONLOCAL_LABEL
        + current_function_returns_pointer * FUNCTION_FLAGS_RETURNS_POINTER
        + current_function_uses_const_pool * FUNCTION_FLAGS_USES_CONST_POOL
-       + current_function_uses_pic_offset_table * FUNCTION_FLAGS_USES_PIC_OFFSET_TABLE);
+       + current_function_uses_pic_offset_table * FUNCTION_FLAGS_USES_PIC_OFFSET_TABLE
+       + current_function_has_computed_jump * FUNCTION_FLAGS_HAS_COMPUTED_JUMP);
 
   /* Clear out PARMDECL_MAP.  It was allocated in the caller's frame.  */
   bzero ((char *) parmdecl_map, max_parm_reg * sizeof (tree));
@@ -3399,6 +3408,9 @@ output_inline_function (fndecl)
 
   if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_USES_PIC_OFFSET_TABLE)
     current_function_uses_pic_offset_table = 1;
+
+  if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_HAS_COMPUTED_JUMP)
+    current_function_has_computed_jump = 1;
 
   current_function_outgoing_args_size = OUTGOING_ARGS_SIZE (head);
   current_function_pops_args = POPS_ARGS (head);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]