aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog33
-rw-r--r--gcc/builtins.c2
-rw-r--r--gcc/calls.c4
-rw-r--r--gcc/cfgcleanup.c2
-rw-r--r--gcc/combine.c4
-rw-r--r--gcc/dwarf2cfi.c41
-rw-r--r--gcc/emit-rtl.c2
-rw-r--r--gcc/explow.c2
-rw-r--r--gcc/expr.c32
-rw-r--r--gcc/recog.c2
-rw-r--r--gcc/reload1.c2
-rw-r--r--gcc/rtl.h6
-rw-r--r--gcc/rtlanal.c18
13 files changed, 101 insertions, 49 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 64577be..40d62bf 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -2,6 +2,39 @@
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
+ * rtl.h (get_args_size, add_args_size_note): New functions.
+ (find_args_size_adjust): Return a poly_int64 rather than a
+ HOST_WIDE_INT.
+ (fixup_args_size_notes): Likewise. Make the same change to the
+ end_args_size parameter.
+ * rtlanal.c (get_args_size, add_args_size_note): New functions.
+ * builtins.c (expand_builtin_trap): Use add_args_size_note.
+ * calls.c (emit_call_1): Likewise.
+ * explow.c (adjust_stack_1): Likewise.
+ * cfgcleanup.c (old_insns_match_p): Update use of
+ find_args_size_adjust.
+ * combine.c (distribute_notes): Track polynomial arg sizes.
+ * dwarf2cfi.c (dw_trace_info): Change beg_true_args_size,
+ end_true_args_size, beg_delay_args_size and end_delay_args_size
+ from HOST_WIDE_INT to poly_int64.
+ (add_cfi_args_size): Take the args_size as a poly_int64 rather
+ than a HOST_WIDE_INT.
+ (notice_args_size, notice_eh_throw, maybe_record_trace_start)
+ (maybe_record_trace_start_abnormal, scan_trace, connect_traces): Track
+ polynomial arg sizes.
+ * emit-rtl.c (try_split): Use get_args_size.
+ * recog.c (peep2_attempt): Likewise.
+ * reload1.c (reload_as_needed): Likewise.
+ * expr.c (find_args_size_adjust): Return the adjustment as a
+ poly_int64 rather than a HOST_WIDE_INT.
+ (fixup_args_size_notes): Change end_args_size from a HOST_WIDE_INT
+ to a poly_int64 and change the return type in the same way.
+ (emit_single_push_insn): Track polynomial arg sizes.
+
+2017-12-21 Richard Sandiford <richard.sandiford@linaro.org>
+ Alan Hayward <alan.hayward@arm.com>
+ David Sherwood <david.sherwood@arm.com>
+
* expr.h (push_block, emit_push_insn): Change the "extra" parameter
from HOST_WIDE_INT to poly_int64.
* expr.c (push_block, emit_push_insn): Likewise.
diff --git a/gcc/builtins.c b/gcc/builtins.c
index f8b853c..0ff0efe 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -5179,7 +5179,7 @@ expand_builtin_trap (void)
REG_ARGS_SIZE note to prevent crossjumping of calls with
different args sizes. */
if (!ACCUMULATE_OUTGOING_ARGS)
- add_reg_note (insn, REG_ARGS_SIZE, GEN_INT (stack_pointer_delta));
+ add_args_size_note (insn, stack_pointer_delta);
}
else
{
diff --git a/gcc/calls.c b/gcc/calls.c
index 5feab3a..1387d15 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -498,7 +498,7 @@ emit_call_1 (rtx funexp, tree fntree ATTRIBUTE_UNUSED, tree fndecl ATTRIBUTE_UNU
rounded_stack_size_rtx = GEN_INT (rounded_stack_size);
stack_pointer_delta -= n_popped;
- add_reg_note (call_insn, REG_ARGS_SIZE, GEN_INT (stack_pointer_delta));
+ add_args_size_note (call_insn, stack_pointer_delta);
/* If popup is needed, stack realign must use DRAP */
if (SUPPORTS_STACK_ALIGNMENT)
@@ -508,7 +508,7 @@ emit_call_1 (rtx funexp, tree fntree ATTRIBUTE_UNUSED, tree fndecl ATTRIBUTE_UNU
REG_ARGS_SIZE note to prevent crossjumping of calls with different
args sizes. */
else if (!ACCUMULATE_OUTGOING_ARGS && (ecf_flags & ECF_NORETURN) != 0)
- add_reg_note (call_insn, REG_ARGS_SIZE, GEN_INT (stack_pointer_delta));
+ add_args_size_note (call_insn, stack_pointer_delta);
if (!ACCUMULATE_OUTGOING_ARGS)
{
diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
index f470f18..6634016 100644
--- a/gcc/cfgcleanup.c
+++ b/gcc/cfgcleanup.c
@@ -1173,7 +1173,7 @@ old_insns_match_p (int mode ATTRIBUTE_UNUSED, rtx_insn *i1, rtx_insn *i2)
/* ??? Worse, this adjustment had better be constant lest we
have differing incoming stack levels. */
if (!frame_pointer_needed
- && find_args_size_adjust (i1) == HOST_WIDE_INT_MIN)
+ && known_eq (find_args_size_adjust (i1), HOST_WIDE_INT_MIN))
return dir_none;
}
else if (p1 || p2)
diff --git a/gcc/combine.c b/gcc/combine.c
index 9f19ee4..e78a713 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -14145,7 +14145,7 @@ distribute_notes (rtx notes, rtx_insn *from_insn, rtx_insn *i3, rtx_insn *i2,
entire adjustment. Assert i3 contains at least some adjust. */
if (!noop_move_p (i3))
{
- int old_size, args_size = INTVAL (XEXP (note, 0));
+ poly_int64 old_size, args_size = get_args_size (note);
/* fixup_args_size_notes looks at REG_NORETURN note,
so ensure the note is placed there first. */
if (CALL_P (i3))
@@ -14164,7 +14164,7 @@ distribute_notes (rtx notes, rtx_insn *from_insn, rtx_insn *i3, rtx_insn *i2,
old_size = fixup_args_size_notes (PREV_INSN (i3), i3, args_size);
/* emit_call_1 adds for !ACCUMULATE_OUTGOING_ARGS
REG_ARGS_SIZE note to all noreturn calls, allow that here. */
- gcc_assert (old_size != args_size
+ gcc_assert (maybe_ne (old_size, args_size)
|| (CALL_P (i3)
&& !ACCUMULATE_OUTGOING_ARGS
&& find_reg_note (i3, REG_NORETURN, NULL_RTX)));
diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c
index 8d08d86..7a70639 100644
--- a/gcc/dwarf2cfi.c
+++ b/gcc/dwarf2cfi.c
@@ -102,8 +102,8 @@ struct dw_trace_info
while scanning insns. However, the args_size value is irrelevant at
any point except can_throw_internal_p insns. Therefore the "delay"
sizes the values that must actually be emitted for this trace. */
- HOST_WIDE_INT beg_true_args_size, end_true_args_size;
- HOST_WIDE_INT beg_delay_args_size, end_delay_args_size;
+ poly_int64_pod beg_true_args_size, end_true_args_size;
+ poly_int64_pod beg_delay_args_size, end_delay_args_size;
/* The first EH insn in the trace, where beg_delay_args_size must be set. */
rtx_insn *eh_head;
@@ -475,16 +475,19 @@ add_cfi (dw_cfi_ref cfi)
}
static void
-add_cfi_args_size (HOST_WIDE_INT size)
+add_cfi_args_size (poly_int64 size)
{
+ /* We don't yet have a representation for polynomial sizes. */
+ HOST_WIDE_INT const_size = size.to_constant ();
+
dw_cfi_ref cfi = new_cfi ();
/* While we can occasionally have args_size < 0 internally, this state
should not persist at a point we actually need an opcode. */
- gcc_assert (size >= 0);
+ gcc_assert (const_size >= 0);
cfi->dw_cfi_opc = DW_CFA_GNU_args_size;
- cfi->dw_cfi_oprnd1.dw_cfi_offset = size;
+ cfi->dw_cfi_oprnd1.dw_cfi_offset = const_size;
add_cfi (cfi);
}
@@ -927,16 +930,16 @@ reg_save (unsigned int reg, unsigned int sreg, poly_int64 offset)
static void
notice_args_size (rtx_insn *insn)
{
- HOST_WIDE_INT args_size, delta;
+ poly_int64 args_size, delta;
rtx note;
note = find_reg_note (insn, REG_ARGS_SIZE, NULL);
if (note == NULL)
return;
- args_size = INTVAL (XEXP (note, 0));
+ args_size = get_args_size (note);
delta = args_size - cur_trace->end_true_args_size;
- if (delta == 0)
+ if (known_eq (delta, 0))
return;
cur_trace->end_true_args_size = args_size;
@@ -962,16 +965,14 @@ notice_args_size (rtx_insn *insn)
static void
notice_eh_throw (rtx_insn *insn)
{
- HOST_WIDE_INT args_size;
-
- args_size = cur_trace->end_true_args_size;
+ poly_int64 args_size = cur_trace->end_true_args_size;
if (cur_trace->eh_head == NULL)
{
cur_trace->eh_head = insn;
cur_trace->beg_delay_args_size = args_size;
cur_trace->end_delay_args_size = args_size;
}
- else if (cur_trace->end_delay_args_size != args_size)
+ else if (maybe_ne (cur_trace->end_delay_args_size, args_size))
{
cur_trace->end_delay_args_size = args_size;
@@ -2292,7 +2293,6 @@ static void
maybe_record_trace_start (rtx_insn *start, rtx_insn *origin)
{
dw_trace_info *ti;
- HOST_WIDE_INT args_size;
ti = get_trace_info (start);
gcc_assert (ti != NULL);
@@ -2305,7 +2305,7 @@ maybe_record_trace_start (rtx_insn *start, rtx_insn *origin)
(origin ? INSN_UID (origin) : 0));
}
- args_size = cur_trace->end_true_args_size;
+ poly_int64 args_size = cur_trace->end_true_args_size;
if (ti->beg_row == NULL)
{
/* This is the first time we've encountered this trace. Propagate
@@ -2345,7 +2345,7 @@ maybe_record_trace_start (rtx_insn *start, rtx_insn *origin)
#endif
/* The args_size is allowed to conflict if it isn't actually used. */
- if (ti->beg_true_args_size != args_size)
+ if (maybe_ne (ti->beg_true_args_size, args_size))
ti->args_size_undefined = true;
}
}
@@ -2356,11 +2356,11 @@ maybe_record_trace_start (rtx_insn *start, rtx_insn *origin)
static void
maybe_record_trace_start_abnormal (rtx_insn *start, rtx_insn *origin)
{
- HOST_WIDE_INT save_args_size, delta;
+ poly_int64 save_args_size, delta;
dw_cfa_location save_cfa;
save_args_size = cur_trace->end_true_args_size;
- if (save_args_size == 0)
+ if (known_eq (save_args_size, 0))
{
maybe_record_trace_start (start, origin);
return;
@@ -2552,7 +2552,6 @@ scan_trace (dw_trace_info *trace)
if (INSN_FROM_TARGET_P (elt))
{
- HOST_WIDE_INT restore_args_size;
cfi_vec save_row_reg_save;
/* If ELT is an instruction from target of an annulled
@@ -2560,7 +2559,7 @@ scan_trace (dw_trace_info *trace)
the args_size and CFA along the current path
shouldn't change. */
add_cfi_insn = NULL;
- restore_args_size = cur_trace->end_true_args_size;
+ poly_int64 restore_args_size = cur_trace->end_true_args_size;
cur_cfa = &cur_row->cfa;
save_row_reg_save = vec_safe_copy (cur_row->reg_save);
@@ -2802,7 +2801,7 @@ connect_traces (void)
/* Connect args_size between traces that have can_throw_internal insns. */
if (cfun->eh->lp_array)
{
- HOST_WIDE_INT prev_args_size = 0;
+ poly_int64 prev_args_size = 0;
for (i = 0; i < n; ++i)
{
@@ -2814,7 +2813,7 @@ connect_traces (void)
continue;
gcc_assert (!ti->args_size_undefined);
- if (ti->beg_delay_args_size != prev_args_size)
+ if (maybe_ne (ti->beg_delay_args_size, prev_args_size))
{
/* ??? Search back to previous CFI note. */
add_cfi_insn = PREV_INSN (ti->eh_head);
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 6f4dea3..8ca192f 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -3924,7 +3924,7 @@ try_split (rtx pat, rtx_insn *trial, int last)
break;
case REG_ARGS_SIZE:
- fixup_args_size_notes (NULL, insn_last, INTVAL (XEXP (note, 0)));
+ fixup_args_size_notes (NULL, insn_last, get_args_size (note));
break;
case REG_CALL_DECL:
diff --git a/gcc/explow.c b/gcc/explow.c
index 4f3e0d4..38a9507 100644
--- a/gcc/explow.c
+++ b/gcc/explow.c
@@ -941,7 +941,7 @@ adjust_stack_1 (rtx adjust, bool anti_p)
}
if (!suppress_reg_args_size)
- add_reg_note (insn, REG_ARGS_SIZE, GEN_INT (stack_pointer_delta));
+ add_args_size_note (insn, stack_pointer_delta);
}
/* Adjust the stack pointer by ADJUST (an rtx for a number of bytes).
diff --git a/gcc/expr.c b/gcc/expr.c
index 64baaaf..06b6f77 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -3941,9 +3941,9 @@ mem_autoinc_base (rtx mem)
The return value is the amount of adjustment that can be trivially
verified, via immediate operand or auto-inc. If the adjustment
- cannot be trivially extracted, the return value is INT_MIN. */
+ cannot be trivially extracted, the return value is HOST_WIDE_INT_MIN. */
-HOST_WIDE_INT
+poly_int64
find_args_size_adjust (rtx_insn *insn)
{
rtx dest, set, pat;
@@ -4066,22 +4066,21 @@ find_args_size_adjust (rtx_insn *insn)
}
}
-int
-fixup_args_size_notes (rtx_insn *prev, rtx_insn *last, int end_args_size)
+poly_int64
+fixup_args_size_notes (rtx_insn *prev, rtx_insn *last,
+ poly_int64 end_args_size)
{
- int args_size = end_args_size;
+ poly_int64 args_size = end_args_size;
bool saw_unknown = false;
rtx_insn *insn;
for (insn = last; insn != prev; insn = PREV_INSN (insn))
{
- HOST_WIDE_INT this_delta;
-
if (!NONDEBUG_INSN_P (insn))
continue;
- this_delta = find_args_size_adjust (insn);
- if (this_delta == 0)
+ poly_int64 this_delta = find_args_size_adjust (insn);
+ if (known_eq (this_delta, 0))
{
if (!CALL_P (insn)
|| ACCUMULATE_OUTGOING_ARGS
@@ -4090,15 +4089,15 @@ fixup_args_size_notes (rtx_insn *prev, rtx_insn *last, int end_args_size)
}
gcc_assert (!saw_unknown);
- if (this_delta == HOST_WIDE_INT_MIN)
+ if (known_eq (this_delta, HOST_WIDE_INT_MIN))
saw_unknown = true;
- add_reg_note (insn, REG_ARGS_SIZE, GEN_INT (args_size));
+ add_args_size_note (insn, args_size);
if (STACK_GROWS_DOWNWARD)
- this_delta = -(unsigned HOST_WIDE_INT) this_delta;
+ this_delta = -poly_uint64 (this_delta);
if (saw_unknown)
- args_size = INT_MIN;
+ args_size = HOST_WIDE_INT_MIN;
else
args_size -= this_delta;
}
@@ -4198,7 +4197,7 @@ emit_single_push_insn_1 (machine_mode mode, rtx x, tree type)
static void
emit_single_push_insn (machine_mode mode, rtx x, tree type)
{
- int delta, old_delta = stack_pointer_delta;
+ poly_int64 delta, old_delta = stack_pointer_delta;
rtx_insn *prev = get_last_insn ();
rtx_insn *last;
@@ -4209,12 +4208,13 @@ emit_single_push_insn (machine_mode mode, rtx x, tree type)
/* Notice the common case where we emitted exactly one insn. */
if (PREV_INSN (last) == prev)
{
- add_reg_note (last, REG_ARGS_SIZE, GEN_INT (stack_pointer_delta));
+ add_args_size_note (last, stack_pointer_delta);
return;
}
delta = fixup_args_size_notes (prev, last, stack_pointer_delta);
- gcc_assert (delta == INT_MIN || delta == old_delta);
+ gcc_assert (known_eq (delta, HOST_WIDE_INT_MIN)
+ || known_eq (delta, old_delta));
}
#endif
diff --git a/gcc/recog.c b/gcc/recog.c
index 8e1218b..99031df 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -3466,7 +3466,7 @@ peep2_attempt (basic_block bb, rtx_insn *insn, int match_len, rtx_insn *attempt)
/* Re-insert the ARGS_SIZE notes. */
if (as_note)
- fixup_args_size_notes (before_try, last, INTVAL (XEXP (as_note, 0)));
+ fixup_args_size_notes (before_try, last, get_args_size (as_note));
/* If we generated a jump instruction, it won't have
JUMP_LABEL set. Recompute after we're done. */
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 7cf6412..2483ed9 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -4649,7 +4649,7 @@ reload_as_needed (int live_known)
{
remove_note (insn, p);
fixup_args_size_notes (prev, PREV_INSN (next),
- INTVAL (XEXP (p, 0)));
+ get_args_size (p));
}
/* If this was an ASM, make sure that all the reload insns
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 17fd920..9989263 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -3355,6 +3355,7 @@ extern rtx get_related_value (const_rtx);
extern bool offset_within_block_p (const_rtx, HOST_WIDE_INT);
extern void split_const (rtx, rtx *, rtx *);
extern rtx strip_offset (rtx, poly_int64_pod *);
+extern poly_int64 get_args_size (const_rtx);
extern bool unsigned_reg_p (rtx);
extern int reg_mentioned_p (const_rtx, const_rtx);
extern int count_occurrences (const_rtx, const_rtx, int);
@@ -3390,6 +3391,7 @@ extern int find_regno_fusage (const_rtx, enum rtx_code, unsigned int);
extern rtx alloc_reg_note (enum reg_note, rtx, rtx);
extern void add_reg_note (rtx, enum reg_note, rtx);
extern void add_int_reg_note (rtx_insn *, enum reg_note, int);
+extern void add_args_size_note (rtx_insn *, poly_int64);
extern void add_shallow_copy_of_reg_note (rtx_insn *, rtx);
extern rtx duplicate_reg_note (rtx);
extern void remove_note (rtx_insn *, const_rtx);
@@ -3979,8 +3981,8 @@ extern void emit_jump (rtx);
/* In expr.c */
extern rtx move_by_pieces (rtx, rtx, unsigned HOST_WIDE_INT,
unsigned int, int);
-extern HOST_WIDE_INT find_args_size_adjust (rtx_insn *);
-extern int fixup_args_size_notes (rtx_insn *, rtx_insn *, int);
+extern poly_int64 find_args_size_adjust (rtx_insn *);
+extern poly_int64 fixup_args_size_notes (rtx_insn *, rtx_insn *, poly_int64);
/* In expmed.c */
extern void init_expmed (void);
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 859754d..6d50781 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -937,6 +937,15 @@ strip_offset (rtx x, poly_int64_pod *offset_out)
*offset_out = 0;
return x;
}
+
+/* Return the argument size in REG_ARGS_SIZE note X. */
+
+poly_int64
+get_args_size (const_rtx x)
+{
+ gcc_checking_assert (REG_NOTE_KIND (x) == REG_ARGS_SIZE);
+ return rtx_to_poly_int64 (XEXP (x, 0));
+}
/* Return the number of places FIND appears within X. If COUNT_DEST is
zero, we do not count occurrences inside the destination of a SET. */
@@ -2362,6 +2371,15 @@ add_int_reg_note (rtx_insn *insn, enum reg_note kind, int datum)
datum, REG_NOTES (insn));
}
+/* Add a REG_ARGS_SIZE note to INSN with value VALUE. */
+
+void
+add_args_size_note (rtx_insn *insn, poly_int64 value)
+{
+ gcc_checking_assert (!find_reg_note (insn, REG_ARGS_SIZE, NULL_RTX));
+ add_reg_note (insn, REG_ARGS_SIZE, gen_int_mode (value, Pmode));
+}
+
/* Add a register note like NOTE to INSN. */
void