मैं एक कोर्स के लिए एक सरल सी-जैसी भाषा के लिए एक कंपाइलर लिख रहा हूं। कोड के इस बिट:इस एलएलवीएम रजिस्टर नंबर के साथ क्या गलत है?
int main() {
printInt(not(0));
return 0;
}
int not(int n) {
if (n == 0) {
return 1;
} else {
int result = 0;
return result;
}
}
..मैं भोलेपन से इस bitcode के संकलन:
declare void @printInt(i32)
declare void @printDouble(double)
declare void @printString(i8*)
declare i32 @readInt()
declare double @readDouble()
define i32 @main() {
entry:
%0 = call i32 @not(i32 0)
call void @printInt(i32 %0)
ret i32 0
unreachable
}
define i32 @not(i32 %n_0) {
entry:
%0 = icmp eq i32 %n_0, 0
br i1 %0, label %lab0, label %lab1
lab0:
ret i32 1
br label %lab2
lab1:
%result_0 = alloca i32
store i32 0, i32* %result_0
%1 = load i32* %result_0
ret i32 %1
br label %lab2
lab2:
unreachable
}
हालांकि, ऑप्ट कि कोड को स्वीकार नहीं करता।
opt: core023.ll:25:5: error: instruction expected to be numbered '%2'
%1 = load i32* %result_0
अब, क्या मैं अनाम अस्थायी रजिस्टरों की समझ में वे चाहिए रहे हैं, उससे 0. कौन सा यहाँ मामला है से शुरू क्रमिक रूप से गिने किया जाना है। लेकिन स्पष्ट रूप से "% 1 = sub .." पंक्ति को% 2 क्रमांकित किया जाना चाहिए था। ऐसा क्यों है? % 0 और% 1 के बीच के निर्देशों में से कोई भी अनुक्रम संख्या बढ़ाता है? या शायद यह किसी और चीज से सिर्फ एक फॉलो-ऑन गलती है?
समस्या का कारण समझने का एक और तरीका यह है कि आपको वापसी विवरण के तुरंत बाद शाखाकरण से बचने की आवश्यकता है। यदि आपकी भाषा में यह गारंटी देने के लिए कोड है कि सभी नियंत्रण पथ वापस आते हैं, तो यह जांचने के लिए छोटा होना चाहिए कि आपकी पिछली शाखा अभी तक लौटी है या नहीं। यदि यह वापस आ गया है, तो शाखा (बीआर) निर्देश डालने की कोई आवश्यकता नहीं है। आपके मूल ब्लॉक के साथ एलएलवीएम खुश करने के लिए आपको कुछ राज्य बहीखाता की आवश्यकता होगी। –