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
पास इन विशेषताओं को परिभाषित कार्यों में भी जोड़ सकता है