This patch adds a new format %N to the avr_xdump functions.
The purpose is to print a tree node, usually a DECL_P or
a TYPE_P in a recursive form that's not too verbose.
For example:
typedef int (* const __flash fun_t)(long, int);
int foo (fun_t (*f[][4]), int x, int y)
{
return (*f[x][y]) (x, y);
}
will print with -mlog=insert_attributes, amongst others:
avr_insert_attributes[:pass=?]:
<parm_decl 0x7f833edd8110 f>
<pointer_type 0x7f833edacb28>
<array_type 0x7f833edac888>
<pointer_type 0x7f833edac690>
<pointer_type 0x7f833edac5e8 fun_t address-space-1>
read-only
<function_type 0x7f833edac3f0>
<integer_type 0x7f833ec745e8 int> return
<integer_type 0x7f833ec74738 long int>
<integer_type 0x7f833ec745e8 int>
<void_type 0x7f833ec7c1f8 void>
Ok for trunk?
Johann
--
AVR: Support to print nodes brief and recursive.
This patch adds a new format %N to the avr_xdump functions.
The purpose is to print a tree node, usually a DECL_P or
a TYPE_P in a recursive form that's not too verbose.
For example:
typedef int (* const __flash fun_t)(long, int);
int foo (fun_t (*f[][4]), int x, int y)
{
return (*f[x][y]) (x, y);
}
will print with -mlog=insert_attributes, amongst others:
avr_insert_attributes[:pass=?]:
<parm_decl 0x7f833edd8110 f>
<pointer_type 0x7f833edacb28>
<array_type 0x7f833edac888>
<pointer_type 0x7f833edac690>
<pointer_type 0x7f833edac5e8 fun_t address-space-1>
read-only
<function_type 0x7f833edac3f0>
<integer_type 0x7f833ec745e8 int> return
<integer_type 0x7f833ec74738 long int>
<integer_type 0x7f833ec745e8 int>
<void_type 0x7f833ec7c1f8 void>
gcc/
* config/avr/avr-protos.h (avr_log_t) <insert_attributes>: New field.
* config/avr/avr-log.cc (avr_log_node): New static function.
(avr_log_vadump) [%N]: Call it.
(avr_log_set_avr_log) <insert_attributes>: New SET_DUMP_DETAIL.
* config/avr/avr.cc (avr_pgm_check_var_decl): Don't call avr_edump.
(avr_insert_attributes) [avr_log.insert_attributes]: Call avr_edump.
diff --git a/gcc/config/avr/avr-log.cc b/gcc/config/avr/avr-log.cc
index 06d83b0a04b..0008cce5c92 100644
--- a/gcc/config/avr/avr-log.cc
+++ b/gcc/config/avr/avr-log.cc
@@ -48,6 +48,7 @@
T: tree (brief)
C: enum rtx_code
m: machine_mode
+ N: tree node (recursive, brief)
R: enum reg_class
L: insn list
H: location_t
@@ -102,6 +103,67 @@ avr_vdump (FILE *stream, const char *caller, ...)
}
+/* %N: Brief dump of a node, but still displaying its structure. */
+
+static void
+avr_log_node (FILE *file, tree node, int tab, const char *tag = nullptr)
+{
+ tab += 3;
+
+ auto code = TREE_CODE (node);
+
+ fprintf (file, "%*s", tab, "");
+
+ print_node_brief (file, "", node, 0);
+ if (tag)
+ fprintf (file, " %s", tag);
+ if (DECL_P (node) && DECL_ARTIFICIAL (node))
+ fprintf (file, " artificial");
+ if (code == VAR_DECL || code == PARM_DECL || code == FIELD_DECL)
+ if (TREE_READONLY (node))
+ fprintf (file, " read-only");
+ if (TYPE_P (node) && TYPE_READONLY (node))
+ fprintf (file, " read-only");
+
+ fprintf (file, "\n");
+
+ switch (code)
+ {
+ case FUNCTION_DECL:
+ avr_log_node (file, TREE_TYPE (TREE_TYPE (node)), tab, "return");
+ for (tree p = DECL_ARGUMENTS (node); p; p = DECL_CHAIN (p))
+ avr_log_node (file, p, tab);
+ break;
+
+ case FUNCTION_TYPE:
+ case METHOD_TYPE:
+ avr_log_node (file, TREE_TYPE (node), tab, "return");
+ for (tree p = TYPE_ARG_TYPES (node); p; p = TREE_CHAIN (p))
+ avr_log_node (file, TREE_VALUE (p), tab);
+ break;
+
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case QUAL_UNION_TYPE:
+ for (tree el = TYPE_FIELDS (node); el; el = DECL_CHAIN (el))
+ if (TREE_CODE (el) == FIELD_DECL)
+ avr_log_node (file, el, tab);
+ break;
+
+ case ARRAY_TYPE:
+ case POINTER_TYPE:
+ case REFERENCE_TYPE:
+ avr_log_node (file, TREE_TYPE (node), tab);
+ break;
+
+ default:
+ if (DECL_P (node))
+ avr_log_node (file, TREE_TYPE (node), tab);
+ break;
+ }
+}
+
+
/* Worker function implementing the %-codes and forwarding to
respective print/dump function. */
@@ -161,6 +223,16 @@ avr_log_vadump (FILE *file, const char *caller, va_list ap)
}
break;
+ case 'N':
+ {
+ tree t = va_arg (ap, tree);
+ if (NULL_TREE == t)
+ fprintf (file, "<NULL-TREE>");
+ else
+ avr_log_node (file, t, 0);
+ }
+ break;
+
case 'b':
fprintf (file, "%s", va_arg (ap, int) ? "true" : "false");
break;
@@ -370,6 +442,7 @@ avr_log_set_avr_log (void)
SET_DUMP_DETAIL (address_cost);
SET_DUMP_DETAIL (builtin);
SET_DUMP_DETAIL (constraints);
+ SET_DUMP_DETAIL (insert_attributes);
SET_DUMP_DETAIL (insn_addresses);
SET_DUMP_DETAIL (legitimate_address_p);
SET_DUMP_DETAIL (legitimize_address);
diff --git a/gcc/config/avr/avr-protos.h b/gcc/config/avr/avr-protos.h
index ef71d3b98bc..9013745d914 100644
--- a/gcc/config/avr/avr-protos.h
+++ b/gcc/config/avr/avr-protos.h
@@ -236,6 +236,7 @@ typedef struct
unsigned address_cost :1;
unsigned builtin :1;
unsigned constraints :1;
+ unsigned insert_attributes :1;
unsigned insn_addresses :1;
unsigned legitimate_address_p :1;
unsigned legitimize_address :1;
diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc
index 3cf43e99f0b..ebc3def80df 100644
--- a/gcc/config/avr/avr.cc
+++ b/gcc/config/avr/avr.cc
@@ -11977,9 +11977,6 @@ avr_pgm_check_var_decl (tree node)
gcc_assert (as == 0);
- if (avr_log.progmem)
- avr_edump ("%?: %t\n", node);
-
switch (TREE_CODE (node))
{
default:
@@ -12082,6 +12079,10 @@ avr_attrs_section_name (tree attrs)
static void
avr_insert_attributes (tree node, tree *attributes)
{
+ if (avr_log.insert_attributes)
+ if (TREE_CODE (node) != FUNCTION_DECL || !fndecl_built_in_p (node))
+ avr_edump ("%?:\n%N\n", node);
+
if (VAR_P (node)
&& ! TREE_STATIC (node)
&& ! DECL_EXTERNAL (node))