[RFC] Centralize knowledge of eh personality routines

Submitted by Richard Henderson on Oct. 12, 2010, 10:59 p.m.

Details

Message ID 4CB4E841.1090308@redhat.com
State New
Headers show

Commit Message

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.

Comments

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 hide | download patch | download mbox

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) \