कैसे आईआर आईआर को संकलित करने के लिए बनाने के लिए


150

मैं अपने C/C++कोड को LLVMबाइनरी एक्ज़ीक्यूटेबल के बजाय बायटेकोड पर संकलित करना चाहता हूं । मैं उसे कैसे प्राप्त कर सकता हूं? और अगर मुझे LLVMबाइटकोड मिलता है, तो मैं इसे आगे बाइनरी एक्ज़ीक्यूटेबल के लिए कैसे संकलित कर सकता हूं।

मूल रूप से मैं LLVMबाइनरी एक्ज़ीक्यूटेबल को संकलित करने से पहले अपने खुद के कुछ कोड को बाईटकोड में जोड़ना चाहता हूं ।


मुझे लगता है कि इसे LLVM बिटकोड कहा जाता है
PreeJackie

जवाबों:


204

कुछ C / C ++ फ़ाइल दी foo.c:

> clang -S -emit-llvm foo.c

उत्पादन foo.llजो एक LLVM IR फ़ाइल है।

-emit-llvmविकल्प भी के माध्यम से सीधे संकलक सामने के अंत करने के लिए पारित किया जा सकता है और नहीं चालक -cc1:

> clang -cc1 foo.c -emit-llvm

foo.llआईआर के साथ उत्पादन करता है। -cc1जैसे कुछ शांत विकल्प जोड़ता है -ast-print। की जाँच करें -cc1 --helpअधिक जानकारी के लिए।


विधानसभा के लिए आगे एलएलवीएम आईआर संकलित करने के लिए, llcउपकरण का उपयोग करें :

> llc foo.ll

का उत्पादन foo.sविधानसभा (मशीन वास्तुकला आप उस पर चलाने के लिए दोषी) के साथ। llcLLVM टूल में से एक है - यहाँ इसका प्रलेखन है


7
यहाँ क्या करता है?
मेवप्लप

13
@meawoppl: -S जैसे gcc में असेंबली बाइनरी के बजाय टेक्स्ट असेंबली का उत्सर्जन करने के लिए कहा गया है
एली बेंडस्की

Ahha। मुझे इसके बारे में डॉक्स में कुछ भी खोजने में मुश्किल समय हो रहा था। यह मानना ​​सुरक्षित है कि क्लच दर्पण में कई झंडे झंडा संरचना?
मेवापॉप

@EliBendersky क्या आप जानते हैं कि एक मानव पठनीय IR में कई .c और .h फ़ाइलों को कैसे संकलित किया जाता है ताकि मैं 'lli theIrFile' का उपयोग करके IR चला सकूं? साभार
कैश

1
@ कैश: प्रत्येक को अपनी आईआर फाइल में संकलित करें और फिर एलएलवीएम लिंकर का उपयोग करके संयोजन करें
एली बेंडरस्की

20

उपयोग

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

9
मैं विस्तार के अर्थ को बरकरार रखने की सलाह दूंगा। IOW, .oबाइनरी ऑब्जेक्ट फ़ाइलों को, .sअसेंबली फ़ाइलों को और कुछ और (कन्वेंशन द्वारा .ll) LLVM IR फ़ाइलों को संदर्भित करना चाहिए । अन्यथा भ्रमित होना आसान है। क्लैंग / एलएलवीएम के पास अब बाइनरी ऑब्जेक्ट्स के लिए खुद का कोई लिंकर नहीं है (हालांकि एक काम करता है)। एलएलवीएम लिंकर llvm-ldसिर्फ कई आईआर फाइलों को एक में
जोड़ता है

1
@EliBendersky: आप सही हैं जहां फ़ाइल एक्सटेंशन चिंतित हैं - और क्लैंग फ्रंटेंड वास्तव में सही काम करता है यदि .bcउपयोग किया जाता है; यह भी ध्यान रखें कि llvm-ldसिस्टम टूलकिन के लिए अग्रिम के रूप में कार्य कर सकता है, अर्थात मेरे पिछले उत्तर का उपयोग llvm-ld -nativeउम्मीद के अनुसार काम करना चाहिए ....
क्रिस्टोफ

1
@rickfoosusa: मेरे लिए काम करता है - foo.bcएक LLVM बिटकोड फ़ाइल है
क्रिस्टोफ़

1
मेरे लिए काम करता है clang -emit-llvm -o test.bc -c test.c && file test.bc: test.bc: LLVM IR bitcode:।
ntc2

18

यदि आपके पास कई स्रोत फ़ाइलें हैं, तो आप संभवतः पूरे कार्यक्रम के लिए एक बिटकोड फ़ाइल को आउटपुट करने के लिए लिंक-टाइम-ऑप्टिमाइज़ेशन का उपयोग करना चाहते हैं। दिए गए अन्य उत्तर आपको हर स्रोत फ़ाइल के लिए बिटकोड फ़ाइल के साथ समाप्त करने का कारण बनेंगे।

इसके बजाय, आप लिंक-टाइम-ऑप्टिमाइज़ेशन के साथ संकलन करना चाहते हैं

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

और अंतिम लिंकिंग चरण के लिए, तर्क जोड़ें -ll, -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

हालाँकि इस बात से अवगत रहें कि आपको इस कदम पर किसी भी आवश्यक लिंकर झंडे (बाहरी पुस्तकालयों आदि के लिए) को शामिल करने की आवश्यकता है।

ध्यान दें कि आपको काम करने के लिए सोने के लिंकर का उपयोग करने की आवश्यकता है। यदि आप किसी विशिष्ट लिंकर का उपयोग करने के लिए क्लेंग को बाध्य करना चाहते हैं, तो अपने कंप्यूटर पर कहीं और "विशेष" निर्देशिका में "ld" नाम के उस लिंकर के लिए एक सिमलिंक बनाएं, और विकल्प जोड़ें

-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" नहीं होने के बीच कोई अंतर है?
पीटर टेह

@PeterTeoh मैं -Sविकल्प का उपयोग करता हूं (चरण 2 में), मैं निर्दिष्ट करता हूं कि मैं एलएलवीएम आईआर में आउटपुट का उत्पादन करना चाहूंगा। असल में, सभी * .ll फ़ाइलों को एक ही में डालें। मैं इस जांच करने के लिए है कि अनुकूलन वास्तव में कोड बदल सकता हूँ, यानी single.llऔर optimised.llअब अलग दिखना चाहिए (कोड वार) और आप भी अगर वहाँ सब पर कोई फर्क है देखने के लिए रिपोर्ट दिखा सकता है।
किको फर्नांडीज

-basicaaaएक गलत ध्वज है, -basicaaइसके बजाय इसका उपयोग किया जाना चाहिए।
anton_rh

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.