Commit 313b30ef by Martin Sebor Committed by Martin Sebor

PR middle-end/90676 - default GIMPLE dumps lack information

gcc/ChangeLog:

	PR middle-end/90676
	* tree-pretty-print.c (dump_mem_ref): New function.  Include
	MEM_REF type in output when different size than operand.
	(dump_generic_node): Move code to dump_mem_ref and call it.

gcc/testsuite/ChangeLog:

	PR middle-end/90676
	* gcc.dg/tree-ssa/dump-6.c: New test.
	* g++.dg/tree-ssa/pr19807.C: Adjust expected output.
	* g++.dg/tree-ssa/ssa-dse-1.C: Same.
	* gcc.dg/store_merging_5.c: Same.
	* gcc.dg/tree-prof/stringop-2.c: Same.
	* gcc.dg/tree-ssa/pr30375.c: Same.
	* gcc.dg/tree-ssa/slsr-27.c: Same.
	* gcc.dg/tree-ssa/slsr-28.c: Same.
	* gcc.dg/tree-ssa/slsr-29.c: Same.
	* gcc.dg/tree-ssa/ssa-dse-24.c: Same.

From-SVN: r272199
parent 7802a8ec
2019-06-12 Martin Sebor <msebor@redhat.com>
PR middle-end/90676
* tree-pretty-print.c (dump_mem_ref): New function. Include
MEM_REF type in output when different size than operand.
(dump_generic_node): Move code to dump_mem_ref and call it.
2019-06-12 Martin Sebor <msebor@redhat.com>
PR tree-optimization/90662
* tree-ssa-strlen.c (get_stridx): Handle simple VLAs and pointers
to arrays.
......
2019-06-12 Martin Sebor <msebor@redhat.com>
PR middle-end/90676
* gcc.dg/tree-ssa/dump-6.c: New test.
* g++.dg/tree-ssa/pr19807.C: Adjust expected output.
* g++.dg/tree-ssa/ssa-dse-1.C: Same.
* gcc.dg/tree-prof/stringop-2.c
* gcc.dg/tree-ssa/pr30375.c: Same.
* gcc.dg/tree-ssa/slsr-27.c (f): Same.
* gcc.dg/tree-ssa/slsr-28.c (f): Same.
* gcc.dg/tree-ssa/slsr-29.c (f): Same.
* gcc.dg/tree-ssa/ssa-dse-24.c: Same.
2019-06-12 Martin Sebor <msebor@redhat.com>
PR tree-optimization/90662
* gcc.dg/strlenopt-62.c: New test.
* gcc.dg/strlenopt-63.c: New test.
......
......@@ -11,7 +11,8 @@ void foo(void)
z = 1 + &a[1];
}
/* { dg-final { scan-tree-dump-times "&MEM\\\[\\\(void .\\\)&a \\\+ 8B\\\]" 3 "optimized" } } */
/* { dg-final { scan-tree-dump-times "&MEM\\\[\\\(void .\\\)&a \\\+ 8B\\\]" 3 "optimized" { target { ! store_merge } } } }
{ dg-final { scan-tree-dump-times "&MEM <int> \\\[\\\(void .\\\)&a \\\+ 8B\\\]" 3 "optimized" { target { store_merge } } } } */
void bar(int i)
......
......@@ -97,5 +97,5 @@ int main()
}
/* { dg-final { scan-tree-dump-times "MEM\\\[\\(struct FixBuf \\*\\)&<retval> \\+ \[0-9\]+B\\\] = {}" 1 "dse1" } } */
/* { dg-final { scan-tree-dump-times "MEM\\\[\\(struct FixBuf \\*\\)&<retval> \\+ \[0-9\]+B\\\] = {}" 1 "dse1" { target { ! store_merge } } } }
{ dg-final { scan-tree-dump-times "MEM <char\\\[176]> \\\[\\(struct FixBuf \\*\\)&<retval> \\+ \[0-9\]+B\\\] = {}" 1 "dse1" { target { store_merge } } } } */
......@@ -26,5 +26,7 @@ foo1 (struct bar *p, char tmp)
}
/* { dg-final { scan-tree-dump-times "Merging successful" 1 "store-merging" } } */
/* { dg-final { scan-tree-dump-times "MEM\\\[.*\\\]" 1 "store-merging" } } */
/* { dg-final { scan-tree-dump-times "Merging successful" 1 "store-merging" } }
{ dg-final { scan-tree-dump-times "MEM\\\[.*\\\]" 1 "store-merging" { target { ! store_merge } } } }
{ dg-final { scan-tree-dump-times "MEM <unsigned int> \\\[.*\\\]" 1 "store-merging" { target { store_merge && ilp32 } } } }
{ dg-final { scan-tree-dump-times "MEM <unsigned long> \\\[.*\\\]" 1 "store-merging" { target { store_merge && lp64 } } } } */
......@@ -21,5 +21,6 @@ main()
}
/* autofdo doesn't support value profiling for now: */
/* { dg-final-use-not-autofdo { scan-ipa-dump "Transformation done: single value 4 stringop" "profile"} } */
/* The versioned memset of size 4 should be optimized to an assignment. */
/* { dg-final-use-not-autofdo { scan-tree-dump "MEM\\\[\\(void .\\)&a\\\] = 168430090" "optimized"} } */
/* The versioned memset of size 4 should be optimized to an assignment.
{ dg-final-use-not-autofdo { scan-tree-dump "MEM\\\[\\(void .\\)&a\\\] = 168430090" "optimized" { target { ! store_merge } } } }
{ dg-final-use-not-autofdo { scan-tree-dump "MEM <\[a-z \]+> \\\[\\(void .\\)&a\\\] = 168430090" "optimized" { target { store_merge } } } } */
/* PR middle-end/90676 - default GIMPLE dumps lack information
{ dg-do compile }
{ dg-options "-O2 -fdump-tree-store-merging" }
{ dg-require-effective-target int32plus }
{ dg-require-effective-target store_merge } */
extern char a2[2];
void f2 (void)
{
a2[0] = 1;
a2[1] = 0;
}
extern char a4[4];
void f4 (void)
{
a4[0] = 1;
a4[1] = 0;
a4[2] = 0;
a4[3] = 0;
}
extern char a8[8];
void f8 (void)
{
a8[0] = 1;
for (int i = 1; i != 8; ++i)
a8[i] = 0;
}
/* { dg-final { scan-tree-dump "MEM <unsigned short> \\\[\\(char \\*\\)\\&a2] = " "store-merging" } }
{ dg-final { scan-tree-dump "MEM <unsigned int> \\\[\\(char \\*\\)\\&a4] = " "store-merging" } }
{ dg-final { scan-tree-dump "MEM <unsigned int> \\\[\\(char \\*\\)\\&a8] = " "store-merging" { target { ilp32 } } } }
{ dg-final { scan-tree-dump "MEM <unsigned long> \\\[\\(char \\*\\)\\&a8] = " "store-merging" { target { lp64 } } } } */
......@@ -22,5 +22,6 @@ void test_signed_msg_encoding(void)
f();
}
/* { dg-final { scan-tree-dump-times "MEM\\\[\\(struct _s \\*\\)&signInfo \\+ \[0-9\]+B\\\] = {}" 1 "dse1" } } */
/* { dg-final { scan-tree-dump-times "MEM\\\[\\(struct _s \\*\\)&signInfo \\+ \[0-9\]+B\\\] = {}" 1 "dse1" { target { ! store_merge } } } }
{ dg-final { scan-tree-dump-times "MEM <char\\\[8]> \\\[\\(struct _s \\*\\)&signInfo \\+ \[0-9\]+B\\\] = {}" 1 "dse1" { target { store_merge } } } } */
......@@ -19,4 +19,5 @@ f (struct x *p, unsigned int n)
/* { dg-final { scan-tree-dump-times "\\* 4;" 1 "dom3" { target { int32 } } } } */
/* { dg-final { scan-tree-dump-times "\\* 2;" 1 "dom3" { target { int16 } } } } */
/* { dg-final { scan-tree-dump-times "p_\\d\+\\(D\\) \\+ \[^\r\n\]*_\\d\+;" 1 "dom3" } } */
/* { dg-final { scan-tree-dump-times "MEM\\\[\\(struct x \\*\\)\[^\r\n\]*_\\d\+" 3 "dom3" } } */
/* { dg-final { scan-tree-dump-times "MEM\\\[\\(struct x \\*\\)\[^\r\n\]*_\\d\+" 3 "dom3" { target { ! store_merge } } } } */
/* { dg-final { scan-tree-dump-times "MEM <int> \\\[\\(struct x \\*\\)\[^\r\n\]*_\\d\+" 3 "dom3" { target { store_merge } } } } */
......@@ -23,4 +23,5 @@ f (struct x *p, unsigned int n)
/* { dg-final { scan-tree-dump-times "\\* 4;" 1 "dom3" { target { int32 } } } } */
/* { dg-final { scan-tree-dump-times "\\* 2;" 1 "dom3" { target { int16 } } } } */
/* { dg-final { scan-tree-dump-times "p_\\d\+\\(D\\) \\+ \[^\r\n\]*_\\d\+" 1 "dom3" } } */
/* { dg-final { scan-tree-dump-times "MEM\\\[\\(struct x \\*\\)\[^\r\n\]*_\\d\+" 9 "dom3" } } */
/* { dg-final { scan-tree-dump-times "MEM\\\[\\(struct x \\*\\)\[^\r\n\]*_\\d\+" 9 "dom3" { target { ! store_merge } } } } */
/* { dg-final { scan-tree-dump-times "MEM <int> \\\[\\(struct x \\*\\)\[^\r\n\]*_\\d\+" 9 "dom3" { target { store_merge } } } } */
......@@ -25,4 +25,5 @@ f (struct x *p, unsigned int n)
/* { dg-final { scan-tree-dump-times "\\* 4;" 1 "dom3" { target { int32 } } } } */
/* { dg-final { scan-tree-dump-times "\\* 2;" 1 "dom3" { target { int16 } } } } */
/* { dg-final { scan-tree-dump-times "p_\\d\+\\(D\\) \\+ \[^\r\n\]*_\\d\+" 1 "dom3" } } */
/* { dg-final { scan-tree-dump-times "MEM\\\[\\(struct x \\*\\)\[^\r\n\]*_\\d\+" 9 "dom3" } } */
/* { dg-final { scan-tree-dump-times "MEM\\\[\\(struct x \\*\\)\[^\r\n\]*_\\d\+" 9 "dom3" { target { ! store_merge } } } } */
/* { dg-final { scan-tree-dump-times "MEM <int> \\\[\\(struct x \\*\\)\[^\r\n\]*_\\d\+" 9 "dom3" { target { store_merge } } } } */
......@@ -59,4 +59,5 @@ void foo(int prec,
bar (&info);
}
/* { dg-final { scan-tree-dump-times "MEM\\\[\\(struct printf_info \\*\\)&info \\+ \[0-9\]+B\\\] = {}" 1 "dse1" } } */
/* { dg-final { scan-tree-dump-times "MEM\\\[\\(struct printf_info \\*\\)&info \\+ \[0-9\]+B\\\] = {}" 1 "dse1" { target { ! store_merge } } } }
{ dg-final { scan-tree-dump-times "MEM <char[4]> \\\[\\(struct printf_info \\*\\)&info \\+ \[0-9\]+B\\\] = {}" 1 "dse1" { target { store_merge } } } } */
......@@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see
#include "internal-fn.h"
#include "gomp-constants.h"
#include "gimple.h"
#include "fold-const.h"
/* Disable warnings about quoting issues in the pp_xxx calls below
that (intentionally) don't follow GCC diagnostic conventions. */
......@@ -1378,6 +1379,129 @@ dump_omp_atomic_memory_order (pretty_printer *pp, enum omp_memory_order mo)
}
}
/* Helper to dump a MEM_REF node. */
static void
dump_mem_ref (pretty_printer *pp, tree node, int spc, dump_flags_t flags)
{
if (flags & TDF_GIMPLE)
{
pp_string (pp, "__MEM <");
dump_generic_node (pp, TREE_TYPE (node),
spc, flags | TDF_SLIM, false);
if (TYPE_ALIGN (TREE_TYPE (node))
!= TYPE_ALIGN (TYPE_MAIN_VARIANT (TREE_TYPE (node))))
{
pp_string (pp, ", ");
pp_decimal_int (pp, TYPE_ALIGN (TREE_TYPE (node)));
}
pp_greater (pp);
pp_string (pp, " (");
if (TREE_TYPE (TREE_OPERAND (node, 0))
!= TREE_TYPE (TREE_OPERAND (node, 1)))
{
pp_left_paren (pp);
dump_generic_node (pp, TREE_TYPE (TREE_OPERAND (node, 1)),
spc, flags | TDF_SLIM, false);
pp_right_paren (pp);
}
dump_generic_node (pp, TREE_OPERAND (node, 0),
spc, flags | TDF_SLIM, false);
if (! integer_zerop (TREE_OPERAND (node, 1)))
{
pp_string (pp, " + ");
dump_generic_node (pp, TREE_OPERAND (node, 1),
spc, flags | TDF_SLIM, false);
}
pp_right_paren (pp);
}
else if (integer_zerop (TREE_OPERAND (node, 1))
/* Dump the types of INTEGER_CSTs explicitly, for we can't
infer them and MEM_ATTR caching will share MEM_REFs
with differently-typed op0s. */
&& TREE_CODE (TREE_OPERAND (node, 0)) != INTEGER_CST
/* Released SSA_NAMES have no TREE_TYPE. */
&& TREE_TYPE (TREE_OPERAND (node, 0)) != NULL_TREE
/* Same pointer types, but ignoring POINTER_TYPE vs.
REFERENCE_TYPE. */
&& (TREE_TYPE (TREE_TYPE (TREE_OPERAND (node, 0)))
== TREE_TYPE (TREE_TYPE (TREE_OPERAND (node, 1))))
&& (TYPE_MODE (TREE_TYPE (TREE_OPERAND (node, 0)))
== TYPE_MODE (TREE_TYPE (TREE_OPERAND (node, 1))))
&& (TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (TREE_OPERAND (node, 0)))
== TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (TREE_OPERAND (node, 1))))
/* Same value types ignoring qualifiers. */
&& (TYPE_MAIN_VARIANT (TREE_TYPE (node))
== TYPE_MAIN_VARIANT
(TREE_TYPE (TREE_TYPE (TREE_OPERAND (node, 1)))))
&& (!(flags & TDF_ALIAS)
|| MR_DEPENDENCE_CLIQUE (node) == 0))
{
if (TREE_CODE (TREE_OPERAND (node, 0)) != ADDR_EXPR)
{
/* Enclose pointers to arrays in parentheses. */
tree op0 = TREE_OPERAND (node, 0);
tree op0type = TREE_TYPE (op0);
if (POINTER_TYPE_P (op0type)
&& TREE_CODE (TREE_TYPE (op0type)) == ARRAY_TYPE)
pp_left_paren (pp);
pp_star (pp);
dump_generic_node (pp, op0, spc, flags, false);
if (POINTER_TYPE_P (op0type)
&& TREE_CODE (TREE_TYPE (op0type)) == ARRAY_TYPE)
pp_right_paren (pp);
}
else
dump_generic_node (pp,
TREE_OPERAND (TREE_OPERAND (node, 0), 0),
spc, flags, false);
}
else
{
pp_string (pp, "MEM");
tree nodetype = TREE_TYPE (node);
tree op0 = TREE_OPERAND (node, 0);
tree op1 = TREE_OPERAND (node, 1);
tree op1type = TYPE_MAIN_VARIANT (TREE_TYPE (op1));
tree op0size = TYPE_SIZE (nodetype);
tree op1size = TYPE_SIZE (TREE_TYPE (op1type));
if (!op0size || !op1size
|| !operand_equal_p (op0size, op1size, 0))
{
pp_string (pp, " <");
/* If the size of the type of the operand is not the same
as the size of the MEM_REF expression include the type
of the latter similar to the TDF_GIMPLE output to make
it clear how many bytes of memory are being accessed. */
dump_generic_node (pp, nodetype, spc, flags | TDF_SLIM, false);
pp_string (pp, "> ");
}
pp_string (pp, "[(");
dump_generic_node (pp, op1type, spc, flags | TDF_SLIM, false);
pp_right_paren (pp);
dump_generic_node (pp, op0, spc, flags, false);
if (!integer_zerop (op1))
if (!integer_zerop (TREE_OPERAND (node, 1)))
{
pp_string (pp, " + ");
dump_generic_node (pp, op1, spc, flags, false);
}
if ((flags & TDF_ALIAS)
&& MR_DEPENDENCE_CLIQUE (node) != 0)
{
pp_string (pp, " clique ");
pp_unsigned_wide_integer (pp, MR_DEPENDENCE_CLIQUE (node));
pp_string (pp, " base ");
pp_unsigned_wide_integer (pp, MR_DEPENDENCE_BASE (node));
}
pp_right_bracket (pp);
}
}
/* Dump the node NODE on the pretty_printer PP, SPC spaces of
indent. FLAGS specifies details to show in the dump (see TDF_* in
dumpfile.h). If IS_STMT is true, the object printed is considered
......@@ -1636,109 +1760,8 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, dump_flags_t flags,
break;
case MEM_REF:
{
if (flags & TDF_GIMPLE)
{
pp_string (pp, "__MEM <");
dump_generic_node (pp, TREE_TYPE (node),
spc, flags | TDF_SLIM, false);
if (TYPE_ALIGN (TREE_TYPE (node))
!= TYPE_ALIGN (TYPE_MAIN_VARIANT (TREE_TYPE (node))))
{
pp_string (pp, ", ");
pp_decimal_int (pp, TYPE_ALIGN (TREE_TYPE (node)));
}
pp_greater (pp);
pp_string (pp, " (");
if (TREE_TYPE (TREE_OPERAND (node, 0))
!= TREE_TYPE (TREE_OPERAND (node, 1)))
{
pp_left_paren (pp);
dump_generic_node (pp, TREE_TYPE (TREE_OPERAND (node, 1)),
spc, flags | TDF_SLIM, false);
pp_right_paren (pp);
}
dump_generic_node (pp, TREE_OPERAND (node, 0),
spc, flags | TDF_SLIM, false);
if (! integer_zerop (TREE_OPERAND (node, 1)))
{
pp_string (pp, " + ");
dump_generic_node (pp, TREE_OPERAND (node, 1),
spc, flags | TDF_SLIM, false);
}
pp_right_paren (pp);
}
else if (integer_zerop (TREE_OPERAND (node, 1))
/* Dump the types of INTEGER_CSTs explicitly, for we can't
infer them and MEM_ATTR caching will share MEM_REFs
with differently-typed op0s. */
&& TREE_CODE (TREE_OPERAND (node, 0)) != INTEGER_CST
/* Released SSA_NAMES have no TREE_TYPE. */
&& TREE_TYPE (TREE_OPERAND (node, 0)) != NULL_TREE
/* Same pointer types, but ignoring POINTER_TYPE vs.
REFERENCE_TYPE. */
&& (TREE_TYPE (TREE_TYPE (TREE_OPERAND (node, 0)))
== TREE_TYPE (TREE_TYPE (TREE_OPERAND (node, 1))))
&& (TYPE_MODE (TREE_TYPE (TREE_OPERAND (node, 0)))
== TYPE_MODE (TREE_TYPE (TREE_OPERAND (node, 1))))
&& (TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (TREE_OPERAND (node, 0)))
== TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (TREE_OPERAND (node, 1))))
/* Same value types ignoring qualifiers. */
&& (TYPE_MAIN_VARIANT (TREE_TYPE (node))
== TYPE_MAIN_VARIANT
(TREE_TYPE (TREE_TYPE (TREE_OPERAND (node, 1)))))
&& (!(flags & TDF_ALIAS)
|| MR_DEPENDENCE_CLIQUE (node) == 0))
{
if (TREE_CODE (TREE_OPERAND (node, 0)) != ADDR_EXPR)
{
/* Enclose pointers to arrays in parentheses. */
tree op0 = TREE_OPERAND (node, 0);
tree op0type = TREE_TYPE (op0);
if (POINTER_TYPE_P (op0type)
&& TREE_CODE (TREE_TYPE (op0type)) == ARRAY_TYPE)
pp_left_paren (pp);
pp_star (pp);
dump_generic_node (pp, op0, spc, flags, false);
if (POINTER_TYPE_P (op0type)
&& TREE_CODE (TREE_TYPE (op0type)) == ARRAY_TYPE)
pp_right_paren (pp);
}
else
dump_generic_node (pp,
TREE_OPERAND (TREE_OPERAND (node, 0), 0),
spc, flags, false);
}
else
{
tree ptype;
pp_string (pp, "MEM[");
pp_left_paren (pp);
ptype = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (node, 1)));
dump_generic_node (pp, ptype,
spc, flags | TDF_SLIM, false);
pp_right_paren (pp);
dump_generic_node (pp, TREE_OPERAND (node, 0),
spc, flags, false);
if (!integer_zerop (TREE_OPERAND (node, 1)))
{
pp_string (pp, " + ");
dump_generic_node (pp, TREE_OPERAND (node, 1),
spc, flags, false);
}
if ((flags & TDF_ALIAS)
&& MR_DEPENDENCE_CLIQUE (node) != 0)
{
pp_string (pp, " clique ");
pp_unsigned_wide_integer (pp, MR_DEPENDENCE_CLIQUE (node));
pp_string (pp, " base ");
pp_unsigned_wide_integer (pp, MR_DEPENDENCE_BASE (node));
}
pp_right_bracket (pp);
}
break;
}
dump_mem_ref (pp, node, spc, flags);
break;
case TARGET_MEM_REF:
{
......
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