Skip to content

Commit cabb5e1

Browse files
authored
Merge pull request #69807 from apple/revert-69450-uninarrayfix
2 parents 09688ab + e8de333 commit cabb5e1

27 files changed

+217
-368
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/ObjectOutliner.swift

Lines changed: 8 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import SIL
4141
///
4242
let objectOutliner = FunctionPass(name: "object-outliner") {
4343
(function: Function, context: FunctionPassContext) in
44+
4445
for inst in function.instructions {
4546
if let ari = inst as? AllocRefInstBase {
4647
if let globalValue = optimizeObjectAllocation(allocRef: ari, context) {
@@ -84,10 +85,6 @@ private func findEndCOWMutation(of object: Value) -> EndCOWMutationInst? {
8485
if let ecm = findEndCOWMutation(of: uci) {
8586
return ecm
8687
}
87-
case let urci as UncheckedRefCastInst:
88-
if let ecm = findEndCOWMutation(of: urci) {
89-
return ecm
90-
}
9188
case let mv as MoveValueInst:
9289
if let ecm = findEndCOWMutation(of: mv) {
9390
return ecm
@@ -150,7 +147,7 @@ private func findInitStores(of object: Value,
150147
return false
151148
}
152149
default:
153-
if !isValidUseOfObject(use) {
150+
if !isValidUseOfObject(use.instruction) {
154151
return false
155152
}
156153
}
@@ -177,18 +174,6 @@ private func findStores(toTailAddress tailAddr: Value, tailElementIndex: Int, st
177174
if !findStores(inUsesOf: tea, index: tailElementIndex * numTupleElements + tupleIdx, stores: &stores) {
178175
return false
179176
}
180-
case let atp as AddressToPointerInst:
181-
if !findStores(toTailAddress: atp, tailElementIndex: tailElementIndex, stores: &stores) {
182-
return false
183-
}
184-
case let mdi as MarkDependenceInst:
185-
if !findStores(toTailAddress: mdi, tailElementIndex: tailElementIndex, stores: &stores) {
186-
return false
187-
}
188-
case let pta as PointerToAddressInst:
189-
if !findStores(toTailAddress: pta, tailElementIndex: tailElementIndex, stores: &stores) {
190-
return false
191-
}
192177
case let store as StoreInst:
193178
if store.source.type.isTuple {
194179
// This kind of SIL is never generated because tuples are stored with separated stores to tuple_element_addr.
@@ -199,7 +184,7 @@ private func findStores(toTailAddress tailAddr: Value, tailElementIndex: Int, st
199184
return false
200185
}
201186
default:
202-
if !isValidUseOfObject(use) {
187+
if !isValidUseOfObject(use.instruction) {
203188
return false
204189
}
205190
}
@@ -213,7 +198,7 @@ private func findStores(inUsesOf address: Value, index: Int, stores: inout [Stor
213198
if !handleStore(store, index: index, stores: &stores) {
214199
return false
215200
}
216-
} else if !isValidUseOfObject(use) {
201+
} else if !isValidUseOfObject(use.instruction) {
217202
return false
218203
}
219204
}
@@ -230,8 +215,7 @@ private func handleStore(_ store: StoreInst, index: Int, stores: inout [StoreIns
230215
return false
231216
}
232217

233-
private func isValidUseOfObject(_ use: Operand) -> Bool {
234-
let inst = use.instruction
218+
private func isValidUseOfObject(_ inst: Instruction) -> Bool {
235219
switch inst {
236220
case is DebugValueInst,
237221
is LoadInst,
@@ -243,17 +227,6 @@ private func isValidUseOfObject(_ use: Operand) -> Bool {
243227
is EndCOWMutationInst:
244228
return true
245229

246-
case let mdi as MarkDependenceInst:
247-
if (use == mdi.baseOperand) {
248-
return true;
249-
}
250-
for mdiUse in mdi.uses {
251-
if !isValidUseOfObject(mdiUse) {
252-
return false
253-
}
254-
}
255-
return true
256-
257230
case is StructElementAddrInst,
258231
is AddressToPointerInst,
259232
is StructInst,
@@ -265,12 +238,9 @@ private func isValidUseOfObject(_ use: Operand) -> Bool {
265238
is UpcastInst,
266239
is BeginDeallocRefInst,
267240
is RefTailAddrInst,
268-
is RefElementAddrInst,
269-
is StructInst,
270-
is PointerToAddressInst,
271-
is IndexAddrInst:
272-
for instUse in (inst as! SingleValueInstruction).uses {
273-
if !isValidUseOfObject(instUse) {
241+
is RefElementAddrInst:
242+
for use in (inst as! SingleValueInstruction).uses {
243+
if !isValidUseOfObject(use.instruction) {
274244
return false
275245
}
276246
}
@@ -372,8 +342,6 @@ private func rewriteUses(of startValue: Value, _ context: FunctionPassContext) {
372342
context.erase(instruction: endMutation)
373343
case let upCast as UpcastInst:
374344
worklist.pushIfNotVisited(usersOf: upCast)
375-
case let urci as UncheckedRefCastInst:
376-
worklist.pushIfNotVisited(usersOf: urci)
377345
case let moveValue as MoveValueInst:
378346
worklist.pushIfNotVisited(usersOf: moveValue)
379347
case is DeallocRefInst, is DeallocStackRefInst:

lib/SILGen/SILGenApply.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6317,10 +6317,7 @@ SILGenFunction::emitUninitializedArrayAllocation(Type ArrayTy,
63176317
SmallVector<ManagedValue, 2> resultElts;
63186318
std::move(result).getAll(resultElts);
63196319

6320-
// Add a mark_dependence between the interior pointer and the array value
6321-
auto dependentValue = B.createMarkDependence(Loc, resultElts[1].getValue(),
6322-
resultElts[0].getValue());
6323-
return {resultElts[0], dependentValue};
6320+
return {resultElts[0], resultElts[1].getUnmanagedValue()};
63246321
}
63256322

63266323
/// Deallocate an uninitialized array.

lib/SILOptimizer/Analysis/ArraySemantic.cpp

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -841,8 +841,7 @@ bool swift::ArraySemanticsCall::mapInitializationStores(
841841
return false;
842842

843843
// Match initialization stores into ElementBuffer. E.g.
844-
// %82 = struct_extract %element_buffer : $UnsafeMutablePointer<Int>
845-
// %83 = mark_dependence %82 : $Builtin.RawPointer on ArrayVal
844+
// %83 = struct_extract %element_buffer : $UnsafeMutablePointer<Int>
846845
// %84 = pointer_to_address %83 : $Builtin.RawPointer to strict $*Int
847846
// store %85 to %84 : $*Int
848847
// %87 = integer_literal $Builtin.Word, 1
@@ -851,27 +850,12 @@ bool swift::ArraySemanticsCall::mapInitializationStores(
851850

852851
// If this an ArrayUninitializedIntrinsic then the ElementBuffer is a
853852
// builtin.RawPointer. Otherwise, it is an UnsafeMutablePointer, which would
854-
// be struct-extracted to obtain a builtin.RawPointer. In this case
855-
// mark_dependence can be an operand of the struct_extract or its user.
856-
857-
SILValue UnsafeMutablePointerExtract;
858-
if (getKind() == ArrayCallKind::kArrayUninitializedIntrinsic) {
859-
UnsafeMutablePointerExtract = dyn_cast_or_null<MarkDependenceInst>(
860-
getSingleNonDebugUser(ElementBuffer));
861-
} else {
862-
auto user = getSingleNonDebugUser(ElementBuffer);
863-
// Match mark_dependence (struct_extract or
864-
// struct_extract (mark_dependence
865-
if (auto *MDI = dyn_cast_or_null<MarkDependenceInst>(user)) {
866-
UnsafeMutablePointerExtract =
867-
dyn_cast_or_null<StructExtractInst>(getSingleNonDebugUser(MDI));
868-
} else {
869-
if (auto *SEI = dyn_cast_or_null<StructExtractInst>(user)) {
870-
UnsafeMutablePointerExtract =
871-
dyn_cast_or_null<MarkDependenceInst>(getSingleNonDebugUser(SEI));
872-
}
873-
}
874-
}
853+
// be struct-extracted to obtain a builtin.RawPointer.
854+
SILValue UnsafeMutablePointerExtract =
855+
(getKind() == ArrayCallKind::kArrayUninitialized)
856+
? dyn_cast_or_null<StructExtractInst>(
857+
getSingleNonDebugUser(ElementBuffer))
858+
: ElementBuffer;
875859
if (!UnsafeMutablePointerExtract)
876860
return false;
877861

lib/SILOptimizer/Analysis/DifferentiableActivityAnalysis.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -429,15 +429,12 @@ void DifferentiableActivityInfo::setUsefulThroughArrayInitialization(
429429
continue;
430430
// The second tuple field of the return value is the `RawPointer`.
431431
for (auto use : dti->getResult(1)->getUses()) {
432-
// The `RawPointer` passes through a `mark_dependence(pointer_to_address`.
433-
// That instruction's first use is a `store` whose source is useful; its
432+
// The `RawPointer` passes through a `pointer_to_address`. That
433+
// instruction's first use is a `store` whose source is useful; its
434434
// subsequent uses are `index_addr`s whose only use is a useful `store`.
435-
auto *mdi = dyn_cast<MarkDependenceInst>(use->getUser());
436-
assert(
437-
mdi &&
438-
"Expected a mark_dependence user for uninitialized array intrinsic.");
439-
auto *ptai = dyn_cast<PointerToAddressInst>(getSingleNonDebugUser(mdi));
440-
assert(ptai && "Expected a pointer_to_address.");
435+
auto *ptai = dyn_cast<PointerToAddressInst>(use->getUser());
436+
assert(ptai && "Expected `pointer_to_address` user for uninitialized "
437+
"array intrinsic");
441438
setUseful(ptai, dependentVariableIndex);
442439
// Propagate usefulness through array element addresses:
443440
// `pointer_to_address` and `index_addr` instructions.

lib/SILOptimizer/Differentiation/Common.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,30 @@ ApplyInst *getAllocateUninitializedArrayIntrinsicElementAddress(SILValue v) {
3737
ptai = dyn_cast<PointerToAddressInst>(iai->getOperand(0));
3838
if (!ptai)
3939
return nullptr;
40-
auto *mdi = dyn_cast<MarkDependenceInst>(
41-
ptai->getOperand()->getDefiningInstruction());
42-
if (!mdi)
43-
return nullptr;
4440
// Return the `array.uninitialized_intrinsic` application, if it exists.
4541
if (auto *dti = dyn_cast<DestructureTupleInst>(
46-
mdi->getValue()->getDefiningInstruction()))
42+
ptai->getOperand()->getDefiningInstruction()))
4743
return ArraySemanticsCall(dti->getOperand(),
4844
semantics::ARRAY_UNINITIALIZED_INTRINSIC);
4945
return nullptr;
5046
}
5147

48+
DestructureTupleInst *getSingleDestructureTupleUser(SILValue value) {
49+
bool foundDestructureTupleUser = false;
50+
if (!value->getType().is<TupleType>())
51+
return nullptr;
52+
DestructureTupleInst *result = nullptr;
53+
for (auto *use : value->getUses()) {
54+
if (auto *dti = dyn_cast<DestructureTupleInst>(use->getUser())) {
55+
assert(!foundDestructureTupleUser &&
56+
"There should only be one `destructure_tuple` user of a tuple");
57+
foundDestructureTupleUser = true;
58+
result = dti;
59+
}
60+
}
61+
return result;
62+
}
63+
5264
bool isSemanticMemberAccessor(SILFunction *original) {
5365
auto *dc = original->getDeclContext();
5466
if (!dc)
@@ -97,7 +109,7 @@ void forEachApplyDirectResult(
97109
resultCallback(ai);
98110
return;
99111
}
100-
if (auto *dti = ai->getSingleUserOfType<DestructureTupleInst>())
112+
if (auto *dti = getSingleDestructureTupleUser(ai))
101113
for (auto directResult : dti->getResults())
102114
resultCallback(directResult);
103115
break;

lib/SILOptimizer/Differentiation/JVPCloner.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1312,8 +1312,7 @@ class JVPCloner::Implementation final
13121312
if (!origResult->getType().is<TupleType>()) {
13131313
setTangentValue(bb, origResult,
13141314
makeConcreteTangentValue(differentialResult));
1315-
} else if (auto *dti =
1316-
ai->getSingleUserOfType<DestructureTupleInst>()) {
1315+
} else if (auto *dti = getSingleDestructureTupleUser(ai)) {
13171316
bool notSetValue = true;
13181317
for (auto result : dti->getResults()) {
13191318
if (activityInfo.isActive(result, getConfig())) {

lib/SILOptimizer/Differentiation/PullbackCloner.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3331,11 +3331,7 @@ void PullbackCloner::Implementation::
33313331
builder.setCurrentDebugScope(remapScope(dti->getDebugScope()));
33323332
builder.setInsertionPoint(arrayAdjoint->getParentBlock());
33333333
for (auto use : dti->getResult(1)->getUses()) {
3334-
auto *mdi = dyn_cast<MarkDependenceInst>(use->getUser());
3335-
assert(mdi && "Expected mark_dependence user");
3336-
auto *ptai =
3337-
dyn_cast_or_null<PointerToAddressInst>(getSingleNonDebugUser(mdi));
3338-
assert(ptai && "Expected pointer_to_address user");
3334+
auto *ptai = dyn_cast<PointerToAddressInst>(use->getUser());
33393335
auto adjBuf = getAdjointBuffer(origBB, ptai);
33403336
auto *eltAdjBuf = getArrayAdjointElementBuffer(arrayAdjoint, 0, loc);
33413337
builder.emitInPlaceAdd(loc, adjBuf, eltAdjBuf);

lib/SILOptimizer/LoopTransforms/ForEachLoopUnroll.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -302,11 +302,6 @@ void ArrayInfo::classifyUsesOfArray(SILValue arrayValue) {
302302
// above as the array would be passed indirectly.
303303
if (isFixLifetimeUseOfArray(user, arrayValue))
304304
continue;
305-
if (auto *MDI = dyn_cast<MarkDependenceInst>(user)) {
306-
if (MDI->getBase() == arrayValue) {
307-
continue;
308-
}
309-
}
310305
// Check if this is a forEach call on the array.
311306
if (TryApplyInst *forEachCall = isForEachUseOfArray(user, arrayValue)) {
312307
forEachCalls.insert(forEachCall);

lib/SILOptimizer/Transforms/ArrayCountPropagation.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -127,12 +127,6 @@ bool ArrayAllocation::recursivelyCollectUses(ValueBase *Def) {
127127
isa<DebugValueInst>(User))
128128
continue;
129129

130-
if (auto *MDI = dyn_cast<MarkDependenceInst>(User)) {
131-
if (Def == MDI->getBase()) {
132-
continue;
133-
}
134-
}
135-
136130
// Array value projection.
137131
if (auto *SEI = dyn_cast<StructExtractInst>(User)) {
138132
if (!recursivelyCollectUses(SEI))

lib/SILOptimizer/Transforms/ArrayElementValuePropagation.cpp

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,6 @@ bool ArrayAllocation::replacementsAreValid() {
122122
/// Recursively look at all uses of this definition. Abort if the array value
123123
/// could escape or be changed. Collect all uses that are calls to array.count.
124124
bool ArrayAllocation::recursivelyCollectUses(ValueBase *Def) {
125-
LLVM_DEBUG(llvm::dbgs() << "Collecting uses of:");
126-
LLVM_DEBUG(Def->dump());
127-
128125
for (auto *Opd : Def->getUses()) {
129126
auto *User = Opd->getUser();
130127
// Ignore reference counting and debug instructions.
@@ -151,12 +148,6 @@ bool ArrayAllocation::recursivelyCollectUses(ValueBase *Def) {
151148
continue;
152149
}
153150

154-
if (auto *MDI = dyn_cast<MarkDependenceInst>(User)) {
155-
if (Def != MDI->getBase())
156-
return false;
157-
continue;
158-
}
159-
160151
// Check array semantic calls.
161152
ArraySemanticsCall ArrayOp(User);
162153
switch (ArrayOp.getKind()) {
@@ -190,28 +181,17 @@ bool ArrayAllocation::analyze(ApplyInst *Alloc) {
190181
if (!Uninitialized)
191182
return false;
192183

193-
LLVM_DEBUG(llvm::dbgs() << "Found array allocation: ");
194-
LLVM_DEBUG(Alloc->dump());
195-
196184
ArrayValue = Uninitialized.getArrayValue();
197-
if (!ArrayValue) {
198-
LLVM_DEBUG(llvm::dbgs() << "Did not find array value\n");
185+
if (!ArrayValue)
199186
return false;
200-
}
201187

202-
LLVM_DEBUG(llvm::dbgs() << "ArrayValue: ");
203-
LLVM_DEBUG(ArrayValue->dump());
204188
// Figure out all stores to the array.
205-
if (!mapInitializationStores(Uninitialized)) {
206-
LLVM_DEBUG(llvm::dbgs() << "Could not map initializing stores\n");
189+
if (!mapInitializationStores(Uninitialized))
207190
return false;
208-
}
209191

210192
// Check if the array value was stored or has escaped.
211-
if (!recursivelyCollectUses(ArrayValue)) {
212-
LLVM_DEBUG(llvm::dbgs() << "Array value stored or escaped\n");
193+
if (!recursivelyCollectUses(ArrayValue))
213194
return false;
214-
}
215195

216196
return true;
217197
}
@@ -348,9 +328,7 @@ class ArrayElementPropagation : public SILFunctionTransform {
348328
auto &Fn = *getFunction();
349329
bool Changed = false;
350330

351-
LLVM_DEBUG(llvm::dbgs() << "ArrayElementPropagation looking at function: "
352-
<< Fn.getName() << "\n");
353-
for (auto &BB : Fn) {
331+
for (auto &BB :Fn) {
354332
for (auto &Inst : BB) {
355333
if (auto *Apply = dyn_cast<ApplyInst>(&Inst)) {
356334
ArrayAllocation ALit;

lib/SILOptimizer/Transforms/DeadObjectElimination.cpp

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -616,13 +616,6 @@ recursivelyCollectInteriorUses(ValueBase *DefInst,
616616
AllUsers.insert(User);
617617
continue;
618618
}
619-
if (auto *MDI = dyn_cast<MarkDependenceInst>(User)) {
620-
if (!recursivelyCollectInteriorUses(MDI, AddressNode,
621-
IsInteriorAddress)) {
622-
return false;
623-
}
624-
continue;
625-
}
626619
if (auto PTAI = dyn_cast<PointerToAddressInst>(User)) {
627620
// Only one pointer-to-address is allowed for safety.
628621
if (SeenPtrToAddr)
@@ -1170,17 +1163,11 @@ bool DeadObjectElimination::processAllocApply(ApplyInst *AI,
11701163

11711164
LLVM_DEBUG(llvm::dbgs() << " Success! Eliminating apply allocate(...).\n");
11721165

1173-
auto *ARI = dyn_cast<AllocRefInst>(AI->getArgument(0));
1174-
11751166
deleter.forceDeleteWithUsers(AI);
11761167
for (auto *toDelete : instsDeadAfterInitializerRemoved) {
11771168
deleter.trackIfDead(toDelete);
11781169
}
11791170

1180-
if (ARI) {
1181-
deleter.forceDeleteWithUsers(ARI);
1182-
}
1183-
11841171
++DeadAllocApplyEliminated;
11851172
return true;
11861173
}

lib/SILOptimizer/Utils/ConstExpr.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -528,9 +528,6 @@ SymbolicValue ConstExprFunctionState::computeConstantValue(SILValue value) {
528528
if (auto *convertEscapeInst = dyn_cast<ConvertEscapeToNoEscapeInst>(value))
529529
return getConstantValue(convertEscapeInst->getOperand());
530530

531-
if (auto *mdi = dyn_cast<MarkDependenceInst>(value))
532-
return getConstantValue(mdi->getValue());
533-
534531
LLVM_DEBUG(llvm::dbgs() << "ConstExpr Unknown simple: " << *value << "\n");
535532

536533
// Otherwise, we don't know how to handle this.

0 commit comments

Comments
 (0)