aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorGeorg-Johann Lay <avr@gjlay.de>2015-03-03 11:25:04 +0000
committerGeorg-Johann Lay <gjl@gcc.gnu.org>2015-03-03 11:25:04 +0000
commit2b4293a3907cce6e9aced9884300227c2def337c (patch)
treec535a224fe287ccd0858abd076395d0a288e0c75 /gcc
parent3882207695588de867178df85b1e2511ccd7fb26 (diff)
downloadgcc-2b4293a3907cce6e9aced9884300227c2def337c.zip
gcc-2b4293a3907cce6e9aced9884300227c2def337c.tar.gz
gcc-2b4293a3907cce6e9aced9884300227c2def337c.tar.bz2
re PR target/64331 (regcprop propagates registers noted as REG_DEAD)
gcc/ PR target/64331 * config/avr/avr.c (context.h, tree-pass.h): Include them. (avr_pass_data_recompute_notes): New static variable. (avr_pass_recompute_notes): New class. (avr_register_passes): New static function. (avr_option_override): Call it. gcc/testsuite/ PR target/64331 * gcc.target/avr/torture/pr64331.c: New test. From-SVN: r221143
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/config/avr/avr.c56
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/avr/torture/pr64331.c37
4 files changed, 107 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index aeeda83..9eef774 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,14 @@
2015-03-03 Georg-Johann Lay <avr@gjlay.de>
+ PR target/64331
+ * config/avr/avr.c (context.h, tree-pass.h): Include them.
+ (avr_pass_data_recompute_notes): New static variable.
+ (avr_pass_recompute_notes): New class.
+ (avr_register_passes): New static function.
+ (avr_option_override): Call it.
+
+2015-03-03 Georg-Johann Lay <avr@gjlay.de>
+
Fix various problems with specs file generation.
PR target/65296
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 07d7baf..827b280 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -81,6 +81,8 @@
#include "basic-block.h"
#include "df.h"
#include "builtins.h"
+#include "context.h"
+#include "tree-pass.h"
/* Maximal allowed offset for an address in the LD command */
#define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE))
@@ -329,6 +331,55 @@ avr_to_int_mode (rtx x)
}
+static const pass_data avr_pass_data_recompute_notes =
+{
+ RTL_PASS, // type
+ "", // name (will be patched)
+ OPTGROUP_NONE, // optinfo_flags
+ TV_DF_SCAN, // tv_id
+ 0, // properties_required
+ 0, // properties_provided
+ 0, // properties_destroyed
+ 0, // todo_flags_start
+ TODO_df_finish | TODO_df_verify // todo_flags_finish
+};
+
+
+class avr_pass_recompute_notes : public rtl_opt_pass
+{
+public:
+ avr_pass_recompute_notes (gcc::context *ctxt, const char *name)
+ : rtl_opt_pass (avr_pass_data_recompute_notes, ctxt)
+ {
+ this->name = name;
+ }
+
+ virtual unsigned int execute (function*)
+ {
+ df_note_add_problem ();
+ df_analyze ();
+
+ return 0;
+ }
+}; // avr_pass_recompute_notes
+
+
+static void
+avr_register_passes (void)
+{
+ /* This avr-specific pass (re)computes insn notes, in particular REG_DEAD
+ notes which are used by `avr.c::reg_unused_after' and branch offset
+ computations. These notes must be correct, i.e. there must be no
+ dangling REG_DEAD notes; otherwise wrong code might result, cf. PR64331.
+
+ DF needs (correct) CFG, hence right before free_cfg is the last
+ opportunity to rectify notes. */
+
+ register_pass (new avr_pass_recompute_notes (g, "avr-notes-free-cfg"),
+ PASS_POS_INSERT_BEFORE, "*free_cfg", 1);
+}
+
+
/* Implement `TARGET_OPTION_OVERRIDE'. */
static void
@@ -411,6 +462,11 @@ avr_option_override (void)
init_machine_status = avr_init_machine_status;
avr_log_set_avr_log();
+
+ /* Register some avr-specific pass(es). There is no canonical place for
+ pass registration. This function is convenient. */
+
+ avr_register_passes ();
}
/* Function to set up the backend function structure. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2b3cf0e..ecc4cc4 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2015-03-03 Georg-Johann Lay <avr@gjlay.de>
+
+ PR target/64331
+ * gcc.target/avr/torture/pr64331.c: New test.
+
2015-03-03 Martin Liska <mliska@suse.cz>
Jan Hubicka <hubicka@ucw.cz>
diff --git a/gcc/testsuite/gcc.target/avr/torture/pr64331.c b/gcc/testsuite/gcc.target/avr/torture/pr64331.c
new file mode 100644
index 0000000..1934ccf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/avr/torture/pr64331.c
@@ -0,0 +1,37 @@
+/* { dg-do run } */
+
+typedef struct
+{
+ unsigned a, b;
+} T2;
+
+
+__attribute__((__noinline__, __noclone__))
+void foo2 (T2 *t, int x)
+{
+ if (x != t->a)
+ {
+ t->a = x;
+
+ if (x && x == t->b)
+ t->a = 20;
+ }
+}
+
+
+T2 t;
+
+int main (void)
+{
+ t.a = 1;
+ t.b = 1234;
+
+ foo2 (&t, 1234);
+
+ if (t.a != 20)
+ __builtin_abort();
+
+ __builtin_exit (0);
+
+ return 0;
+}