Skip to content

[semantic-arc-opts] Implement @owned phi web elimination for phi webs with a single phi node that only have copy_value introducers. #30289

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
12 changes: 10 additions & 2 deletions include/swift/Basic/FrozenMultiMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,17 @@ class FrozenMultiMap {
frozen = true;
}

/// Reset the frozen multimap in an unfrozen state with its storage cleared.
void reset() {
storage.clear();
frozen = false;
}

unsigned size() const { return storage.size(); }
bool empty() const { return storage.empty(); }

struct iterator : std::iterator<std::forward_iterator_tag,
std::pair<Key, ArrayRef<Value>>> {
std::pair<Key, PairToSecondEltRange>> {
using base_iterator = typename decltype(storage)::iterator;

FrozenMultiMap &map;
Expand Down Expand Up @@ -159,9 +165,11 @@ class FrozenMultiMap {
}
};

using RangeType = llvm::iterator_range<iterator>;

/// Return a range of (key, ArrayRef<Value>) pairs. The keys are guaranteed to
/// be in key sorted order and the ArrayRef<Value> are in insertion order.
llvm::iterator_range<iterator> getRange() const {
RangeType getRange() const {
assert(isFrozen() &&
"Can not create range until data structure is frozen?!");
auto *self = const_cast<FrozenMultiMap *>(this);
Expand Down
22 changes: 22 additions & 0 deletions include/swift/SIL/OwnershipUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,28 @@ struct OwnedValueIntroducer {
return OwnedValueIntroducer(value, *kind);
}

/// Returns true if this owned introducer is able to be converted into a
/// guaranteed form if none of its uses are consuming uses (looking through
/// forwarding uses).
bool isConvertableToGuaranteed() const {
switch (kind) {
case OwnedValueIntroducerKind::Copy:
case OwnedValueIntroducerKind::LoadCopy:
return true;
case OwnedValueIntroducerKind::Apply:
case OwnedValueIntroducerKind::BeginApply:
case OwnedValueIntroducerKind::TryApply:
case OwnedValueIntroducerKind::LoadTake:
case OwnedValueIntroducerKind::Phi:
case OwnedValueIntroducerKind::FunctionArgument:
case OwnedValueIntroducerKind::PartialApplyInit:
case OwnedValueIntroducerKind::AllocBoxInit:
case OwnedValueIntroducerKind::AllocRefInit:
return false;
}
llvm_unreachable("Covered switch isn't covered?!");
}

bool operator==(const OwnedValueIntroducer &other) const {
return value == other.value;
}
Expand Down
Loading