static void process_uses (df_ref use, int top_flag) { for (; use; use = DF_REF_NEXT_LOC (use)) if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == top_flag) { unsigned int uregno = DF_REF_REGNO (use); if (reg_defs[uregno] && !bitmap_bit_p (local_md, uregno) && bitmap_bit_p (local_lr, uregno)) use_def_ref[DF_REF_ID (use)] = reg_defs[uregno]; } }
static void process_defs (df_ref def, int top_flag) { for (; def; def = DF_REF_NEXT_LOC (def)) { df_ref curr_def = reg_defs[DF_REF_REGNO (def)]; unsigned int dregno; if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) != top_flag) continue; dregno = DF_REF_REGNO (def); if (curr_def) reg_defs_stack.safe_push (curr_def); else { /* Do not store anything if "transitioning" from NULL to NULL. But otherwise, push a special entry on the stack to tell the leave_block callback that the entry in reg_defs was NULL. */ if (DF_REF_FLAGS (def) & DF_MD_GEN_FLAGS) ; else reg_defs_stack.safe_push (def); } if (DF_REF_FLAGS (def) & DF_MD_GEN_FLAGS) { bitmap_set_bit (local_md, dregno); reg_defs[dregno] = NULL; } else { bitmap_clear_bit (local_md, dregno); reg_defs[dregno] = def; } } }
static void union_match_dups (rtx insn, struct web_entry *def_entry, struct web_entry *use_entry, bool (*fun) (struct web_entry *, struct web_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); for (i = 0; i < recog_data.n_dups; i++) { int op = recog_data.dup_num[i]; enum op_type type = recog_data.operand_type[op]; df_ref ref, dupref; struct web_entry *entry; dup_entry = use_entry; for (dupref = use_link; dupref; dupref = DF_REF_NEXT_LOC (dupref)) if (DF_REF_LOC (dupref) == recog_data.dup_loc[i]) break; if (dupref == NULL && type == OP_INOUT) { dup_entry = def_entry; for (dupref = def_link; dupref; dupref = DF_REF_NEXT_LOC (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; ref = type == OP_IN ? use_link : def_link; entry = type == OP_IN ? use_entry : def_entry; for (; ref; ref = DF_REF_NEXT_LOC (ref)) { rtx *l = DF_REF_LOC (ref); if (l == recog_data.operand_loc[op]) break; if (l && DF_REF_REAL_LOC (ref) == recog_data.operand_loc[op]) break; } if (!ref && type == OP_INOUT) { entry = use_entry; for (ref = use_link; ref; ref = DF_REF_NEXT_LOC (ref)) { rtx *l = DF_REF_LOC (ref); if (l == recog_data.operand_loc[op]) break; if (l && DF_REF_REAL_LOC (ref) == recog_data.operand_loc[op]) break; } } gcc_assert (ref); (*fun) (dup_entry + DF_REF_ID (dupref), entry + DF_REF_ID (ref)); } }