[llvm-branch-commits] [llvm] 6c43564 - [Coroutine] Improve coro-elide-musttail.ll test
Author: Xun Li Date: 2021-01-22T20:23:48-08:00 New Revision: 6c43564530365ac2c074d7515d4eada294d4ca0c URL: https://github.com/llvm/llvm-project/commit/6c43564530365ac2c074d7515d4eada294d4ca0c DIFF: https://github.com/llvm/llvm-project/commit/6c43564530365ac2c074d7515d4eada294d4ca0c.diff LOG: [Coroutine] Improve coro-elide-musttail.ll test The test wasn't sensitive to alias analysis. As you can seen from D95117 when AA is added by default this is affected. Updating the test so that it coveres both cases for AA analysis. Note that this patch depends on D95117 to land first. Differential Revision: https://reviews.llvm.org/D95247 Added: Modified: llvm/test/Transforms/Coroutines/coro-elide-musttail.ll Removed: diff --git a/llvm/test/Transforms/Coroutines/coro-elide-musttail.ll b/llvm/test/Transforms/Coroutines/coro-elide-musttail.ll index 26f9b5826920..2920bacb5635 100644 --- a/llvm/test/Transforms/Coroutines/coro-elide-musttail.ll +++ b/llvm/test/Transforms/Coroutines/coro-elide-musttail.ll @@ -2,7 +2,10 @@ ; Only run with new pass manager since old pass manager's alias analysis isn't ; powerful enough to tell that the tailcall's arguments don't alias the frame. ; +; RUN: opt < %s -coro-elide -S | FileCheck %s +; RUN: opt < %s -disable-basic-aa -coro-elide -S | FileCheck %s -check-prefix=NOAA ; RUN: opt < %s -passes='coro-elide' -S | FileCheck %s +; RUN: opt < %s -aa-pipeline= -passes='coro-elide' -S | FileCheck %s -check-prefix=NOAA %"bar.Frame" = type { void (%"bar.Frame"*)*, void (%"bar.Frame"*)*, %"struct.coroutine::promise_type", i1 } %"struct.coroutine::promise_type" = type { i32 } @@ -14,6 +17,7 @@ declare dso_local void @"bar"() align 2 declare dso_local fastcc void @"bar.resume"(%"bar.Frame"*) align 2 +; There is a musttail call. CoroElide won't happen. define internal fastcc void @foo.resume_musttail(%"foo.Frame"* %FramePtr) { ; CHECK-LABEL: @foo.resume_musttail( ; CHECK-NEXT: entry: @@ -34,8 +38,32 @@ entry: ret void } -define internal fastcc void @foo.resume_no_musttail(%"foo.Frame"* %FramePtr) { -; CHECK-LABEL: @foo.resume_no_musttail( +; The new frame (TMP0) could potentially alias CALL34, the tailcall attribute on that call must be removed +define internal fastcc void @foo.resume_no_musttail_with_alias(%"foo.Frame"* %FramePtr) { +; CHECK-LABEL: @foo.resume_no_musttail_with_alias( +; CHECK-NEXT: entry: +; CHECK-NEXT:[[TMP0:%.*]] = alloca [24 x i8], align 8 +; CHECK-NEXT:[[VFRAME:%.*]] = bitcast [24 x i8]* [[TMP0]] to i8* +; CHECK-NEXT:[[TMP1:%.*]] = tail call token @llvm.coro.id(i32 16, i8* null, i8* bitcast (void ()* @bar to i8*), i8* bitcast ([3 x void (%bar.Frame*)*]* @bar.resumers to i8*)) +; CHECK-NEXT:call fastcc void undef(i8* [[VFRAME]]) +; CHECK-NEXT:[[CALL34:%.*]] = call i8* undef() +; CHECK-NEXT:call fastcc void undef(i8* [[CALL34]]) +; CHECK-NEXT:ret void +; +entry: + %0 = tail call token @llvm.coro.id(i32 16, i8* null, i8* bitcast (void ()* @"bar" to i8*), i8* bitcast ([3 x void (%"bar.Frame"*)*]* @"bar.resumers" to i8*)) + %1 = tail call i1 @llvm.coro.alloc(token %0) + %2 = tail call i8* @llvm.coro.begin(token %0, i8* null) + call i8* @llvm.coro.subfn.addr(i8* %2, i8 1) + call fastcc void undef(i8* %2) + %call34 = call i8* undef() + tail call fastcc void undef(i8* %call34) + ret void +} + +; The new frame (TMP0) does not alias CALL34, tailcall attribute can reimain. This analysis is only available when alias analysis is enabled. +define internal fastcc void @foo.resume_no_musttail_no_alias(%"foo.Frame"* %FramePtr) { +; CHECK-LABEL: @foo.resume_no_musttail_no_alias( ; CHECK-NEXT: entry: ; CHECK-NEXT:[[TMP0:%.*]] = alloca [24 x i8], align 8 ; CHECK-NEXT:[[VFRAME:%.*]] = bitcast [24 x i8]* [[TMP0]] to i8* @@ -44,6 +72,15 @@ define internal fastcc void @foo.resume_no_musttail(%"foo.Frame"* %FramePtr) { ; CHECK-NEXT:tail call fastcc void undef(i8* [[CALL34]]) ; CHECK-NEXT:ret void ; +; NOAA-LABEL: @foo.resume_no_musttail_no_alias( +; NOAA-NEXT: entry: +; NOAA-NEXT:[[TMP0:%.*]] = alloca [24 x i8], align 8 +; NOAA-NEXT:[[VFRAME:%.*]] = bitcast [24 x i8]* [[TMP0]] to i8* +; NOAA-NEXT:[[TMP1:%.*]] = call token @llvm.coro.id(i32 16, i8* null, i8* bitcast (void ()* @bar to i8*), i8* bitcast ([3 x void (%bar.Frame*)*]* @bar.resumers to i8*)) +; NOAA-NEXT:[[CALL34:%.*]] = call i8* undef() +; NOAA-NEXT:call fastcc void undef(i8* [[CALL34]]) +; NOAA-NEXT:ret void +; entry: %0 = tail call token @llvm.coro.id(i32 16, i8* null, i8* bitcast (void ()* @"bar" to i8*), i8* bitcast ([3 x void (%"bar.Frame"*)*]* @"bar.resumers" to i8*)) %1 = tail call i1 @llvm.coro.alloc(token %0) @@ -54,6 +91,7 @@ entry: ret void } + ; Function Attrs: argmemonly nofree nosync nounwind willreturn declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #0
[llvm-branch-commits] [llvm] 17c3538 - Revert "Fix unused variable in CoroFrame.cpp when building Release with GCC 10"
Author: Xun Li Date: 2021-01-25T08:37:45-08:00 New Revision: 17c3538aef656178b342573043eff328f5cf2673 URL: https://github.com/llvm/llvm-project/commit/17c3538aef656178b342573043eff328f5cf2673 DIFF: https://github.com/llvm/llvm-project/commit/17c3538aef656178b342573043eff328f5cf2673.diff LOG: Revert "Fix unused variable in CoroFrame.cpp when building Release with GCC 10" This reverts commit ff5e896425577f445ed080d88b582aab0896fba0. Added: Modified: llvm/lib/Transforms/Coroutines/CoroFrame.cpp Removed: diff --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp index 3f290f2f087b..cd5c1863bb3c 100644 --- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp @@ -1549,7 +1549,6 @@ static void rewritePHIs(BasicBlock &BB) { for (BasicBlock *Pred : Preds) { if (CatchSwitchInst *CS = dyn_cast(Pred->getTerminator())) { -(void)CS; // CleanupPad with a CatchSwitch predecessor: therefore this is an // unwind destination that needs to be handle specially. assert(CS->getUnwindDest() == &BB); ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [libc] af2439f - [libc][Obvious] Add header guards for the generated linux syscall header file.
Author: Siva Chandra Reddy Date: 2021-08-30T17:41:45-07:00 New Revision: af2439f559cb6fcb8db797e58adde6b9ec0457cb URL: https://github.com/llvm/llvm-project/commit/af2439f559cb6fcb8db797e58adde6b9ec0457cb DIFF: https://github.com/llvm/llvm-project/commit/af2439f559cb6fcb8db797e58adde6b9ec0457cb.diff LOG: [libc][Obvious] Add header guards for the generated linux syscall header file. Added: Modified: libc/config/linux/syscall.h.def Removed: diff --git a/libc/config/linux/syscall.h.def b/libc/config/linux/syscall.h.def index 7f52a26ff0e7b..0daceaf00dded 100644 --- a/libc/config/linux/syscall.h.def +++ b/libc/config/linux/syscall.h.def @@ -6,4 +6,9 @@ // //===--===// +#ifndef LLVM_LIBC_CONFIG_LINUX_SYSCALL_H +#define LLVM_LIBC_CONFIG_LINUX_SYSCALL_H + %%include_file(${inline_syscalls}) + +#endif // LLVM_LIBC_CONFIG_LINUX_SYSCALL_H ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] ff5e896 - Fix unused variable in CoroFrame.cpp when building Release with GCC 10
Author: Daniel Paoliello Date: 2021-01-13T22:53:25-08:00 New Revision: ff5e896425577f445ed080d88b582aab0896fba0 URL: https://github.com/llvm/llvm-project/commit/ff5e896425577f445ed080d88b582aab0896fba0 DIFF: https://github.com/llvm/llvm-project/commit/ff5e896425577f445ed080d88b582aab0896fba0.diff LOG: Fix unused variable in CoroFrame.cpp when building Release with GCC 10 When building with GCC 10, the following warning is reported: ``` /llvm-project/llvm/lib/Transforms/Coroutines/CoroFrame.cpp:1527:28: warning: unused variable ‘CS’ [-Wunused-variable] 1527 | if (CatchSwitchInst *CS = ``` This change adds a cast to `void` to avoid the warning. Reviewed By: lxfind Differential Revision: https://reviews.llvm.org/D94456 Added: Modified: llvm/lib/Transforms/Coroutines/CoroFrame.cpp Removed: diff --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp index 84b78fce3f44..16e7e2c2ceaf 100644 --- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp @@ -1535,6 +1535,7 @@ static void rewritePHIs(BasicBlock &BB) { for (BasicBlock *Pred : Preds) { if (CatchSwitchInst *CS = dyn_cast(Pred->getTerminator())) { +(void)CS; // CleanupPad with a CatchSwitch predecessor: therefore this is an // unwind destination that needs to be handle specially. assert(CS->getUnwindDest() == &BB); ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 1d04dc5 - [Coroutine] Do not CoroElide if there are musttail calls
Author: Xun Li Date: 2021-01-18T09:06:21-08:00 New Revision: 1d04dc52dd24d791970e56053cdd67fe149b0554 URL: https://github.com/llvm/llvm-project/commit/1d04dc52dd24d791970e56053cdd67fe149b0554 DIFF: https://github.com/llvm/llvm-project/commit/1d04dc52dd24d791970e56053cdd67fe149b0554.diff LOG: [Coroutine] Do not CoroElide if there are musttail calls This is to address https://bugs.llvm.org/show_bug.cgi?id=48626. When there are musttail calls that use parameters aliasing the newly created coroutine frame, the existing implementation will fatal. We simply cannot perform CoroElide in such cases. In theory a precise analysis can be done to check whether the parameters of the musttail call actually alias the frame, but it's very hard to do it before the transformation happens. Also in most cases the existence of musttail call is generated due to symmetric transfers, and in those cases alias analysis won't be able to tell that they don't alias anyway. Differential Revision: https://reviews.llvm.org/D94834 Added: llvm/test/Transforms/Coroutines/coro-elide-musttail.ll Modified: llvm/lib/Transforms/Coroutines/CoroElide.cpp Removed: diff --git a/llvm/lib/Transforms/Coroutines/CoroElide.cpp b/llvm/lib/Transforms/Coroutines/CoroElide.cpp index a0b8168f8717..07a183cfc66b 100644 --- a/llvm/lib/Transforms/Coroutines/CoroElide.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroElide.cpp @@ -83,14 +83,8 @@ static void removeTailCallAttribute(AllocaInst *Frame, AAResults &AA) { Function &F = *Frame->getFunction(); for (Instruction &I : instructions(F)) if (auto *Call = dyn_cast(&I)) - if (Call->isTailCall() && operandReferences(Call, Frame, AA)) { -// FIXME: If we ever hit this check. Evaluate whether it is more -// appropriate to retain musttail and allow the code to compile. -if (Call->isMustTailCall()) - report_fatal_error("Call referring to the coroutine frame cannot be " - "marked as musttail"); + if (Call->isTailCall() && operandReferences(Call, Frame, AA)) Call->setTailCall(false); - } } // Given a resume function @f.resume(%f.frame* %frame), returns the size @@ -252,7 +246,20 @@ bool Lowerer::shouldElide(Function *F, DominatorTree &DT) const { // If size of the set is the same as total number of coro.begin, that means we // found a coro.free or coro.destroy referencing each coro.begin, so we can // perform heap elision. - return ReferencedCoroBegins.size() == CoroBegins.size(); + if (ReferencedCoroBegins.size() != CoroBegins.size()) +return false; + + // If any call in the function is a musttail call, it usually won't work + // because we cannot drop the tailcall attribute, and a tail call will reuse + // the entire stack where we are going to put the new frame. In theory a more + // precise analysis can be done to check whether the new frame aliases with + // the call, however it's challenging to do so before the elision actually + // happened. + for (BasicBlock &BB : *F) +if (BB.getTerminatingMustTailCall()) + return false; + + return true; } void Lowerer::collectPostSplitCoroIds(Function *F) { diff --git a/llvm/test/Transforms/Coroutines/coro-elide-musttail.ll b/llvm/test/Transforms/Coroutines/coro-elide-musttail.ll new file mode 100644 index ..751190413b03 --- /dev/null +++ b/llvm/test/Transforms/Coroutines/coro-elide-musttail.ll @@ -0,0 +1,74 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; Only run with new pass manager since old pass manager's alias analysis isn't +; powerful enough to tell that the tailcall's arguments don't alias the frame. +; +; RUN: opt < %s -passes='coro-elide' -S | FileCheck %s + +%"bar.Frame" = type { void (%"bar.Frame"*)*, void (%"bar.Frame"*)*, %"struct.coroutine::promise_type", i1 } +%"struct.coroutine::promise_type" = type { i32 } +%"foo.Frame" = type { void (%"foo.Frame"*)*, void (%"foo.Frame"*)*, %"struct.coroutine::promise_type", i1, %"struct.coroutine::promise_type::final_awaitable" } +%"struct.coroutine::promise_type" = type { i32 } +%"struct.coroutine::promise_type::final_awaitable" = type { i8 } +@"bar.resumers" = private constant [3 x void (%"bar.Frame"*)*] [void (%"bar.Frame"*)* @"bar.resume", void (%"bar.Frame"*)* undef, void (%"bar.Frame"*)* undef] + +declare dso_local void @"bar"() align 2 +declare dso_local fastcc void @"bar.resume"(%"bar.Frame"*) align 2 + +define internal fastcc void @foo.resume_musttail(%"foo.Frame"* %FramePtr) { +; CHECK-LABEL: @foo.resume_musttail( +; CHECK-NEXT: entry: +; CHECK-NEXT:[[TMP0:%.*]] = tail call token @llvm.coro.id +; CHECK-NEXT:[[TMP1:%.*]] = tail call i1 @llvm.coro.alloc(token [[TMP0]]) +; CHECK-NEXT:[[TMP2:%.*]] = tail call i8* @llvm.coro.begin(token [[TMP0]], i8* null) +; CHECK-NEXT:[[CALL34:%.*]] = call i8* undef() +; CH
[llvm-branch-commits] [llvm] bd3ca66 - [Inlining] Delete redundant optnone/alwaysinline check
Author: Xun Li Date: 2021-01-21T18:38:10-08:00 New Revision: bd3cad14464b1bb7eecbd3cc227ee0614799 URL: https://github.com/llvm/llvm-project/commit/bd3cad14464b1bb7eecbd3cc227ee0614799 DIFF: https://github.com/llvm/llvm-project/commit/bd3cad14464b1bb7eecbd3cc227ee0614799.diff LOG: [Inlining] Delete redundant optnone/alwaysinline check The same check is done in InlineCost: https://github.com/llvm/llvm-project/blob/8b0bd54d0ec968df28ccc58bbb537a7b7c074ef2/llvm/lib/Analysis/InlineCost.cpp#L2537-L2552 Also, doing a check on the callee here is confusing, because anything that deals with callee should be done in the inner loop where we proecss all calls from the same caller. Differential Revision: https://reviews.llvm.org/D95186 Added: Modified: llvm/lib/Transforms/IPO/Inliner.cpp Removed: diff --git a/llvm/lib/Transforms/IPO/Inliner.cpp b/llvm/lib/Transforms/IPO/Inliner.cpp index 574d870bccd8..a7d7594c00b3 100644 --- a/llvm/lib/Transforms/IPO/Inliner.cpp +++ b/llvm/lib/Transforms/IPO/Inliner.cpp @@ -761,12 +761,6 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC, LazyCallGraph::Node &N = *CG.lookup(F); if (CG.lookupSCC(N) != C) continue; -if (!Calls[I].first->getCalledFunction()->hasFnAttribute( -Attribute::AlwaysInline) && -F.hasOptNone()) { - setInlineRemark(*Calls[I].first, "optnone attribute"); - continue; -} LLVM_DEBUG(dbgs() << "Inlining calls in: " << F.getName() << "\n"); ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 3e2b424 - Remove RefSCC::handleTrivialEdgeInsertion
Author: Xun Li Date: 2021-01-04T20:21:01-08:00 New Revision: 3e2b42489f897ededae1d3269dcaf084da692111 URL: https://github.com/llvm/llvm-project/commit/3e2b42489f897ededae1d3269dcaf084da692111 DIFF: https://github.com/llvm/llvm-project/commit/3e2b42489f897ededae1d3269dcaf084da692111.diff LOG: Remove RefSCC::handleTrivialEdgeInsertion This function no longer does anything useful. It probably did something originally but latter changes removed them and didn't clean up this function. The checks are already done in the callers as well. Differential Revision: https://reviews.llvm.org/D94055 Added: Modified: llvm/include/llvm/Analysis/LazyCallGraph.h llvm/lib/Analysis/LazyCallGraph.cpp Removed: diff --git a/llvm/include/llvm/Analysis/LazyCallGraph.h b/llvm/include/llvm/Analysis/LazyCallGraph.h index 7478e1726366..e92134d074e5 100644 --- a/llvm/include/llvm/Analysis/LazyCallGraph.h +++ b/llvm/include/llvm/Analysis/LazyCallGraph.h @@ -598,10 +598,6 @@ class LazyCallGraph { void verify(); #endif -/// Handle any necessary parent set updates after inserting a trivial ref -/// or call edge. -void handleTrivialEdgeInsertion(Node &SourceN, Node &TargetN); - public: using iterator = pointee_iterator::const_iterator>; using range = iterator_range; diff --git a/llvm/lib/Analysis/LazyCallGraph.cpp b/llvm/lib/Analysis/LazyCallGraph.cpp index 26529891bc03..ab6946ee96be 100644 --- a/llvm/lib/Analysis/LazyCallGraph.cpp +++ b/llvm/lib/Analysis/LazyCallGraph.cpp @@ -1373,23 +1373,6 @@ LazyCallGraph::RefSCC::removeInternalRefEdge(Node &SourceN, return Result; } -void LazyCallGraph::RefSCC::handleTrivialEdgeInsertion(Node &SourceN, - Node &TargetN) { - // The only trivial case that requires any graph updates is when we add new - // ref edge and may connect diff erent RefSCCs along that path. This is only - // because of the parents set. Every other part of the graph remains constant - // after this edge insertion. - assert(G->lookupRefSCC(SourceN) == this && "Source must be in this RefSCC."); - RefSCC &TargetRC = *G->lookupRefSCC(TargetN); - if (&TargetRC == this) -return; - -#ifdef EXPENSIVE_CHECKS - assert(TargetRC.isDescendantOf(*this) && - "Target must be a descendant of the Source."); -#endif -} - void LazyCallGraph::RefSCC::insertTrivialCallEdge(Node &SourceN, Node &TargetN) { #ifndef NDEBUG @@ -1420,9 +1403,6 @@ void LazyCallGraph::RefSCC::insertTrivialCallEdge(Node &SourceN, // Create the new edge. SourceN->Edges.emplace_back(TargetN, Edge::Call); } - - // Now that we have the edge, handle the graph fallout. - handleTrivialEdgeInsertion(SourceN, TargetN); } void LazyCallGraph::RefSCC::insertTrivialRefEdge(Node &SourceN, Node &TargetN) { @@ -1449,9 +1429,6 @@ void LazyCallGraph::RefSCC::insertTrivialRefEdge(Node &SourceN, Node &TargetN) { // Create the new edge. SourceN->Edges.emplace_back(TargetN, Edge::Ref); - - // Now that we have the edge, handle the graph fallout. - handleTrivialEdgeInsertion(SourceN, TargetN); } void LazyCallGraph::RefSCC::replaceNodeFunction(Node &N, Function &NewF) { ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 4652718 - Cleanup coro-inline.ll
Author: Xun Li Date: 2020-12-18T08:05:04-08:00 New Revision: 4652718ee38c519c6bb9470758d07430b0de02dd URL: https://github.com/llvm/llvm-project/commit/4652718ee38c519c6bb9470758d07430b0de02dd DIFF: https://github.com/llvm/llvm-project/commit/4652718ee38c519c6bb9470758d07430b0de02dd.diff LOG: Cleanup coro-inline.ll Following up with the comments in D92706. - Use -passes instead of -enable-new-pm - CoroEarly should happen before AlwaysInliner, adjust it. - Remove some unnecessary barriers (still kept one) - Cleanup unnecessary debug info Differential Revision: https://reviews.llvm.org/D93342 Added: Modified: llvm/test/Transforms/Coroutines/coro-inline.ll Removed: diff --git a/llvm/test/Transforms/Coroutines/coro-inline.ll b/llvm/test/Transforms/Coroutines/coro-inline.ll index fc5c1d0d6b1f..2cc679a0127d 100644 --- a/llvm/test/Transforms/Coroutines/coro-inline.ll +++ b/llvm/test/Transforms/Coroutines/coro-inline.ll @@ -1,7 +1,7 @@ -; RUN: opt < %s -always-inline -barrier -coro-early -barrier -coro-split -S | FileCheck %s -; RUN: opt < %s -enable-new-pm -always-inline -coro-early -coro-split -S | FileCheck %s -; RUN: opt < %s -sample-profile-file=%S/Inputs/sample.text.prof -pgo-kind=pgo-sample-use-pipeline -coro-early -barrier -sample-profile -barrier -coro-split -disable-inlining=true -S | FileCheck %s -; RUN: opt < %s -enable-new-pm -sample-profile-file=%S/Inputs/sample.text.prof -pgo-kind=pgo-sample-use-pipeline -coro-early -sample-profile -coro-split -disable-inlining=true -S | FileCheck %s +; RUN: opt < %s -always-inline -barrier -coro-split -S | FileCheck %s +; RUN: opt < %s -passes='always-inline,cgscc(coro-split)' -S | FileCheck %s +; RUN: opt < %s -sample-profile-file=%S/Inputs/sample.text.prof -pgo-kind=pgo-sample-use-pipeline -sample-profile -coro-split -disable-inlining=true -S | FileCheck %s +; RUN: opt < %s -sample-profile-file=%S/Inputs/sample.text.prof -pgo-kind=pgo-sample-use-pipeline -passes='sample-profile,cgscc(coro-split)' -disable-inlining=true -S | FileCheck %s ; Function Attrs: alwaysinline ssp uwtable define void @ff() #0 !dbg !12 { @@ -11,7 +11,6 @@ entry: ret void } -; CHECK: call void @ff() ; Function Attrs: alwaysinline ssp uwtable define void @foo() #0 !dbg !8 { entry: @@ -20,11 +19,14 @@ entry: call void @ff(), !dbg !11 ret void } +; CHECK-LABEL: define void @foo() +; CHECK: call void @ff() + declare token @llvm.coro.id(i32, i8* readnone, i8* nocapture readonly, i8*) declare i8* @llvm.coro.begin(token, i8* writeonly) -attributes #0 = { alwaysinline ssp uwtable "coroutine.presplit"="1" "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+cx8,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-sample-profile" "use-soft-float"="false" } +attributes #0 = { alwaysinline ssp uwtable "coroutine.presplit"="1" "use-sample-profile" } !llvm.dbg.cu = !{!0} !llvm.module.flags = !{!3, !4, !5, !6} ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 80b0f74 - Small improvements to Intrinsic::getName
Author: Xun Li Date: 2020-12-02T16:49:12-08:00 New Revision: 80b0f74c8c539b2385f897467aa99b2b6b298c04 URL: https://github.com/llvm/llvm-project/commit/80b0f74c8c539b2385f897467aa99b2b6b298c04 DIFF: https://github.com/llvm/llvm-project/commit/80b0f74c8c539b2385f897467aa99b2b6b298c04.diff LOG: Small improvements to Intrinsic::getName While I was adding a new intrinsic instruction (not overloaded), I accidentally used CreateUnaryIntrinsic to create the intrinsics, which turns out to be passing the type list to getName, and ended up naming the intrinsics function with type suffix, which leads to wierd bugs latter on. It took me a long time to debug. It seems a good idea to add an assertion in getName so that it fails if types are passed but it's not a overloaded function. Also, the overloade version of getName is less efficient because it creates an std::string. We should avoid calling it if we know that there are no types provided. Differential Revision: https://reviews.llvm.org/D92523 Added: Modified: llvm/lib/IR/Function.cpp Removed: diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index a2857707..37fa3d272781 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -781,6 +781,8 @@ StringRef Intrinsic::getName(ID id) { std::string Intrinsic::getName(ID id, ArrayRef Tys) { assert(id < num_intrinsics && "Invalid intrinsic ID!"); + assert((Tys.empty() || Intrinsic::isOverloaded(id)) && + "This version of getName is for overloaded intrinsics only"); std::string Result(IntrinsicNameTable[id]); for (Type *Ty : Tys) { Result += "." + getMangledTypeStr(Ty); @@ -1243,7 +1245,7 @@ Function *Intrinsic::getDeclaration(Module *M, ID id, ArrayRef Tys) { // There can never be multiple globals with the same name of diff erent types, // because intrinsics must be a specific type. return cast( - M->getOrInsertFunction(getName(id, Tys), + M->getOrInsertFunction(Tys.empty() ? getName(id) : getName(id, Tys), getType(M->getContext(), id, Tys)) .getCallee()); } ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 31e60b9 - [coroutine] should disable inline before calling coro split
Author: Xun Li Date: 2020-12-08T08:53:08-08:00 New Revision: 31e60b9133596c185e6daac7f1761dc17e464826 URL: https://github.com/llvm/llvm-project/commit/31e60b9133596c185e6daac7f1761dc17e464826 DIFF: https://github.com/llvm/llvm-project/commit/31e60b9133596c185e6daac7f1761dc17e464826.diff LOG: [coroutine] should disable inline before calling coro split This is a rework of D85812, which didn't land. When callee coroutine function is inlined into caller coroutine function before coro-split pass, llvm will emits "coroutine should have exactly one defining @llvm.coro.begin". It seems that coro-early pass can not handle this quiet well. So we believe that unsplited coroutine function should not be inlined. This patch fix such issue by not inlining function if it has attribute "coroutine.presplit" (it means the function has not been splited) to fix this issue test plan: check-llvm, check-clang In D85812, there was suggestions on moving the macros to Attributes.td to avoid circular header dependency issue. I believe it's not worth doing just to be able to use one constant string in one place. Today, there are already 3 possible attribute values for "coroutine.presplit": https://github.com/llvm/llvm-project/blob/c6543cc6b8f107b58e7205d8fc64865a508bacba/llvm/lib/Transforms/Coroutines/CoroInternal.h#L40-L42 If we move them into Attributes.td, we would be adding 3 new attributes to EnumAttr, just to support this, which I think is an overkill. Instead, I think the best way to do this is to add an API in Function class that checks whether this function is a coroutine, by checking the attribute by name directly. Differential Revision: https://reviews.llvm.org/D92706 Added: llvm/test/Transforms/Coroutines/Inputs/sample.text.prof llvm/test/Transforms/Coroutines/coro-inline.ll Modified: llvm/include/llvm/IR/Function.h llvm/lib/Analysis/InlineCost.cpp llvm/lib/Transforms/IPO/AlwaysInliner.cpp Removed: diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h index cf61db1d33479..019e3a98a1af5 100644 --- a/llvm/include/llvm/IR/Function.h +++ b/llvm/include/llvm/IR/Function.h @@ -268,6 +268,12 @@ class Function : public GlobalObject, public ilist_node { getContext(), AttributeList::FunctionIndex, Kind)); } + /// A function will have the "coroutine.presplit" attribute if it's + /// a coroutine and has not gone through full CoroSplit pass. + bool isPresplitCoroutine() const { +return hasFnAttribute("coroutine.presplit"); + } + enum ProfileCountType { PCT_Invalid, PCT_Real, PCT_Synthetic }; /// Class to represent profile counts. diff --git a/llvm/lib/Analysis/InlineCost.cpp b/llvm/lib/Analysis/InlineCost.cpp index 077b05edcd136..5ee12818e44cc 100644 --- a/llvm/lib/Analysis/InlineCost.cpp +++ b/llvm/lib/Analysis/InlineCost.cpp @@ -2332,6 +2332,13 @@ Optional llvm::getAttributeBasedInliningDecision( if (!Callee) return InlineResult::failure("indirect call"); + // When callee coroutine function is inlined into caller coroutine function + // before coro-split pass, + // coro-early pass can not handle this quiet well. + // So we won't inline the coroutine function if it have not been unsplited + if (Callee->isPresplitCoroutine()) +return InlineResult::failure("unsplited coroutine call"); + // Never inline calls with byval arguments that does not have the alloca // address space. Since byval arguments can be replaced with a copy to an // alloca, the inlined code would need to be adjusted to handle that the diff --git a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp index cf810dbc39523..532599b42e0dc 100644 --- a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp +++ b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp @@ -46,7 +46,14 @@ PreservedAnalyses AlwaysInlinerPass::run(Module &M, SmallSetVector Calls; bool Changed = false; SmallVector InlinedFunctions; - for (Function &F : M) + for (Function &F : M) { +// When callee coroutine function is inlined into caller coroutine function +// before coro-split pass, +// coro-early pass can not handle this quiet well. +// So we won't inline the coroutine function if it have not been unsplited +if (F.isPresplitCoroutine()) + continue; + if (!F.isDeclaration() && F.hasFnAttribute(Attribute::AlwaysInline) && isInlineViable(F).isSuccess()) { Calls.clear(); @@ -90,6 +97,7 @@ PreservedAnalyses AlwaysInlinerPass::run(Module &M, // invalidation issues while deleting functions. InlinedFunctions.push_back(&F); } + } // Remove any live functions. erase_if(InlinedFunctions, [&](Function *F) { @@ -182,6 +190,13 @@ InlineCost AlwaysInlinerLegacyPass::getInlineCost(CallBase &CB) { if (!Callee) return InlineCost::getNever("indirect call"); + // When callee coroutine function