[PATCH] D151774: [LICM] Don't hoist threadlocals within presplit coroutines
Chuanqi Xu via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 1 19:12:57 PDT 2023
ChuanqiXu updated this revision to Diff 527702.
ChuanqiXu added a comment.
Address comments.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D151774/new/
https://reviews.llvm.org/D151774
Files:
llvm/lib/Transforms/Scalar/LICM.cpp
llvm/test/Transforms/LICM/sink-with-coroutine.ll
Index: llvm/test/Transforms/LICM/sink-with-coroutine.ll
===================================================================
--- llvm/test/Transforms/LICM/sink-with-coroutine.ll
+++ llvm/test/Transforms/LICM/sink-with-coroutine.ll
@@ -48,5 +48,63 @@
ret i64 0
}
+ at tls = thread_local global i32 0
+
+define i64 @hoist_threadlocal() presplitcoroutine {
+; CHECK-LABEL: @hoist_threadlocal
+; CHECK: loop.preheader:
+; CHECK-NEXT: br label %for.body
+; CHECK: for.body:
+; CHECK-NEXT: %i = phi i64
+; CHECK-NEXT: %i.next = add i64 %i
+; CHECK-NEXT: %thread_local.0 = call ptr @llvm.threadlocal.address
+; CHECK-NEXT: %readonly.0 = call ptr @readonly_funcs()
+; CHECK-NEXT: %suspend = call i8 @llvm.coro.suspend
+; CHECK-NEXT: switch i8 %suspend, label %exit
+; CHECK-NEXT: i8 0, label %await.ready
+; CHECK: await.ready:
+; CHECK-NEXT: %thread_local.1 = call ptr @llvm.threadlocal.address
+; CHECK-NEXT: %readonly.1 = call ptr @readonly_funcs()
+entry:
+ %p = alloca i64
+ br label %loop.preheader
+
+loop.preheader:
+ br label %for.body
+
+for.body:
+ %i = phi i64 [ 0, %loop.preheader ], [ %i.next, %loop.end ]
+ %i.next = add i64 %i, 1
+ %thread_local.0 = call ptr @llvm.threadlocal.address(ptr @tls)
+ %readonly.0 = call ptr @readonly_funcs()
+ %suspend = call i8 @llvm.coro.suspend(token none, i1 false)
+ switch i8 %suspend, label %exit [
+ i8 0, label %await.ready
+ ]
+
+await.ready:
+ %thread_local.1 = call ptr @llvm.threadlocal.address(ptr @tls)
+ %readonly.1 = call ptr @readonly_funcs()
+ %cmp.0 = icmp eq ptr %thread_local.0, %thread_local.1
+ %cmp.1 = icmp eq ptr %readonly.0, %readonly.1
+ %cmp = and i1 %cmp.0, %cmp.1
+ br i1 %cmp, label %not.reachable, label %loop.end
+
+not.reachable:
+ call void @not.reachable()
+ br label %loop.end
+
+loop.end:
+ %loop.end.cond = icmp ugt i64 %i.next, 5
+ br i1 %cmp, label %exit, label %for.body
+
+exit:
+ %res = call i1 @llvm.coro.end(ptr null, i1 false)
+ ret i64 0
+}
+
declare i8 @llvm.coro.suspend(token, i1)
declare i1 @llvm.coro.end(ptr, i1)
+declare nonnull ptr @readonly_funcs() readonly
+declare nonnull ptr @llvm.threadlocal.address(ptr nonnull) nounwind readnone willreturn
+declare void @not.reachable()
Index: llvm/lib/Transforms/Scalar/LICM.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/LICM.cpp
+++ llvm/lib/Transforms/Scalar/LICM.cpp
@@ -1219,6 +1219,14 @@
if (CI->isConvergent())
return false;
+ // FIXME: We don't handle the semantics of thread local well. So that the
+ // address of thread locals are fake constants in coroutines. So We forbid
+ // to treat onlyReadsMemory call in coroutines as constants now. Note that
+ // it is possible to hide a thread local access in a onlyReadsMemory call.
+ // Remove this check after we handle the semantics of thread locals well.
+ if (CI->onlyReadsMemory() && CI->getFunction()->isPresplitCoroutine())
+ return false;
+
using namespace PatternMatch;
if (match(CI, m_Intrinsic<Intrinsic::assume>()))
// Assumes don't actually alias anything or throw
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D151774.527702.patch
Type: text/x-patch
Size: 3119 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230602/89bcec92/attachment.bin>
More information about the llvm-commits
mailing list