[PATCH] D119571: [funcattrs] use DominatorTree to improve noreturn

Nick Desaulniers via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 11 13:45:01 PST 2022


nickdesaulniers updated this revision to Diff 408041.
nickdesaulniers added a comment.

- use SmallPtrSet, avoid push if visited


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D119571/new/

https://reviews.llvm.org/D119571

Files:
  llvm/lib/Transforms/IPO/FunctionAttrs.cpp
  llvm/test/Transforms/FunctionAttrs/noreturn.ll


Index: llvm/test/Transforms/FunctionAttrs/noreturn.ll
===================================================================
--- llvm/test/Transforms/FunctionAttrs/noreturn.ll
+++ llvm/test/Transforms/FunctionAttrs/noreturn.ll
@@ -40,9 +40,8 @@
   ret i32 %c
 }
 
-; CHECK-NOT: Function Attrs: {{.*}}noreturn
+; CHECK: Function Attrs: {{.*}}noreturn
 ; CHECK: @caller5()
-; We currently don't handle unreachable blocks.
 define i32 @caller5() {
 entry:
   %c = call i32 @noreturn()
@@ -87,4 +86,4 @@
 }
 
 declare token @llvm.coro.id.retcon.once(i32 %size, i32 %align, i8* %buffer, i8* %prototype, i8* %alloc, i8* %free)
-declare i1 @llvm.coro.end(i8*, i1)
\ No newline at end of file
+declare i1 @llvm.coro.end(i8*, i1)
Index: llvm/lib/Transforms/IPO/FunctionAttrs.cpp
===================================================================
--- llvm/lib/Transforms/IPO/FunctionAttrs.cpp
+++ llvm/lib/Transforms/IPO/FunctionAttrs.cpp
@@ -1614,6 +1614,26 @@
   return none_of(BB, instructionDoesNotReturn);
 }
 
+// FIXME: this doesn't handle recursion.
+static bool canReturn(Function &F) {
+  SmallVector<BasicBlock *, 16> Worklist;
+  SmallPtrSet<BasicBlock *, 16> Visited;
+
+  Visited.insert(&F.front());
+  Worklist.push_back(&F.front());
+
+  do {
+    BasicBlock *BB = Worklist.pop_back_val();
+    if (basicBlockCanReturn(*BB))
+      return true;
+    for (BasicBlock *Succ : successors(BB))
+      if (Visited.insert(Succ).second)
+        Worklist.push_back(Succ);
+  } while (!Worklist.empty());
+
+  return false;
+}
+
 // Set the noreturn function attribute if possible.
 static void addNoReturnAttrs(const SCCNodeSet &SCCNodes,
                              SmallSet<Function *, 8> &Changed) {
@@ -1622,9 +1642,7 @@
         F->doesNotReturn())
       continue;
 
-    // The function can return if any basic blocks can return.
-    // FIXME: this doesn't handle recursion or unreachable blocks.
-    if (none_of(*F, basicBlockCanReturn)) {
+    if (!canReturn(*F)) {
       F->setDoesNotReturn();
       Changed.insert(F);
     }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D119571.408041.patch
Type: text/x-patch
Size: 2039 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220211/1e3386c3/attachment.bin>


More information about the llvm-commits mailing list