This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch,AVR]: Better log output with -mdeb


This is a tentative patch for better support of logging information for avr BE
developers.

There are situations where it is more convenient to let the compiler produce
information than to debug into the compiler. One example are -da dumps.

This patch proposes a better support to print information by means of a
printf-like function via %-codes.

The current debug output with avr-gcc's option -mdeb produces bulk of
information that is very hard to read because
 - there is much output
 - there is no information on current_function_decl
 - there is no information on current pass name/number
 - there is no print-like function so the trees, rtxes so that it is
   tedious to get formatted output.

For example, the following call to avr_edump

static int
avr_OS_main_function_p (tree func)
{
  avr_edump ("%?: %t\n", func);
  return avr_lookup_function_attribute1 (func, "OS_main");
}

prints additional information in a convenient way (foo is function to be compiled):

avr_OS_main_function_p[foo:pro_and_epilogue(202)]: <function_decl # foo
    type <function_type #
        type <void_type # void VOID
...

Wondering that similar functionality is not provided by GCC itself, I wrote
this patch. GCC's diagnostic seems to be overwhelmingly complicated and not
intended for the purpose mentioned above.

The code is dead code at the moment. No function in the BE uses the new
functions. This patch just adds them.

Moreover; I don't know if avr port maintainers or global reviewers like such
stuff in the compiler... Therefore it's just tentative draft.

Supported %-codes are:

  r: rtx
  t: tree
  T: tree (brief)
  C: enum rtx_code
  m: enum machine_mode
  R: enum reg_class
  L: insn list
  H: location_t

  -- no args --
  A: call abort()
  f: current_function_name()
  F: caller (via __FUNCTION__)
  P: Pass name and number
  ?: Print caller, current function and pass info

  -- same as printf --
  %: %
  c: char
  s: string
  d: int (decimal)
  x: int (hex)

These codes cover great deal of BE developers needs and if something is missing
it can be added easily.

The calling itself is not as straight forward as it could be in the presence of
variadic macros (to get __FUNCTION__), but that should not matter here.

Johann

	* config/avr/avr-protos.h (avr_edump, avr_fdump): New macros.
	(avr__set_caller_e, avr__set_caller_f): New prototypes.
	* config/avr/avr.c: Include tree-pass.h.
	(avr__caller, avr__stream): New static variables.
	(avr__fdump_e, avr__fdump_f, avr__vadump): New static functions.
	(avr__set_caller_e, avr__set_caller_f): New functions.
Index: config/avr/avr-protos.h
===================================================================
--- config/avr/avr-protos.h	(revision 179257)
+++ config/avr/avr-protos.h	(working copy)
@@ -111,3 +111,9 @@ extern rtx avr_incoming_return_addr_rtx
 #ifdef REAL_VALUE_TYPE
 extern void asm_output_float (FILE *file, REAL_VALUE_TYPE n);
 #endif
+
+#define avr_edump (avr__set_caller_e (__FUNCTION__))
+#define avr_fdump (avr__set_caller_f (__FUNCTION__))
+
+extern int (*avr__set_caller_e (const char*))(const char*, ...);
+extern int (*avr__set_caller_f (const char*))(FILE*, const char*, ...);
Index: config/avr/avr.c
===================================================================
--- config/avr/avr.c	(revision 179257)
+++ config/avr/avr.c	(working copy)
@@ -7810,5 +7810,233 @@ avr_expand_builtin (tree exp, rtx target
   gcc_unreachable ();
 }
 
+
+/***********************************************************************
+ ** Logging, for BE developers only
+ ***********************************************************************/
+
+#include "tree-pass.h"
+
+static const char* avr__caller = "?";
+static FILE* avr__stream;
+
+static void avr__vadump (FILE*, const char*, va_list);
+
+static int
+avr__fdump_f (FILE *stream, const char* fmt, ...)
+{
+  va_list ap;
+        
+  va_start (ap, fmt);
+  if (stream)
+    avr__vadump (stream, fmt, ap);
+  va_end (ap);
+    
+  return 1;
+}
+
+int (*
+avr__set_caller_f (const char* caller)
+     )(FILE*, const char*, ...)
+{
+  avr__caller = caller;
+
+  return avr__fdump_f;
+}
+
+static int
+avr__fdump_e (const char* fmt, ...)
+{
+  va_list ap;
+        
+  va_start (ap, fmt);
+  avr__vadump (stderr, fmt, ap);
+  va_end (ap);
+    
+  return 1;
+}
+
+int (*
+avr__set_caller_e (const char* caller)
+     )(const char*, ...)
+{
+  avr__caller = caller;
+  avr__stream = stderr;
+  
+  return avr__fdump_e;
+}
+
+/*
+  -- known %-codes --
+  
+  r: rtx
+  t: tree
+  T: tree (brief)
+  C: enum rtx_code
+  m: enum machine_mode
+  R: enum reg_class
+  L: insn list
+  H: location_t
+
+  -- no args --
+  A: call abort()
+  f: current_function_name()
+  F: caller (via __FUNCTION__)
+  P: Pass name and number
+  ?: Print caller, current function and pass info
+
+  -- same as printf --
+  %: %
+  c: char
+  s: string
+  d: int (decimal)
+  x: int (hex)
+*/
+
+static void
+avr__vadump (FILE *file, const char *fmt, va_list ap)
+{
+  char bs[3] = {'\\', '?', '\0'};
+
+  while (*fmt)
+    {
+      switch (*fmt++)
+        {
+        default:
+          fputc (*(fmt-1), file);
+          break;
+          
+        case '\\':
+          bs[1] = *fmt++;
+          fputs (bs, file);
+          break;
+          
+        case '%':
+          switch (*fmt++)
+            {
+            case '%':
+              fputc ('%', file);
+              break;
+
+            case 't':
+              {
+                tree t = va_arg (ap, tree);
+                if (NULL_TREE == t)
+                  fprintf (file, "<NULL-TREE>");
+                else
+                  {
+                    if (stderr == file)
+                      debug_tree (t);
+                  }
+                break;
+              }
+
+            case 'T':
+              print_node_brief (file, "", va_arg (ap, tree), 3);
+              break;
+
+            case 'd':
+              fprintf (file, "%d", va_arg (ap, int));
+              break;
+
+            case 'x':
+              fprintf (file, "%x", va_arg (ap, int));
+              break;
+                        
+            case 'c':
+              fputc (va_arg (ap, int), file);
+              break;
+                        
+            case 'r':
+              print_inline_rtx (file, va_arg (ap, rtx), 0);
+              break;
+                        
+            case 'L':
+              {
+                rtx insn = va_arg (ap, rtx);
+
+                while (insn)
+                  {
+                    print_inline_rtx (file, insn, 0);
+                    fprintf (file, "\n");
+                    insn = NEXT_INSN (insn);
+                  }
+                break;
+              }
+                        
+            case 'f':
+              if (cfun && cfun->decl)
+                fputs (current_function_name(), file);
+              break;
+                        
+            case 's':
+              {
+                const char *str = va_arg (ap, char*);
+                fputs (str ? str : "(null)", file);
+              }
+              break;
+                        
+            case 'm':
+              fputs (GET_MODE_NAME (va_arg (ap, enum machine_mode)), file);
+              break;
+
+            case 'C':
+              fputs (rtx_name[va_arg (ap, enum rtx_code)], file);
+              break;
+
+            case 'R':
+              fputs (reg_class_names[va_arg (ap, enum reg_class)], file);
+              break;
+    
+            case 'F':
+              fputs (avr__caller, file);
+              break;
+
+            case 'H':
+              {
+                location_t loc = va_arg (ap, location_t);
+
+                if (BUILTINS_LOCATION == loc)
+                  fprintf (file, "<BUILTIN-LOCATION");
+                else if (UNKNOWN_LOCATION == loc)
+                  fprintf (file, "<UNKNOWN-LOCATION>");
+                else
+                  fprintf (file, "%s:%d",
+                           LOCATION_FILE (loc), LOCATION_LINE (loc));
+                
+                break;
+              }
+
+            case '!':
+              if (!current_pass)
+                return;
+              /* FALLTHRU */
+
+            case '?':
+              avr__fdump_f (file, "%F[%f:%P]");
+              break;
+                        
+            case 'P':
+              if (current_pass)
+                fprintf (file, "%s(%d)", 
+                         current_pass->name,
+                         current_pass->static_pass_number);
+              else
+                fprintf (file, "pass=?");
+                        
+              break;
+                        
+            case 'A':
+              abort();
+
+            default:
+              fputc (*(fmt-1), file);
+            }
+          break; /* % */
+        }
+    }
+    
+  fflush (file);
+}
 
 #include "gt-avr.h"

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]