Skip to content

[pmo] Eliminate incomplete support for promoting enums. #17543

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
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
39 changes: 2 additions & 37 deletions lib/SILOptimizer/Mandatory/PMOMemoryUseCollector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,10 +231,6 @@ class ElementUseCollector {
/// element we attribute an access to.
bool InStructSubElement = false;

/// When walking the use list, if we index into an enum slice, keep track
/// of this.
bool InEnumSubElement = false;

public:
ElementUseCollector(const PMOMemoryObjectInfo &TheMemory,
SmallVectorImpl<PMOMemoryUse> &Uses,
Expand Down Expand Up @@ -294,7 +290,7 @@ void ElementUseCollector::addElementUses(unsigned BaseEltNo, SILType UseTy,
// If we're in a subelement of a struct or enum, just mark the struct, not
// things that come after it in a parent tuple.
unsigned NumElements = 1;
if (TheMemory.NumElements != 1 && !InStructSubElement && !InEnumSubElement)
if (TheMemory.NumElements != 1 && !InStructSubElement)
NumElements = getElementCountRec(Module, UseTy);

Uses.push_back(PMOMemoryUse(User, Kind, BaseEltNo, NumElements));
Expand All @@ -309,7 +305,7 @@ bool ElementUseCollector::collectTupleElementUses(TupleElementAddrInst *TEAI,
// If we're walking into a tuple within a struct or enum, don't adjust the
// BaseElt. The uses hanging off the tuple_element_addr are going to be
// counted as uses of the struct or enum itself.
if (InStructSubElement || InEnumSubElement)
if (InStructSubElement)
return collectUses(TEAI, BaseEltNo);

// tuple_element_addr P, 42 indexes into the current tuple element.
Expand Down Expand Up @@ -554,26 +550,6 @@ bool ElementUseCollector::collectUses(SILValue Pointer, unsigned BaseEltNo) {
llvm_unreachable("bad parameter convention");
}

// init_enum_data_addr is treated like a tuple_element_addr or other
// instruction that is looking into the memory object (i.e., the memory
// object needs to be explicitly initialized by a copy_addr or some other
// use of the projected address).
if (auto I = dyn_cast<InitEnumDataAddrInst>(User)) {
// If we are in a struct already, bail. With proper analysis, we should be
// able to do this optimization.
if (InStructSubElement) {
return false;
}

// Keep track of the fact that we're inside of an enum. This informs our
// recursion that tuple stores are not scalarized outside, and that stores
// should not be treated as partial stores.
llvm::SaveAndRestore<bool> X(InEnumSubElement, true);
if (!collectUses(I, BaseEltNo))
return false;
continue;
}

// init_existential_addr is modeled as an initialization store.
if (isa<InitExistentialAddrInst>(User)) {
// init_existential_addr should not apply to struct subelements.
Expand All @@ -585,17 +561,6 @@ bool ElementUseCollector::collectUses(SILValue Pointer, unsigned BaseEltNo) {
continue;
}

// inject_enum_addr is modeled as an initialization store.
if (isa<InjectEnumAddrInst>(User)) {
// inject_enum_addr the subelement of a struct unless in a ctor.
if (InStructSubElement) {
return false;
}
Uses.push_back(
PMOMemoryUse(User, PMOUseKind::Initialization, BaseEltNo, 1));
continue;
}

// open_existential_addr is a use of the protocol value,
// so it is modeled as a load.
if (isa<OpenExistentialAddrInst>(User)) {
Expand Down
20 changes: 20 additions & 0 deletions test/SILOptimizer/predictable_memopt.sil
Original file line number Diff line number Diff line change
Expand Up @@ -881,3 +881,23 @@ bb0(%arg : $K):
dealloc_stack %0 : $*SWithOpt
return %4 : $SWithOpt
}

// We do not support this now, so make sure we do not do anything.
//
// CHECK-LABEL: sil @promote_init_enum_data_addr : $@convention(thin)
// CHECK: alloc_stack
// CHECK: load
// CHECK: [[RESULT:%.*]] = load
// CHECK: return [[RESULT]]
// CHECK: } // end sil function 'promote_init_enum_data_addr'
sil @promote_init_enum_data_addr : $@convention(thin) (@in Int) -> Int {
bb0(%0 : $*Int):
%1 = alloc_stack $Optional<Int>
%2 = load %0 : $*Int
%3 = init_enum_data_addr %1 : $*Optional<Int>, #Optional.some!enumelt.1
store %2 to %3 : $*Int
inject_enum_addr %1 : $*Optional<Int>, #Optional.some!enumelt.1
%4 = load %3 : $*Int
dealloc_stack %1 : $*Optional<Int>
return %4 : $Int
}