|
10 | 10 | //
|
11 | 11 | //===----------------------------------------------------------------------===//
|
12 | 12 |
|
| 13 | +#include "swift/SILOptimizer/Utils/InstructionDeleter.h" |
13 | 14 | #include "swift/SIL/SILFunction.h"
|
| 15 | +#include "swift/SIL/Test.h" |
14 | 16 | #include "swift/SILOptimizer/Utils/ConstExpr.h"
|
15 | 17 | #include "swift/SILOptimizer/Utils/DebugOptUtils.h"
|
16 |
| -#include "swift/SILOptimizer/Utils/InstructionDeleter.h" |
17 | 18 | #include "swift/SILOptimizer/Utils/InstOptUtils.h"
|
18 | 19 |
|
19 | 20 | using namespace swift;
|
@@ -60,6 +61,21 @@ static bool isScopeAffectingInstructionDead(SILInstruction *inst,
|
60 | 61 | if (!hasOnlyEndOfScopeOrEndOfLifetimeUses(inst)) {
|
61 | 62 | return false;
|
62 | 63 | }
|
| 64 | + |
| 65 | + // If inst has any owned move-only value as a result, deleting it may shorten |
| 66 | + // that value's lifetime which is illegal according to language rules. |
| 67 | + // |
| 68 | + // In particular, this check is needed before returning true when |
| 69 | + // getSingleValueCopyOrCast returns true. That function returns true for |
| 70 | + // move_value instructions. And `move_value %moveOnlyValue` must not be |
| 71 | + // deleted. |
| 72 | + for (auto result : inst->getResults()) { |
| 73 | + if (result->getType().isPureMoveOnly() && |
| 74 | + result->getOwnershipKind() == OwnershipKind::Owned) { |
| 75 | + return false; |
| 76 | + } |
| 77 | + } |
| 78 | + |
63 | 79 | // If inst is a copy or beginning of scope, inst is dead, since we know that
|
64 | 80 | // it is used only in a destroy_value or end-of-scope instruction.
|
65 | 81 | if (getSingleValueCopyOrCast(inst))
|
@@ -289,6 +305,22 @@ bool InstructionDeleter::deleteIfDead(SILInstruction *inst, bool fixLifetime) {
|
289 | 305 | return false;
|
290 | 306 | }
|
291 | 307 |
|
| 308 | +namespace swift::test { |
| 309 | +// Arguments: |
| 310 | +// - instruction: the instruction to delete |
| 311 | +// Dumps: |
| 312 | +// - the function |
| 313 | +static FunctionTest DeleterDeleteIfDeadTest( |
| 314 | + "deleter-delete-if-dead", [](auto &function, auto &arguments, auto &test) { |
| 315 | + auto *inst = arguments.takeInstruction(); |
| 316 | + InstructionDeleter deleter; |
| 317 | + llvm::dbgs() << "Deleting-if-dead " << *inst; |
| 318 | + auto deleted = deleter.deleteIfDead(inst); |
| 319 | + llvm::dbgs() << "deleteIfDead returned " << deleted << "\n"; |
| 320 | + function.dump(); |
| 321 | + }); |
| 322 | +} // namespace swift::test |
| 323 | + |
292 | 324 | void InstructionDeleter::forceDeleteAndFixLifetimes(SILInstruction *inst) {
|
293 | 325 | SILFunction *fun = inst->getFunction();
|
294 | 326 | bool preserveDebugInfo =
|
|
0 commit comments