GCC プラグインが新しい組み込み関数を追加することは可能ですか? もしそうなら、それを正しく行う方法は?
GCC のバージョンは 5.3 (またはそれ以降) です。コードは、C で記述されたプラグインによってコンパイルおよび処理されます。
gcc-melt.org の GCC プラグインの理論的根拠で、これは実行可能であると述べられていますが、方法がわかりません。
GCC のソースを見る限り、ビルトインはgcc/langhooks.cadd_builtin_function()
を使用して作成されています。
tree
add_builtin_function (const char *name,
tree type,
int function_code,
enum built_in_class cl,
const char *library_name,
tree attrs)
function_code
関数の一意の数値 ID を除いて、この関数の引数が持つべき値は多かれ少なかれ明確です。
( を参照) のように見えますが、そこにはadd_builtin_function_common()
値enum built_in_function
が期待されていますが、GCC プラグインはその列挙型を変更できません。
いずれかより大きいランダムな値を渡すことはできないEND_BUILTINS
ようfunction_code
です。その場合、アサーションは失敗しますbuiltin_decl_implicit()
。builtin_decl_explicit()
では、GCC プラグインにビルトインを追加する適切な方法は何ですか (MELT などを使用せず、GCC プラグイン API のみ)。
更新add_builtin_function_common()
とlanghooks.builtin_function()
for C の実装と、これらが GCC でどのように使用されているか
をもう一度調べました。場合によっては 0 も許容されるようですfunction_code
。thenは使用できませんbuiltin_decl_implicit()
が、返された DECL を保存してadd_builtin_function()
後で使用できます。
そのようにビルトインを作成しようとすることができる唯一のイベントのように見えます PLUGIN_START_UNIT (そうしないと、external_scope
変数が NULL であるために GCC がクラッシュする可能性があります)。
その段階で次のことを試しました(fntype
以前に作成されました):
decl = add_builtin_function (
"my_helper", fntype,
0 /* function_code */,
BUILT_IN_NORMAL /* enum built_in_class cl */,
NULL /* library_name */,
NULL_TREE /* attrs */)
my_helper
コンパイルされ、メイン ソース ファイルとリンクされた別の C ソース ファイルで定義されました。gimple_build_call
次に、GIMPLE パス中にdecl を使用して、その関数の呼び出しを他の関数 ( ) に挿入しました。
GCC はエラーを出力せず、実際にmy_helper
通常の関数への呼び出しとして but への呼び出しを挿入しました。実際には、呼び出しを回避するためにビルトインが必要でしたが、関数の本体を挿入しました。
一方、tsan0
私のパスの直後に実行される pass は、期待どおりに組み込み関数の呼び出しを挿入します。結果として明示的な呼び出しはなく、関数の本体のみが挿入されます。ただし、そのビルトインは、プラグインではなく GCC 自体によって定義されます。
したがって、ビルトインが有効なビルトインであるためにはまだ何かが必要だと思いますが、それが何であるかはわかりません。それは何でしょうか?