Commit 9fa07b13 by Eric Botcazou Committed by Eric Botcazou

re PR rtl-optimization/45593 (segfault with -Os)

	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.

From-SVN: r164318
parent 06730c5d
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> 2010-09-15 Ian Lance Taylor <iant@google.com>
* incpath.c (remove_duplicates): If name is not a directory, issue * incpath.c (remove_duplicates): If name is not a directory, issue
......
...@@ -3459,9 +3459,13 @@ relax_delay_slots (rtx first) ...@@ -3459,9 +3459,13 @@ relax_delay_slots (rtx first)
We do this by deleting the INSN containing the SEQUENCE, then We do this by deleting the INSN containing the SEQUENCE, then
re-emitting the insns separately, and then deleting the RETURN. re-emitting the insns separately, and then deleting the RETURN.
This allows the count of the jump target to be properly 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. */ in delay slots. */
for (i = 0; i < XVECLEN (pat, 0); i++) for (i = 0; i < XVECLEN (pat, 0); i++)
INSN_FROM_TARGET_P (XVECEXP (pat, 0, i)) = 0; INSN_FROM_TARGET_P (XVECEXP (pat, 0, i)) = 0;
...@@ -3469,13 +3473,10 @@ relax_delay_slots (rtx first) ...@@ -3469,13 +3473,10 @@ relax_delay_slots (rtx first)
trial = PREV_INSN (insn); trial = PREV_INSN (insn);
delete_related_insns (insn); delete_related_insns (insn);
gcc_assert (GET_CODE (pat) == SEQUENCE); gcc_assert (GET_CODE (pat) == SEQUENCE);
after = trial; add_insn_after (delay_insn, trial, NULL);
for (i = 0; i < XVECLEN (pat, 0); i++) after = delay_insn;
{ for (i = 1; i < XVECLEN (pat, 0); i++)
rtx this_insn = XVECEXP (pat, 0, i); after = emit_copy_of_insn_after (XVECEXP (pat, 0, i), after);
add_insn_after (this_insn, after, NULL);
after = this_insn;
}
delete_scheduled_jump (delay_insn); delete_scheduled_jump (delay_insn);
continue; continue;
} }
...@@ -3580,9 +3581,13 @@ relax_delay_slots (rtx first) ...@@ -3580,9 +3581,13 @@ relax_delay_slots (rtx first)
We do this by deleting the INSN containing the SEQUENCE, then We do this by deleting the INSN containing the SEQUENCE, then
re-emitting the insns separately, and then deleting the jump. re-emitting the insns separately, and then deleting the jump.
This allows the count of the jump target to be properly 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. */ in delay slots. */
for (i = 0; i < XVECLEN (pat, 0); i++) for (i = 0; i < XVECLEN (pat, 0); i++)
INSN_FROM_TARGET_P (XVECEXP (pat, 0, i)) = 0; INSN_FROM_TARGET_P (XVECEXP (pat, 0, i)) = 0;
...@@ -3590,13 +3595,10 @@ relax_delay_slots (rtx first) ...@@ -3590,13 +3595,10 @@ relax_delay_slots (rtx first)
trial = PREV_INSN (insn); trial = PREV_INSN (insn);
delete_related_insns (insn); delete_related_insns (insn);
gcc_assert (GET_CODE (pat) == SEQUENCE); gcc_assert (GET_CODE (pat) == SEQUENCE);
after = trial; add_insn_after (delay_insn, trial, NULL);
for (i = 0; i < XVECLEN (pat, 0); i++) after = delay_insn;
{ for (i = 1; i < XVECLEN (pat, 0); i++)
rtx this_insn = XVECEXP (pat, 0, i); after = emit_copy_of_insn_after (XVECEXP (pat, 0, i), after);
add_insn_after (this_insn, after, NULL);
after = this_insn;
}
delete_scheduled_jump (delay_insn); delete_scheduled_jump (delay_insn);
continue; continue;
} }
......
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> 2010-09-15 Martin Jambor <mjambor@suse.cz>
PR middle-end/45644 PR middle-end/45644
......
/* 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment