Patchwork Fix constant folding of SWTCH statements

login
register
mail settings
Submitter Jan Hubicka
Date Sept. 3, 2010, 11:34 p.m.
Message ID <20100903233447.GR1664@kam.mff.cuni.cz>
Download mbox | patch
Permalink /patch/63734/
State New
Headers show

Comments

Jan Hubicka - Sept. 3, 2010, 11:34 p.m.
Hi,
the following testcase from testsuite fails to get switch value folded
to constant before it reach cfgexpand.  The problem is twofold.  First
we require ctor to have TREE_STATIC (for some reason) that is not set by
tree-switch-conversion.c. Secondly we screw up for variables introduced
late because we do not compute varpool_decide_const_value_known.

Fixed thus,
Bootstrapped/regtested x86_64-linux, OK?
Honza
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized" } */
void bar (unsigned int);

void
foo (void)
{
  char buf[1] = { 3 };
  const char *p = buf;
  const char **q = &p;
  unsigned int ch;
  switch (**q)
    {
    case 1:  ch = 5; break;
    case 2:  ch = 4; break;
    case 3:  ch = 3; break;
    case 4:  ch = 2; break;
    case 5:  ch = 1; break;
    default: ch = 0; break;
    }
  bar (ch);
}
/* The switch should be switch converted and later constant propagated.  */
/* { dg-final { scan-tree-dump-not "CSWTCH.1.2" "optimized"} } */

	* tree-switch-conversion.c (build_one_array): Set ctor static flag.
	* varpool.c (varpool_finalize_decl): Set const_value_known.
Richard Guenther - Sept. 4, 2010, 8:32 a.m.
On Sat, 4 Sep 2010, Jan Hubicka wrote:

> Hi,
> the following testcase from testsuite fails to get switch value folded
> to constant before it reach cfgexpand.  The problem is twofold.  First
> we require ctor to have TREE_STATIC (for some reason) that is not set by
> tree-switch-conversion.c. Secondly we screw up for variables introduced
> late because we do not compute varpool_decide_const_value_known.
> 
> Fixed thus,
> Bootstrapped/regtested x86_64-linux, OK?

Ok.

Thanks,
Richard.

> Honza
> /* { dg-do compile } */
> /* { dg-options "-O2 -fdump-tree-optimized" } */
> void bar (unsigned int);
> 
> void
> foo (void)
> {
>   char buf[1] = { 3 };
>   const char *p = buf;
>   const char **q = &p;
>   unsigned int ch;
>   switch (**q)
>     {
>     case 1:  ch = 5; break;
>     case 2:  ch = 4; break;
>     case 3:  ch = 3; break;
>     case 4:  ch = 2; break;
>     case 5:  ch = 1; break;
>     default: ch = 0; break;
>     }
>   bar (ch);
> }
> /* The switch should be switch converted and later constant propagated.  */
> /* { dg-final { scan-tree-dump-not "CSWTCH.1.2" "optimized"} } */
> 
> 	* tree-switch-conversion.c (build_one_array): Set ctor static flag.
> 	* varpool.c (varpool_finalize_decl): Set const_value_known.
> Index: tree-switch-conversion.c
> ===================================================================
> --- tree-switch-conversion.c	(revision 163808)
> +++ tree-switch-conversion.c	(working copy)
> @@ -518,6 +518,7 @@ build_one_array (gimple swtch, int num, 
>        array_type = build_array_type (value_type, arr_index_type);
>        ctor = build_constructor (array_type, info.constructors[num]);
>        TREE_CONSTANT (ctor) = true;
> +      TREE_STATIC (ctor) = true;
>  
>        decl = build_decl (loc, VAR_DECL, NULL_TREE, array_type);
>        TREE_STATIC (decl) = 1;
> Index: varpool.c
> ===================================================================
> --- varpool.c	(revision 163808)
> +++ varpool.c	(working copy)
> @@ -423,6 +423,7 @@ varpool_finalize_decl (tree decl)
>       there.  */
>    else if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
>      varpool_mark_needed_node (node);
> +  node->const_value_known |= varpool_decide_const_value_known (node);
>    if (cgraph_global_info_ready)
>      varpool_assemble_pending_decls ();
>  }
> 
>

Patch

Index: tree-switch-conversion.c
===================================================================
--- tree-switch-conversion.c	(revision 163808)
+++ tree-switch-conversion.c	(working copy)
@@ -518,6 +518,7 @@  build_one_array (gimple swtch, int num, 
       array_type = build_array_type (value_type, arr_index_type);
       ctor = build_constructor (array_type, info.constructors[num]);
       TREE_CONSTANT (ctor) = true;
+      TREE_STATIC (ctor) = true;
 
       decl = build_decl (loc, VAR_DECL, NULL_TREE, array_type);
       TREE_STATIC (decl) = 1;
Index: varpool.c
===================================================================
--- varpool.c	(revision 163808)
+++ varpool.c	(working copy)
@@ -423,6 +423,7 @@  varpool_finalize_decl (tree decl)
      there.  */
   else if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
     varpool_mark_needed_node (node);
+  node->const_value_known |= varpool_decide_const_value_known (node);
   if (cgraph_global_info_ready)
     varpool_assemble_pending_decls ();
 }