Hi. As shown from examples with -O2 optimization level, previous approach was not viable. A more complex approach is necessary and can be shortly described as follows: 1) each function has assigned start and end line in a source file 2) group functions are these functions that begin on a line and there's another function that begins on the same line (template initializations, deleting dtors, ...) 3) both source_file and function have 'vector lines': a) source_file::lines represent all lines of non-group functions b) function_info::lines exists if a function is a group function and represent lines that belong to the function 4) function_info::lines for a group of functions are summed to source_file::lines; that makes function output_lines easier 5) branches, calls and blocks are printed per function in a group, not to 'global scope' lines 6) DECL_ARTIFICIAL functions are ignored There are 2 examples that illustrate the approach: 1: 7:class ClassB -: 8:{ -: 9:public: -: 10: virtual ~ClassB (); -: 11:}; -: 12: 3: 13:ClassB::~ClassB () -: 14:{ 1: 15: int r = inline_me (glob); 1: 16: std::cout << "Bey, ClassB!" << r << std::endl; 2: 17:} ------------------ _ZN6ClassBD0Ev: 1: 13:ClassB::~ClassB () -: 14:{ -: 15: int r = inline_me (glob); -: 16: std::cout << "Bey, ClassB!" << r << std::endl; 1: 17:} ------------------ _ZN6ClassBD2Ev: 2: 13:ClassB::~ClassB () -: 14:{ 1: 15: int r = inline_me (glob); 1: 16: std::cout << "Bey, ClassB!" << r << std::endl; 1: 17:} ------------------ -: 18: -: 19:int 1: 20:main (int argc, char **argv) -: 21:{ 1: 22: ClassB *pObjB = new ClassB (); 1: 23: delete pObjB; -: 24: 1: 25: if (argc == 123) #####: 26: return 1; -: 27: -: 28: return 0; -: 29:} -: 30: -: 31: -: 32:static int #####: 33:inline_me(int a) -: 34:{ 1*: 35: return a * a; -: 36:} It's compiled with -O2 and it shows that ZN6ClassBD2Ev function executes also line 35, but the line is not counted to function_info::lines as it does not live in function scope. Note that line 35 is marked with '*'. That's because I used -fkeep-inline-functions. -: 0:Source:test.cpp -: 0:Graph:test.gcno -: 0:Data:test.gcda -: 0:Runs:1 -: 0:Programs:1 -: 1:template -: 2:class Foo -: 3:{ -: 4: public: 3: 5: Foo() -: 6: { 3: 7: b = 123; 3: 8: } ------------------ Foo::Foo(): #####: 5: Foo() -: 6: { #####: 7: b = 123; #####: 8: } ------------------ Foo::Foo(): 1: 5: Foo() -: 6: { 1: 7: b = 123; 1: 8: } ------------------ Foo::Foo(): 2: 5: Foo() -: 6: { 2: 7: b = 123; 2: 8: } ------------------ -: 9: 1: 10: void test() { if (!b) __builtin_abort (); b = 111; } ------------------ Foo::test(): #####: 10: void test() { if (!b) __builtin_abort (); b = 111; } %%%%%: 10-block 0 %%%%%: 10-block 1 ------------------ Foo::test(): 1*: 10: void test() { if (!b) __builtin_abort (); b = 111; } 1: 10-block 0 %%%%%: 10-block 1 ------------------ Foo::test(): #####: 10: void test() { if (!b) __builtin_abort (); b = 111; } %%%%%: 10-block 0 %%%%%: 10-block 1 ------------------ -: 11: -: 12: private: -: 13: int b; -: 14:}; -: 15: -: 16:template class Foo; -: 17:template class Foo; -: 18:template class Foo; -: 19: 1: 20:int main() -: 21:{ 1: 22: Foo xx; 1: 22-block 0 1: 23: Foo yy; 1: 23-block 0 1: 24: Foo zz; 1: 24-block 0 1: 25: xx.test(); 1: 25-block 0 -: 26: 1: 27: return 0; 1: 27-block 0 -: 28:} This sample is illustration of how we aggregate statistics. I've added changelog entry and I'm still planning to enhance documentation, add some tests (which would be tricky) and small follow-up clean-up is planned. In meantime I would appreciate a feedback. Thanks, Martin