|
15 | 15 | #include "swift/SILOptimizer/Utils/SILInliner.h" |
16 | 16 | #include "swift/AST/Builtins.h" |
17 | 17 | #include "swift/AST/DiagnosticsSIL.h" |
| 18 | +#include "swift/Basic/Defer.h" |
| 19 | +#include "swift/SIL/MemAccessUtils.h" |
18 | 20 | #include "swift/SIL/PrettyStackTrace.h" |
19 | 21 | #include "swift/SIL/SILDebugScope.h" |
20 | 22 | #include "swift/SIL/SILInstruction.h" |
@@ -433,17 +435,44 @@ void SILInlineCloner::cloneInline(ArrayRef<SILValue> AppliedArgs) { |
433 | 435 | auto calleeConv = getCalleeFunction()->getConventions(); |
434 | 436 | for (auto p : llvm::enumerate(AppliedArgs)) { |
435 | 437 | SILValue callArg = p.value(); |
| 438 | + SWIFT_DEFER { entryArgs.push_back(callArg); }; |
436 | 439 | unsigned idx = p.index(); |
437 | 440 | if (idx >= calleeConv.getSILArgIndexOfFirstParam()) { |
438 | | - // Insert begin/end borrow for guaranteed arguments. |
439 | | - if (calleeConv.getParamInfoForSILArg(idx).isGuaranteed()) { |
440 | | - if (SILValue newValue = borrowFunctionArgument(callArg, Apply)) { |
441 | | - callArg = newValue; |
442 | | - borrowedArgs[idx] = true; |
| 441 | + auto paramInfo = calleeConv.getParamInfoForSILArg(idx); |
| 442 | + if (callArg->getType().isAddress()) { |
| 443 | + // If lexical lifetimes are enabled, any alloc_stacks in the caller that |
| 444 | + // are passed to the callee being inlined (except mutating exclusive |
| 445 | + // accesses) need to be promoted to be lexical. Otherwise, |
| 446 | + // destroy_addrs could be hoisted through the body of the newly inlined |
| 447 | + // function without regard to the deinit barriers it contains. |
| 448 | + // |
| 449 | + // TODO: [begin_borrow_addr] Instead of marking the alloc_stack as a |
| 450 | + // whole lexical, just mark the inlined range lexical via |
| 451 | + // begin_borrow_addr [lexical]/end_borrow_addr just as is done |
| 452 | + // with values. |
| 453 | + auto &module = Apply.getFunction()->getModule(); |
| 454 | + auto enableLexicalLifetimes = |
| 455 | + module.getASTContext().SILOpts.supportsLexicalLifetimes(module); |
| 456 | + if (!enableLexicalLifetimes) |
| 457 | + continue; |
| 458 | + |
| 459 | + // Exclusive mutating accesses don't entail a lexical scope. |
| 460 | + if (paramInfo.getConvention() == ParameterConvention::Indirect_Inout) |
| 461 | + continue; |
| 462 | + |
| 463 | + auto storage = AccessStorageWithBase::compute(callArg); |
| 464 | + if (auto *asi = dyn_cast<AllocStackInst>(storage.base)) |
| 465 | + asi->setIsLexical(); |
| 466 | + } else { |
| 467 | + // Insert begin/end borrow for guaranteed arguments. |
| 468 | + if (paramInfo.isGuaranteed()) { |
| 469 | + if (SILValue newValue = borrowFunctionArgument(callArg, Apply)) { |
| 470 | + callArg = newValue; |
| 471 | + borrowedArgs[idx] = true; |
| 472 | + } |
443 | 473 | } |
444 | 474 | } |
445 | 475 | } |
446 | | - entryArgs.push_back(callArg); |
447 | 476 | } |
448 | 477 |
|
449 | 478 | // Create the return block and set ReturnToBB for use in visitTerminator |
|
0 commit comments