diff options
author | amylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-10-15 11:20:02 +0000 |
---|---|---|
committer | amylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-10-15 11:20:02 +0000 |
commit | 4241a7ebdb910b0d2c6556e533fe1c7c7b42b964 (patch) | |
tree | 4bb1946929d0b4f58c34e16f1a365f4985dba9cc /gcc | |
parent | d3909c678e112ec8c4b574932c2c9f273131f107 (diff) | |
download | gcc-4241a7ebdb910b0d2c6556e533fe1c7c7b42b964.tar.gz |
* web.c (union_match_dups): Properly handle OP_INOUT match_dups.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@192453 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/web.c | 27 |
2 files changed, 29 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2c7af2a0735..790c69e485c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2012-10-15 Joern Rennecke <joern.rennecke@embecosm.com> + + * web.c (union_match_dups): Properly handle OP_INOUT match_dups. + 2012-10-15 Eric Botcazou <ebotcazou@adacore.com> * expr.c (expand_expr_real_1) <VIEW_CONVERT_EXPR>: Do not unnecessarily diff --git a/gcc/web.c b/gcc/web.c index 74904d2c350..7b6e8c6208e 100644 --- a/gcc/web.c +++ b/gcc/web.c @@ -96,6 +96,7 @@ union_match_dups (rtx insn, struct web_entry *def_entry, struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn); df_ref *use_link = DF_INSN_INFO_USES (insn_info); df_ref *def_link = DF_INSN_INFO_DEFS (insn_info); + struct web_entry *dup_entry; int i; extract_insn (insn); @@ -107,10 +108,24 @@ union_match_dups (rtx insn, struct web_entry *def_entry, df_ref *ref, *dupref; struct web_entry *entry; - for (dupref = use_link; *dupref; dupref++) + for (dup_entry = use_entry, dupref = use_link; *dupref; dupref++) if (DF_REF_LOC (*dupref) == recog_data.dup_loc[i]) break; + if (*dupref == NULL && type == OP_INOUT) + { + + for (dup_entry = def_entry, dupref = def_link; *dupref; dupref++) + if (DF_REF_LOC (*dupref) == recog_data.dup_loc[i]) + break; + } + /* ??? *DUPREF can still be zero, because when an operand matches + a memory, DF_REF_LOC (use_link[n]) points to the register part + of the address, whereas recog_data.dup_loc[m] points to the + entire memory ref, thus we fail to find the duplicate entry, + even though it is there. + Example: i686-pc-linux-gnu gcc.c-torture/compile/950607-1.c + -O3 -fomit-frame-pointer -funroll-loops */ if (*dupref == NULL || DF_REF_REGNO (*dupref) < FIRST_PSEUDO_REGISTER) continue; @@ -121,7 +136,15 @@ union_match_dups (rtx insn, struct web_entry *def_entry, if (DF_REF_LOC (*ref) == recog_data.operand_loc[op]) break; - (*fun) (use_entry + DF_REF_ID (*dupref), entry + DF_REF_ID (*ref)); + if (!*ref && type == OP_INOUT) + { + for (ref = use_link, entry = use_entry; *ref; ref++) + if (DF_REF_LOC (*ref) == recog_data.operand_loc[op]) + break; + } + + gcc_assert (*ref); + (*fun) (dup_entry + DF_REF_ID (*dupref), entry + DF_REF_ID (*ref)); } } |