วิธีการทำเสียงดังกราวรวบรวมเพื่อ llvm IR


150

ฉันต้องการเสียงดังกราวด์เพื่อรวบรวมC/C++รหัสของฉันเพื่อLLVMbytecode มากกว่าปฏิบัติการไบนารี ฉันจะบรรลุสิ่งนั้นได้อย่างไร และถ้าฉันได้รับLLVMbytecode ฉันจะนำมันไปใช้เพื่อคอมไพล์มันต่อไปยังไบนารีที่ปฏิบัติการได้

โดยทั่วไปฉันต้องการเพิ่มรหัสของตัวเองลงใน LLVM bytecode ก่อนที่จะคอมไพล์ไปยังโปรแกรมปฏิบัติการไบนารี


ฉันเดาว่ามันถูกเรียกว่าเป็น LLVM bitcode
PreeJackie

คำตอบ:


204

รับไฟล์ C / C ++ บางส่วนfoo.c:

> clang -S -emit-llvm foo.c

ผลิตfoo.llซึ่งเป็นไฟล์ IRVM IR

-emit-llvmตัวเลือกนอกจากนี้ยังสามารถส่งผ่านไปยังคอมไพเลอร์ front-end โดยตรงและไม่ขับรถโดยใช้วิธีการ-cc1:

> clang -cc1 foo.c -emit-llvm

ผลิตfoo.llด้วย IR เพิ่มตัวเลือกในเย็นบางอย่างเช่น-cc1 -ast-printตรวจสอบ-cc1 --helpรายละเอียดเพิ่มเติม


ในการรวบรวม LLVM IR เพิ่มเติมเพื่อประกอบให้ใช้llcเครื่องมือ:

> llc foo.ll

ผลิตfoo.sด้วยชุดประกอบ (ค่าเริ่มต้นกับสถาปัตยกรรมเครื่องที่คุณเรียกใช้) llcเป็นหนึ่งในเครื่องมือ LLVM - การที่นี่เป็นเอกสารประกอบ


7
-S ทำอะไรที่นี่
meawoppl

13
@meawoppl: -S เหมือนใน GCC กล่าวว่าปล่อยต้นฉบับเดิมประกอบมากกว่าประกอบไบนารี
Eli Bendersky

Ahha ฉันมีปัญหาในการค้นหาสิ่งใดในเอกสารเกี่ยวกับเรื่องนี้ มีความปลอดภัยหรือไม่ที่จะสมมติว่ามีธงจำนวนมากในโครงสร้างธง gcc กระจกสะท้อนเสียง
meawoppl

@EliBendersky คุณรู้วิธีรวบรวมไฟล์. c และ. h หลายไฟล์เป็น IR ที่มนุษย์สามารถอ่านได้หนึ่งตัวหรือไม่เพื่อที่ฉันจะสามารถเรียกใช้ IR ได้โดยใช้ 'lli theIrFile'? ขอบคุณ
แคช

1
@cache: รวบรวมแต่ละไฟล์เป็น IR ของตัวเองแล้วใช้ตัวเชื่อมโยง LLVM เพื่อรวม
Eli Bendersky

20

ใช้

clang -emit-llvm -o foo.bc -c foo.c
clang -o foo foo.bc

9
ฉันขอแนะนำให้รักษาความหมายของนามสกุลไว้เหมือนเดิม IOW .oควรอ้างถึงไฟล์วัตถุไบนารี, ไฟล์.sประกอบและอย่างอื่น (ตามแบบแผน.ll) ไปยังไฟล์ IRVM IR มิฉะนั้นมันจะสับสนได้ง่าย Clang / LLVM ไม่มีตัวเชื่อมโยงของตนเองสำหรับวัตถุไบนารี (แม้ว่าจะอยู่ในผลงาน) ตัวเชื่อมโยง LLVM llvm-ldเพิ่งรวมไฟล์ IR หลายไฟล์ไว้ในที่เดียว
Eli Bendersky

1
@EliBendersky: คุณถูกต้องที่เกี่ยวข้องกับนามสกุลไฟล์ - และส่วนหน้าเสียงดังกราวทำในสิ่งที่ถูกต้องหาก.bcใช้ ยังเก็บไว้ในใจว่าllvm-ldสามารถทำหน้าที่เป็นส่วนหน้าสำหรับ toolchain ระบบคือคำตอบก่อนหน้าของฉันโดยใช้llvm-ld -nativeควรจะทำงานตามที่คาดไว้ ....
คริสโต

1
@rickfoosusa: ใช้งานได้สำหรับฉัน - foo.bcเป็นไฟล์บิตโค้ด LLVM
Christoph

1
ได้ผลสำหรับฉัน: clang -emit-llvm -o test.bc -c test.c && file test.bc: test.bc: LLVM IR bitcode.
ntc2

18

หากคุณมีไฟล์ต้นฉบับหลายไฟล์คุณอาจต้องการใช้การเพิ่มประสิทธิภาพลิงค์เวลาเพื่อส่งออกไฟล์บิตโค้ดหนึ่งไฟล์สำหรับโปรแกรมทั้งหมด คำตอบอื่น ๆ ที่ระบุจะทำให้คุณจบลงด้วยไฟล์ bitcode สำหรับไฟล์ต้นฉบับทุกไฟล์

คุณต้องการรวบรวมด้วย link-time-optimization แทน

clang -flto -c program1.c -o program1.o
clang -flto -c program2.c -o program2.o

และสำหรับขั้นตอนการเชื่อมโยงขั้นสุดท้ายให้เพิ่มอาร์กิวเมนต์ -Wl, -plugin-opt = also-emit-llvm

clang -flto -Wl,-plugin-opt=also-emit-llvm program1.o program2.o -o program

สิ่งนี้จะให้ทั้งโปรแกรมที่คอมไพล์และบิตโค้ดที่สอดคล้องกับมัน (program.bc) จากนั้นคุณสามารถแก้ไข program.bc ในแบบที่คุณต้องการและคอมไพล์โปรแกรมที่แก้ไขใหม่ได้ตลอดเวลาโดยทำ

clang program.bc -o program

แม้ว่าจะต้องระวังว่าคุณจำเป็นต้องรวมค่าลิงเกอร์ลิงเกอร์ที่จำเป็น (สำหรับไลบรารีภายนอก ฯลฯ ) ในขั้นตอนนี้อีกครั้ง

โปรดทราบว่าคุณต้องใช้ gold linker เพื่อให้สามารถใช้งานได้ หากคุณต้องการบังคับให้เสียงดังกราวด์ใช้ตัวเชื่อมโยงเฉพาะสร้าง symlink ให้ตัวเชื่อมโยงนั้นชื่อ "ld" ในไดเรกทอรีพิเศษชื่อ "fakebin" ที่ใดที่หนึ่งบนคอมพิวเตอร์ของคุณและเพิ่มตัวเลือก

-B/home/jeremy/fakebin

ไปยังขั้นตอนการเชื่อมโยงใด ๆ ข้างต้น


13

หากคุณมีหลายไฟล์และคุณไม่ต้องการที่จะพิมพ์แต่ละไฟล์ฉันขอแนะนำให้คุณทำตามขั้นตอนง่าย ๆ (ฉันใช้clang-3.8แต่คุณสามารถใช้รุ่นอื่น ๆ ):

  1. สร้าง.llไฟล์ทั้งหมด

    clang-3.8 -S -emit-llvm *.c
  2. เชื่อมโยงพวกเขาเป็นหนึ่งเดียว

    llvm-link-3.8 -S -v -o single.ll *.ll
  3. (ไม่บังคับ) เพิ่มประสิทธิภาพรหัสของคุณ (อาจมีการวิเคราะห์นามแฝง)

    opt-3.8 -S -O3 -aa -basicaaa -tbaa -licm single.ll -o optimised.ll
  4. สร้างชุดประกอบ (สร้างoptimised.sไฟล์)

    llc-3.8 optimised.ll
  5. สร้างปฏิบัติการ (ชื่อa.out)

    clang-3.8 optimised.s

โซลูชันของคุณไม่เหมือนใคร: คุณใช้ "-S" แทนที่จะปล่อยไว้เป็นเอาต์พุตไบนารี การมี "-S" และการไม่มี "-S" แตกต่างกันหรือไม่?
Peter Teoh

@PeterTeoh ฉันใช้-Sตัวเลือก (ในขั้นตอนที่ 2) ฉันระบุว่าฉันต้องการผลิตผลลัพธ์ใน LLVM IR โดยทั่วไปให้ใส่ไฟล์ * .ll ทั้งหมดไว้ในไฟล์เดียว ฉันทำเช่นนี้เพื่อตรวจสอบว่าการเพิ่มประสิทธิภาพจริง ๆ เปลี่ยนรหัสคือsingle.llและoptimised.llตอนนี้ควรมีลักษณะที่แตกต่างกัน (รหัสฉลาด) และคุณสามารถแสดงรายงานเพื่อดูว่ามีความแตกต่างใด ๆ เลย
Kiko Fernandez

-basicaaaเป็นธงผิด-basicaaต้องใช้แทน
anton_rh

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.