|
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