aboutsummaryrefslogtreecommitdiff
path: root/gcc/dwarf2out.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/dwarf2out.c')
-rw-r--r--gcc/dwarf2out.c64
1 files changed, 60 insertions, 4 deletions
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 8d9a384..0d643dd 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -14464,6 +14464,41 @@ const_ok_for_output_1 (rtx rtl)
case NOT:
case NEG:
return false;
+ case PLUS:
+ {
+ /* Make sure SYMBOL_REFs/UNSPECs are at most in one of the
+ operands. */
+ subrtx_var_iterator::array_type array;
+ bool first = false;
+ FOR_EACH_SUBRTX_VAR (iter, array, XEXP (rtl, 0), ALL)
+ if (SYMBOL_REF_P (*iter)
+ || LABEL_P (*iter)
+ || GET_CODE (*iter) == UNSPEC)
+ {
+ first = true;
+ break;
+ }
+ if (!first)
+ return true;
+ FOR_EACH_SUBRTX_VAR (iter, array, XEXP (rtl, 1), ALL)
+ if (SYMBOL_REF_P (*iter)
+ || LABEL_P (*iter)
+ || GET_CODE (*iter) == UNSPEC)
+ return false;
+ return true;
+ }
+ case MINUS:
+ {
+ /* Disallow negation of SYMBOL_REFs or UNSPECs when they
+ appear in the second operand of MINUS. */
+ subrtx_var_iterator::array_type array;
+ FOR_EACH_SUBRTX_VAR (iter, array, XEXP (rtl, 1), ALL)
+ if (SYMBOL_REF_P (*iter)
+ || LABEL_P (*iter)
+ || GET_CODE (*iter) == UNSPEC)
+ return false;
+ return true;
+ }
default:
return true;
}
@@ -15607,6 +15642,7 @@ mem_loc_descriptor (rtx rtl, machine_mode mode,
pool. */
case CONST:
case SYMBOL_REF:
+ case UNSPEC:
if (!is_a <scalar_int_mode> (mode, &int_mode)
|| (GET_MODE_SIZE (int_mode) > DWARF2_ADDR_SIZE
#ifdef POINTERS_EXTEND_UNSIGNED
@@ -15614,6 +15650,30 @@ mem_loc_descriptor (rtx rtl, machine_mode mode,
#endif
))
break;
+
+ if (GET_CODE (rtl) == UNSPEC)
+ {
+ /* If delegitimize_address couldn't do anything with the UNSPEC, we
+ can't express it in the debug info. This can happen e.g. with some
+ TLS UNSPECs. Allow UNSPECs formerly from CONST that the backend
+ approves. */
+ bool not_ok = false;
+ subrtx_var_iterator::array_type array;
+ FOR_EACH_SUBRTX_VAR (iter, array, rtl, ALL)
+ if ((*iter != rtl && !CONSTANT_P (*iter))
+ || !const_ok_for_output_1 (*iter))
+ {
+ not_ok = true;
+ break;
+ }
+
+ if (not_ok)
+ break;
+
+ rtl = gen_rtx_CONST (GET_MODE (rtl), rtl);
+ goto symref;
+ }
+
if (GET_CODE (rtl) == SYMBOL_REF
&& SYMBOL_REF_TLS_MODEL (rtl) != TLS_MODEL_NONE)
{
@@ -16282,7 +16342,6 @@ mem_loc_descriptor (rtx rtl, machine_mode mode,
case VEC_CONCAT:
case VEC_DUPLICATE:
case VEC_SERIES:
- case UNSPEC:
case HIGH:
case FMA:
case STRICT_LOW_PART:
@@ -16291,9 +16350,6 @@ mem_loc_descriptor (rtx rtl, machine_mode mode,
case CLRSB:
case CLOBBER:
case CLOBBER_HIGH:
- /* If delegitimize_address couldn't do anything with the UNSPEC, we
- can't express it in the debug info. This can happen e.g. with some
- TLS UNSPECs. */
break;
case CONST_STRING: