2

現在、CreateEntryBlockAllocaを使用してブロックスコープの先頭に変数を挿入しています。

template <typename VariableType>
            static inline llvm::AllocaInst *CreateEntryBlockAlloca(BuilderParameter& buildParameters,
                    const std::string &VarName) {
                HAssertMsg( 1 != 0 , "Not Implemented");
            };

            template <>
              inline llvm::AllocaInst *CreateEntryBlockAlloca<double>(BuilderParameter& buildParameters,
                    const std::string &VarName) {
                llvm::Function* TheFunction = buildParameters.dag.llvmFunction;
                llvm::IRBuilder<> TmpB(&TheFunction->getEntryBlock(),
                        TheFunction->getEntryBlock().begin());
                return TmpB.CreateAlloca(llvm::Type::getDoubleTy(buildParameters.getLLVMContext()), 0,
                        VarName.c_str());
            }

ここで、非PODタイプのAllocasを追加したいと思います(終了時にデストラクタ/クリーンアップ関数が必要になる場合があります)。ただし、通常のDWARF例外がスローされたときにデストラクタ呼び出しを呼び出す方法が明確でないため、exitスコープブロックの最後にデストラクタ呼び出しを追加するだけでは不十分です(この引数の目的で、例外がPODタイプのみをスローするC++関数を呼び出すCallポイントからスローされるため、私の場合、無知は至福であり、理解が深まらない限り、固有のllvm例外を避けたいと思います)。

Allocaレジスタを使用してスタックにオフセットを持つテーブルを作成し、例外ハンドラ(スタックの最下部、JIT関数の呼び出しポイント)にテーブル上のそれらのオフセットをウォークオーバーさせることができるのではないかと考えていました。デストラクタを適切に呼び出します。

私が知らないのは、CreateAllocaで作成されたAllocaされたレジスタのオフセットをクエリする方法です。どうすればそれを確実に行うことができますか?

また、これを達成するためのより良い方法があると思われる場合は、llvmのパスについて教えてください

  • テクニカルコメント:JITコードはboost :: context内で呼び出され、try catch内でのみJITコードを呼び出し、catchに対しては何も実行せず、コンテキストを終了してメインの実行スタックに戻ります。メインの実行スタックでアンワインドを処理する場合、呼び出す関数(たとえば、スタック変数のクリーンアップ)は、終了したJITコンテキストから同じスタックの内容を上書きしないため、破損することはありません。私が十分に理にかなっていることを願っています
4

1 に答える 1

2

私が知らないことは、CreateAlloca で作成された Alloca'ed レジスタのオフセットを照会する方法です。どうすれば確実にそれを行うことができますか?

alloca のアドレスを直接使用できますが、そのオフセットをスタック フレームに取得する簡単な方法はありません。

固有の LLVM 例外を使用したくないのはなぜですか? 特に、コードが実際に何もキャッチしない単純なケースでは、それらを実際に使用するのはそれほど難しくありません。基本的には、clang が単純なケースで生成したコードをコピーして貼り付けるだけです。

編集:単純なケースで IR で例外を使用する方法を確認するには、次の C++ コードをhttp://llvm.org/demo/ のデモ ページに貼り付けてみてください。

class X { public: ~X() __attribute((nothrow)); };
void a(X* p);
void b() { X x; a(&x); }

それほど複雑ではありません。

于 2011-09-23T19:10:38.360 に答える