Implementing Speed Counters in GDC

4 steps to timing just how long it takes for GDC to parse and generate code.

Step 1:

Add the timevar header and object into the GDC build.

Include timevar.h in gcc/d/d-gcc-includes.h

#include "ggc.h"
#include "opts.h"
#include "tm_p.h"
 /* Added timevar.h */
#include "timevar.h"

Append timevar.o to the borrowed C objects in gcc/d/Make-lang.in

D_BORROWED_C_OBJS += timevar.o

Step 2:

Define your own counters

Put your defined timevar macros in gcc/timevar.def
Here’s what mine look like:

/* GDC-Specific */
DEFTIMEVAR (TV_D_READ        , "Module::read")
DEFTIMEVAR (TV_D_PARSE       , "Module::parse")
DEFTIMEVAR (TV_D_IMPORTALL   , "Module::importAll")
DEFTIMEVAR (TV_D_SEMANTIC    , "Module::semantic")
DEFTIMEVAR (TV_D_SEMANTIC2   , "Module::semantic2")
DEFTIMEVAR (TV_D_SEMANTIC3   , "Module::semantic3")
DEFTIMEVAR (TV_D_GENOBJFILE  , "Module::genobjfile")

Step 3:

Add the counters to GDC

Add your push and pop functions anywhere in the code. timevar_push starts the timer, timevar_pop stops the timer.

As I’m interested in the top level only I’ve done mine in gcc/d/d-lang.cc
There’s a lot here, so a diff view should give you the general idea of it.

--- a/gcc/d/d-lang.cc        2010-09-17 19:02:38.580306157 +0100
+++ b/gcc/d/d-lang.cc     2010-09-11 21:24:34.059001743 +0100
@@ -1044,6 +1044,7 @@
     //global.params.verbose = 1;

     // Read files
+    timevar_push (TV_D_READ);
 #if ! V2
     aw = AsyncRead::create(modules.dim);
     for (i = 0; i read(0);
     }
 #endif
+    timevar_pop (TV_D_READ);
     // Parse files
+    timevar_push (TV_D_PARSE);
     for (i = 0; i < modules.dim; i++)
     {
        m = (Module *)modules.data[i];
@@ -1089,6 +1092,7 @@
            i--;
        }
     }
+    timevar_pop (TV_D_PARSE);
     if (global.errors)
        goto had_errors;

@@ -1116,6 +1120,7 @@

 #if ! V2
     // load all unconditional imports for better symbol resolving
+    timevar_push (TV_D_IMPORTALL);
     for (i = 0; i toChars());
        m->importAll(0);
     }
+    timevar_pop (TV_D_IMPORTALL);
     if (global.errors)
        goto had_errors;
 #endif

     // Do semantic analysis
+    timevar_push (TV_D_SEMANTIC);
     for (i = 0; i toChars());
        m->semantic();
     }
+    timevar_pop (TV_D_SEMANTIC);
     if (global.errors)
        goto had_errors;

@@ -1144,6 +1152,7 @@
 #endif

     // Do pass 2 semantic analysis
+    timevar_push (TV_D_SEMANTIC2);
     for (i = 0; i toChars());
        m->semantic2();
     }
+    timevar_pop (TV_D_SEMANTIC2);
     if (global.errors)
        goto had_errors;

     // Do pass 3 semantic analysis
+    timevar_push (TV_D_SEMANTIC3);
     for (i = 0; i toChars());
        m->semantic3();
     }
+    timevar_pop (TV_D_SEMANTIC3);
     if (global.errors)
        goto had_errors;

@@ -1233,6 +1245,7 @@
        json_generate(&modules);
 #endif

+    timevar_push (TV_D_GENOBJFILE);
     for (i = 0; i gendocfile();
        }
     }
+    timevar_pop (TV_D_GENOBJFILE);

     // better to use input_location.xxx ?
     (*debug_hooks->end_source_file) (input_line);

Step 4:

Build GDC

make

Then compile your project with the DFLAG -ftime-report and post your results!

Here’s one I made earlier ( that’s not very tidy! :-)
D2 Druntime/Phobos time report

About these ads

About ibuclaw
An avant developer and support analyst.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: