[PATCH] [RewriteStatepointsForGC] Exclude noreturn calls from doing GC liveness analysis

Chen Li meloli87 at gmail.com
Tue May 19 13:28:02 PDT 2015


Hi sanjoy, reames,

noreturn calls can never return normally so they do not need GC safepoints. Therefore, don't waste time on doing liveness analysis for them.

http://reviews.llvm.org/D9860

Files:
  lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
  test/Transforms/RewriteStatepointsForGC/noreturn-calls.ll

Index: lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
===================================================================
--- lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
+++ lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
@@ -1003,6 +1003,19 @@
   result.PointerToBase = PointerToBase;
 }
 
+// noreturn call can never return normally so it does not need
+// a GC safepoint. Therefore, don't waste time on doing liveness
+// analysis for it.
+static bool isNoReturnCall(const CallSite &CS) {
+  // Be conservative on invokes
+  if (CS.isInvoke()) { return false; }
+  // Explicitly marked as noreturn
+  if (CS.hasFnAttr(Attribute::NoReturn)) { return true; }
+  // Effectively noreturn if the next instruction is unreachable
+  return CS.getInstruction()->getNextNode() &&
+      isa<UnreachableInst>(CS.getInstruction()->getNextNode());
+}
+
 /// Given an updated version of the dataflow liveness results, update the
 /// liveset and base pointer maps for the call site CS.
 static void recomputeLiveInValues(GCPtrLivenessData &RevisedLivenessData,
@@ -1019,7 +1032,9 @@
   for (size_t i = 0; i < records.size(); i++) {
     struct PartiallyConstructedSafepointRecord &info = records[i];
     const CallSite &CS = toUpdate[i];
-    recomputeLiveInValues(RevisedLivenessData, CS, info);
+    if (!isNoReturnCall(CS)) {
+      recomputeLiveInValues(RevisedLivenessData, CS, info);
+    }
   }
 }
 
@@ -1681,7 +1696,9 @@
   for (size_t i = 0; i < records.size(); i++) {
     struct PartiallyConstructedSafepointRecord &info = records[i];
     const CallSite &CS = toUpdate[i];
-    analyzeParsePointLiveness(DT, OriginalLivenessData, CS, info);
+    if (!isNoReturnCall(CS)) {
+      analyzeParsePointLiveness(DT, OriginalLivenessData, CS, info);
+    }
   }
 }
 
Index: test/Transforms/RewriteStatepointsForGC/noreturn-calls.ll
===================================================================
--- /dev/null
+++ test/Transforms/RewriteStatepointsForGC/noreturn-calls.ll
@@ -0,0 +1,31 @@
+; RUN:  opt %s -rewrite-statepoints-for-gc -spp-print-liveset -S 2>&1 | FileCheck %s
+
+; We're testing to make sure noreturn call does not need liveness analysis and thus
+; there's no live varibales for them 
+
+; CHECK-NOT: Live Variables:
+
+
+%jObject = type { [8 x i8] }
+
+declare void @some_call(%jObject addrspace(1)*)
+
+; Function Attrs: noreturn nounwind
+define void @"test"(%jObject addrspace(1)* %arg, i1 %cond) #0 gc "statepoint-example" {
+bci_0:
+  br i1 %cond, label %branch1, label %branch2
+
+branch1:
+; effectively noreturn call because it's unreachable after call
+  %safepoint_token0 = tail call i32 (i64, i32, void (%jObject addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidp1jObjectf(i64 0, i32 0, void (%jObject addrspace(1)*)* @some_call, i32 1, i32 0, %jObject addrspace(1)* %arg, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i32 0) 
+  unreachable
+
+branch2:
+; explicitly marked as noreturn
+  %safepoint_token1 = tail call i32 (i64, i32, void (%jObject addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidp1jObjectf(i64 0, i32 0, void (%jObject addrspace(1)*)* @some_call, i32 1, i32 0, %jObject addrspace(1)* %arg, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i32 0) noreturn
+  ret void
+}
+
+declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidp1jObjectf(i64, i32, void (%jObject addrspace(1)*)*, i32, i32, ...)
+
+attributes #0 = { noreturn nounwind "gc-add-backedge-safepoints"="true" "gc-add-call-safepoints"="true" "gc-add-entry-safepoints"="true" }

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D9860.26087.patch
Type: text/x-patch
Size: 3540 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150519/df07d125/attachment.bin>


More information about the llvm-commits mailing list