2011-09-23 60 views
2

,我使用CreateEntryBlockAlloca把各種變量納入塊範圍的開頭:LLVM異常;如何在此刻放鬆

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()); 
      } 

現在,我想補充Allocas非POD類型(可能需要一個析構函數/清理功能退出)。但是,在退出範圍塊的末尾添加析構函數調用是不夠的,因爲在拋出常規DWARF異常時如何調用它們並不清楚(爲了這個參數的目的,可以說異常是從調用C++函數中拋出的那些只會拋出POD類型的調用點拋出,所以在我的例子中,不知道是無知,並且我想遠離intrinsic llvm exceptions,除非我更好地理解它們)。

我在想,也許我可以在Alloca寄存器中有一個帶有偏移量的表,並且有異常處理程序(在堆棧底部,在JIT函數的調用點)遍歷那些抵消表格並適當地調用析構函數。

我不知道的是如何查詢使用CreateAlloca創建的Alloca'ed寄存器的偏移量。 我該如何可靠地做到這一點?

另外,如果你想有更好的方式來做到這一點,請賜教

  • 技術評論的LLVM的路徑:在JIT代碼被稱爲boost::context內只在try catch中調用JIT代碼,並且對catch沒有做任何處理,它只是從上下文中退出並返回到主執行堆棧。這個想法是,如果我在主執行堆棧中處理展開,那麼我調用的任何函數(例如清理堆棧變量)都不會覆蓋終止的JIT上下文中的相同堆棧內容,因此它不會被破壞。希望我做足夠的理智

回答

2

我不知道事情是如何查詢與CreateAlloca創建的Alloca'ed寄存器的偏移量。我怎樣才能可靠地做到這一點?

您可以直接使用alloca的地址......但是沒有任何簡單的方法可以將其偏移量存入堆棧幀。

爲什麼你不想使用內在的LLVM異常?他們真的不是很難使用,特別是在你的代碼從未實際捕獲任何東西的簡單情況下。基本上你可以把簡單情況下生成的代碼叮噹,然後複製粘貼它。

編輯: 要了解如何使用異常在IR在簡單情況下,嘗試在http://llvm.org/demo/粘貼下面的C++代碼插入到演示頁:

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

這真的沒有那麼複雜。

+0

原因是這樣的;我不知道在何處以及如何構建分解器IR代碼,以便每次展開幀時調用它們。 – lurscher

+0

我已經更新了我的答案,試圖展示如何正確構建IR。 – servn

+0

請向我解釋這一點;如果調用b,則調用a並引發異常;在b幀展開之後,將要調用@X ::〜X()的代碼在哪裏?我不確定如何從API級別 – lurscher