我开发了一个GCC插件,用于检测正在编译的应用程序。应用程序使用C语言编写,并且在x86 Linux系统上使用GCC 4.7(4.8和4.9也是选件)构建。GCC插件:复制函数的参数
我的插件实现了一个编译过程,放在“ssa”标准过程之后,并对GIMPLE表示进行操作。除其他外,我需要实现以下内容,但目前无法弄清楚如何正确执行。
处理C函数时,我需要在开始时插入代码,将其参数复制到我创建的局部变量中,以供将来处理。
我的第一个幼稚的做法看起来如下:
tree p;
gimple_seq seq = NULL;
gimple_stmt_iterator gsi = gsi_start_bb(single_succ(ENTRY_BLOCK_PTR));
for (p = DECL_ARGUMENTS(current_function_decl); p; p = DECL_CHAIN(param)) {
tree copy_par;
copy_par = create_tmp_var(TREE_TYPE(p), NULL);
add_referenced_var(copy_par);
copy_par = make_ssa_name(copy_par, NULL);
g = gimple_build_assign(copy_par, p);
SSA_NAME_DEF_STMT(copy_par) = g;
gimple_seq_add_stmt_without_update (&seq, g);
... // more processing here
}
...
gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
这种方式,但是,在创建参数声明一个变量的无效分配根据转储:
gimple_assign <parm_decl, D.2206_11, par, NULL>
D.2206_11
对应到我创建的局部变量,par
- 我想要复制的函数的参数。
因此GCC在稍后的一次传递中崩溃,试图处理这个添加的语句。我想这是因为p
不是变量保存各自参数的值,但声明该变量。这是这样吗?以及如何获得该变量?
我尝试使用gimple_build_assign_with_ops(NOP_EXPR, copy_par, p, NULL_TREE)
而不是gimple_build_assign()
,但它也没有。海湾合作委员会仍然在同一地点崩溃。我可以提供回溯,但我觉得我只是缺少一些基本的东西。
我还查看了从TYPE_ARG_TYPES (TREE_TYPE (current_function_decl))
开始并进一步通过TREE_CHAIN(...)
树的遍历,但似乎给出了参数的类型而不是各自的变量。
所以,问题是,如何正确添加函数参数的拷贝。
注意 也许,这可能是与熔体或GCC的Python插件的帮助下完成的,但在这个项目中,我需要执行只有本身就提供什么GCC使用的代码的所有转换。
'get_or_create_ssa_default_def'? –
@MarcGlisse:你的意思是使用'get_or_create_ssa_default_def'而不是手动插入GIMPLE_NOPs?也许吧。保存一些输入。 – Eugene