<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      一. 使用LLVM編譯程序

      1. 編譯C程序:

      編寫 C 程序 HelloLLVM.c:

      #include <stdio.h>
      int main() {
       printf("Hello LLVM!\n");
      }

      執行編譯命令:

      clang HelloLLVM.c -o HelloLLVM

      運行結果:

      ./HelloLLVM
      Hello LLVM!

      2. 編譯 C++ 程序:

      類似的,編寫 C++ 程序 HelloLLVM.cpp:

      #include <iostream>
      
      using namespace std;
      
      int main() {
       cout << "Hello LLVM!" << std::endl;
      }

      使用 clang++ 編譯:

      clang++ HelloLLVM.cpp -o HelloLLVM

      運行結果:

      ./HelloLLVM
      Hello LLVM!

      3. 拆解編譯過程:

      我們前面展示的編譯過程是通過 Clang 進而調用 LLVM 編譯出最終的程序,這其中包括了多個步驟。Clang 提供了眾多編譯參數,通過這些參數我們可以控制編譯的過程,使其只進行其中的某一個或多個步驟。

      clang --help | grep 'Only run'
        -c                 Only run preprocess, compile, and assemble steps
        -E                 Only run the preprocessor
        -S                 Only run preprocess and compilation steps

      我們通過以上對幫助文檔的過濾可以找到拆分步驟的參數。

      3.1. 預處理

      假設我們有一個自定義的頭文件 print.h。

      void print(const char *);

      在 HelloLLVM.c 中 include 這個頭文件。

      #include "print.h"
      
      int main() {
          print("Hello LLVM!\n");
      }

      執行下面的命令:

       clang -E HelloLLVM.c -o HelloLLVM.e
       cat HelloLLVM.e

      預處理的結果:

      在開頭是一些注釋,緊接著就是 print.h 的內容,被原封不動的插入到了預處理結果中。

      3.2. 生成匯編代碼

      原博命令:

      clang -S HelloLLVM.e -o HelloLLVM.s

      但是我沒成功。。

      3.3. 匯編

      這一步將把匯編代碼翻譯成機器碼:

      clang -c HelloLLVM.c -o HelloLLVM.o
      file HelloLLVM.o
      HelloLLVM.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped

       這一步生成的文件通常成為對象文件,更專業的說法可能是可重定位文件。之所以說可重定向是因為這個文件的符號在下一步過程中會被放在一個更大的文件中,那么符號的位置也自然會被重新確立位置。

      3.4. 鏈接

      這是我們剛才提到的 print.h 對應的 print.c 文件。

      #include <stdio.h>
      
      void print(const char * str)
      {
          printf("%s", str);
      }

      把前面的 print 函數也編譯成對象文件

      clang -c print.c -o print.o
      file print.o
      print.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped

      鏈接過程實際上是使用 ld 命令,不過這個命令需要配合許多參數一起使用,我們很少會手動調用,一般是通過編譯工具來幫助我們完成,這里我們使用 clang 來完成鏈接過程

      clang HelloLLVM.o print.o -o HelloLLVM
      file HelloLLVM
      HelloLLVM: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, not stripped
       可以通過給 clang 加 --verbose 參數獲得更多編譯細節,你可以看到 clang 確實是使用了 ld 來完成鏈接過程的
      clang HelloLLVM.o print.o HelloLLVM --verbose

      獲得編譯器更多輸出。

      驗證一下鏈接出來的可執行程序:

      ./HelloLLVM 
      Hello LLVM!

      3.5. 中間表示

      實際上作為一般的編譯器都可以拆解成以上步驟:預處理、輸出匯編、匯編、鏈接。而 LLVM 有強大的中間表示,這種中間表示可以以物理的形式存在,而非想 gcc 只能在內存中臨時存在。

      不過 clang 本身并沒有開放這樣的功能,clang 留了一個“后門”,通過它你可以直接控制 clang 背后的引擎程序(clang命令 實際上是一個調度程序,實際的工作都由它來完成)

      clang -cc1 HelloLLVM.c -emit-llvm
      cat HelloLLVM.ll 

      LLVM 的中間表示:

      打開這個“后門”就是通過加 -cc1 參數,

      clang -cclang -cc1是Clang編譯器的兩個不同選項,用于不同的編譯步驟。

      1. clang -c:這是Clang的編譯選項,用于將源代碼文件編譯為目標文件(二進制文件)。當你執行clang -c <source_file>時,Clang會進行以下步驟:

        • 預處理:執行宏展開、條件編譯等預處理操作。
        • 編譯:將預處理后的源代碼編譯為匯編代碼。
        • 匯編:將匯編代碼轉換為目標文件(二進制文件),這個目標文件可以被鏈接器使用。

        例如,執行以下命令將source.c編譯為object.o目標文件:

        clang -c source.c -o object.o
      2. clang -cc1:這是Clang的底層編譯器驅動程序,用于控制Clang的內部編譯過程。-cc1選項用于手動指定Clang的各個編譯階段,可以對源代碼進行逐步的編譯和轉換。它通常與其他選項結合使用,用于進行高級的編譯控制和分析。

        例如,執行以下命令將source.c進行逐步編譯:

        clang -cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -o source.bc -x c source.c
        

         

         

        在上述命令中,-cc1選項告訴Clang使用底層編譯器驅動程序,-emit-llvm選項告訴Clang生成LLVM字節碼,-o source.bc指定生成的字節碼文件名為source.bc-x c指定輸入源代碼類型為C語言。

      ??總結來說,clang -c是用于將源代碼編譯為目標文件的簡化選項,而clang -cc1是Clang底層編譯器驅動程序的選項,用于手動控制編譯過程和進行更高級的編譯控制。

      參數 -emit-llvm 表示輸出 LLVM 中間表示,默認會保存在同名的 .ll 文件中。

      這里我們看到,.ll 文件是一個文本形式,我們還可以將其轉換成二進制形式。

      lvm-as HelloLLVM.ll
      file HelloLLVM.bc
      HelloLLVM.bc: LLVM IR bitcode

       這個過程是可逆的,通過以下命令完成。

      llvm-dis HelloLLVM.bc

      中間表示也可以被編譯。

      clang -c HelloLLVM.ll -o HelloLLVM.o

      或者

      clang -c HelloLLVM.bc -o HelloLLVM.o

      llc 是 llvm 的后端,可以用來把 中間表示編譯成匯編。

      llc HelloLLVM.bc -o HelloLLVM.s

      這與前面用 clang -S 是一樣的效果。

      3.6. 中間表示鏈接

      程序指令在優化的時候,單看獨立的文件有時候不能很好的進行優化,所以 llvm-link 提供了把獨立的 IR 文件鏈接在一起的功能。

      我們先生成 print.c 對應的 IR 文件。

      clang -cc1 -emit-llvm print.c
      
      print.c:1:10: fatal error: 'stdio.h' file not found
      
      #include <stdio.h>
      
               ^~~~~~~~~
      
      1 error generated.

      按照剛才的方式,結果報錯了,原因是 我們加入了 -cc1 參數,使用了背后的引擎,沒有調度工具 clang 幫助我們添加指定頭文件目錄的工作。但這也不難,我們通過 --verbose 看看 clang 都加了那些參數。

      clang -c print.c --verbose

      獲得編譯器的更多輸出 ? 把里面的參數復制出來,并修改 -emit-obj 為 -emit-llvm,去掉 -o print.o。

      -cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -mrelax-all -disable-free -disable-llvm-verifier -discard-value-names -main-file-name print.c -mrelocation-model static -mthread-model posix -mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -v -dwarf-column-info -debugger-tuning=gdb -coverage-notes-file /home/cc16-04/test/print.gcno -resource-dir /usr/local/bin/../lib/clang/4.0.0 -internal-isystem /usr/local/include -internal-isystem /usr/local/bin/../lib/clang/4.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir /home/cc16-04/test -ferror-limit 19 -fmessage-length 80 -fobjc-runtime=gcc -fdiagnostics-show-option -x c print.c

       

      得到 print.ll 文件,把兩個 IR 文件鏈接起來

      llvm-link print.ll HelloLLVM.ll -S -o all.ll

      查看 all.ll

      cat all.ll

      同時出現了 print 和 main 兩個定義

      3.7.語法分析

      clang可以輸出程序的抽象語法樹(也可以以圖象形式輸出。)

      clang -cc1 -ast-dump HelloLLVM.c

      3.8. 生成控制流圖

      首先需要安裝graphviz

      sudo apt install graphviz

      對于中間表達的*.ll文件

      opt -dot-cfg all.ll

       生成了main和print各自的dot文件,以main為例

      dot -Tpng .cfg.main.dot -o main.png

       得到


      參考:1. https://github.com/tuoxie007/play_with_llvm/blob/master/ch02.md

      ???2. (24條消息) LLVM 編譯器學習筆記之二十九 -- 控制流程CFG_llvm控制流圖_清鐘沁桐的博客-CSDN博客

      posted @ 2023-07-11 19:08  種玫瑰的小劉  閱讀(1902)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 久久久久香蕉国产线看观看伊| 国产欧美另类久久久精品丝瓜| 风流老熟女一区二区三区| 色哟哟www网站入口成人学校| 亚洲最大天堂在线看视频| 亚洲日韩国产精品第一页一区 | 久久精品无码中文字幕| 成人区人妻精品一区二蜜臀| 欧美和黑人xxxx猛交视频| 中国china露脸自拍性hd| 国产午夜精品理论大片| 国产精品自拍午夜福利| 在线亚洲人成电影网站色www| 亚洲香蕉免费有线视频| 国产中文字幕精品在线| 国产亚洲精品久久久久蜜臀| 被灌满精子的少妇视频| 国产嫩草精品网亚洲av| 国产成AV人片久青草影院| 绯色蜜臀av一区二区不卡| 日韩精品中文字幕国产一| 久久国产热这里只有精品| 亚洲精品自拍在线视频| 狼人大伊人久久一区二区| 狠狠躁夜夜躁无码中文字幕| 国产成人无码区免费内射一片色欲| 巨胸爆乳美女露双奶头挤奶| 国产亚洲精品VA片在线播放| 国产微拍一区二区三区四区| 国产一级三级三级在线视 | 免费无码成人AV片在线| 国产无遮挡性视频免费看| 日本亚洲欧洲无免费码在线| 国产精品熟妇视频国产偷人| 国产国产乱老熟女视频网站97| 综合色天天久久| 达日县| 无码视频一区二区三区| 2020年最新国产精品正在播放| 巩义市| 国产视频一区二区三区四区视频|