短表的操作碼我正在做一個小的語言,這是非常相似的HLSL,但僅支持像素着色器。該語言使用reflection.emit構建實現相同功能的點網絡程序集。我目前正在測試我的分支指令「if」的實現,並且在我的一個單元測試中(如果使用內部if else的話,其大小如果失敗,則顯示以下錯誤消息:錯誤與Reflection.Emit的
System.NotSupportedException:Illegal單字節分支在位置:32支要求是:132
我追查問題使用縮寫形式說明我的情況OpCodes.Br_S。該解決方案很簡單,我已經換成OpCodes.Br OpCodes.Br_S但是我有幾個關於這個解決方案的問題:
該解決方案對生成的代碼對性能的影響? 如果我想正確地生成單個字節的Br_S和其他情況下的Br,我該怎麼做?這裏的問題是,我使用的訪問者模式和分支指令,如「如果」我必須首先輸出Br或Br_s,並且在那時我無法知道剩餘的代碼是否將需要多於單個字節跳轉到標籤。爲了更好地說明我的問題,這是我生成以下語句代碼:
我的語言:
int a = -1; if (1>1) { a=1; } else if(2>2) { a=2; }
IL:
.method public virtual final instance int32 Main() cil managed {
.maxstack 4
.locals init (
[0] int32 num)
L_0000: ldc.i4.m1
L_0001: stloc.0
L_0002: ldc.i4.1
L_0003: ldc.i4.1
L_0004: ble.s L_000a
L_0006: ldc.i4.1
L_0007: stloc.0
L_0008: br.s L_0010
L_000a: ldc.i4.2
L_000b: ldc.i4.2
L_000c: ble.s L_0010
L_000e: ldc.i4.2
L_000f: stloc.0
L_0010: ldloc.0
L_0011: ret
}
在這種情況下,我使用兩個簡短形式的指令ble.s和br.s來實現ifs,就像.net編譯器所做的一樣。然而.NET編譯器能夠根據案例選擇br.s或br,我的問題是我該如何做類似的事情?
TNKS
你的IL有點大,沒什麼大不了的。相信JIT編譯器可以做到這一點。這些微型優化不值得你花時間。 – 2010-08-12 18:05:08
我想這樣做,但我需要自己生成IL,因爲例如在silverlight中沒有c#編譯器。我想在Silverlight中以及在沒有編譯器可用的其他環境中使用它... – 2010-08-12 18:07:41
我相信Hans建議您不要打擾簡短形式(您遇到問題)並使用標準的長形式,因爲這種優化將自動與JIT(Silverlight所具有,就像任何其他CLR impl一樣)發生。 – 2010-08-12 23:05:02