+/* Call back for note_stores to find the hard regs set or clobbered by
+ insn. Data is a bitmap of the hardregs set so far. */
+
+static void
+look_for_hardregs (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data)
+{
+ bitmap regs_set = (bitmap) data;
+
+ if (REG_P (x)
+ && REGNO (x) < FIRST_PSEUDO_REGISTER)
+ {
+ int regno = REGNO (x);
+ int n = hard_regno_nregs[regno][GET_MODE (x)];
+ while (--n >= 0)
+ bitmap_set_bit (regs_set, regno + n);
+ }
+}
+
+/* Helper function for replace_read and record_store.
+ Attempt to return a value stored in STORE_INFO, from READ_BEGIN
+ to one before READ_END bytes read in READ_MODE. Return NULL
+ if not successful. If REQUIRE_CST is true, return always constant. */
+
+static rtx
+get_stored_val (store_info_t store_info, enum machine_mode read_mode,
+ HOST_WIDE_INT read_begin, HOST_WIDE_INT read_end,
+ basic_block bb, bool require_cst)
+{
+ enum machine_mode store_mode = GET_MODE (store_info->mem);
+ int shift;
+ int access_size; /* In bytes. */
+ rtx read_reg;
+
+ /* To get here the read is within the boundaries of the write so
+ shift will never be negative. Start out with the shift being in
+ bytes. */
+ if (store_mode == BLKmode)
+ shift = 0;
+ else if (BYTES_BIG_ENDIAN)
+ shift = store_info->end - read_end;
+ else
+ shift = read_begin - store_info->begin;
+
+ access_size = shift + GET_MODE_SIZE (read_mode);
+
+ /* From now on it is bits. */
+ shift *= BITS_PER_UNIT;
+
+ if (shift)
+ read_reg = find_shift_sequence (access_size, store_info, read_mode, shift,
+ optimize_bb_for_speed_p (bb),
+ require_cst);
+ else if (store_mode == BLKmode)
+ {
+ /* The store is a memset (addr, const_val, const_size). */
+ gcc_assert (CONST_INT_P (store_info->rhs));
+ store_mode = int_mode_for_mode (read_mode);
+ if (store_mode == BLKmode)
+ read_reg = NULL_RTX;
+ else if (store_info->rhs == const0_rtx)
+ read_reg = extract_low_bits (read_mode, store_mode, const0_rtx);
+ else if (GET_MODE_BITSIZE (store_mode) > HOST_BITS_PER_WIDE_INT
+ || BITS_PER_UNIT >= HOST_BITS_PER_WIDE_INT)
+ read_reg = NULL_RTX;
+ else
+ {
+ unsigned HOST_WIDE_INT c
+ = INTVAL (store_info->rhs)
+ & (((HOST_WIDE_INT) 1 << BITS_PER_UNIT) - 1);
+ int shift = BITS_PER_UNIT;
+ while (shift < HOST_BITS_PER_WIDE_INT)
+ {
+ c |= (c << shift);
+ shift <<= 1;
+ }
+ read_reg = GEN_INT (trunc_int_for_mode (c, store_mode));
+ read_reg = extract_low_bits (read_mode, store_mode, read_reg);
+ }
+ }
+ else if (store_info->const_rhs
+ && (require_cst
+ || GET_MODE_CLASS (read_mode) != GET_MODE_CLASS (store_mode)))
+ read_reg = extract_low_bits (read_mode, store_mode,
+ copy_rtx (store_info->const_rhs));
+ else
+ read_reg = extract_low_bits (read_mode, store_mode,
+ copy_rtx (store_info->rhs));
+ if (require_cst && read_reg && !CONSTANT_P (read_reg))
+ read_reg = NULL_RTX;
+ return read_reg;
+}
+