LLVM: समस्याएँ
(npopov.com)- LLVM प्रोजेक्ट की संरचनात्मक सीमाओं और तकनीकी debt का कई कोणों से विश्लेषण करते हुए, सुधार की ज़रूरत वाले क्षेत्रों को ठोस रूप से चिन्हित किया गया है
- रिव्यू की कमी, API अस्थिरता, बिल्ड और कंपाइल समय, CI अस्थिरता आदि जैसे बड़े open source प्रोजेक्ट के संचालन में आने वाले bottleneck सामने रखे गए हैं
- IR डिज़ाइन समस्याओं में undef वैल्यू हैंडलिंग, constraint encoding, floating-point semantics, और specification की अपूर्णता जैसी बातें शामिल हैं
- बैकएंड विषमता, ABI हैंडलिंग में भ्रम, GlobalISel·pass manager migration में देरी जैसी दीर्घकालिक संरचनात्मक समस्याओं की ओर इशारा किया गया है
- LLVM की मौजूदा स्थिति को नकारने के बजाय, इसे निरंतर सुधार और व्यापक योगदान के अवसर के रूप में प्रस्तुत किया गया है
प्रमुख संरचनात्मक समस्याएँ
-
रिव्यू क्षमता की कमी को सबसे बड़ा bottleneck बताया गया है
- कोड लिखने वाले लोग ज़्यादा हैं, लेकिन reviewers कम हैं, इसलिए बिना पर्याप्त सत्यापन के changes merge होने के मामले सामने आते हैं
- review request भेजने की ज़िम्मेदारी author पर होने के कारण, नए contributors के लिए सही reviewer ढूँढना मुश्किल होता है
- Rust के PR auto-assignment system को एक सुधार उपाय के रूप में उल्लेख किया गया है
-
API और IR में बार-बार होने वाले बदलाव (churn) उपयोगकर्ताओं पर बोझ डालते हैं
- C API अपेक्षाकृत स्थिर है, लेकिन C++ API अक्सर बदलती रहती है, जिससे frontend और backend की maintenance cost बढ़ती है
- “Upstream or GTFO” दर्शन के कारण shared न होने वाले codebases निर्णय-प्रक्रिया में परिलक्षित नहीं होते
-
बिल्ड समय बहुत अधिक होने की समस्या
- LLVM 25 लाख से अधिक lines के C++ codebase से बना है, इसलिए build time बहुत लंबा है, और debug build में memory तथा disk usage तेज़ी से बढ़ता है
- precompiled headers (PCH), default dylib build, और test daemonization जैसे उपायों पर चर्चा की गई है
-
CI अस्थिरता
- 200 से अधिक build bots अलग-अलग environments में test चलाते हैं, लेकिन हमेशा “green state” बनाए नहीं रख पाते
- flaky tests और build bot समस्याओं के कारण warning signals dilute हो जाते हैं, जिससे असली errors पकड़ना कठिन हो जाता है
- PR pre-submit testing आने से कुछ सुधार हुआ है, लेकिन मूल समस्या अब भी बनी हुई है
-
end-to-end testing की कमी
- अलग-अलग optimization unit tests अच्छे हैं, लेकिन पूरे pipeline या backend integration tests लगभग नहीं के बराबर हैं
llvm-test-suiteमौजूद है, लेकिन यह बुनियादी operations और data type combinations को पर्याप्त रूप से cover नहीं करता
बैकएंड और प्रदर्शन से जुड़ी समस्याएँ
-
बैकएंड्स के बीच विषमता
- मध्य-स्तर एकीकृत है, लेकिन backends में target-दर-target स्वतंत्र संशोधन बहुत हैं, जिससे duplication और divergence बढ़ते हैं
- common optimizations की जगह target-specific hooks जोड़ने की प्रवृत्ति है
-
कंपाइल समय
- JIT और बड़े IR उत्पन्न करने वाली भाषाओं (Rust, C++) में यह धीमा है
-O0builds विशेष रूप से धीमे हैं, और TPDE backend को 10~20 गुना तेज़ विकल्प के रूप में प्रस्तुत किया गया है
-
प्रदर्शन ट्रैकिंग का अभाव
- आधिकारिक runtime performance tracking infrastructure मौजूद नहीं है
- LNT system अस्थिर संचालन, UX समस्याओं और डेटा की कमी के कारण बहुत प्रभावी नहीं है
IR डिज़ाइन समस्याएँ
-
undef वैल्यू हैंडलिंग की जटिलता
- हर use पर अलग value हो सकती है, जिससे optimization के दौरान errors पैदा हो सकते हैं
- भविष्य में इसे poison value से बदला जा सकता है, लेकिन memory में poison handling अभी पर्याप्त नहीं है
-
specification की अपूर्णता और असंगति
- लंबे समय से unresolved miscompilation cases मौजूद हैं
- provenance model जैसी डिज़ाइन-स्तरीय कठिन समस्याएँ भी हैं
- इन्हें सुलझाने के लिए formal specification working group बनाया गया है
-
constraint encoding में सुसंगतता की कमी
- poison flags, metadata, attributes, assumes आदि जैसे कई तरीके मिले-जुले रूप में उपयोग हो रहे हैं
- इससे information loss या जरूरत से ज़्यादा information retention होता है, जो optimization पर नकारात्मक असर डालता है
-
floating-point (FP) semantics की समस्याएँ
- signaling NaN, non-standard environments, denormal handling, x87 excess precision आदि में असंगतियाँ दिखाई देती हैं
- constrained FP intrinsics के अलग handling के कारण जटिलता और बढ़ती है
अन्य तकनीकी समस्याएँ
-
आंशिक migration में देरी
- new pass manager केवल मध्य-स्तर तक लागू है, backend अब भी पुराने सिस्टम का उपयोग करता है
- GlobalISel 10 साल बाद भी पूरी तरह transition नहीं कर पाया है, और SDAG के साथ सह-अस्तित्व में है
-
ABI और calling convention हैंडलिंग में भ्रम
- frontend और backend के बीच responsibility split स्पष्ट नहीं है और documentation भी अपर्याप्त है
- ABI library के परिचय और prototype implementation पर काम चल रहा है
- target features enable होने पर ABI बदल जाने की समस्या भी मौजूद है
-
builtin functions और libcalls प्रबंधन में असंगति
- TargetLibraryInfo और RuntimeLibcalls अलग-अलग हैं, जिससे consistency की कमी है
- runtime libraries (libgcc, compiler-rt आदि) के प्रकार के अनुसार availability की सही समझ नहीं बन पाती
- Rust जैसे बाहरी runtimes के लिए customization points का अभाव है
-
Context / Module संरचना की अक्षमता
- types और constants Context में, जबकि functions और globals Module में मौजूद हैं
- data layout तक पहुँच न होने से constant folding जैसी चीज़ों में असुविधा होती है
- cross-context linking संभव नहीं है, इसलिए संरचना को सरल बनाने की ज़रूरत है
-
LICM (loop-invariant code motion) से बढ़ने वाला register pressure
- बिना cost model के सीधे hoist किया जाता है
- backend बाद में इसे sink नहीं करता, जिससे spill और reload बढ़ जाते हैं
निष्कर्ष
- सूचीबद्ध समस्याएँ LLVM की परिपक्वता और विशाल पैमाने से उपजी संरचनात्मक चुनौतियाँ हैं,
और इन्हें प्रोजेक्ट गुणवत्ता और contributor experience सुधारने के अवसर के रूप में देखा गया है - कुछ क्षेत्रों (build optimization, ABI library, performance tracking आदि) में सुधार का काम पहले से चल रहा है
- कुल मिलाकर LLVM अब भी शक्तिशाली है, लेकिन निरंतर refactoring और specification सुधार अनिवार्य हैं
1 टिप्पणियां
Hacker News प्रतिक्रियाएँ
पूरा लेख बहुत अच्छी तरह व्यवस्थित है, इसलिए उससे काफी सहमति महसूस होती है
आजकल LLVM IR की स्थिरता काफी ऊँची हो गई है। Fil-C को LLVM 17 से 20 पर एक ही दिन में rebase किया गया।
दूसरे प्रोजेक्ट्स में भी कई LLVM versions पर वही pass बनाए रखा, और कोई बड़ी समस्या नहीं हुई
लेकिन LICM का register pressure खासकर C/C++ के अलावा दूसरे sources में गंभीर है। समस्या LICM से ज़्यादा शायद इस बात की है कि regalloc को rematerialize बेहतर तरीके से सीखना चाहिए
अच्छा होगा अगर frontend developers के लिए और options खोले जाएँ ताकि वे अलग-अलग settings को benchmark करके best values चुन सकें
हर tool और component के अपने नियम होते हैं, इसलिए versions के बीच अंतर आना उल्टा स्वाभाविक लगता है। क्या मैं इसे ग़लत समझ रहा हूँ, यह जिज्ञासा है
LLVM 18 को macOS पर build करने के लिए मैंने compiler-rt maintainer से सिर्फ एक boolean बदलने का अनुरोध किया था, लेकिन issue को “heated” कहकर lock कर दिया गया और 4 साल से अब तक unresolved है
फिर भी LLVM अब भी पसंद है। clang-tidy, ASAN, UBSAN, LSAN, MSAN, TSAN सचमुच शानदार हैं।
C/C++ code लिखते समय clang-tidy का इस्तेमाल न करना मुझे ग़लत फैसला लगता है
लेकिन -fbounds-safety सिर्फ AppleClang में है, और MSAN/LSAN सिर्फ LLVM Clang में हैं। Xcode में clang-tidy, clang-format, llvm-symbolizer भी नहीं हैं।
आख़िरकार macOS पर सीधे Darwin LLVM को build करके इस्तेमाल करना पड़ा।
Linux side पर भी काफ़ी भ्रम है। RHEL libcxx नहीं देता, लेकिन Fedora देता है। लेकिन MSAN के लिए instrumented libcxx किसी भी distribution में नहीं है
Fedora लगभग वहाँ तक पहुँच गया है, लेकिन फिर भी compiler-rt को manually build करना पड़ता है
हाल की LLVM चर्चाओं से गुज़रते हुए लगा कि C से नहीं बल्कि LLVM IR से शुरू होने वाली executable test suite सचमुच ज़रूरी है
अगर आप backend सीधे बनाते हैं, तो SelectionDAG या GlobalISel से जुड़ी documentation कम है, और operations का meaning अस्पष्ट होता है, इसलिए ग़लत implementation करना आसान है
C API LLVM में उपेक्षित-सा महसूस होता है। बहुत से options या opt passes expose नहीं किए गए हैं
ज़्यादातर developers सीधे C++ API इस्तेमाल करते हैं, इसलिए C API पीछे छूट जाता है और आख़िर में second-class citizen बना रहता है
code review का तत्काल इनाम नहीं मिलता, इसलिए लोग इसे कम करते हैं
अगर review के लिए भी contribution credit दिया जाए तो शायद motivation बने
6 साल पहले 8GB Dell 9360 laptop पर मैं LLVM को अक्सर build करता था। link parallelism कम कर देने पर memory limit के भीतर यह संभव था
अब भी क्या 8GB पर build हो सकता है, यह जानने की उत्सुकता है
LLVM के शुरुआती दौर में GCC से तेज़ compile speed इसकी ताकत थी।
अब LLVM के 23 साल बाद क्या फिर कुछ नया आएगा, यह सोचने वाली बात है
Cranelift जैसा विकल्प भी है जो LLVM IR का इस्तेमाल नहीं करता (Cranelift GitHub)
ABI और calling convention का handling सबसे बड़ा दर्द है।
compiler frontend में arguments passing को सीधे manage करना पड़ता है, और कभी-कभी register count की गणना तक करनी पड़ती है
लेख में कहा गया था कि “frontend स्थिर C API की वजह से सुरक्षित रहते हैं”, लेकिन हक़ीक़त में ऐसा नहीं है
कुछ APIs स्थिर हैं, लेकिन Orc जैसे हिस्से अक्सर बदलते रहते हैं
LLVM में issue review system लगभग न के बराबर लगता है। मैंने जो bug reports डाली थीं, वे भी कई सालों से पड़ी हैं