diff options
author | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-09-15 22:48:00 +0000 |
---|---|---|
committer | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-09-15 22:48:00 +0000 |
commit | bd405dcfc7c885cada1539e3414e2597c01ec8cf (patch) | |
tree | 53bdda0670a317b7ee0c5d54eced29a316056e18 | |
parent | ebd7c4c16a68a086b62f6d7af7654e5937784d72 (diff) | |
download | gcc-bd405dcfc7c885cada1539e3414e2597c01ec8cf.tar.gz |
PR rtl-optimization/45593
* reorg.c (relax_delay_slots): Use emit_copy_of_insn_after to re-emit
insns that were in delay slots as stand-alone insns.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@164318 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/reorg.c | 38 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/20100915-1.c | 82 |
4 files changed, 112 insertions, 18 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 178b31dbb52..184894a0b91 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2010-09-15 Eric Botcazou <ebotcazou@adacore.com> + + PR rtl-optimization/45593 + * reorg.c (relax_delay_slots): Use emit_copy_of_insn_after to re-emit + insns that were in delay slots as stand-alone insns. + 2010-09-15 Ian Lance Taylor <iant@google.com> * incpath.c (remove_duplicates): If name is not a directory, issue diff --git a/gcc/reorg.c b/gcc/reorg.c index ec13bcc470e..7776fa20c7e 100644 --- a/gcc/reorg.c +++ b/gcc/reorg.c @@ -3459,9 +3459,13 @@ relax_delay_slots (rtx first) We do this by deleting the INSN containing the SEQUENCE, then re-emitting the insns separately, and then deleting the RETURN. This allows the count of the jump target to be properly - decremented. */ + decremented. - /* Clear the from target bit, since these insns are no longer + Note that we need to change the INSN_UID of the re-emitted insns + since it is used to hash the insns for mark_target_live_regs and + the re-emitted insns will no longer be wrapped up in a SEQUENCE. + + Clear the from target bit, since these insns are no longer in delay slots. */ for (i = 0; i < XVECLEN (pat, 0); i++) INSN_FROM_TARGET_P (XVECEXP (pat, 0, i)) = 0; @@ -3469,13 +3473,10 @@ relax_delay_slots (rtx first) trial = PREV_INSN (insn); delete_related_insns (insn); gcc_assert (GET_CODE (pat) == SEQUENCE); - after = trial; - for (i = 0; i < XVECLEN (pat, 0); i++) - { - rtx this_insn = XVECEXP (pat, 0, i); - add_insn_after (this_insn, after, NULL); - after = this_insn; - } + add_insn_after (delay_insn, trial, NULL); + after = delay_insn; + for (i = 1; i < XVECLEN (pat, 0); i++) + after = emit_copy_of_insn_after (XVECEXP (pat, 0, i), after); delete_scheduled_jump (delay_insn); continue; } @@ -3580,9 +3581,13 @@ relax_delay_slots (rtx first) We do this by deleting the INSN containing the SEQUENCE, then re-emitting the insns separately, and then deleting the jump. This allows the count of the jump target to be properly - decremented. */ + decremented. - /* Clear the from target bit, since these insns are no longer + Note that we need to change the INSN_UID of the re-emitted insns + since it is used to hash the insns for mark_target_live_regs and + the re-emitted insns will no longer be wrapped up in a SEQUENCE. + + Clear the from target bit, since these insns are no longer in delay slots. */ for (i = 0; i < XVECLEN (pat, 0); i++) INSN_FROM_TARGET_P (XVECEXP (pat, 0, i)) = 0; @@ -3590,13 +3595,10 @@ relax_delay_slots (rtx first) trial = PREV_INSN (insn); delete_related_insns (insn); gcc_assert (GET_CODE (pat) == SEQUENCE); - after = trial; - for (i = 0; i < XVECLEN (pat, 0); i++) - { - rtx this_insn = XVECEXP (pat, 0, i); - add_insn_after (this_insn, after, NULL); - after = this_insn; - } + add_insn_after (delay_insn, trial, NULL); + after = delay_insn; + for (i = 1; i < XVECLEN (pat, 0); i++) + after = emit_copy_of_insn_after (XVECEXP (pat, 0, i), after); delete_scheduled_jump (delay_insn); continue; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d03b01751e9..b1f87446da0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2010-09-15 Eric Botcazou <ebotcazou@adacore.com> + + * gcc.c-torture/compile/20100915-1.c: New test. + 2010-09-15 Martin Jambor <mjambor@suse.cz> PR middle-end/45644 diff --git a/gcc/testsuite/gcc.c-torture/compile/20100915-1.c b/gcc/testsuite/gcc.c-torture/compile/20100915-1.c new file mode 100644 index 00000000000..04f6ab0fd70 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/20100915-1.c @@ -0,0 +1,82 @@ +/* PR rtl-optimization/45593 */ +/* Testcase by Arnaud Lacombe <lacombar@gmail.com> */ + +typedef unsigned int __u32; +typedef __u32 __be32; +static inline __attribute__((always_inline)) int __attribute__((__cold__)) printk(const char *s, ...) { return 0; } +typedef struct journal_s journal_t; +typedef struct journal_header_s +{ + __be32 h_magic; + __be32 h_blocktype; + __be32 h_sequence; +} journal_header_t; +typedef struct journal_superblock_s +{ + journal_header_t s_header; + __be32 s_blocksize; + __be32 s_maxlen; +} journal_superblock_t; +struct journal_s +{ + struct buffer_head *j_sb_buffer; + journal_superblock_t *j_superblock; + int j_format_version; + int j_blocksize; + unsigned int j_maxlen; +}; +static void journal_fail_superblock (journal_t *journal) +{ + journal->j_sb_buffer = ((void *)0); +} +static int journal_get_superblock(journal_t *journal) +{ + struct buffer_head *bh; + journal_superblock_t *sb; + int err = -100; + bh = journal->j_sb_buffer; + if (!buffer_uptodate(bh)) { + if (!buffer_uptodate(bh)) { + printk ("JBD: IO error reading journal superblock\n"); + goto out; + } + } + err = -101; + if (sb->s_header.h_magic != (( __be32)(__u32)(0)) || + sb->s_blocksize != (( __be32)(__u32)(journal->j_blocksize))) { + printk("JBD: no valid journal superblock found\n"); + goto out; + } + switch((( __u32)(__be32)(sb->s_header.h_blocktype))) { + case 0: + case 1: + break; + default: + goto out; + } + if ((( __u32)(__be32)(sb->s_maxlen)) < journal->j_maxlen) + journal->j_maxlen = (( __u32)(__be32)(sb->s_maxlen)); + else if ((( __u32)(__be32)(sb->s_maxlen)) > journal->j_maxlen) { + printk ("JBD: journal file too short\n"); + goto out; + } + return 0; +out: + journal_fail_superblock(journal); + return err; +} +static int load_superblock(journal_t *journal) +{ + journal_get_superblock(journal); + return 0; +} +int jbd2_journal_update_format (journal_t *journal) +{ + journal_get_superblock(journal); + return 0; +} +int jbd2_journal_wipe(journal_t *journal, int write) +{ + load_superblock(journal); + return 0; +} |