コンパイル中のアプリケーションを計測する GCC プラグインを開発しています。アプリケーションは C で記述されており、x86 Linux システム上で GCC 4.7 (4.8 および 4.9 もオプション) でビルドされています。
私のプラグインは、「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()
ましたが、どちらもしませんでした。GCC は依然として同じ場所でクラッシュします。バックトレースを提供することはできますが、基本的なものが欠けているように感じます。
また、ツリーのトラバーサルから始まりTYPE_ARG_TYPES (TREE_TYPE (current_function_decl))
、さらに経由することも調べましTREE_CHAIN(...)
たが、それぞれの変数ではなく、引数の型を示しているようです。
したがって、問題は、関数の引数のコピーを適切に追加する方法です。
注 おそらく、これは MELT または GCC Python プラグインの助けを借りて行うことができますが、このプロジェクトでは、GCC 自体が提供するもののみを使用してコードのすべての変換を実行する必要があります。