Implementing Speed Counters in GDC
September 18, 2010 Leave a comment
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