<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                LLVM平臺,短短幾年間,改變了眾多編程語言的走向,也催生了一大批具有特色的編程語言的出現,不愧為編譯器架構的王者,也榮獲2012年ACM軟件系統獎 —— 題記 版權聲明:本文為 西風逍遙游 原創文章,轉載請注明出處 西風世界 [http://blog.csdn.net/xfxyy_sxfancy](http://blog.csdn.net/xfxyy_sxfancy) # 深入理解GetElementPtr LLVM平臺,和C語言極為類似,強類型,需要復雜的指針操作,基于系統的符號調用等。而LLVM的指針操作指令,GetElementPtr,幾乎是所有指針計算的關鍵,而理解它個運作原理,正確的使用,非常的重要。 ### 強類型的LLVM 編寫LLVM需要時刻記住,LLVM是強類型的,每一條語句,都有確定的類型,GetElementPtr也正是這樣,不同的參數,會有不同類型的返回類型。 我們先來看一段LLVM官網上的示例: ~~~ struct munger_struct { int f1; int f2; }; void munge(struct munger_struct *P) { P[0].f1 = P[1].f1 + P[2].f2; } ... munger_struct Array[3]; ... munge(Array); ~~~ 我們用Clang以C格式編譯這段代碼,`munge`函數會編譯成如下IR: ~~~ void %munge(%struct.munger_struct* %P) { entry: %tmp = getelementptr %struct.munger_struct* %P, i32 1, i32 0 %tmp = load i32* %tmp %tmp6 = getelementptr %struct.munger_struct* %P, i32 2, i32 1 %tmp7 = load i32* %tmp6 %tmp8 = add i32 %tmp7, %tmp %tmp9 = getelementptr %struct.munger_struct* %P, i32 0, i32 0 store i32 %tmp8, i32* %tmp9 ret void } ~~~ 我們仔細來觀察一下,每一條指令,都有明確的指明 `P` 指針的類型為 `%struct.munger_struct*`, 而下面的load語句,也間接說明了返回類型為 `i32*` 我們在正確理解GetElementPtr的工作方式時,必須時刻了解對應的類型,這樣才不會偏差。 ### GetElementPtr的指令規則 GetElementPtr指令其實是一條指針計算語句,本身并不進行任何數據的訪問或修改,進行是計算指針,修改計算后指針的類型。 GetElementPtr至少有兩個參數,第一個參數為要進行計算的原始指針,往往是一個結構體指針,或數組首地址指針。 第二個參數及以后的參數,都稱為`indices`,表示要進行計算的參數,如結構體的第幾個元素,數組的第幾個元素。 下面我們結合示例,來對應看一下是如何工作的: ~~~ P[0].f1 ~~~ 這是示例代碼中的被賦值指針,我們C語言的經驗告訴我們,首先`P[0]`的地址就是數組的首地址,而`f1`又是結構體的第一個參數,那么P的地址就是我們最終要放置數據的結構地址。 這條地址計算對應如下語句: ~~~ %tmp9 = getelementptr %struct.munger_struct* %P, i32 0, i32 0 ~~~ 我們發現參數是兩個0,這兩個0含義不大一樣,第一個0是數組計算符,并不會改變返回的類型,因為,我們任何一個指針都可以作為一個數組來使用,進行對應的指針計算,所以這個0并不會省略。 第二個0是結構體的計算地址,表示的是結構體的第0個元素的地址,這時,會根據結構體指針的類型,選取其中的元素長度,進行計算,最后返回的則是結構體成員的指針。 同理,我們可以對照參考這兩條語句: ~~~ P[1].f1 P[2].f2 ~~~ 對應的計算翻譯后為: ~~~ %tmp = getelementptr %struct.munger_struct* %P, i32 1, i32 0 %tmp6 = getelementptr %struct.munger_struct* %P, i32 2, i32 1 ~~~ ### 注意事項 首先,不是全部的`indices`都必須是i32,也可以是i64,但結構體的計算地址,也就是上面例子中的第二個數字,必須是i32 GEP x,1,0,0 和 GEP x,1 計算后的地址是一樣的,但類型不一樣,所以千萬注意不要在語句后添加多余的0。 ### 其他情況 ### 僅有數組計算 如果僅有數組指針計算,那么就簡單了許多,數組指針的移動只需要一個參數即可。 但如果是僅有結構體指針,那么還是必須兩個參數才行 ### 多維數組 個人覺得LLVM的數組定義很難寫,推薦自己用一維數組代替,比較計算也不復雜。這樣高維數組統一化成一維后,都成了基本的指針計算,就非常簡單了。 ### 連續選取 GetElementPtr基本上可以認為是不限參數長度的,可以連續選取,于是我們可以實現: ~~~ A->B->C ~~~ 這類連續指向的計算。 但個人不推薦這樣做,尤其是語法驅動的編譯時,也很難做到這點,建議分開一條一條的語句進行執行,分別選取。 ### 參考 [http://llvm.org/docs/GetElementPtr.html](http://llvm.org/docs/GetElementPtr.html) 最近研究的LLVM技術,大部分應用于在進行的ELite編譯器開發,歡迎朋友們關注和參與。 [https://github.com/elite-lang/Elite](https://github.com/elite-lang/Elite)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看