2011-05-28 169 views
2

我已將一些C函數編譯爲LLVM字節碼。 現在我想讓這些功能可以通過Lua腳本引擎訪問,然後將Lua腳本編譯爲本地機器代碼。使用LLVM JIT編譯lua包裝的C函數?

我找到了使用llvm編譯lua腳本的llvm-lua項目。 我現在想知道是否可以執行從lua腳本調用的C函數的jit編譯和優化。

例如,我有這兩個C函數:

void func1() { 
    for(int i = 1; i < 5; ++i) 
    printf("hello from func1"); 
} 
void func2() { 
    for(int i = 1; i < 5; ++i) 
    printf("hello from func2"); 
} 

和我揭露他們的一個Lua腳本引擎並運行Lua中那樣:

func1() 
func2() 

然後我想的llvm-lua編譯器將其優化並編譯成相應程序

for(int i = 1; i < 5; ++i) { 
    printf("hello from func1"); 
    printf("hello from func2"); 
} 

不是分成

for(int i = 1; i < 5; ++i) 
    printf("hello from func1"); 
for(int i = 1; i < 5; ++i) 
    printf("hello from func2"); 

有沒有可能實現這一點?

乾杯,

曼努埃爾

+0

是的,這聽起來像是可能的,至少在抽象中......你有什麼特別的麻煩? – servn 2011-05-29 23:19:39

+4

沒有編譯器會執行該優化,因爲它執行可觀察的差異(輸出將按不同順序排列)。 – celion 2011-05-30 01:07:10

+2

你看過luajit嗎?最新的版本是非常有前途的速度 - 也許你可以完全擺脫C。 – 2011-06-23 02:39:23

回答

3

對於任何一種像你想在這裏實現了一個複雜的程序改造,這是最好的去除儘可能多的中間環節增加複雜性越好。首先證明它適用於最簡單的情況,然後逐步將複雜性添加回來。對於你的特定問題,這可以轉化爲:嘗試獲得所需的優化,以便在純C代碼中使用同一文件中的所有代碼,然後在不同文件中使用純C代碼等。如果不能在所有代碼中都發生這種情況的更簡單的情況下,那麼你可以使它爲最初的目標工作並且增加所有的複雜性是相當不可能的(並且通過一步一步地做,你也會更好地瞭解你遇到的任何問題的可能原因) 。

如果你按照上面的建議,我非常有信心(雖然我還沒有嘗試過),你需要的優化將由LLVM優化器來完成,即使在具有一切最簡單的情況單一的C文件並運行完全優化。原因在於你希望優化器改變你的代碼的語義,因爲兩個連續的for循環不能保證有一個單一的for循環具有相同的副作用(可觀察到的變化)你提供的代碼就是一個很好的例子)。爲了優化是安全的,編譯器必須能夠保證(證明)關於從循環體執行的所有代碼的副作用的各種屬性。雖然不是不可能,但在一般情況下,使用C等不受控制的副作用的語言很難做到,並且在大多數情況下,如果您跨越任何圖書館邊界(如您在此處可能會遇到的情況)則不可行,因爲你實際上沒有一個統一的優化步驟(至少在理論上)可以考慮所有必要的代碼。如果您真的想深入研究LLVM及其優化器框架,我建議您首先閱讀excellent article outlining the motivations and design of LLVM,然後找出優化器必須能夠在一個步驟中查看哪些代碼才能實現。

我推薦你想想你的動機是什麼,試圖讓Lua編譯成LLVM位碼,並與來自C的LLVM位碼一起優化。我確信有合理的理由,但除非你絕對相信這是實現你的目標的唯一方法,那麼我個人會嘗試一種不同的方法。

可以說你的主要動機是表現。正如Andrew Y已經提到,我建議看看luajit。它使純(正確書寫)Lua to perform close to Cmany times better than standard Lua,它還包括一個Foreign Function Interface (FFI)這可能會有助於您的問題。從FFI頁:

的FFI庫允許主叫用C數據結構從純Lua代碼外部C函數

FFI庫很大程度上避免了在C中編寫乏味的手動Lua/C綁定的需要。無需學習單獨的綁定語言 - 它分析純C語言聲明!這些可以從C頭文件或參考手冊中剪切粘貼。無需處理脆弱的綁定生成器就可以完成綁定大型庫的任務。

FFI庫緊密集成到LuaJIT中(它不作爲單獨的模塊提供)。由JIT編譯器生成的用於訪問來自Lua代碼的C數據結構的代碼與C編譯器將生成的代碼一致。調用C函數可以在JIT編譯的代碼中內聯,不像調用通過傳統的Lua/C API綁定的函數。