[backport gcc-4.9/trunk r201326 ] List-Archive: Date: Thu, 27 Jun 2013 17:02:49 +0800 Subject: [PATCH] Fix pr57637 From: Zhenqiang Chen Hi, Shrink-wrap optimization sinks some instructions for more opportunities. It uses DF_LR_BB_INFO (bb)->def to check whether BB clobbers SRC. But for ARM, gcc might generate cond_exec insns before shrink-wrapping. And DF_LR_BB_INFO (bb)->def does not include def info from cond_exec insns. So the check in function move_insn_for_shrink_wrap is not enough. The patch is to add more check bases on DF_LIVE_BB_INFO (bb)->gen if df-live is available. Bootstrap and no make check regression on x86-64 and Panda board. Is is OK for trunk? Thanks! -Zhenqiang gcc/ 2013-07-30 Zhenqiang Chen PR rtl-optimization/57637 * function.c (move_insn_for_shrink_wrap): Also check the GEN set of the LIVE problem for the liveness analysis if it exists, otherwise give up. gcc/testsuite/ 2013-07-30 Zhenqiang Chen * gcc.target/arm/pr57637.c: New testcase. --- gcc-4.8.1/gcc/function.c.~1~ 2013-03-09 08:54:02.000000000 +0100 +++ gcc-4.8.1/gcc/function.c 2013-08-03 12:18:32.748263638 +0200 @@ -5509,22 +5509,45 @@ move_insn_for_shrink_wrap (basic_block b except for any part that overlaps SRC (next loop). */ bb_uses = &DF_LR_BB_INFO (bb)->use; bb_defs = &DF_LR_BB_INFO (bb)->def; - for (i = dregno; i < end_dregno; i++) + if (df_live) { - if (REGNO_REG_SET_P (bb_uses, i) || REGNO_REG_SET_P (bb_defs, i)) - next_block = NULL; - CLEAR_REGNO_REG_SET (live_out, i); - CLEAR_REGNO_REG_SET (live_in, i); - } + for (i = dregno; i < end_dregno; i++) + { + if (REGNO_REG_SET_P (bb_uses, i) || REGNO_REG_SET_P (bb_defs, i) + || REGNO_REG_SET_P (&DF_LIVE_BB_INFO (bb)->gen, i)) + next_block = NULL; + CLEAR_REGNO_REG_SET (live_out, i); + CLEAR_REGNO_REG_SET (live_in, i); + } - /* Check whether BB clobbers SRC. We need to add INSN to BB if so. - Either way, SRC is now live on entry. */ - for (i = sregno; i < end_sregno; i++) + /* Check whether BB clobbers SRC. We need to add INSN to BB if so. + Either way, SRC is now live on entry. */ + for (i = sregno; i < end_sregno; i++) + { + if (REGNO_REG_SET_P (bb_defs, i) + || REGNO_REG_SET_P (&DF_LIVE_BB_INFO (bb)->gen, i)) + next_block = NULL; + SET_REGNO_REG_SET (live_out, i); + SET_REGNO_REG_SET (live_in, i); + } + } + else { - if (REGNO_REG_SET_P (bb_defs, i)) - next_block = NULL; - SET_REGNO_REG_SET (live_out, i); - SET_REGNO_REG_SET (live_in, i); + /* DF_LR_BB_INFO (bb)->def does not comprise the DF_REF_PARTIAL and + DF_REF_CONDITIONAL defs. So if DF_LIVE doesn't exist, i.e. + at -O1, just give up searching NEXT_BLOCK. */ + next_block = NULL; + for (i = dregno; i < end_dregno; i++) + { + CLEAR_REGNO_REG_SET (live_out, i); + CLEAR_REGNO_REG_SET (live_in, i); + } + + for (i = sregno; i < end_sregno; i++) + { + SET_REGNO_REG_SET (live_out, i); + SET_REGNO_REG_SET (live_in, i); + } } /* If we don't need to add the move to BB, look for a single --- gcc-4.8.1/gcc/testsuite/gcc.target/arm/pr57637.c.~1~ 1970-01-01 01:00:00.000000000 +0100 +++ gcc-4.8.1/gcc/testsuite/gcc.target/arm/pr57637.c 2013-08-03 12:18:32.748263638 +0200 @@ -0,0 +1,206 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fno-inline" } */ + +typedef struct _GtkCssStyleProperty GtkCssStyleProperty; + +struct _GtkCssStyleProperty +{ + int *initial_value; + unsigned int id; + unsigned int inherit :1; + unsigned int animated :1; + unsigned int affects_size :1; + unsigned int affects_font :1; + + int * parse_value; + int * query_value; + int * assign_value; +}; + +void +g_assertion_message_expr (const char *domain, + const char *file, + int line, + const char *func, + const char *expr) __attribute__((__noreturn__)); + +void +g_assertion_message_expr (const char *domain, + const char *file, + int line, + const char *func, + const char *expr) +{ + __builtin_abort (); +} +int +get_id (GtkCssStyleProperty *property) +{ + return 1; +} +int +_gtk_css_style_property_get_type () +{ + return 1; +} + +GtkCssStyleProperty * +g_object_new (int object_type, + const char *first_property_name, + ...) +{ + return (GtkCssStyleProperty *) __builtin_malloc (sizeof (GtkCssStyleProperty)); +} + +typedef enum { + INHERIT = (1 << 0), + ANIMATED = (1 << 1), + RESIZE = (1 << 2), + FONT = (1 << 3) +} GtkStylePropertyFlags; + +int t = 0; +void +gtk_css_style_property_register (const char * name, + int expected_id, + int value_type, + int flags, + int *parse_value, + int *query_value, + int *assign_value, + int *initial_value) +{ + GtkCssStyleProperty *node; + + do + { + if (__builtin_expect (__extension__ ( + { + int _g_boolean_var_; + if (initial_value != ((void *)0)) + _g_boolean_var_ = 1; + else + _g_boolean_var_ = 0; + _g_boolean_var_; + }), + 1)) + ; + else + g_assertion_message_expr ("Gtk", + "gtkcssstylepropertyimpl.c", + 85, + ((const char*) (__PRETTY_FUNCTION__)), + "initial_value != NULL"); + } while (0); + + do + { + if (__builtin_expect (__extension__ ( + { + int _g_boolean_var_; + if (parse_value != ((void *)0)) + _g_boolean_var_ = 1; + else + _g_boolean_var_ = 0; + _g_boolean_var_; + }), + 1)) + ; + else + g_assertion_message_expr ("Gtk", + "gtkcssstylepropertyimpl.c", + 86, + ((const char*) (__PRETTY_FUNCTION__)), + "parse_value != NULL"); + } while (0); + + do + { + if (__builtin_expect (__extension__ ( + { + int _g_boolean_var_; + if (value_type == ((int) ((1) << (2))) + || query_value != ((void *)0)) + _g_boolean_var_ = 1; + else + _g_boolean_var_ = 0; + _g_boolean_var_; + }), + 1)) + ; + else + g_assertion_message_expr ("Gtk", + "gtkcssstylepropertyimpl.c", + 87, ((const char*) (__PRETTY_FUNCTION__)), + "value_type == NONE || query_value != NULL"); + } while (0); + + /* FLAGS is changed in a cond_exec instruction with pr57637. */ + if (flags == 15) + t = 15; + + do + { + if (__builtin_expect (__extension__ ( + { + int _g_boolean_var_; + if (value_type == ((1) << (2)) + || assign_value != ((void *)0)) + _g_boolean_var_ = 1; + else + _g_boolean_var_ = 0; + _g_boolean_var_; + }), + 1)) + ; + else + g_assertion_message_expr ("Gtk", + "gtkcssstylepropertyimpl.c", + 88, ((const char*) (__PRETTY_FUNCTION__)), + "value_type == NONE || assign_value != NULL"); + } while (0); + + node = g_object_new ((_gtk_css_style_property_get_type ()), + "value-type", value_type, + "affects-size", (flags & RESIZE) ? (0) : (!(0)), + "affects-font", (flags & FONT) ? (!(0)) : (0), + "animated", (flags & ANIMATED) ? (!(0)) : (0), + "inherit", (flags & INHERIT) ? (!(0)) : (0), + "initial-value", initial_value, + "name", name, + ((void *)0)); + + node->parse_value = parse_value; + node->query_value = query_value; + node->assign_value = assign_value; + + do + { + if (__builtin_expect (__extension__ ( + { + int _g_boolean_var_; + if (get_id (node) == expected_id) + _g_boolean_var_ = 1; + else + _g_boolean_var_ = 0; + _g_boolean_var_; + }), + 1)) + ; + else + g_assertion_message_expr ("Gtk", + "gtkcssstylepropertyimpl.c", + 106, + ((const char*) (__PRETTY_FUNCTION__)), + "get_id (node) == expected_id"); + } while (0); +} + +int main () +{ + gtk_css_style_property_register ("test", 1, 4, 15, &t, &t, &t, &t); + + if (t != 15) + __builtin_abort (); + return 0; +}