|
11 | 11 | //===----------------------------------------------------------------------===// |
12 | 12 |
|
13 | 13 | #define DEBUG_TYPE "sil-combine" |
| 14 | + |
14 | 15 | #include "SILCombiner.h" |
15 | 16 | #include "swift/Basic/STLExtras.h" |
16 | 17 | #include "swift/SIL/DebugUtils.h" |
17 | 18 | #include "swift/SIL/DynamicCasts.h" |
18 | 19 | #include "swift/SIL/InstructionUtils.h" |
19 | 20 | #include "swift/SIL/PatternMatch.h" |
20 | 21 | #include "swift/SIL/Projection.h" |
| 22 | +#include "swift/SIL/SILBitfield.h" |
21 | 23 | #include "swift/SIL/SILBuilder.h" |
| 24 | +#include "swift/SIL/SILInstruction.h" |
22 | 25 | #include "swift/SIL/SILVisitor.h" |
23 | | -#include "swift/SIL/SILBitfield.h" |
24 | 26 | #include "swift/SILOptimizer/Analysis/ARCAnalysis.h" |
25 | 27 | #include "swift/SILOptimizer/Analysis/AliasAnalysis.h" |
26 | 28 | #include "swift/SILOptimizer/Analysis/ValueTracking.h" |
| 29 | +#include "swift/SILOptimizer/Utils/BasicBlockOptUtils.h" |
27 | 30 | #include "swift/SILOptimizer/Utils/CFGOptUtils.h" |
28 | 31 | #include "swift/SILOptimizer/Utils/Devirtualize.h" |
29 | 32 | #include "swift/SILOptimizer/Utils/InstOptUtils.h" |
30 | | -#include "swift/SILOptimizer/Utils/BasicBlockOptUtils.h" |
31 | 33 | #include "llvm/ADT/DenseMap.h" |
32 | 34 | #include "llvm/ADT/SmallPtrSet.h" |
33 | 35 | #include "llvm/ADT/SmallVector.h" |
@@ -1764,10 +1766,22 @@ SILInstruction *SILCombiner::visitUncheckedTakeEnumDataAddrInst( |
1764 | 1766 | auto *svi = cast<SingleValueInstruction>(user); |
1765 | 1767 | SILValue newValue; |
1766 | 1768 | if (auto *oldLoad = dyn_cast<LoadInst>(svi)) { |
1767 | | - auto newLoad = Builder.emitLoadValueOperation( |
1768 | | - loc, enumAddr, oldLoad->getOwnershipQualifier()); |
1769 | | - newValue = |
1770 | | - Builder.createUncheckedEnumData(loc, newLoad, enumElt, payloadType); |
| 1769 | + // If the old load is trivial and our enum addr is non-trivial, we need to |
| 1770 | + // use a load_borrow here. We know that the unchecked_enum_data will |
| 1771 | + // produce a trivial value meaning that we can just do a |
| 1772 | + // load_borrow/immediately end the lifetime here. |
| 1773 | + if (oldLoad->getOwnershipQualifier() == LoadOwnershipQualifier::Trivial && |
| 1774 | + !enumAddr->getType().isTrivial(Builder.getFunction())) { |
| 1775 | + Builder.emitScopedBorrowOperation(loc, enumAddr, [&](SILValue newLoad) { |
| 1776 | + newValue = Builder.createUncheckedEnumData(loc, newLoad, enumElt, |
| 1777 | + payloadType); |
| 1778 | + }); |
| 1779 | + } else { |
| 1780 | + auto newLoad = Builder.emitLoadValueOperation( |
| 1781 | + loc, enumAddr, oldLoad->getOwnershipQualifier()); |
| 1782 | + newValue = |
| 1783 | + Builder.createUncheckedEnumData(loc, newLoad, enumElt, payloadType); |
| 1784 | + } |
1771 | 1785 | } else if (auto *lbi = cast<LoadBorrowInst>(svi)) { |
1772 | 1786 | auto newLoad = Builder.emitLoadBorrowOperation(loc, enumAddr); |
1773 | 1787 | for (auto ui = lbi->consuming_use_begin(), ue = lbi->consuming_use_end(); |
|
0 commit comments