2012-05-06 18 views
6

मैं एक कोर्स के लिए एक सरल सी-जैसी भाषा के लिए एक कंपाइलर लिख रहा हूं। कोड के इस बिट:इस एलएलवीएम रजिस्टर नंबर के साथ क्या गलत है?

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 के बीच के निर्देशों में से कोई भी अनुक्रम संख्या बढ़ाता है? या शायद यह किसी और चीज से सिर्फ एक फॉलो-ऑन गलती है?

उत्तर

9

LLVM में, सब कुछ कि कर सकते हैं एक नाम है लेकिन है एक नंबर दिया जाता है नहीं। इसमें बुनियादी ब्लॉक भी शामिल हैं। आपके मामले में

lab0: 
    ret i32 1 
    br label %lab2 

क्योंकि हर terminator instruction एक बुनियादी ब्लॉक समाप्त होता है दो बुनियादी ब्लॉक परिभाषित करता है। इसका मतलब है कि, धारणात्मक, अपने कोड के रूप में

lab0: 
    ret i32 1 
1: 
    br label %lab2 

और अगले फ्री नंबर के बाद कि 2.

, मैं हमेशा स्पष्ट रूप से बुनियादी ब्लॉक नामकरण की सलाह देते हैं इस तरह अजीब व्यवहार को रोकने के लिए है पार्स किया गया है।

+0

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

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