Skip to content

Commit adbcd6a

Browse files
authored
Merge pull request swiftlang#34267 from slavapestov/misc-sil-cleanup
A couple of SIL fixes
2 parents 3bc381b + 53b91da commit adbcd6a

File tree

7 files changed

+112
-400
lines changed

7 files changed

+112
-400
lines changed

lib/SIL/Utils/OwnershipUtils.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -543,16 +543,18 @@ bool InteriorPointerOperand::getImplicitUses(
543543
isa<BeginUnpairedAccessInst>(user) ||
544544
isa<EndUnpairedAccessInst>(user) || isa<WitnessMethodInst>(user) ||
545545
isa<SwitchEnumAddrInst>(user) || isa<CheckedCastAddrBranchInst>(user) ||
546-
isa<SelectEnumAddrInst>(user)) {
546+
isa<SelectEnumAddrInst>(user) || isa<InjectEnumAddrInst>(user)) {
547547
continue;
548548
}
549549

550550
// Then handle users that we need to look at transitive uses of.
551551
if (Projection::isAddressProjection(user) ||
552552
isa<ProjectBlockStorageInst>(user) ||
553553
isa<OpenExistentialAddrInst>(user) ||
554-
isa<InitExistentialAddrInst>(user) || isa<BeginAccessInst>(user) ||
555-
isa<TailAddrInst>(user) || isa<IndexAddrInst>(user)) {
554+
isa<InitExistentialAddrInst>(user) ||
555+
isa<InitEnumDataAddrInst>(user) || isa<BeginAccessInst>(user) ||
556+
isa<TailAddrInst>(user) || isa<IndexAddrInst>(user) ||
557+
isa<UnconditionalCheckedCastAddrInst>(user)) {
556558
for (SILValue r : user->getResults()) {
557559
llvm::copy(r->getUses(), std::back_inserter(worklist));
558560
}

lib/SIL/Verifier/SILOwnershipVerifier.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ bool SILValueOwnershipChecker::gatherUsers(
391391
llvm::errs() << "Could not recognize address user of interior "
392392
"pointer operand!\n"
393393
<< "Interior Pointer Operand: "
394-
<< interiorPointerOperand->operand->getUser()
394+
<< *interiorPointerOperand->operand->getUser()
395395
<< "Address User: " << *op->getUser();
396396
});
397397
};

lib/SILOptimizer/Mandatory/DIMemoryUseCollector.cpp

Lines changed: 1 addition & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -466,48 +466,6 @@ void DIElementUseInfo::trackStoreToSelf(SILInstruction *I) {
466466
StoresToSelf.push_back(I);
467467
}
468468

469-
//===----------------------------------------------------------------------===//
470-
// Scalarization Logic
471-
//===----------------------------------------------------------------------===//
472-
473-
/// Given a pointer to a tuple type, compute the addresses of each element and
474-
/// add them to the ElementAddrs vector.
475-
static void
476-
getScalarizedElementAddresses(SILValue Pointer, SILBuilder &B, SILLocation Loc,
477-
SmallVectorImpl<SILValue> &ElementAddrs) {
478-
TupleType *TT = Pointer->getType().castTo<TupleType>();
479-
for (auto Index : indices(TT->getElements())) {
480-
ElementAddrs.push_back(B.createTupleElementAddr(Loc, Pointer, Index));
481-
}
482-
}
483-
484-
/// Given an RValue of aggregate type, compute the values of the elements by
485-
/// emitting a destructure.
486-
static void getScalarizedElements(SILValue V,
487-
SmallVectorImpl<SILValue> &ElementVals,
488-
SILLocation Loc, SILBuilder &B) {
489-
auto *DTI = B.createDestructureTuple(Loc, V);
490-
llvm::copy(DTI->getResults(), std::back_inserter(ElementVals));
491-
}
492-
493-
/// Scalarize a load down to its subelements. If NewLoads is specified, this
494-
/// can return the newly generated sub-element loads.
495-
static SILValue scalarizeLoad(LoadInst *LI,
496-
SmallVectorImpl<SILValue> &ElementAddrs) {
497-
SILBuilderWithScope B(LI);
498-
SmallVector<SILValue, 4> ElementTmps;
499-
500-
for (unsigned i = 0, e = ElementAddrs.size(); i != e; ++i) {
501-
auto *SubLI = B.createTrivialLoadOr(LI->getLoc(), ElementAddrs[i],
502-
LI->getOwnershipQualifier());
503-
ElementTmps.push_back(SubLI);
504-
}
505-
506-
if (LI->getType().is<TupleType>())
507-
return B.createTuple(LI->getLoc(), LI->getType(), ElementTmps);
508-
return B.createStruct(LI->getLoc(), LI->getType(), ElementTmps);
509-
}
510-
511469
//===----------------------------------------------------------------------===//
512470
// ElementUseCollector Implementation
513471
//===----------------------------------------------------------------------===//
@@ -671,11 +629,6 @@ void ElementUseCollector::collectUses(SILValue Pointer, unsigned BaseEltNo) {
671629
"Walked through the pointer to the value?");
672630
SILType PointeeType = Pointer->getType().getObjectType();
673631

674-
// This keeps track of instructions in the use list that touch multiple tuple
675-
// elements and should be scalarized. This is done as a second phase to
676-
// avoid invalidating the use iterator.
677-
SmallVector<SILInstruction *, 4> UsesToScalarize;
678-
679632
for (auto *Op : Pointer->getUses()) {
680633
auto *User = Op->getUser();
681634

@@ -705,10 +658,7 @@ void ElementUseCollector::collectUses(SILValue Pointer, unsigned BaseEltNo) {
705658

706659
// Loads are a use of the value.
707660
if (isa<LoadInst>(User)) {
708-
if (PointeeType.is<TupleType>())
709-
UsesToScalarize.push_back(User);
710-
else
711-
addElementUses(BaseEltNo, PointeeType, User, DIUseKind::Load);
661+
addElementUses(BaseEltNo, PointeeType, User, DIUseKind::Load);
712662
continue;
713663
}
714664

@@ -730,13 +680,6 @@ void ElementUseCollector::collectUses(SILValue Pointer, unsigned BaseEltNo) {
730680
if ((isa<StoreInst>(User) || isa<AssignInst>(User) ||
731681
isa<AssignByWrapperInst>(User)) &&
732682
Op->getOperandNumber() == 1) {
733-
if (PointeeType.is<TupleType>()) {
734-
assert(!isa<AssignByWrapperInst>(User) &&
735-
"cannot assign a typle with assign_by_wrapper");
736-
UsesToScalarize.push_back(User);
737-
continue;
738-
}
739-
740683
// Coming out of SILGen, we assume that raw stores are initializations,
741684
// unless they have trivial type (which we classify as InitOrAssign).
742685
DIUseKind Kind;
@@ -769,13 +712,6 @@ void ElementUseCollector::collectUses(SILValue Pointer, unsigned BaseEltNo) {
769712
#include "swift/AST/ReferenceStorage.def"
770713

771714
if (auto *CAI = dyn_cast<CopyAddrInst>(User)) {
772-
// If this is a copy of a tuple, we should scalarize it so that we don't
773-
// have an access that crosses elements.
774-
if (PointeeType.is<TupleType>()) {
775-
UsesToScalarize.push_back(CAI);
776-
continue;
777-
}
778-
779715
// If this is the source of the copy_addr, then this is a load. If it is
780716
// the destination, then this is an unknown assignment. Note that we'll
781717
// revisit this instruction and add it to Uses twice if it is both a load
@@ -988,88 +924,6 @@ void ElementUseCollector::collectUses(SILValue Pointer, unsigned BaseEltNo) {
988924
// Otherwise, the use is something complicated, it escapes.
989925
addElementUses(BaseEltNo, PointeeType, User, DIUseKind::Escape);
990926
}
991-
992-
// Now that we've walked all of the immediate uses, scalarize any operations
993-
// working on tuples if we need to for canonicalization or analysis reasons.
994-
if (!UsesToScalarize.empty()) {
995-
SILInstruction *PointerInst = Pointer->getDefiningInstruction();
996-
SmallVector<SILValue, 4> ElementAddrs;
997-
SILBuilderWithScope AddrBuilder(++SILBasicBlock::iterator(PointerInst),
998-
PointerInst);
999-
getScalarizedElementAddresses(Pointer, AddrBuilder, PointerInst->getLoc(),
1000-
ElementAddrs);
1001-
1002-
SmallVector<SILValue, 4> ElementTmps;
1003-
for (auto *User : UsesToScalarize) {
1004-
ElementTmps.clear();
1005-
1006-
LLVM_DEBUG(llvm::errs() << " *** Scalarizing: " << *User << "\n");
1007-
1008-
// Scalarize LoadInst
1009-
if (auto *LI = dyn_cast<LoadInst>(User)) {
1010-
SILValue Result = scalarizeLoad(LI, ElementAddrs);
1011-
LI->replaceAllUsesWith(Result);
1012-
LI->eraseFromParent();
1013-
continue;
1014-
}
1015-
1016-
// Scalarize AssignInst
1017-
if (auto *AI = dyn_cast<AssignInst>(User)) {
1018-
SILBuilderWithScope B(User, AI);
1019-
getScalarizedElements(AI->getOperand(0), ElementTmps, AI->getLoc(), B);
1020-
1021-
for (unsigned i = 0, e = ElementAddrs.size(); i != e; ++i)
1022-
B.createAssign(AI->getLoc(), ElementTmps[i], ElementAddrs[i],
1023-
AssignOwnershipQualifier::Unknown);
1024-
AI->eraseFromParent();
1025-
continue;
1026-
}
1027-
1028-
// Scalarize StoreInst
1029-
if (auto *SI = dyn_cast<StoreInst>(User)) {
1030-
SILBuilderWithScope B(User, SI);
1031-
getScalarizedElements(SI->getOperand(0), ElementTmps, SI->getLoc(), B);
1032-
1033-
for (unsigned i = 0, e = ElementAddrs.size(); i != e; ++i)
1034-
B.createTrivialStoreOr(SI->getLoc(), ElementTmps[i], ElementAddrs[i],
1035-
SI->getOwnershipQualifier());
1036-
SI->eraseFromParent();
1037-
continue;
1038-
}
1039-
1040-
// Scalarize CopyAddrInst.
1041-
auto *CAI = cast<CopyAddrInst>(User);
1042-
SILBuilderWithScope B(User, CAI);
1043-
1044-
// Determine if this is a copy *from* or *to* "Pointer".
1045-
if (CAI->getSrc() == Pointer) {
1046-
// Copy from pointer.
1047-
getScalarizedElementAddresses(CAI->getDest(), B, CAI->getLoc(),
1048-
ElementTmps);
1049-
for (unsigned i = 0, e = ElementAddrs.size(); i != e; ++i)
1050-
B.createCopyAddr(CAI->getLoc(), ElementAddrs[i], ElementTmps[i],
1051-
CAI->isTakeOfSrc(), CAI->isInitializationOfDest());
1052-
1053-
} else {
1054-
getScalarizedElementAddresses(CAI->getSrc(), B, CAI->getLoc(),
1055-
ElementTmps);
1056-
for (unsigned i = 0, e = ElementAddrs.size(); i != e; ++i)
1057-
B.createCopyAddr(CAI->getLoc(), ElementTmps[i], ElementAddrs[i],
1058-
CAI->isTakeOfSrc(), CAI->isInitializationOfDest());
1059-
}
1060-
CAI->eraseFromParent();
1061-
}
1062-
1063-
// Now that we've scalarized some stuff, recurse down into the newly created
1064-
// element address computations to recursively process it. This can cause
1065-
// further scalarization.
1066-
for (SILValue EltPtr : ElementAddrs) {
1067-
if (auto *TEAI = dyn_cast<TupleElementAddrInst>(EltPtr)) {
1068-
collectTupleElementUses(TEAI, BaseEltNo);
1069-
continue;
1070-
}
1071-
}
1072-
}
1073927
}
1074928

1075929
/// collectClassSelfUses - Collect all the uses of a 'self' pointer in a class

lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ namespace {
394394

395395
/// This is a map of uses that are not loads (i.e., they are Stores,
396396
/// InOutUses, and Escapes), to their entry in Uses.
397-
llvm::SmallDenseMap<SILInstruction*, unsigned, 16> NonLoadUses;
397+
llvm::SmallDenseMap<SILInstruction*, SmallVector<unsigned, 1>, 16> NonLoadUses;
398398

399399
/// This is true when there is an ambiguous store, which may be an init or
400400
/// assign, depending on the CFG path.
@@ -472,7 +472,7 @@ namespace {
472472

473473
void handleSelfInitUse(unsigned UseID);
474474

475-
void updateInstructionForInitState(DIMemoryUse &Use);
475+
void updateInstructionForInitState(unsigned UseID);
476476

477477

478478
void processUninitializedRelease(SILInstruction *Release,
@@ -544,7 +544,7 @@ LifetimeChecker::LifetimeChecker(const DIMemoryObjectInfo &TheMemory,
544544
break;
545545
}
546546

547-
NonLoadUses[Use.Inst] = ui;
547+
NonLoadUses[Use.Inst].push_back(ui);
548548

549549
auto &BBInfo = getBlockInfo(Use.Inst->getParent());
550550
BBInfo.HasNonLoadUse = true;
@@ -562,9 +562,8 @@ LifetimeChecker::LifetimeChecker(const DIMemoryObjectInfo &TheMemory,
562562
getBlockInfo(bb).markStoreToSelf();
563563
}
564564

565-
// If isn't really a use, but we account for the mark_uninitialized or
565+
// It isn't really a use, but we account for the mark_uninitialized or
566566
// project_box as a use so we see it in our dataflow walks.
567-
NonLoadUses[TheMemory.getUninitializedValue()] = ~0U;
568567
auto &MemBBInfo = getBlockInfo(TheMemory.getParentBlock());
569568
MemBBInfo.HasNonLoadUse = true;
570569

@@ -826,7 +825,7 @@ void LifetimeChecker::doIt() {
826825
// postpone lowering of assignment instructions to avoid deleting
827826
// instructions that still appear in the Uses list.
828827
for (unsigned UseID : NeedsUpdateForInitState)
829-
updateInstructionForInitState(Uses[UseID]);
828+
updateInstructionForInitState(UseID);
830829
}
831830

832831
void LifetimeChecker::handleLoadUse(const DIMemoryUse &Use) {
@@ -1911,7 +1910,8 @@ void LifetimeChecker::handleSelfInitUse(unsigned UseID) {
19111910
/// from being InitOrAssign to some concrete state, update it for that state.
19121911
/// This includes rewriting them from assign instructions into their composite
19131912
/// operations.
1914-
void LifetimeChecker::updateInstructionForInitState(DIMemoryUse &Use) {
1913+
void LifetimeChecker::updateInstructionForInitState(unsigned UseID) {
1914+
DIMemoryUse &Use = Uses[UseID];
19151915
SILInstruction *Inst = Use.Inst;
19161916

19171917
IsInitialization_t InitKind;
@@ -1945,10 +1945,11 @@ void LifetimeChecker::updateInstructionForInitState(DIMemoryUse &Use) {
19451945
// If this is an assign, rewrite it based on whether it is an initialization
19461946
// or not.
19471947
if (auto *AI = dyn_cast<AssignInst>(Inst)) {
1948+
19481949
// Remove this instruction from our data structures, since we will be
19491950
// removing it.
19501951
Use.Inst = nullptr;
1951-
NonLoadUses.erase(Inst);
1952+
llvm::erase_if(NonLoadUses[Inst], [&](unsigned id) { return id == UseID; });
19521953

19531954
if (TheMemory.isClassInitSelf() &&
19541955
Use.Kind == DIUseKind::SelfInit) {
@@ -1966,7 +1967,7 @@ void LifetimeChecker::updateInstructionForInitState(DIMemoryUse &Use) {
19661967
// Remove this instruction from our data structures, since we will be
19671968
// removing it.
19681969
Use.Inst = nullptr;
1969-
NonLoadUses.erase(Inst);
1970+
llvm::erase_if(NonLoadUses[Inst], [&](unsigned id) { return id == UseID; });
19701971

19711972
switch (Use.Kind) {
19721973
case DIUseKind::Initialization:
@@ -2819,17 +2820,17 @@ LifetimeChecker::getLivenessAtNonTupleInst(swift::SILInstruction *Inst,
28192820
--BBI;
28202821
SILInstruction *TheInst = &*BBI;
28212822

2822-
// If this instruction is unrelated to the memory, ignore it.
2823-
if (!NonLoadUses.count(TheInst))
2824-
continue;
2823+
if (TheInst == TheMemory.getUninitializedValue()) {
2824+
Result.set(0, DIKind::No);
2825+
return Result;
2826+
}
28252827

2826-
// If we found the allocation itself, then we are loading something that
2827-
// is not defined at all yet. Otherwise, we've found a definition, or
2828-
// something else that will require that the memory is initialized at
2829-
// this point.
2830-
Result.set(0, TheInst == TheMemory.getUninitializedValue() ? DIKind::No
2831-
: DIKind::Yes);
2832-
return Result;
2828+
if (NonLoadUses.count(TheInst)) {
2829+
// We've found a definition, or something else that will require that
2830+
// the memory is initialized at this point.
2831+
Result.set(0, DIKind::Yes);
2832+
return Result;
2833+
}
28332834
}
28342835
}
28352836

@@ -2882,11 +2883,6 @@ AvailabilitySet LifetimeChecker::getLivenessAtInst(SILInstruction *Inst,
28822883
--BBI;
28832884
SILInstruction *TheInst = &*BBI;
28842885

2885-
// If this instruction is unrelated to the memory, ignore it.
2886-
auto It = NonLoadUses.find(TheInst);
2887-
if (It == NonLoadUses.end())
2888-
continue;
2889-
28902886
// If we found the allocation itself, then we are loading something that
28912887
// is not defined at all yet. Scan no further.
28922888
if (TheInst == TheMemory.getUninitializedValue()) {
@@ -2896,11 +2892,19 @@ AvailabilitySet LifetimeChecker::getLivenessAtInst(SILInstruction *Inst,
28962892
return Result;
28972893
}
28982894

2895+
// If this instruction is unrelated to the memory, ignore it.
2896+
auto It = NonLoadUses.find(TheInst);
2897+
if (It == NonLoadUses.end())
2898+
continue;
2899+
28992900
// Check to see which tuple elements this instruction defines. Clear them
29002901
// from the set we're scanning from.
2901-
auto &TheInstUse = Uses[It->second];
2902-
NeededElements.reset(TheInstUse.FirstElement,
2903-
TheInstUse.FirstElement+TheInstUse.NumElements);
2902+
for (unsigned TheUse : It->second) {
2903+
auto &TheInstUse = Uses[TheUse];
2904+
NeededElements.reset(TheInstUse.FirstElement,
2905+
TheInstUse.FirstElement+TheInstUse.NumElements);
2906+
}
2907+
29042908
// If that satisfied all of the elements we're looking for, then we're
29052909
// done. Otherwise, keep going.
29062910
if (NeededElements.none()) {

0 commit comments

Comments
 (0)