|
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,27 @@ 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 | + MetadataSetTy CommonDebugInfo; |
| 91 | + DebugInfoFinder DIFinder; |
| 92 | + DISubprogram *SPClonedWithinModule = CollectDebugInfoForCloning( |
| 93 | + F, CloneFunctionChangeType::LocalChangesOnly, DIFinder); |
| 94 | + |
| 95 | + FindDebugInfoToIdentityMap(CommonDebugInfo, |
| 96 | + CloneFunctionChangeType::LocalChangesOnly, |
| 97 | + DIFinder, SPClonedWithinModule); |
| 98 | + return CommonDebugInfo; |
| 99 | +} |
| 100 | +} // end anonymous namespace |
| 101 | + |
80 | 102 | // FIXME:
|
81 | 103 | // Lower the intrinisc in CoroEarly phase if coroutine frame doesn't escape
|
82 | 104 | // and it is known that other transformations, for example, sanitizers
|
@@ -891,8 +913,11 @@ void coro::BaseCloner::create() {
|
891 | 913 | auto savedLinkage = NewF->getLinkage();
|
892 | 914 | NewF->setLinkage(llvm::GlobalValue::ExternalLinkage);
|
893 | 915 |
|
894 |
| - CloneFunctionInto(NewF, &OrigF, VMap, |
895 |
| - CloneFunctionChangeType::LocalChangesOnly, Returns); |
| 916 | + CloneFunctionAttributesInto(NewF, &OrigF, VMap, false); |
| 917 | + CloneFunctionMetadataInto(*NewF, OrigF, VMap, RF_None, nullptr, nullptr, |
| 918 | + &CommonDebugInfo); |
| 919 | + CloneFunctionBodyInto(*NewF, OrigF, VMap, RF_None, Returns, "", nullptr, |
| 920 | + nullptr, nullptr, &CommonDebugInfo); |
896 | 921 |
|
897 | 922 | auto &Context = NewF->getContext();
|
898 | 923 |
|
@@ -1374,16 +1399,21 @@ struct SwitchCoroutineSplitter {
|
1374 | 1399 | TargetTransformInfo &TTI) {
|
1375 | 1400 | assert(Shape.ABI == coro::ABI::Switch);
|
1376 | 1401 |
|
| 1402 | + MetadataSetTy CommonDebugInfo{collectCommonDebugInfo(F)}; |
| 1403 | + |
1377 | 1404 | // Create a resume clone by cloning the body of the original function,
|
1378 | 1405 | // setting new entry block and replacing coro.suspend an appropriate value
|
1379 | 1406 | // to force resume or cleanup pass for every suspend point.
|
1380 | 1407 | createResumeEntryBlock(F, Shape);
|
1381 | 1408 | auto *ResumeClone = coro::SwitchCloner::createClone(
|
1382 |
| - F, ".resume", Shape, coro::CloneKind::SwitchResume, TTI); |
| 1409 | + F, ".resume", Shape, coro::CloneKind::SwitchResume, TTI, |
| 1410 | + CommonDebugInfo); |
1383 | 1411 | auto *DestroyClone = coro::SwitchCloner::createClone(
|
1384 |
| - F, ".destroy", Shape, coro::CloneKind::SwitchUnwind, TTI); |
| 1412 | + F, ".destroy", Shape, coro::CloneKind::SwitchUnwind, TTI, |
| 1413 | + CommonDebugInfo); |
1385 | 1414 | auto *CleanupClone = coro::SwitchCloner::createClone(
|
1386 |
| - F, ".cleanup", Shape, coro::CloneKind::SwitchCleanup, TTI); |
| 1415 | + F, ".cleanup", Shape, coro::CloneKind::SwitchCleanup, TTI, |
| 1416 | + CommonDebugInfo); |
1387 | 1417 |
|
1388 | 1418 | postSplitCleanup(*ResumeClone);
|
1389 | 1419 | postSplitCleanup(*DestroyClone);
|
@@ -1768,12 +1798,15 @@ void coro::AsyncABI::splitCoroutine(Function &F, coro::Shape &Shape,
|
1768 | 1798 | }
|
1769 | 1799 |
|
1770 | 1800 | assert(Clones.size() == Shape.CoroSuspends.size());
|
| 1801 | + |
| 1802 | + MetadataSetTy CommonDebugInfo{collectCommonDebugInfo(F)}; |
| 1803 | + |
1771 | 1804 | for (auto [Idx, CS] : llvm::enumerate(Shape.CoroSuspends)) {
|
1772 | 1805 | auto *Suspend = CS;
|
1773 | 1806 | auto *Clone = Clones[Idx];
|
1774 | 1807 |
|
1775 | 1808 | coro::BaseCloner::createClone(F, "resume." + Twine(Idx), Shape, Clone,
|
1776 |
| - Suspend, TTI); |
| 1809 | + Suspend, TTI, CommonDebugInfo); |
1777 | 1810 | }
|
1778 | 1811 | }
|
1779 | 1812 |
|
@@ -1899,12 +1932,15 @@ void coro::AnyRetconABI::splitCoroutine(Function &F, coro::Shape &Shape,
|
1899 | 1932 | }
|
1900 | 1933 |
|
1901 | 1934 | assert(Clones.size() == Shape.CoroSuspends.size());
|
| 1935 | + |
| 1936 | + MetadataSetTy CommonDebugInfo{collectCommonDebugInfo(F)}; |
| 1937 | + |
1902 | 1938 | for (auto [Idx, CS] : llvm::enumerate(Shape.CoroSuspends)) {
|
1903 | 1939 | auto Suspend = CS;
|
1904 | 1940 | auto Clone = Clones[Idx];
|
1905 | 1941 |
|
1906 | 1942 | coro::BaseCloner::createClone(F, "resume." + Twine(Idx), Shape, Clone,
|
1907 |
| - Suspend, TTI); |
| 1943 | + Suspend, TTI, CommonDebugInfo); |
1908 | 1944 | }
|
1909 | 1945 | }
|
1910 | 1946 |
|
|
0 commit comments