[PATCH] D14769: [FunctionAttrs] Calls to libcalls don't cause a function to potentially recurse
James Molloy via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 18 03:51:38 PST 2015
jmolloy created this revision.
jmolloy added reviewers: joker.eph, manmanren, dexonsmith.
jmolloy added a subscriber: llvm-commits.
jmolloy set the repository for this revision to rL LLVM.
If a function calls a library function, that shouldn't be treated as potentially causing a cycle in the CFG. Additionally calls to noreturn functions are norecurse by definition.
Repository:
rL LLVM
http://reviews.llvm.org/D14769
Files:
lib/Transforms/IPO/FunctionAttrs.cpp
test/Transforms/FunctionAttrs/norecurse.ll
Index: test/Transforms/FunctionAttrs/norecurse.ll
===================================================================
--- test/Transforms/FunctionAttrs/norecurse.ll
+++ test/Transforms/FunctionAttrs/norecurse.ll
@@ -1,5 +1,7 @@
; RUN: opt < %s -basicaa -functionattrs -S | FileCheck %s
+target triple = "x86_64-linux-gnu"
+
; CHECK: define i32 @leaf() #0
define i32 @leaf() {
ret i32 1
@@ -53,5 +55,24 @@
ret void
}
+; CHECK: define i32 @calls_exit() #2
+define i32 @calls_exit() {
+ call void @exit(i32 2)
+ ret i32 5
+}
+
+declare void @exit(i32) noreturn
+
+; CHECK: define i32 @calls_only_libcalls() #2
+define i32 @calls_only_libcalls() {
+ %a = call double @sin(double 0.0)
+ call void @fclose(i8* null)
+ ret i32 2
+}
+
+declare double @sin(double)
+declare void @fclose(i8*)
+
; CHECK: attributes #0 = { norecurse readnone }
; CHECK: attributes #1 = { readnone }
+; CHECK: attributes #2 = { norecurse }
\ No newline at end of file
Index: lib/Transforms/IPO/FunctionAttrs.cpp
===================================================================
--- lib/Transforms/IPO/FunctionAttrs.cpp
+++ lib/Transforms/IPO/FunctionAttrs.cpp
@@ -1795,6 +1795,7 @@
}
static bool addNoRecurseAttrs(const CallGraphSCC &SCC,
+ const TargetLibraryInfo &TLI,
SmallVectorImpl<WeakVH> &Revisit) {
// Try and identify functions that do not recurse.
@@ -1804,16 +1805,29 @@
const CallGraphNode *CGN = *SCC.begin();
Function *F = CGN->getFunction();
- if (!F || F->isDeclaration() || F->doesNotRecurse())
+ if (!F || F->doesNotRecurse())
return false;
- // If all of the calls in F are identifiable and are to norecurse functions, F
- // is norecurse. This check also detects self-recursion as F is not currently
- // marked norecurse, so any called from F to F will not be marked norecurse.
+ // A noreturn function by definition cannot recurse.
+ if (F->doesNotReturn())
+ return setDoesNotRecurse(*F);
+
+ if (F->isDeclaration())
+ return false;
+
+ auto IsLibCall = [&](Function *F) {
+ LibFunc::Func LF;
+ return TLI.getLibFunc(F->getName(), LF) && TLI.has(LF);
+ };
+
+ // If all of the calls in F are identifiable and are to norecurse functions or
+ // are libcalls, F is norecurse. This check also detects self-recursion as F
+ // is not currently marked norecurse, so any called from F to F will not be
+ // marked norecurse.
if (std::all_of(CGN->begin(), CGN->end(),
- [](const CallGraphNode::CallRecord &CR) {
+ [&](const CallGraphNode::CallRecord &CR) {
Function *F = CR.second->getFunction();
- return F && F->doesNotRecurse();
+ return F && (F->doesNotRecurse() || IsLibCall(F));
}))
// Function calls a potentially recursive function.
return setDoesNotRecurse(*F);
@@ -1890,8 +1904,8 @@
Changed |= addNoAliasAttrs(SCCNodes);
Changed |= addNonNullAttrs(SCCNodes, *TLI);
}
-
- Changed |= addNoRecurseAttrs(SCC, Revisit);
+
+ Changed |= addNoRecurseAttrs(SCC, *TLI, Revisit);
return Changed;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D14769.40490.patch
Type: text/x-patch
Size: 3165 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151118/50cdff95/attachment.bin>
More information about the llvm-commits
mailing list