Commit 53cfcb2e by Jakub Jelinek Committed by Jakub Jelinek

re PR debug/77844 (Compilation of simple C++ example exhaust memory)

	PR debug/77844
	* valtrack.c: Include rtl-iter.h.
	(struct rtx_subst_pair): Add insn field.
	(propagate_for_debug_subst): If pair->to contains at least 2
	regs, create a DEBUG_INSN with a debug temp before pair->insn
	and replace from with the debug temp instead of pair->to.
	(propagate_for_debug): Initialize p.insn.
	* combine.c (insn_uid_check): New inline function.
	(INSN_COST, LOG_LINKS): Use it instead of INSN_UID.
	(find_single_use, combine_instructions,
	cant_combine_insn_p, try_combine): Use NONDEBUG_INSN_P instead of
	INSN_P.

	* g++.dg/opt/pr77844.C: New test.

From-SVN: r243662
parent 474da67e
2016-12-14 Jakub Jelinek <jakub@redhat.com>
PR debug/77844
* valtrack.c: Include rtl-iter.h.
(struct rtx_subst_pair): Add insn field.
(propagate_for_debug_subst): If pair->to contains at least 2
regs, create a DEBUG_INSN with a debug temp before pair->insn
and replace from with the debug temp instead of pair->to.
(propagate_for_debug): Initialize p.insn.
* combine.c (insn_uid_check): New inline function.
(INSN_COST, LOG_LINKS): Use it instead of INSN_UID.
(find_single_use, combine_instructions,
cant_combine_insn_p, try_combine): Use NONDEBUG_INSN_P instead of
INSN_P.
2016-12-14 Martin Sebor <msebor@redhat.com> 2016-12-14 Martin Sebor <msebor@redhat.com>
PR c/17308 PR c/17308
...@@ -327,8 +327,16 @@ struct insn_link { ...@@ -327,8 +327,16 @@ struct insn_link {
static struct insn_link **uid_log_links; static struct insn_link **uid_log_links;
#define INSN_COST(INSN) (uid_insn_cost[INSN_UID (INSN)]) static inline int
#define LOG_LINKS(INSN) (uid_log_links[INSN_UID (INSN)]) insn_uid_check (const_rtx insn)
{
int uid = INSN_UID (insn);
gcc_checking_assert (uid <= max_uid_known);
return uid;
}
#define INSN_COST(INSN) (uid_insn_cost[insn_uid_check (INSN)])
#define LOG_LINKS(INSN) (uid_log_links[insn_uid_check (INSN)])
#define FOR_EACH_LOG_LINK(L, INSN) \ #define FOR_EACH_LOG_LINK(L, INSN) \
for ((L) = LOG_LINKS (INSN); (L); (L) = (L)->next) for ((L) = LOG_LINKS (INSN); (L); (L) = (L)->next)
...@@ -676,7 +684,7 @@ find_single_use (rtx dest, rtx_insn *insn, rtx_insn **ploc) ...@@ -676,7 +684,7 @@ find_single_use (rtx dest, rtx_insn *insn, rtx_insn **ploc)
for (next = NEXT_INSN (insn); for (next = NEXT_INSN (insn);
next && BLOCK_FOR_INSN (next) == bb; next && BLOCK_FOR_INSN (next) == bb;
next = NEXT_INSN (next)) next = NEXT_INSN (next))
if (INSN_P (next) && dead_or_set_p (next, dest)) if (NONDEBUG_INSN_P (next) && dead_or_set_p (next, dest))
{ {
FOR_EACH_LOG_LINK (link, next) FOR_EACH_LOG_LINK (link, next)
if (link->insn == insn && link->regno == REGNO (dest)) if (link->insn == insn && link->regno == REGNO (dest))
...@@ -1127,7 +1135,7 @@ combine_instructions (rtx_insn *f, unsigned int nregs) ...@@ -1127,7 +1135,7 @@ combine_instructions (rtx_insn *f, unsigned int nregs)
int new_direct_jump_p = 0; int new_direct_jump_p = 0;
for (first = f; first && !INSN_P (first); ) for (first = f; first && !NONDEBUG_INSN_P (first); )
first = NEXT_INSN (first); first = NEXT_INSN (first);
if (!first) if (!first)
return 0; return 0;
...@@ -2275,7 +2283,7 @@ cant_combine_insn_p (rtx_insn *insn) ...@@ -2275,7 +2283,7 @@ cant_combine_insn_p (rtx_insn *insn)
/* If this isn't really an insn, we can't do anything. /* If this isn't really an insn, we can't do anything.
This can occur when flow deletes an insn that it has merged into an This can occur when flow deletes an insn that it has merged into an
auto-increment address. */ auto-increment address. */
if (! INSN_P (insn)) if (!NONDEBUG_INSN_P (insn))
return 1; return 1;
/* Never combine loads and stores involving hard regs that are likely /* Never combine loads and stores involving hard regs that are likely
...@@ -4178,7 +4186,8 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, ...@@ -4178,7 +4186,8 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
|| insn != BB_HEAD (this_basic_block->next_bb)); || insn != BB_HEAD (this_basic_block->next_bb));
insn = NEXT_INSN (insn)) insn = NEXT_INSN (insn))
{ {
if (INSN_P (insn) && reg_referenced_p (ni2dest, PATTERN (insn))) if (NONDEBUG_INSN_P (insn)
&& reg_referenced_p (ni2dest, PATTERN (insn)))
{ {
FOR_EACH_LOG_LINK (link, insn) FOR_EACH_LOG_LINK (link, insn)
if (link->insn == i3) if (link->insn == i3)
...@@ -4319,9 +4328,9 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, ...@@ -4319,9 +4328,9 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
for (temp_insn = NEXT_INSN (i2); for (temp_insn = NEXT_INSN (i2);
temp_insn temp_insn
&& (this_basic_block->next_bb == EXIT_BLOCK_PTR_FOR_FN (cfun) && (this_basic_block->next_bb == EXIT_BLOCK_PTR_FOR_FN (cfun)
|| BB_HEAD (this_basic_block) != temp_insn); || BB_HEAD (this_basic_block) != temp_insn);
temp_insn = NEXT_INSN (temp_insn)) temp_insn = NEXT_INSN (temp_insn))
if (temp_insn != i3 && INSN_P (temp_insn)) if (temp_insn != i3 && NONDEBUG_INSN_P (temp_insn))
FOR_EACH_LOG_LINK (link, temp_insn) FOR_EACH_LOG_LINK (link, temp_insn)
if (link->insn == i2) if (link->insn == i2)
link->insn = i3; link->insn = i3;
......
2016-12-14 Jakub Jelinek <jakub@redhat.com>
PR debug/77844
* g++.dg/opt/pr77844.C: New test.
2016-12-14 Martin Sebor <msebor@redhat.com> 2016-12-14 Martin Sebor <msebor@redhat.com>
PR c/17308 PR c/17308
......
// PR debug/77844
// { dg-do compile }
// { dg-options "-O3 -g" }
#include <vector>
void
foo (std::vector<bool>& v, int i, int j)
{
for (int k = 0; k < 5; ++k)
v[5 * i + k] = v[5 * i + k] | v[5 * j + k];
}
void
bar (std::vector<bool>& v, int i, int j)
{
for (int k = 0; k < 5; ++k)
v[5 * i + k] = v[5 * i + k] ^ v[5 * j + k];
}
void
baz (std::vector<bool>& v)
{
foo (v, 4, 1);
foo (v, 4, 2);
foo (v, 4, 3);
foo (v, 4, 4);
bar (v, 4, 1);
bar (v, 4, 2);
bar (v, 4, 3);
bar (v, 4, 4);
}
...@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "regs.h" #include "regs.h"
#include "memmodel.h" #include "memmodel.h"
#include "emit-rtl.h" #include "emit-rtl.h"
#include "rtl-iter.h"
/* gen_lowpart_no_emit hook implementation for DEBUG_INSNs. In DEBUG_INSNs, /* gen_lowpart_no_emit hook implementation for DEBUG_INSNs. In DEBUG_INSNs,
all lowpart SUBREGs are valid, despite what the machine requires for all lowpart SUBREGs are valid, despite what the machine requires for
...@@ -145,6 +146,7 @@ struct rtx_subst_pair ...@@ -145,6 +146,7 @@ struct rtx_subst_pair
{ {
rtx to; rtx to;
bool adjusted; bool adjusted;
rtx_insn *insn;
}; };
/* DATA points to an rtx_subst_pair. Return the value that should be /* DATA points to an rtx_subst_pair. Return the value that should be
...@@ -162,6 +164,23 @@ propagate_for_debug_subst (rtx from, const_rtx old_rtx, void *data) ...@@ -162,6 +164,23 @@ propagate_for_debug_subst (rtx from, const_rtx old_rtx, void *data)
pair->adjusted = true; pair->adjusted = true;
pair->to = cleanup_auto_inc_dec (pair->to, VOIDmode); pair->to = cleanup_auto_inc_dec (pair->to, VOIDmode);
pair->to = make_compound_operation (pair->to, SET); pair->to = make_compound_operation (pair->to, SET);
/* Avoid propagation from growing DEBUG_INSN expressions too much. */
int cnt = 0;
subrtx_iterator::array_type array;
FOR_EACH_SUBRTX (iter, array, pair->to, ALL)
if (REG_P (*iter) && ++cnt > 1)
{
rtx dval = make_debug_expr_from_rtl (old_rtx);
/* Emit a debug bind insn. */
rtx bind
= gen_rtx_VAR_LOCATION (GET_MODE (old_rtx),
DEBUG_EXPR_TREE_DECL (dval), pair->to,
VAR_INIT_STATUS_INITIALIZED);
rtx_insn *bind_insn = emit_debug_insn_before (bind, pair->insn);
df_insn_rescan (bind_insn);
pair->to = dval;
break;
}
return pair->to; return pair->to;
} }
return copy_rtx (pair->to); return copy_rtx (pair->to);
...@@ -182,6 +201,7 @@ propagate_for_debug (rtx_insn *insn, rtx_insn *last, rtx dest, rtx src, ...@@ -182,6 +201,7 @@ propagate_for_debug (rtx_insn *insn, rtx_insn *last, rtx dest, rtx src,
struct rtx_subst_pair p; struct rtx_subst_pair p;
p.to = src; p.to = src;
p.adjusted = false; p.adjusted = false;
p.insn = NEXT_INSN (insn);
next = NEXT_INSN (insn); next = NEXT_INSN (insn);
last = NEXT_INSN (last); last = NEXT_INSN (last);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment