|
43 | 43 | #include "llvm/IR/CallingConv.h" |
44 | 44 | #include "llvm/IR/Constants.h" |
45 | 45 | #include "llvm/IR/DataLayout.h" |
| 46 | +#include "llvm/IR/DebugInfo.h" |
46 | 47 | #include "llvm/IR/DerivedTypes.h" |
47 | 48 | #include "llvm/IR/Dominators.h" |
48 | 49 | #include "llvm/IR/GlobalValue.h" |
@@ -77,6 +78,24 @@ using namespace llvm; |
77 | 78 |
|
78 | 79 | #define DEBUG_TYPE "coro-split" |
79 | 80 |
|
| 81 | +namespace { |
| 82 | +/// Collect (a known) subset of global debug info metadata potentially used by |
| 83 | +/// the function \p F. |
| 84 | +/// |
| 85 | +/// This metadata set can be used to avoid cloning debug info not owned by \p F |
| 86 | +/// and is shared among all potential clones \p F. |
| 87 | +MetadataSetTy collectCommonDebugInfo(Function &F) { |
| 88 | + TimeTraceScope FunctionScope("CollectCommonDebugInfo"); |
| 89 | + |
| 90 | + DebugInfoFinder DIFinder; |
| 91 | + DISubprogram *SPClonedWithinModule = CollectDebugInfoForCloning( |
| 92 | + F, CloneFunctionChangeType::LocalChangesOnly, DIFinder); |
| 93 | + |
| 94 | + return FindDebugInfoToIdentityMap(CloneFunctionChangeType::LocalChangesOnly, |
| 95 | + DIFinder, SPClonedWithinModule); |
| 96 | +} |
| 97 | +} // end anonymous namespace |
| 98 | + |
80 | 99 | // FIXME: |
81 | 100 | // Lower the intrinisc in CoroEarly phase if coroutine frame doesn't escape |
82 | 101 | // and it is known that other transformations, for example, sanitizers |
@@ -891,8 +910,11 @@ void coro::BaseCloner::create() { |
891 | 910 | auto savedLinkage = NewF->getLinkage(); |
892 | 911 | NewF->setLinkage(llvm::GlobalValue::ExternalLinkage); |
893 | 912 |
|
894 | | - CloneFunctionInto(NewF, &OrigF, VMap, |
895 | | - CloneFunctionChangeType::LocalChangesOnly, Returns); |
| 913 | + CloneFunctionAttributesInto(NewF, &OrigF, VMap, false); |
| 914 | + CloneFunctionMetadataInto(*NewF, OrigF, VMap, RF_None, nullptr, nullptr, |
| 915 | + &CommonDebugInfo); |
| 916 | + CloneFunctionBodyInto(*NewF, OrigF, VMap, RF_None, Returns, "", nullptr, |
| 917 | + nullptr, nullptr, &CommonDebugInfo); |
896 | 918 |
|
897 | 919 | auto &Context = NewF->getContext(); |
898 | 920 |
|
@@ -1374,16 +1396,21 @@ struct SwitchCoroutineSplitter { |
1374 | 1396 | TargetTransformInfo &TTI) { |
1375 | 1397 | assert(Shape.ABI == coro::ABI::Switch); |
1376 | 1398 |
|
| 1399 | + MetadataSetTy CommonDebugInfo{collectCommonDebugInfo(F)}; |
| 1400 | + |
1377 | 1401 | // Create a resume clone by cloning the body of the original function, |
1378 | 1402 | // setting new entry block and replacing coro.suspend an appropriate value |
1379 | 1403 | // to force resume or cleanup pass for every suspend point. |
1380 | 1404 | createResumeEntryBlock(F, Shape); |
1381 | 1405 | auto *ResumeClone = coro::SwitchCloner::createClone( |
1382 | | - F, ".resume", Shape, coro::CloneKind::SwitchResume, TTI); |
| 1406 | + F, ".resume", Shape, coro::CloneKind::SwitchResume, TTI, |
| 1407 | + CommonDebugInfo); |
1383 | 1408 | auto *DestroyClone = coro::SwitchCloner::createClone( |
1384 | | - F, ".destroy", Shape, coro::CloneKind::SwitchUnwind, TTI); |
| 1409 | + F, ".destroy", Shape, coro::CloneKind::SwitchUnwind, TTI, |
| 1410 | + CommonDebugInfo); |
1385 | 1411 | auto *CleanupClone = coro::SwitchCloner::createClone( |
1386 | | - F, ".cleanup", Shape, coro::CloneKind::SwitchCleanup, TTI); |
| 1412 | + F, ".cleanup", Shape, coro::CloneKind::SwitchCleanup, TTI, |
| 1413 | + CommonDebugInfo); |
1387 | 1414 |
|
1388 | 1415 | postSplitCleanup(*ResumeClone); |
1389 | 1416 | postSplitCleanup(*DestroyClone); |
@@ -1768,12 +1795,15 @@ void coro::AsyncABI::splitCoroutine(Function &F, coro::Shape &Shape, |
1768 | 1795 | } |
1769 | 1796 |
|
1770 | 1797 | assert(Clones.size() == Shape.CoroSuspends.size()); |
| 1798 | + |
| 1799 | + MetadataSetTy CommonDebugInfo{collectCommonDebugInfo(F)}; |
| 1800 | + |
1771 | 1801 | for (auto [Idx, CS] : llvm::enumerate(Shape.CoroSuspends)) { |
1772 | 1802 | auto *Suspend = CS; |
1773 | 1803 | auto *Clone = Clones[Idx]; |
1774 | 1804 |
|
1775 | 1805 | coro::BaseCloner::createClone(F, "resume." + Twine(Idx), Shape, Clone, |
1776 | | - Suspend, TTI); |
| 1806 | + Suspend, TTI, CommonDebugInfo); |
1777 | 1807 | } |
1778 | 1808 | } |
1779 | 1809 |
|
@@ -1899,12 +1929,15 @@ void coro::AnyRetconABI::splitCoroutine(Function &F, coro::Shape &Shape, |
1899 | 1929 | } |
1900 | 1930 |
|
1901 | 1931 | assert(Clones.size() == Shape.CoroSuspends.size()); |
| 1932 | + |
| 1933 | + MetadataSetTy CommonDebugInfo{collectCommonDebugInfo(F)}; |
| 1934 | + |
1902 | 1935 | for (auto [Idx, CS] : llvm::enumerate(Shape.CoroSuspends)) { |
1903 | 1936 | auto Suspend = CS; |
1904 | 1937 | auto Clone = Clones[Idx]; |
1905 | 1938 |
|
1906 | 1939 | coro::BaseCloner::createClone(F, "resume." + Twine(Idx), Shape, Clone, |
1907 | | - Suspend, TTI); |
| 1940 | + Suspend, TTI, CommonDebugInfo); |
1908 | 1941 | } |
1909 | 1942 | } |
1910 | 1943 |
|
|
0 commit comments