# HG changeset patch # User Thinker K.F. Li # Date 1283991615 -28800 # Node ID 958c2366e6825427f15e20f311fd7c2c54481f6e # Parent 5502f175d3482b56ee1e545765c2e10cfac996a1 More information about design and consideration diff -r 5502f175d348 -r 958c2366e682 src/cospy.c --- a/src/cospy.c Wed Sep 08 22:16:25 2010 +0800 +++ b/src/cospy.c Thu Sep 09 08:20:15 2010 +0800 @@ -8,10 +8,19 @@ #include "cgraph.h" #include +/* This is required for GCC plugin, or it is can not be loaded */ int plugin_is_GPL_compatible; /*! \brief Parse a tree of type and return respective string. * + * The struncture of a pointer type + * - pointer:pointer_type + * - type:*_type + * - name:type_decl + * - name:identifier + * + * For a constant type, it is flaged as a readonly. + * * \return a string for the type. It must be free through ggc_free(). */ static char * @@ -19,12 +28,12 @@ tree type_v; tree *pointers; tree type_decl, type_name; - int lvl = 0; + int ptr_lvl = 0; int const_cnt = 0; char *type_str; const char *base_type_name; int type_str_len; - int i, ptr_i; + int str_i, ptr_i; /* Collect pointers */ type_v = type_node; @@ -32,12 +41,12 @@ if(TREE_READONLY(type_v)) const_cnt++; type_v = TREE_TYPE(type_v); - lvl++; + ptr_lvl++; } - pointers = (tree *)ggc_alloc(sizeof(tree) * lvl); + pointers = (tree *)ggc_alloc(sizeof(tree) * ptr_lvl); type_v = type_node; - for(ptr_i = 0; ptr_i < lvl; ptr_i++) { + for(ptr_i = 0; ptr_i < ptr_lvl; ptr_i++) { pointers[ptr_i] = type_v; type_v = TREE_TYPE(type_v); } @@ -48,29 +57,29 @@ base_type_name = IDENTIFIER_POINTER(type_name); /* Compute total length of string of full type */ - type_str_len = lvl + strlen(base_type_name) + const_cnt * 5; /* "const" */ + type_str_len = ptr_lvl + strlen(base_type_name) + + const_cnt * 5; /* "const" */ if(TREE_READONLY(type_v)) type_str_len += 6; /* "const " */ type_str = (char *)ggc_alloc(type_str_len + 1); - /* modify const for base type */ + /* base type and constant modification */ type_str[0] = 0; if(TREE_READONLY(type_v)) strcpy(type_str, "const "); strcat(type_str, base_type_name); /* Add pointers and const modifications after base type */ - i = strlen(type_str); - for(ptr_i = lvl - 1; ptr_i >= 0; ptr_i--) { + str_i = strlen(type_str); + for(ptr_i = ptr_lvl - 1; ptr_i >= 0; ptr_i--) { type_v = pointers[ptr_i]; - type_str[i++] = '*'; + type_str[str_i++] = '*'; if(TREE_READONLY(type_v)) { - type_str[i] = 0; - strcat(type_str, "const"); - i += 5; + strcpy(type_str + str_i, "const"); + str_i += 5; } } - type_str[i] = 0; + type_str[str_i] = 0; ggc_free(pointers); @@ -100,6 +109,13 @@ } } +/*! \brief This function is called before running all_passes. + * + * all_passes is a list of optimization passes of GCC. See + * init_optimization_passes() in gcc/passes.c of GCC. + * + * This function is called for every function. + */ static void handle_all_passes(void *gcc_data, void *user_data) { tree decl; @@ -110,16 +126,32 @@ char *arg_type_str; function_args_iterator itr; + /* + * GCC uses cgraph_node to save information of functions and + * relationships between functions (a.k.a call graphy). + */ decl = cfun->decl; cgn = cgraph_node(decl); printf("%s:%d:%s\n", current_function_name(), DECL_SOURCE_LINE(decl), DECL_SOURCE_FILE(decl)); + show_callees(cgn); + /* + * Parse and show arguments of the function. + */ arg = DECL_ARGUMENTS(decl); while(arg) { + /* + * The structure of an argument. + * - parm + * - name:identifier + * - type:type + * - name:type_decl + * - name:identifier + */ arg_name = DECL_NAME(arg); arg_type = TREE_TYPE(arg); arg_type_str = parse_type(arg_type); @@ -131,6 +163,8 @@ } } +/*! \brief Initialize function for the plugin. + */ int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version) { @@ -140,6 +174,9 @@ return 1; printf("Initialize plugin %s\n", plugin_info->base_name); + /* + * Register a callback called before running passes in all_passes. + */ register_callback(plugin_info->base_name, PLUGIN_ALL_PASSES_START, handle_all_passes, NULL); return 0;