現在、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コンテキストから同じスタックの内容を上書きしないため、破損することはありません。私が十分に理にかなっていることを願っています