[PFUNCT]: Differentiate inlining cases

Following what is in the DWARF2 specs:

Name                          Meaning
-----------------------------------------------------------------------------
DW_INL_not_inlined            Not declared inline nor inlined by the compiler
DW_INL_inlined                Not declared inline but inlined by the compiler
DW_INL_declared_not_inlined   Declared inline but not inlined by the compiler
DW_INL_declared_inlined       Declared inline and inlined by the compiler

Take advantae of this and use it in a new pfunct option: --cc_inlined, to
show which functions were of the DW_INL_inlined type.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
This commit is contained in:
Arnaldo Carvalho de Melo 2006-11-18 19:02:55 -02:00
parent c9e858a4d1
commit 179e15d553
3 changed files with 39 additions and 10 deletions

View File

@ -763,7 +763,7 @@ void function__print(struct function *self)
}
printf("/* %s:%u */\n", self->tag.decl_file, self->tag.decl_line);
printf("%s%s %s(", self->inlined ? "inline " : "",
printf("%s%s %s(", function__declared_inline(self) ? "inline " : "",
type, self->name ?: "");
list_for_each_entry(pos, &self->parameters, tag.node) {
if (!first_parameter)
@ -1127,9 +1127,10 @@ static void cu__process_die(Dwarf *dwarf, Dwarf_Die *die)
if (cu__current_function != NULL)
function__add_variable(cu__current_function, variable);
cu__add_variable(current_cu, variable);
} else if (tag == DW_TAG_label)
++cu__current_function->nr_labels;
else if (tag == DW_TAG_inlined_subroutine) {
} else if (tag == DW_TAG_label) {
if (cu__current_function != NULL)
++cu__current_function->nr_labels;
} else if (tag == DW_TAG_inlined_subroutine) {
Dwarf_Addr high_pc, low_pc;
if (dwarf_highpc(die, &high_pc)) high_pc = 0;
if (dwarf_lowpc(die, &low_pc)) low_pc = 0;

View File

@ -11,6 +11,7 @@
#include <stdint.h>
#include <dwarf.h>
#include "list.h"
@ -159,6 +160,18 @@ static inline uint32_t function__size(const struct function *self)
return self->high_pc - self->low_pc;
}
static inline int function__declared_inline(const struct function *self)
{
return (self->inlined == DW_INL_declared_inlined ||
self->inlined == DW_INL_declared_not_inlined);
}
static inline int function__inlined(const struct function *self)
{
return (self->inlined == DW_INL_inlined ||
self->inlined == DW_INL_declared_inlined);
}
extern struct class_member *class__find_member_by_name(const struct class *self,
const char *name);

View File

@ -90,6 +90,7 @@ static void print_total_inline_stats(void)
static struct option long_options[] = {
{ "class", required_argument, NULL, 'c' },
{ "externals", no_argument, NULL, 'e' },
{ "cc_inlined", no_argument, NULL, 'H' },
{ "cu_inline_expansions_stats", no_argument, NULL, 'C' },
{ "function_name_len", no_argument, NULL, 'N' },
{ "goto_labels", no_argument, NULL, 'g' },
@ -114,6 +115,7 @@ static void usage(void)
"pointer parameters\n"
" -e, --externals show just external functions\n"
" -g, --goto_labels show number of goto labels\n"
" -H, --cc_inlined not declared inline, inlined by compiler\n"
" -i, --inline_expansions show inline expansions\n"
" -I, --inline_expansions_stats show inline expansions stats\n"
" -C, --cu_inline_expansions_stats show CU inline expansions stats\n"
@ -227,9 +229,6 @@ static int cu_goto_labels_iterator(struct cu *cu, void *cookie)
static int function_iterator(struct function *function, void *cookie)
{
if (function->inlined)
return 0;
if (cookie == NULL) {
if (function->nr_inline_expansions > 0)
printf("%s: %u %u\n", function->name ?: "",
@ -254,7 +253,7 @@ static int cu_function_iterator(struct cu *cu, void *cookie)
static int inlines_iterator(struct function *function, void *cookie)
{
if (!function->inlined)
if (!function__inlined(function))
return 0;
if (function->name != NULL)
@ -300,7 +299,7 @@ static int cu_function_name_len_iterator(struct cu *cu, void *cookie)
static int total_inlines_iterator(struct function *function, void *cookie)
{
if (function->inlined)
if (function__inlined(function))
inlines__add(function);
return 0;
}
@ -313,6 +312,18 @@ static int cu_total_inlines_iterator(struct cu *cu, void *cookie)
return 0;
}
static int cc_inlined_iterator(struct function *function, void *cookie)
{
if (function->inlined == DW_INL_inlined)
puts(function->name);
return 0;
}
static int cu_cc_inlined_iterator(struct cu *cu, void *cookie)
{
return cu__for_each_function(cu, cc_inlined_iterator, cookie);
}
int main(int argc, char *argv[])
{
int option, option_index;
@ -329,8 +340,9 @@ int main(int argc, char *argv[])
int show_inline_expansions_stats = 0;
int show_inline_stats = 0;
int show_total_inline_expansion_stats = 0;
int show_cc_inlined = 0;
while ((option = getopt_long(argc, argv, "c:CegiINpsStTV",
while ((option = getopt_long(argc, argv, "c:CegHiINpsStTV",
long_options, &option_index)) >= 0)
switch (option) {
case 'c': class_name = optarg; break;
@ -340,6 +352,7 @@ int main(int argc, char *argv[])
case 'S': show_nr_variables = 1; break;
case 'p': show_nr_parameters = 1; break;
case 'g': show_goto_labels = 1; break;
case 'H': show_cc_inlined = 1; break;
case 'i': show_inline_expansions = 1; break;
case 'I': show_inline_expansions_stats = 1; break;
case 't': show_total_inline_expansion_stats = 1;break;
@ -379,6 +392,8 @@ int main(int argc, char *argv[])
print_total_inline_stats();
} else if (show_inline_stats)
cus__for_each_cu(cus, cu_inlines_iterator, NULL);
else if (show_cc_inlined)
cus__for_each_cu(cus, cu_cc_inlined_iterator, NULL);
else if (show_nr_parameters)
cus__for_each_cu(cus, cu_nr_parameters_iterator, NULL);
else if (show_nr_variables)