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]
Other format: [Raw text]

[PATCH] Use DW_OP_fbreg where possible


Hi!

{,mem_}loc_descriptor is called with can_use_fbreg unconditionally false
in 4 places, which means that e.g. in
int
foo(int x, int y)
{
  char s[128];
  bar(s);
  return x + y;
}
on x86 -O2 -m32 -g -fomit-frame-pointer the x value is correct only after
the prologue, not before it.  If DW_OP_fbreg instead is used and for
-fomit-frame-pointer there is a location list for DW_AT_frame_base
describing sp changes, the debug info is correct even in the prologue.
Ok for HEAD?

2005-08-11  Jakub Jelinek  <jakub@redhat.com>

	* dwarf2out.c (concat_loc_descriptor): Add can_use_fbreg argument,
	pass it down to loc_descriptor.
	(loc_descriptor): Pass can_use_fbreg to concat_loc_descriptor.
	(containing_function_has_frame_base): Move earlier in the file.
	(loc_descriptor_from_tree_1): Use containing_function_has_frame_base
	instead of always assuming fbreg can't be used.

--- gcc/dwarf2out.c.jj	2005-08-06 10:39:55.000000000 +0200
+++ gcc/dwarf2out.c	2005-08-10 10:23:26.000000000 +0200
@@ -3982,7 +3982,7 @@ static dw_loc_descr_ref int_loc_descript
 static dw_loc_descr_ref based_loc_descr (unsigned, HOST_WIDE_INT, bool);
 static int is_based_loc (rtx);
 static dw_loc_descr_ref mem_loc_descriptor (rtx, enum machine_mode mode, bool);
-static dw_loc_descr_ref concat_loc_descriptor (rtx, rtx);
+static dw_loc_descr_ref concat_loc_descriptor (rtx, rtx, bool);
 static dw_loc_descr_ref loc_descriptor (rtx, bool);
 static dw_loc_descr_ref loc_descriptor_from_tree_1 (tree, int);
 static dw_loc_descr_ref loc_descriptor_from_tree (tree);
@@ -8806,11 +8806,11 @@ mem_loc_descriptor (rtx rtl, enum machin
    This is typically a complex variable.  */
 
 static dw_loc_descr_ref
-concat_loc_descriptor (rtx x0, rtx x1)
+concat_loc_descriptor (rtx x0, rtx x1, bool can_use_fbreg)
 {
   dw_loc_descr_ref cc_loc_result = NULL;
-  dw_loc_descr_ref x0_ref = loc_descriptor (x0, false);
-  dw_loc_descr_ref x1_ref = loc_descriptor (x1, false);
+  dw_loc_descr_ref x0_ref = loc_descriptor (x0, can_use_fbreg);
+  dw_loc_descr_ref x1_ref = loc_descriptor (x1, can_use_fbreg);
 
   if (x0_ref == 0 || x1_ref == 0)
     return 0;
@@ -8824,6 +8824,29 @@ concat_loc_descriptor (rtx x0, rtx x1)
   return cc_loc_result;
 }
 
+/* Return true if DECL's containing function has a frame base attribute.
+   Return false otherwise.  */
+
+static bool
+containing_function_has_frame_base (tree decl)
+{
+  tree declcontext = decl_function_context (decl);
+  dw_die_ref context;
+  dw_attr_ref attr;
+  
+  if (!declcontext)
+    return false;
+
+  context = lookup_decl_die (declcontext);
+  if (!context)
+    return false;
+
+  for (attr = context->die_attr; attr; attr = attr->dw_attr_next)
+    if (attr->dw_attr == DW_AT_frame_base)
+      return true;
+  return false;
+}
+
 /* Output a proper Dwarf location descriptor for a variable or parameter
    which is either allocated in a register or in a memory location.  For a
    register, we just generate an OP_REG and the register number.  For a
@@ -8859,7 +8882,8 @@ loc_descriptor (rtx rtl, bool can_use_fb
       break;
 
     case CONCAT:
-      loc_result = concat_loc_descriptor (XEXP (rtl, 0), XEXP (rtl, 1));
+      loc_result = concat_loc_descriptor (XEXP (rtl, 0), XEXP (rtl, 1),
+					  can_use_fbreg);
       break;
 
     case VAR_LOCATION:
@@ -9019,10 +9043,11 @@ loc_descriptor_from_tree_1 (tree loc, in
 	else
 	  {
 	    enum machine_mode mode;
+	    bool can_use_fb = containing_function_has_frame_base (loc);
 
 	    /* Certain constructs can only be represented at top-level.  */
 	    if (want_address == 2)
-	      return loc_descriptor (rtl, false);
+	      return loc_descriptor (rtl, can_use_fb);
 
 	    mode = GET_MODE (rtl);
 	    if (MEM_P (rtl))
@@ -9030,7 +9055,7 @@ loc_descriptor_from_tree_1 (tree loc, in
 		rtl = XEXP (rtl, 0);
 		have_address = 1;
 	      }
-	    ret = mem_loc_descriptor (rtl, mode, false);
+	    ret = mem_loc_descriptor (rtl, mode, can_use_fb);
 	  }
       }
       break;
@@ -9104,12 +9129,14 @@ loc_descriptor_from_tree_1 (tree loc, in
 	/* Get an RTL for this, if something has been emitted.  */
 	rtx rtl = lookup_constant_def (loc);
 	enum machine_mode mode;
+	bool can_use_fb;
 
 	if (!rtl || !MEM_P (rtl))
 	  return 0;
+	can_use_fb = containing_function_has_frame_base (loc);
 	mode = GET_MODE (rtl);
 	rtl = XEXP (rtl, 0);
-	ret = mem_loc_descriptor (rtl, mode, false);
+	ret = mem_loc_descriptor (rtl, mode, can_use_fb);
 	have_address = 1;
 	break;
       }
@@ -10073,29 +10100,6 @@ rtl_for_decl_location (tree decl)
   return rtl;
 }
 
-/* Return true if DECL's containing function has a frame base attribute.
-   Return false otherwise.  */
-
-static bool
-containing_function_has_frame_base (tree decl)
-{
-  tree declcontext = decl_function_context (decl);
-  dw_die_ref context;
-  dw_attr_ref attr;
-  
-  if (!declcontext)
-    return false;
-
-  context = lookup_decl_die (declcontext);
-  if (!context)
-    return false;
-
-  for (attr = context->die_attr; attr; attr = attr->dw_attr_next)
-    if (attr->dw_attr == DW_AT_frame_base)
-      return true;
-  return false;
-}
-  
 /* Generate *either* a DW_AT_location attribute or else a DW_AT_const_value
    data attribute for a variable or a parameter.  We generate the
    DW_AT_const_value attribute only in those cases where the given variable

	Jakub


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