+/* Scan X expression if it does not dereference any argument slots
+ we already clobbered by tail call arguments (as noted in stored_args_map
+ bitmap).
+ Return non-zero if X expression dereferences such argument slots,
+ zero otherwise. */
+
+static int
+check_sibcall_argument_overlap_1 (x)
+ rtx x;
+{
+ RTX_CODE code;
+ int i, j;
+ unsigned int k;
+ const char *fmt;
+
+ if (x == NULL_RTX)
+ return 0;
+
+ code = GET_CODE (x);
+
+ if (code == MEM)
+ {
+ if (XEXP (x, 0) == current_function_internal_arg_pointer)
+ i = 0;
+ else if (GET_CODE (XEXP (x, 0)) == PLUS
+ && XEXP (XEXP (x, 0), 0) ==
+ current_function_internal_arg_pointer
+ && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
+ i = INTVAL (XEXP (XEXP (x, 0), 1));
+ else
+ return 0;
+
+#ifdef ARGS_GROW_DOWNWARD
+ i = -i - GET_MODE_SIZE (GET_MODE (x));
+#endif
+
+ for (k = 0; k < GET_MODE_SIZE (GET_MODE (x)); k++)
+ if (i + k < stored_args_map->n_bits
+ && TEST_BIT (stored_args_map, i + k))
+ return 1;
+
+ return 0;
+ }
+
+ /* Scan all subexpressions. */
+ fmt = GET_RTX_FORMAT (code);
+ for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
+ {
+ if (*fmt == 'e')
+ {
+ if (check_sibcall_argument_overlap_1 (XEXP (x, i)))
+ return 1;
+ }
+ else if (*fmt == 'E')
+ {
+ for (j = 0; j < XVECLEN (x, i); j++)
+ if (check_sibcall_argument_overlap_1 (XVECEXP (x, i, j)))
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* Scan sequence after INSN if it does not dereference any argument slots
+ we already clobbered by tail call arguments (as noted in stored_args_map
+ bitmap). Add stack slots for ARG to stored_args_map bitmap afterwards.
+ Return non-zero if sequence after INSN dereferences such argument slots,
+ zero otherwise. */
+
+static int
+check_sibcall_argument_overlap (insn, arg)
+ rtx insn;
+ struct arg_data *arg;
+{
+ int low, high;
+
+ if (insn == NULL_RTX)
+ insn = get_insns ();
+ else
+ insn = NEXT_INSN (insn);
+
+ for (; insn; insn = NEXT_INSN (insn))
+ if (INSN_P (insn)
+ && check_sibcall_argument_overlap_1 (PATTERN (insn)))
+ break;
+
+#ifdef ARGS_GROW_DOWNWARD
+ low = -arg->offset.constant - arg->size.constant;
+#else
+ low = arg->offset.constant;
+#endif
+
+ for (high = low + arg->size.constant; low < high; low++)
+ SET_BIT (stored_args_map, low);
+ return insn != NULL_RTX;
+}
+