diff --git a/lib/SILOptimizer/Mandatory/MoveOnlyBorrowToDestructureUtils.cpp b/lib/SILOptimizer/Mandatory/MoveOnlyBorrowToDestructureUtils.cpp index cb247d16eecdd..14a43773cd65c 100644 --- a/lib/SILOptimizer/Mandatory/MoveOnlyBorrowToDestructureUtils.cpp +++ b/lib/SILOptimizer/Mandatory/MoveOnlyBorrowToDestructureUtils.cpp @@ -143,17 +143,19 @@ struct AvailableValueStore { liveness.getNumSubElements()), numBits(liveness.getNumSubElements()) {} - std::pair get(SILBasicBlock *block) { + std::pair get(SILBasicBlock *block) { auto iter = blockToValues.try_emplace(block, AvailableValues()); if (!iter.second) { - return {&iter.first->second, false}; + return {iter.first->second, false}; } + ASSERT(dataStore.size() >= (nextOffset + numBits) && "underallocated!"); + iter.first->second.values = MutableArrayRef(&dataStore[nextOffset], numBits); nextOffset += numBits; - return {&iter.first->second, true}; + return {iter.first->second, true}; } }; @@ -239,7 +241,7 @@ struct borrowtodestructure::Implementation { void cleanup(); - AvailableValues &computeAvailableValues(SILBasicBlock *block); + AvailableValues computeAvailableValues(SILBasicBlock *block); /// Returns mark_unresolved_non_copyable_value if we are processing borrows or /// the enum argument if we are processing switch_enum. @@ -702,23 +704,24 @@ static void dumpSmallestTypeAvailable( /// ensures that we match at the source level the assumption by users that they /// can use entire valid parts as late as possible. If we were to do it earlier /// we would emit errors too early. -AvailableValues &Implementation::computeAvailableValues(SILBasicBlock *block) { +AvailableValues Implementation::computeAvailableValues(SILBasicBlock *block) { LLVM_DEBUG(llvm::dbgs() << " Computing Available Values For bb" << block->getDebugID() << '\n'); // First grab our block. If we already have state for the block, just return // its available values. We already computed the available values and // potentially updated it with new destructured values for our block. + ASSERT(blockToAvailableValues.has_value()); auto pair = blockToAvailableValues->get(block); if (!pair.second) { LLVM_DEBUG(llvm::dbgs() << " Already have values! Returning them!\n"); - LLVM_DEBUG(pair.first->print(llvm::dbgs(), " ")); - return *pair.first; + LLVM_DEBUG(pair.first.print(llvm::dbgs(), " ")); + return pair.first; } LLVM_DEBUG(llvm::dbgs() << " No values computed! Initializing!\n"); - auto &newValues = *pair.first; + AvailableValues newValues = pair.first; // Otherwise, we need to initialize our available values with predecessor // information. @@ -825,7 +828,7 @@ AvailableValues &Implementation::computeAvailableValues(SILBasicBlock *block) { << " Recursively loading its available values to " "compute initial smallest type available for block bb" << block->getDebugID() << '\n'); - auto &predAvailableValues = computeAvailableValues(bb); + auto predAvailableValues = computeAvailableValues(bb); LLVM_DEBUG( llvm::dbgs() << " Computing initial smallest type available for block bb" @@ -852,7 +855,7 @@ AvailableValues &Implementation::computeAvailableValues(SILBasicBlock *block) { << bb->getDebugID() << '\n'); LLVM_DEBUG(llvm::dbgs() << " Recursively loading its available values!\n"); - auto &predAvailableValues = computeAvailableValues(bb); + auto predAvailableValues = computeAvailableValues(bb); for (unsigned i : range(predAvailableValues.size())) { if (!smallestTypeAvailable[i].has_value()) continue; @@ -892,7 +895,7 @@ AvailableValues &Implementation::computeAvailableValues(SILBasicBlock *block) { for (auto *predBlock : predsSkippingBackEdges) { SWIFT_DEFER { typeSpanToValue.clear(); }; - auto &predAvailableValues = computeAvailableValues(predBlock); + auto predAvailableValues = computeAvailableValues(predBlock); // First go through our available values and initialize our interval map. We // should never fail to insert. We want to insert /all/ available values so @@ -1008,7 +1011,7 @@ AvailableValues &Implementation::computeAvailableValues(SILBasicBlock *block) { // phis. SILValue sameValue; for (auto *predBlock : predsSkippingBackEdges) { - auto &predAvailableValues = computeAvailableValues(predBlock); + auto predAvailableValues = computeAvailableValues(predBlock); if (!sameValue) { sameValue = predAvailableValues[i]; } else if (sameValue != predAvailableValues[i]) { @@ -1029,7 +1032,7 @@ AvailableValues &Implementation::computeAvailableValues(SILBasicBlock *block) { } for (auto *predBlock : predsSkippingBackEdges) { - auto &predAvailableValues = computeAvailableValues(predBlock); + auto predAvailableValues = computeAvailableValues(predBlock); addNewEdgeValueToBranch(predBlock->getTerminator(), block, predAvailableValues[i], deleter); } @@ -1192,7 +1195,7 @@ void Implementation::rewriteUses(InstructionDeleter *deleter) { // block. LLVM_DEBUG(llvm::dbgs() << " Found needed bits! Propagating available values!\n"); - auto &availableValues = computeAvailableValues(block); + auto availableValues = computeAvailableValues(block); LLVM_DEBUG(llvm::dbgs() << " Computed available values for block bb" << block->getDebugID() << '\n'; availableValues.print(llvm::dbgs(), " "));