Patchwork [RFC] Centralize knowledge of eh personality routines

login
register
mail settings
Submitter Richard Henderson
Date Oct. 12, 2010, 10:59 p.m.
Message ID <4CB4E841.1090308@redhat.com>
Download mbox | patch
Permalink /patch/67630/
State New
Headers show

Comments

Richard Henderson - Oct. 12, 2010, 10:59 p.m.
The driver for this patch is SEH, which will add yet another function
name variant in each of these places in each front end.  While I could
adjust each language appropriately, it seems to me that it is a bit
cleaner to centralize this knowledge.

The next possibly objectionable point is including dwarf2.h in tree.h.
I went ahead and did this because in the past we had talked about using
the dwarf language enum in LTO.  I could see eliminating the hackish
language_string -> enum mapping that is done in dwarf2out.c as well.

Comments?  Objections?


r~
gcc/
	* expr.c (build_personality_function): Take parameter LANG instead
	of parameter NAME.  Build the name based on a known lang-specific
	prefix and the unwind method in use.
	* tree.c (lhd_gcc_personality): Update call to
	build_personality_function.
	* tree.h: Include dwarf2.h.
	(build_personality_function): Update decl.
	* Makefile.in (TREE_H): Update deps.

gcc/ada/
	* gcc-interface/misc.c (gnat_eh_personality): Update call to
	build_personality_function.
gcc/cp/
	* cp-lang.c (cp_eh_personality): Update call to
	build_personality_function.
	* except.c (choose_personality_routine): Update function comment.
gcc/java/
	* lang.c (java_eh_personality): Update call to
	build_personality_function.
gcc/objc/
	* objc-act.c (objc_eh_personality): Update call to
	build_personality_function.
gcc/objcp/
	* objcp-lang.c (objcxx_eh_personality): Update call to
	build_personality_function.
Jason Merrill - Oct. 13, 2010, 1:10 a.m.
Makes sense to me.

Jason
Ian Lance Taylor - Oct. 13, 2010, 4:58 a.m.
Richard Henderson <rth@redhat.com> writes:

> The driver for this patch is SEH, which will add yet another function
> name variant in each of these places in each front end.  While I could
> adjust each language appropriately, it seems to me that it is a bit
> cleaner to centralize this knowledge.

Works for me.

> The next possibly objectionable point is including dwarf2.h in tree.h.

Yeah.  Ugh.  I guess it's that or just using int.

Ian
Eric Botcazou - Oct. 13, 2010, 7:02 a.m.
> The driver for this patch is SEH, which will add yet another function
> name variant in each of these places in each front end.  While I could
> adjust each language appropriately, it seems to me that it is a bit
> cleaner to centralize this knowledge.

-/* Build a decl for a EH personality function named NAME. */
+/* Build a personality function given a language.  LANG is really an
+   enum dwarf_source_language.  */

Left-overs from when it was only an integer?


+    case DW_LANG_Ada83:
+    case DW_LANG_Ada95:
+      prefix = "__gnat_eh_personality";
+      /* The GNAT folk did not follow the standard naming format.
+	 That can change if we ever have to increment the version.  */
+      if (ui == UI_DWARF2 || ui == UI_TARGET)
+	unwind = "";
+      version = "";
+      break;

Let's change that right now, we don't guarantee any ABI compatibility between 
different major releases.  Olivier, any objections?
Arnaud Charlet - Oct. 13, 2010, 7:09 a.m.
> +    case DW_LANG_Ada83:
> +    case DW_LANG_Ada95:
> +      prefix = "__gnat_eh_personality";
> +      /* The GNAT folk did not follow the standard naming format.
> +	 That can change if we ever have to increment the version.  */
> +      if (ui == UI_DWARF2 || ui == UI_TARGET)
> +	unwind = "";
> +      version = "";
> +      break;
> 
> Let's change that right now, we don't guarantee any ABI compatibility
> between different major releases.  Olivier, any objections?

Looks like a good idea to me, so that we're consistent with other languages
and follow the standard naming format. As you said, we don't guarantee
ABI compatibility.

Arno
Olivier Hainque - Oct. 13, 2010, 7:23 a.m.
Eric Botcazou wrote:
> +    case DW_LANG_Ada83:
> +    case DW_LANG_Ada95:
> +      prefix = "__gnat_eh_personality";
> +      /* The GNAT folk did not follow the standard naming format.
> +	 That can change if we ever have to increment the version.  */

> Let's change that right now, we don't guarantee any ABI
> compatibility between different major releases.  Olivier, any
> objections?

 No, on the contrary, I'm all for it. Thanks :)

 Olivier
Mark Mitchell - Oct. 13, 2010, 2:14 p.m.
On 10/12/2010 3:59 PM, Richard Henderson wrote:
> The driver for this patch is SEH, which will add yet another function
> name variant in each of these places in each front end.  While I could
> adjust each language appropriately, it seems to me that it is a bit
> cleaner to centralize this knowledge.

> Comments?  Objections?

None in principle, but I think it would be better to have
build_personality_function take a language prefix string (e.g., "gxx" or
"gcj") rather than an enum.  Logically, the middle-end shouldn't be
aware of what front-end languages exist, and passing in a string would
avoid that.  And also avoid the tree.h -> dwarf2.h issue.

Patch

diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c
index 7703e2e..3fea6a3 100644
--- a/gcc/ada/gcc-interface/misc.c
+++ b/gcc/ada/gcc-interface/misc.c
@@ -687,11 +687,7 @@  static tree
 gnat_eh_personality (void)
 {
   if (!gnat_eh_personality_decl)
-    gnat_eh_personality_decl
-      = build_personality_function (targetm.except_unwind_info () == UI_SJLJ
-				    ? "__gnat_eh_personality_sj"
-				    : "__gnat_eh_personality");
-
+    gnat_eh_personality_decl = build_personality_function (DW_LANG_Ada95);
   return gnat_eh_personality_decl;
 }
 
diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c
index 0b70444..1126283 100644
--- a/gcc/cp/cp-lang.c
+++ b/gcc/cp/cp-lang.c
@@ -166,17 +166,10 @@  cp_eh_personality (void)
 {
   if (!cp_eh_personality_decl)
     {
-      const char *name;
+      enum dwarf_source_language lang;
 
-      name = (targetm.except_unwind_info () == UI_SJLJ
-	      ? (pragma_java_exceptions
-		 ? "__gcj_personality_sj0"
-		 : "__gxx_personality_sj0")
-	      : (pragma_java_exceptions
-		 ? "__gcj_personality_v0"
-		 : "__gxx_personality_v0"));
-
-      cp_eh_personality_decl = build_personality_function (name);
+      lang = (pragma_java_exceptions ? DW_LANG_Java : DW_LANG_C_plus_plus);
+      cp_eh_personality_decl = build_personality_function (lang);
     }
 
   return cp_eh_personality_decl;
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index 9d19aa9..b917664 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -295,9 +295,8 @@  decl_is_java_type (tree decl, int err)
 /* Select the personality routine to be used for exception handling,
    or issue an error if we need two different ones in the same
    translation unit.
-   ??? At present eh_personality_decl is set to
-   __gxx_personality_(sj|v)0 in init_exception_processing - should it
-   be done here instead?  */
+   ??? At present DECL_FUNCTION_PERSONALITY is set via
+   LANG_HOOKS_EH_PERSONALITY.  Should it be done here instead?  */
 void
 choose_personality_routine (enum languages lang)
 {
diff --git a/gcc/expr.c b/gcc/expr.c
index b0c160f..3093967 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -10255,13 +10255,63 @@  const_vector_from_tree (tree exp)
   return gen_rtx_CONST_VECTOR (mode, v);
 }
 
-
-/* Build a decl for a EH personality function named NAME. */
+/* Build a personality function given a language.  LANG is really an
+   enum dwarf_source_language.  */
 
 tree
-build_personality_function (const char *name)
+build_personality_function (enum dwarf_source_language lang)
 {
+  enum unwind_info_type ui = targetm.except_unwind_info ();
+  const char *prefix, *unwind, *version = "0";
   tree decl, type;
+  char *name;
+
+  switch (ui)
+    {
+    case UI_NONE:
+      return NULL;
+    case UI_SJLJ:
+      unwind = "_sj";
+      break;
+    case UI_DWARF2:
+    case UI_TARGET:
+      unwind = "_v";
+      break;
+    default:
+      gcc_unreachable ();
+    }
+
+  switch (lang)
+    {
+    case DW_LANG_Ada83:
+    case DW_LANG_Ada95:
+      prefix = "__gnat_eh_personality";
+      /* The GNAT folk did not follow the standard naming format.
+	 That can change if we ever have to increment the version.  */
+      if (ui == UI_DWARF2 || ui == UI_TARGET)
+	unwind = "";
+      version = "";
+      break;
+
+    case DW_LANG_C_plus_plus:
+      prefix = "__gxx_personality";
+      break;
+
+    case DW_LANG_Java:
+      prefix = "__gcj_personality";
+      break;
+
+    case DW_LANG_ObjC:
+      prefix = "__gnu_objc_personality";
+      break;
+
+    default:
+      /* All other languages use the minimal C personality.  */
+      prefix = "__gcc_personality";
+      break;
+    }
+
+  name = concat (prefix, unwind, version, NULL);
 
   type = build_function_type_list (integer_type_node, integer_type_node,
 				   long_long_unsigned_type_node,
@@ -10276,6 +10326,7 @@  build_personality_function (const char *name)
      are the flags assigned by targetm.encode_section_info.  */
   SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl), 0), NULL);
 
+  free (name);
   return decl;
 }
 
diff --git a/gcc/java/lang.c b/gcc/java/lang.c
index fbe25ad..7b29ea3 100644
--- a/gcc/java/lang.c
+++ b/gcc/java/lang.c
@@ -911,11 +911,7 @@  static tree
 java_eh_personality (void)
 {
   if (!java_eh_personality_decl)
-    java_eh_personality_decl
-      = build_personality_function (targetm.except_unwind_info () == UI_SJLJ
-				    ? "__gcj_personality_sj0"
-				    : "__gcj_personality_v0");
-
+    java_eh_personality_decl = build_personality_function (DW_LANG_Java);
   return java_eh_personality_decl;
 }
 
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index 3a13519..6e2a0fa 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -3693,13 +3693,8 @@  objc_eh_runtime_type (tree type)
 tree
 objc_eh_personality (void)
 {
-  if (!flag_objc_sjlj_exceptions
-      && !objc_eh_personality_decl)
-    objc_eh_personality_decl
-      = build_personality_function (targetm.except_unwind_info () == UI_SJLJ
-				    ? "__gnu_objc_personality_sj0"
-				    : "__gnu_objc_personality_v0");
-
+  if (!flag_objc_sjlj_exceptions && !objc_eh_personality_decl)
+    objc_eh_personality_decl = build_personality_function (DW_LANG_ObjC);
   return objc_eh_personality_decl;
 }
 #endif
diff --git a/gcc/objcp/objcp-lang.c b/gcc/objcp/objcp-lang.c
index fdb2976..1224c31 100644
--- a/gcc/objcp/objcp-lang.c
+++ b/gcc/objcp/objcp-lang.c
@@ -148,9 +148,7 @@  objcxx_eh_personality (void)
 {
   if (!objcp_eh_personality_decl)
     objcp_eh_personality_decl
-	= build_personality_function (targetm.except_unwind_info () == UI_SJLJ
-				      ? "__gxx_personality_sj0"
-				      : "__gxx_personality_v0");
+      = build_personality_function (DW_LANG_C_plus_plus);
 
   return objcp_eh_personality_decl;
 }
diff --git a/gcc/tree.c b/gcc/tree.c
index cf5881a..e02ad3e 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -10874,11 +10874,7 @@  tree
 lhd_gcc_personality (void)
 {
   if (!gcc_eh_personality_decl)
-    gcc_eh_personality_decl
-      = build_personality_function (targetm.except_unwind_info () == UI_SJLJ
-				    ? "__gcc_personality_sj0"
-				    : "__gcc_personality_v0");
-
+    gcc_eh_personality_decl = build_personality_function (DW_LANG_C);
   return gcc_eh_personality_decl;
 }
 
diff --git a/gcc/tree.h b/gcc/tree.h
index 8aedf1a..ef7f409 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -33,6 +33,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "fixed-value.h"
 #include "alias.h"
 #include "flags.h"
+#include "dwarf2.h"		/* for enum dwarf_source_language */
 
 /* Codes of tree nodes */
 
@@ -5474,7 +5475,7 @@  extern unsigned HOST_WIDE_INT compute_builtin_object_size (tree, int);
 
 /* In expr.c.  */
 extern unsigned HOST_WIDE_INT highest_pow2_factor (const_tree);
-extern tree build_personality_function (const char *);
+extern tree build_personality_function (enum dwarf_source_language);
 
 /* In tree-inline.c.  */
 
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 8118c06..f1b6972 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -886,7 +886,7 @@  TREE_H = tree.h all-tree.def tree.def c-family/c-common.def \
 	$(lang_tree_files) $(MACHMODE_H) tree-check.h $(BUILTINS_DEF) \
 	$(INPUT_H) statistics.h $(VEC_H) treestruct.def $(HASHTAB_H) \
 	double-int.h alias.h $(SYMTAB_H) $(FLAGS_H) vecir.h \
-	$(REAL_H) $(FIXED_VALUE_H)
+	$(REAL_H) $(FIXED_VALUE_H) $(DWARF2_H)
 REGSET_H = regset.h $(BITMAP_H) hard-reg-set.h
 BASIC_BLOCK_H = basic-block.h $(PREDICT_H) $(VEC_H) $(FUNCTION_H) cfghooks.h
 GIMPLE_H = gimple.h gimple.def gsstruct.def pointer-set.h $(VEC_H) \