[PATCH, PR 49495] Cgraph verifier must look through aliases

2011-07-03 Thread Martin Jambor
Hi,

PR 49495 is actually a bug in the verifier that does not look through
aliases at one point.  Fixed wit the patch below (created a special
function, otherwise I just wasn't able to fit the 80 column limit).
Bootstrapped and tested on x86_64-linux.  OK for trunk?

Thanks,

Martin


2011-07-02  Martin Jambor  

PR middle-end/49495
* cgraphunit.c (verify_edge_corresponds_to_fndecl): New function.
(verify_cgraph_node): Some functinality moved to
verify_edge_corresponds_to_fndecl, call it.


Index: src/gcc/cgraphunit.c
===
--- src.orig/gcc/cgraphunit.c
+++ src/gcc/cgraphunit.c
@@ -450,6 +450,34 @@ cgraph_debug_gimple_stmt (struct functio
   debug_gimple_stmt (stmt);
 }
 
+/* Verify that call graph edge E corresponds to DECL from the associated
+   statement.  Return true if the verification should fail.  */
+
+static bool
+verify_edge_corresponds_to_fndecl (struct cgraph_edge *e, tree decl)
+{
+  if (!e->callee->global.inlined_to
+  && decl
+  && cgraph_get_node (decl)
+  && (e->callee->former_clone_of
+ != cgraph_function_or_thunk_node (cgraph_get_node (decl), NULL)->decl)
+  /* IPA-CP sometimes redirect edge to clone and then back to the former
+function.  This ping-pong has to go, eventaully.  */
+  && (cgraph_function_or_thunk_node (cgraph_get_node (decl), NULL)
+ != cgraph_function_or_thunk_node (e->callee, NULL))
+  && !clone_of_p (cgraph_get_node (decl),
+ e->callee))
+{
+  error ("edge points to wrong declaration:");
+  debug_tree (e->callee->decl);
+  fprintf (stderr," Instead of:");
+  debug_tree (decl);
+  return true;
+}
+  else
+return false;
+}
+
 /* Verify cgraph nodes of given cgraph node.  */
 DEBUG_FUNCTION void
 verify_cgraph_node (struct cgraph_node *node)
@@ -702,24 +730,8 @@ verify_cgraph_node (struct cgraph_node *
  }
if (!e->indirect_unknown_callee)
  {
-   if (!e->callee->global.inlined_to
-   && decl
-   && cgraph_get_node (decl)
-   && (e->callee->former_clone_of
-   != cgraph_get_node (decl)->decl)
-   /* IPA-CP sometimes redirect edge to clone and 
then back to the former
-  function.  This ping-pong has to go, 
eventaully.  */
-   && (cgraph_function_or_thunk_node 
(cgraph_get_node (decl), NULL)
-   != cgraph_function_or_thunk_node 
(e->callee, NULL))
-   && !clone_of_p (cgraph_get_node (decl),
-   e->callee))
- {
-   error ("edge points to wrong declaration:");
-   debug_tree (e->callee->decl);
-   fprintf (stderr," Instead of:");
-   debug_tree (decl);
-   error_found = true;
- }
+   if (verify_edge_corresponds_to_fndecl (e, decl))
+ error_found = true;
  }
else if (decl)
  {


Re: Request to backport two -mvzeroupper related patches to 4.6 branch

2011-07-03 Thread Uros Bizjak
On Wed, Jun 29, 2011 at 2:58 AM, Fang, Changpeng  wrote:

> Attached are two patches in gcc 4.7 trunk that we request to backport to 4.6 
> branch.
> There are all related to -mvzerupper
>
> 1)
> 0001-Save-the-initial-options-after-checking-vzeroupper.patch
> This patch fixes bug 47315, ICE: in extract_insn, at recog.c:2109 
> (unrecognizable insn) with -mvzeroupper and __attribute__((target("avx")))
>
> The patch was committed to trunk: 2011-05-23  H.J. Lu  
>
> The bug still exists in gcc 4.6.1. Backporting this patches would fix it.
>
> 2).
> 0001--config-i386-i386.c-ix86_reorg-Run-move_or_dele.patch
> This patch Run move_or_delete_vzeroupper first, and was committed to trunk:
> 2011-05-04  Uros Bizjak  
>
>
> Is It OK to commit to 4.6 branch?

This is OK for the branch.

Thanks,
Uros.


Re: [PATCH] Handle vectorization of invariant loads (PR46787)

2011-07-03 Thread Ira Rosen


Richard Guenther  wrote on 30/06/2011 06:24:50 PM:


> FYI, I'm testing the following which cures a fallout seen when
> building SPEC2k6 with the committed patch.  It's suboptimal for
> j != 0 though - is there a way to get to the vectorized stmt
> of the j == 0 iteration?

Yes, I think we can simply use the stmt from the previous iteration, but we
have to avoid creation of unnecessary vector loads. Even though multiple
uses of that single load are still created, they are cleaned up later.

(I didn't indent the code properly and only tested the patch on the
vectorizer testsuite).

Ira

Index: tree-vect-stmts.c
===
--- tree-vect-stmts.c   (revision 175785)
+++ tree-vect-stmts.c   (working copy)
@@ -4386,6 +4386,8 @@ vectorizable_load (gimple stmt, gimple_s
   for (j = 0; j < ncopies; j++)
 {
   /* 1. Create the vector or array pointer update chain.  */
+  if (!inv_p || bb_vinfo)
+{
   if (j == 0)
 dataref_ptr = vect_create_data_ref_ptr (first_stmt, aggr_type,
at_loop,
offset, &dummy, gsi,
@@ -4393,11 +4395,11 @@ vectorizable_load (gimple stmt, gimple_s
   else
 dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, gsi, stmt,
   TYPE_SIZE_UNIT (aggr_type));
-
+}
   if (strided_load || slp_perm)
dr_chain = VEC_alloc (tree, heap, vec_num);

-  if (load_lanes_p)
+  if (load_lanes_p && (!inv_p || bb_vinfo))
{
  tree vec_array;

@@ -4426,6 +4428,8 @@ vectorizable_load (gimple stmt, gimple_s
{
  for (i = 0; i < vec_num; i++)
{
+  if (!inv_p || bb_vinfo)
+{
  if (i > 0)
dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, gsi,
   stmt, NULL_TREE);
@@ -4570,18 +4574,22 @@ vectorizable_load (gimple stmt, gimple_s
  msq = lsq;
}
}
-
+}
+
  /* 4. Handle invariant-load.  */
- if (inv_p && !bb_vinfo)
-   {
- tree vec_inv;
- gimple_stmt_iterator gsi2 = *gsi;
- gcc_assert (!strided_load);
- gsi_next (&gsi2);
- vec_inv = build_vector_from_val (vectype, scalar_dest);
- new_temp = vect_init_vector (stmt, vec_inv,
-  vectype, &gsi2);
- new_stmt = SSA_NAME_DEF_STMT (new_temp);
+ else
+  {
+  if (j==0)
+{
+ tree vec_inv;
+ gimple_stmt_iterator gsi2 = *gsi;
+ gcc_assert (!strided_load);
+ gsi_next (&gsi2);
+ vec_inv = build_vector_from_val (vectype,
scalar_dest);
+ new_temp = vect_init_vector (stmt, vec_inv,
+  vectype, &gsi2);
+ new_stmt = SSA_NAME_DEF_STMT (new_temp);
+}
}

  if (negative)


>
> Thanks,
> Richard.
>
> 2011-06-30  Richard Guenther  
>
>* tree-vect-stmts.c (vectorizable_load): Remove unnecessary
>assert.
>
> Index: gcc/tree-vect-stmts.c
> ===
> --- gcc/tree-vect-stmts.c   (revision 175709)
> +++ gcc/tree-vect-stmts.c   (working copy)
> @@ -4574,19 +4574,14 @@ vectorizable_load (gimple stmt, gimple_s
>   /* 4. Handle invariant-load.  */
>   if (inv_p && !bb_vinfo)
>{
> +tree vec_inv;
> +gimple_stmt_iterator gsi2 = *gsi;
>  gcc_assert (!strided_load);
> -if (j == 0)
> -  {
> -tree vec_inv;
> -gimple_stmt_iterator gsi2 = *gsi;
> -gsi_next (&gsi2);
> -vec_inv = build_vector_from_val (vectype, scalar_dest);
> -new_temp = vect_init_vector (stmt, vec_inv,
> - vectype, &gsi2);
> -new_stmt = SSA_NAME_DEF_STMT (new_temp);
> -  }
> -else
> -  gcc_unreachable (); /* FORNOW. */
> +gsi_next (&gsi2);
> +vec_inv = build_vector_from_val (vectype, scalar_dest);
> +new_temp = vect_init_vector (stmt, vec_inv,
> +  vectype, &gsi2);
> +new_stmt = SSA_NAME_DEF_STMT (new_temp);
>}
>
>   if (negative)



[patch] Fix PR tree-optimization/49610

2011-07-03 Thread Ira Rosen
Hi,

This patch adds a missing check that a basic blocks exists before using it.

Bootstrapped and tested on powerpc64-suse-linux.
Committed.

Ira

ChangeLog:

   PR tree-optimization/49610
   * tree-vect-loop.c (vect_is_slp_reduction): Check that DEF_STMT has
  a basic block.

testsuite/ChangeLog:

   PR tree-optimization/49610
   * gcc.dg/vect/pr49610.c: New test.

Index: testsuite/gcc.dg/vect/pr49610.c
===
--- testsuite/gcc.dg/vect/pr49610.c (revision 0)
+++ testsuite/gcc.dg/vect/pr49610.c (revision 0)
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+
+extern int g_7;
+void func_13(int p_17) {
+  int i;
+for (i=0; i < 16; i = (signed char)(i+1)) {
+g_7 &= p_17;
+g_7 &= (p_17 > 1);
+}
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
Index: tree-vect-loop.c
===
--- tree-vect-loop.c(revision 175785)
+++ tree-vect-loop.c(working copy)
@@ -1823,6 +1823,7 @@ vect_is_slp_reduction (loop_vec_info loop_info, gi
 ("vect_internal_def"), or it's an induction (defined by a
 loop-header phi-node).  */
   if (def_stmt
+  && gimple_bb (def_stmt)
  && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt))
   && (is_gimple_assign (def_stmt)
   || is_gimple_call (def_stmt)
@@ -1852,6 +1853,7 @@ vect_is_slp_reduction (loop_vec_info loop_info, gi
 ("vect_internal_def"), or it's an induction (defined by a
 loop-header phi-node).  */
   if (def_stmt
+  && gimple_bb (def_stmt)
  && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt))
   && (is_gimple_assign (def_stmt)
   || is_gimple_call (def_stmt)


Re: objc/objc++: refactor encoding code

2011-07-03 Thread Iain Sandoe

Hi Nicola,

On 2 Jul 2011, at 19:06, Nicola Pero wrote:

This patch improves the modularity of the Objective-C Front-End by  
separating
out the encoding code into separate objc-encoding.h and objc- 
encoding.c files.


thanks for doing this .. :-)

The performance impact of this patch should be minimal; there a few,  
well-defined
entry points to the encoding machinery (such as calls to encode a  
method prototype, or
an instance variable, or to produce an @encode string) and they were  
already standard
functions; having them in one compilation unit or the other doesn't  
change anything.  All
the other encoding functions just call each other, and are static,  
so again moving them to

a different unit has no performance impact.


I suspect that having a more modular code base will bring its own  
improvements, since it becomes easier to focus on and see the scope of  
optimizations.


In any event, as we move towards bootstrapping with lto, these issues  
should vanish as a concern.


as a datum, the patch works for me on *-darwin9 ...

cheers
Iain



Re: [PATCH, MELT] pragma support in MELT

2011-07-03 Thread Pierre Vittet

Hello,

This patch is an improvment of 
http://gcc.gnu.org/ml/gcc-patches/2011-06/msg01861.html. It completes 
pragma support into MELT. Main changes are mostly comments improvments, 
better respect of coding standard and using long instead of int for 
pragma index when we have several pragmas being registered. I also 
removed the PRAGMA_BAD macro as it was said to be less readable, and 
changed malformed pragma warnings into errors.


I tested the patch without seing any error or regression.

Pierre Vittet
2011-07-03  Pierre Vittet  

* melt-runtime.c: include c-pragma.h.
[__GNUC__>4.6] (melt_handle_melt_pragma, handle_melt_pragma,
melt_pragma_callback): Add functions for full pragma handling.
[__GNUC__<=4.6] (melt_handle_melt_pragma, handle_melt_pragma,
melt_pragma_callback): Add functions for limited pragma handling.
(melt_really_initialize): Register a callback for pragma.
* Makefile.in (CFAMILYINC): We need c-family header in include headers.

Index: gcc/melt-runtime.c
===
--- gcc/melt-runtime.c  (revision 175724)
+++ gcc/melt-runtime.c  (working copy)
@@ -74,6 +74,7 @@ along with GCC; see the file COPYING3.   If not se
 #include "md5.h"
 #include "plugin.h"
 #include "cppdefault.h"
+#include "c-pragma.h"
 
 #if BUILDING_GCC_VERSION > 4005
 /* GCC 4.6 has realmpfr.h which includes   */
@@ -8982,7 +8983,296 @@ melt_attribute_callback(void *gcc_data ATTRIBUTE_U
   register_attribute(&melt_attr_spec);
 }
 
+/* We declare weak functions because they cannot be linked when we use lto (it
+   loses langage specific informations).
+   If you use one of those functions you must check them to be not NULL.
+*/
+extern enum cpp_ttype __attribute__((weak)) pragma_lex (tree *);
 
+/* Test for GCC > 4.6.0.  */
+#if __GNUC__ > 4 || \
+(__GNUC__ == 4 && (__GNUC_MINOR__ > 6))
+/* Full pragma with data support.   */
+
+/* Call the MELT function which handle pragma: it is one of the handler of the
+   list sysdata_meltpragmas.  First argument is a tree containing the operator
+   and the second argument contains a list of tree (the arguments of the
+   pragma).  Third argument is the index of the handler to use (in list
+   sysdata_meltpragmas).  */
+void melt_handle_melt_pragma (melt_ptr_t optreev, melt_ptr_t listargtreev,
+  long i_handler);
+
+extern void __attribute__((weak)) c_register_pragma_with_expansion_and_data
+(const char *space, const char *name,
+ pragma_handler_2arg handler, void *data);
+
+/* Handle a melt pragma: data contains the index of the pragma handler.  */
+static void
+handle_melt_pragma (cpp_reader *ARG_UNUSED(dummy), void *data)
+{
+  enum cpp_ttype token;
+  /* List containing the pragma arguments .  */
+  tree x;
+  long i_handler = (long) data;
+  MELT_ENTERFRAME (3, NULL);
+#define seqv  meltfram__.mcfr_varptr[0]
+#define treev meltfram__.mcfr_varptr[1]
+#define optreev   meltfram__.mcfr_varptr[2]
+  if (!pragma_lex || !c_register_pragma_with_expansion_and_data)
+fatal_error ("Cannot use pragma symbol at this level \
+   (maybe you use -flto which is incompatible).");
+
+  token = pragma_lex (&x);
+  if (token != CPP_NAME)
+{
+  error ("malformed #pragma melt, ignored");
+  goto end;
+}
+  optreev = meltgc_new_tree ((meltobject_ptr_t) MELT_PREDEF (DISCR_TREE), x);
+  /* If the pragma has the form #pragma MELT name id (...) then optreev is the
+  tree containing "id".  */
+  /* Next element should be a parenthesis opening.  */
+  token = pragma_lex (&x);
+  if (token != CPP_OPEN_PAREN)
+{
+  if (token != CPP_EOF)
+   {
+ error ("malformed #pragma melt, ignored");
+ goto end;
+   }
+  else{ /* We have a pragma of the type '#pragma MELT name instr'.  */
+   melt_handle_melt_pragma ((melt_ptr_t ) optreev, (melt_ptr_t ) NULL,
+i_handler);
+  }
+}
+  else
+{/* Opening parenthesis.  */
+  seqv = meltgc_new_list ((meltobject_ptr_t) MELT_PREDEF (DISCR_LIST));
+  do
+   {
+ token = pragma_lex (&x);
+ if(token != CPP_NAME && token != CPP_STRING && token != CPP_NUMBER)
+   {
+ error ("malformed #pragma melt, ignored");
+ goto end;
+   }
+ /* Convert gcc tree into a boxed tree.  */
+ treev = meltgc_new_tree ((meltobject_ptr_t) MELT_PREDEF (DISCR_TREE),
+  x);
+ /* Put the arg in IDENTIFIER_POINTER (x) in a list.  */
+ meltgc_append_list ((melt_ptr_t) seqv, (melt_ptr_t) treev);
+ token = pragma_lex (&x);
+   } while (token == CPP_COMMA);
+  if (token == CPP_CLOSE_PAREN && pragma_lex (&x) == CPP_EOF)
+   melt_handle_melt_pragma ((melt_ptr_t ) optreev, (melt_ptr_t ) seqv,
+i_hand

Re: PATCH: PR target/49600: Bad SSE2 int->float split in i386.md

2011-07-03 Thread Uros Bizjak
On Fri, Jul 1, 2011 at 12:50 AM, H.J. Lu  wrote:
> In one SSE2 int->float split, when TARGET_USE_VECTOR_CONVERTS is true,
> TARGET_INTER_UNIT_MOVES is false and GENERAL_REG_P (op1) is true. we
> will get gcc_unreachable.  This patch removes TARGET_INTER_UNIT_MOVES
> check.  OK for trunk?

This will result in register allocation failure. Operand 0 of
sse2_loadld pattern has conditional constraint Yi that depends on
TARGET_INTER_UNIT_MOVES, so we can't blindly generate sse2_loadld
after reload.  I'm testing attached patch.

BTW: Do you perhaps have a testcase for this problem?

2011-07-03  Uros Bizjak  

PR target/49600
* config/i386/i386.md (SSE2 int->float split): Push operand 1 in
general register to memory for !TARGET_INTER_UNIT_MOVES.

Thanks,
Uros.
Index: i386.md
===
--- i386.md (revision 175786)
+++ i386.md (working copy)
@@ -4959,11 +4959,20 @@
   if (GET_CODE (op1) == SUBREG)
 op1 = SUBREG_REG (op1);
 
-  if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
+  if (GENERAL_REG_P (op1))
 {
   operands[4] = simplify_gen_subreg (V4SImode, operands[0], mode, 0);
-  emit_insn (gen_sse2_loadld (operands[4],
- CONST0_RTX (V4SImode), operands[1]));
+  if (TARGET_INTER_UNIT_MOVES)
+   emit_insn (gen_sse2_loadld (operands[4],
+   CONST0_RTX (V4SImode), operands[1]));
+  else
+   {
+ operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
+ operands[1]);
+ emit_insn (gen_sse2_loadld (operands[4],
+ CONST0_RTX (V4SImode), operands[5]));
+ ix86_free_from_memory (GET_MODE (operands[1]));
+   }
 }
   /* We can ignore possible trapping value in the
  high part of SSE register for non-trapping math. */


Re: Ping: C-family stack check for threads

2011-07-03 Thread Thomas Klein

Ye Joey wrote:

 Thomas,

 I think your are working on a very useful feature. I have ARM MCU
 applications running of out stack space and resulting strange
 behaviors silently. I'd like to try your patch and probably give
 further comments

 - Joey


Hi
Due to convention of of thumb prologue to rtl, this patch needs to be modified 
too.

Regards
  Thomas Klein

gcc/ChangeLog
2011-07-03  Thomas Klein  

* opts.c (common_handle_option): introduce additional stack checking
parameters "direct" and "indirect"
* flag-types.h (enum stack_check_type): Likewise
* explow.c (allocate_dynamic_stack_space):
- suppress stack probing if parameter "direct", "indirect" or if a
stack-limit is given
- do additional read of limit value if parameter "indirect" and a
stack-limit symbol is given
- emit a call to a stack_failure function [as an alternative to a trap
call]
(function probe_stack_range): if allowed to override the range probe
emit generic_limit_check_stack
* config/arm/arm.c (stack_check_output_function): new function to write
the stack check code sequence to the assember file (inside prologue)
(stack_check_work_registers): new function to find possible working
registers [only used by "stack check"]
(arm_expand_prologue): stack check integration for ARM and Thumb-2
(thumb1_expand_prologue): stack check integration for Thumb-1
* config/arm/arm.md (probe_stack): do not emit code when parameters
"direct" or "indirect" given, emit move code as in gcc/explow.c
[function emit_stack_probe]
(probe_stack_done): dummy to make sure probe_stack insns are not
optimized away
(generic_limit_check_stack): if stack-limit and parameter "generic" is
given use the limit the same way as in function
allocate_dynamic_stack_space
(stack_check): ARM/Thumb-2/Thumb-1 insn to output function
stack_check_output_function
(stack_failure): failure call used in function
allocate_dynamic_stack_space [similar to a trap but avoid conflict with
builtin_trap]

Index: gcc/flag-types.h
===
--- gcc/flag-types.h(revision 175786)
+++ gcc/flag-types.h(working copy)
@@ -153,7 +153,15 @@ enum stack_check_type

   /* Check the stack and entirely rely on the target configuration
  files, i.e. do not use the generic mechanism at all.  */
-  FULL_BUILTIN_STACK_CHECK
+  FULL_BUILTIN_STACK_CHECK,
+
+  /* Check the stack (if possible) before allocation of local variables at
+ each function entry. The stack limit is directly given e.g. by address
+ of a symbol */
+  DIRECT_STACK_CHECK,
+  /* Check the stack (if possible) before allocation of local variables at
+ each function entry. The stack limit is given by global variable. */
+  INDIRECT_STACK_CHECK
 };

 /* Names for the different levels of -Wstrict-overflow=N.  The numeric
Index: gcc/explow.c
===
--- gcc/explow.c(revision 175786)
+++ gcc/explow.c(working copy)
@@ -1358,7 +1358,12 @@ allocate_dynamic_stack_space (rtx size, unsigned s

   /* If needed, check that we have the required amount of stack.  Take into
  account what has already been checked.  */
-  if (STACK_CHECK_MOVING_SP)
+  if (  STACK_CHECK_MOVING_SP
+#ifdef HAVE_generic_limit_check_stack
+ || crtl->limit_stack
+#endif
+ || flag_stack_check == DIRECT_STACK_CHECK
+ || flag_stack_check == INDIRECT_STACK_CHECK)
 ;
   else if (flag_stack_check == GENERIC_STACK_CHECK)
 probe_stack_range (STACK_OLD_CHECK_PROTECT + STACK_CHECK_MAX_FRAME_SIZE,
@@ -1392,19 +1397,32 @@ allocate_dynamic_stack_space (rtx size, unsigned s
   /* Check stack bounds if necessary.  */
   if (crtl->limit_stack)
{
+  rtx limit_rtx;
  rtx available;
  rtx space_available = gen_label_rtx ();
+  if (  GET_CODE (stack_limit_rtx) == SYMBOL_REF
+&&  flag_stack_check == INDIRECT_STACK_CHECK)
+limit_rtx = expand_unop (Pmode, mov_optab,
+   gen_rtx_MEM (Pmode, stack_limit_rtx),
+   NULL_RTX, 1);
+  else
+limit_rtx = stack_limit_rtx;
 #ifdef STACK_GROWS_DOWNWARD
  available = expand_binop (Pmode, sub_optab,
-   stack_pointer_rtx, stack_limit_rtx,
+   stack_pointer_rtx, limit_rtx,
NULL_RTX, 1, OPTAB_WIDEN);
 #else
  available = expand_binop (Pmode, sub_optab,
-   stack_limit_rtx, stack_pointer_rtx,
+   limit_rtx, stack_pointer_rtx,
NULL_RTX, 1, OPTAB_WIDEN);
 #endif
  emit_cmp_and_jump_insns (available, size, GEU, NULL_RTX, Pmode, 1,
   space_available);
+#ifdef HAVE_

Re: Generic hwloop support library

2011-07-03 Thread Steven Bosscher
On Tue, Jun 21, 2011 at 3:37 PM, Bernd Schmidt  wrote:
>
> +static void
> +reorder_loops (loop_info loops)
> +{
> +  basic_block bb;
> +  loop_info loop;
> +
> +  FOR_EACH_BB (bb)
> +bb->aux = NULL;


See clear_aux_for_blocks().

Ciao!
Steven


Re: Ping: C-family stack check for threads

2011-07-03 Thread Richard Henderson
On 07/03/2011 08:06 AM, Thomas Klein wrote:
> +/*
> + * Write prolouge part of stack check into asm file.
> + * For Thumb this may look like this:
> + *   push {rsym,ramn}
> + *   ldr rsym, .LSPCHK0
> + *   ldr rsym, [rsym]
> + *   ldr ramn, .LSPCHK0 + 4
> + *   add rsym, rsym, ramn
> + *   cmp sp, rsym
> + *   bhs .LSPCHK1
> + *   push {lr}
> + *   bl __thumb_stack_failure
> + * .align 2
> + * .LSPCHK0:
> + *   .word symbol_addr_of(stack_limit_rtx)
> + *   .word lenght_of(amount)
> + * .LSPCHK1:
> + *   pop {rsym,ramn}
> + */
> +void
> +stack_check_output_function (FILE *f, int reg0, int reg1, unsigned amount,
> + unsigned numregs)
> +{

Is there an exceedingly good reason you're emitting this much code
as text, rather than as rtl?

In particular, you adjust the stack but not the unwind info.  So
if one puts a breakpoint at your __thumb_stack_failure function,
the unwind information will be incorrect.


r~


[CFT][PATCH 0/6] Move dwarf2 cfi creation to a new pass

2011-07-03 Thread Richard Henderson
Bernd's original patch to optimize dwarf2 cfi for shrink-wrapping
is difficult to analyze because that optimization was done via a
random debugging hook during final, and the cfi notes are deleted
at the end of final so that we don't get debug comparison failures.

By pulling the note creation out to a separate pass, we can dump
the notes and thus debug the optimization.

So far I've tested this only on x86_64-linux.  It needs a bit more
testing across other targets before going in.  Any help that can
be given there would be welcome.

The complete patch set is available at

  git://gcc.gnu.org/git/gcc.git rth/cfi-pass


Thanks,


r~


Richard Henderson (6):
  dwarf2out: Split CFI construction routines into a new file.
  dwarf2out: Move insn scanning out of final.c.
  dwarf2out: Emit NOTE_INSN_CFI_* both with and without cfi-asm.
  dwarf2out: Convert fde_table to a VEC.
  dwarf2: Extract cfi creation to a new pass.
  Dump NOTE_INSN_CFI notes.

 gcc/Makefile.in  |   10 +-
 gcc/ada/gcc-interface/misc.c |   10 -
 gcc/coretypes.h  |   10 +
 gcc/debug.h  |5 +-
 gcc/dwarf2cfi.c  | 2734 
 gcc/dwarf2out.c  | 3171 +++---
 gcc/dwarf2out.h  |  232 +++-
 gcc/final.c  |   59 +-
 gcc/function.h   |6 +
 gcc/gengtype.c   |2 +-
 gcc/insn-notes.def   |8 +
 gcc/lto-streamer-in.c|8 -
 gcc/passes.c |1 +
 gcc/print-rtl.c  |9 +
 gcc/rtl.h|   15 +-
 gcc/toplev.c |5 -
 gcc/tree-pass.h  |1 +
 17 files changed, 3258 insertions(+), 3028 deletions(-)
 create mode 100644 gcc/dwarf2cfi.c

-- 
1.7.5.4



[PATCH 6/6] Dump NOTE_INSN_CFI notes.

2011-07-03 Thread Richard Henderson
---
 gcc/dwarf2out.c |   14 +++---
 gcc/dwarf2out.h |2 ++
 gcc/print-rtl.c |9 +
 3 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 097e57f..2736477 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -822,8 +822,8 @@ output_cfi (dw_cfi_ref cfi, dw_fde_ref fde, int for_eh)
 
 /* Similar, but do it via assembler directives instead.  */
 
-static void
-output_cfi_directive (dw_cfi_ref cfi)
+void
+output_cfi_directive (FILE *asm_out_file, dw_cfi_ref cfi)
 {
   unsigned long r, r2;
 
@@ -925,7 +925,7 @@ void
 dwarf2out_emit_cfi (dw_cfi_ref cfi)
 {
   if (dwarf2out_do_cfi_asm ())
-output_cfi_directive (cfi);
+output_cfi_directive (asm_out_file, cfi);
 }
 
 /* Output CFIs from VEC, up to index UPTO, to bring current FDE to the
@@ -1032,7 +1032,7 @@ output_cfis (cfi_vec vec, int upto, bool do_cfi_asm,
  && cfi2->dw_cfi_opc != DW_CFA_restore_extended)
{
  if (do_cfi_asm)
-   output_cfi_directive (cfi2);
+   output_cfi_directive (asm_out_file, cfi2);
  else
output_cfi (cfi2, fde, for_eh);
}
@@ -1066,7 +1066,7 @@ output_cfis (cfi_vec vec, int upto, bool do_cfi_asm,
  if (cfi_cfa)
{
  if (do_cfi_asm)
-   output_cfi_directive (cfi_cfa);
+   output_cfi_directive (asm_out_file, cfi_cfa);
  else
output_cfi (cfi_cfa, fde, for_eh);
}
@@ -1076,7 +1076,7 @@ output_cfis (cfi_vec vec, int upto, bool do_cfi_asm,
  && cfi_args_size->dw_cfi_oprnd1.dw_cfi_offset)
{
  if (do_cfi_asm)
-   output_cfi_directive (cfi_args_size);
+   output_cfi_directive (asm_out_file, cfi_args_size);
  else
output_cfi (cfi_args_size, fde, for_eh);
}
@@ -1087,7 +1087,7 @@ output_cfis (cfi_vec vec, int upto, bool do_cfi_asm,
  return;
}
  else if (do_cfi_asm)
-   output_cfi_directive (cfi);
+   output_cfi_directive (asm_out_file, cfi);
  else
output_cfi (cfi, fde, for_eh);
  break;
diff --git a/gcc/dwarf2out.h b/gcc/dwarf2out.h
index 7122dee..19bae4a 100644
--- a/gcc/dwarf2out.h
+++ b/gcc/dwarf2out.h
@@ -241,6 +241,8 @@ extern enum dw_cfi_oprnd_type dw_cfi_oprnd1_desc
 extern enum dw_cfi_oprnd_type dw_cfi_oprnd2_desc
   (enum dwarf_call_frame_info cfi);
 
+extern void output_cfi_directive (FILE *f, struct dw_cfi_struct *cfi);
+
 extern void dwarf2out_decl (tree);
 extern void dwarf2out_emit_cfi (dw_cfi_ref cfi);
 
diff --git a/gcc/print-rtl.c b/gcc/print-rtl.c
index c20ff6c..d7fd73b 100644
--- a/gcc/print-rtl.c
+++ b/gcc/print-rtl.c
@@ -43,6 +43,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-pretty-print.h"
 #include "cselib.h"
 #include "tree-pass.h"
+#include "dwarf2out.h"
 #endif
 
 static FILE *outfile;
@@ -309,6 +310,14 @@ print_rtx (const_rtx in_rtx)
 #endif
break;
 
+ case NOTE_INSN_CFI:
+#ifndef GENERATOR_FILE
+   fputc ('\n', outfile);
+   output_cfi_directive (outfile, NOTE_CFI (in_rtx));
+   fputc ('\t', outfile);
+#endif
+   break;
+
  default:
break;
  }
-- 
1.7.5.4



[PATCH 2/6] dwarf2out: Move insn scanning out of final.c.

2011-07-03 Thread Richard Henderson
This patch is essentially Bernd's 005-scanfirst patch, updated for
the introduction of the dwarf2cfi.c file.

We introduce NOTE_INSN_CFI and NOTE_INSN_CFI_LABEL to hold the dwarf2
info during the bulk of final.  The actual construction of these notes
still happens during final, right at the very beginning of the pass,
via the dwarf2out_frame_debug_init hook.
---
 gcc/dwarf2cfi.c|   97 ++-
 gcc/dwarf2out.c|8 -
 gcc/dwarf2out.h|4 +--
 gcc/final.c|   54 +++--
 gcc/insn-notes.def |8 
 gcc/rtl.h  |5 +++
 6 files changed, 121 insertions(+), 55 deletions(-)

diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c
index 8de13e5..3e8958f 100644
--- a/gcc/dwarf2cfi.c
+++ b/gcc/dwarf2cfi.c
@@ -143,6 +143,19 @@ cfi_vec cie_cfi_vec;
 
 static GTY(()) unsigned long dwarf2out_cfi_label_num;
 
+/* The insn after which a new CFI note should be emitted.  */
+static rtx cfi_insn;
+
+/* True if remember_state should be emitted before following CFI directive.  */
+static bool emit_cfa_remember;
+
+/* True if any CFI directives were emitted at the current insn.  */
+static bool any_cfis_emitted;
+
+
+static void dwarf2out_cfi_begin_epilogue (rtx insn);
+static void dwarf2out_frame_debug_restore_state (void);
+
 
 /* Hook used by __throw.  */
 
@@ -292,18 +305,13 @@ dwarf2out_cfi_label (bool force)
 {
   int num = dwarf2out_cfi_label_num++;
   ASM_GENERATE_INTERNAL_LABEL (label, "LCFI", num);
-  ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LCFI", num);
+  cfi_insn = emit_note_after (NOTE_INSN_CFI_LABEL, cfi_insn);
+  NOTE_LABEL_NUMBER (cfi_insn) = num;
 }
 
   return label;
 }
 
-/* True if remember_state should be emitted before following CFI directive.  */
-static bool emit_cfa_remember;
-
-/* True if any CFI directives were emitted at the current insn.  */
-static bool any_cfis_emitted;
-
 /* Add CFI to the current fde at the PC value indicated by LABEL if specified,
or to the CIE if LABEL is NULL.  */
 
@@ -383,7 +391,8 @@ add_fde_cfi (const char *label, dw_cfi_ref cfi)
}
}
 
- output_cfi_directive (cfi);
+ cfi_insn = emit_note_after (NOTE_INSN_CFI, cfi_insn);
+ NOTE_CFI (cfi_insn) = cfi;
 
  vec = &fde->dw_fde_cfi;
  any_cfis_emitted = true;
@@ -2301,6 +2310,9 @@ dwarf2out_frame_debug (rtx insn, bool after_p)
   bool handled_one = false;
   bool need_flush = false;
 
+  /* Remember where we are to insert notes.  */
+  cfi_insn = (after_p ? insn : PREV_INSN (insn));
+
   if (!NONJUMP_INSN_P (insn) || clobbers_queued_reg_save (insn))
 dwarf2out_flush_queued_reg_saves ();
 
@@ -2440,8 +2452,16 @@ dwarf2out_frame_debug (rtx insn, bool after_p)
 void
 dwarf2out_frame_debug_init (void)
 {
-  /* Flush any queued register saves.  */
-  dwarf2out_flush_queued_reg_saves ();
+  rtx insn;
+
+  regs_saved_in_regs = NULL;
+  queued_reg_saves = NULL;
+
+  if (barrier_args_size)
+{
+  XDELETEVEC (barrier_args_size);
+  barrier_args_size = NULL;
+}
 
   /* Set up state for generating call frame debug info.  */
   lookup_cfa (&cfa);
@@ -2453,12 +2473,55 @@ dwarf2out_frame_debug_init (void)
   cfa_temp.reg = -1;
   cfa_temp.offset = 0;
 
-  regs_saved_in_regs = NULL;
-
-  if (barrier_args_size)
+  for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
 {
-  XDELETEVEC (barrier_args_size);
-  barrier_args_size = NULL;
+  rtx pat;
+
+  if (BARRIER_P (insn))
+   {
+ dwarf2out_frame_debug (insn, false);
+ continue;
+}
+
+  if (NOTE_P (insn))
+   {
+ switch (NOTE_KIND (insn))
+   {
+   case NOTE_INSN_EPILOGUE_BEG:
+#if defined(HAVE_epilogue)
+ dwarf2out_cfi_begin_epilogue (insn);
+#endif
+ break;
+   case NOTE_INSN_CFA_RESTORE_STATE:
+ cfi_insn = insn;
+ dwarf2out_frame_debug_restore_state ();
+ break;
+   }
+ continue;
+   }
+
+  if (!NONDEBUG_INSN_P (insn))
+   continue;
+
+  pat = PATTERN (insn);
+  if (asm_noperands (pat) >= 0)
+   {
+ dwarf2out_frame_debug (insn, false);
+ continue;
+   }
+
+  if (GET_CODE (pat) == SEQUENCE)
+   {
+ int i, n = XVECLEN (pat, 0);
+ for (i = 1; i < n; ++i)
+   dwarf2out_frame_debug (XVECEXP (pat, 0, i), false);
+   }
+
+  if (CALL_P (insn)
+ || find_reg_note (insn, REG_CFA_FLUSH_QUEUE, NULL))
+   dwarf2out_frame_debug (insn, false);
+
+  dwarf2out_frame_debug (insn, true);
 }
 }
 
@@ -2467,7 +2530,7 @@ dwarf2out_frame_debug_init (void)
we do need to save/restore, then emit the save now, and insert a
NOTE_INSN_CFA_RESTORE_STATE at the appropriate place in the stream.  */
 
-void
+static void
 dwarf2out_cfi_begin_epilogue (rtx insn)
 {
   bool saw_frp = false;
@@ -2544,7 +2607,7 @@ dwarf2out_cfi_begin_epilogue (rt

[PATCH 5/6] dwarf2: Extract cfi creation to a new pass.

2011-07-03 Thread Richard Henderson
---
 gcc/ada/gcc-interface/misc.c |   10 ---
 gcc/debug.h  |5 +-
 gcc/dwarf2cfi.c  |  161 +-
 gcc/dwarf2out.c  |   11 ++-
 gcc/dwarf2out.h  |4 -
 gcc/final.c  |   10 ---
 gcc/lto-streamer-in.c|8 --
 gcc/passes.c |1 +
 gcc/toplev.c |5 --
 gcc/tree-pass.h  |1 +
 10 files changed, 109 insertions(+), 107 deletions(-)

diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c
index e69668a..bdba7ed 100644
--- a/gcc/ada/gcc-interface/misc.c
+++ b/gcc/ada/gcc-interface/misc.c
@@ -339,11 +339,6 @@ gnat_init (void)
 void
 gnat_init_gcc_eh (void)
 {
-#ifdef DWARF2_UNWIND_INFO
-  /* lang_dependent_init already called dwarf2out_frame_init if true.  */
-  int dwarf2out_frame_initialized = dwarf2out_do_frame ();
-#endif
-
   /* We shouldn't do anything if the No_Exceptions_Handler pragma is set,
  though. This could for instance lead to the emission of tables with
  references to symbols (such as the Ada eh personality routine) within
@@ -370,11 +365,6 @@ gnat_init_gcc_eh (void)
   flag_non_call_exceptions = 1;
 
   init_eh ();
-
-#ifdef DWARF2_UNWIND_INFO
-  if (!dwarf2out_frame_initialized && dwarf2out_do_frame ())
-dwarf2out_frame_init ();
-#endif
 }
 
 /* Print language-specific items in declaration NODE.  */
diff --git a/gcc/debug.h b/gcc/debug.h
index efdffe1..828ede2 100644
--- a/gcc/debug.h
+++ b/gcc/debug.h
@@ -178,12 +178,11 @@ extern void dwarf2out_begin_prologue (unsigned int, const 
char *);
 extern void dwarf2out_vms_end_prologue (unsigned int, const char *);
 extern void dwarf2out_vms_begin_epilogue (unsigned int, const char *);
 extern void dwarf2out_end_epilogue (unsigned int, const char *);
-extern void dwarf2out_frame_init (void);
 extern void dwarf2out_frame_finish (void);
 /* Decide whether we want to emit frame unwind information for the current
translation unit.  */
-extern int dwarf2out_do_frame (void);
-extern int dwarf2out_do_cfi_asm (void);
+extern bool dwarf2out_do_frame (void);
+extern bool dwarf2out_do_cfi_asm (void);
 extern void dwarf2out_switch_text_section (void);
 
 const char *remap_debug_filename (const char *);
diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c
index 3e63299..44655bb 100644
--- a/gcc/dwarf2cfi.c
+++ b/gcc/dwarf2cfi.c
@@ -2173,7 +2173,7 @@ dwarf2out_frame_debug_expr (rtx expr)
If AFTER_P is false, we're being called before the insn is emitted,
otherwise after.  Call instructions get invoked twice.  */
 
-void
+static void
 dwarf2out_frame_debug (rtx insn, bool after_p)
 {
   rtx note, n;
@@ -2318,33 +2318,6 @@ dwarf2out_frame_debug (rtx insn, bool after_p)
   cfi_insn = NULL;
 }
 
-/* Called once at the start of final to initialize some data for the
-   current function.  */
-
-void
-dwarf2out_frame_debug_init (void)
-{
-  regs_saved_in_regs = NULL;
-  queued_reg_saves = NULL;
-
-  if (barrier_args_size)
-{
-  XDELETEVEC (barrier_args_size);
-  barrier_args_size = NULL;
-}
-
-  /* Set up state for generating call frame debug info.  */
-  lookup_cfa (&cfa);
-  gcc_assert (cfa.reg
- == (unsigned long)DWARF_FRAME_REGNUM (STACK_POINTER_REGNUM));
-
-  old_cfa = cfa;
-  cfa.reg = STACK_POINTER_REGNUM;
-  cfa_store = cfa;
-  cfa_temp.reg = -1;
-  cfa_temp.offset = 0;
-}
-
 /* Examine CFI and return true if a cfi label and set_loc is needed
beforehand.  Even when generating CFI assembler instructions, we
still have to add the cfi to the list so that lookup_cfa works
@@ -2440,11 +2413,10 @@ add_cfis_to_fde (void)
 }
 }
 
-/* After the (optional) text prologue has been written, emit CFI insns
-   and update the FDE for frame-related instructions.  */
+/* Scan the function and create the initial set of CFI notes.  */
  
-void
-dwarf2out_frame_debug_after_prologue (void)
+static void
+create_cfi_notes (void)
 {
   rtx insn;
 
@@ -2499,8 +2471,6 @@ dwarf2out_frame_debug_after_prologue (void)
 
   dwarf2out_frame_debug (insn, true);
 }
-
-  add_cfis_to_fde ();
 }
 
 /* Determine if we need to save and restore CFI information around this
@@ -2599,47 +2569,70 @@ dwarf2out_frame_debug_restore_state (void)
   old_cfa = old_cfa_remember;
   cfa_remember.in_use = 0;
 }
+
 
-/* Run once per function.  */
+/* Annotate the function with NOTE_INSN_CFI notes to record the CFI
+   state at each location within the function.  These notes will be
+   emitted during pass_final.  */
 
-void
-dwarf2cfi_function_init (void)
+static unsigned int
+execute_dwarf2_frame (void)
 {
-  args_size = old_args_size = 0;
-}
+  /* The first time we're called, compute the incoming frame state.  */
+  if (cie_cfi_vec == NULL)
+{
+  dw_cfa_location loc;
 
-/* Run once.  */
+  memset(&old_cfa, 0, sizeof (old_cfa));
+  old_cfa.reg = INVALID_REGNUM;
 
-void
-dwarf2out_frame_init (void)
-{
-  dw_cfa_location loc;
+  /* On entry, the Ca

[PATCH 4/6] dwarf2out: Convert fde_table to a VEC.

2011-07-03 Thread Richard Henderson
Prepare for allocating the FDE for the current function earlier
than dwarf2out_begin_prologue.
---
 gcc/dwarf2cfi.c |   16 +++---
 gcc/dwarf2out.c |  172 +--
 gcc/dwarf2out.h |6 +-
 gcc/function.h  |6 ++
 4 files changed, 84 insertions(+), 116 deletions(-)

diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c
index cd22e53..3e63299 100644
--- a/gcc/dwarf2cfi.c
+++ b/gcc/dwarf2cfi.c
@@ -294,7 +294,7 @@ add_fde_cfi (dw_cfi_ref cfi)
 }
   else
 {
-  dw_fde_ref fde = current_fde ();
+  dw_fde_ref fde = cfun->fde;
   VEC_safe_push (dw_cfi_ref, gc, fde->dw_fde_cfi, cfi);
   dwarf2out_emit_cfi (cfi);
 }
@@ -468,7 +468,7 @@ lookup_cfa (dw_cfa_location *loc)
   FOR_EACH_VEC_ELT (dw_cfi_ref, cie_cfi_vec, ix, cfi)
 lookup_cfa_1 (cfi, loc, &remember);
 
-  fde = current_fde ();
+  fde = cfun->fde;
   if (fde)
 FOR_EACH_VEC_ELT (dw_cfi_ref, fde->dw_fde_cfi, ix, cfi)
   lookup_cfa_1 (cfi, loc, &remember);
@@ -599,8 +599,8 @@ static void
 reg_save (bool for_cie, unsigned int reg, unsigned int sreg,
   HOST_WIDE_INT offset)
 {
+  dw_fde_ref fde = for_cie ? NULL : cfun->fde;
   dw_cfi_ref cfi = new_cfi ();
-  dw_fde_ref fde = current_fde ();
 
   cfi->dw_cfi_oprnd1.dw_cfi_reg_num = reg;
 
@@ -1652,7 +1652,7 @@ dwarf2out_frame_debug_cfa_window_save (void)
   Rule 16:
   (set sp (and: sp ))
   constraints: cfa_store.reg == sp
-  effects: current_fde.stack_realign = 1
+  effects: cfun->fde.stack_realign = 1
cfa_store.offset = 0
   fde->drap_reg = cfa.reg if cfa.reg != sp and cfa.reg != fp
 
@@ -1742,7 +1742,7 @@ dwarf2out_frame_debug_expr (rtx expr)
src = rsi;
 }
 
-  fde = current_fde ();
+  fde = cfun->fde;
 
   switch (GET_CODE (dest))
 {
@@ -2268,7 +2268,7 @@ dwarf2out_frame_debug (rtx insn, bool after_p)
n = XEXP (note, 0);
if (REG_P (n))
  {
-   dw_fde_ref fde = current_fde ();
+   dw_fde_ref fde = cfun->fde;
if (fde)
  {
gcc_assert (fde->vdrap_reg == INVALID_REGNUM);
@@ -2387,7 +2387,7 @@ cfi_label_required_p (dw_cfi_ref cfi)
 static void
 add_cfis_to_fde (void)
 {
-  dw_fde_ref fde = current_fde ();
+  dw_fde_ref fde = cfun->fde;
   rtx insn, next;
   /* We always start with a function_begin label.  */
   bool first = false;
@@ -2611,7 +2611,7 @@ dwarf2cfi_function_init (void)
 /* Run once.  */
 
 void
-dwarf2cfi_frame_init (void)
+dwarf2out_frame_init (void)
 {
   dw_cfa_location loc;
 
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index b655a2a..0f93964 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -233,33 +233,12 @@ static GTY(()) section *debug_frame_section;
 #define DWARF_CIE_ID DW_CIE_ID
 #endif
 
-/* A pointer to the base of a table that contains frame description
-   information for each routine.  */
-static GTY((length ("fde_table_allocated"))) dw_fde_ref fde_table;
-
-/* Number of elements currently allocated for fde_table.  */
-static GTY(()) unsigned fde_table_allocated;
-
-/* Number of elements in fde_table currently in use.  */
-static GTY(()) unsigned fde_table_in_use;
-
-/* Size (in elements) of increments by which we may expand the
-   fde_table.  */
-#define FDE_TABLE_INCREMENT 256
-
-/* Get the current fde_table entry we should use.  */
-
-dw_fde_ref
-current_fde (void)
-{
-  return fde_table_in_use ? &fde_table[fde_table_in_use - 1] : NULL;
-}
+DEF_VEC_P (dw_fde_ref);
+DEF_VEC_ALLOC_P (dw_fde_ref, gc);
 
-/* Some DWARF extensions (e.g., MIPS/SGI) implement a subprogram
-   attribute that accelerates the lookup of the FDE associated
-   with the subprogram.  This variable holds the table index of the FDE
-   associated with the current function (body) definition.  */
-static unsigned current_funcdef_fde;
+/* A vector for a table that contains frame description
+   information for each routine.  */
+static GTY(()) VEC(dw_fde_ref, gc) *fde_vec;
 
 struct GTY(()) indirect_string_node {
   const char *str;
@@ -1313,7 +1292,7 @@ output_call_frame_info (int for_eh)
   int dw_cie_version;
 
   /* Don't emit a CIE if there won't be any FDEs.  */
-  if (fde_table_in_use == 0)
+  if (fde_vec == NULL)
 return;
 
   /* Nothing to do if the assembler's doing it all.  */
@@ -1330,14 +1309,15 @@ output_call_frame_info (int for_eh)
 {
   bool any_eh_needed = false;
 
-  for (i = 0; i < fde_table_in_use; i++)
-   if (fde_table[i].uses_eh_lsda)
- any_eh_needed = any_lsda_needed = true;
-   else if (fde_needed_for_eh_p (&fde_table[i]))
- any_eh_needed = true;
-   else if (TARGET_USES_WEAK_UNWIND_INFO)
- targetm.asm_out.emit_unwind_label (asm_out_file, fde_table[i].decl,
-1, 1);
+  FOR_EACH_VEC_ELT (dw_fde_ref, fde_vec, i, fde)
+   {
+ if (fde->uses_eh_lsda)
+   any_eh_needed = any_lsda_needed = true;
+ else if (fde_needed_for_eh_p (fde))
+   any_eh_needed = tru

[PATCH 3/6] dwarf2out: Emit NOTE_INSN_CFI_* both with and without cfi-asm.

2011-07-03 Thread Richard Henderson
This patch is essentially Bernd's 006-cfilabel patch, updated
for all the other changes to dwarf2out.

The patch reduces the difference between the cfi-asm and non-cfi-asm
code paths.  We now emit the CFI notes in all cases.  Later, after we're
done producing the CFI insns we need, another pass over the rtl adds
the necessary labels and set_loc/advance_loc CFIs.  One consequence of
this is that def_cfa_1 can no longer use lookup_cfa, so it just compares
to an old_cfa variable instead.

The major change since Bernd's patch is that all the target-specific
changes are no longer necessary.
---
 gcc/dwarf2cfi.c |  430 ++-
 gcc/dwarf2out.c |7 +-
 gcc/dwarf2out.h |1 +
 gcc/final.c |5 +
 4 files changed, 214 insertions(+), 229 deletions(-)

diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c
index 3e8958f..cd22e53 100644
--- a/gcc/dwarf2cfi.c
+++ b/gcc/dwarf2cfi.c
@@ -257,74 +257,24 @@ new_cfi (void)
   return cfi;
 }
 
-/* Add a Call Frame Instruction to list of instructions.  */
-
-static inline void
-add_cfi (cfi_vec *vec, dw_cfi_ref cfi)
-{
-  dw_fde_ref fde = current_fde ();
-
-  /* When DRAP is used, CFA is defined with an expression.  Redefine
- CFA may lead to a different CFA value.   */
-  /* ??? Of course, this heuristic fails when we're annotating epilogues,
- because of course we'll always want to redefine the CFA back to the
- stack pointer on the way out.  Where should we move this check?  */
-  if (0 && fde && fde->drap_reg != INVALID_REGNUM)
-switch (cfi->dw_cfi_opc)
-  {
-  case DW_CFA_def_cfa_register:
-  case DW_CFA_def_cfa_offset:
-  case DW_CFA_def_cfa_offset_sf:
-  case DW_CFA_def_cfa:
-  case DW_CFA_def_cfa_sf:
-   gcc_unreachable ();
-
-  default:
-   break;
-  }
-
-  VEC_safe_push (dw_cfi_ref, gc, *vec, cfi);
-}
-
-/* Generate a new label for the CFI info to refer to.  FORCE is true
-   if a label needs to be output even when using .cfi_* directives.  */
+/* Generate a new label for the CFI info to refer to.  */
 
 static char *
-dwarf2out_cfi_label (bool force)
+dwarf2out_cfi_label (void)
 {
-  static char label[20];
+  int num = dwarf2out_cfi_label_num++;
+  char label[20];
 
-  if (!force && dwarf2out_do_cfi_asm ())
-{
-  /* In this case, we will be emitting the asm directive instead of
-the label, so just return a placeholder to keep the rest of the
-interfaces happy.  */
-  strcpy (label, "");
-}
-  else
-{
-  int num = dwarf2out_cfi_label_num++;
-  ASM_GENERATE_INTERNAL_LABEL (label, "LCFI", num);
-  cfi_insn = emit_note_after (NOTE_INSN_CFI_LABEL, cfi_insn);
-  NOTE_LABEL_NUMBER (cfi_insn) = num;
-}
+  ASM_GENERATE_INTERNAL_LABEL (label, "LCFI", num);
 
-  return label;
+  return xstrdup (label);
 }
 
-/* Add CFI to the current fde at the PC value indicated by LABEL if specified,
-   or to the CIE if LABEL is NULL.  */
+/* Add CFI to the current fde.  */
 
 static void
-add_fde_cfi (const char *label, dw_cfi_ref cfi)
+add_fde_cfi (dw_cfi_ref cfi)
 {
-  cfi_vec *vec;
-
-  if (cie_cfi_vec == NULL)
-cie_cfi_vec = VEC_alloc (dw_cfi_ref, gc, 20);
-
-  vec = &cie_cfi_vec;
-
   if (emit_cfa_remember)
 {
   dw_cfi_ref cfi_remember;
@@ -333,110 +283,27 @@ add_fde_cfi (const char *label, dw_cfi_ref cfi)
   emit_cfa_remember = false;
   cfi_remember = new_cfi ();
   cfi_remember->dw_cfi_opc = DW_CFA_remember_state;
-  add_fde_cfi (label, cfi_remember);
+  add_fde_cfi (cfi_remember);
 }
 
-  if (dwarf2out_do_cfi_asm ())
+  any_cfis_emitted = true;
+  if (cfi_insn != NULL)
 {
-  if (label)
-   {
- dw_fde_ref fde = current_fde ();
-
- gcc_assert (fde != NULL);
-
- /* We still have to add the cfi to the list so that lookup_cfa
-works later on.  When -g2 and above we even need to force
-emitting of CFI labels and add to list a DW_CFA_set_loc for
-convert_cfa_to_fb_loc_list purposes.  If we're generating
-DWARF3 output we use DW_OP_call_frame_cfa and so don't use
-convert_cfa_to_fb_loc_list.  */
- if (dwarf_version == 2
- && debug_info_level > DINFO_LEVEL_TERSE
- && (write_symbols == DWARF2_DEBUG
- || write_symbols == VMS_AND_DWARF2_DEBUG))
-   {
- switch (cfi->dw_cfi_opc)
-   {
-   case DW_CFA_def_cfa_offset:
-   case DW_CFA_def_cfa_offset_sf:
-   case DW_CFA_def_cfa_register:
-   case DW_CFA_def_cfa:
-   case DW_CFA_def_cfa_sf:
-   case DW_CFA_def_cfa_expression:
-   case DW_CFA_restore_state:
- if (*label == 0 || strcmp (label, "") == 0)
-   label = dwarf2out_cfi_label (true);
-
- if (fde->dw_fde_current_label == NULL
- || strcmp (label, fde->dw_fde_current_label) != 

Re: [patch, fortran] Always return malloc(1) for empty arrays in the library

2011-07-03 Thread Janne Blomqvist
On Fri, Jul 1, 2011 at 21:31, Thomas Koenig  wrote:
> Is this better?

Index: runtime/memory.c
===
--- runtime/memory.c(Revision 175598)
+++ runtime/memory.c(Arbeitskopie)
@@ -54,8 +54,8 @@ get_mem (size_t n)
 void *
 internal_malloc_size (size_t size)
 {
-  if (size == 0)
-return NULL;
+  if (unlikely (size <= 0))
+size = 1;

   return get_mem (size);
 }

Since size_t is unsigned, just test (size == 0).  Otherwise Ok. Thanks
for the patch.




-- 
Janne Blomqvist


[Patch, libfortran] PR 49296 List read of file without EOR

2011-07-03 Thread Janne Blomqvist
Hi,

the attached patch fixes the remaining cases of handling input that
ends in EOF instead of a normal separator for list formatted read of
the primitive types. Ok for trunk and 4.6?

2011-07-04  Janne Blomqvist  

PR libfortran/49296
* io/list_read.c (read_logical): Don't error out if a valid value
is followed by EOF instead of a normal separator.
(read_integer): Likewise.

testsuite:

2011-07-04  Janne Blomqvist  

PR libfortran/49296
* gfortran.dg/read_list_eof_1.f90: Add tests for integer, real,
and logical reads.


-- 
Janne Blomqvist
diff --git a/libgfortran/io/list_read.c b/libgfortran/io/list_read.c
index baf2f54..c88f232 100644
--- a/libgfortran/io/list_read.c
+++ b/libgfortran/io/list_read.c
@@ -657,22 +657,20 @@ read_logical (st_parameter_dt *dtp, int length)
 {
 case 't':
   v = 1;
-  if ((c = next_char (dtp)) == EOF)
-	goto bad_logical;
+  c = next_char (dtp);
   l_push_char (dtp, c);
 
-  if (!is_separator(c))
+  if (!is_separator(c) && c != EOF)
 	goto possible_name;
 
   unget_char (dtp, c);
   break;
 case 'f':
   v = 0;
-  if ((c = next_char (dtp)) == EOF)
-	goto bad_logical;
+  c = next_char (dtp);
   l_push_char (dtp, c);
 
-  if (!is_separator(c))
+  if (!is_separator(c) && c != EOF)
 	goto possible_name;
 
   unget_char (dtp, c);
@@ -837,6 +835,7 @@ read_integer (st_parameter_dt *dtp, int length)
 	  goto repeat;
 
 	CASE_SEPARATORS:	/* Not a repeat count.  */
+	case EOF:
 	  goto done;
 
 	default:
@@ -886,6 +885,7 @@ read_integer (st_parameter_dt *dtp, int length)
 	  break;
 
 	CASE_SEPARATORS:
+	case EOF:
 	  goto done;
 
 	default:
! { dg-do run }
! PR 49296 List formatted read of file without EOR marker (\n).
program read_list_eof_1
  implicit none
  character(len=100) :: s
  integer :: ii
  real :: rr
  logical :: ll

  call genfil ('a')
  open (unit=20, file='read.dat', form='FORMATTED', action='READ', &
   status='OLD')
  read (20, fmt=*) s
  close (20, status='delete')
  if (trim(s) /= "a") then
 call abort ()
  end if

  call genfil ('1')
  open (unit=20, file='read.dat', form='FORMATTED', action='READ', &
   status='OLD')
  read (20, fmt=*) ii
  close (20, status='delete')
  if (ii /= 1) then
 call abort ()
  end if

  call genfil ('1.5')
  open (unit=20, file='read.dat', form='FORMATTED', action='READ', &
   status='OLD')
  read (20, fmt=*) rr
  close (20, status='delete')
  if (rr /= 1.5) then
 call abort ()
  end if

  call genfil ('T')
  open (unit=20, file='read.dat', form='FORMATTED', action='READ', &
   status='OLD')
  read (20, fmt=*) ll
  close (20, status='delete')
  if (.not. ll) then
 call abort ()
  end if

contains
  subroutine genfil(str)
character(len=*), intent(in) :: str
open(10, file='read.dat', form='unformatted', action='write', &
 status='replace', access='stream')
write(10) str
close(10)
  end subroutine genfil
end program read_list_eof_1


Re: objc/objc++: refactor encoding code

2011-07-03 Thread Mike Stump
On Jul 2, 2011, at 11:06 AM, Nicola Pero wrote:
> This patch improves the modularity of the Objective-C Front-End by separating
> out the encoding code into separate objc-encoding.h and objc-encoding.c files.

> Ok to commit ?

Ok.


Re: PATCH: PR target/49600: Bad SSE2 int->float split in i386.md

2011-07-03 Thread H.J. Lu
On Sun, Jul 3, 2011 at 4:27 AM, Uros Bizjak  wrote:
> On Fri, Jul 1, 2011 at 12:50 AM, H.J. Lu  wrote:
>> In one SSE2 int->float split, when TARGET_USE_VECTOR_CONVERTS is true,
>> TARGET_INTER_UNIT_MOVES is false and GENERAL_REG_P (op1) is true. we
>> will get gcc_unreachable.  This patch removes TARGET_INTER_UNIT_MOVES
>> check.  OK for trunk?
>
> This will result in register allocation failure. Operand 0 of
> sse2_loadld pattern has conditional constraint Yi that depends on
> TARGET_INTER_UNIT_MOVES, so we can't blindly generate sse2_loadld
> after reload.  I'm testing attached patch.
>
> BTW: Do you perhaps have a testcase for this problem?

I have a testcase. But it needs a new x86 optimization we are working on it.

> 2011-07-03  Uros Bizjak  
>
>        PR target/49600
>        * config/i386/i386.md (SSE2 int->float split): Push operand 1 in
>        general register to memory for !TARGET_INTER_UNIT_MOVES.
>

I will give it a try.

Thanks.

-- 
H.J.


Re: PATCH: PR target/49600: Bad SSE2 int->float split in i386.md

2011-07-03 Thread H.J. Lu
On Sun, Jul 3, 2011 at 9:27 PM, H.J. Lu  wrote:
> On Sun, Jul 3, 2011 at 4:27 AM, Uros Bizjak  wrote:
>> On Fri, Jul 1, 2011 at 12:50 AM, H.J. Lu  wrote:
>>> In one SSE2 int->float split, when TARGET_USE_VECTOR_CONVERTS is true,
>>> TARGET_INTER_UNIT_MOVES is false and GENERAL_REG_P (op1) is true. we
>>> will get gcc_unreachable.  This patch removes TARGET_INTER_UNIT_MOVES
>>> check.  OK for trunk?
>>
>> This will result in register allocation failure. Operand 0 of

That particular sse2_loadld insn matches:

(insn 49 22 50 5 (set (reg:V4SI 21 xmm0 [83])
(vec_merge:V4SI (vec_duplicate:V4SI (reg/v:SI 1 dx [orig:64
test ] [64]))
(const_vector:V4SI [
(const_int 0 [0])
(const_int 0 [0])
(const_int 0 [0])
(const_int 0 [0])
])
(const_int 1 [0x1]))) x.i:11 1365 {vec_setv4si_0}
 (nil))

>> sse2_loadld pattern has conditional constraint Yi that depends on
>> TARGET_INTER_UNIT_MOVES, so we can't blindly generate sse2_loadld
>> after reload.  I'm testing attached patch.
>>
>> BTW: Do you perhaps have a testcase for this problem?
>
> I have a testcase. But it needs a new x86 optimization we are working on it.
>
>> 2011-07-03  Uros Bizjak  
>>
>>        PR target/49600
>>        * config/i386/i386.md (SSE2 int->float split): Push operand 1 in
>>        general register to memory for !TARGET_INTER_UNIT_MOVES.
>>
>
> I will give it a try.
>

It doesn't work: I still got

x.i: In function \u2018ran\u2019:
x.i:12:2: internal compiler error: in gen_split_2030, at
config/i386/i386.md:5045
Please submit a full bug report,
with preprocessed source if appropriate.
See  for instructions.
make: *** [x.s] Error 1




-- 
H.J.


PATCH [6/n]: Prepare x32: PR rtl-optimization/47449: Don't propagate hard register non-local goto save area

2011-07-03 Thread H.J. Lu
Hi,

RTL-based forward propagation pass shouldn't propagate hard register.
OK for trunk?

Thanks.


H.J.
---
2011-06-14  H.J. Lu  

PR rtl-optimization/47449
* fwprop.c (forward_propagate_subreg): Don't propagate hard
register nor zero/sign extended hard register.

diff --git a/gcc/fwprop.c b/gcc/fwprop.c
index b2fd955..c8009d0 100644
--- a/gcc/fwprop.c
+++ b/gcc/fwprop.c
@@ -1101,6 +1101,7 @@ forward_propagate_subreg (df_ref use, rtx def_insn, rtx 
def_set)
   src = SET_SRC (def_set);
   if (GET_CODE (src) == SUBREG
  && REG_P (SUBREG_REG (src))
+ && REGNO (SUBREG_REG (src)) >= FIRST_PSEUDO_REGISTER
  && GET_MODE (SUBREG_REG (src)) == use_mode
  && subreg_lowpart_p (src)
  && all_uses_available_at (def_insn, use_insn))
@@ -1119,6 +1120,7 @@ forward_propagate_subreg (df_ref use, rtx def_insn, rtx 
def_set)
   if ((GET_CODE (src) == ZERO_EXTEND
   || GET_CODE (src) == SIGN_EXTEND)
  && REG_P (XEXP (src, 0))
+ && REGNO (XEXP (src, 0)) >= FIRST_PSEUDO_REGISTER
  && GET_MODE (XEXP (src, 0)) == use_mode
  && !free_load_extend (src, def_insn)
  && all_uses_available_at (def_insn, use_insn))