|
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