問題タブ [llvm-c++-api]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
llvm - LLVM で関数に引数を追加する
タイプ i32 の 2 つの引数を渡して関数を選択する LLVM を作成したいと考えています。私の最初の試み(下図)は失敗しました:
上記を試すと、モジュール検証ツールがクラッシュします。新しく追加された引数の型は、ジャンク 0xCDCDCDCD (初期化されていないヒープ メモリ) です。関数型はそのままです。
新しい によって拡張される代わりにi32
。
また、コンストラクター自体が関数にリンクしているため、パラメーター リストに直接パラメーターを追加するとFunction::getArgumentList()
失敗し、Argument
これは二重リンクとして検出されます。
- これを行うには ModulePass が必要ですか、それとも FunctionPass で十分ですか?
- これを行うエレガントな方法はありますか?
ありがとう!
c++ - LLVM モジュールでの C++ クラスの使用
KaleidoscopeおよびKaleidoscope with MCJITチュートリアルに基づいて、モジュールと関数を作成し、MCJIT を使用してそれを呼び出すコードがあります。関数にはプロトタイプが必要です。
ただし、この例では、Double をパラメーターと戻り値としてのみカバーしています (上記では int を使用しています)。高度なことを行うには、クラスやコンテナーなどを渡す必要があります。
モジュールで既存の C++ クラスをどのように使用しますか?
もちろん、任意のライブラリにリンクできますが、それらを使用するには関数プロトタイプを宣言する必要があります。ライブラリ API にクラスがある場合、それらをどのように宣言しますか?
私が欲しいのは次のようなものです:
class.std::string は string.h からインポートされています。
LLVM API にはプリミティブ型しかありません。クラスを表す構造体を定義することはできますが、これを手動で行うのは非常に困難です (そして移植できません)。
それを行う方法は、クラスをビットコードにコンパイルしてモジュールに読み込むことかもしれませんが、可能であれば一時ファイルを避けたいです。また、モジュールから型を抽出する方法もわかりませんが、可能であるはずです。クラスの1つのヘッダーファイルでこれを試しました(ヘッダーファイルの名前をcppファイルに変更しました。そうしないと、clangが.gchプリコンパイル済みヘッダーになります)、結果は単なる定数でした...おそらく最適化されましたか?cppファイルで試してみたところ、36000行のコードになりました...
すると、このページを見つけました。Clang はコンパイラとしてコードをモジュールにコンパイルできるため、LLVM API を使用する代わりに Clang API を使用する必要があります。次に、インポートしたモジュールで LLVM API を使用できます。これは正しい方法ですか?関数呼び出しが機能するようになるまでには永遠にかかったので、機能するソース コードは高く評価されます (チュートリアルは古く、ドキュメントも不足しています)。
c++ - C++ に埋め込まれた LLVM からバイナリ コード (共有ライブラリ) を生成する
私は C++ で書かれた高性能システムに取り組んでいます。プロセスは、このアプリケーション用に開発された単純な言語で記述された複雑なロジック (ルール) を実行時に理解できる必要があります。2 つのオプションがあります。
ロジックの解釈 - 組み込みインタープリターを実行し、動的関数呼び出しを生成します。これは、データを受信すると、解釈されたロジックに基づいてデータに作用します
ロジックを plugin.so 動的共有ファイルにコンパイルし、dlopen、dlsym を使用してプラグインをロードし、実行時にロジック関数を呼び出します。
オプション 2 は、最適化されたマシン コードであり、プロセスに組み込まれたインタープリターよりもはるかに高速に実行されるため、非常に魅力的です。
私が検討しているオプションは次のとおりです。
- コンパイルメソッドを書く string compile( string logic, list & errors, list & warnings )
- ここで入力ロジックは、カスタム言語でコード化されたロジックを含む文字列です
- llvm ir を生成し、compile メソッドの戻り値は ir 文字列を返します
- リンクメソッドを書く bool link(string ir, string filename, list & errors, list & warnings)
- リンク メソッドについては、llvm のドキュメントを検索しましたが、そのようなメソッドを作成する可能性があるかどうかを確認できませんでした。
私が正しければ、LLVM IR は LLVM バイト コードまたはアセンブリ コードに変換されます。次に、LLVM JIT を使用して JIT モードで実行するか、GNU アセンブラーを使用してネイティブ コードを生成します。
それを行うLLVMで関数を見つけることは可能ですか? C++ のシステム コマンドを使用して "as" を呼び出して、私の要件に合わせて plugin.so ファイルを生成するよりも、すべてコード内で行う方がはるかに優れています。
実行時にプロセスから共有ライブラリのネイティブ バイナリ コードを生成する方法を知っている場合はお知らせください。
c++ - llvm::StringRef の特性テンプレート クラスの検索 operator<< ができないのはなぜですか?
質問に従って、タイプを std::ostream にストリーミングできるかどうかを検出するにはどうすればよいですか? あるタイプを IO ストリームにストリーミングできるかどうかを示す特性クラスを作成しました。この特性は、私が問題を発見した今までうまく機能しているように見えました。
私はLLVMを使用するプロジェクト内のコードを使用しており、StringRefクラスを使用しています(提案されたstd::string_viewと精神的に似ています)。クラスの Doxygen doc へのリンクを次に示します。必要に応じて、宣言ヘッダー ファイルを見つけることができます。LLVM は、StringRef オブジェクトを std ストリームにストリーミングする operator<< を提供しないため (カスタムの軽量ストリーム クラスを使用します)、1 つ作成しました。
ただし、トレイトを使用する場合、カスタム operator<< がトレイトの後に宣言されていると機能しません (これは、あるヘッダーにトレイトがあり、別のヘッダーに operator<< 関数があるために発生します)。テンプレートのインスタンス化でのルックアップは、インスタンス化ポイントの観点から機能すると考えていたので、機能するはずだと考えました。実際、以下に示すように、別のクラスとそのカスタム operator<< をトレイトの後に宣言すると、すべてが期待どおりに機能します (そのため、この問題を発見したのは今だけです)。特別な。
これは完全な例です:
私の予想に反して、これは次のように表示されます。
特性宣言の前に StringRef の operator<< の宣言を移動すると、 true が出力されます。では、なぜこの奇妙なことが起こっているのでしょうか?どうすればこの問題を解決できますか?
c - LLVM ビルド、文字列を LLVMSetValueName C API に渡す際の問題
MinGW を使用して LLVM を正常に構築したので、C API を使用してプログラムを実装しようとしています。
ビルドが成功したかどうかを確認するためのスターター アプリケーションとして、ここにある llvmpy の例をhttp://www.llvmpy.org/llvmpy-doc/0.9/doc/firstexample.htmlに変換しました (私が思うに) C と同等ですが、印刷機能から期待する出力が得られません。
私のCプログラムは次のとおりです。
私が得る出力は次のとおりです。
0x1.74bb00p-1012 および 0x1.95bc40p+876 は「%a」と読む必要があることに注意してください。
ある種のメモリ破損だとしか思えませんが、考えられる原因はわかりません。これが機能するようにコードを変更するにはどうすればよいですか?
llvm - llvm パスによるユーザー定義関数の識別
呼び出し先関数がユーザー定義かどうかを識別する方法はありますか? 例えば:
この場合、foo() はユーザー定義ですが、printf() はライブラリー関数です。
私が現在使用している方法は、すべてのモジュールを繰り返し処理し、そのサイズが 0 より大きいかどうかを確認することです。すなわち:
しかし、その精度について確信が持てませんか?
llvm - タイプが「Instruction*」の LLVM create 関数
Function::Create
メソッドを使用して入力パラメーターの型llvm::Instruction*
が class Type
誰かヒントを教えてくれませんか?
また、具体的な比較については、Instruction *pi
試しpi->getType()->print(errs())
てみたところi1
、タイプとして返されました。しかし、関数を別の cpp ファイルに書き、int externalCall(Instruction *p)
IR にコンパイルしたとき。この IR は、タイプが であると述べていclass.llvm::Instruction
ます。この 2 つが異なるのはなぜですか?API から後者を取得するにはどうすればよいですか?
llvm - LLVM get オペランドと命令の左辺値名
LLVM IR 命令の場合、%cmp7 = icmp eq i32 %6 %7
3 つのレジスタ/シンボル名をすべて取得したい (つまり%cmp %6 and %7
)
これで、pi が命令ポインターである%cmp
コマンドで文字列を取得できます。pi->getName()
しかし、オペランド名を取得しようとすると、 と入力して空の文字列pi->getOperand(0)->getName()
を取得しました。
isa<Instruction>(pi->getOperand(0))
これが命令であるかどうかを確認しようとしましたが、true がpi->getOperand(0)->hasName()
返されましたが、false が返されました。なぜ と の両方pi
がpi->getOperand(0)
指示であるのpi
に名前しかないのですか?
APIを使用してオペランド名(文字列%6
と ここ)を取得できると思いますか?%7
私が使用しているLLVMのバージョンは3.4.2です
llvm - ユーザーデータをLLVM命令ノードに関連付ける
カスタム データを各 LLVM 命令ノードに格納する最良の方法は何ですか? あるパスから別のパスに情報を渡すとしますか? 命令クラスでユーザーが任意のデータを保存できるように見えませんか?