Skip to content

Delete Dead Code from DI #16849

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 15 additions & 77 deletions lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,19 +62,9 @@ static unsigned getElementCountRec(SILModule &Module, SILType T,
}

static std::pair<SILType, bool>
computeMemorySILType(SILInstruction *MemoryInst) {
computeMemorySILType(MarkUninitializedInst *MemoryInst) {
// Compute the type of the memory object.
if (auto *ABI = dyn_cast<AllocBoxInst>(MemoryInst)) {
assert(ABI->getBoxType()->getLayout()->getFields().size() == 1 &&
"analyzing multi-field boxes not implemented");
return {ABI->getBoxType()->getFieldType(MemoryInst->getModule(), 0), false};
}

if (auto *ASI = dyn_cast<AllocStackInst>(MemoryInst)) {
return {ASI->getElementType(), false};
}

auto *MUI = cast<MarkUninitializedInst>(MemoryInst);
auto *MUI = MemoryInst;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove MUI since you never re-assign it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

SILType MemorySILType = MUI->getType().getObjectType();

// If this is a let variable we're initializing, remember this so we don't
Expand All @@ -89,7 +79,7 @@ computeMemorySILType(SILInstruction *MemoryInst) {
return {MemorySILType, VDecl->isLet()};
}

DIMemoryObjectInfo::DIMemoryObjectInfo(SingleValueInstruction *MI)
DIMemoryObjectInfo::DIMemoryObjectInfo(MarkUninitializedInst *MI)
: MemoryInst(MI) {
auto &Module = MI->getModule();

Expand Down Expand Up @@ -352,9 +342,8 @@ DIMemoryObjectInfo::getPathStringToElement(unsigned Element,

// If we are analyzing a variable, we can generally get the decl associated
// with it.
if (auto *MUI = dyn_cast<MarkUninitializedInst>(MemoryInst))
if (MUI->isVar())
return MUI->getLoc().getAsASTNode<VarDecl>();
if (MemoryInst->isVar())
return MemoryInst->getLoc().getAsASTNode<VarDecl>();

// Otherwise, we can't.
return nullptr;
Expand Down Expand Up @@ -389,23 +378,6 @@ bool DIMemoryObjectInfo::isElementLetProperty(unsigned Element) const {
return false;
}

void DIMemoryObjectInfo::collectRetainCountInfo(
DIElementUseInfo &OutVar) const {
if (isa<MarkUninitializedInst>(MemoryInst))
return;

// Collect information about the retain count result as well.
for (auto *Op : MemoryInst->getUses()) {
auto *User = Op->getUser();

// If this is a release or dealloc_stack, then remember it as such.
if (isa<StrongReleaseInst>(User) || isa<DeallocStackInst>(User) ||
isa<DeallocBoxInst>(User) || isa<DestroyValueInst>(User)) {
OutVar.trackDestroy(User);
}
}
}

//===----------------------------------------------------------------------===//
// DIMemoryUse Implementation
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -535,17 +507,10 @@ class ElementUseCollector {
"Should have been handled outside of here");
// If this is a class pointer, we need to look through ref_element_addrs.
collectClassSelfUses();
TheMemory.collectRetainCountInfo(UseInfo);
return;
}

if (auto *ABI = TheMemory.getContainer()) {
collectContainerUses(ABI);
} else {
collectUses(TheMemory.getAddress(), 0);
}

TheMemory.collectRetainCountInfo(UseInfo);
collectUses(TheMemory.MemoryInst, 0);
}

void trackUse(DIMemoryUse Use) { UseInfo.trackUse(Use); }
Expand All @@ -558,7 +523,6 @@ class ElementUseCollector {

private:
void collectUses(SILValue Pointer, unsigned BaseEltNo);
void collectContainerUses(AllocBoxInst *ABI);
void collectClassSelfUses();
void collectClassSelfUses(SILValue ClassPointer, SILType MemorySILType,
llvm::SmallDenseMap<VarDecl *, unsigned> &EN);
Expand Down Expand Up @@ -670,29 +634,6 @@ void ElementUseCollector::collectStructElementUses(StructElementAddrInst *SEAI,
collectUses(SEAI, BaseEltNo);
}

void ElementUseCollector::collectContainerUses(AllocBoxInst *ABI) {
for (auto *Op : ABI->getUses()) {
auto *User = Op->getUser();

// Deallocations and retain/release don't affect the value directly.
if (isa<DeallocBoxInst>(User) || isa<StrongRetainInst>(User) ||
isa<StrongReleaseInst>(User) || isa<DestroyValueInst>(User))
continue;

if (auto *PBI = dyn_cast<ProjectBoxInst>(User)) {
collectUses(PBI, PBI->getFieldIndex());
continue;
}

// Other uses of the container are considered escapes of the values.
for (unsigned Field : indices(ABI->getBoxType()->getLayout()->getFields())) {
addElementUses(Field,
ABI->getBoxType()->getFieldType(ABI->getModule(), Field),
User, DIUseKind::Escape);
}
}
}

/// Return the underlying accessed pointer value. This peeks through
/// begin_access patterns such as:
///
Expand Down Expand Up @@ -1092,10 +1033,9 @@ void ElementUseCollector::collectClassSelfUses() {

// If we are looking at the init method for a root class, just walk the
// MUI use-def chain directly to find our uses.
auto *MUI = cast<MarkUninitializedInst>(TheMemory.MemoryInst);
if (MUI->getKind() == MarkUninitializedInst::RootSelf) {
collectClassSelfUses(TheMemory.getAddress(), TheMemory.MemorySILType,
EltNumbering);
auto *MemoryInst = TheMemory.MemoryInst;
if (MemoryInst->getKind() == MarkUninitializedInst::RootSelf) {
collectClassSelfUses(MemoryInst, TheMemory.MemorySILType, EltNumbering);
return;
}

Expand All @@ -1112,7 +1052,7 @@ void ElementUseCollector::collectClassSelfUses() {
// 4) Potential escapes after super.init, if self is closed over.
//
// Handle each of these in turn.
SmallVector<Operand *, 8> Uses(MUI->getUses());
SmallVector<Operand *, 8> Uses(MemoryInst->getUses());
while (!Uses.empty()) {
Operand *Op = Uses.pop_back_val();
SILInstruction *User = Op->getUser();
Expand All @@ -1123,7 +1063,7 @@ void ElementUseCollector::collectClassSelfUses() {
// The initial store of 'self' into the box at the start of the
// function. Ignore it.
if (auto *Arg = dyn_cast<SILArgument>(SI->getSrc())) {
if (Arg->getParent() == MUI->getParent()) {
if (Arg->getParent() == MemoryInst->getParent()) {
StoresOfArgumentToSelf++;
continue;
}
Expand All @@ -1138,7 +1078,7 @@ void ElementUseCollector::collectClassSelfUses() {
src = conversion->getConverted();

if (auto *LI = dyn_cast<LoadInst>(src))
if (LI->getOperand() == MUI)
if (LI->getOperand() == MemoryInst)
continue;

// Any other store needs to be recorded.
Expand Down Expand Up @@ -1548,7 +1488,7 @@ void DelegatingClassInitElementUseCollector::collectClassInitSelfUses() {
// all. Just treat all members of self as uses of the single
// non-field-sensitive value.
assert(TheMemory.NumElements == 1 && "delegating inits only have 1 bit");
auto *MUI = cast<MarkUninitializedInst>(TheMemory.MemoryInst);
auto *MUI = TheMemory.MemoryInst;

// The number of stores of the initial 'self' argument into the self box
// that we saw.
Expand Down Expand Up @@ -1792,16 +1732,14 @@ void swift::ownership::collectDIElementUsesFrom(
// at all. Just treat all members of self as uses of the single
// non-field-sensitive value.
assert(MemoryInfo.NumElements == 1 && "delegating inits only have 1 bit");
auto *MUI = cast<MarkUninitializedInst>(MemoryInfo.MemoryInst);
collectValueTypeDelegatingInitUses(MemoryInfo, UseInfo, MUI);
MemoryInfo.collectRetainCountInfo(UseInfo);
collectValueTypeDelegatingInitUses(MemoryInfo, UseInfo,
MemoryInfo.MemoryInst);
return;
}

if (shouldPerformClassInitSelf(MemoryInfo)) {
DelegatingClassInitElementUseCollector UseCollector(MemoryInfo, UseInfo);
UseCollector.collectClassInitSelfUses();
MemoryInfo.collectRetainCountInfo(UseInfo);
return;
}

Expand Down
106 changes: 38 additions & 68 deletions lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,8 @@ struct DIElementUseInfo;
/// not super.init() has been called or not.
class DIMemoryObjectInfo {
public:
/// This is the instruction that represents the memory. It is either an
/// allocation (alloc_box, alloc_stack) or a mark_uninitialized.
SingleValueInstruction *MemoryInst;
/// The uninitialized memory that we are analyzing.
MarkUninitializedInst *MemoryInst;

/// This is the base type of the memory allocation.
SILType MemorySILType;
Expand All @@ -74,7 +73,7 @@ class DIMemoryObjectInfo {
bool HasDummyElement = false;

public:
DIMemoryObjectInfo(SingleValueInstruction *MemoryInst);
DIMemoryObjectInfo(MarkUninitializedInst *MemoryInst);

SILLocation getLoc() const { return MemoryInst->getLoc(); }
SILFunction &getFunction() const { return *MemoryInst->getFunction(); }
Expand All @@ -84,17 +83,7 @@ class DIMemoryObjectInfo {

CanType getType() const { return MemorySILType.getASTType(); }

SingleValueInstruction *getAddress() const {
if (isa<MarkUninitializedInst>(MemoryInst) ||
isa<AllocStackInst>(MemoryInst))
return MemoryInst;
assert(false);
return nullptr;
}

AllocBoxInst *getContainer() const {
return dyn_cast<AllocBoxInst>(MemoryInst);
}
SingleValueInstruction *getAddress() const { return MemoryInst; }

/// getNumMemoryElements - Return the number of elements, without the extra
/// "super.init" tracker in initializers of derived classes.
Expand All @@ -103,99 +92,82 @@ class DIMemoryObjectInfo {
}

/// isAnyInitSelf - Return true if this is 'self' in any kind of initializer.
bool isAnyInitSelf() const {
if (auto *MUI = dyn_cast<MarkUninitializedInst>(MemoryInst))
return !MUI->isVar();
return false;
}
bool isAnyInitSelf() const { return !MemoryInst->isVar(); }

/// True if the memory object is the 'self' argument of a struct initializer.
bool isStructInitSelf() const {
if (auto *MUI = dyn_cast<MarkUninitializedInst>(MemoryInst))
if (MUI->isRootSelf() || MUI->isCrossModuleRootSelf())
if (auto decl = getType()->getAnyNominal())
if (isa<StructDecl>(decl))
return true;
if (MemoryInst->isRootSelf() || MemoryInst->isCrossModuleRootSelf()) {
if (auto decl = getType()->getAnyNominal()) {
if (isa<StructDecl>(decl)) {
return true;
}
}
}
return false;
}

/// True if the memory object is the 'self' argument of a non-delegating
/// cross-module struct initializer.
bool isCrossModuleStructInitSelf() const {
if (auto *MUI = dyn_cast<MarkUninitializedInst>(MemoryInst)) {
if (MUI->isCrossModuleRootSelf()) {
assert(isStructInitSelf());
return true;
}
if (MemoryInst->isCrossModuleRootSelf()) {
assert(isStructInitSelf());
return true;
}
return false;
}

/// True if the memory object is the 'self' argument of a class initializer.
bool isClassInitSelf() const {
if (auto *MUI = dyn_cast<MarkUninitializedInst>(MemoryInst))
if (!MUI->isVar())
if (auto decl = getType()->getAnyNominal())
if (isa<ClassDecl>(decl))
return true;
if (!MemoryInst->isVar()) {
if (auto decl = getType()->getAnyNominal()) {
if (isa<ClassDecl>(decl)) {
return true;
}
}
}
return false;
}

/// True if this memory object is the 'self' of a derived class initializer.
bool isDerivedClassSelf() const {
if (auto MUI = dyn_cast<MarkUninitializedInst>(MemoryInst))
return MUI->isDerivedClassSelf();
return false;
}
bool isDerivedClassSelf() const { return MemoryInst->isDerivedClassSelf(); }

/// True if this memory object is the 'self' of a derived class initializer for
/// which we can assume that all ivars have been initialized.
bool isDerivedClassSelfOnly() const {
if (auto MUI = dyn_cast<MarkUninitializedInst>(MemoryInst))
return MUI->isDerivedClassSelfOnly();
return false;
return MemoryInst->isDerivedClassSelfOnly();
}

/// True if this memory object is the 'self' of a derived class init method,
/// regardless of whether we're tracking ivar initializations or not.
bool isAnyDerivedClassSelf() const {
if (auto MUI = dyn_cast<MarkUninitializedInst>(MemoryInst))
return MUI->isDerivedClassSelf() || MUI->isDerivedClassSelfOnly();
return false;
return MemoryInst->isDerivedClassSelf() ||
MemoryInst->isDerivedClassSelfOnly();
}

/// True if this memory object is the 'self' of a non-root class init method.
bool isNonRootClassSelf() const {
if (isClassInitSelf())
if (auto MUI = dyn_cast<MarkUninitializedInst>(MemoryInst))
return !MUI->isRootSelf();

return false;
return isClassInitSelf() && !MemoryInst->isRootSelf();
}

/// isDelegatingInit - True if this is a delegating initializer, one that
/// calls 'self.init'.
bool isDelegatingInit() const {
if (auto MUI = dyn_cast<MarkUninitializedInst>(MemoryInst))
return MUI->isDelegatingSelf();
return false;
return MemoryInst->isDelegatingSelf();
}

/// isNonDelegatingInit - True if this is an initializer that initializes
/// stored properties.
bool isNonDelegatingInit() const {
if (auto *MUI = dyn_cast<MarkUninitializedInst>(MemoryInst)) {
switch (MUI->getKind()) {
case MarkUninitializedInst::Var:
return false;
case MarkUninitializedInst::RootSelf:
case MarkUninitializedInst::CrossModuleRootSelf:
case MarkUninitializedInst::DerivedSelf:
case MarkUninitializedInst::DerivedSelfOnly:
return true;
case MarkUninitializedInst::DelegatingSelf:
return false;
}
switch (MemoryInst->getKind()) {
case MarkUninitializedInst::Var:
return false;
case MarkUninitializedInst::RootSelf:
case MarkUninitializedInst::CrossModuleRootSelf:
case MarkUninitializedInst::DerivedSelf:
case MarkUninitializedInst::DerivedSelfOnly:
return true;
case MarkUninitializedInst::DelegatingSelf:
return false;
}
return false;
}
Expand All @@ -218,8 +190,6 @@ class DIMemoryObjectInfo {

/// If the specified value is a 'let' property in an initializer, return true.
bool isElementLetProperty(unsigned Element) const;

void collectRetainCountInfo(DIElementUseInfo &OutVar) const;
};

enum DIUseKind {
Expand Down
Loading