<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>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                LLVM平臺,短短幾年間,改變了眾多編程語言的走向,也催生了一大批具有特色的編程語言的出現,不愧為編譯器架構的王者,也榮獲2012年ACM軟件系統獎 —— 題記 版權聲明:本文為 西風逍遙游 原創文章,轉載請注明出處 西風世界 [http://blog.csdn.net/xfxyy_sxfancy](http://blog.csdn.net/xfxyy_sxfancy) ### 現代編譯器架構 編譯器技術,作為計算機科學的皇后,從誕生起,就不斷推進著計算機科學的發展,編譯器的發展史,簡直就是計算機發展史的縮影,而編譯器的架構也逐句變得更加優雅,獨立性更強。 但說到編譯器的架構,可能還留存著編譯原理課程的印象,5個經典流程: 詞法分析 -> 語法分析 -> 語義分析 -> 中間代碼優化 -> 目標代碼生成 一般,我們會將編譯器分為一個前端,一個后端,前端負責處理源代碼,后端負責生成目標代碼。 但軟件工程,就是在不斷的抽象和分層,分層解決問題是重要的特點,分層能夠增加層之間的獨立性,更好的完成任務。 ### LLVM中間代碼優化 LLVM的一大特色就是,有著獨立的、完善的、嚴格約束的中間代碼表示。這種中間代碼,就是LLVM的字節碼,是LLVM抽象的精髓,前端生成這種中間代碼,后端自動進行各類優化分析,讓用LLVM開發的編譯器,都能用上最先見的后端優化技術。 ![](https://box.kancloud.cn/2016-06-03_5750ee19a439e.png) LLVM另外一大特色就是自帶JIT,要知道,這可是在原來很難想象的技術,一個編譯器要想實現JIT,是需要進行大量努力的,即時翻譯代碼,還要兼顧效率和編譯時間,可不是一件簡單的事情。 但如果你用上了LLVM,JIT只是其中的副產品,直接就可以使用的。 LLVM將中間代碼優化這個流程做到了極致,LLVM工具鏈,不但可以生成所支持的各個后端平臺的代碼,更可以方便的將各語言的前端編譯后的模塊鏈接到一起,你可以方便的在你的語言中調用C函數。 ![](https://box.kancloud.cn/2016-06-03_5750ee1b42a50.png "") ### 可讀的中間代碼 LLVM中間代碼是非常易讀的,而且擁有很多高級結構,例如類型和結構體、元數據等,使用起來非常方便。 ~~~ ; Declare the string constant as a global constant. @.str = private unnamed_addr constant [13 x i8] c"hello world\0A\00" ; External declaration of the puts function declare i32 @puts(i8* nocapture) nounwind ; Definition of main function define i32 @main() { ; i32()* ; Convert [13 x i8]* to i8 *... %cast210 = getelementptr [13 x i8], [13 x i8]* @.str, i64 0, i64 0 ; Call puts function to write out the string to stdout. call i32 @puts(i8* %cast210) ret i32 0 } ; Named metadata !0 = !{i32 42, null, !"string"} !foo = !{!0} ~~~ 這是一段HelloWorld的LLVM字節碼,我們發現很清晰,而且幾乎所有的位置都有注明類型,這也是在強調,LLVM是強類型的,每個變量和臨時值,都要有明確的類型定義。 下面是結構體的聲明: ~~~ %mytype = type { %mytype*, i32 } ~~~ 非常遺憾的是,這個結構體的定義只有類型序列信息,沒有對應子成員的名稱,這是讓編譯器前端自行保存和查表,來記錄這些信息。 C函數的調用非常方便,只需要簡單的聲明 ~~~ declare i32 @printf(i8* noalias nocapture, ...) declare i32 @atoi(i8 zeroext) ~~~ 你可以將源碼用LLVM編譯成.bc,然后用llc編譯成.o,再拿Clang鏈接上各個庫就可以了。
                  <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>

                              哎呀哎呀视频在线观看