|
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