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>
PR c/17308
......@@ -327,8 +327,16 @@ struct insn_link {
static struct insn_link **uid_log_links;
#define INSN_COST(INSN) (uid_insn_cost[INSN_UID (INSN)])
#define LOG_LINKS(INSN) (uid_log_links[INSN_UID (INSN)])
static inline int
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) \
for ((L) = LOG_LINKS (INSN); (L); (L) = (L)->next)
......@@ -676,7 +684,7 @@ find_single_use (rtx dest, rtx_insn *insn, rtx_insn **ploc)
for (next = NEXT_INSN (insn);
next && BLOCK_FOR_INSN (next) == bb;
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)
if (link->insn == insn && link->regno == REGNO (dest))
......@@ -1127,7 +1135,7 @@ combine_instructions (rtx_insn *f, unsigned int nregs)
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);
if (!first)
return 0;
......@@ -2275,7 +2283,7 @@ cant_combine_insn_p (rtx_insn *insn)
/* 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
auto-increment address. */
if (! INSN_P (insn))
if (!NONDEBUG_INSN_P (insn))
return 1;
/* 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,
|| insn != BB_HEAD (this_basic_block->next_bb));
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)
if (link->insn == i3)
......@@ -4321,7 +4330,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
&& (this_basic_block->next_bb == EXIT_BLOCK_PTR_FOR_FN (cfun)
|| BB_HEAD (this_basic_block) != 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)
if (link->insn == i2)
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>
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
#include "regs.h"
#include "memmodel.h"
#include "emit-rtl.h"
#include "rtl-iter.h"
/* gen_lowpart_no_emit hook implementation for DEBUG_INSNs. In DEBUG_INSNs,
all lowpart SUBREGs are valid, despite what the machine requires for
......@@ -145,6 +146,7 @@ struct rtx_subst_pair
{
rtx to;
bool adjusted;
rtx_insn *insn;
};
/* 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)
pair->adjusted = true;
pair->to = cleanup_auto_inc_dec (pair->to, VOIDmode);
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 copy_rtx (pair->to);
......@@ -182,6 +201,7 @@ propagate_for_debug (rtx_insn *insn, rtx_insn *last, rtx dest, rtx src,
struct rtx_subst_pair p;
p.to = src;
p.adjusted = false;
p.insn = NEXT_INSN (insn);
next = NEXT_INSN (insn);
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