Hello,
The attached plug-in builds a function like this:
my_function (void * parm.0)
{
__builtin_puts (parm.0);
}
However, the generated assembly clears the first-argument register
(%edi) before calling ‘puts’, instead of actually passing the parameter:
my_function:
.LFB0:
.file 1 "tt.c"
.loc 1 1 0
.cfi_startproc
.loc 1 1 0
xorl %edi, %edi ;; %edi shouldn’t be cleared
jmp puts
.cfi_endproc
Any idea what I’m doing wrong?
(Please let me know if I should direct such questions elsewhere.)
Thanks,
Ludo’.
int plugin_is_GPL_compatible;
#include <gcc-plugin.h>
#include <plugin-version.h>
#include <plugin.h>
#include <tree.h>
#include <gimple.h>
#include <function.h>
#include <cgraph.h>
static void
define_function (void *gcc_data, void *user_data)
{
tree decl, void_ptr;
location_t loc = input_location;
void_ptr = build_pointer_type (void_type_node);
decl = build_decl (loc, FUNCTION_DECL, get_identifier ("my_function"),
build_function_type_list (void_type_node,
void_ptr, NULL_TREE));
tree parm;
parm = build_decl (loc, PARM_DECL,
create_tmp_var_name ("parm"),
void_ptr);
DECL_CONTEXT (parm) = decl;
TREE_USED (parm) = true;
DECL_ARGUMENTS (decl) = parm;
tree result;
result = build_decl (loc, RESULT_DECL, NULL_TREE, void_type_node);
DECL_CONTEXT (result) = decl;
DECL_ARTIFICIAL (result) = true;
DECL_IGNORED_P (result) = true;
DECL_RESULT (decl) = result;
DECL_INITIAL (decl) =
build_block (NULL_TREE, NULL_TREE, decl, NULL_TREE);
DECL_SAVED_TREE (decl) =
build_call_expr (built_in_decls[BUILT_IN_PUTS], 1, parm);
TREE_PUBLIC (decl) = true;
TREE_STATIC (decl) = true;
TREE_USED (decl) = true;
DECL_ARTIFICIAL (decl) = true;
DECL_EXTERNAL (decl) = false;
DECL_UNINLINABLE (decl) = true;
set_cfun (NULL);
current_function_decl = decl;
allocate_struct_function (decl, false);
cfun->function_end_locus = loc;
cgraph_finalize_function (decl, false);
}
int
plugin_init (struct plugin_name_args *plugin_info,
struct plugin_gcc_version *version)
{
if (!plugin_default_version_check (version, &gcc_version))
return 1;
register_callback ("the-plugin", PLUGIN_START_UNIT,
define_function, NULL);
return 0;
}
/*
Local Variables:
compile-command: "gcc -Wall -g -fPIC -shared -o t.so t.c -I`gcc -print-file-name=plugin`/include"
End:
*/