2012-07-23 6 views
5

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

धन्यवाद!

उत्तर

1

http://llvm.org/docs/LangRef.html#function-attributes के अनुसार आप गुण केवल पढ़ने के लिए तैयार करें या एक समारोह के लिए readnone कर सकते हैं:

declare i32 @fn(i32 %i); 
declare i32 @readonly_fn(i32 %i) readonly; 
declare i32 @readnone_fn(i32 %i) readnone; 

readonly मतलब यह है कि समारोह स्मृति बारे में नहीं है, readnone मतलब है कि यह भी के लिए स्मृति पढ़ा नहीं करता है (उदाहरण पाप() को पढ़ा जा सकता है)

यदि कोई फ़ंक्शन स्मृति नहीं लिखता है, तो इसे केवल पैरामीटर के आधार पर परिणाम लौटा देना चाहिए, और एक शुद्ध कार्य होना चाहिए (यदि वैश्विक स्थिति नहीं बदली जाती है)। रीडोनोन फ़ंक्शन के मामले में, यहां तक ​​कि वैश्विक स्थिति भी बदल सकती है।

LLVM अनुकूलक जैसा कि निम्न उदाहरण में दिखाया गया है कॉल केवल पढ़ने के लिए और EarlyCSE पास (आम उपसूचक उन्मूलन) के साथ readnone कार्यों के लिए, अनुकूलन कर सकते हैं:

निम्न परीक्षण कार्यों

define i32 @test_no_readonly() 
{ 
    %1 = call i32 @fn(i32 0) 
    %2 = call i32 @fn(i32 0) 
    %add = add i32 %1, %2 
    ret i32 %add 
} 
define i32 @test_readonly() 
{ 
    %1 = call i32 @readonly_fn(i32 0) 
    %2 = call i32 @readonly_fn(i32 0) 
    %add = add i32 %1, %2 
    ret i32 %add 
} 
define i32 @test_readnone() 
{ 
    %1 = call i32 @readnone_fn(i32 0) 
    %2 = call i32 @readnone_fn(i32 0) 
    %add = add i32 %1, %2 
    ret i32 %add 
} 

और चल रहा है का उपयोग करते हुए opt -early-cse -S readonly_fn.ll > readonly_fn_opt.ll केवल पढ़ने और पढ़ने के कार्यों के लिए दूसरी कॉल को अनुकूलित करता है, जिसके परिणामस्वरूप

define i32 @test_no_readonly() { 
    %1 = call i32 @fn(i32 0) 
    %2 = call i32 @fn(i32 0) 
    %add = add i32 %1, %2 
    ret i32 %add 
} 

define i32 @test_readonly() { 
    %1 = call i32 @readonly_fn(i32 0) 
    %add = add i32 %1, %1 
    ret i32 %add 
} 

define i32 @test_readnone() { 
    %1 = call i32 @readnone_fn(i32 0) 
    %add = add i32 %1, %1 
    ret i32 %add 
} 

readonly_fn और readnone_fn फ़ंक्शन केवल एक बार बुलाए जाते हैं, इस प्रकार अनावश्यक redundand कॉल।

-functionattrs पास इन विशेषताओं को परिभाषित कार्यों में भी जोड़ सकता है

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

  • कोई संबंधित समस्या नहीं^_^