Last active
November 11, 2016 14:09
-
-
Save yen3/3e6c22a0d4b7269629240baf34b80918 to your computer and use it in GitHub Desktop.
GCC plugin: dump call graph for a single file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "gcc-plugin.h" | |
#include "plugin-version.h" | |
#include "tree.h" | |
#include "cgraph.h" | |
#include <string> | |
#include <vector> | |
#include <map> | |
#define DEBUG(...) fprintf(stderr, __VA_ARGS__) | |
int plugin_is_GPL_compatible; | |
extern symbol_table *symtab; | |
/* Define main structure. */ | |
typedef std::string Name; | |
typedef std::vector<std::string> Callees; | |
typedef std::map<Name, Callees> CallGraph; | |
static CallGraph call_graph; | |
#define FUNCTION_NAME(fun) (const char*) IDENTIFIER_POINTER \ | |
(DECL_ASSEMBLER_NAME ((fun) ->decl)) | |
/* Plugin callback function for PLUGIN_ALL_IPA_PASSES_START */ | |
void | |
dump_callgraph (void * ARG_UNUSED (gcc_data), | |
void * ARG_UNUSED (data)) | |
{ | |
for (cgraph_node* node = symtab->first_function (); | |
node; | |
node = symtab->next_function (node)) | |
{ | |
if (!node->callees) | |
continue; | |
for (cgraph_edge* edge = node->callees; | |
edge; | |
edge = edge->next_callee) | |
{ | |
std::string sfn (FUNCTION_NAME (edge->caller->get_fun ())); | |
std::string dfn (FUNCTION_NAME (edge->callee->get_fun ())); | |
call_graph[sfn].push_back (dfn); | |
} | |
} | |
for (CallGraph::iterator iter = call_graph.begin (); | |
iter != call_graph.end (); | |
++iter) | |
{ | |
DEBUG ("%s\n", iter->first.c_str ()); | |
for (Callees::iterator citer = iter->second.begin (); | |
citer != iter->second.end (); | |
++citer) | |
{ | |
DEBUG ("\t-> %s\n", citer->c_str ()); | |
} | |
} | |
} | |
int | |
plugin_init (struct plugin_name_args *plugin_info, | |
struct plugin_gcc_version *version) | |
{ | |
/* Check the building plugin compiler and the executing compiler are the | |
same. */ | |
if (!plugin_default_version_check (version, &gcc_version)) | |
return 1; | |
/* Dump the callgraph before IPA passes. */ | |
register_callback (plugin_info -> base_name, | |
PLUGIN_ALL_IPA_PASSES_START, | |
dump_callgraph, | |
NULL); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment