|
20 | 20 | #include "swift/SIL/BasicBlockDatastructures.h"
|
21 | 21 | #include "swift/SIL/Dominance.h"
|
22 | 22 | #include "swift/SIL/MemAccessUtils.h"
|
| 23 | +#include "swift/SIL/NodeDatastructures.h" |
23 | 24 | #include "swift/SIL/SILArgument.h"
|
24 | 25 | #include "swift/SIL/SILBuilder.h"
|
25 | 26 | #include "swift/SIL/SILCloner.h"
|
@@ -1101,7 +1102,30 @@ specializeApplySite(SILOptFunctionBuilder &FuncBuilder, ApplySite Apply,
|
1101 | 1102 | // borrows its captures, and we don't need to adjust capture lifetimes.
|
1102 | 1103 | if (!PAI->isOnStack()) {
|
1103 | 1104 | if (PAFrontier.empty()) {
|
1104 |
| - ValueLifetimeAnalysis VLA(PAI, PAI->getUses()); |
| 1105 | + SmallVector<SILInstruction *, 8> users; |
| 1106 | + InstructionWorklist worklist(PAI->getFunction()); |
| 1107 | + worklist.push(PAI); |
| 1108 | + while (auto *inst = worklist.pop()) { |
| 1109 | + auto *svi = cast<SingleValueInstruction>(inst); |
| 1110 | + for (auto *use : svi->getUses()) { |
| 1111 | + auto *user = use->getUser(); |
| 1112 | + SingleValueInstruction *svi; |
| 1113 | + // A copy_value produces a value with a new lifetime on which the |
| 1114 | + // captured alloc_box's lifetime depends. If the transformation |
| 1115 | + // were only to create a destroy_value of the alloc_box (and to |
| 1116 | + // rewrite the closure not to consume it), the alloc_box would be |
| 1117 | + // kept alive by the copy_value. The transformation does more, |
| 1118 | + // however: it rewrites the alloc_box as an alloc_stack, creating |
| 1119 | + // the alloc_stack/dealloc_stack instructions where the alloc_box/ |
| 1120 | + // destroy_value instructions are respectively. The copy_value |
| 1121 | + // can't keep the alloc_stack alive. |
| 1122 | + if ((svi = dyn_cast<CopyValueInst>(user))) { |
| 1123 | + worklist.push(svi); |
| 1124 | + } |
| 1125 | + users.push_back(user); |
| 1126 | + } |
| 1127 | + } |
| 1128 | + ValueLifetimeAnalysis VLA(PAI, users); |
1105 | 1129 | pass.CFGChanged |= !VLA.computeFrontier(
|
1106 | 1130 | PAFrontier, ValueLifetimeAnalysis::AllowToModifyCFG);
|
1107 | 1131 | assert(!PAFrontier.empty() &&
|
|
0 commit comments