+/* Ensure INSN_VAR_LOCATION_LOC (insn) doesn't have unbound complexity.
+ Allow 4 levels of rtl nesting for most rtl codes, and if we see anything
+ deeper than that, create DEBUG_EXPRs and emit DEBUG_INSNs before INSN. */
+
+static void
+avoid_complex_debug_insns (rtx insn, rtx *exp_p, int depth)
+{
+ rtx exp = *exp_p;
+ const char *format_ptr;
+ int i, j;
+
+ if (exp == NULL_RTX)
+ return;
+
+ if ((OBJECT_P (exp) && !MEM_P (exp)) || GET_CODE (exp) == CLOBBER)
+ return;
+
+ if (depth == 4)
+ {
+ /* Create DEBUG_EXPR (and DEBUG_EXPR_DECL). */
+ rtx dval = make_debug_expr_from_rtl (exp);
+
+ /* Emit a debug bind insn before INSN. */
+ rtx bind = gen_rtx_VAR_LOCATION (GET_MODE (exp),
+ DEBUG_EXPR_TREE_DECL (dval), exp,
+ VAR_INIT_STATUS_INITIALIZED);
+
+ emit_debug_insn_before (bind, insn);
+ *exp_p = dval;
+ return;
+ }
+
+ format_ptr = GET_RTX_FORMAT (GET_CODE (exp));
+ for (i = 0; i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
+ switch (*format_ptr++)
+ {
+ case 'e':
+ avoid_complex_debug_insns (insn, &XEXP (exp, i), depth + 1);
+ break;
+
+ case 'E':
+ case 'V':
+ for (j = 0; j < XVECLEN (exp, i); j++)
+ avoid_complex_debug_insns (insn, &XVECEXP (exp, i, j), depth + 1);
+ break;
+
+ default:
+ break;
+ }
+}
+