2010-08-18 13 views
18

मुझे समझ में नहीं आता कि एलएलवीएम जेआईटी सामान्य जेआईटी संकलन से कैसे संबंधित है और दस्तावेज अच्छा नहीं है।एलएलवीएम जेट और मूल

  1. केस 1:: मैं बजना/LLVM साथ देशी सी फ़ाइल संकलन

    उदाहरण के लिए मैं clang सामने अंत का उपयोग लगता है। यह प्रवाह मैं समझता हूं कि जीसीसी प्रवाह की तरह है - मुझे अपना x86 निष्पादन योग्य लगता है और यह चलता है।

  2. केस 2: मैं कुछ प्रकार के एलएलवीएम आईआर में संकलित हूं जो एलएलवीएम जेआईटी पर चलता है। इस मामले में निष्पादन योग्य में जेआईटी पर आईआर निष्पादित करने के लिए एलएलवीएम रनटाइम होता है, या यह कैसे काम करता है?

इन दोनों के बीच क्या अंतर है और क्या वे सही हैं? क्या एलएलवीएम प्रवाह में जेआईटी और गैर जेआईटी दोनों के लिए समर्थन शामिल है? मैं जेआईटी का उपयोग कब करना चाहता हूं - क्या यह सी जैसी भाषा के लिए बिल्कुल समझ में आता है?

उत्तर

30

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

क्लैंग सीएल/सी ++ कोड एलएलवीएम आईआर में अनुवाद करता है और इसे एलएलवीएम पर सौंपता है, जो इसे देशी कोड में संकलित करता है।

एलएलवीएम भी देशी कोड को स्मृति में सीधे उत्पन्न करने में सक्षम है, जिसे तब सामान्य कार्य के रूप में कहा जा सकता है। तो मामला 1. और 2. एलएलवीएम के अनुकूलन और कोड पीढ़ी साझा करें।

तो एलएलवीएम का उपयोग जेआईटी कंपाइलर के रूप में कैसे करता है? आप एक ऐसा एप्लिकेशन बनाते हैं जो कुछ एलएलवीएम आईआर (स्मृति में) उत्पन्न करता है, फिर मूल कोड उत्पन्न करने के लिए एलएलवीएम लाइब्रेरी का उपयोग करें (अभी भी स्मृति में)। एलएलवीएम आपको एक पॉइंटर वापस रखता है जिसे आप बाद में कॉल कर सकते हैं। कोई झुकाव शामिल नहीं है।

हालांकि, आप कुछ सी कोड को एलएलवीएम आईआर में अनुवाद करने के लिए क्लैंग का उपयोग कर सकते हैं और कार्यों का उपयोग करने के लिए इसे अपने जेआईटी संदर्भ में लोड कर सकते हैं।

असली दुनिया उदाहरण:

वहाँ भी है Kaleidoscope ट्यूटोरियल दिखाता है कि किन कैसे JIT कम्पाइलर के साथ एक सरल भाषा को लागू करने।

+0

से तो JIT रूप LLVM उपयोग करने के लिए आप अपने आवेदन में यह लिंक करने के लिए, सही है? क्या ऐसे अनुप्रयोग हैं जो ऐसा करते हैं? – zaharpopov

2

अधिकांश कंप्यूटर्स का फ्रंट एंड, कुछ मध्य कोड/कुछ प्रकार की संरचना, और बैकएंड होता है। जब आप अपना सी प्रोग्राम लेते हैं और क्लैंग का उपयोग करते हैं और संकलित करते हैं कि आप एक गैर-जेआईटी x86 प्रोग्राम के साथ समाप्त हो जाते हैं जिसे आप अभी चला सकते हैं, तो आप अभी भी फ्रंटेंड से मध्य तक बैकएंड तक चले गए हैं। जीसीसी के लिए भी चला जाता है, जीसीसी फ्रंटेंड से एक मध्यम चीज और बैकएंड तक जाता है। जीसीसी मध्यम बात व्यापक रूप से खुली नहीं है और एलएलवीएम की तरह उपयोग योग्य है।

अब एक चीज जो llvm के बारे में मजेदार/रोचक है, कि आप दूसरों के साथ नहीं कर सकते हैं, या कम से कम जीसीसी, यह है कि आप अपने सभी स्रोत कोड मॉड्यूल ले सकते हैं, उन्हें बाइटमोड के लिए संकलित कर सकते हैं, उन्हें एक बड़े में विलय कर सकते हैं बाइटकोड फ़ाइल, फिर प्रति फ़ाइल या प्रति फ़ंक्शंस ऑप्टिमाइज़ेशन के बजाय आपको अन्य कंपाइलर्स के साथ पूरी चीज को अनुकूलित करें, llvm के साथ आप अपनी पसंद के संकलित प्रोग्राम अनुकूलन के आंशिक स्तर का आंशिक प्राप्त कर सकते हैं। तो आप उस बाइटकोड को ले सकते हैं और लक्ष्यों को असेंबलर को निर्यात करने के लिए llc का उपयोग कर सकते हैं। मैं आमतौर पर एम्बेडेड करता हूं इसलिए मेरे पास अपना स्टार्टअप कोड है जो मैं उसके चारों ओर लपेटता हूं लेकिन सिद्धांत में आपको उस असेंबलर फ़ाइल को लेना और जीसीसी संकलन के साथ और इसे लिंक करने और इसे चलाने में सक्षम होना चाहिए। gcc myfile.s -o myfile।मुझे लगता है कि llvm टूल्स को ऐसा करने का कोई तरीका है और binutils या gcc का उपयोग नहीं करना है, लेकिन मैंने समय नहीं लिया है।

मैं LLVM तरह हमेशा एक क्रॉस संकलक है, क्योंकि यह, जीसीसी के विपरीत आप न प्रत्येक लक्ष्य के लिए एक नया एक संकलन और प्रत्येक लक्ष्य के लिए बारीकियों से निपटने के लिए। मुझे नहीं पता कि मेरे पास जेआईटी चीज के लिए कोई उपयोग है जो मैं कह रहा हूं कि मैं इसे क्रॉस कंपाइलर और देशी कंपाइलर के रूप में उपयोग करता हूं।

तो अपने पहले मामले सामने, मध्य, अंत है और इस प्रक्रिया को आप से छिपा हुआ है आप स्रोत के साथ शुरू करने और एक द्विआधारी मिलता है, किया। दूसरा मामला यह है कि अगर मैं सामने और बीच में सही समझता हूं और बीच में प्रतिनिधित्व करने वाली कुछ फाइलों के साथ रुक जाता हूं। फिर मध्य से अंत (विशिष्ट लक्ष्य प्रोसेसर) रनटाइम पर समय पर हो सकता है। बैकएंड में अंतर, दो मामले की मध्य भाषा का वास्तविक समय निष्पादन, संभवतः मामले के बैकएंड से अलग है।

+4

दोनों जीसीसी और आईसीसी में एक एलटीओ और आईपीओ है जो "पूरी चीज को अनुकूलित करता है", इसलिए यह llvm की एक अनूठी विशेषता नहीं है। इसके अलावा, llvm एक "क्रॉस कंपाइलर" नहीं है, यह एक कंपाइलर है, जो एकल बाइनरी में कई लक्ष्यों का समर्थन करता है। यह सरल क्रॉस-कंपाइलर से थोड़ा बेहतर है, यह सार्वभौमिक कंपाइलर है - किसी भी लक्ष्य के लिए काम करता है। – osgx

+0

मुझे वह शब्द "सार्वभौमिक कंपाइलर" पसंद है। अपडेट के लिए धन्यवाद, मुझे नहीं पता था कि आप ऐसा करने के लिए जीसीसी प्राप्त कर सकते हैं, कुछ दिन के साथ खेलने के लिए कुछ। –

22

सबसे पहले, आप LLVM बाईटकोड (LLVM आईआर) मिलती है:

lli test.bc 

कि कार्यक्रम चलाता है:

clang -emit-llvm -S -o test.bc test.c 

दूसरे, आप LLVM JIT का उपयोग करें।

तब, यदि आप देशी प्राप्त करना चाहते हैं, तो आप LLVM बैकएंड का उपयोग करें:

llc test.bc 

विधानसभा उत्पादन से:

as test.S 
5

मैं कदम उठा रहा हूँ संकलन और चलाने के लिए JIT'ed एलएलवीएम समुदाय में एक मेल संदेश से कोड।

[LLVMdev] MCJIT and Kaleidoscope Tutorial

हैडर फ़ाइल:

// foo.h 
extern void foo(void); 

और एक साधारण foo के लिए समारोह() फ़ंक्शन:

//foo.c 
#include <stdio.h> 
void foo(void) { 
    puts("Hello, I'm a shared library"); 
} 

और मुख्य कार्य:

//main.c 
#include <stdio.h> 
#include "foo.h" 
int main(void) { 
    puts("This is a shared library test..."); 
    foo(); 
    return 0; 
} 

Foo.c:

gcc foo.c -shared -o libfoo.so -fPIC 

मुख्य के लिए एलएलवीएम बिटकोड उत्पन्न करके साझा लाइब्रेरी बनाएं।ग फ़ाइल:

clang -Wall -c -emit-llvm -O3 main.c -o main.bc 

और JIT (और MCJIT) के माध्यम से LLVM bitcode चलाने वांछित आउटपुट प्राप्त करने के लिए:

lli -load=./libfoo.so main.bc 
lli -use-mcjit -load=./libfoo.so main.bc 

आप कर सकते हैं lli में भी पाइप बजना उत्पादन:

clang -Wall -c -emit-llvm -O3 main.c -o - | lli -load=./libfoo.so 

आउटपुट

This is a shared library test... 
Hello, I'm a shared library 

स्रोत प्राप्त करना ained

Shared libraries with GCC on Linux

संबंधित मुद्दे