Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ private func createAllocStack(for allocBox: AllocBoxInst, flags: Flags, _ contex
isLexical: flags.isLexical,
isFromVarDecl: flags.isFromVarDecl)
let stackLocation: Value
if let mu = allocBox.uses.getSingleUser(ofType: MarkUninitializedInst.self) {
if let mu = allocBox.uses.singleUser(ofType: MarkUninitializedInst.self) {
stackLocation = builder.createMarkUninitialized(value: asi, kind: mu.kind)
} else {
stackLocation = asi
Expand Down Expand Up @@ -484,7 +484,7 @@ private func hoistMarkUnresolvedInsts(stackAddress: Value,
builder = Builder(atBeginOf: stackAddress.parentBlock, context)
}
let mu = builder.createMarkUnresolvedNonCopyableValue(value: stackAddress, checkKind: checkKind, isStrict: false)
stackAddress.uses.ignore(user: mu).ignoreDebugUses.ignoreUses(ofType: DeallocStackInst.self)
stackAddress.uses.ignore(user: mu).ignoreDebugUses.ignore(usersOfType: DeallocStackInst.self)
.replaceAll(with: mu, context)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ private func rewritePartialApply(_ partialApply: PartialApplyInst, withSpecializ
// leave the key path itself out of the dependency chain, and introduce dependencies on those
// operands instead, so that the key path object itself can be made dead.
for md in newClosure.uses.users(ofType: MarkDependenceInst.self) {
if md.base.uses.getSingleUser(ofType: PartialApplyInst.self) == partialApply {
if md.base.uses.singleUser(ofType: PartialApplyInst.self) == partialApply {
md.replace(with: newClosure, context)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ let destroyHoisting = FunctionPass(name: "destroy-hoisting") {
private func optimize(value: Value, _ context: FunctionPassContext) {
guard value.ownership == .owned,
// Avoid all the analysis effort if there are no destroys to hoist.
!value.uses.filterUses(ofType: DestroyValueInst.self).isEmpty
!value.uses.filter(usersOfType: DestroyValueInst.self).isEmpty
else {
return
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ private struct InitValueBuilder: AddressDefUseWalker {
case .PrepareInitialization:
return .continueWalk
case .AddressOfRawLayout:
if let addr2Ptr = bi.uses.getSingleUser(ofType: PointerToAddressInst.self) {
if let addr2Ptr = bi.uses.singleUser(ofType: PointerToAddressInst.self) {
return walkDownUses(ofAddress: addr2Ptr, path: path)
}
return .abortWalk
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ private func tryEliminate(copy: CopyLikeInstruction, keepDebugInfo: Bool, _ cont
removeDestroys(of: allocStack, context)
}

allocStack.uses.ignoreUses(ofType: DeallocStackInst.self).replaceAll(with: copy.sourceAddress, context)
allocStack.uses.ignore(usersOfType: DeallocStackInst.self).replaceAll(with: copy.sourceAddress, context)

if keepDebugInfo {
Builder(before: copy, context).createDebugStep()
Expand Down Expand Up @@ -247,7 +247,7 @@ private extension AllocStackInst {
var liferange = InstructionRange(begin: self, context)
defer { liferange.deinitialize() }

liferange.insert(contentsOf: uses.ignoreUses(ofType: DeallocStackInst.self).lazy.map { $0.instruction })
liferange.insert(contentsOf: uses.ignore(usersOfType: DeallocStackInst.self).lazy.map { $0.instruction })

for use in uses {
switch use.instruction {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ private extension AllocStackInst {
iea.replace(with: newAlloc, context)
}
case let oea as OpenExistentialAddrInst:
assert(oea.uses.ignoreUses(ofType: DestroyAddrInst.self).isEmpty)
assert(oea.uses.ignore(usersOfType: DestroyAddrInst.self).isEmpty)
oea.replace(with: newAlloc, context)
case let cab as CheckedCastAddrBranchInst:
let builder = Builder(before: cab, context)
Expand Down Expand Up @@ -247,7 +247,7 @@ private extension AllocStackInst {
is DebugValueInst:
break
case let oea as OpenExistentialAddrInst:
if !oea.uses.ignoreUses(ofType: DestroyAddrInst.self).isEmpty {
if !oea.uses.ignore(usersOfType: DestroyAddrInst.self).isEmpty {
return nil
}
case let iea as InitExistentialAddrInst:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ extension BeginBorrowInst : OnoneSimplifiable, SILCombineSimplifiable {

extension LoadBorrowInst : Simplifiable, SILCombineSimplifiable {
func simplify(_ context: SimplifyContext) {
if uses.ignoreDebugUses.ignoreUses(ofType: EndBorrowInst.self).isEmpty {
if uses.ignoreDebugUses.ignore(usersOfType: EndBorrowInst.self).isEmpty {
context.erase(instructionIncludingAllUsers: self)
return
}
Expand All @@ -52,7 +52,7 @@ extension LoadBorrowInst : Simplifiable, SILCombineSimplifiable {

private func tryCombineWithCopy(_ context: SimplifyContext) {
let forwardedValue = lookThroughSingleForwardingUses()
guard let singleUser = forwardedValue.uses.ignoreUses(ofType: EndBorrowInst.self).singleUse?.instruction,
guard let singleUser = forwardedValue.uses.ignore(usersOfType: EndBorrowInst.self).singleUse?.instruction,
let copy = singleUser as? CopyValueInst,
copy.parentBlock == self.parentBlock else {
return
Expand Down Expand Up @@ -81,13 +81,13 @@ private func tryReplaceBorrowWithOwnedOperand(beginBorrow: BeginBorrowInst, _ co
private func removeBorrowOfThinFunction(beginBorrow: BeginBorrowInst, _ context: SimplifyContext) {
guard let thin2thickFn = beginBorrow.borrowedValue as? ThinToThickFunctionInst,
// For simplicity don't go into the trouble of removing reborrow phi arguments.
beginBorrow.uses.filterUses(ofType: BranchInst.self).isEmpty else
beginBorrow.uses.filter(usersOfType: BranchInst.self).isEmpty else
{
return
}
// `thin_to_thick_function` has "none" ownership and is compatible with guaranteed values.
// Therefore the `begin_borrow` is not needed.
beginBorrow.uses.ignoreUses(ofType: EndBorrowInst.self).replaceAll(with: thin2thickFn, context)
beginBorrow.uses.ignore(usersOfType: EndBorrowInst.self).replaceAll(with: thin2thickFn, context)
context.erase(instructionIncludingAllUsers: beginBorrow)
}

Expand All @@ -110,7 +110,7 @@ private func tryReplaceCopy(
withCopiedOperandOf beginBorrow: BeginBorrowInst,
_ context: SimplifyContext
) -> Bool {
guard let singleUser = forwardedValue.uses.ignoreUses(ofType: EndBorrowInst.self).singleUse?.instruction,
guard let singleUser = forwardedValue.uses.ignore(usersOfType: EndBorrowInst.self).singleUse?.instruction,
let copy = singleUser as? CopyValueInst,
copy.parentBlock == beginBorrow.parentBlock else {
return false
Expand Down Expand Up @@ -153,7 +153,7 @@ private extension Value {
/// ```
/// Returns self if this value has no uses which are ForwardingInstructions.
func lookThroughSingleForwardingUses() -> Value {
if let singleUse = uses.ignoreUses(ofType: EndBorrowInst.self).singleUse,
if let singleUse = uses.ignore(usersOfType: EndBorrowInst.self).singleUse,
let fwdInst = singleUse.instruction as? (SingleValueInstruction & ForwardingInstruction),
fwdInst.canConvertToOwned,
fwdInst.isSingleForwardedOperand(singleUse),
Expand All @@ -165,17 +165,17 @@ private extension Value {
}

var allUsesCanBeConvertedToOwned: Bool {
let relevantUses = uses.ignoreUses(ofType: EndBorrowInst.self)
let relevantUses = uses.ignore(usersOfType: EndBorrowInst.self)
return relevantUses.allSatisfy { $0.canAccept(ownership: .owned) }
}

func isDestroyed(after nonDestroyUser: Instruction) -> Bool {
return uses.getSingleUser(notOfType: DestroyValueInst.self) == nonDestroyUser &&
return uses.singleUser(notOfType: DestroyValueInst.self) == nonDestroyUser &&
nonDestroyUser.dominates(destroysOf: self)
}

func replaceAllDestroys(with replacement: Value, _ context: SimplifyContext) {
uses.filterUses(ofType: DestroyValueInst.self).replaceAll(with: replacement, context)
uses.filter(usersOfType: DestroyValueInst.self).replaceAll(with: replacement, context)
}
}

Expand All @@ -187,7 +187,7 @@ private extension Instruction {
// The value and instruction are in the same block. All uses are dominated by both.
return true
}
let destroys = value.uses.filterUses(ofType: DestroyValueInst.self)
let destroys = value.uses.filter(usersOfType: DestroyValueInst.self)
return destroys.allSatisfy({ $0.instruction.parentBlock == parentBlock})
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ private extension Value {
// var p = Point(x: 10, y: 20)
// let o = UnsafePointer(&p)
// Therefore ignore the `end_access` use of a `begin_access`.
let relevantUses = singleUseValue.uses.ignoreDebugUses.ignoreUses(ofType: EndAccessInst.self)
let relevantUses = singleUseValue.uses.ignoreDebugUses.ignore(usersOfType: EndAccessInst.self)

guard let use = relevantUses.singleUse else {
return nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ private struct StackProtectionOptimization {
let builder = Builder(after: beginAccess, location: beginAccess.location.asAutoGenerated, context)
let temporary = builder.createAllocStack(beginAccess.type)

beginAccess.uses.ignoreUses(ofType: EndAccessInst.self).replaceAll(with: temporary, context)
beginAccess.uses.ignore(usersOfType: EndAccessInst.self).replaceAll(with: temporary, context)

for endAccess in beginAccess.endInstructions {
let endBuilder = Builder(before: endAccess, location: endAccess.location.asAutoGenerated, context)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ extension Instruction {
case .USubOver:
// Handle StringObjectOr(tuple_extract(usub_with_overflow(x, offset)), bits)
// This pattern appears in UTF8 String literal construction.
if let tei = bi.uses.getSingleUser(ofType: TupleExtractInst.self),
if let tei = bi.uses.singleUser(ofType: TupleExtractInst.self),
tei.isResultOfOffsetSubtract {
return true
}
Expand All @@ -446,7 +446,7 @@ extension Instruction {
// Handle StringObjectOr(tuple_extract(usub_with_overflow(x, offset)), bits)
// This pattern appears in UTF8 String literal construction.
if tei.isResultOfOffsetSubtract,
let bi = tei.uses.getSingleUser(ofType: BuiltinInst.self),
let bi = tei.uses.singleUser(ofType: BuiltinInst.self),
bi.id == .StringObjectOr {
return true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,7 @@ extension InteriorUseWalker: AddressUseVisitor {
if handleInner(borrowed: sb) == .abortWalk {
return .abortWalk
}
return sb.uses.filterUses(ofType: EndBorrowInst.self).walk {
return sb.uses.filter(usersOfType: EndBorrowInst.self).walk {
useVisitor($0)
}
case let load as LoadBorrowInst:
Expand Down
29 changes: 8 additions & 21 deletions SwiftCompilerSources/Sources/SIL/Operand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -143,16 +143,7 @@ extension Sequence where Element == Operand {
self.lazy.map { $0.value }
}

public var singleUse: Operand? {
var result: Operand? = nil
for op in self {
if result != nil {
return nil
}
result = op
}
return result
}
public var singleUse: Operand? { singleElement }

public var isSingleUse: Bool { singleUse != nil }

Expand All @@ -161,31 +152,27 @@ extension Sequence where Element == Operand {
}

public var ignoreDebugUses: LazyFilterSequence<Self> {
self.lazy.filter { !($0.instruction is DebugValueInst) }
ignore(usersOfType: DebugValueInst.self)
}

public func filterUses<I: Instruction>(ofType: I.Type) -> LazyFilterSequence<Self> {
public func filter<I: Instruction>(usersOfType: I.Type) -> LazyFilterSequence<Self> {
self.lazy.filter { $0.instruction is I }
}

public func filterUsers<I: Instruction>(ofType: I.Type) -> LazyMapSequence<LazyFilterSequence<Self>, I> {
self.lazy.filter { $0.instruction is I }.lazy.map { $0.instruction as! I }
}

public func ignoreUses<I: Instruction>(ofType: I.Type) -> LazyFilterSequence<Self> {
public func ignore<I: Instruction>(usersOfType: I.Type) -> LazyFilterSequence<Self> {
self.lazy.filter { !($0.instruction is I) }
}

public func ignore(user: Instruction) -> LazyFilterSequence<Self> {
self.lazy.filter { !($0.instruction == user) }
}

public func getSingleUser<I: Instruction>(ofType: I.Type) -> I? {
filterUses(ofType: I.self).singleUse?.instruction as? I
public func singleUser<I: Instruction>(ofType: I.Type) -> I? {
filter(usersOfType: I.self).singleUse?.instruction as? I
}

public func getSingleUser<I: Instruction>(notOfType: I.Type) -> Instruction? {
ignoreUses(ofType: I.self).singleUse?.instruction
public func singleUser<I: Instruction>(notOfType: I.Type) -> Instruction? {
ignore(usersOfType: I.self).singleUse?.instruction
}

public var endingLifetime: LazyFilterSequence<Self> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ public enum BorrowingInstruction : CustomStringConvertible, Hashable {
extension BorrowingInstruction {
private func visitEndBorrows(value: Value, _ context: Context, _ visitor: @escaping (Operand) -> WalkResult)
-> WalkResult {
return value.lookThroughBorrowedFromUser.uses.filterUses(ofType: EndBorrowInst.self).walk {
return value.lookThroughBorrowedFromUser.uses.filter(usersOfType: EndBorrowInst.self).walk {
visitor($0)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ private func createEmptyBorrowedFrom(for phi: Phi, _ context: some MutatingConte
}
let builder = Builder(atBeginOf: phi.value.parentBlock, context)
let bfi = builder.createBorrowedFrom(borrowedValue: phi.value, enclosingValues: [])
phi.value.uses.ignoreUses(ofType: BorrowedFromInst.self).replaceAll(with: bfi, context)
phi.value.uses.ignore(usersOfType: BorrowedFromInst.self).replaceAll(with: bfi, context)
}

/// Replaces a phi with the unique incoming value if all incoming values are the same:
Expand Down