From 218ef587e6cf5d034ecd7ace242c8689b67009db Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Thu, 21 Apr 2022 20:33:09 -0700 Subject: [PATCH] Revert "Merge pull request #42242 from eeckstein/escapeinfo" This reverts commit c05e064cd831dda5c47ac6360dc82b31fe587d1f, reversing changes made to c1534d5af9a480f82e0da9d7a4ec5d5341b5a1ab. This caused a regression on Windows. --- .../Optimizer/Analysis/AliasAnalysis.swift | 17 - .../Optimizer/FunctionPasses/CMakeLists.txt | 2 - .../FunctionPasses/ComputeEffects.swift | 235 ---- .../FunctionPasses/EscapeInfoDumper.swift | 134 -- .../PassManager/PassRegistration.swift | 3 - .../Optimizer/Utilities/CMakeLists.txt | 1 - .../Optimizer/Utilities/EscapeInfo.swift | 1006 --------------- .../Sources/SIL/SmallProjectionPath.swift | 116 +- SwiftCompilerSources/Sources/SIL/Type.swift | 4 - include/swift/SIL/SILBridging.h | 1 - include/swift/SIL/SILType.h | 9 - include/swift/SIL/TypeLowering.h | 28 +- .../swift/SILOptimizer/PassManager/Passes.def | 6 - lib/SIL/IR/SILType.cpp | 11 - lib/SIL/IR/TypeLowering.cpp | 9 +- lib/SIL/Utils/SILBridging.cpp | 6 - lib/SILOptimizer/PassManager/PassPipeline.cpp | 10 - test/DebugInfo/optimizer_pipeline.swift | 2 +- test/SIL/Parser/default_witness_tables.sil | 6 +- .../function_param_convention.sil | 2 +- .../perf_inline_without_inline_all.swift | 2 +- .../specializer_can_deserialize.swift | 2 +- test/SILGen/copy_operator.swift | 4 +- test/SILGen/deinit_in_vtable.swift | 4 +- test/SILGen/global_resilience.swift | 2 +- test/SILGen/specialize_attr.swift | 16 +- test/SILGen/unsafevalue.swift | 2 +- test/SILOptimizer/access_wmo.swift | 2 +- test/SILOptimizer/addr_escape_info.sil | 497 -------- test/SILOptimizer/array_contentof_opt.swift | 8 +- .../array_metadata_optimization.swift | 4 +- test/SILOptimizer/bridged_casts_folding.sil | 6 +- test/SILOptimizer/bridged_casts_folding.swift | 4 +- .../bridged_casts_folding_ownership.sil | 6 +- .../capture_promotion_generic_context.sil | 8 +- ...re_promotion_generic_context_ownership.sil | 8 +- test/SILOptimizer/cast_folding.swift | 8 +- .../SILOptimizer/cast_folding_no_bridging.sil | 8 +- test/SILOptimizer/cast_folding_objc.swift | 39 +- .../cast_folding_objc_generics.swift | 4 +- .../constant_propagation_stdlib.swift | 4 +- test/SILOptimizer/dead_array_elim.swift | 2 +- test/SILOptimizer/dead_bridging_code.swift | 2 +- .../devirt_covariant_return.swift | 2 +- test/SILOptimizer/devirt_nested_class.swift | 2 +- .../devirt_outer_requirements.swift | 2 +- .../devirt_protocol_method_invocations.swift | 8 +- .../devirt_specialized_conformance.swift | 2 +- .../SILOptimizer/devirt_unbound_generic.swift | 2 +- .../SILOptimizer/devirt_value_metatypes.swift | 6 +- test/SILOptimizer/dynamic_self_cast.sil | 2 +- test/SILOptimizer/escape_info.sil | 1118 ----------------- test/SILOptimizer/escape_info_objc.sil | 81 -- ...existential_specializer_indirect_class.sil | 4 +- test/SILOptimizer/fold_enums.sil | 2 +- test/SILOptimizer/function_effects.sil | 315 ----- test/SILOptimizer/function_effects_objc.sil | 52 - test/SILOptimizer/generic_loop.swift | 2 +- .../inline_generic_coroutines.swift | 2 +- test/SILOptimizer/inline_self.swift | 2 +- test/SILOptimizer/let_propagation.swift | 2 +- test/SILOptimizer/licm_exclusivity.swift | 2 +- .../opened_archetype_operands_tracking.sil | 6 +- test/SILOptimizer/opt_enumerate.swift | 6 +- test/SILOptimizer/outliner.swift | 2 +- test/SILOptimizer/pre_specialize-macos.swift | 4 +- test/SILOptimizer/reverse-array.swift | 2 +- .../sil_combine_concrete_existential.swift | 2 +- .../sil_combine_protocol_conf.swift | 6 +- .../simplify_switch_enum_objc.swift | 4 +- test/SILOptimizer/spec_conf1.swift | 2 +- test/SILOptimizer/spec_conf2.swift | 2 +- .../specialize_checked_cast_branch.swift | 46 +- .../specialize_opaque_type_archetypes.swift | 2 +- ...pecialize_unconditional_checked_cast.swift | 48 +- test/SILOptimizer/stack_promotion.sil | 8 +- .../stack_promotion_escaping.swift | 2 +- test/SILOptimizer/static_arrays.swift | 2 +- test/SILOptimizer/templvalueopt.swift | 4 +- 79 files changed, 181 insertions(+), 3825 deletions(-) delete mode 100644 SwiftCompilerSources/Sources/Optimizer/FunctionPasses/ComputeEffects.swift delete mode 100644 SwiftCompilerSources/Sources/Optimizer/FunctionPasses/EscapeInfoDumper.swift delete mode 100644 SwiftCompilerSources/Sources/Optimizer/Utilities/EscapeInfo.swift delete mode 100644 test/SILOptimizer/addr_escape_info.sil delete mode 100644 test/SILOptimizer/escape_info.sil delete mode 100644 test/SILOptimizer/escape_info_objc.sil delete mode 100644 test/SILOptimizer/function_effects.sil delete mode 100644 test/SILOptimizer/function_effects_objc.sil diff --git a/SwiftCompilerSources/Sources/Optimizer/Analysis/AliasAnalysis.swift b/SwiftCompilerSources/Sources/Optimizer/Analysis/AliasAnalysis.swift index 7ac0083eba3..e567b05ecb2 100644 --- a/SwiftCompilerSources/Sources/Optimizer/Analysis/AliasAnalysis.swift +++ b/SwiftCompilerSources/Sources/Optimizer/Analysis/AliasAnalysis.swift @@ -43,21 +43,4 @@ struct AliasAnalysis { return false } } - - /// Returns the correct path for address-alias functions. - static func getPtrOrAddressPath(for value: Value) -> EscapeInfo.Path { - let ty = value.type - if ty.isAddress { - // This is the regular case: the path selects any sub-fields of an address. - return EscapeInfo.Path(.anyValueFields) - } - // Some optimizations use the address-alias APIs with non-address SIL values. - // TODO: this is non-intuitive and we should eliminate those API uses. - if ty.isClass { - // If the value is a (non-address) reference it means: all addresses within the class instance. - return EscapeInfo.Path(.anyValueFields).push(.anyClassField) - } - // Any other non-address value means: all addresses of any referenced class instances within the value. - return EscapeInfo.Path(.anyValueFields).push(.anyClassField).push(.anyValueFields) - } } diff --git a/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/CMakeLists.txt b/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/CMakeLists.txt index a968c98eacb..c9ebafb13e2 100644 --- a/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/CMakeLists.txt +++ b/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/CMakeLists.txt @@ -8,8 +8,6 @@ swift_compiler_sources(Optimizer AssumeSingleThreaded.swift - ComputeEffects.swift - EscapeInfoDumper.swift SILPrinter.swift MergeCondFails.swift RangeDumper.swift diff --git a/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/ComputeEffects.swift b/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/ComputeEffects.swift deleted file mode 100644 index 9dd96e406c6..00000000000 --- a/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/ComputeEffects.swift +++ /dev/null @@ -1,235 +0,0 @@ -//===--- ComputeEffects.swift - Compute function effects ------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import SIL - -fileprivate typealias Selection = ArgumentEffect.Selection -fileprivate typealias Path = ArgumentEffect.Path - -/// Computes effects for function arguments. -/// -/// For example, if an argument does not escape, adds a non-escaping effect, -/// e.g. "[escapes !%0.**]": -/// -/// sil [escapes !%0.**] @foo : $@convention(thin) (@guaranteed X) -> () { -/// bb0(%0 : $X): -/// %1 = tuple () -/// return %1 : $() -/// } -/// -/// The pass does not try to change or re-compute _defined_ effects. -/// Currently, only escaping effects are handled. -/// In future, this pass may also add other effects, like memory side effects. -let computeEffects = FunctionPass(name: "compute-effects", { - (function: Function, context: PassContext) in - - var argsWithDefinedEffects = getArgIndicesWithDefinedEffects(of: function) - - var escapeInfo = EscapeInfo(calleeAnalysis: context.calleeAnalysis) - var newEffects = Stack(context) - let returnInst = function.returnInstruction - - for arg in function.arguments { - // We are not interested in arguments with trivial types. - if !arg.type.isNonTrivialOrContainsRawPointer(in: function) { continue } - - // Also, we don't want to override defined effects. - if argsWithDefinedEffects.contains(arg.index) { continue } - - // First check: is the argument (or a projected value of it) escaping at all? - if !escapeInfo.isEscapingWhenWalkingDown(object: arg, path: Path(.anything), - visitUse: { op, _, _ in - isOperandOfRecursiveCall(op) ? .ignore : .continueWalking - }) { - let selectedArg = Selection(arg, pathPattern: Path(.anything)) - newEffects.push(ArgumentEffect(.notEscaping, selectedArg: selectedArg)) - continue - } - - // Now compute effects for two important cases: - // * the argument itself + any value projections, and... - if addArgEffects(arg, argPath: Path(), to: &newEffects, returnInst, &escapeInfo) { - // * single class indirections - _ = addArgEffects(arg, argPath: Path(.anyValueFields).push(.anyClassField), - to: &newEffects, returnInst, &escapeInfo) - } - } - - context.modifyEffects(in: function) { (effects: inout FunctionEffects) in - effects.removeDerivedEffects() - effects.argumentEffects.append(contentsOf: newEffects) - } - newEffects.removeAll() -}) - -/// Returns true if an argument effect was added. -private -func addArgEffects(_ arg: FunctionArgument, argPath ap: Path, - to newEffects: inout Stack, - _ returnInst: ReturnInst?, - _ escapeInfo: inout EscapeInfo) -> Bool { - - var toSelection: Selection? - // Correct the path if the argument is not a class reference itself, but a value type - // containing one or more references. - let argPath = arg.type.isClass ? ap : ap.push(.anyValueFields) - - if escapeInfo.isEscapingWhenWalkingDown(object: arg, path: argPath, - visitUse: { op, path, followStores in - if op.instruction == returnInst { - // The argument escapes to the function return - if followStores { - // The escaping path must not introduce a followStores. - return .markEscaping - } - if let ta = toSelection { - if ta.value != .returnValue { return .markEscaping } - toSelection = Selection(.returnValue, pathPattern: path.merge(with: ta.pathPattern)) - } else { - toSelection = Selection(.returnValue, pathPattern: path) - } - return .ignore - } - if isOperandOfRecursiveCall(op) { - return .ignore - } - return .continueWalking - }, - visitDef: { def, path, followStores in - guard let destArg = def as? FunctionArgument else { - return .continueWalkingUp - } - // The argument escapes to another argument (e.g. an out or inout argument) - if followStores { - // The escaping path must not introduce a followStores. - return .markEscaping - } - let argIdx = destArg.index - if let ta = toSelection { - if ta.value != .argument(argIdx) { return .markEscaping } - toSelection = Selection(.argument(argIdx), pathPattern: path.merge(with: ta.pathPattern)) - } else { - toSelection = Selection(.argument(argIdx), pathPattern: path) - } - return .continueWalkingDown - }) { - return false - } - - let fromSelection = Selection(arg, pathPattern: argPath) - - guard let toSelection = toSelection else { - newEffects.push(ArgumentEffect(.notEscaping, selectedArg: fromSelection)) - return true - } - - // If the function never returns, the argument can not escape to another arg/return. - guard let returnInst = returnInst else { - return false - } - - let exclusive = isExclusiveEscape(fromArgument: arg, fromPath: argPath, to: toSelection, returnInst, &escapeInfo) - - newEffects.push(ArgumentEffect(.escaping(toSelection, exclusive), selectedArg: fromSelection)) - return true -} - -/// Returns a set of argument indices for which there are "defined" effects (as opposed to derived effects). -private func getArgIndicesWithDefinedEffects(of function: Function) -> Set { - var argsWithDefinedEffects = Set() - - for effect in function.effects.argumentEffects { - if effect.isDerived { continue } - - if case .argument(let argIdx) = effect.selectedArg.value { - argsWithDefinedEffects.insert(argIdx) - } - - switch effect.kind { - case .notEscaping: - break - case .escaping(let to, _): - if case .argument(let toArgIdx) = to.value { - argsWithDefinedEffects.insert(toArgIdx) - } - } - } - return argsWithDefinedEffects -} - -/// Returns true if `op` is passed to a recursive call to the current function - -/// at the same argument index. -private func isOperandOfRecursiveCall(_ op: Operand) -> Bool { - let inst = op.instruction - if let applySite = inst as? FullApplySite, - let callee = applySite.referencedFunction, - callee == inst.function, - let argIdx = applySite.argumentIndex(of: op), - op.value == callee.arguments[argIdx] { - return true - } - return false -} - -/// Returns true if when walking from the `toSelection` to the `fromArgument`, -/// there are no other arguments or escape points than `fromArgument`. Also, the -/// path at the `fromArgument` must match with `fromPath`. -private -func isExclusiveEscape(fromArgument: Argument, fromPath: Path, to toSelection: Selection, - _ returnInst: ReturnInst, _ escapeInfo: inout EscapeInfo) -> Bool { - switch toSelection.value { - - // argument -> return - case .returnValue: - if escapeInfo.isEscaping( - object: returnInst.operand, path: toSelection.pathPattern, - visitUse: { op, path, followStores in - if op.instruction == returnInst { - if followStores { return .markEscaping } - if path.matches(pattern: toSelection.pathPattern) { - return .ignore - } - return .markEscaping - } - return .continueWalking - }, - visitDef: { def, path, followStores in - guard let arg = def as? FunctionArgument else { - return .continueWalkingUp - } - if followStores { return .markEscaping } - if arg == fromArgument && path.matches(pattern: fromPath) { - return .continueWalkingDown - } - return .markEscaping - }) { - return false - } - - // argument -> argument - case .argument(let toArgIdx): - let toArg = returnInst.function.arguments[toArgIdx] - if escapeInfo.isEscaping(object: toArg, path: toSelection.pathPattern, - visitDef: { def, path, followStores in - guard let arg = def as? FunctionArgument else { - return .continueWalkingUp - } - if followStores { return .markEscaping } - if arg == fromArgument && path.matches(pattern: fromPath) { return .continueWalkingDown } - if arg == toArg && path.matches(pattern: toSelection.pathPattern) { return .continueWalkingDown } - return .markEscaping - }) { - return false - } - } - return true -} diff --git a/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/EscapeInfoDumper.swift b/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/EscapeInfoDumper.swift deleted file mode 100644 index 6b05ff084ee..00000000000 --- a/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/EscapeInfoDumper.swift +++ /dev/null @@ -1,134 +0,0 @@ -//===--- EscapeInfoDumper.swift - Dumps escape information ----------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import SIL - -/// Dumps the results of escape analysis. -/// -/// Dumps the EscapeInfo query results for all `alloc_stack` instructions in a function. -/// -/// This pass is used for testing EscapeInfo. -let escapeInfoDumper = FunctionPass(name: "dump-escape-info", { - (function: Function, context: PassContext) in - - print("Escape information for \(function.name):") - - var escapeInfo = EscapeInfo(calleeAnalysis: context.calleeAnalysis) - - for block in function.blocks { - for inst in block.instructions { - if let allocRef = inst as? AllocRefInst { - var results = Set() - - let escapes = escapeInfo.isEscaping(object: allocRef, - visitUse: { op, path, _ in - if op.instruction is ReturnInst { - results.insert("return[\(path)]") - return .ignore - } - return .continueWalking - }, - visitDef: { def, path, followStores in - guard let arg = def as? FunctionArgument else { - return .continueWalkingUp - } - results.insert("arg\(arg.index)[\(path)]") - return .continueWalkingDown - }) - - let res: String - if escapes { - res = "global" - } else if results.isEmpty { - res = " - " - } else { - res = Array(results).sorted().joined(separator: ",") - } - print("\(res): \(allocRef)") - } - } - } - print("End function \(function.name)\n") -}) - -/// Dumps the results of address-related escape analysis. -/// -/// Dumps the EscapeInfo query results for addresses escaping to function calls. -/// The `fix_lifetime` instruction is used as marker for addresses and values to query. -/// -/// This pass is used for testing EscapeInfo. -let addressEscapeInfoDumper = FunctionPass(name: "dump-addr-escape-info", { - (function: Function, context: PassContext) in - - print("Address escape information for \(function.name):") - - var valuesToCheck = [Value]() - var applies = [Instruction]() - - for block in function.blocks { - for inst in block.instructions { - switch inst { - case let fli as FixLifetimeInst: - valuesToCheck.append(fli.operand) - case is FullApplySite: - applies.append(inst) - default: - break - } - } - } - - var escapeInfo = EscapeInfo(calleeAnalysis: context.calleeAnalysis) - - // test `isEscaping(addressesOf:)` - for value in valuesToCheck { - print("value:\(value)") - for apply in applies { - let path = AliasAnalysis.getPtrOrAddressPath(for: value) - let escaping = escapeInfo.isEscaping(addressesOf: value, path: path, - visitUse: { op, _, _ in - let user = op.instruction - if user == apply { - return .markEscaping - } - if user is ReturnInst { - // Anything which is returned cannot escape to an instruction inside the function. - return .ignore - } - return .continueWalking - }) - print(" \(escaping ? "==>" : "- ") \(apply)") - } - } - - // test `canReferenceSameField` for each pair of `fix_lifetime`. - if !valuesToCheck.isEmpty { - for lhsIdx in 0..<(valuesToCheck.count - 1) { - for rhsIdx in (lhsIdx + 1) ..< valuesToCheck.count { - print("pair \(lhsIdx) - \(rhsIdx)") - let lhs = valuesToCheck[lhsIdx] - let rhs = valuesToCheck[rhsIdx] - print(lhs) - print(rhs) - if escapeInfo.canReferenceSameField( - lhs, path: AliasAnalysis.getPtrOrAddressPath(for: lhs), - rhs, path: AliasAnalysis.getPtrOrAddressPath(for: rhs)) { - print("may alias") - } else { - print("no alias") - } - } - } - } - - print("End function \(function.name)\n") -}) diff --git a/SwiftCompilerSources/Sources/Optimizer/PassManager/PassRegistration.swift b/SwiftCompilerSources/Sources/Optimizer/PassManager/PassRegistration.swift index 52ff087de39..1f6c1f6cd9f 100644 --- a/SwiftCompilerSources/Sources/Optimizer/PassManager/PassRegistration.swift +++ b/SwiftCompilerSources/Sources/Optimizer/PassManager/PassRegistration.swift @@ -46,9 +46,6 @@ private func registerPass( private func registerSwiftPasses() { registerPass(silPrinterPass, { silPrinterPass.run($0) }) registerPass(mergeCondFailsPass, { mergeCondFailsPass.run($0) }) - registerPass(escapeInfoDumper, { escapeInfoDumper.run($0) }) - registerPass(addressEscapeInfoDumper, { addressEscapeInfoDumper.run($0) }) - registerPass(computeEffects, { computeEffects.run($0) }) registerPass(simplifyBeginCOWMutationPass, { simplifyBeginCOWMutationPass.run($0) }) registerPass(simplifyGlobalValuePass, { simplifyGlobalValuePass.run($0) }) registerPass(simplifyStrongRetainPass, { simplifyStrongRetainPass.run($0) }) diff --git a/SwiftCompilerSources/Sources/Optimizer/Utilities/CMakeLists.txt b/SwiftCompilerSources/Sources/Optimizer/Utilities/CMakeLists.txt index 1f54556153b..6fc3d9beeea 100644 --- a/SwiftCompilerSources/Sources/Optimizer/Utilities/CMakeLists.txt +++ b/SwiftCompilerSources/Sources/Optimizer/Utilities/CMakeLists.txt @@ -7,5 +7,4 @@ # See http://swift.org/CONTRIBUTORS.txt for Swift project authors swift_compiler_sources(Optimizer - EscapeInfo.swift OptUtils.swift) diff --git a/SwiftCompilerSources/Sources/Optimizer/Utilities/EscapeInfo.swift b/SwiftCompilerSources/Sources/Optimizer/Utilities/EscapeInfo.swift deleted file mode 100644 index 115e1070781..00000000000 --- a/SwiftCompilerSources/Sources/Optimizer/Utilities/EscapeInfo.swift +++ /dev/null @@ -1,1006 +0,0 @@ -//===--- EscapeInfo.swift - Finds escape points of a value ----------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import SIL - -/// A utility for checking if a value escapes and for finding the escape points. -/// -/// The EscapeInfo starts at the initial value and alternately walks in two directions: -/// * Starting at allocations, walks down from defs to uses ("Where does the value go to?") -/// * Starting at stores, walks up from uses to defs ("Were does the value come from?") -/// -/// The result of the walk indicates if the initial value "escapes" or not. -/// The value escapes if the walk reaches a point where the further flow of the -/// value cannot be tracked anymore. -/// Example: -/// \code -/// %1 = alloc_ref $X // 1. initial value: walk down to the `store` -/// %2 = alloc_stack $X // 3. walk down to %3 -/// store %1 to %2 // 2. walk up to `%2` -/// %3 = load %2 // 4. continue walking down to the `return` -/// return %3 // 5. The value is escaping! -/// \endcode -/// -/// During the walk, a projection path indicates where the initial value is -/// contained in an aggregate. -/// Example for a walk-down: -/// \code -/// %1 = alloc_ref // 1. initial value, path = empty -/// %2 = struct $S (%1) // 2. path = s0 -/// %3 = tuple (%other, %1) // 3. path = t1.s0 -/// %4 = tuple_extract %3, 1 // 4. path = s0 -/// %5 = struct_extract %4, #field // 5. path = empty -/// \endcode -/// -/// The `followStores` flag, which is passed together with the path, indicates -/// if stored values should be included in the walk. -/// If the initial value is stored to some memory allocation, we usually don't -/// care if other values are stored to that location as well. Example: -/// \code -/// %1 = alloc_ref $X // 1. initial value, walk down to the `store` -/// %2 = alloc_stack $X // 3. walk down to the second `store` -/// store %1 to %2 // 2. walk up to %2 -/// store %other to %2 // 4. ignore (followStores == false): %other doesn't impact the "escapeness" of %1 -/// \endcode -/// -/// But once the the up-walk sees a load, it has to follow stores from that point on. -/// Example: -/// \code -/// bb0(%function_arg): // 7. escaping! %1 escapes through %function_arg -/// %1 = alloc_ref $X // 1. initial value, walk down to the second `store` -/// %addr = alloc_stack %X // 5. walk down to the first `store` -/// store %function_arg to %addr // 6. walk up to %function_arg (followStores == true) -/// %2 = load %addr // 4. walk up to %addr, followStores = true -/// %3 = ref_element_addr %2, #f // 3. walk up to %2 -/// store %1 to %3 // 2. walk up to %3 -/// \endcode -/// -/// The algorithm doesn't distinguish between addresses and values, i.e. loads -/// and stores are treated as simple forwarding instructions, like casts. -/// For escaping it doesn't make a difference if a value or an address pointing to -/// the value, escapes. -/// An exception are `isEscaping(address: Value)` and similar functions: they ignore -/// values which are loaded from the address in question. -struct EscapeInfo { - - typealias Path = SmallProjectionPath - - public enum UseCallbackResult { - case ignore - case markEscaping - case continueWalking - case continueWithNewPath(Path) - } - - /// Called for all operands with the current path and `followStores` when walking down. - typealias UseCallback = (Operand, Path, Bool) -> UseCallbackResult - - public enum DefCallbackResult { - case ignore - case markEscaping - case continueWalkingUp - case continueWalkingDown - } - - /// Called for all values with the current path and `followStores` when walking up. - typealias DefCallback = (Value, Path, Bool) -> DefCallbackResult - - //===--------------------------------------------------------------------===// - // The top-level API - //===--------------------------------------------------------------------===// - - init(calleeAnalysis: CalleeAnalysis) { - self.calleeAnalysis = calleeAnalysis - } - - /// Returns true if `object`, or any sub-objects which are selected by `path`, can escape. - /// - /// For example, let's assume this function is called with a struct, containing a reference, - /// and a path of `s0.c*`: - /// \code - /// %value : $Struct // path == s0.c*, the initial `object` - /// %ref = struct_extract %value, #field0 // path == c* - /// %ref1 = struct_extract %value, #field1 // ignored - not selected by path - /// %addr = ref_element_addr %ref, #some_field // path is empty - /// %v = load %addr // path is empty - /// return %v // escaping! - /// \endcode - /// - /// Trivial values are ignored, even if they are selected by `path`. - mutating func isEscaping(object: Value, path: Path = Path(), - visitUse: UseCallback = { _, _, _ in .continueWalking }, - visitDef: DefCallback = { _, _, _ in .continueWalkingUp }) -> Bool { - start() - defer { cleanup() } - - let function = object.function - return walkUpAndCache(object, path: path, followStores: false, - visitUse: { op, opPath, followStores in - if !op.value.type.isNonTrivialOrContainsRawPointer(in: function) { - return .ignore - } - return visitUse(op, opPath, followStores) - }, - visitDef: visitDef) - } - - /// Returns true if the definition of `value` is escaping. - /// - /// In contrast to `isEscaping`, this function starts with a walk-up instead of a walk-down from `value`. - mutating func isEscapingWhenWalkingDown(object: Value, - path: Path = Path(), - visitUse: UseCallback = { _, _, _ in .continueWalking }, - visitDef: DefCallback = { _, _, _ in .continueWalkingUp }) -> Bool { - start() - defer { cleanup() } - - let function = object.function - return walkDownAndCache(object, path: path, followStores: false, knownType: nil, - visitUse: { op, path, followStores in - if !op.value.type.isNonTrivialOrContainsRawPointer(in: function) { - return .ignore - } - return visitUse(op, path, followStores) - }, - visitDef: visitDef) - } - - /// Returns true if any address of `value`, which is selected by `path`, can escape. - /// - /// For example, let's assume this function is called with a struct, containing a reference, - /// and a path of `s0.c*.v**`: - /// \code - /// %value : $Struct // path == s0.c*.v**, the initial `value` - /// %ref = struct_extract %value, #field0 // path == c*.v** - /// %selected_addr = ref_element_addr %ref, #x // path == v**, the selected address - /// apply %f(%selected_addr) // escaping! - /// \endcode - /// - /// There are two differences to `isEscaping(object:)`: - /// * Loads from the selected address(es) are ignored. So it's really about the _address_ and - /// not the value stored at the address. - /// * Addresses with trivial types are _not_ ignored. - mutating - func isEscaping(addressesOf value: Value, path: Path = Path(.anyValueFields), - visitUse: UseCallback = { _, _, _ in .continueWalking }) -> Bool { - start() - defer { cleanup() } - - let function = value.function - - func isInteresting(_ type: Type, at p: Path) -> Bool { - if type.isNonTrivialOrContainsRawPointer(in: function) { return true } - // For selected addresses we also need to consider trivial types (the current value - // is an selected address if the path does not contain any class projections). - if type.isAddress && !p.hasClassProjection { return true } - return false - } - - return walkUpAndCache(value, path: path, - followStores: false, - visitUse: { operand, usePath, followStores in - if !isInteresting(operand.value.type, at: usePath) { - return .ignore - } - switch visitUse(operand, usePath, followStores) { - case .ignore: return .ignore - case .markEscaping: return .markEscaping - case .continueWithNewPath(_): fatalError("not supported") - case .continueWalking: break - } - - switch operand.instruction { - case is ApplySite, is StrongReleaseInst, is DestroyValueInst, is ReleaseValueInst: - if usePath.hasNoClassProjection { - // Passing the selected address (or a value loaded from the selected address) directly - // to a function, cannot let the selected address escape: - // * if it's passed as address: indirect parameters cannot escape a function - // * a load from the address does not let the address escape - // - // Example (continued from the previous example): - // apply %other_func1(%selected_addr) // cannot let %selected_addr escape (path == v**) - // %l = load %selected_addr - // apply %other_func2(%l) // cannot let %selected_addr escape (path == v**) - // apply %other_func3(%ref) // can let %selected_addr escape! (path == c*.v**) - // - // The same is true for destroys/releases. - return .ignore - } - return .continueWithNewPath(usePath.popLastClassAndValuesFromTail()) - case is CopyAddrInst, is LoadInst, is LoadWeakInst, is LoadUnownedInst: - if usePath.hasNoClassProjection { - // Loads+copies from the selected address cannot let escape the selected address. - return .ignore - } - default: - break - } - return .continueWalking - }, - visitDef: { def, defPath, followStores in - guard let arg = def as? FunctionArgument else { - return .continueWalkingUp - } - if !isInteresting(arg.type, at: defPath) { - return .ignore - } - if arg.isExclusiveIndirectParameter && defPath.hasNoClassProjection && !followStores { - // Non-aliasing indirect arguments cannot alias to anything unrelated. - return .continueWalkingDown - } - return .markEscaping - }) - } - - /// Returns true if the selected address(es) of `lhs`/`lhsPath` can reference the same field as - /// the selected address(es) of `rhs`/`rhsPath`. - /// - /// Example: - /// %1 = struct_element_addr %s, #field1 // true for (%1, %s) - /// %2 = struct_element_addr %s, #field2 // true for (%2, %s), false for (%1,%2) - /// - mutating func canReferenceSameField(_ lhs: Value, path lhsPath: Path = Path(.anyValueFields), - _ rhs: Value, path rhsPath: Path = Path(.anyValueFields)) -> Bool { - // lhs -> rhs will succeed (= return false) if lhs is a non-escaping "local" object, - // but not necessarily rhs. - if !isEscaping(addressesOf: lhs, path: lhsPath, - visitUse: { op, _, _ in - // Note: since we are checking the vale of an operand, we are ignoring address - // projections with no uses. This is no problem. It just requires a fix_lifetime for - // each address to test in alias-analysis test files. - if op.value == rhs { return .markEscaping } - if op.instruction is ReturnInst { return .ignore } - return .continueWalking - }) { - return false - } - // The other way round: rhs -> lhs will succeed if rhs is a non-escaping "local" object, - // but not necessarily lhs. - if !isEscaping(addressesOf: rhs, path: rhsPath, - visitUse: { op, _, _ in - if op.value == lhs { return .markEscaping } - if op.instruction is ReturnInst { return .ignore } - return .continueWalking - }) { - return false - } - return true - } - - //===--------------------------------------------------------------------===// - // private state - //===--------------------------------------------------------------------===// - - private struct CacheEntry { - private(set) var path = Path() - private(set) var followStores = false - private(set) var knownType: Type? - private var valid = false - - /// Merge the entry wit a new `path`, `followStores` and `knownType` and - /// return the resulting entry if a new walk is needed. - mutating func needWalk(path: Path, followStores: Bool, knownType: Type?) -> CacheEntry? { - if !valid { - // The first time we reach the value: do the walk with `path`, `followStores` and `knownType`. - valid = true - self.path = path - self.followStores = followStores - self.knownType = knownType - return self - } - // There was already a walk for the value. Merge the `path`, `followStores` and - // `knownType`. - var newWalkIsNeeded = false - if self.path != path { - let newPath = self.path.merge(with: path) - if newPath != self.path { - self.path = newPath - newWalkIsNeeded = true - } - } - if !self.followStores && followStores { - self.followStores = true - newWalkIsNeeded = true - } - if let ty = self.knownType, ty != knownType { - self.knownType = nil - newWalkIsNeeded = true - } - if newWalkIsNeeded { - // Merging the parameters resulted in something new (more conservative): a new walk is needed. - return self - } - // Nothing changed, no new walk is necessary. - return nil - } - } - - // The caches are not only useful for performance, but are need to avoid infinite - // recursions of walkUp-walkDown cycles. - private var walkedDownCache = Dictionary() - private var walkedUpCache = Dictionary() - - private let calleeAnalysis: CalleeAnalysis - - //===--------------------------------------------------------------------===// - // private utility functions - //===--------------------------------------------------------------------===// - - private func start() { - precondition(walkedDownCache.isEmpty && walkedUpCache.isEmpty) - } - - private mutating func cleanup() { - walkedDownCache.removeAll(keepingCapacity: true) - walkedUpCache.removeAll(keepingCapacity: true) - } - - // Set a breakpoint here to debug when a value is escaping. - private var isEscaping: Bool { - true - } - - //===--------------------------------------------------------------------===// - // walk-down functions - //===--------------------------------------------------------------------===// - - /// The entry point to the down-walk. - /// - /// It's a no-op if the walkDown is already cached, i.e was already done before with - /// the same/matching `path`, `followStores` and `knownType`. - /// - /// In addition to the other common arguments, the `knownType` - if not nil - is the exact type - /// of `value`. This is used for analysing releases by lookup up the knownType's destructor. - /// - /// Returns true if the `value` escapes. - private mutating - func walkDownAndCache(_ value: Value, path: Path, followStores: Bool, - knownType: Type?, - visitUse: UseCallback, visitDef: DefCallback) -> Bool { - if let entry = walkedDownCache[value.hashable, default: CacheEntry()].needWalk(path: path, followStores: followStores, knownType: knownType) { - return walkDown(value, path: entry.path, followStores: entry.followStores, knownType: entry.knownType, - visitUse: visitUse, visitDef: visitDef) - } - return false - } - - /// Recursively walks down defs to uses, handling all relevant instructions. - /// - /// Returns true if the `value` escapes. - private mutating - func walkDown(_ value: Value, path origPath: Path, followStores: Bool, knownType: Type?, - visitUse: UseCallback, visitDef: DefCallback) -> Bool { - for use in value.uses { - if use.isTypeDependent { continue} - - let path: Path - switch visitUse(use, origPath, followStores) { - case .ignore: - continue - case .markEscaping: - return isEscaping - case .continueWalking: - path = origPath - case .continueWithNewPath(let newPath): - path = newPath - } - - let user = use.instruction - switch user { - case let rta as RefTailAddrInst: - if let newPath = path.popIfMatches(.tailElements) { - if walkDown(rta, path: newPath, followStores: followStores, knownType: nil, - visitUse: visitUse, visitDef: visitDef) { - return true - } - } - case let rea as RefElementAddrInst: - if let newPath = path.popIfMatches(.classField, index: rea.fieldIndex) { - if walkDown(rea, path: newPath, followStores: followStores, knownType: nil, - visitUse: visitUse, visitDef: visitDef) { - return true - } - } - case let pb as ProjectBoxInst: - if let newPath = path.popIfMatches(.classField, index: pb.fieldIndex) { - if walkDown(pb, path: newPath, followStores: followStores, knownType: nil, - visitUse: visitUse, visitDef: visitDef) { - return true - } - } - case let str as StructInst: - if walkDown(str, path: path.push(.structField, index: use.index), - followStores: followStores, knownType: knownType, - visitUse: visitUse, visitDef: visitDef) { - return true - } - case let se as StructExtractInst: - if let newPath = path.popIfMatches(.structField, index: se.fieldIndex) { - if walkDown(se, path: newPath, followStores: followStores, knownType: knownType, - visitUse: visitUse, visitDef: visitDef) { - return true - } - } - case let ds as DestructureStructInst: - if walkDownInstructionResults(results: ds.results, - fieldKind: .structField, path: path, followStores: followStores, knownType: knownType, - visitUse: visitUse, visitDef: visitDef) { - return true - } - case let dt as DestructureTupleInst: - if walkDownInstructionResults(results: dt.results, - fieldKind: .tupleField, path: path, followStores: followStores, knownType: knownType, - visitUse: visitUse, visitDef: visitDef) { - return true - } - case let sea as StructElementAddrInst: - if let newPath = path.popIfMatches(.structField, index: sea.fieldIndex) { - if walkDown(sea, path: newPath, followStores: followStores, knownType: nil, - visitUse: visitUse, visitDef: visitDef) { - return true - } - } - case let t as TupleInst: - if walkDown(t, path: path.push(.tupleField, index: use.index), - followStores: followStores, knownType: knownType, - visitUse: visitUse, visitDef: visitDef) { - return true - } - case let te as TupleExtractInst: - if let newPath = path.popIfMatches(.tupleField, index: te.fieldIndex) { - if walkDown(te, path: newPath, followStores: followStores, knownType: knownType, - visitUse: visitUse, visitDef: visitDef) { - return true - } - } - case let tea as TupleElementAddrInst: - if let newPath = path.popIfMatches(.tupleField, index: tea.fieldIndex) { - if walkDown(tea, path: newPath, followStores: followStores, knownType: nil, - visitUse: visitUse, visitDef: visitDef) { - return true - } - } - case let e as EnumInst: - if walkDown(e, path: path.push(.enumCase, index: e.caseIndex), - followStores: followStores, knownType: knownType, - visitUse: visitUse, visitDef: visitDef) { - return true - } - case is UncheckedEnumDataInst, is InitEnumDataAddrInst, is UncheckedTakeEnumDataAddrInst: - if let newPath = path.popIfMatches(.enumCase, index: (user as! EnumInstruction).caseIndex) { - if walkDown(user as! SingleValueInstruction, path: newPath, followStores: followStores, - knownType: knownType, - visitUse: visitUse, visitDef: visitDef) { - return true - } - } - case let se as SwitchEnumInst: - if let (caseIdx, newPath) = path.pop(kind: .enumCase) { - if let succBlock = se.getUniqueSuccessor(forCaseIndex: caseIdx) { - if let payload = succBlock.arguments.first { - if walkDown(payload, path: newPath, followStores: followStores, knownType: knownType, - visitUse: visitUse, visitDef: visitDef) { - return true - } - } - } - } else if path.topMatchesAnyValueField { - // We don't know the enum case: we have to containue with _all_ cases. - for succBlock in se.block.successors { - if let payload = succBlock.arguments.first { - if walkDown(payload, path: path, followStores: followStores, knownType: knownType, - visitUse: visitUse, visitDef: visitDef) { - return true - } - } - } - } else { - return isEscaping - } - case is StoreInst, is StoreWeakInst, is StoreUnownedInst: - let store = user as! StoringInstruction - if use == store.sourceOperand { - if walkUp(store.destination, path: path, - followStores: followStores, - visitUse: visitUse, visitDef: visitDef) { - return true - } - } else { - assert(use == store.destinationOperand) - if let si = store as? StoreInst, si.destinationOwnership == .assign { - if handleDestroy(of: value, path: path, followStores: followStores, knownType: nil) { - return true - } - } - if followStores { - if walkUp(store.source, path: path, followStores: followStores, - visitUse: visitUse, visitDef: visitDef) { - return true - } - } - } - case let copyAddr as CopyAddrInst: - if use == copyAddr.sourceOperand { - if walkUp(copyAddr.destination, path: path, followStores: followStores, - visitUse: visitUse, visitDef: visitDef) { - return true - } - } else { - if !copyAddr.isInitializationOfDest { - if handleDestroy(of: value, path: path, followStores: followStores, knownType: nil) { - return true - } - } - if followStores { - assert(use == copyAddr.destinationOperand) - if walkUp(copyAddr.source, path: path, followStores: followStores, - visitUse: visitUse, visitDef: visitDef) { - return true - } - } - } - case is DestroyValueInst, is ReleaseValueInst, is StrongReleaseInst, - is DestroyAddrInst: - if handleDestroy(of: value, path: path, followStores: followStores, knownType: knownType) { - return true - } - case let br as BranchInst: - // We need to check the cache to avoid cycles and/or exploding complexity in - // case of control flow merges. - if walkDownAndCache(br.getArgument(for: use), path: path, - followStores: followStores, knownType: knownType, - visitUse: visitUse, visitDef: visitDef) { - return true - } - case let cbr as CondBranchInst: - // Same here: we need to check the cache. - if walkDownAndCache(cbr.getArgument(for: use), path: path, - followStores: followStores, knownType: knownType, - visitUse: visitUse, visitDef: visitDef) { - return true - } - case is ReturnInst: - return isEscaping - case is ApplyInst, is TryApplyInst, is BeginApplyInst: - if walkDownCallee(argOp: use, apply: user as! FullApplySite, path: path, - followStores: followStores, knownType: knownType, - visitUse: visitUse, visitDef: visitDef) { - return true - } - case let pai as PartialApplyInst: - if walkDownCallee(argOp: use, apply: pai, path: path, - followStores: followStores, knownType: nil, - visitUse: visitUse, visitDef: visitDef) { - return true - } - // We need to follow the partial_apply value for two reasons: - // 1. the closure (with the captured values) itself can escape - // 2. something can escape in a destructor when the context is destroyed - if walkDown(pai, path: path, followStores: followStores, knownType: nil, - visitUse: visitUse, visitDef: visitDef) { - return true - } - - case is LoadInst, is LoadWeakInst, is LoadUnownedInst, - is InitExistentialAddrInst, is OpenExistentialAddrInst, is BeginAccessInst, - is PointerToAddressInst, is AddressToPointerInst, is IndexAddrInst: - if walkDown(user as! SingleValueInstruction, path: path, - followStores: followStores, knownType: nil, - visitUse: visitUse, visitDef: visitDef) { - return true - } - case is InitExistentialRefInst, is OpenExistentialRefInst, - is BeginBorrowInst, is CopyValueInst, - is UpcastInst, is UncheckedRefCastInst, is EndCOWMutationInst, - is RefToBridgeObjectInst, is BridgeObjectToRefInst: - if walkDown(user as! SingleValueInstruction, path: path, - followStores: followStores, knownType: knownType, - visitUse: visitUse, visitDef: visitDef) { - return true - } - case let bcm as BeginCOWMutationInst: - if walkDown(bcm.bufferResult, path: path, followStores: followStores, knownType: knownType, - visitUse: visitUse, visitDef: visitDef) { - return true - } - case let mdi as MarkDependenceInst: - if use.index == 0 { - if walkDown(mdi, path: path, followStores: followStores, knownType: knownType, - visitUse: visitUse, visitDef: visitDef) { - return true - } - } - case let bi as BuiltinInst: - switch bi.id { - case .DestroyArray: - if use.index != 1 || - path.popAllValueFields().popIfMatches(.anyClassField) != nil { - return isEscaping - } - default: - return isEscaping - } - case is DeallocStackInst, is StrongRetainInst, is RetainValueInst, - is DebugValueInst, is ValueMetatypeInst, is InjectEnumAddrInst, - is InitExistentialMetatypeInst, is OpenExistentialMetatypeInst, - is ExistentialMetatypeInst, is DeallocRefInst, is SetDeallocatingInst, - is FixLifetimeInst, is ClassifyBridgeObjectInst, is BridgeObjectToWordInst, - is EndBorrowInst, is EndAccessInst, - is StrongRetainInst, is RetainValueInst, - is ClassMethodInst, is SuperMethodInst, is ObjCMethodInst, - is ObjCSuperMethodInst, is WitnessMethodInst,is DeallocStackRefInst: - break - default: - return isEscaping - } - } - return false - } - - /// Utility function to continue walking down multi-result instructions, like - /// `destructure_struct` and `destructure_tuple`. - private mutating - func walkDownInstructionResults(results: Instruction.Results, - fieldKind: Path.FieldKind, - path: Path, followStores: Bool, knownType: Type?, - visitUse: UseCallback, - visitDef: DefCallback) -> Bool { - if let (index, newPath) = path.pop(kind: fieldKind) { - return walkDown(results[index], path: newPath, followStores: followStores, knownType: knownType, - visitUse: visitUse, visitDef: visitDef) - } - if path.topMatchesAnyValueField { - // We don't know the struct/tuple field: we have to continue with _all_ fields. - for elem in results { - if walkDown(elem, path: path, followStores: followStores, knownType: nil, - visitUse: visitUse, visitDef: visitDef) { - return true - } - } - return false - } - return isEscaping - } - - /// Handle an apply (full or partial) during the walk-down. - private mutating - func walkDownCallee(argOp: Operand, apply: ApplySite, - path: Path, followStores: Bool, knownType: Type?, - visitUse: UseCallback, visitDef: DefCallback) -> Bool { - guard let argIdx = apply.argumentIndex(of: argOp) else { - // The callee or a type dependent operand of the apply does not let escape anything. - return false - } - - // Argument effects do not consider any potential stores to the argument (or it's content). - // Therefore, if we need to track stores, the argument effects do not correctly describe what we need. - // For example, argument 0 in the following function is marked as not-escaping, although there - // is a store to the argument: - // - // sil [escapes !%0.**] @callee(@inout X, @owned X) -> () { - // bb0(%0 : $*X, %1 : $X): - // store %1 to %0 : $*X - // } - if followStores { return isEscaping } - - guard let callees = calleeAnalysis.getCallees(callee: apply.callee) else { - // The callees are not know, e.g. if the callee is a closure, class method, etc. - return isEscaping - } - - for callee in callees { - if walkDownArgument(argIdx: argIdx, argPath: path, knownType: knownType, - apply: apply, callee: callee, - visitUse: visitUse, visitDef: visitDef) { - return true - } - } - return false - } - - /// Handle an apply argument during the walk-down. - private mutating - func walkDownArgument(argIdx: Int, argPath: Path, knownType: Type?, - apply: ApplySite, callee: Function, - visitUse: UseCallback, visitDef: DefCallback) -> Bool { - var matched = false - let calleeArgIdx = apply.calleeArgIndex(callerArgIndex: argIdx) - - for effect in callee.effects.argumentEffects { - switch effect.kind { - case .notEscaping: - if effect.selectedArg.matches(.argument(calleeArgIdx), argPath) { - return false - } - case .escaping(let to, let exclusive): - if effect.selectedArg.matches(.argument(calleeArgIdx), argPath) { - matched = true - - switch to.value { - case .returnValue: - guard let fas = apply as? FullApplySite, let result = fas.singleDirectResult else { return isEscaping } - - if walkDown(result, path: to.pathPattern, followStores: false, - knownType: exclusive ? knownType : nil, - visitUse: visitUse, visitDef: visitDef) { - return true - } - case .argument(let toArgIdx): - guard let callerToIdx = apply.callerArgIndex(calleeArgIndex: toArgIdx) else { - return isEscaping - } - - // Continue at the destination of an arg-to-arg escape. - if walkUp(apply.arguments[callerToIdx], path: to.pathPattern, followStores: false, - visitUse: visitUse, visitDef: visitDef) { - return true - } - } - } else if to.matches(.argument(calleeArgIdx), argPath) { - // The reverse direction of an arg-to-arg escape. - guard let callerArgIdx = apply.callerArgIndex(calleeArgIndex: effect.selectedArg.argumentIndex) else { - return isEscaping - } - if !exclusive { return isEscaping } - - matched = true - - if walkUp(apply.arguments[callerArgIdx], path: effect.selectedArg.pathPattern, followStores: false, - visitUse: visitUse, visitDef: visitDef) { - return true - } - } - } - } - if !matched { - return isEscaping - } - return false - } - - private func handleDestroy(of value: Value, path: Path, followStores: Bool, knownType: Type?) -> Bool { - // Destroying cannot escape the value/reference itself, but its - // contents (in the destructor). - let unwrappedClassPath = path.popAllValueFields() - if let _ = unwrappedClassPath.popIfMatches(.anyClassField) { - if followStores { - return isEscaping - } - if let exactTy = knownType { - guard let destructor = calleeAnalysis.getDestructor(ofExactType: exactTy) else { - return isEscaping - } - if destructor.effects.canEscape(path: unwrappedClassPath) { - return isEscaping - } - } else { - // We don't know the exact type, so get all possible called destructure from - // the callee analysis. - guard let destructors = calleeAnalysis.getDestructors(of: value.type) else { - return isEscaping - } - for destructor in destructors { - if destructor.effects.canEscape(path: unwrappedClassPath) { - return isEscaping - } - } - } - } - return false - } - - //===--------------------------------------------------------------------===// - // walk-up functions - //===--------------------------------------------------------------------===// - - /// The entry point to the up-walk. - /// - /// It's a no-op if the walkUp is already cached, i.e was already done before with - /// the same/matching `path` and `followStores`. - /// - /// Returns true if the `value` escapes. - private mutating - func walkUpAndCache(_ value: Value, path: Path, followStores: Bool, - visitUse: UseCallback, visitDef: DefCallback) -> Bool { - if let entry = walkedUpCache[value.hashable, default: CacheEntry()].needWalk(path: path, followStores: followStores, knownType: nil) { - return walkUp(value, path: entry.path, followStores: entry.followStores, - visitUse: visitUse, visitDef: visitDef) - } - return false - } - - /// Recursively walks up uses to defs, handling all relevant instructions. - /// - /// Returns true if the `value` escapes. - private mutating - func walkUp(_ value: Value, path: Path, followStores: Bool, - visitUse: UseCallback, visitDef: DefCallback) -> Bool { - var val = value - var p = path - var fSt = followStores - while true { - switch visitDef(val, p, fSt) { - case .ignore: return false - case .markEscaping: return isEscaping - case .continueWalkingUp: break - case .continueWalkingDown: - return walkDownAndCache(val, path: p, followStores: fSt, knownType: nil, - visitUse: visitUse, visitDef: visitDef) - } - switch val { - case is AllocRefInst, is AllocRefDynamicInst: - return walkDownAndCache(val, path: p, followStores: fSt, knownType: val.type, - visitUse: visitUse, visitDef: visitDef) - case is AllocRefInst, is AllocRefDynamicInst, is AllocStackInst, is AllocBoxInst: - return walkDownAndCache(val, path: p, followStores: fSt, knownType: nil, - visitUse: visitUse, visitDef: visitDef) - case is FunctionArgument: - return isEscaping - case let arg as BlockArgument: - if arg.isPhiArgument { - for incoming in arg.incomingPhiValues { - if walkUpAndCache(incoming, path: p, followStores: fSt, - visitUse: visitUse, visitDef: visitDef) { - return true - } - } - return false - } - let block = arg.block - switch block.singlePredecessor!.terminator { - case let se as SwitchEnumInst: - guard let caseIdx = se.getUniqueCase(forSuccessor: block) else { - return isEscaping - } - val = se.enumOp - p = p.push(.enumCase, index: caseIdx) - case let ta as TryApplyInst: - if block != ta.normalBlock { return isEscaping } - return walkUpApplyResult(apply: ta, - path: p, followStores: fSt, - visitUse: visitUse, visitDef: visitDef) - default: - return isEscaping - } - case let ap as ApplyInst: - return walkUpApplyResult(apply: ap, - path: p, followStores: fSt, - visitUse: visitUse, visitDef: visitDef) - case let str as StructInst: - if let (structField, poppedPath) = p.pop(kind: .structField) { - val = str.operands[structField].value - p = poppedPath - } else if p.topMatchesAnyValueField { - // We don't know the struct field: we have to continue with _all_ operands. - for op in str.operands { - if walkUpAndCache(op.value, path: p, followStores: fSt, visitUse: visitUse, visitDef: visitDef) { - return true - } - } - return false - } else { - return false - } - case let se as StructExtractInst: - val = se.operand - p = p.push(.structField, index: se.fieldIndex) - case let t as TupleInst: - if let (tupleField, poppedPath) = p.pop(kind: .tupleField) { - val = t.operands[tupleField].value - p = poppedPath - } else if p.topMatchesAnyValueField { - // We don't know the tuple element: we have to continue with _all_ operands. - for op in t.operands { - if walkUpAndCache(op.value, path: p, followStores: fSt, visitUse: visitUse, visitDef: visitDef) { - return true - } - } - return false - } else { - return false - } - case let te as TupleExtractInst: - val = te.operand - p = p.push(.tupleField, index: te.fieldIndex) - case is LoadInst, is LoadWeakInst, is LoadUnownedInst: - val = (val as! UnaryInstruction).operand - // When the value is loaded from somewhere it also matters what's - // stored to that memory location. - fSt = true - case let rta as RefTailAddrInst: - val = rta.operand - p = p.push(.tailElements) - case let rea as RefElementAddrInst: - val = rea.operand - p = p.push(.classField, index: rea.fieldIndex) - case let pb as ProjectBoxInst: - val = pb.operand - p = p.push(.classField, index: pb.fieldIndex) - case let sea as StructElementAddrInst: - p = p.push(.structField, index: sea.fieldIndex) - val = sea.operand - case let tea as TupleElementAddrInst: - p = p.push(.tupleField, index: tea.fieldIndex) - val = tea.operand - case let e as EnumInst: - guard let newPath = p.popIfMatches(.enumCase, index: e.caseIndex) else { - return false - } - guard let op = e.operand else { return false } - p = newPath - val = op - case is UncheckedEnumDataInst, is InitEnumDataAddrInst, is UncheckedTakeEnumDataAddrInst: - p = p.push(.enumCase, index: (val as! EnumInstruction).caseIndex) - val = (val as! UnaryInstruction).operand - case is UpcastInst, is UncheckedRefCastInst, - is InitExistentialRefInst, is OpenExistentialRefInst, - is InitExistentialAddrInst, is OpenExistentialAddrInst, - is BeginAccessInst, is BeginBorrowInst, - is EndCOWMutationInst, - is RefToBridgeObjectInst, is BridgeObjectToRefInst, - is IndexAddrInst, is CopyValueInst, is MarkDependenceInst, - is PointerToAddressInst, is AddressToPointerInst: - val = (val as! Instruction).operands[0].value - case let mvr as MultipleValueInstructionResult: - let inst = mvr.instruction - switch inst { - case is DestructureStructInst, is DestructureTupleInst: - val = inst.operands[0].value - // TODO: only push the specific result index. - // But currently there is no O(0) method to get the result index - // from a result value. - p = p.popAllValueFields().push(.anyValueFields) - case let bcm as BeginCOWMutationInst: - val = bcm.operand - default: - return isEscaping - } - default: - return isEscaping - } - } - } - - /// Walks up from the return to the source argument if there is an "exclusive" - /// escaping effect on an argument. - private mutating - func walkUpApplyResult(apply: FullApplySite, - path: Path, followStores: Bool, - visitUse: UseCallback, visitDef: DefCallback) -> Bool { - guard let callees = calleeAnalysis.getCallees(callee: apply.callee) else { - return isEscaping - } - - for callee in callees { - var matched = false - for effect in callee.effects.argumentEffects { - switch effect.kind { - case .notEscaping: - break - case .escaping(let toSelectedArg, let exclusive): - if exclusive && toSelectedArg.matches(.returnValue, path) { - matched = true - if walkUp(apply.arguments[effect.selectedArg.argumentIndex], - path: effect.selectedArg.pathPattern, followStores: followStores, - visitUse: visitUse, visitDef: visitDef) { - return true - } - } - } - } - if !matched { - return isEscaping - } - } - return false - } -} diff --git a/SwiftCompilerSources/Sources/SIL/SmallProjectionPath.swift b/SwiftCompilerSources/Sources/SIL/SmallProjectionPath.swift index bf6e5f06bf0..fdaae762897 100644 --- a/SwiftCompilerSources/Sources/SIL/SmallProjectionPath.swift +++ b/SwiftCompilerSources/Sources/SIL/SmallProjectionPath.swift @@ -42,7 +42,7 @@ public struct SmallProjectionPath : CustomStringConvertible, CustomReflectable, /// The physical representation of the path. The path components are stored in /// reverse order: the first path component is stored in the lowest bits (LSB), /// the last component is stored in the highest bits (MSB). - /// Each path component consists of zero or more "index-overflow" bytes followed + /// Each pass component consists of zero or more "index-overflow" bytes followed /// by the "index-kind" main byte (from LSB to MSB). /// /// index overflow byte: bit-nr: | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | @@ -70,10 +70,10 @@ public struct SmallProjectionPath : CustomStringConvertible, CustomReflectable, case classField = 0x4 // A concrete class field: syntax e.g. `c1` case tailElements = 0x5 // A tail allocated element of a class: syntax `ct` case anyValueFields = 0x6 // Any number of any value fields (struct, tuple, enum): syntax `v**` - + case anyClassField = 0x7 // Any class field, including tail elements: syntax `c*` + // "Large" kinds: starting from here the low 3 bits must be 1. // This and all following kinds (we'll add in the future) cannot have a field index. - case anyClassField = 0x7 // Any class field, including tail elements: syntax `c*` case anything = 0xf // Any number of any fields: syntax `**` public var isValueField: Bool { @@ -180,10 +180,7 @@ public struct SmallProjectionPath : CustomStringConvertible, CustomReflectable, assert(kind != .anything || bytes == 0, "'anything' only allowed in last path component") var idx = index var b = bytes - if (b >> 56) != 0 { - // Overflow - return Self(.anything) - } + if (b >> 56) != 0 { return Self(.anything) } b = (b << 8) | UInt64(((idx & 0xf) << 4) | (kind.rawValue << 1)) idx >>= 4 while idx != 0 { @@ -245,37 +242,13 @@ public struct SmallProjectionPath : CustomStringConvertible, CustomReflectable, /// returns true for `v**.c3` /// returns true for `**` /// returns false for `s0.c3` (because e.g. `s1` would not match) - public var topMatchesAnyValueField: Bool { + public var matchesAllValueFields: Bool { switch top.kind { case .anyValueFields, .anything: return true default: return false } } - /// Returns true if the path does not have any class projections. - /// For example: - /// returns true for `v**` - /// returns false for `c0` - /// returns false for `**` (because '**' can have any number of class projections) - public var hasNoClassProjection: Bool { - return matches(pattern: Self(.anyValueFields)) - } - - /// Returns true if the path has at least one class projection. - /// For example: - /// returns false for `v**` - /// returns true for `v**.c0.s1.v**` - /// returns false for `**` (because '**' can have zero class projections) - public var hasClassProjection: Bool { - var p = self - while true { - let (k, _, numBits) = p.top - if k == .root { return false } - if k.isClassField { return true } - p = p.pop(numBits: numBits) - } - } - /// Pops all value field components from the beginning of the path. /// For example: /// `s0.e2.3.c4.s1` -> `c4.s1` @@ -289,35 +262,7 @@ public struct SmallProjectionPath : CustomStringConvertible, CustomReflectable, p = p.pop(numBits: numBits) } } - - /// Pops the last class projection and all following value fields from the tail of the path. - /// For example: - /// `s0.e2.3.c4.s1` -> `s0.e2.3` - /// `v**.c1.c4.s1` -> `v**.c1` - /// `c1.**` -> `c1.**` (because it's unknown how many class projections are in `**`) - public func popLastClassAndValuesFromTail() -> SmallProjectionPath { - var p = self - var totalBits = 0 - var neededBits = 0 - while true { - let (k, _, numBits) = p.top - if k == .root { break } - if k.isClassField { - neededBits = totalBits - totalBits += numBits - } else { - totalBits += numBits - if !k.isValueField { - // k is `anything` - neededBits = totalBits - } - } - p = p.pop(numBits: numBits) - } - if neededBits == 64 { return self } - return SmallProjectionPath(bytes: bytes & ((1 << neededBits) - 1)) - } - + /// Returns true if this path matches a pattern path. /// /// Formally speaking: @@ -515,8 +460,6 @@ extension SmallProjectionPath { parsing() merging() matching() - predicates() - path2path() func basicPushPop() { let p1 = SmallProjectionPath(.structField, index: 3) @@ -626,52 +569,5 @@ extension SmallProjectionPath { let result = lhs.matches(pattern: rhs) precondition(result == expect) } - - func predicates() { - testPredicate("v**.c3", \.topMatchesAnyValueField, expect: true) - testPredicate("**", \.topMatchesAnyValueField, expect: true) - testPredicate("s0.c3", \.topMatchesAnyValueField, expect: false) - - testPredicate("v**", \.hasNoClassProjection, expect: true) - testPredicate("c0", \.hasNoClassProjection, expect: false) - testPredicate("1", \.hasNoClassProjection, expect: true) - testPredicate("**", \.hasNoClassProjection, expect: false) - - testPredicate("v**", \.hasClassProjection, expect: false) - testPredicate("v**.c0.s1.v**", \.hasClassProjection, expect: true) - testPredicate("c0.**", \.hasClassProjection, expect: true) - testPredicate("c0.c1", \.hasClassProjection, expect: true) - testPredicate("ct", \.hasClassProjection, expect: true) - testPredicate("s0", \.hasClassProjection, expect: false) - } - - func testPredicate(_ pathStr: String, _ property: (SmallProjectionPath) -> Bool, expect: Bool) { - var parser = StringParser(pathStr) - let path = try! parser.parseProjectionPathFromSIL() - let result = property(path) - precondition(result == expect) - } - - func path2path() { - testPath2Path("s0.e2.3.c4.s1", { $0.popAllValueFields() }, expect: "c4.s1") - testPath2Path("v**.c4.s1", { $0.popAllValueFields() }, expect: "c4.s1") - testPath2Path("**", { $0.popAllValueFields() }, expect: "**") - - testPath2Path("s0.e2.3.c4.s1.e2.v**.**", { $0.popLastClassAndValuesFromTail() }, expect: "s0.e2.3.c4.s1.e2.v**.**") - testPath2Path("s0.c2.3.c4.s1", { $0.popLastClassAndValuesFromTail() }, expect: "s0.c2.3") - testPath2Path("v**.c*.s1", { $0.popLastClassAndValuesFromTail() }, expect: "v**") - testPath2Path("s1.ct.v**", { $0.popLastClassAndValuesFromTail() }, expect: "s1") - testPath2Path("c0.c1.c2", { $0.popLastClassAndValuesFromTail() }, expect: "c0.c1") - testPath2Path("**", { $0.popLastClassAndValuesFromTail() }, expect: "**") - } - - func testPath2Path(_ pathStr: String, _ transform: (SmallProjectionPath) -> SmallProjectionPath, expect: String) { - var parser = StringParser(pathStr) - let path = try! parser.parseProjectionPathFromSIL() - var expectParser = StringParser(expect) - let expectPath = try! expectParser.parseProjectionPathFromSIL() - let result = transform(path) - precondition(result == expectPath) - } } } diff --git a/SwiftCompilerSources/Sources/SIL/Type.swift b/SwiftCompilerSources/Sources/SIL/Type.swift index 5c4123ff593..24b78e58b66 100644 --- a/SwiftCompilerSources/Sources/SIL/Type.swift +++ b/SwiftCompilerSources/Sources/SIL/Type.swift @@ -27,10 +27,6 @@ public struct Type : CustomStringConvertible, CustomReflectable { return SILType_isReferenceCounted(bridged, function.bridged) != 0 } - public func isNonTrivialOrContainsRawPointer(in function: Function) -> Bool { - return SILType_isNonTrivialOrContainsRawPointer(bridged, function.bridged) != 0 - } - public var isNominal: Bool { SILType_isNominal(bridged) != 0 } public var isClass: Bool { SILType_isClass(bridged) != 0 } public var isStruct: Bool { SILType_isStruct(bridged) != 0 } diff --git a/include/swift/SIL/SILBridging.h b/include/swift/SIL/SILBridging.h index 1c9ef921735..e7a62eae0c6 100644 --- a/include/swift/SIL/SILBridging.h +++ b/include/swift/SIL/SILBridging.h @@ -219,7 +219,6 @@ BridgedStringRef SILType_debugDescription(BridgedType); SwiftInt SILType_isAddress(BridgedType); SwiftInt SILType_isTrivial(BridgedType, BridgedFunction); SwiftInt SILType_isReferenceCounted(BridgedType type, BridgedFunction); -SwiftInt SILType_isNonTrivialOrContainsRawPointer(BridgedType, BridgedFunction); SwiftInt SILType_isNominal(BridgedType type); SwiftInt SILType_isClass(BridgedType type); SwiftInt SILType_isStruct(BridgedType type); diff --git a/include/swift/SIL/SILType.h b/include/swift/SIL/SILType.h index 3a98c68f4de..84db56718c3 100644 --- a/include/swift/SIL/SILType.h +++ b/include/swift/SIL/SILType.h @@ -308,15 +308,6 @@ public: /// even though they are technically trivial. bool isTrivial(const SILFunction &F) const; - /// True if the type is the Builtin.RawPointer or a struct/tuple/enum which - /// contains a Builtin.RawPointer. - /// Returns false for types for which this property is not known, e.g. generic - /// types. - bool isOrContainsRawPointer(const SILFunction &F) const; - - /// An efficient implementation of `!isTrivial() && isOrContainsRawPointer()`. - bool isNonTrivialOrContainsRawPointer(const SILFunction &F) const; - /// True if the type is an empty tuple or an empty struct or a tuple or /// struct containing only empty types. bool isEmpty(const SILFunction &F) const; diff --git a/include/swift/SIL/TypeLowering.h b/include/swift/SIL/TypeLowering.h index a552b4ee2bb..7686bc4e36b 100644 --- a/include/swift/SIL/TypeLowering.h +++ b/include/swift/SIL/TypeLowering.h @@ -98,15 +98,6 @@ enum IsTrivial_t : bool { IsTrivial = true }; -/// Is a lowered SIL type the Builtin.RawPointer or a struct/tuple/enum which -/// contains a Builtin.RawPointer? -/// HasRawPointer is true only for types that are known to contain -/// Builtin.RawPointer. It is not assumed true for generic or resilient types. -enum HasRawPointer_t : bool { - DoesNotHaveRawPointer = false, - HasRawPointer = true -}; - /// Is a lowered SIL type fixed-ABI? That is, can the current context /// assign it a fixed size and alignment and perform value operations on it /// (such as copies, destroys, constructions, and projections) without @@ -181,7 +172,6 @@ public: ResilientFlag = 1 << 3, TypeExpansionSensitiveFlag = 1 << 4, InfiniteFlag = 1 << 5, - HasRawPointerFlag = 1 << 6, }; uint8_t Flags; @@ -194,14 +184,12 @@ public: IsTrivial_t isTrivial, IsFixedABI_t isFixedABI, IsAddressOnly_t isAddressOnly, IsResilient_t isResilient, IsTypeExpansionSensitive_t isTypeExpansionSensitive = - IsNotTypeExpansionSensitive, - HasRawPointer_t hasRawPointer = DoesNotHaveRawPointer) + IsNotTypeExpansionSensitive) : Flags((isTrivial ? 0U : NonTrivialFlag) | (isFixedABI ? 0U : NonFixedABIFlag) | (isAddressOnly ? AddressOnlyFlag : 0U) | (isResilient ? ResilientFlag : 0U) | - (isTypeExpansionSensitive ? TypeExpansionSensitiveFlag : 0U) | - (hasRawPointer ? HasRawPointerFlag : 0U)) {} + (isTypeExpansionSensitive ? TypeExpansionSensitiveFlag : 0U)) {} constexpr bool operator==(RecursiveProperties p) const { return Flags == p.Flags; @@ -211,11 +199,6 @@ public: return {IsTrivial, IsFixedABI, IsNotAddressOnly, IsNotResilient}; } - static constexpr RecursiveProperties forRawPointer() { - return {IsTrivial, IsFixedABI, IsNotAddressOnly, IsNotResilient, - IsNotTypeExpansionSensitive, HasRawPointer}; - } - static constexpr RecursiveProperties forReference() { return {IsNotTrivial, IsFixedABI, IsNotAddressOnly, IsNotResilient}; } @@ -236,9 +219,6 @@ public: IsTrivial_t isTrivial() const { return IsTrivial_t((Flags & NonTrivialFlag) == 0); } - IsTrivial_t isOrContainsRawPointer() const { - return IsTrivial_t((Flags & HasRawPointerFlag) != 0); - } IsFixedABI_t isFixedABI() const { return IsFixedABI_t((Flags & NonFixedABIFlag) == 0); } @@ -335,10 +315,6 @@ public: return Properties.isTrivial(); } - bool isOrContainsRawPointer() const { - return Properties.isOrContainsRawPointer(); - } - /// Returns true if the type is a scalar reference-counted reference, which /// can be retained and released. bool isReferenceCounted() const { diff --git a/include/swift/SILOptimizer/PassManager/Passes.def b/include/swift/SILOptimizer/PassManager/Passes.def index bea872b0753..69f84f1e3a9 100644 --- a/include/swift/SILOptimizer/PassManager/Passes.def +++ b/include/swift/SILOptimizer/PassManager/Passes.def @@ -224,12 +224,6 @@ PASS(EmitDFDiagnostics, "dataflow-diagnostics", "Emit SIL Diagnostics") PASS(EscapeAnalysisDumper, "escapes-dump", "Dump Escape Analysis Results") -SWIFT_FUNCTION_PASS(EscapeInfoDumper, "dump-escape-info", - "Dumps escape information") -SWIFT_FUNCTION_PASS(AddressEscapeInfoDumper, "dump-addr-escape-info", - "Dumps address escape information") -SWIFT_FUNCTION_PASS(ComputeEffects, "compute-effects", - "Computes function effects") PASS(FlowIsolation, "flow-isolation", "Enforces flow-sensitive actor isolation rules") PASS(FunctionOrderPrinter, "function-order-printer", diff --git a/lib/SIL/IR/SILType.cpp b/lib/SIL/IR/SILType.cpp index 1f929a37ada..9914d564b4d 100644 --- a/lib/SIL/IR/SILType.cpp +++ b/lib/SIL/IR/SILType.cpp @@ -108,17 +108,6 @@ bool SILType::isTrivial(const SILFunction &F) const { return F.getTypeLowering(contextType).isTrivial(); } -bool SILType::isOrContainsRawPointer(const SILFunction &F) const { - auto contextType = hasTypeParameter() ? F.mapTypeIntoContext(*this) : *this; - return F.getTypeLowering(contextType).isOrContainsRawPointer(); -} - -bool SILType::isNonTrivialOrContainsRawPointer(const SILFunction &F) const { - auto contextType = hasTypeParameter() ? F.mapTypeIntoContext(*this) : *this; - const TypeLowering &tyLowering = F.getTypeLowering(contextType); - return !tyLowering.isTrivial() || tyLowering.isOrContainsRawPointer(); -} - bool SILType::isEmpty(const SILFunction &F) const { // Infinite types are never empty. if (F.getTypeLowering(*this).getRecursiveProperties().isInfinite()) { diff --git a/lib/SIL/IR/TypeLowering.cpp b/lib/SIL/IR/TypeLowering.cpp index 5cd110cc2a8..52b0faf8f72 100644 --- a/lib/SIL/IR/TypeLowering.cpp +++ b/lib/SIL/IR/TypeLowering.cpp @@ -244,6 +244,7 @@ namespace { IMPL(BuiltinInteger, Trivial) IMPL(BuiltinIntegerLiteral, Trivial) IMPL(BuiltinFloat, Trivial) + IMPL(BuiltinRawPointer, Trivial) IMPL(BuiltinRawUnsafeContinuation, Trivial) IMPL(BuiltinJob, Trivial) IMPL(BuiltinExecutor, Trivial) @@ -258,14 +259,6 @@ namespace { #undef IMPL - RetTy visitBuiltinRawPointerType(CanBuiltinRawPointerType type, - AbstractionPattern orig, - IsTypeExpansionSensitive_t isSensitive) { - RecursiveProperties props = mergeIsTypeExpansionSensitive(isSensitive, - RecursiveProperties::forRawPointer()); - return asImpl().handleTrivial(type, props); - } - RetTy visitBuiltinUnsafeValueBufferType( CanBuiltinUnsafeValueBufferType type, AbstractionPattern origType, diff --git a/lib/SIL/Utils/SILBridging.cpp b/lib/SIL/Utils/SILBridging.cpp index 536a6c62300..fe1d1115dc0 100644 --- a/lib/SIL/Utils/SILBridging.cpp +++ b/lib/SIL/Utils/SILBridging.cpp @@ -371,12 +371,6 @@ SwiftInt SILType_isReferenceCounted(BridgedType type, BridgedFunction function) return castToSILType(type).isReferenceCounted(f->getModule()) ? 1 : 0; } -SwiftInt SILType_isNonTrivialOrContainsRawPointer(BridgedType type, - BridgedFunction function) { - SILFunction *f = castToFunction(function); - return castToSILType(type).isNonTrivialOrContainsRawPointer(*f); -} - SwiftInt SILType_isNominal(BridgedType type) { return castToSILType(type).getNominalOrBoundGenericNominal() ? 1 : 0; } diff --git a/lib/SILOptimizer/PassManager/PassPipeline.cpp b/lib/SILOptimizer/PassManager/PassPipeline.cpp index 25062234b46..a71eb48c5fb 100644 --- a/lib/SILOptimizer/PassManager/PassPipeline.cpp +++ b/lib/SILOptimizer/PassManager/PassPipeline.cpp @@ -618,7 +618,6 @@ static void addHighLevelFunctionPipeline(SILPassPipelinePlan &P) { addHighLevelLoopOptPasses(P); P.addStringOptimization(); - P.addComputeEffects(); } // After "high-level" function passes have processed the entire call tree, run @@ -633,7 +632,6 @@ static void addHighLevelModulePipeline(SILPassPipelinePlan &P) { // Do the first stack promotion on high-level SIL before serialization. // // FIXME: why does StackPromotion need to run in the module pipeline? - P.addComputeEffects(); P.addStackPromotion(); P.addGlobalOpt(); @@ -670,10 +668,6 @@ static void addClosureSpecializePassPipeline(SILPassPipelinePlan &P) { P.addSILCombine(); P.addPerformanceConstantPropagation(); P.addSimplifyCFG(); - - // ComputeEffects should be done at the end of a function-pipeline. The next - // pass (GlobalOpt) is a module pass, so this is the end of a function-pipeline. - P.addComputeEffects(); // Hoist globals out of loops. // Global-init functions should not be inlined GlobalOpt is done. @@ -704,8 +698,6 @@ static void addClosureSpecializePassPipeline(SILPassPipelinePlan &P) { // passes can expose more inlining opportunities. addSimplifyCFGSILCombinePasses(P); - P.addComputeEffects(); - // We do this late since it is a pass like the inline caches that we only want // to run once very late. Make sure to run at least one round of the ARC // optimizer after this. @@ -725,7 +717,6 @@ static void addLowLevelPassPipeline(SILPassPipelinePlan &P) { // We've done a lot of optimizations on this function, attempt to FSO. P.addFunctionSignatureOpts(); - P.addComputeEffects(); } static void addLateLoopOptPassPipeline(SILPassPipelinePlan &P) { @@ -754,7 +745,6 @@ static void addLateLoopOptPassPipeline(SILPassPipelinePlan &P) { // Sometimes stack promotion can catch cases only at this late stage of the // pipeline, after FunctionSignatureOpts. - P.addComputeEffects(); P.addStackPromotion(); // Optimize overflow checks. diff --git a/test/DebugInfo/optimizer_pipeline.swift b/test/DebugInfo/optimizer_pipeline.swift index 05984193ded..8fc154d566a 100644 --- a/test/DebugInfo/optimizer_pipeline.swift +++ b/test/DebugInfo/optimizer_pipeline.swift @@ -10,7 +10,7 @@ import Swift // CHECK: sil_scope [[S1:[0-9]+]] { {{.*}} parent @$s18optimizer_pipeline1AVyACs13KeyValuePairsVyypypGcfC // CHECK: sil_scope [[S2:[0-9]+]] { {{.*}} parent [[S1]] } // -// CHECK-LABEL: sil {{.*}}@$s18optimizer_pipeline1AVyACs13KeyValuePairsVyypypGcfC : $@convention(method) (@owned KeyValuePairs, @thin A.Type) -> A { +// CHECK-LABEL: sil @$s18optimizer_pipeline1AVyACs13KeyValuePairsVyypypGcfC : $@convention(method) (@owned KeyValuePairs, @thin A.Type) -> A { // CHECK: bb0(%0 : $KeyValuePairs, %1 : $@thin A.Type): // CHECK: unreachable , scope [[S2]] // CHECK-LABEL: } // end sil function '$s18optimizer_pipeline1AVyACs13KeyValuePairsVyypypGcfC' diff --git a/test/SIL/Parser/default_witness_tables.sil b/test/SIL/Parser/default_witness_tables.sil index 72994a979fa..fad6be47634 100644 --- a/test/SIL/Parser/default_witness_tables.sil +++ b/test/SIL/Parser/default_witness_tables.sil @@ -15,7 +15,7 @@ public protocol ResilientProtocol { func defaultE() } -// CHECK-LABEL: sil {{.*}}@defaultC : $@convention(witness_method: ResilientProtocol) (@in_guaranteed Self) -> () +// CHECK-LABEL: sil @defaultC : $@convention(witness_method: ResilientProtocol) (@in_guaranteed Self) -> () sil @defaultC : $@convention(witness_method: ResilientProtocol) (@in_guaranteed Self) -> () { bb0(%0 : $*Self): %result = tuple () @@ -23,7 +23,7 @@ bb0(%0 : $*Self): } -// CHECK-LABEL: sil {{.*}}@defaultD : $@convention(witness_method: ResilientProtocol) (@in_guaranteed Self) -> () +// CHECK-LABEL: sil @defaultD : $@convention(witness_method: ResilientProtocol) (@in_guaranteed Self) -> () sil @defaultD : $@convention(witness_method: ResilientProtocol) (@in_guaranteed Self) -> () { bb0(%0 : $*Self): %result = tuple () @@ -39,7 +39,7 @@ protocol InternalProtocol { func defaultF() } -// CHECK-LABEL: sil hidden {{.*}}@defaultF +// CHECK-LABEL: sil hidden @defaultF sil hidden @defaultF : $@convention(witness_method: InternalProtocol) (@in_guaranteed Self) -> () { bb0(%0 : $*Self): %result = tuple () diff --git a/test/SIL/Serialization/function_param_convention.sil b/test/SIL/Serialization/function_param_convention.sil index 133e0cdbd79..82a5f27d3e3 100644 --- a/test/SIL/Serialization/function_param_convention.sil +++ b/test/SIL/Serialization/function_param_convention.sil @@ -6,7 +6,7 @@ import Swift import FunctionInput // Make sure we can deserialize a SIL function with these various attributes. -// CHECK: sil public_external [serialized] {{.*}}[canonical] @foo : $@convention(thin) (@in X, @inout X, @in_guaranteed X, @owned X, X, @guaranteed X) -> @out X { +// CHECK: sil public_external [serialized] [canonical] @foo : $@convention(thin) (@in X, @inout X, @in_guaranteed X, @owned X, X, @guaranteed X) -> @out X { sil @foo : $@convention(thin) (@in X, @inout X, @in_guaranteed X, @owned X, X, @guaranteed X) -> @out X diff --git a/test/SIL/Serialization/perf_inline_without_inline_all.swift b/test/SIL/Serialization/perf_inline_without_inline_all.swift index 8b3baea18ac..ceb1e24bc44 100644 --- a/test/SIL/Serialization/perf_inline_without_inline_all.swift +++ b/test/SIL/Serialization/perf_inline_without_inline_all.swift @@ -6,7 +6,7 @@ import Swift // Make sure we inline everything. -// CHECK-LABEL: sil {{.*}}@main +// CHECK-LABEL: sil @main // CHECK: bb0({{.*}}): // CHECK-NEXT: alloc_global // CHECK-NEXT: global_addr diff --git a/test/SIL/Serialization/specializer_can_deserialize.swift b/test/SIL/Serialization/specializer_can_deserialize.swift index bd60c0f440c..9ff5f01bb41 100644 --- a/test/SIL/Serialization/specializer_can_deserialize.swift +++ b/test/SIL/Serialization/specializer_can_deserialize.swift @@ -6,7 +6,7 @@ import Swift // Make sure the specializer can deserialize code. -// CHECK-LABEL: sil {{.*}}@main +// CHECK-LABEL: sil @main // CHECK: bb0({{.*}}): // CHECK: function_ref @$ss9ContainerVAByxGycfCBi32__Tg5{{.*}} // CHECK: function_ref @$ss9ContainerV11doSomethingyyFBi32__Tg5{{.*}} diff --git a/test/SILGen/copy_operator.swift b/test/SILGen/copy_operator.swift index e6abe1f1b74..a415748fa6a 100644 --- a/test/SILGen/copy_operator.swift +++ b/test/SILGen/copy_operator.swift @@ -50,7 +50,7 @@ class Klass {} // CHECK-SIL-NEXT: return [[VALUE]] : $Klass // CHECK-SIL: } // end sil function '$s8moveonly7useCopyyAA5KlassCADF' -// CHECK-SIL-OPT-LABEL: sil {{.*}}@$s8moveonly7useCopyyAA5KlassCADF : $@convention(thin) (@guaranteed Klass) -> @owned Klass { +// CHECK-SIL-OPT-LABEL: sil @$s8moveonly7useCopyyAA5KlassCADF : $@convention(thin) (@guaranteed Klass) -> @owned Klass { // CHECK-SIL-OPT: bb0([[ARG:%.*]] : $Klass): // CHECK-SIL-OPT-NEXT: debug_value // CHECK-SIL-OPT-NEXT: strong_retain [[ARG]] @@ -91,7 +91,7 @@ public func useCopy(_ k: Klass) -> Klass { // CHECK-SIL-NEXT: return [[VALUE]] : $T // CHECK-SIL: } // end sil function '$s8moveonly7useCopyyxxRlzClF' -// CHECK-SIL-OPT-LABEL: sil {{.*}}@$s8moveonly7useCopyyxxRlzClF : $@convention(thin) (@guaranteed T) -> @owned T { +// CHECK-SIL-OPT-LABEL: sil @$s8moveonly7useCopyyxxRlzClF : $@convention(thin) (@guaranteed T) -> @owned T { // CHECK-SIL-OPT: bb0([[ARG:%.*]] : // CHECK-SIL-OPT-NEXT: debug_value // CHECK-SIL-OPT-NEXT: strong_retain [[ARG]] diff --git a/test/SILGen/deinit_in_vtable.swift b/test/SILGen/deinit_in_vtable.swift index 9730cec7e21..4cd2af3b4af 100644 --- a/test/SILGen/deinit_in_vtable.swift +++ b/test/SILGen/deinit_in_vtable.swift @@ -8,14 +8,14 @@ private class A { } // CHECK-LABEL: deinit_in_vtable.(A in {{.*}}).__deallocating_deinit -// CHECK: sil private {{.*}}@[[A:.*]] : +// CHECK: sil private @[[A:.*]] : private class B : A { override func foo() -> Int { return 1 } } // CHECK-LABEL: deinit_in_vtable.(B in {{.*}}).__deallocating_deinit -// CHECK: sil private {{.*}}@[[B:.*]] : +// CHECK: sil private @[[B:.*]] : @inline(never) private func testfunc(_ a: A) -> Int { diff --git a/test/SILGen/global_resilience.swift b/test/SILGen/global_resilience.swift index 1d0902bae70..2f5ea45c549 100644 --- a/test/SILGen/global_resilience.swift +++ b/test/SILGen/global_resilience.swift @@ -52,7 +52,7 @@ public var myEmptyGlobal = MyEmptyStruct() // CHECK: global_addr @$s17global_resilience19myFixedLayoutGlobalAA13MyEmptyStructVv // CHECK: return -// CHECK-OPT-LABEL: sil private [global_init_once_fn] {{.*}}@{{.*}}WZ +// CHECK-OPT-LABEL: sil private [global_init_once_fn] @{{.*}}WZ // CHECK-OPT: alloc_global @$s17global_resilience19myFixedLayoutGlobalAA13MyEmptyStructVv // CHECK-OPT: return diff --git a/test/SILGen/specialize_attr.swift b/test/SILGen/specialize_attr.swift index 3fb19f220c7..2fa6b3d8cee 100644 --- a/test/SILGen/specialize_attr.swift +++ b/test/SILGen/specialize_attr.swift @@ -136,11 +136,11 @@ public struct CC2 { // CHECK-LABEL: sil [_specialize exported: false, kind: full, where T == Klass1, U == FakeString] [_specialize exported: false, kind: full, where T == Int, U == Float] [ossa] @$s15specialize_attr0A4This_1uyx_q_tr0_lF : $@convention(thin) (@in_guaranteed T, @in_guaranteed U) -> () { -// CHECK-OPT-DAG: sil shared [noinline] {{.*}}@$s15specialize_attr2CCC3foo_1gqd___AA2GGVyxGtqd___AHtAA2QQRd__lFAA12RRNonTrivialV_AA05SSNonH0VTg5 : $@convention(method) (@guaranteed SSNonTrivial, @guaranteed GG, @guaranteed CC) -> (@owned SSNonTrivial, @out GG) { +// CHECK-OPT-DAG: sil shared [noinline] @$s15specialize_attr2CCC3foo_1gqd___AA2GGVyxGtqd___AHtAA2QQRd__lFAA12RRNonTrivialV_AA05SSNonH0VTg5 : $@convention(method) (@guaranteed SSNonTrivial, @guaranteed GG, @guaranteed CC) -> (@owned SSNonTrivial, @out GG) { -// CHECK-OPT-DAG: sil shared [noinline] {{.*}}@$s15specialize_attr2CCC4foo2_1gqd___AA2GGVyxGtqd__n_AHntAA2QQRd__lFAA2RRV_AA2SSVTg5 : $@convention(method) (SS, GG, @guaranteed CC) -> (SS, @out GG) { +// CHECK-OPT-DAG: sil shared [noinline] @$s15specialize_attr2CCC4foo2_1gqd___AA2GGVyxGtqd__n_AHntAA2QQRd__lFAA2RRV_AA2SSVTg5 : $@convention(method) (SS, GG, @guaranteed CC) -> (SS, @out GG) { -// CHECK-OPT-DAG: sil [noinline] {{.*}}@$s15specialize_attr2CCC4foo2_1gqd___AA2GGVyxGtqd__n_AHntAA2QQRd__lF : $@convention(method) (@in U, @in GG, @guaranteed CC) -> (@out U, @out GG) { +// CHECK-OPT-DAG: sil [noinline] @$s15specialize_attr2CCC4foo2_1gqd___AA2GGVyxGtqd__n_AHntAA2QQRd__lF : $@convention(method) (@in U, @in GG, @guaranteed CC) -> (@out U, @out GG) { // CHECK-LABEL: sil [noinline] [_specialize exported: false, kind: full, where T == RRNonTrivial, U == SSNonTrivial] [_specialize exported: false, kind: full, where T == RR, U == SS] [ossa] @$s15specialize_attr2CCC3foo_1gqd___AA2GGVyxGtqd___AHtAA2QQRd__lF : $@convention(method) (@in_guaranteed U, @in_guaranteed GG, @guaranteed CC) -> (@out U, @out GG) { @@ -279,7 +279,7 @@ extension InternalThing2 { public var specializeComputedX : T { // CHECK-LABEL: sil [_specialize exported: true, kind: full, target: "$s1A14InternalThing2V9computedXxvg", where T == Klass1] [ossa] @$s1A14InternalThing2V15specialize_attrE0C9ComputedXxvg : $@convention(method) (@in_guaranteed InternalThing2) -> @out T { - // CHECK-OPT-DAG: sil {{.*}}@$s1A14InternalThing2V9computedXxvg15specialize_attr6Klass1C_Ts5 : $@convention(method) (@guaranteed InternalThing2) -> @owned Klass1 { + // CHECK-OPT-DAG: sil @$s1A14InternalThing2V9computedXxvg15specialize_attr6Klass1C_Ts5 : $@convention(method) (@guaranteed InternalThing2) -> @owned Klass1 { @_specialize(exported: true, target: computedX, where T == Klass1) get { @@ -290,7 +290,7 @@ extension InternalThing2 { public var specializeComputedY : T { // CHECK-LABEL: sil [_specialize exported: true, kind: full, target: "$s1A14InternalThing2V9computedYxvg", where T == Klass1] [ossa] @$s1A14InternalThing2V15specialize_attrE0C9ComputedYxvg : $@convention(method) (@in_guaranteed InternalThing2) -> @out T { - // CHECK-OPT-DAG: sil {{.*}}@$s1A14InternalThing2V9computedYxvg15specialize_attr6Klass1C_Ts5 : $@convention(method) (@guaranteed InternalThing2) -> @owned Klass1 { + // CHECK-OPT-DAG: sil @$s1A14InternalThing2V9computedYxvg15specialize_attr6Klass1C_Ts5 : $@convention(method) (@guaranteed InternalThing2) -> @owned Klass1 { @_specialize(exported: true, target: computedY, where T == Klass1) get { @@ -298,7 +298,7 @@ extension InternalThing2 { } // CHECK-LABEL: sil [_specialize exported: true, kind: full, target: "$s1A14InternalThing2V9computedYxvs", where T == Klass1] [ossa] @$s1A14InternalThing2V15specialize_attrE0C9ComputedYxvs : $@convention(method) (@in T, @inout InternalThing2) -> () { - // CHECK-OPT-DAG: sil {{.*}}@$s1A14InternalThing2V9computedYxvs15specialize_attr6Klass1C_Ts5 : $@convention(method) (@owned Klass1, @inout InternalThing2) -> () { + // CHECK-OPT-DAG: sil @$s1A14InternalThing2V9computedYxvs15specialize_attr6Klass1C_Ts5 : $@convention(method) (@owned Klass1, @inout InternalThing2) -> () { @_specialize(exported: true, target: computedY, where T == Klass1) set {} @@ -326,7 +326,7 @@ extension InternalThing2 { public subscript(specialized i: Int) -> T { // CHECK-LABEL: sil [_specialize exported: true, kind: full, target: "$s1A14InternalThing2VyxSicig", where T == Klass1] [ossa] @$s1A14InternalThing2V15specialize_attrE11specializedxSi_tcig : $@convention(method) (Int, @in_guaranteed InternalThing2) -> @out T { - // CHECK-OPT-DAG: sil {{.*}}@$s1A14InternalThing2VyxSicig15specialize_attr6Klass1C_Ts5 : $@convention(method) (Int, @guaranteed InternalThing2) -> @owned Klass1 { + // CHECK-OPT-DAG: sil @$s1A14InternalThing2VyxSicig15specialize_attr6Klass1C_Ts5 : $@convention(method) (Int, @guaranteed InternalThing2) -> @owned Klass1 { @_specialize(exported: true, target: subscript(_:), where T == Klass1) get { @@ -334,7 +334,7 @@ extension InternalThing2 { } // CHECK-LABEL: sil [_specialize exported: true, kind: full, target: "$s1A14InternalThing2VyxSicis", where T == Klass1] [ossa] @$s1A14InternalThing2V15specialize_attrE11specializedxSi_tcis : $@convention(method) (@in T, Int, @inout InternalThing2) -> () { - // CHECK-OPT-DAG: sil {{.*}}@$s1A14InternalThing2VyxSicis15specialize_attr6Klass1C_Ts5 : $@convention(method) (@owned Klass1, Int, @inout InternalThing2) -> () { + // CHECK-OPT-DAG: sil @$s1A14InternalThing2VyxSicis15specialize_attr6Klass1C_Ts5 : $@convention(method) (@owned Klass1, Int, @inout InternalThing2) -> () { @_specialize(exported: true, target: subscript(_:), where T == Klass1) set { diff --git a/test/SILGen/unsafevalue.swift b/test/SILGen/unsafevalue.swift index 4ca0018add2..e2ea2d598f8 100644 --- a/test/SILGen/unsafevalue.swift +++ b/test/SILGen/unsafevalue.swift @@ -96,7 +96,7 @@ public struct UnsafeValue { // CANONICAL: apply [[CLOSURE]]([[RESULT]], [[GUARANTEED_REF_DEP_ON_BASE]]) // CANONICAL: } // end sil function '$s11unsafevalue11UnsafeValueV20withGuaranteeingBase4base_qd_0_qd___qd_0_xXEtr0_lF' // - // OPT-LABEL: sil [transparent] {{.*}}@$s11unsafevalue11UnsafeValueV20withGuaranteeingBase4base_qd_0_qd___qd_0_xXEtr0_lF : + // OPT-LABEL: sil [transparent] @$s11unsafevalue11UnsafeValueV20withGuaranteeingBase4base_qd_0_qd___qd_0_xXEtr0_lF : // OPT: bb0([[RESULT:%.*]] : $*Result, [[BASE:%.*]] : $*Base, [[CLOSURE:%.*]] : $@noescape @callee_guaranteed {{.*}}, [[UNSAFE_VALUE:%.*]] : $UnsafeValue): // OPT: [[UNMANAGED_VALUE:%.*]] = struct_extract [[UNSAFE_VALUE]] // OPT: [[UNOWNED_REF:%.*]] = unmanaged_to_ref [[UNMANAGED_VALUE]] diff --git a/test/SILOptimizer/access_wmo.swift b/test/SILOptimizer/access_wmo.swift index 7c640ca1abd..9b59d1df0d1 100644 --- a/test/SILOptimizer/access_wmo.swift +++ b/test/SILOptimizer/access_wmo.swift @@ -163,7 +163,7 @@ public func testAccessProp(c: C, v: Int) { // PRIMARY-NOT: begin_{{.*}}access // PRIMARY-LABEL: } // end sil function '$s10access_wmo8readProp1cSiAA1CC_tF' // -// WMO-LABEL: sil {{.*}}@$s10access_wmo8readProp1cSiAA1CC_tF : $@convention(thin) (@guaranteed C) -> Int { +// WMO-LABEL: sil @$s10access_wmo8readProp1cSiAA1CC_tF : $@convention(thin) (@guaranteed C) -> Int { // WMO: [[E1:%.*]] = ref_element_addr %0 : $C, #C.setterProp // WMO: [[A1:%.*]] = begin_access [read] [static] [no_nested_conflict] [[E1]] : $*Int // WMO: end_access [[A1]] : $*Int diff --git a/test/SILOptimizer/addr_escape_info.sil b/test/SILOptimizer/addr_escape_info.sil deleted file mode 100644 index 15cedc2f9c7..00000000000 --- a/test/SILOptimizer/addr_escape_info.sil +++ /dev/null @@ -1,497 +0,0 @@ -// RUN: %target-sil-opt %s -dump-addr-escape-info -o /dev/null | %FileCheck %s - -// REQUIRES: swift_in_compiler - -sil_stage canonical - -import Builtin -import Swift -import SwiftShims - -struct Str { - @_hasStorage var a: Int - @_hasStorage var b: Int -} - -class X { - @_hasStorage var s: Str -} - -struct Container { - @_hasStorage var x: X -} - -struct XandInt { - @_hasStorage var x: X - @_hasStorage var i: Int -} - -class XandIntClass { - @_hasStorage var x: X - @_hasStorage var i: Int -} - -sil @no_arguments : $@convention(thin) () -> () -sil @indirect_argument : $@convention(thin) (@in Int) -> () -sil @indirect_struct_argument : $@convention(thin) (@in Str) -> () -sil @direct_argument : $@convention(thin) (Int) -> () -sil @class_argument : $@convention(thin) (@guaranteed X) -> () -sil [escapes !%0] @non_escaping_class_argument : $@convention(thin) (@guaranteed X) -> () -sil [escapes !%0.**] @inout_class_argument : $@convention(thin) (@inout X) -> () -sil @container_argument : $@convention(thin) (@guaranteed Container) -> () -sil @take_closure_as_addr : $@convention(thin) (@in @callee_guaranteed () -> ()) -> () -sil [escapes !%0.**] @closure_with_inout : $@convention(thin) (@inout Str) -> () - -// CHECK-LABEL: Address escape information for test_simple: -// CHECK: value: %1 = struct_element_addr %0 : $*Str, #Str.a -// CHECK-NEXT: ==> %7 = apply %6(%5) : $@convention(thin) (@in Int) -> () -// CHECK-NEXT: - %10 = apply %8(%9) : $@convention(thin) (Int) -> () -// CHECK: value: %3 = struct_element_addr %0 : $*Str, #Str.b -// CHECK-NEXT: - %7 = apply %6(%5) : $@convention(thin) (@in Int) -> () -// CHECK-NEXT: - %10 = apply %8(%9) : $@convention(thin) (Int) -> () -// CHECK: pair 0 - 1 -// CHECK-NEXT: %1 = struct_element_addr %0 : $*Str, #Str.a -// CHECK-NEXT: %3 = struct_element_addr %0 : $*Str, #Str.b -// CHECK-NEXT: no alias -// CHECK: End function test_simple -sil @test_simple : $@convention(thin) () -> () { -bb0: - %0 = alloc_stack $Str - %1 = struct_element_addr %0 : $*Str, #Str.a - fix_lifetime %1 : $*Int - %3 = struct_element_addr %0 : $*Str, #Str.b - fix_lifetime %3 : $*Int - %5 = struct_element_addr %0 : $*Str, #Str.a - %6 = function_ref @indirect_argument : $@convention(thin) (@in Int) -> () - %7 = apply %6(%5) : $@convention(thin) (@in Int) -> () - %8 = function_ref @direct_argument : $@convention(thin) (Int) -> () - %9 = load %3 : $*Int - %10 = apply %8(%9) : $@convention(thin) (Int) -> () - dealloc_stack %0 : $*Str - %12 = tuple () - return %12 : $() -} - -// CHECK-LABEL: Address escape information for test_class: -// CHECK: value: %0 = alloc_ref $X -// CHECK-NEXT: ==> %11 = apply %10(%0) : $@convention(thin) (@guaranteed X) -> () -// CHECK: value: %2 = struct_element_addr %1 : $*Str, #Str.a -// CHECK-NEXT: ==> %11 = apply %10(%0) : $@convention(thin) (@guaranteed X) -> () -// CHECK: value: %5 = alloc_ref $X -// CHECK-NEXT: - %11 = apply %10(%0) : $@convention(thin) (@guaranteed X) -> () -// CHECK: value: %7 = struct_element_addr %6 : $*Str, #Str.a -// CHECK-NEXT: - %11 = apply %10(%0) : $@convention(thin) (@guaranteed X) -> () -// CHECK: pair 0 - 1 -// CHECK-NEXT: %0 = alloc_ref $X -// CHECK-NEXT: %2 = struct_element_addr %1 : $*Str, #Str.a -// CHECK-NEXT: may alias -// CHECK: pair 0 - 2 -// CHECK-NEXT: %0 = alloc_ref $X -// CHECK-NEXT: %5 = alloc_ref $X -// CHECK-NEXT: no alias -// CHECK: pair 0 - 3 -// CHECK-NEXT: %0 = alloc_ref $X -// CHECK-NEXT: %7 = struct_element_addr %6 : $*Str, #Str.a -// CHECK-NEXT: no alias -// CHECK: pair 1 - 2 -// CHECK-NEXT: %2 = struct_element_addr %1 : $*Str, #Str.a -// CHECK-NEXT: %5 = alloc_ref $X -// CHECK-NEXT: no alias -// CHECK: pair 1 - 3 -// CHECK-NEXT: %2 = struct_element_addr %1 : $*Str, #Str.a -// CHECK-NEXT: %7 = struct_element_addr %6 : $*Str, #Str.a -// CHECK-NEXT: no alias -// CHECK: pair 2 - 3 -// CHECK-NEXT: %5 = alloc_ref $X -// CHECK-NEXT: %7 = struct_element_addr %6 : $*Str, #Str.a -// CHECK-NEXT: may alias -// CHECK: End function test_class -sil @test_class : $@convention(thin) () -> X { -bb0: - %0 = alloc_ref $X - %1 = ref_element_addr %0 : $X, #X.s - %2 = struct_element_addr %1 : $*Str, #Str.a - fix_lifetime %0 : $X - fix_lifetime %2 : $*Int - %5 = alloc_ref $X - %6 = ref_element_addr %5 : $X, #X.s - %7 = struct_element_addr %6 : $*Str, #Str.a - fix_lifetime %5 : $X - fix_lifetime %7 : $*Int - %10 = function_ref @class_argument : $@convention(thin) (@guaranteed X) -> () - %11 = apply %10(%0) : $@convention(thin) (@guaranteed X) -> () - return %5 : $X -} - -// CHECK-LABEL: Address escape information for test_struct_with_class: -// CHECK: value: %1 = struct $Container (%0 : $X) -// CHECK-NEXT: ==> %7 = apply %6(%1) : $@convention(thin) (@guaranteed Container) -> () -// CHECK: value: %4 = struct $Container (%3 : $X) -// CHECK-NEXT: - %7 = apply %6(%1) : $@convention(thin) (@guaranteed Container) -> () -// CHECK: End function test_struct_with_class -sil @test_struct_with_class : $@convention(thin) () -> Container { -bb0: - %0 = alloc_ref $X - %1 = struct $Container (%0 : $X) - fix_lifetime %1 : $Container - %3 = alloc_ref $X - %4 = struct $Container (%3 : $X) - fix_lifetime %4 : $Container - %6 = function_ref @container_argument : $@convention(thin) (@guaranteed Container) -> () - %10 = apply %6(%1) : $@convention(thin) (@guaranteed Container) -> () - return %4 : $Container -} - -// CHECK-LABEL: Address escape information for ignore_indirect_arg_of_other_call: -// CHECK: value: %1 = ref_element_addr %0 : $X, #X.s -// CHECK-NEXT: ==> %5 = apply %4(%3) : $@convention(thin) (@in Int) -> () -// CHECK-NEXT: - %7 = apply %6() : $@convention(thin) () -> () -// CHECK: End function ignore_indirect_arg_of_other_call -sil @ignore_indirect_arg_of_other_call : $@convention(thin) () -> () { -bb0: - %0 = alloc_ref $X - %1 = ref_element_addr %0 : $X, #X.s - fix_lifetime %1 : $*Str - %3 = struct_element_addr %1 : $*Str, #Str.a - %4 = function_ref @indirect_argument : $@convention(thin) (@in Int) -> () - %5 = apply %4(%3) : $@convention(thin) (@in Int) -> () - %6 = function_ref @no_arguments : $@convention(thin) () -> () - %7 = apply %6() : $@convention(thin) () -> () - %8 = tuple () - return %8 : $() -} - -// CHECK-LABEL: Address escape information for dont_ignore_direct_arg_of_other_call: -// CHECK: value: %1 = ref_element_addr %0 : $X, #X.s -// CHECK-NEXT: ==> %4 = apply %3(%0) : $@convention(thin) (@guaranteed X) -> () -// CHECK-NEXT: ==> %6 = apply %5() : $@convention(thin) () -> () -// CHECK: End function dont_ignore_direct_arg_of_other_call -sil @dont_ignore_direct_arg_of_other_call : $@convention(thin) () -> () { -bb0: - %0 = alloc_ref $X - %1 = ref_element_addr %0 : $X, #X.s - fix_lifetime %1 : $*Str - %3 = function_ref @class_argument : $@convention(thin) (@guaranteed X) -> () - %4 = apply %3(%0) : $@convention(thin) (@guaranteed X) -> () - %5 = function_ref @no_arguments : $@convention(thin) () -> () - %6 = apply %5() : $@convention(thin) () -> () - %7 = tuple () - return %7 : $() -} - -// CHECK-LABEL: Address escape information for ignore_non_escaping_arg_of_other_call: -// CHECK: value: %1 = ref_element_addr %0 : $X, #X.s -// CHECK-NEXT: ==> %4 = apply %3(%0) : $@convention(thin) (@guaranteed X) -> () -// CHECK-NEXT: - %6 = apply %5() : $@convention(thin) () -> () -// CHECK: End function ignore_non_escaping_arg_of_other_call -sil @ignore_non_escaping_arg_of_other_call : $@convention(thin) () -> () { -bb0: - %0 = alloc_ref $X - %1 = ref_element_addr %0 : $X, #X.s - fix_lifetime %1 : $*Str - %3 = function_ref @non_escaping_class_argument : $@convention(thin) (@guaranteed X) -> () - %4 = apply %3(%0) : $@convention(thin) (@guaranteed X) -> () - %5 = function_ref @no_arguments : $@convention(thin) () -> () - %6 = apply %5() : $@convention(thin) () -> () - %7 = tuple () - return %7 : $() -} - -// CHECK-LABEL: Address escape information for dont_ignore_non_escaping_arg_of_other_call_if_followstores: -// CHECK: value: %7 = ref_element_addr %6 : $X, #X.s -// CHECK-NEXT: ==> %5 = apply %4(%1) : $@convention(thin) (@inout X) -> () -// CHECK-NEXT: ==> %10 = apply %9() : $@convention(thin) () -> () -// CHECK: End function dont_ignore_non_escaping_arg_of_other_call_if_followstores -sil @dont_ignore_non_escaping_arg_of_other_call_if_followstores : $@convention(thin) () -> () { -bb0: - %0 = alloc_ref $X - %1 = alloc_stack $X - store %0 to %1 : $*X - %3 = alloc_ref $X - %4 = function_ref @inout_class_argument : $@convention(thin) (@inout X) -> () - %5 = apply %4(%1) : $@convention(thin) (@inout X) -> () - %6 = load %1 : $*X - %7 = ref_element_addr %6 : $X, #X.s - fix_lifetime %7 : $*Str - %9 = function_ref @no_arguments : $@convention(thin) () -> () - %10 = apply %9() : $@convention(thin) () -> () - dealloc_stack %1 : $*X - %12 = tuple () - return %12 : $() -} - -// CHECK-LABEL: Address escape information for ignore_copy_addr_and_release: -// CHECK: value: %1 = ref_element_addr %0 : $X, #X.s -// CHECK-NEXT: - %6 = apply %5(%3) : $@convention(thin) (@in Str) -> () -// CHECK: End function ignore_copy_addr_and_release -sil @ignore_copy_addr_and_release : $@convention(thin) () -> () { -bb0: - %0 = alloc_ref $X - %1 = ref_element_addr %0 : $X, #X.s - fix_lifetime %1 : $*Str - %3 = alloc_stack $Str - copy_addr %1 to [initialization] %3 : $*Str - %5 = function_ref @indirect_struct_argument : $@convention(thin) (@in Str) -> () - %6 = apply %5(%3) : $@convention(thin) (@in Str) -> () - strong_release %0 : $X - dealloc_stack %3 : $*Str - %9 = tuple () - return %9 : $() -} - -// CHECK-LABEL: Address escape information for non_aliased_addr_arg: -// CHECK: value:%0 = argument of bb0 : $*Int -// CHECK-NEXT: - %3 = apply %2() : $@convention(thin) () -> () -// CHECK: End function non_aliased_addr_arg -sil @non_aliased_addr_arg : $@convention(thin) (@inout Int) -> () { -bb0(%0 : $*Int): - fix_lifetime %0 : $*Int - %2 = function_ref @no_arguments : $@convention(thin) () -> () - %3 = apply %2() : $@convention(thin) () -> () - %4 = tuple () - return %4 : $() -} - -// CHECK-LABEL: Address escape information for aliased_addr_arg: -// CHECK: value:%0 = argument of bb0 : $*Int -// CHECK-NEXT: ==> %3 = apply %2() : $@convention(thin) () -> () -// CHECK: End function aliased_addr_arg -sil @aliased_addr_arg : $@convention(thin) (@inout_aliasable Int) -> () { -bb0(%0 : $*Int): - fix_lifetime %0 : $*Int - %2 = function_ref @no_arguments : $@convention(thin) () -> () - %3 = apply %2() : $@convention(thin) () -> () - %4 = tuple () - return %4 : $() -} - -// CHECK-LABEL: Address escape information for adddr_arg_with_aliased_content: -// CHECK: value: %2 = ref_element_addr %1 : $X, #X.s -// CHECK-NEXT: ==> %5 = apply %4() : $@convention(thin) () -> () -// CHECK: End function adddr_arg_with_aliased_content -sil @adddr_arg_with_aliased_content : $@convention(thin) (@inout X) -> () { -bb0(%0 : $*X): - %1 = load %0 : $*X - %2 = ref_element_addr %1 : $X, #X.s - fix_lifetime %2 : $*Str - %4 = function_ref @no_arguments : $@convention(thin) () -> () - %5 = apply %4() : $@convention(thin) () -> () - %6 = tuple () - return %6 : $() -} - -// CHECK-LABEL: Address escape information for pointer_arg: -// CHECK: value: %1 = pointer_to_address %0 : $Builtin.RawPointer to [strict] $*Str -// CHECK-NEXT: ==> %4 = apply %3() : $@convention(thin) () -> () -// CHECK: End function pointer_arg -sil @pointer_arg : $@convention(thin) (Builtin.RawPointer) -> () { -bb0(%0 : $Builtin.RawPointer): - %1 = pointer_to_address %0 : $Builtin.RawPointer to [strict] $*Str - fix_lifetime %1 : $*Str - %3 = function_ref @no_arguments : $@convention(thin) () -> () - %4 = apply %3() : $@convention(thin) () -> () - %5 = tuple () - return %5 : $() -} - -// CHECK-LABEL: Address escape information for follow_stores_to_arg: -// CHECK: value: %2 = pointer_to_address %1 : $Builtin.RawPointer to [strict] $*Str -// CHECK-NEXT: ==> %5 = apply %4() : $@convention(thin) () -> () -// CHECK: End function follow_stores_to_arg -sil @follow_stores_to_arg : $@convention(thin) (@inout Builtin.RawPointer) -> () { -bb0(%0 : $*Builtin.RawPointer): - %1 = load %0 : $*Builtin.RawPointer - %2 = pointer_to_address %1 : $Builtin.RawPointer to [strict] $*Str - fix_lifetime %2 : $*Str - %4 = function_ref @no_arguments : $@convention(thin) () -> () - %5 = apply %4() : $@convention(thin) () -> () - %6 = tuple () - return %6 : $() -} - - -// CHECK-LABEL: Address escape information for partial_apply: -// CHECK: value: %0 = alloc_stack $Str -// CHECK-NEXT: - %5 = apply %4() : $@convention(thin) () -> () -// CHECK: End function partial_apply -sil @partial_apply : $@convention(thin) () -> () { -bb0: - %0 = alloc_stack $Str - fix_lifetime %0 : $*Str - %2 = function_ref @closure_with_inout : $@convention(thin) (@inout Str) -> () - %3 = partial_apply [callee_guaranteed] [on_stack] %2(%0) : $@convention(thin) (@inout Str) -> () - %8 = function_ref @no_arguments : $@convention(thin) () -> () - %9 = apply %8() : $@convention(thin) () -> () - dealloc_stack %3 : $@callee_guaranteed @noescape () -> () - dealloc_stack %0 : $*Str - %12 = tuple () - return %12 : $() -} - -// CHECK-LABEL: Address escape information for partial_apply_with_inout: -// CHECK: value: %0 = alloc_stack $Str -// CHECK-NEXT: - %7 = apply %6(%4) : $@convention(thin) (@in @callee_guaranteed () -> ()) -> () -// CHECK-NEXT: - %9 = apply %8() : $@convention(thin) () -> () -// CHECK: End function partial_apply_with_inout -sil @partial_apply_with_inout : $@convention(thin) () -> () { -bb0: - %0 = alloc_stack $Str - fix_lifetime %0 : $*Str - %2 = function_ref @closure_with_inout : $@convention(thin) (@inout Str) -> () - %3 = partial_apply [callee_guaranteed] %2(%0) : $@convention(thin) (@inout Str) -> () - %4 = alloc_stack $@callee_guaranteed () -> () - store %3 to %4 : $*@callee_guaranteed () -> () - %6 = function_ref @take_closure_as_addr : $@convention(thin) (@in @callee_guaranteed () -> ()) -> () - %7 = apply %6(%4) : $@convention(thin) (@in @callee_guaranteed () -> ()) -> () - %8 = function_ref @no_arguments : $@convention(thin) () -> () - %9 = apply %8() : $@convention(thin) () -> () - dealloc_stack %4 : $*@callee_guaranteed () -> () - dealloc_stack %0 : $*Str - %12 = tuple () - return %12 : $() -} - -// CHECK-LABEL: Address escape information for non_escaping_trivial_member: -// CHECK: value: %2 = struct $XandInt (%1 : $X, %0 : $Int) -// CHECK-NEXT: - %8 = apply %7(%6) : $@convention(thin) (@in Int) -> () -// CHECK: End function non_escaping_trivial_member -sil @non_escaping_trivial_member : $@convention(thin) (Int) -> () { -bb0(%0 : $Int): - %1 = alloc_ref $X - %2 = struct $XandInt(%1 : $X, %0 : $Int) - %3 = alloc_stack $XandInt - store %2 to %3 : $*XandInt - fix_lifetime %2 : $XandInt - %6 = struct_element_addr %3 : $*XandInt, #XandInt.i - %7 = function_ref @indirect_argument : $@convention(thin) (@in Int) -> () - %8 = apply %7(%6) : $@convention(thin) (@in Int) -> () - dealloc_stack %3 : $*XandInt - %12 = tuple () - return %12 : $() -} - -// CHECK-LABEL: Address escape information for escaping_nontrivial_member: -// CHECK: value: %2 = struct $XandInt (%1 : $X, %0 : $Int) -// CHECK-NEXT: ==> %8 = apply %7(%6) : $@convention(thin) (@inout X) -> () -// CHECK: End function escaping_nontrivial_member -sil @escaping_nontrivial_member : $@convention(thin) (Int) -> () { -bb0(%0 : $Int): - %1 = alloc_ref $X - %2 = struct $XandInt(%1 : $X, %0 : $Int) - %3 = alloc_stack $XandInt - store %2 to %3 : $*XandInt - fix_lifetime %2 : $XandInt - %6 = struct_element_addr %3 : $*XandInt, #XandInt.x - %7 = function_ref @inout_class_argument : $@convention(thin) (@inout X) -> () - %8 = apply %7(%6) : $@convention(thin) (@inout X) -> () - dealloc_stack %3 : $*XandInt - %10 = tuple () - return %10 : $() -} - -// CHECK-LABEL: Address escape information for escaping_address_in_nontrivial_member: -// CHECK: value: %2 = struct $XandInt (%1 : $X, %0 : $Int) -// CHECK-NEXT: ==> %11 = apply %10(%9) : $@convention(thin) (@in Int) -> () -// CHECK: End function escaping_address_in_nontrivial_member -sil @escaping_address_in_nontrivial_member : $@convention(thin) (Int) -> () { -bb0(%0 : $Int): - %1 = alloc_ref $X - %2 = struct $XandInt(%1 : $X, %0 : $Int) - %3 = alloc_stack $XandInt - store %2 to %3 : $*XandInt - fix_lifetime %2 : $XandInt - %6 = struct_element_addr %3 : $*XandInt, #XandInt.x - %7 = load %6 : $*X - %8 = ref_element_addr %7 : $X, #X.s - %9 = struct_element_addr %8 : $*Str, #Str.a - %10 = function_ref @indirect_argument : $@convention(thin) (@in Int) -> () - %11 = apply %10(%9) : $@convention(thin) (@in Int) -> () - dealloc_stack %3 : $*XandInt - %13 = tuple () - return %13 : $() -} - -// CHECK-LABEL: Address escape information for test_addr_alias1: -// CHECK: pair 0 - 1 -// CHECK-NEXT: %2 = ref_element_addr %0 : $XandIntClass, #XandIntClass.x -// CHECK-NEXT: %4 = ref_element_addr %0 : $XandIntClass, #XandIntClass.i -// CHECK-NEXT: no alias -// CHECK: pair 0 - 2 -// CHECK-NEXT: %2 = ref_element_addr %0 : $XandIntClass, #XandIntClass.x -// CHECK-NEXT: %5 = ref_element_addr %1 : $X, #X.s -// CHECK-NEXT: no alias -// CHECK: pair 0 - 3 -// CHECK-NEXT: %2 = ref_element_addr %0 : $XandIntClass, #XandIntClass.x -// CHECK-NEXT: %6 = struct_element_addr %5 : $*Str, #Str.a -// CHECK-NEXT: no alias -// CHECK: pair 1 - 2 -// CHECK-NEXT: %4 = ref_element_addr %0 : $XandIntClass, #XandIntClass.i -// CHECK-NEXT: %5 = ref_element_addr %1 : $X, #X.s -// CHECK-NEXT: no alias -// CHECK: pair 1 - 3 -// CHECK-NEXT: %4 = ref_element_addr %0 : $XandIntClass, #XandIntClass.i -// CHECK-NEXT: %6 = struct_element_addr %5 : $*Str, #Str.a -// CHECK-NEXT: no alias -// CHECK: pair 2 - 3 -// CHECK-NEXT: %5 = ref_element_addr %1 : $X, #X.s -// CHECK-NEXT: %6 = struct_element_addr %5 : $*Str, #Str.a -// CHECK-NEXT: may alias -// CHECK: End function test_addr_alias1 -sil @test_addr_alias1 : $@convention(thin) () -> () { -bb0: - %0 = alloc_ref $XandIntClass - %1 = alloc_ref $X - %2 = ref_element_addr %0 : $XandIntClass, #XandIntClass.x - store %1 to %2 : $*X - %4 = ref_element_addr %0 : $XandIntClass, #XandIntClass.i - %5 = ref_element_addr %1 : $X, #X.s - %6 = struct_element_addr %5 : $*Str, #Str.a - fix_lifetime %2 : $*X - fix_lifetime %4 : $*Int - fix_lifetime %5 : $*Str - fix_lifetime %6 : $*Int - %11 = tuple () - return %11 : $() -} - -// CHECK-LABEL: Address escape information for test_addr_alias2: -// CHECK: pair 0 - 1 -// CHECK-NEXT: %1 = ref_element_addr %0 : $X, #X.s -// CHECK-NEXT: %2 = struct_element_addr %1 : $*Str, #Str.a -// CHECK-NEXT: may alias -// CHECK: pair 0 - 2 -// CHECK-NEXT: %1 = ref_element_addr %0 : $X, #X.s -// CHECK-NEXT: %3 = struct_element_addr %1 : $*Str, #Str.b -// CHECK-NEXT: may alias -// CHECK: pair 0 - 3 -// CHECK-NEXT: %1 = ref_element_addr %0 : $X, #X.s -// CHECK-NEXT: %5 = struct_element_addr %4 : $*Str, #Str.a -// CHECK-NEXT: may alias -// CHECK: pair 1 - 2 -// CHECK-NEXT: %2 = struct_element_addr %1 : $*Str, #Str.a -// CHECK-NEXT: %3 = struct_element_addr %1 : $*Str, #Str.b -// CHECK-NEXT: no alias -// CHECK: pair 1 - 3 -// CHECK-NEXT: %2 = struct_element_addr %1 : $*Str, #Str.a -// CHECK-NEXT: %5 = struct_element_addr %4 : $*Str, #Str.a -// CHECK-NEXT: may alias -// CHECK: pair 2 - 3 -// CHECK-NEXT: %3 = struct_element_addr %1 : $*Str, #Str.b -// CHECK-NEXT: %5 = struct_element_addr %4 : $*Str, #Str.a -// CHECK-NEXT: no alias -// CHECK: End function test_addr_alias2 -sil @test_addr_alias2 : $@convention(thin) () -> () { -bb0: - %0 = alloc_ref $X - %1 = ref_element_addr %0 : $X, #X.s - %2 = struct_element_addr %1 : $*Str, #Str.a - %3 = struct_element_addr %1 : $*Str, #Str.b - %4 = ref_element_addr %0 : $X, #X.s - %5 = struct_element_addr %4 : $*Str, #Str.a - fix_lifetime %1 : $*Str - fix_lifetime %2 : $*Int - fix_lifetime %3 : $*Int - fix_lifetime %5 : $*Int - %11 = tuple () - return %11 : $() -} diff --git a/test/SILOptimizer/array_contentof_opt.swift b/test/SILOptimizer/array_contentof_opt.swift index 7d5cf5a0a71..12951228bc5 100644 --- a/test/SILOptimizer/array_contentof_opt.swift +++ b/test/SILOptimizer/array_contentof_opt.swift @@ -12,7 +12,7 @@ // Likewise, negative tests check for the existence of // Array.append(contentsOf:), so don't inline those either. -// CHECK-LABEL: sil {{.*}}@{{.*}}testInt +// CHECK-LABEL: sil @{{.*}}testInt // CHECK-NOT: apply // CHECK: [[F:%[0-9]+]] = function_ref @$sSa6appendyyxnFSi_Tg5 // CHECK-NOT: apply @@ -23,7 +23,7 @@ public func testInt(_ a: inout [Int]) { a += [1] } -// CHECK-LABEL: sil {{.*}}@{{.*}}testThreeInts +// CHECK-LABEL: sil @{{.*}}testThreeInts // CHECK-DAG: [[FR:%[0-9]+]] = function_ref @${{.*(reserveCapacity|_createNewBuffer)}} // CHECK-DAG: apply [[FR]] // CHECK-DAG: [[F:%[0-9]+]] = function_ref @$sSa6appendyyxnFSi_Tg5 @@ -35,7 +35,7 @@ public func testThreeInts(_ a: inout [Int]) { a += [1, 2, 3] } -// CHECK-LABEL: sil {{.*}}@{{.*}}testTooManyInts +// CHECK-LABEL: sil @{{.*}}testTooManyInts // CHECK-NOT: apply // CHECK: [[F:%[0-9]+]] = function_ref @${{.*append.*contentsOf.*}} // CHECK-NOT: apply @@ -46,7 +46,7 @@ public func testTooManyInts(_ a: inout [Int]) { a += [1, 2, 3, 4, 5, 6, 7] } -// CHECK-LABEL: sil {{.*}}@{{.*}}testString +// CHECK-LABEL: sil @{{.*}}testString // CHECK-NOT: apply // CHECK: [[F:%[0-9]+]] = function_ref @$sSa6appendyyxnFSS_Tg5 // CHECK-NOT: apply diff --git a/test/SILOptimizer/array_metadata_optimization.swift b/test/SILOptimizer/array_metadata_optimization.swift index ea7b8cf45b0..91c6a808fc1 100644 --- a/test/SILOptimizer/array_metadata_optimization.swift +++ b/test/SILOptimizer/array_metadata_optimization.swift @@ -12,9 +12,9 @@ public func makeArrayInt(x: Int) -> [Int] { return [0, 1, x] } -// CHECK: sil {{.*}}@$s4test14makeArrayClass1xSayAA1CCGAE_tF +// CHECK: sil @$s4test14makeArrayClass1xSayAA1CCGAE_tF // CHECK: alloc_ref [tail_elems $C * {{.*}} : $Builtin.Word] $_ContiguousArrayStorage -// NOOPTCLASS: sil {{.*}}@$s4test14makeArrayClass1xSayAA1CCGAE_tF +// NOOPTCLASS: sil @$s4test14makeArrayClass1xSayAA1CCGAE_tF // NOOPTCLASS: function_ref @$ss29getContiguousArrayStorageType3fors01 // NOOPTCLASS: alloc_ref_dynamic [tail_elems $C * {{.*}} : $Builtin.Word] public class C {} diff --git a/test/SILOptimizer/bridged_casts_folding.sil b/test/SILOptimizer/bridged_casts_folding.sil index 52b4a3e8b05..062d155abe0 100644 --- a/test/SILOptimizer/bridged_casts_folding.sil +++ b/test/SILOptimizer/bridged_casts_folding.sil @@ -24,7 +24,7 @@ entry(%0 : $*AnyHashable): return %3 : $NSObjectSubclass } -// CHECK-LABEL: sil {{.*}}@anyhashable_cast_take_always +// CHECK-LABEL: sil @anyhashable_cast_take_always // CHECK: [[BRIDGED:%.*]] = apply {{.*}}(%0) // CHECK-NEXT: destroy_addr %0 // CHECK-NEXT: checked_cast_br [[BRIDGED]] : $NSObject to NSObjectSubclass, [[YES:bb[0-9]+]], [[NO:bb[0-9]+]] @@ -47,7 +47,7 @@ bb3(%8 : @owned $NSObjectSubclass): return %8 : $NSObjectSubclass } -// CHECK-LABEL: sil {{.*}}@anyhashable_cast_take_on_success +// CHECK-LABEL: sil @anyhashable_cast_take_on_success // CHECK: [[BRIDGED:%.*]] = apply {{.*}}(%0) // CHECK-NEXT: destroy_addr %0 // CHECK-NEXT: checked_cast_br [[BRIDGED]] : $NSObject to NSObjectSubclass, {{bb[0-9]+}}, {{bb[0-9]+}} @@ -71,7 +71,7 @@ bb3(%8 : @owned $NSObjectSubclass): return %8 : $NSObjectSubclass } -// CHECK-LABEL: sil {{.*}}@anyhashable_cast_copy_on_success +// CHECK-LABEL: sil @anyhashable_cast_copy_on_success // CHECK-NOT: copy_addr // CHECK: [[BRIDGED:%.*]] = apply {{.*}}(%0) // CHECK-NOT: destroy_addr diff --git a/test/SILOptimizer/bridged_casts_folding.swift b/test/SILOptimizer/bridged_casts_folding.swift index d419270be85..e02c312a3a9 100644 --- a/test/SILOptimizer/bridged_casts_folding.swift +++ b/test/SILOptimizer/bridged_casts_folding.swift @@ -632,7 +632,7 @@ public func testForcedCastFromGeneric(_ x: T) -> NSString { return set } -// CHECK-LABEL: sil [noinline] {{.*}}@$s21bridged_casts_folding23testForcedCastToGeneric{{[_0-9a-zA-Z]*}}F +// CHECK-LABEL: sil [noinline] @$s21bridged_casts_folding23testForcedCastToGeneric{{[_0-9a-zA-Z]*}}F // CHECK: unconditional_checked // CHECK: return @inline(never) @@ -650,7 +650,7 @@ public func testCondCastFromGeneric(_ x: T) -> NSString? { return setOpt } -// CHECK-LABEL: sil [noinline] {{.*}}@$s21bridged_casts_folding21testCondCastToGeneric{{[_0-9a-zA-Z]*}}F +// CHECK-LABEL: sil [noinline] @$s21bridged_casts_folding21testCondCastToGeneric{{[_0-9a-zA-Z]*}}F // CHECK: checked_cast_addr_br // CHECK: return @inline(never) diff --git a/test/SILOptimizer/bridged_casts_folding_ownership.sil b/test/SILOptimizer/bridged_casts_folding_ownership.sil index 349df6ff5f0..987e91ff8fb 100644 --- a/test/SILOptimizer/bridged_casts_folding_ownership.sil +++ b/test/SILOptimizer/bridged_casts_folding_ownership.sil @@ -26,7 +26,7 @@ entry(%0 : $*AnyHashable): return %3 : $NSObjectSubclass } -// CHECK-LABEL: sil {{.*}}@anyhashable_cast_take_always +// CHECK-LABEL: sil @anyhashable_cast_take_always // CHECK: [[BRIDGED:%.*]] = apply {{.*}}(%0) // CHECK-NEXT: destroy_addr %0 // CHECK-NEXT: checked_cast_br [[BRIDGED]] : $NSObject to NSObjectSubclass, [[YES:bb[0-9]+]], [[NO:bb[0-9]+]] @@ -49,7 +49,7 @@ bb3(%8 : @owned $NSObjectSubclass): return %8 : $NSObjectSubclass } -// CHECK-LABEL: sil {{.*}}@anyhashable_cast_take_on_success +// CHECK-LABEL: sil @anyhashable_cast_take_on_success // CHECK: [[BRIDGED:%.*]] = apply {{.*}}(%0) // CHECK-NEXT: destroy_addr %0 // CHECK-NEXT: checked_cast_br [[BRIDGED]] : $NSObject to NSObjectSubclass, [[YES:bb[0-9]+]], [[NO:bb[0-9]+]] @@ -73,7 +73,7 @@ bb3(%8 : @owned $NSObjectSubclass): return %8 : $NSObjectSubclass } -// CHECK-LABEL: sil {{.*}}@anyhashable_cast_copy_on_success +// CHECK-LABEL: sil @anyhashable_cast_copy_on_success // CHECK-NOT: copy_addr // CHECK: [[BRIDGED:%.*]] = apply {{.*}}(%0) // CHECK-NOT: destroy_addr diff --git a/test/SILOptimizer/capture_promotion_generic_context.sil b/test/SILOptimizer/capture_promotion_generic_context.sil index 3e9e6b02f96..2dabafcbd4f 100644 --- a/test/SILOptimizer/capture_promotion_generic_context.sil +++ b/test/SILOptimizer/capture_promotion_generic_context.sil @@ -38,7 +38,7 @@ entry(%0 : $*T, %1 : $Int): protocol P {} -// CHECK-LABEL: sil {{.*}}@$s22generic_promotable_boxTf2ni_n : $@convention(thin) (@in_guaranteed T, Builtin.Int32) -> Builtin.Int32 +// CHECK-LABEL: sil @$s22generic_promotable_boxTf2ni_n : $@convention(thin) (@in_guaranteed T, Builtin.Int32) -> Builtin.Int32 // CHECK: bb0(%0 : $*T, %1 : $Builtin.Int32): // CHECK-NEXT: return %1 : $Builtin.Int32 // CHECK: } // end sil function '$s22generic_promotable_boxTf2ni_n' @@ -49,7 +49,7 @@ entry(%0 : $*T, %b : @guaranteed $<τ_0_0> { var τ_0_0 } ): return %v : $Int } -// CHECK-LABEL: sil {{.*}}@call_generic_promotable_box_from_different_generic : +// CHECK-LABEL: sil @call_generic_promotable_box_from_different_generic : // CHECK: bb0(%0 : $*T, %1 : $*U, %2 : $Builtin.Int32): // CHECK: [[F:%.*]] = function_ref @$s22generic_promotable_boxTf2ni_n : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0, Builtin.Int32) -> Builtin.Int32 // CHECK-NEXT: [[CLOSURE:%.*]] = partial_apply [callee_guaranteed] [[F]](%2) @@ -77,7 +77,7 @@ struct R { // take argument of a type E<(R) -> Builtin.Int32>, which used // to be a slot inside a box. // -// CHECK-LABEL: sil {{.*}}@$s23generic_promotable_box2Tf2nnni_n : $@convention(thin) (@in_guaranteed R, @in_guaranteed Builtin.Int32, @guaranteed E<(R) -> Builtin.Int32>) -> @out Builtin.Int32 { +// CHECK-LABEL: sil @$s23generic_promotable_box2Tf2nnni_n : $@convention(thin) (@in_guaranteed R, @in_guaranteed Builtin.Int32, @guaranteed E<(R) -> Builtin.Int32>) -> @out Builtin.Int32 { // CHECK: bb0(%0 : $*Builtin.Int32, %1 : $*R, %2 : $*Builtin.Int32, %3 : $E<(R) -> Builtin.Int32>): // CHECK-NOT: project_box // CHECK: switch_enum %3 : $E<(R) -> Builtin.Int32> @@ -106,7 +106,7 @@ exit: // Check that alloc_box was eliminated and a specialized version of the // closure is invoked. -// CHECK-LABEL: sil {{.*}}@call_generic_promotable_box_from_different_generic2 : +// CHECK-LABEL: sil @call_generic_promotable_box_from_different_generic2 : // CHECK: bb0(%0 : $*R, %1 : $*E<(R) -> Builtin.Int32>, %2 : $*Builtin.Int32): // CHECK: %3 = load %1 : $*E<(R) -> Builtin.Int32> // CHECK: [[F:%.*]] = function_ref @$s23generic_promotable_box2Tf2nnni_n : $@convention(thin) <τ_0_0> (@in_guaranteed R<τ_0_0>, @in_guaranteed Builtin.Int32, @guaranteed E<(R<τ_0_0>) -> Builtin.Int32>) -> @out Builtin.Int32 diff --git a/test/SILOptimizer/capture_promotion_generic_context_ownership.sil b/test/SILOptimizer/capture_promotion_generic_context_ownership.sil index 4c94990b07c..79ae464252e 100644 --- a/test/SILOptimizer/capture_promotion_generic_context_ownership.sil +++ b/test/SILOptimizer/capture_promotion_generic_context_ownership.sil @@ -37,7 +37,7 @@ entry(%0 : $*T, %1 : $Int): protocol P {} -// CHECK-LABEL: sil {{.*}}@$s22generic_promotable_boxTf2ni_n : $@convention(thin) (@in T, Builtin.Int32) -> Builtin.Int32 +// CHECK-LABEL: sil @$s22generic_promotable_boxTf2ni_n : $@convention(thin) (@in T, Builtin.Int32) -> Builtin.Int32 // CHECK: bb0([[ARG0:%.*]] : $*T, [[ARG1:%.*]] : $Builtin.Int32): // CHECK-NEXT: destroy_addr %0 // CHECK-NEXT: return [[ARG1]] : $Builtin.Int32 @@ -51,7 +51,7 @@ entry(%0 : $*T, %b : @owned $<τ_0_0> { var τ_0_0 } ): return %v : $Int } -// CHECK-LABEL: sil {{.*}}@call_generic_promotable_box_from_different_generic +// CHECK-LABEL: sil @call_generic_promotable_box_from_different_generic // CHECK: bb0([[ARG0:%.*]] : $*T, [[ARG1:%.*]] : $*U, [[ARG2:%.*]] : $Builtin.Int32): // CHECK-NEXT: destroy_addr [[ARG1]] : $*U // CHECK-NEXT: destroy_addr [[ARG0]] : $*T @@ -82,7 +82,7 @@ struct R { // Check that the capture promotion took place and the function now // take argument of a type E<(R) -> Builtin.Int32>, which used // to be a slot inside a box. -// CHECK-LABEL: sil {{.*}}@$s23generic_promotable_box2Tf2nni_n : $@convention(thin) (@in R, @in Builtin.Int32, @owned E<(R) -> Builtin.Int32>) -> () +// CHECK-LABEL: sil @$s23generic_promotable_box2Tf2nni_n : $@convention(thin) (@in R, @in Builtin.Int32, @owned E<(R) -> Builtin.Int32>) -> () // CHECK: bb0([[ARG0:%.*]] : $*R, [[ARG1:%.*]] : $*Builtin.Int32, [[ARG2:%.*]] : $E<(R) -> Builtin.Int32>): // CHECK-NOT: project_box // CHECK: switch_enum [[ARG2]] : $E<(R) -> Builtin.Int32> @@ -112,7 +112,7 @@ exit: // Check that alloc_box was eliminated and a specialized version of the // closure is invoked. -// CHECK-LABEL: sil {{.*}}@call_generic_promotable_box_from_different_generic2 +// CHECK-LABEL: sil @call_generic_promotable_box_from_different_generic2 // CHECK: bb0([[ARG0:%.*]] : $*R, [[ARG1:%.*]] : $*E<(R) -> Builtin.Int32>, [[ARG2:%.*]] : $*Builtin.Int32): // CHECK: %3 = load [[ARG1]] : $*E<(R) -> Builtin.Int32> // CHECK: [[F:%.*]] = function_ref @$s23generic_promotable_box2Tf2nni_n : $@convention(thin) <τ_0_0> (@in R<τ_0_0>, @in Builtin.Int32, @owned E<(R<τ_0_0>) -> Builtin.Int32>) -> () diff --git a/test/SILOptimizer/cast_folding.swift b/test/SILOptimizer/cast_folding.swift index 4d4c78fd962..1c8d05e9651 100644 --- a/test/SILOptimizer/cast_folding.swift +++ b/test/SILOptimizer/cast_folding.swift @@ -740,7 +740,7 @@ public class DD : PP { // Check that the body of the function // contains a trap followed by unreachable // and no code afterwards. -// CHECK-LABEL: sil {{.*}}@$s12cast_folding7getAsDDyAA0E0CAA2CCCF +// CHECK-LABEL: sil @$s12cast_folding7getAsDDyAA0E0CAA2CCCF // CHECK: builtin "int_trap" // CHECK-NEXT: unreachable // CHECK-NEXT: } @@ -751,7 +751,7 @@ public func getAsDD(_ c: CC) -> DD { // Check that the body of the function // contains a trap followed by unreachable // and no code afterwards. -// CHECK-LABEL: sil {{.*}}@$s12cast_folding7callFooySiAA2CCCF +// CHECK-LABEL: sil @$s12cast_folding7callFooySiAA2CCCF // CHECK: builtin "int_trap" // CHECK-NEXT: unreachable // CHECK-NEXT: } @@ -767,7 +767,7 @@ func callFooGeneric(_ c: T) -> Int { // Check that the inlined version of callFooGeneric contains only a trap // followed by unreachable and no code afterwards -// CHECK-LABEL: sil [noinline] {{.*}}@$s12cast_folding16callForGenericCCyyAA0F0CF +// CHECK-LABEL: sil [noinline] @$s12cast_folding16callForGenericCCyyAA0F0CF // CHECK: builtin "int_trap" // CHECK-NEXT: unreachable // CHECK-NEXT: } @@ -943,7 +943,7 @@ public func test41() -> Bool { return cast41(A(), P.self) } -// CHECK-LABEL: sil [noinline] {{.*}}@$s12cast_folding6test42{{.*}}F +// CHECK-LABEL: sil [noinline] @$s12cast_folding6test42{{.*}}F // CHECK: bb0 // CHECK-NOT: return: // CHECK: checked_cast diff --git a/test/SILOptimizer/cast_folding_no_bridging.sil b/test/SILOptimizer/cast_folding_no_bridging.sil index 180bc291640..1a43616525a 100644 --- a/test/SILOptimizer/cast_folding_no_bridging.sil +++ b/test/SILOptimizer/cast_folding_no_bridging.sil @@ -14,7 +14,7 @@ import SwiftShims import Foundation -// CHECK-LABEL: sil {{.*}}@testSwiftToSwift : $@convention(thin) (@in Set, @guaranteed Set) +// CHECK-LABEL: sil @testSwiftToSwift : $@convention(thin) (@in Set, @guaranteed Set) // CHECK: bb0 // CHECK-NOT: checked_cast_addr_br // CHECK-NOT: _bridgeToObjectiveC @@ -41,7 +41,7 @@ bb3: br bb2(%1 : $Set) } -// CHECK-LABEL: sil {{.*}}@testObjCToObjC : $@convention(thin) (NSSet, NSSet) +// CHECK-LABEL: sil @testObjCToObjC : $@convention(thin) (NSSet, NSSet) // CHECK: bb0 // CHECK-NOT: checked_cast_br // CHECK-NOT: BridgeFromObjectiveC @@ -63,7 +63,7 @@ bb3: sil @fail : $@convention(thin) () -> Never -// CHECK-LABEL: sil {{.*}}@testCFToObjC +// CHECK-LABEL: sil @testCFToObjC // CHECK: bb0( // CHECK-NEXT: [[T0:%.*]] = load %1 : $*CFString // CHECK-NEXT: [[T1:%.*]] = unchecked_ref_cast [[T0]] : $CFString to $NSString @@ -82,7 +82,7 @@ bb2: unreachable } -// CHECK-LABEL: sil {{.*}}@testCFToSwift +// CHECK-LABEL: sil @testCFToSwift // CHECK: bb0( // CHECK-NEXT: [[T0:%.*]] = load %1 : $*CFString // CHECK-NEXT: [[T1:%.*]] = unchecked_ref_cast [[T0]] : $CFString to $NSString diff --git a/test/SILOptimizer/cast_folding_objc.swift b/test/SILOptimizer/cast_folding_objc.swift index 6d270236599..d2d7e2f85de 100644 --- a/test/SILOptimizer/cast_folding_objc.swift +++ b/test/SILOptimizer/cast_folding_objc.swift @@ -1,4 +1,5 @@ // RUN: %target-swift-frontend -O -Xllvm -sil-disable-pass=FunctionSignatureOpts -Xllvm -sil-disable-pass=PerfInliner -emit-sil %s | %FileCheck %s +// RUN: %target-swift-frontend -O -Xllvm -sil-disable-pass=FunctionSignatureOpts -Xllvm -sil-disable-pass=PerfInliner -emit-sil %s | %FileCheck %s // We want to check two things here: // - Correctness @@ -78,7 +79,7 @@ public func castObjCToSwift(_ t: T) -> Int { } // Check that compiler understands that this cast always fails -// CHECK-LABEL: sil [noinline] {{.*}}@$s17cast_folding_objc37testFailingBridgedCastFromObjCtoSwiftySiSo8NSStringCF +// CHECK-LABEL: sil [noinline] @$s17cast_folding_objc37testFailingBridgedCastFromObjCtoSwiftySiSo8NSStringCF // CHECK: builtin "int_trap" // CHECK-NEXT: unreachable // CHECK-NEXT: } @@ -88,7 +89,7 @@ public func testFailingBridgedCastFromObjCtoSwift(_ ns: NSString) -> Int { } // Check that compiler understands that this cast always fails -// CHECK-LABEL: sil [noinline] {{.*}}@$s17cast_folding_objc37testFailingBridgedCastFromSwiftToObjCySiSSF +// CHECK-LABEL: sil [noinline] @$s17cast_folding_objc37testFailingBridgedCastFromSwiftToObjCySiSSF // CHECK: builtin "int_trap" // CHECK-NEXT: unreachable // CHECK-NEXT: } @@ -232,57 +233,57 @@ public func testCastProtocolCompositionProtocolToProtocolType () -> P.Type? { print("test0=\(test0())") -// CHECK-LABEL: sil [noinline] {{.*}}@{{.*}}testCastNSObjectToEveryType{{.*}} +// CHECK-LABEL: sil [noinline] @{{.*}}testCastNSObjectToEveryType{{.*}} // CHECK: unconditional_checked_cast_addr -// CHECK-LABEL: sil [noinline] {{.*}}@{{.*}}testCastNSObjectToNonClassType +// CHECK-LABEL: sil [noinline] @{{.*}}testCastNSObjectToNonClassType // CHECK: builtin "int_trap" -// CHECK-LABEL: sil [noinline] {{.*}}@{{.*}}testCastAnyObjectToEveryType{{.*}} +// CHECK-LABEL: sil [noinline] @{{.*}}testCastAnyObjectToEveryType{{.*}} // CHECK: unconditional_checked_cast_addr -// CHECK-LABEL: sil [noinline] {{.*}}@{{.*}}testCastAnyObjectToNonClassType +// CHECK-LABEL: sil [noinline] @{{.*}}testCastAnyObjectToNonClassType // CHECK-NOT: builtin "int_trap" -// CHECK-LABEL: sil [noinline] {{.*}}@{{.*}}testCastAnyToAny2Class{{.*}} +// CHECK-LABEL: sil [noinline] @{{.*}}testCastAnyToAny2Class{{.*}} // CHECK: unconditional_checked_cast_addr -// CHECK-LABEL: sil [noinline] {{.*}}@{{.*}}testCastAnyToClassObject{{.*}} +// CHECK-LABEL: sil [noinline] @{{.*}}testCastAnyToClassObject{{.*}} // CHECK: unconditional_checked_cast_addr -// CHECK-LABEL: sil [noinline] {{.*}}@{{.*}}testCastAnyToAny2Type{{.*}} +// CHECK-LABEL: sil [noinline] @{{.*}}testCastAnyToAny2Type{{.*}} // CHECK: unconditional_checked_cast_addr -// CHECK-LABEL: sil [noinline] {{.*}}@{{.*}}testCastAnyToEveryType{{.*}} +// CHECK-LABEL: sil [noinline] @{{.*}}testCastAnyToEveryType{{.*}} // CHECK: unconditional_checked_cast_addr -// CHECK-LABEL: sil [noinline] {{.*}}@{{.*}}testCastAnyToNonClassType +// CHECK-LABEL: sil [noinline] @{{.*}}testCastAnyToNonClassType // CHECK: unconditional_checked_cast_addr -// CHECK-LABEL: sil [noinline] {{.*}}@{{.*}}testCastEveryToAnyClass{{.*}} +// CHECK-LABEL: sil [noinline] @{{.*}}testCastEveryToAnyClass{{.*}} // CHECK: unconditional_checked_cast_addr -// CHECK-LABEL: sil [noinline] {{.*}}@{{.*}}testCastEveryToClassObject{{.*}} +// CHECK-LABEL: sil [noinline] @{{.*}}testCastEveryToClassObject{{.*}} // CHECK: unconditional_checked_cast_addr -// CHECK-LABEL: sil [noinline] {{.*}}@{{.*}}testCastEveryToAnyType{{.*}} +// CHECK-LABEL: sil [noinline] @{{.*}}testCastEveryToAnyType{{.*}} // CHECK: unconditional_checked_cast_addr -// CHECK-LABEL: sil [noinline] {{.*}}@{{.*}}testCastEveryToEvery2Type{{.*}} +// CHECK-LABEL: sil [noinline] @{{.*}}testCastEveryToEvery2Type{{.*}} // CHECK: unconditional_checked_cast_addr -// CHECK-LABEL: sil [noinline] {{.*}}@{{.*}}testCastEveryToNonClassType +// CHECK-LABEL: sil [noinline] @{{.*}}testCastEveryToNonClassType // CHECK: unconditional_checked_cast_addr -// CHECK-LABEL: sil [noinline] {{.*}}@{{.*}}testCastPProtocolToPType +// CHECK-LABEL: sil [noinline] @{{.*}}testCastPProtocolToPType // CHECK: %0 = enum $Optional{{.*}}, #Optional.none!enumelt // CHECK-NEXT: return %0 -// CHECK-LABEL: sil [noinline] {{.*}}@{{.*}}testCastObjCPProtocolTo{{.*}}PType +// CHECK-LABEL: sil [noinline] @{{.*}}testCastObjCPProtocolTo{{.*}}PType // CHECK: %0 = enum $Optional{{.*}}, #Optional.none!enumelt // CHECK-NEXT: return %0 -// CHECK-LABEL: sil [noinline] {{.*}}@{{.*}}testCastProtocolComposition{{.*}}Type +// CHECK-LABEL: sil [noinline] @{{.*}}testCastProtocolComposition{{.*}}Type // CHECK: %0 = enum $Optional{{.*}}, #Optional.none!enumelt // CHECK-NEXT: return %0 diff --git a/test/SILOptimizer/cast_folding_objc_generics.swift b/test/SILOptimizer/cast_folding_objc_generics.swift index f86b38fc0f9..855ffb47c06 100644 --- a/test/SILOptimizer/cast_folding_objc_generics.swift +++ b/test/SILOptimizer/cast_folding_objc_generics.swift @@ -5,7 +5,7 @@ import objc_generics -// CHECK-LABEL: sil [noinline] {{.*}}@$s26cast_folding_objc_generics26testObjCGenericParamChangeySo12GenericClassCySo8NSStringCGADySo15NSMutableStringCGF : $@convention(thin) (@guaranteed GenericClass) -> @owned GenericClass { +// CHECK-LABEL: sil [noinline] @$s26cast_folding_objc_generics26testObjCGenericParamChangeySo12GenericClassCySo8NSStringCGADySo15NSMutableStringCGF : $@convention(thin) (@guaranteed GenericClass) -> @owned GenericClass { // CHECK: upcast // CHECK-NOT: int_trap // CHECK: } // end sil function '$s26cast_folding_objc_generics26testObjCGenericParamChangeySo12GenericClassCySo8NSStringCGADySo15NSMutableStringCGF' @@ -23,7 +23,7 @@ public func testObjCGenericParamChangeSubclass(_ a: GenericClass } -// CHECK-LABEL: sil [noinline] {{.*}}@$s26cast_folding_objc_generics36testObjCGenericParamChangeSuperclassySo12GenericClassCySo8NSStringCGSo0K8SubclassCySo15NSMutableStringCGF : $@convention(thin) (@guaranteed GenericSubclass) -> @owned GenericClass { +// CHECK-LABEL: sil [noinline] @$s26cast_folding_objc_generics36testObjCGenericParamChangeSuperclassySo12GenericClassCySo8NSStringCGSo0K8SubclassCySo15NSMutableStringCGF : $@convention(thin) (@guaranteed GenericSubclass) -> @owned GenericClass { // CHECK: upcast // CHECK-NOT: int_trap // CHECK: } // end sil function '$s26cast_folding_objc_generics36testObjCGenericParamChangeSuperclassySo12GenericClassCySo8NSStringCGSo0K8SubclassCySo15NSMutableStringCGF' diff --git a/test/SILOptimizer/constant_propagation_stdlib.swift b/test/SILOptimizer/constant_propagation_stdlib.swift index 1ad8beb59ea..fe579d3dcfc 100644 --- a/test/SILOptimizer/constant_propagation_stdlib.swift +++ b/test/SILOptimizer/constant_propagation_stdlib.swift @@ -25,7 +25,7 @@ public func isConcrete_true(_ x: MyInt) -> Builtin.Int1 { // CHECK-ONONE: [[RESULT:%.*]] = builtin "isConcrete"([[METATYPE]] : $@thick T.Type) : $Builtin.Int1 // CHECK-ONONE: return [[RESULT]] // CHECK-ONONE: } // end sil function '$s27constant_propagation_stdlib16isConcrete_falseyBi1_xlF' -// CHECK-O-LABEL: sil [signature_optimized_thunk] [always_inline] {{.*}}@$s27constant_propagation_stdlib16isConcrete_falseyBi1_xlF : $@convention(thin) (@in_guaranteed T) -> Builtin.Int1 { +// CHECK-O-LABEL: sil [signature_optimized_thunk] [always_inline] @$s27constant_propagation_stdlib16isConcrete_falseyBi1_xlF : $@convention(thin) (@in_guaranteed T) -> Builtin.Int1 { // CHECK-O: bb0( // CHECK-O: [[GEN_FUNC:%.*]] = function_ref @$s27constant_propagation_stdlib16isConcrete_falseyBi1_xlFTf4d_n : $@convention(thin) <τ_0_0> () -> Builtin.Int1 // CHECK-O: [[RESULT:%.*]] = apply [[GEN_FUNC]]() : $@convention(thin) <τ_0_0> () -> Builtin.Int1 @@ -41,7 +41,7 @@ public func isConcrete_false(_ x: T) -> Builtin.Int1 { // CHECK-ONONE: [[RESULT:%.*]] = apply [[GEN_FUNC]](%0) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> Builtin.Int1 // CHECK-ONONE: return [[RESULT]] // CHECK-ONONE: } // end sil function '$s27constant_propagation_stdlib25isConcrete_generic_calleryBi1_xlF' -// CHECK-O-LABEL: sil {{.*}}@$s27constant_propagation_stdlib25isConcrete_generic_calleryBi1_xlF : $@convention(thin) (@in_guaranteed T) -> Builtin.Int1 { +// CHECK-O-LABEL: sil @$s27constant_propagation_stdlib25isConcrete_generic_calleryBi1_xlF : $@convention(thin) (@in_guaranteed T) -> Builtin.Int1 { // CHECK-O: bb0( // CHECK-O: [[GEN_FUNC:%.*]] = function_ref @$s27constant_propagation_stdlib16isConcrete_falseyBi1_xlFTf4d_n : $@convention(thin) <τ_0_0> () -> Builtin.Int1 // CHECK-O: [[RESULT:%.*]] = apply [[GEN_FUNC]]() : $@convention(thin) <τ_0_0> () -> Builtin.Int1 diff --git a/test/SILOptimizer/dead_array_elim.swift b/test/SILOptimizer/dead_array_elim.swift index 0929aeb8ce7..c3359d82ebc 100644 --- a/test/SILOptimizer/dead_array_elim.swift +++ b/test/SILOptimizer/dead_array_elim.swift @@ -57,7 +57,7 @@ func testDeadArrayElimWithAddressOnlyValues(x: T, y: T) { _ = [x, y] } -// CHECK-LABEL: sil hidden {{.*}}@$s15dead_array_elim31testDeadArrayAfterOptimizationsySiSSF +// CHECK-LABEL: sil hidden @$s15dead_array_elim31testDeadArrayAfterOptimizationsySiSSF // CHECK: bb0(%0 : $String): // CHECK-NEXT: debug_value // CHECK-NEXT: integer_literal $Builtin.Int{{[0-9]+}}, 21 diff --git a/test/SILOptimizer/dead_bridging_code.swift b/test/SILOptimizer/dead_bridging_code.swift index a87069ca051..260f43b25f4 100644 --- a/test/SILOptimizer/dead_bridging_code.swift +++ b/test/SILOptimizer/dead_bridging_code.swift @@ -8,7 +8,7 @@ import Foundation class Myclass : NSObject { -// CHECK-LABEL: sil hidden [thunk] {{.*}}@$s4test7MyclassC3fooyySSFTo +// CHECK-LABEL: sil hidden [thunk] @$s4test7MyclassC3fooyySSFTo // CHECK: bb0(%0 : $NSString, %1 : $Myclass): // CHECK-NEXT: debug_value // CHECK-NEXT: tuple () diff --git a/test/SILOptimizer/devirt_covariant_return.swift b/test/SILOptimizer/devirt_covariant_return.swift index 05cc2258215..0f63101cc62 100644 --- a/test/SILOptimizer/devirt_covariant_return.swift +++ b/test/SILOptimizer/devirt_covariant_return.swift @@ -176,7 +176,7 @@ final class C2:C { // Check that the Optional return value from doSomething // gets properly unwrapped into a Payload object and then further // devirtualized. -// CHECK-LABEL: sil hidden [noinline] {{.*}}@$s23devirt_covariant_return7driver1ys5Int32VAA2C1CF +// CHECK-LABEL: sil hidden [noinline] @$s23devirt_covariant_return7driver1ys5Int32VAA2C1CF // CHECK: integer_literal $Builtin.Int32, 2 // CHECK: struct $Int32 (%{{.*}} : $Builtin.Int32) // CHECK-NOT: class_method diff --git a/test/SILOptimizer/devirt_nested_class.swift b/test/SILOptimizer/devirt_nested_class.swift index 11d1145efe8..f8ca4b0776d 100644 --- a/test/SILOptimizer/devirt_nested_class.swift +++ b/test/SILOptimizer/devirt_nested_class.swift @@ -26,6 +26,6 @@ fileprivate func foo(d: Outer.Inner, v: V) { foo(d: Outer.Inner(), v: 0) -// CHECK-LABEL: sil {{.*}}@main : $@convention(c) (Int32, UnsafeMutablePointer>>) -> Int32 +// CHECK-LABEL: sil @main : $@convention(c) (Int32, UnsafeMutablePointer>>) -> Int32 // CHECK: function_ref @$s19devirt_nested_class5Outer{{.*}}LC5InnerC6method1vyqd0___tlF : $@convention(method) <τ_0_0><τ_1_0><τ_2_0> (@in_guaranteed τ_2_0, @guaranteed Outer<τ_0_0>.Inner<τ_1_0>) -> () // CHECK: return diff --git a/test/SILOptimizer/devirt_outer_requirements.swift b/test/SILOptimizer/devirt_outer_requirements.swift index 28ede3ade47..8cfba6a2c0d 100644 --- a/test/SILOptimizer/devirt_outer_requirements.swift +++ b/test/SILOptimizer/devirt_outer_requirements.swift @@ -33,7 +33,7 @@ public func takesBase(_ b: Base, _ v: V) where T : P { b.foo(v) } -// CHECK-LABEL: sil {{.*}}@$s25devirt_outer_requirements12takesDerivedyyAA0E0CyxG_q_tAA1QRzr0_lF : $@convention(thin) (@guaranteed Derived, @in_guaranteed V) -> () { +// CHECK-LABEL: sil @$s25devirt_outer_requirements12takesDerivedyyAA0E0CyxG_q_tAA1QRzr0_lF : $@convention(thin) (@guaranteed Derived, @in_guaranteed V) -> () { public func takesDerived(_ d: Derived, _ v: V) where T : Q { // CHECK: function_ref @$s25devirt_outer_requirements12takesDerivedyyAA0E0CyxG_q_tAA1QRzr0_lF : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : Q> (@guaranteed Derived<τ_0_0>, @in_guaranteed τ_0_1) -> () takesDerived(d, v) diff --git a/test/SILOptimizer/devirt_protocol_method_invocations.swift b/test/SILOptimizer/devirt_protocol_method_invocations.swift index a4428578fbf..e4551fdf388 100644 --- a/test/SILOptimizer/devirt_protocol_method_invocations.swift +++ b/test/SILOptimizer/devirt_protocol_method_invocations.swift @@ -82,7 +82,7 @@ func callGetSelf(_ f: Foo) -> Foo { } // Check that methods returning Self are not devirtualized and do not crash the compiler. -// CHECK-LABEL: sil [noinline] {{.*}}@$s34devirt_protocol_method_invocations05test_a1_b11_extension_C33_invocation_with_self_return_typeyAA3Foo_pAA1CCF +// CHECK-LABEL: sil [noinline] @$s34devirt_protocol_method_invocations05test_a1_b11_extension_C33_invocation_with_self_return_typeyAA3Foo_pAA1CCF // CHECK: init_existential_addr // CHECK: open_existential_addr // CHECK: return @@ -124,7 +124,7 @@ public func test_devirt_protocol_extension_method_invocation_with_self_return_ty // In fact, the call is expected to be inlined and then constant-folded // into a single integer constant. -// CHECK-LABEL: sil [noinline] {{.*}}@$s34devirt_protocol_method_invocations05test_a1_b11_extension_C11_invocationys5Int32VAA1CCF +// CHECK-LABEL: sil [noinline] @$s34devirt_protocol_method_invocations05test_a1_b11_extension_C11_invocationys5Int32VAA1CCF // CHECK-NOT: checked_cast // CHECK-NOT: open_existential // CHECK-NOT: witness_method @@ -252,7 +252,7 @@ public final class V { } // Check that all witness_method invocations are devirtualized. -// CHECK-LABEL: sil [noinline] {{.*}}@$s34devirt_protocol_method_invocations44testPropagationOfConcreteTypeIntoExistential1v1xyAA1VC_s5Int32VtF +// CHECK-LABEL: sil [noinline] @$s34devirt_protocol_method_invocations44testPropagationOfConcreteTypeIntoExistential1v1xyAA1VC_s5Int32VtF // CHECK-NOT: witness_method // CHECK-NOT: class_method // CHECK: return @@ -274,7 +274,7 @@ extension Optional : ReabstractedP { func f() {} } -// CHECK-LABEL: sil hidden [noinline] {{.*}}@$s34devirt_protocol_method_invocations23testReabstractedWitnessyyAA0F1P_pF : $@convention(thin) (@in_guaranteed ReabstractedP) -> () { +// CHECK-LABEL: sil hidden [noinline] @$s34devirt_protocol_method_invocations23testReabstractedWitnessyyAA0F1P_pF : $@convention(thin) (@in_guaranteed ReabstractedP) -> () { // CHECK: bb0(%0 : $*ReabstractedP): // CHECK: [[OPEN:%.*]] = open_existential_addr immutable_access %0 : $*ReabstractedP to $*@opened([[ID:.*]]) ReabstractedP // CHECK: [[WM:%.*]] = witness_method $@opened([[ID]]) ReabstractedP, #ReabstractedP.f : (Self) -> () -> (), [[OPEN]] : $*@opened([[ID]]) ReabstractedP : $@convention(witness_method: ReabstractedP) <τ_0_0 where τ_0_0 : ReabstractedP> (@in_guaranteed τ_0_0) -> () diff --git a/test/SILOptimizer/devirt_specialized_conformance.swift b/test/SILOptimizer/devirt_specialized_conformance.swift index f39f1948f66..8df90ee2e07 100644 --- a/test/SILOptimizer/devirt_specialized_conformance.swift +++ b/test/SILOptimizer/devirt_specialized_conformance.swift @@ -3,7 +3,7 @@ // Make sure that we completely inline/devirtualize/substitute all the way down // to unknown1. -// CHECK-LABEL: sil {{.*}}@main +// CHECK-LABEL: sil @main // CHECK: bb0({{.*}}): // CHECK: function_ref @unknown1 // CHECK: apply diff --git a/test/SILOptimizer/devirt_unbound_generic.swift b/test/SILOptimizer/devirt_unbound_generic.swift index 73d0408c66f..67427ef9223 100644 --- a/test/SILOptimizer/devirt_unbound_generic.swift +++ b/test/SILOptimizer/devirt_unbound_generic.swift @@ -178,7 +178,7 @@ public func test5() -> Int32? { // // rdar://25891588 // -// CHECK-LABEL: sil private [noinline] {{.*}}@{{.*}}test6 +// CHECK-LABEL: sil private [noinline] @{{.*}}test6 // CHECK-NOT: class_method // CHECK-NOT: checked_cast_br // CHECK-NOT: class_method diff --git a/test/SILOptimizer/devirt_value_metatypes.swift b/test/SILOptimizer/devirt_value_metatypes.swift index 6cb71851f26..23dd0e22637 100644 --- a/test/SILOptimizer/devirt_value_metatypes.swift +++ b/test/SILOptimizer/devirt_value_metatypes.swift @@ -13,7 +13,7 @@ class B: A { override class func foo() {} } -// CHECK-LABEL: sil {{.*}}@$s22devirt_value_metatypes17testValueMetatypeyyAA1ACF +// CHECK-LABEL: sil @$s22devirt_value_metatypes17testValueMetatypeyyAA1ACF // CHECK: value_metatype $@thick A.Type // CHECK: checked_cast_br // CHECK: checked_cast_br @@ -33,7 +33,7 @@ open class D : C { override class func foo() -> Int { return 1 } } -// CHECK-LABEL: sil {{.*}}@$s22devirt_value_metatypes5testDySiAA1DCF +// CHECK-LABEL: sil @$s22devirt_value_metatypes5testDySiAA1DCF // CHECK-NOT: value_metatype % // D.foo is an internal method, D has no subclasses and it is a wmo compilation, // therefore D.foo method invocation can be devirtualized. @@ -52,7 +52,7 @@ public final class E : C { override class func foo() -> Int { return 1 } } -// CHECK-LABEL: sil {{.*}}@$s22devirt_value_metatypes5testEySiAA1ECF +// CHECK-LABEL: sil @$s22devirt_value_metatypes5testEySiAA1ECF // CHECK-NOT: value_metatype $@thick E.Type // CHECK_NOT: checked_cast_br // CHECK: function_ref diff --git a/test/SILOptimizer/dynamic_self_cast.sil b/test/SILOptimizer/dynamic_self_cast.sil index 818f83bda98..af52dfe59d7 100644 --- a/test/SILOptimizer/dynamic_self_cast.sil +++ b/test/SILOptimizer/dynamic_self_cast.sil @@ -26,7 +26,7 @@ bb3(%13 : $Optional): return %13 : $Optional } -// CHECK-LABEL: sil {{.*}}@$dynamic_self_cast_2 : $@convention(method) (@guaranteed SelfCasts, @thick SelfCasts.Type) -> @owned Optional +// CHECK-LABEL: sil @$dynamic_self_cast_2 : $@convention(method) (@guaranteed SelfCasts, @thick SelfCasts.Type) -> @owned Optional sil @$dynamic_self_cast_2 : $@convention(method) (@guaranteed SelfCasts, @thick SelfCasts.Type) -> @owned Optional { bb0(%0 : $SelfCasts, %1 : $@thick SelfCasts.Type): strong_retain %0 : $SelfCasts diff --git a/test/SILOptimizer/escape_info.sil b/test/SILOptimizer/escape_info.sil deleted file mode 100644 index 6456b2e19d6..00000000000 --- a/test/SILOptimizer/escape_info.sil +++ /dev/null @@ -1,1118 +0,0 @@ -// RUN: %target-sil-opt %s -dump-escape-info -module-name=test -o /dev/null | %FileCheck %s - -// REQUIRES: swift_in_compiler - -sil_stage canonical - -import Builtin -import Swift -import SwiftShims - -protocol ClassP : AnyObject { - func foo() -} - -class X : ClassP { - func foo() - deinit -} - -class Derived : X { -} - -struct Str { - @_hasStorage var a: X - @_hasStorage var b: (X, X) -} - -class Y { - @_hasStorage var s: Str -} - -class Z { - @_hasStorage var y: Y - @_hasStorage var y2: Y -} - -class DerivedZ : Z { -} - -class WZ { - @_hasStorage weak var w: @sil_weak Y? - @_hasStorage unowned var u: @sil_unowned Y -} - -struct PointerStr { - @_hasStorage var p: UnsafeMutablePointer -} - -class LinkedNode { - @_hasStorage var next: LinkedNode; - @_hasStorage var x: X; -} - -struct TwoNodes { - @_hasStorage var a: LinkedNode - @_hasStorage var b: LinkedNode -} - -enum E { - case A(Z) - case B(Z) -} - -sil [escapes !%0.**] @not_escaping_argument : $@convention(thin) (@guaranteed Z) -> () -sil [ossa] [escapes !%1.**] @not_escaping_second_argument : $@convention(thin) (@owned X, @owned Y) -> () -sil [escapes %0 => %r, %0.c*.c*.v** => %r.c*.c*.v**] @exclusive_arg_to_return : $@convention(thin) (@owned Z) -> @owned Z -sil [escapes %0 => %r, %0.c*.c*.v** -> %r.c*.c*.v**] @nonexclusive_arg_to_return : $@convention(thin) (@owned Z) -> @owned Z -sil [ossa] [escapes %0 => %r.s0] @arg_to_return : $@convention(thin) (@owned X) -> @owned Str -sil [escapes %1 => %0.s0, !%0] [ossa] @arg_to_arg : $@convention(thin) (@owned X) -> @out Str -sil [escapes !%0, %0.c* => %r] [ossa] @content_of_arg_to_return : $@convention(thin) (@owned Z) -> @owned Y -sil [ossa] [escapes !%0.**] @non_escaping_in_arg : $@convention(thin) (@in Z) -> () -sil [escapes %0 -> %r, %0.c*.v** -> %r.c*.v**] @load_from_inout : $@convention(thin) (@inout Y) -> @owned Y -sil [escapes %0 => %r, %0.c*.v** => %r.c*.v**] @forward_from_inout : $@convention(thin) (@inout Z, @guaranteed Y) -> Z -sil [escapes %0 -> %r, %0.c*.v** -> %r.c*.v**] @load_and_store_to_inout : $@convention(thin) (@inout Z, @guaranteed Y) -> Z -sil [escapes %0 => %r, %0.c1.v** => %r.c1.v**] @exclusive2 : $@convention(thin) (@owned Z) -> @owned Z -sil [escapes %0 -> %r, %0.c1.v** -> %r.c1.v**] @nonexclusive2 : $@convention(thin) (@owned Z) -> @owned Z - -// CHECK-LABEL: Escape information for test_simple: -// CHECK: return[]: %1 = alloc_ref $X -// CHECK: - : %2 = alloc_ref $Y -// CHECK: arg0[]: %3 = alloc_ref $X -// CHECK: End function test_simple -sil [ossa] @test_simple : $@convention(thin) (@inout X) -> @owned X { -bb0(%0 : $*X): - %1 = alloc_ref $X - %2 = alloc_ref $Y - %3 = alloc_ref $X - store %3 to [assign] %0 : $*X - destroy_value %2 : $Y - return %1 : $X -} - -// CHECK-LABEL: Escape information for test_value_projection: -// %0 is conservatively calculated as "return" because of path merging -// CHECK: return[v**]: %0 = alloc_ref $X -// CHECK: return[]: %1 = alloc_ref $X -// CHECK: - : %2 = alloc_ref $Y -// CHECK: End function test_value_projection -sil @test_value_projection : $@convention(thin) () -> @owned X { -bb0: - %0 = alloc_ref $X - %1 = alloc_ref $X - %2 = alloc_ref $Y - %3 = ref_element_addr %2 : $Y, #Y.s - %4 = begin_access [modify] [dynamic] %3 : $*Str - %5 = tuple (%0 : $X, %1 : $X) - %6 = struct $Str (%0 : $X, %5 : $(X, X)) - store %6 to %3 : $*Str - %8 = load %3 : $*Str - end_access %4 : $*Str - %10 = struct_extract %8 : $Str, #Str.b - %11 = tuple_extract %10 : $(X, X), 1 - return %11 : $X -} - -// CHECK-LABEL: Escape information for test_addr_projection: -// %0 is conservatively calculated as "return" because of path merging -// CHECK: return[v**]: %0 = alloc_ref $X -// CHECK: return[]: %1 = alloc_ref $X -// CHECK: - : %2 = alloc_ref $Y -// CHECK: End function test_addr_projection -sil @test_addr_projection : $@convention(thin) () -> @owned X { -bb0: - %0 = alloc_ref $X - %1 = alloc_ref $X - %2 = alloc_ref $Y - %3 = ref_element_addr %2 : $Y, #Y.s - %4 = struct_element_addr %3 : $*Str, #Str.a - store %0 to %4 : $*X - %6 = struct_element_addr %3 : $*Str, #Str.b - %7 = tuple_element_addr %6 : $*(X, X), 0 - %8 = tuple_element_addr %6 : $*(X, X), 1 - store %0 to %7 : $*X - store %1 to %8 : $*X - %11 = struct_element_addr %3 : $*Str, #Str.b - %12 = tuple_element_addr %6 : $*(X, X), 1 - %13 = load %12 : $*X - return %13 : $X -} - -// CHECK-LABEL: Escape information for test_follow_stores: -// CHECK: arg0[c0.s0]: %1 = alloc_ref $X -// CHECK: - : %2 = alloc_ref $Z -// CHECK: End function test_follow_stores -sil @test_follow_stores : $@convention(thin) (Y) -> () { -bb0(%0 : $Y): - %1 = alloc_ref $X - %2 = alloc_ref $Z - %3 = ref_element_addr %2 : $Z, #Z.y - store %0 to %3 : $*Y - %5 = load %3 : $*Y - %6 = ref_element_addr %5 : $Y, #Y.s - %7 = struct_element_addr %6 : $*Str, #Str.a - store %1 to %7 : $*X - %9 = tuple () - return %9 : $() -} - -// CHECK-LABEL: Escape information for dont_follow_stores: -// CHECK: return[]: %1 = alloc_ref $Y -// CHECK: - : %2 = alloc_ref $Z -// CHECK: End function dont_follow_stores -sil @dont_follow_stores : $@convention(thin) (Y) -> Y { -bb0(%0 : $Y): - %1 = alloc_ref $Y - %2 = alloc_ref $Z - %3 = ref_element_addr %2 : $Z, #Z.y - cond_br undef, bb1, bb2 -bb1: - store %0 to %3 : $*Y - br bb3 -bb2: - store %1 to %3 : $*Y - br bb3 -bb3: - %9 = load %3 : $*Y - return %9 : $Y -} - -// CHECK-LABEL: Escape information for walkup_multiple_struct_tuple_operands: -// CHECK: arg0[**],arg0[c*.**]: %1 = alloc_ref $X -// CHECK: - : %2 = alloc_ref $LinkedNode -// CHECK: - : %3 = alloc_ref $LinkedNode -// CHECK: End function walkup_multiple_struct_tuple_operands -sil @walkup_multiple_struct_tuple_operands : $@convention(thin) (LinkedNode) -> () { -bb0(%0 : $LinkedNode): - %1 = alloc_ref $X - %2 = alloc_ref $LinkedNode - %3 = alloc_ref $LinkedNode - %4 = ref_element_addr %3 : $LinkedNode, #LinkedNode.next - store %0 to %4 : $*LinkedNode - %6 = tuple(%2 : $LinkedNode, %3 : $LinkedNode) - cond_br undef, bb1, bb2 -bb1: - %8 = tuple_extract %6 : $(LinkedNode, LinkedNode), 0 - br bb3(%8 : $LinkedNode) -bb2: - %10 = tuple_extract %6 : $(LinkedNode, LinkedNode), 1 - br bb3(%10 : $LinkedNode) - -bb3(%12 : $LinkedNode): - %13 = struct $TwoNodes (%12 : $LinkedNode, %3 : $LinkedNode) - cond_br undef, bb4, bb5 -bb4: - %16 = struct_extract %13 : $TwoNodes, #TwoNodes.a - br bb6(%16 : $LinkedNode) -bb5: - %18 = struct_extract %13 : $TwoNodes, #TwoNodes.b - br bb6(%18 : $LinkedNode) - -bb6(%20 : $LinkedNode): - br bb7(%20 : $LinkedNode) -bb7(%22 : $LinkedNode): - %23 = ref_element_addr %22 : $LinkedNode, #LinkedNode.x - store %1 to %23 : $*X - %25 = ref_element_addr %22 : $LinkedNode, #LinkedNode.next - %26 = load %25 : $*LinkedNode - cond_br undef, bb7(%26 : $LinkedNode), bb8 - -bb8: - %28 = tuple () - return %28 : $() -} - -// CHECK-LABEL: Escape information for callee_may_store_to_non_escaping_argument: -// CHECK: global: %1 = alloc_ref $X -// CHECK: - : %2 = alloc_ref $Z -// CHECK: End function callee_may_store_to_non_escaping_argument -sil @callee_may_store_to_non_escaping_argument : $@convention(thin) (Y) -> () { -bb0(%0 : $Y): - %1 = alloc_ref $X - %2 = alloc_ref $Z - %3 = function_ref @not_escaping_argument : $@convention(thin) (@guaranteed Z) -> () - %4 = apply %3(%2) : $@convention(thin) (@guaranteed Z) -> () - %5 = ref_element_addr %2 : $Z, #Z.y - %6 = load %5 : $*Y - %7 = ref_element_addr %6 : $Y, #Y.s - %8 = struct_element_addr %7 : $*Str, #Str.a - store %1 to %8 : $*X - %10 = tuple () - return %10 : $() -} - -// CHECK-LABEL: Escape information for callee_may_store_to_forwarded_argument: -// CHECK: global: %1 = alloc_ref $X -// CHECK: - : %2 = alloc_ref $Z -// CHECK: End function callee_may_store_to_forwarded_argument -sil @callee_may_store_to_forwarded_argument : $@convention(thin) (Y) -> () { -bb0(%0 : $Y): - %1 = alloc_ref $X - %2 = alloc_ref $Z - %3 = function_ref @exclusive_arg_to_return : $@convention(thin) (@owned Z) -> @owned Z - %4 = apply %3(%2) : $@convention(thin) (@owned Z) -> @owned Z - %5 = ref_element_addr %4 : $Z, #Z.y - %6 = load %5 : $*Y - %7 = ref_element_addr %6 : $Y, #Y.s - %8 = struct_element_addr %7 : $*Str, #Str.a - store %1 to %8 : $*X - %10 = tuple () - return %10 : $() -} - -// CHECK-LABEL: Escape information for callee_may_not_store_to_forwarded_argument: -// CHECK: global: %1 = alloc_ref $X -// CHECK: - : %2 = alloc_ref $Z -// CHECK: End function callee_may_not_store_to_forwarded_argument -sil @callee_may_not_store_to_forwarded_argument : $@convention(thin) (Y) -> () { -bb0(%0 : $Y): - %1 = alloc_ref $X - %2 = alloc_ref $Z - %3 = function_ref @nonexclusive_arg_to_return : $@convention(thin) (@owned Z) -> @owned Z - %4 = apply %3(%2) : $@convention(thin) (@owned Z) -> @owned Z - %5 = ref_element_addr %4 : $Z, #Z.y - %6 = load %5 : $*Y - %7 = ref_element_addr %6 : $Y, #Y.s - %8 = struct_element_addr %7 : $*Str, #Str.a - store %1 to %8 : $*X - %10 = tuple () - return %10 : $() -} - -// CHECK-LABEL: Escape information for callee_may_load: -// CHECK: global: %1 = alloc_ref $X -// CHECK: End function callee_may_load -sil @callee_may_load : $@convention(thin) (Y) -> () { -bb0(%0 : $Y): - %1 = alloc_ref $X - %2 = alloc_stack $Y - store %0 to %2 : $*Y - %3 = function_ref @load_from_inout : $@convention(thin) (@inout Y) -> @owned Y - %4 = apply %3(%2) : $@convention(thin) (@inout Y) -> @owned Y - %7 = ref_element_addr %4 : $Y, #Y.s - %8 = struct_element_addr %7 : $*Str, #Str.a - store %1 to %8 : $*X - dealloc_stack %2 : $*Y - %10 = tuple () - return %10 : $() -} - -// CHECK-LABEL: Escape information for test_phiterms_merge_down: -// CHECK: return[]: %1 = alloc_ref $X -// CHECK: - : %2 = alloc_ref $Y -// CHECK: return[]: %4 = alloc_ref $X -// CHECK: - : %5 = alloc_ref $Y -// CHECK: End function test_phiterms_merge_down -sil @test_phiterms_merge_down : $@convention(thin) () -> @owned X { -bb0: - cond_br undef, bb1, bb2 -bb1: - %0 = alloc_ref $X - %1 = alloc_ref $Y - br bb3(%0 : $X, %1 : $Y) -bb2: - %3 = alloc_ref $X - %4 = alloc_ref $Y - br bb3(%3 : $X, %4 : $Y) -bb3(%5 : $X, %6 : $Y): - return %5 : $X -} - -// CHECK-LABEL: Escape information for test_phiterms_merge_up: -// CHECK: - : %3 = alloc_ref $LinkedNode -// CHECK: arg0[**],arg1[**],arg1[],arg2[**]: %4 = alloc_ref $X -// CHECK: End function test_phiterms_merge_up -sil @test_phiterms_merge_up : $@convention(thin) (@inout X, @inout X, @inout X) -> () { -bb0(%0 : $*X, %1 : $*X, %2 : $*X): - %3 = alloc_ref $LinkedNode - %4 = alloc_ref $X - %5 = ref_element_addr %3 : $LinkedNode, #LinkedNode.next - %6 = load %5 : $*LinkedNode - cond_br undef, bb1, bb2 -bb1: - br bb3(%3 : $LinkedNode) -bb2: - br bb3(%6 : $LinkedNode) -bb3(%9 : $LinkedNode): - %10 = ref_element_addr %9 : $LinkedNode, #LinkedNode.x - // store X to either indirection level 0 or 1 of Y - store %4 to %10 : $*X - - // load x of indirection levels 0, 1, 2 and store to arguments 0, 1, 2 - %12 = ref_element_addr %3 : $LinkedNode, #LinkedNode.x - %13 = load %12 : $*X - store %13 to %0 : $*X - %15 = ref_element_addr %6 : $LinkedNode, #LinkedNode.x - %16 = load %15 : $*X - store %16 to %1 : $*X - %18 = ref_element_addr %6 : $LinkedNode, #LinkedNode.next - %19 = load %18 : $*LinkedNode - %20 = ref_element_addr %19 : $LinkedNode, #LinkedNode.x - %21 = load %20 : $*X - store %21 to %2 : $*X - %r = tuple () - return %r : $() -} - -// CHECK-LABEL: Escape information for test_cycle: -// CHECK: - : %0 = alloc_ref $LinkedNode -// CHECK: return[**]: %1 = alloc_ref $X -// CHECK: End function test_cycle -sil @test_cycle : $@convention(thin) () -> @owned X { -bb0: - %0 = alloc_ref $LinkedNode - %1 = alloc_ref $X - br bb1(%0 : $LinkedNode) - -bb1(%5 : $LinkedNode): - cond_br undef, bb2, bb3 - -bb2: - %8 = ref_element_addr %5 : $LinkedNode, #LinkedNode.next - %9 = load %8 : $*LinkedNode - br bb1(%9 : $LinkedNode) - -bb3: - %2 = ref_element_addr %5 : $LinkedNode, #LinkedNode.x - store %1 to %2 : $*X - %11 = ref_element_addr %0 : $LinkedNode, #LinkedNode.x - %12 = load %11 : $*X - return %12 : $X -} - -// CHECK-LABEL: Escape information for test_switch_enum_walk_down: -// CHECK: arg0[]: %1 = alloc_ref $Z -// CHECK: - : %2 = alloc_ref $Z -// CHECK: End function test_switch_enum_walk_down -sil @test_switch_enum_walk_down : $@convention(thin) () -> @out Z { -bb0(%0 : $*Z): - %1 = alloc_ref $Z - %2 = alloc_ref $Z - cond_br undef, bb1, bb2 - -bb1: - %3 = enum $E, #E.A!enumelt, %1 : $Z - br bb3(%3 : $E) - -bb2: - %5 = enum $E, #E.B!enumelt, %2 : $Z - br bb3(%5 : $E) - -bb3(%7 : $E): - switch_enum %7 : $E, case #E.A!enumelt: bb4, case #E.B!enumelt: bb5 - -bb4(%9 : $Z): - store %9 to %0 : $*Z - br bb6 - -bb5(%12: $Z): - br bb6 - -bb6: - %14 = tuple () - return %14 : $() -} - -// CHECK-LABEL: Escape information for test_switch_enum_walk_up: -// CHECK: arg0[c0]: %1 = alloc_ref $Y -// CHECK: - : %2 = alloc_ref $Y -// CHECK: - : %6 = alloc_ref $Z -// CHECK: End function test_switch_enum_walk_up -sil @test_switch_enum_walk_up : $@convention(thin) (@guaranteed Z) -> () { -bb0(%0 : $Z): - %1 = alloc_ref $Y - %2 = alloc_ref $Y - cond_br undef, bb1, bb2 - -bb1: - %3 = enum $E, #E.A!enumelt, %0 : $Z - br bb3(%3 : $E) - -bb2: - %4 = alloc_ref $Z - %5 = enum $E, #E.B!enumelt, %4 : $Z - br bb3(%5 : $E) - -bb3(%7 : $E): - switch_enum %7 : $E, case #E.A!enumelt: bb4, case #E.B!enumelt: bb5 - -bb4(%9 : $Z): - %10 = ref_element_addr %9 : $Z, #Z.y - store %1 to %10 : $*Y - br bb6 - -bb5(%12: $Z): - %13 = ref_element_addr %12 : $Z, #Z.y - store %2 to %13 : $*Y - br bb6 - -bb6: - %14 = tuple () - return %14 : $() -} - -// CHECK-LABEL: Escape information for test_enum_data_walk_down: -// CHECK: - : %1 = alloc_ref $Z -// CHECK: arg0[]: %2 = alloc_ref $Z -// CHECK: End function test_enum_data_walk_down -sil @test_enum_data_walk_down : $@convention(thin) () -> @out Z { -bb0(%0 : $*Z): - %1 = alloc_ref $Z - %2 = alloc_ref $Z - cond_br undef, bb1, bb2 - -bb1: - %3 = enum $E, #E.A!enumelt, %1 : $Z - br bb3(%3 : $E) - -bb2: - %5 = enum $E, #E.B!enumelt, %2 : $Z - br bb3(%5 : $E) - -bb3(%7 : $E): - %8 = unchecked_enum_data %7 : $E, #E.B!enumelt - store %8 to %0 : $*Z - %10 = tuple () - return %10 : $() -} - -// CHECK-LABEL: Escape information for test_enum_data_walk_up: -// CHECK: - : %1 = alloc_ref $Y -// CHECK: arg0[c0]: %2 = alloc_ref $Y -// CHECK: - : %4 = alloc_ref $Z -// CHECK: End function test_enum_data_walk_up -sil @test_enum_data_walk_up : $@convention(thin) (@guaranteed Z) -> () { -bb0(%0 : $Z): - %1 = alloc_ref $Y - %2 = alloc_ref $Y - cond_br undef, bb1, bb2 - -bb1: - %4 = alloc_ref $Z - %5 = enum $E, #E.A!enumelt, %4 : $Z - br bb3(%5 : $E) - -bb2: - %7 = enum $E, #E.B!enumelt, %0 : $Z - br bb3(%7 : $E) - -bb3(%9 : $E): - %10 = unchecked_enum_data %9 : $E, #E.A!enumelt - %11 = ref_element_addr %10 : $Z, #Z.y - store %1 to %11 : $*Y - - %13 = unchecked_enum_data %9 : $E, #E.B!enumelt - %14 = ref_element_addr %13 : $Z, #Z.y - store %2 to %14 : $*Y - - %16 = tuple () - return %16 : $() -} - -// CHECK-LABEL: Escape information for test_enum_addr: -// CHECK: - : %1 = alloc_ref $Z -// CHECK: arg0[]: %2 = alloc_ref $Z -// CHECK: End function test_enum_addr -sil @test_enum_addr : $@convention(thin) () -> @out Z { -bb0(%0 : $*Z): - %1 = alloc_ref $Z - %2 = alloc_ref $Z - %3 = alloc_stack $E - cond_br undef, bb1, bb2 - -bb1: - %5 = init_enum_data_addr %3 : $*E, #E.A!enumelt - store %1 to %5 : $*Z - inject_enum_addr %3 : $*E, #E.A!enumelt - br bb3 - -bb2: - %9 = init_enum_data_addr %3 : $*E, #E.B!enumelt - store %2 to %9 : $*Z - inject_enum_addr %3 : $*E, #E.B!enumelt - br bb3 - -bb3: - %13 = unchecked_take_enum_data_addr %3 : $*E, #E.B!enumelt - copy_addr [take] %13 to [initialization] %0 : $*Z - dealloc_stack %3 : $*E - %15 = tuple () - return %15 : $() -} - - -// CHECK-LABEL: Escape information for test_mark_dependence_not_escaping: -// CHECK: - : %0 = alloc_ref $Z -// CHECK: - : %3 = alloc_ref $Y -// CHECK: End function test_mark_dependence_not_escaping -sil @test_mark_dependence_not_escaping : $@convention(thin) () -> () { -bb0: - %0 = alloc_ref $Z - %1 = ref_element_addr %0 : $Z, #Z.y - %2 = mark_dependence %1 : $*Y on %0 : $Z - %3 = alloc_ref $Y - store %3 to %2 : $*Y - %5 = tuple () - return %5 : $() -} - -// CHECK-LABEL: Escape information for test_mark_dependence_escaping: -// CHECK: return[]: %0 = alloc_ref $Z -// CHECK: return[c0]: %3 = alloc_ref $Y -// CHECK: End function test_mark_dependence_escaping -sil @test_mark_dependence_escaping : $@convention(thin) () -> Z { -bb0: - %0 = alloc_ref $Z - %1 = ref_element_addr %0 : $Z, #Z.y - %2 = mark_dependence %1 : $*Y on %0 : $Z - %3 = alloc_ref $Y - store %3 to %2 : $*Y - return %0 : $Z -} - - -// CHECK-LABEL: Escape information for test_cast_and_existentials_walk_down: -// CHECK: return[]: %0 = alloc_ref $Derived -// CHECK: - : %1 = alloc_ref $Derived -// CHECK: End function test_cast_and_existentials_walk_down -sil @test_cast_and_existentials_walk_down : $@convention(thin) () -> ClassP { -bb0: - %0 = alloc_ref $Derived - %1 = alloc_ref $Derived - - (%2,%3) = begin_cow_mutation %0 : $Derived - %4 = end_cow_mutation %3 : $Derived - %5 = upcast %4 : $Derived to $X - %6 = init_existential_ref %5 : $X : $X, $ClassP - %7 = open_existential_ref %6 : $ClassP to $@opened("53729A20-8747-11EB-82C4-D0817AD9985D") ClassP - - (%8,%9) = begin_cow_mutation %1 : $Derived - %10 = end_cow_mutation %9 : $Derived - %11 = upcast %10 : $Derived to $X - %12 = init_existential_ref %11 : $X : $X, $ClassP - %13 = open_existential_ref %12 : $ClassP to $@opened("12345678-8747-11EB-82C4-D0817AD9985D") ClassP - - return %6 : $ClassP -} - -// CHECK-LABEL: Escape information for test_cast_walk_up: -// CHECK: - : %1 = alloc_ref $Y -// CHECK: arg0[c0]: %2 = alloc_ref $Y -// CHECK: - : %3 = alloc_ref $DerivedZ -// CHECK: End function test_cast_walk_up -sil @test_cast_walk_up : $@convention(thin) (@guaranteed DerivedZ) -> () { -bb0(%0 : $DerivedZ): - %1 = alloc_ref $Y - %2 = alloc_ref $Y - - %3 = alloc_ref $DerivedZ - (%4,%5) = begin_cow_mutation %3 : $DerivedZ - %6 = end_cow_mutation %5 : $DerivedZ - %7 = upcast %6 : $DerivedZ to $Z - %8 = ref_element_addr %7 : $Z, #Z.y - store %1 to %8 : $*Y - - (%10,%11) = begin_cow_mutation %0 : $DerivedZ - %12 = end_cow_mutation %11 : $DerivedZ - %13 = upcast %12 : $DerivedZ to $Z - %14 = ref_element_addr %13 : $Z, #Z.y - store %2 to %14 : $*Y - - %15 = tuple () - return %15 : $() -} - -// CHECK-LABEL: Escape information for test_address_pointer_casts: -// CHECK: - : %0 = alloc_ref $Z -// CHECK: return[]: %1 = alloc_ref $Y -// CHECK: return[]: %2 = alloc_ref $Y -// CHECK: End function test_address_pointer_casts -sil @test_address_pointer_casts : $@convention(thin) () -> Y { -bb0: - %0 = alloc_ref $Z - %1 = alloc_ref $Y - %2 = alloc_ref $Y - %3 = ref_element_addr %0 : $Z, #Z.y - store %1 to %3 : $*Y - %5 = address_to_pointer %3 : $*Y to $Builtin.RawPointer - %6 = struct $UnsafeMutablePointer (%5 : $Builtin.RawPointer) - %7 = struct_extract %6 : $UnsafeMutablePointer, #UnsafeMutablePointer._rawValue - %8 = pointer_to_address %7 : $Builtin.RawPointer to [strict] $*Y - store %2 to %8 : $*Y - %10 = load %8 : $*Y - return %10 : $Y -} - -// CHECK-LABEL:Escape information for test_escaping_address_to_pointer: -// CHECK: - : %0 = alloc_ref $Z -// CHECK: return[s0.s0]: %1 = alloc_ref $Y -// CHECK: End function test_escaping_address_to_pointer -sil @test_escaping_address_to_pointer : $@convention(thin) () -> PointerStr { -bb0: - %0 = alloc_ref $Z - %1 = alloc_ref $Y - %2 = ref_element_addr %0 : $Z, #Z.y - store %1 to %2 : $*Y - %4 = address_to_pointer %2 : $*Y to $Builtin.RawPointer - %5 = struct $UnsafeMutablePointer (%4 : $Builtin.RawPointer) - %6 = struct $PointerStr (%5 : $UnsafeMutablePointer) - return %6 : $PointerStr -} - -// CHECK-LABEL: Escape information for test_copy_addr: -// CHECK: arg0[]: %2 = alloc_ref $X -// CHECK: End function test_copy_addr -sil [ossa] @test_copy_addr : $@convention(thin) (@in_guaranteed X) -> @out X { -bb0(%0 : $*X, %1 : $*X): - %2 = alloc_ref $X - - %4 = alloc_stack $X - cond_br undef, bb1, bb2 -bb1: - store %2 to [init] %4 : $*X - br bb3 -bb2: - destroy_value %2 : $X - copy_addr %1 to [initialization] %4 : $*X - br bb3 -bb3: - copy_addr %4 to [initialization] %0 : $*X - destroy_addr %4 : $*X - dealloc_stack %4 : $*X - - %11 = tuple () - return %11 : $() -} - -// CHECK-LABEL: Escape information for test_weak: -// CHECK: - : %0 = alloc_ref $WZ -// CHECK: return[e1]: %1 = alloc_ref $Y -// CHECK: End function test_weak -sil @test_weak : $@convention(thin) () -> Optional { -bb0: - %0 = alloc_ref $WZ - %1 = alloc_ref $Y - %2 = enum $Optional, #Optional.some!enumelt, %1 : $Y - %3 = ref_element_addr %0 : $WZ, #WZ.w - store_weak %2 to [initialization] %3 : $*@sil_weak Optional - %5 = load_weak %3 : $*@sil_weak Optional - return %5 : $Optional -} - -// CHECK-LABEL: Escape information for test_unowned: -// CHECK: - : %0 = alloc_ref $WZ -// CHECK: return[]: %1 = alloc_ref $Y -// CHECK: End function test_unowned -sil @test_unowned : $@convention(thin) () -> Y { -bb0: - %0 = alloc_ref $WZ - %1 = alloc_ref $Y - %2 = ref_element_addr %0 : $WZ, #WZ.u - store_unowned %1 to [initialization] %2 : $*@sil_unowned Y - %4 = load_unowned %2 : $*@sil_unowned Y - return %4 : $Y -} - -// CHECK-LABEL: Escape information for test_bridge_object: -// CHECK: arg0[c0]: %1 = alloc_ref $Y -// CHECK: End function test_bridge_object -sil @test_bridge_object : $@convention(thin) (Z) -> (Builtin.Int1, Builtin.Int1) { -bb0(%0 : $Z): - %1 = alloc_ref $Y - %2 = integer_literal $Builtin.Word, 1 - %3 = ref_to_bridge_object %1 : $Y, %2 : $Builtin.Word - %4 = bridge_object_to_ref %3 : $Builtin.BridgeObject to $Y - %5 = ref_to_bridge_object %0 : $Z, %2 : $Builtin.Word - %6 = bridge_object_to_ref %5 : $Builtin.BridgeObject to $Z - %7 = ref_element_addr %6 : $Z, #Z.y - store %4 to %7 : $*Y - %9 = classify_bridge_object %3 : $Builtin.BridgeObject - return %9 : $(Builtin.Int1, Builtin.Int1) -} - -// CHECK-LABEL: Escape information for test_ossa: -// CHECK: global: %0 = alloc_ref $Y -// CHECK: - : %1 = alloc_ref $Z -// CHECK: End function test_ossa -sil [ossa] @test_ossa : $@convention(thin) () -> () { -bb0: - %0 = alloc_ref $Y - %1 = alloc_ref $Z - %2 = copy_value %1 : $Z - %3 = begin_borrow %2 : $Z - %4 = ref_element_addr %3 : $Z, #Z.y - store %0 to [init] %4 : $*Y - end_borrow %3 : $Z - // destoying %1 and %8 may escape %0 in its destructor - destroy_value %1 : $Z - %8 = enum $E, #E.A!enumelt, %2 : $Z - destroy_value %8 : $E - %9 = tuple () - return %9 : $() -} - -// CHECK-LABEL: Escape information for call_unknown: -// CHECK: global: %0 = alloc_ref $X -// CHECK: - : %1 = alloc_ref $Y -// CHECK: End function call_unknown -sil [ossa] @call_unknown : $@convention(thin) () -> () { -bb0: - %0 = alloc_ref $X - %1 = alloc_ref $Y - %2 = function_ref @not_escaping_second_argument : $@convention(thin) (@owned X, @owned Y) -> () - %3 = apply %2(%0, %1) : $@convention(thin) (@owned X, @owned Y) -> () - %4 = tuple () - return %4 : $() -} - -// CHECK-LABEL: Escape information for call_arg_to_return: -// CHECK: - : %0 = alloc_ref $X -// CHECK: return[]: %1 = alloc_ref $X -// CHECK: End function call_arg_to_return -sil [ossa] @call_arg_to_return : $@convention(thin) () -> @owned X { -bb0: - %0 = alloc_ref $X - %1 = alloc_ref $X - %2 = function_ref @arg_to_return : $@convention(thin) (@owned X) -> @owned Str - %3 = apply %2(%0) : $@convention(thin) (@owned X) -> @owned Str - destroy_value %3 : $Str - %5 = apply %2(%1) : $@convention(thin) (@owned X) -> @owned Str - (%6, %7) = destructure_struct %5 : $Str - destroy_value %7 : $(X, X) - return %6 : $X -} - -// CHECK-LABEL: Escape information for call_arg_to_arg: -// CHECK: - : %0 = alloc_ref $X -// CHECK: return[]: %1 = alloc_ref $X -// CHECK: End function call_arg_to_arg -sil [ossa] @call_arg_to_arg : $@convention(thin) () -> @owned X { -bb0: - %0 = alloc_ref $X - %1 = alloc_ref $X - %2 = function_ref @arg_to_arg : $@convention(thin) (@owned X) -> @out Str - %3 = alloc_stack $Str - %4 = apply %2(%3, %0) : $@convention(thin) (@owned X) -> @out Str - destroy_addr %3 : $*Str - dealloc_stack %3 : $*Str - %7 = alloc_stack $Str - %8 = apply %2(%7, %1) : $@convention(thin) (@owned X) -> @out Str - %9 = struct_element_addr %7 : $*Str, #Str.a - %10 = load [copy] %9 : $*X - destroy_addr %7 : $*Str - dealloc_stack %7 : $*Str - return %10 : $X -} - -// CHECK-LABEL: Escape information for call_content_of_arg_to_arg: -// CHECK: - : %0 = alloc_ref $Z -// CHECK: - : %1 = alloc_ref $Y -// CHECK: - : %6 = alloc_ref $Z -// CHECK: return[]: %7 = alloc_ref $Y -// CHECK: End function call_content_of_arg_to_arg -sil [ossa] @call_content_of_arg_to_arg : $@convention(thin) () -> @owned Y { -bb0: - %0 = alloc_ref $Z - %1 = alloc_ref $Y - %2 = begin_borrow %0 : $Z - %3 = ref_element_addr %2 : $Z, #Z.y - store %1 to [init] %3 : $*Y - end_borrow %2 : $Z - - %6 = alloc_ref $Z - %7 = alloc_ref $Y - %8 = begin_borrow %6 : $Z - %9 = ref_element_addr %8 : $Z, #Z.y - store %7 to [init] %9 : $*Y - end_borrow %8 : $Z - - %16 = function_ref @content_of_arg_to_return : $@convention(thin) (@owned Z) -> @owned Y - %17 = apply %16(%0) : $@convention(thin) (@owned Z) -> @owned Y - destroy_value %17 : $Y - %19 = apply %16(%6) : $@convention(thin) (@owned Z) -> @owned Y - return %19 : $Y -} - -// CHECK-LABEL: Escape information for escape_via_copy_addr_destructor: -// CHECK: - : %1 = alloc_ref $Z -// CHECK: global: %2 = alloc_ref $Y -// CHECK: End function escape_via_copy_addr_destructor -sil [ossa] @escape_via_copy_addr_destructor : $@convention(thin) (@in_guaranteed Z) -> () { -bb0(%0 : $*Z): - %1 = alloc_ref $Z - %2 = alloc_ref $Y - %3 = begin_borrow %1 : $Z - %4 = ref_element_addr %3 : $Z, #Z.y - store %2 to [init] %4 : $*Y - end_borrow %3 : $Z - %7 = alloc_stack $Z - store %1 to [init] %7 : $*Z - copy_addr %0 to %7 : $*Z - %f = function_ref @non_escaping_in_arg : $@convention(thin) (@in Z) -> () - %a = apply %f(%7) : $@convention(thin) (@in Z) -> () - dealloc_stack %7 : $*Z - %11 = tuple () - return %11 : $() -} - -// CHECK-LABEL: Escape information for escape_via_store_assign_destructor: -// CHECK: - : %1 = alloc_ref $Z -// CHECK: global: %2 = alloc_ref $Y -// CHECK: End function escape_via_store_assign_destructor -sil [ossa] @escape_via_store_assign_destructor : $@convention(thin) (@owned Z) -> () { -bb0(%0 : @owned $Z): - %1 = alloc_ref $Z - %2 = alloc_ref $Y - %3 = begin_borrow %1 : $Z - %4 = ref_element_addr %3 : $Z, #Z.y - store %2 to [init] %4 : $*Y - end_borrow %3 : $Z - %7 = alloc_stack $Z - store %1 to [init] %7 : $*Z - store %0 to [assign] %7 : $*Z - %f = function_ref @non_escaping_in_arg : $@convention(thin) (@in Z) -> () - %a = apply %f(%7) : $@convention(thin) (@in Z) -> () - dealloc_stack %7 : $*Z - %11 = tuple () - return %11 : $() -} - -sil [ossa] [escapes !%1] @closure1 : $@convention(thin) (@guaranteed Y, @guaranteed Y) -> () -sil [ossa] [escapes !%0] @closure2 : $@convention(thin) (@guaranteed Y, @guaranteed Y) -> () -sil [escapes !%0.**] @closure3 : $@convention(thin) (@guaranteed Z) -> () - -// CHECK-LABEL: Escape information for callClosure1: -// CHECK: - : %0 = alloc_ref $Y -// CHECK: global: %1 = alloc_ref $Y -// CHECK: End function callClosure1 -sil [ossa] @callClosure1 : $@convention(thin) () -> () { -bb0: - %0 = alloc_ref $Y - %1 = alloc_ref $Y - %2 = function_ref @closure1 : $@convention(thin) (@guaranteed Y, @guaranteed Y) -> () - %3 = partial_apply [callee_guaranteed] %2(%0) : $@convention(thin) (@guaranteed Y, @guaranteed Y) -> () - %8 = apply %3(%1) : $@callee_guaranteed (@guaranteed Y) -> () - destroy_value %3 : $@callee_guaranteed (@guaranteed Y) -> () - destroy_value %1 : $Y - %11 = tuple () - return %11 : $() -} - -// CHECK-LABEL: Escape information for callClosure2: -// CHECK: global: %0 = alloc_ref $Y -// CHECK: - : %1 = alloc_ref $Y -// CHECK: End function callClosure2 -sil [ossa] @callClosure2 : $@convention(thin) () -> () { -bb0: - %0 = alloc_ref $Y - %1 = alloc_ref $Y - %2 = function_ref @closure2 : $@convention(thin) (@guaranteed Y, @guaranteed Y) -> () - %3 = partial_apply [callee_guaranteed] %2(%0) : $@convention(thin) (@guaranteed Y, @guaranteed Y) -> () - %8 = apply %3(%1) : $@callee_guaranteed (@guaranteed Y) -> () - destroy_value %3 : $@callee_guaranteed (@guaranteed Y) -> () - destroy_value %1 : $Y - %11 = tuple () - return %11 : $() -} - -// CHECK-LABEL: Escape information for noescape_via_closure: -// CHECK: - : %0 = alloc_ref $Z -// CHECK: - : %1 = alloc_ref $Y -// CHECK: End function noescape_via_closure -sil @noescape_via_closure : $@convention(thin) () -> () { -bb0: - %0 = alloc_ref $Z - %1 = alloc_ref $Y - %2 = ref_element_addr %0 : $Z, #Z.y - store %1 to %2 : $*Y - %4 = function_ref @closure3 : $@convention(thin) (@guaranteed Z) -> () - %5 = partial_apply [callee_guaranteed] %4(%0) : $@convention(thin) (@guaranteed Z) -> () - %6 = tuple () - return %6 : $() -} - -// CHECK-LABEL: Escape information for escape_via_destroy_of_closure: -// CHECK: - : %0 = alloc_ref $Z -// CHECK: global: %1 = alloc_ref $Y -// CHECK: End function escape_via_destroy_of_closure -sil @escape_via_destroy_of_closure : $@convention(thin) () -> () { -bb0: - %0 = alloc_ref $Z - %1 = alloc_ref $Y - %2 = ref_element_addr %0 : $Z, #Z.y - store %1 to %2 : $*Y - %4 = function_ref @closure3 : $@convention(thin) (@guaranteed Z) -> () - %5 = partial_apply [callee_guaranteed] %4(%0) : $@convention(thin) (@guaranteed Z) -> () - strong_release %5 : $@callee_guaranteed () -> () - %6 = tuple () - return %6 : $() -} - -// CHECK-LABEL: Escape information for escapingClosure: -// CHECK: return[]: %0 = alloc_ref $Y -// CHECK: End function escapingClosure -sil [ossa] @escapingClosure : $@convention(thin) () -> @owned @callee_guaranteed (@guaranteed Y) -> () { -bb0: - %0 = alloc_ref $Y - %1 = function_ref @closure1 : $@convention(thin) (@guaranteed Y, @guaranteed Y) -> () - %2 = partial_apply [callee_guaranteed] %1(%0) : $@convention(thin) (@guaranteed Y, @guaranteed Y) -> () - return %2 : $@callee_guaranteed (@guaranteed Y) -> () -} - -// CHECK-LABEL: Escape information for test_box: -// CHECK: - : %0 = alloc_ref $Z -// CHECK: return[]: %1 = alloc_ref $Z -// CHECK: End function test_box -sil @test_box : $@convention(thin) () -> Z { -bb0: - %0 = alloc_ref $Z - %1 = alloc_ref $Z - %2 = alloc_box ${ var Z, var Z } - %3 = project_box %2 : ${ var Z, var Z }, 0 - %4 = project_box %2 : ${ var Z, var Z }, 1 - store %0 to %3 : $*Z - store %1 to %4 : $*Z - %7 = load %4 : $*Z - return %7 : $Z -} - -// CHECK-LABEL: Escape information for exclusive_arg_and_load: -// CHECK: - : %2 = alloc_ref $Z -// CHECK: global: %4 = alloc_ref $Y -// CHECK: End function exclusive_arg_and_load -sil @exclusive_arg_and_load : $@convention(thin) (Y) -> () { -bb0(%0 : $Y): - %1 = alloc_stack $Z - %2 = alloc_ref $Z - store %2 to %1 : $*Z - %4 = alloc_ref $Y - %f = function_ref @forward_from_inout : $@convention(thin) (@inout Z, @guaranteed Y) -> Z - %a = apply %f(%1, %0) : $@convention(thin) (@inout Z, @guaranteed Y) -> Z - %6 = load %1 : $*Z - %7 = ref_element_addr %6 : $Z, #Z.y - store %4 to %7 : $*Y - dealloc_stack %1 : $*Z - %10 = tuple () - return %10 : $() -} - -// CHECK-LABEL: Escape information for nonexclusive_arg_and_load: -// CHECK: - : %2 = alloc_ref $Z -// CHECK: global: %4 = alloc_ref $Y -// CHECK: End function nonexclusive_arg_and_load -sil @nonexclusive_arg_and_load : $@convention(thin) (Y) -> () { -bb0(%0 : $Y): - %1 = alloc_stack $Z - %2 = alloc_ref $Z - store %2 to %1 : $*Z - %4 = alloc_ref $Y - %f = function_ref @load_and_store_to_inout : $@convention(thin) (@inout Z, @guaranteed Y) -> Z - %a = apply %f(%1, %0) : $@convention(thin) (@inout Z, @guaranteed Y) -> Z - %6 = load %1 : $*Z - %7 = ref_element_addr %6 : $Z, #Z.y - store %4 to %7 : $*Y - dealloc_stack %1 : $*Z - %10 = tuple () - return %10 : $() -} - -sil [escapes !%0.c1.**] @$s4test1ZCfD : $@convention(method) (@owned Z) -> () -sil [escapes !%0.c0.**] @$s4test8DerivedZCfD : $@convention(method) (@owned DerivedZ) -> () - -// CHECK-LABEL: Escape information for known_type: -// CHECK: global: %0 = alloc_ref $Y -// CHECK: - : %1 = alloc_ref $Y -// CHECK: - : %2 = alloc_ref $Z -// CHECK: End function known_type -sil @known_type : $@convention(thin) () -> () { -bb0: - %0 = alloc_ref $Y - %1 = alloc_ref $Y - %2 = alloc_ref $Z - %3 = ref_element_addr %2 : $Z, #Z.y - store %0 to %3 : $*Y - %5 = ref_element_addr %2 : $Z, #Z.y2 - store %1 to %5 : $*Y - strong_release %2 : $Z - %9 = tuple () - return %9 : $() -} - -// CHECK-LABEL: Escape information for propagate_types_through_phi_args: -// CHECK: - : %0 = alloc_ref $Y -// CHECK: global: %1 = alloc_ref $Y -// CHECK: - : %3 = alloc_ref $Z -// CHECK: - : %5 = alloc_ref $Z -// CHECK: - : %6 = alloc_ref $DerivedZ -// CHECK: End function propagate_types_through_phi_args -sil @propagate_types_through_phi_args : $@convention(thin) () -> () { -bb0: - %0 = alloc_ref $Y - %1 = alloc_ref $Y - cond_br undef, bb1, bb2 -bb1: - %3 = alloc_ref $Z - br bb3(%3 : $Z, %3 : $Z) -bb2: - %5 = alloc_ref $Z - %6 = alloc_ref $DerivedZ - %7 = upcast %6 : $DerivedZ to $Z - br bb3(%5 : $Z, %7 : $Z) -bb3(%9 : $Z, %10 : $Z): - %11 = ref_element_addr %9 : $Z, #Z.y2 - store %0 to %11 : $*Y - %13 = ref_element_addr %10 : $Z, #Z.y2 - store %1 to %13 : $*Y - strong_release %9 : $Z - strong_release %10 : $Z - %17 = tuple () - return %17 : $() -} - -// CHECK-LABEL: Escape information for no_known_type_of_loaded_ref: -// CHECK: global: %0 = alloc_ref $X -// CHECK: - : %1 = alloc_ref $Y -// CHECK: - : %2 = alloc_ref $Z -// CHECK: End function no_known_type_of_loaded_ref -sil @no_known_type_of_loaded_ref : $@convention(thin) () -> () { -bb0: - %0 = alloc_ref $X - %1 = alloc_ref $Y - %2 = alloc_ref $Z - %3 = ref_element_addr %2 : $Z, #Z.y2 - store %1 to %3 : $*Y - %5 = load %3 : $*Y - %6 = ref_element_addr %5 : $Y, #Y.s - %7 = struct_element_addr %6 : $*Str, #Str.a - store %0 to %7 : $*X - strong_release %5 : $Y - %17 = tuple () - return %17 : $() -} - -// CHECK-LABEL: Escape information for known_type_through_callee: -// CHECK: - : %0 = alloc_ref $Y -// CHECK: global: %1 = alloc_ref $Y -// CHECK: - : %2 = alloc_ref $Z -// CHECK: - : %3 = alloc_ref $Z -// CHECK: End function known_type_through_callee -sil @known_type_through_callee : $@convention(thin) () -> () { -bb0: - %0 = alloc_ref $Y - %1 = alloc_ref $Y - %2 = alloc_ref $Z - %3 = alloc_ref $Z - %4 = function_ref @exclusive2 : $@convention(thin) (@owned Z) -> @owned Z - %5 = apply %4(%2) : $@convention(thin) (@owned Z) -> @owned Z - %6 = function_ref @nonexclusive2 : $@convention(thin) (@owned Z) -> @owned Z - %7 = apply %6(%3) : $@convention(thin) (@owned Z) -> @owned Z - %8 = ref_element_addr %5 : $Z, #Z.y2 - store %0 to %8 : $*Y - %10 = ref_element_addr %7 : $Z, #Z.y2 - store %1 to %10 : $*Y - strong_release %5 : $Z - strong_release %7 : $Z - %14 = tuple () - return %14 : $() -} - diff --git a/test/SILOptimizer/escape_info_objc.sil b/test/SILOptimizer/escape_info_objc.sil deleted file mode 100644 index 56dc693a25b..00000000000 --- a/test/SILOptimizer/escape_info_objc.sil +++ /dev/null @@ -1,81 +0,0 @@ -// RUN: %target-sil-opt %s -dump-escape-info -module-name=test -o /dev/null | %FileCheck %s - -// REQUIRES: swift_in_compiler -// REQUIRES: objc_interop -// REQUIRES: PTRSIZE=64 - -sil_stage canonical - -import Builtin -import Swift -import SwiftShims - -class X {} - -sil [escapes !%0, !%0.c*.v**] @$ss23_ContiguousArrayStorageCfD : $@convention(method) (@owned _ContiguousArrayStorage) -> () - -sil [defined_escapes %0 => %r.0.v**, %0.c*.v** => %r.0.v**.c*.v**, %0.c*.v** => %r.1.v**] @array_adopt_storage_class : $@convention(method) (@owned _ContiguousArrayStorage, Int, @thin Array.Type) -> (@owned Array, UnsafeMutablePointer) - -sil [escapes %0 => %r.0.s0.**] @array_adopt_storage : $@convention(thin) (@owned _ContiguousArrayStorage) -> (@owned Array, UnsafeMutablePointer) -sil @take_ptr : $@convention(thin) (UnsafeMutablePointer) -> () - -// CHECK-LABEL: Escape information for call_array_adopt_storage: -// CHECK: return[s0.**]: %0 = alloc_ref $_ContiguousArrayStorage -// CHECK: End function call_array_adopt_storage -sil @call_array_adopt_storage : $@convention(thin) () -> @owned Array { -bb0: - %0 = alloc_ref $_ContiguousArrayStorage - %1 = function_ref @array_adopt_storage : $@convention(thin) (@owned _ContiguousArrayStorage) -> (@owned Array, UnsafeMutablePointer) - %2 = apply %1(%0) : $@convention(thin) (@owned _ContiguousArrayStorage) -> (@owned Array, UnsafeMutablePointer) - %3 = tuple_extract %2 : $(Array, UnsafeMutablePointer), 0 - %4 = tuple_extract %2 : $(Array, UnsafeMutablePointer), 1 - %5 = function_ref @take_ptr : $@convention(thin) (UnsafeMutablePointer) -> () - %6 = apply %5(%4) : $@convention(thin) (UnsafeMutablePointer) -> () - return %3 : $Array -} - -// CHECK-LABEL: Escape information for release_array: -// CHECK: - : %1 = alloc_ref [tail_elems $Array * %0 : $Builtin.Word] $_ContiguousArrayStorage -// CHECK: - : %2 = alloc_ref $X -// CHECK: End function release_array -sil @release_array : $@convention(thin) () -> () { -bb0: - %0 = integer_literal $Builtin.Word, 2 - %1 = alloc_ref [tail_elems $Array * %0 : $Builtin.Word] $_ContiguousArrayStorage - %2 = alloc_ref $X - %3 = upcast %1 : $_ContiguousArrayStorage to $__ContiguousArrayStorageBase - %4 = ref_tail_addr %3 : $__ContiguousArrayStorageBase, $X - store %2 to %4 : $*X - %6 = enum $Optional<_ContiguousArrayStorage>, #Optional.some!enumelt, %1 : $_ContiguousArrayStorage - release_value %6 : $Optional<_ContiguousArrayStorage> - %10 = tuple () - return %10 : $() -} - -// CHECK-LABEL: Escape information for store_to_adopt_storage_result: -// CHECK: - : %3 = alloc_ref [tail_elems $X * %2 : $Builtin.Word] $_ContiguousArrayStorage -// CHECK: - : %11 = alloc_ref $X -// CHECK: End function store_to_adopt_storage_result -sil @store_to_adopt_storage_result : $@convention(thin) () -> () { -bb0: - %0 = integer_literal $Builtin.Int64, 1 - %1 = struct $Int (%0 : $Builtin.Int64) - %2 = integer_literal $Builtin.Word, 1 - %3 = alloc_ref [tail_elems $X * %2 : $Builtin.Word] $_ContiguousArrayStorage - %4 = metatype $@thin Array.Type - %5 = function_ref @array_adopt_storage_class : $@convention(method) (@owned _ContiguousArrayStorage, Int, @thin Array.Type) -> (@owned Array, UnsafeMutablePointer) - %6 = apply %5(%3, %1, %4) : $@convention(method) (@owned _ContiguousArrayStorage, Int, @thin Array.Type) -> (@owned Array, UnsafeMutablePointer) - %7 = tuple_extract %6 : $(Array, UnsafeMutablePointer), 0 - %8 = tuple_extract %6 : $(Array, UnsafeMutablePointer), 1 - %9 = struct_extract %8 : $UnsafeMutablePointer, #UnsafeMutablePointer._rawValue - %10 = pointer_to_address %9 : $Builtin.RawPointer to [strict] $*X - %11 = alloc_ref $X - store %11 to %10 : $*X - %13 = struct_extract %7 : $Array, #Array._buffer - %14 = struct_extract %13 : $_ArrayBuffer, #_ArrayBuffer._storage - %15 = struct_extract %14 : $_BridgeStorage<__ContiguousArrayStorageBase>, #_BridgeStorage.rawValue - strong_release %15 : $Builtin.BridgeObject - %17 = tuple () - return %17 : $() -} - diff --git a/test/SILOptimizer/existential_specializer_indirect_class.sil b/test/SILOptimizer/existential_specializer_indirect_class.sil index f2b0b15c8fd..416779e23fd 100644 --- a/test/SILOptimizer/existential_specializer_indirect_class.sil +++ b/test/SILOptimizer/existential_specializer_indirect_class.sil @@ -8,7 +8,7 @@ protocol ClassProtocol: AnyObject { func method() } class C: ClassProtocol { func method() {} } -// CHECK-LABEL: sil [signature_optimized_thunk] [always_inline] {{.*}}@test_indirect_class_protocol : $@convention(thin) (@in ClassProtocol) -> () +// CHECK-LABEL: sil [signature_optimized_thunk] [always_inline] @test_indirect_class_protocol : $@convention(thin) (@in ClassProtocol) -> () sil @test_indirect_class_protocol : $@convention(thin) (@in ClassProtocol) -> () { // CHECK-NEXT: // // CHECK-NEXT: bb0(%0 : $*ClassProtocol): @@ -40,7 +40,7 @@ bb0(%0 : $*ClassProtocol): } // Check that a specialization of test_indirect_class_protocol is created. -// CHECK-LABEL: sil shared [signature_optimized_thunk] [always_inline] {{.*}}@$s28test_indirect_class_protocolTf4e_n4main1CC_Tg5 : $@convention(thin) (@owned C) -> () +// CHECK-LABEL: sil shared [signature_optimized_thunk] [always_inline] @$s28test_indirect_class_protocolTf4e_n4main1CC_Tg5 : $@convention(thin) (@owned C) -> () // CHECK-NEXT: // // CHECK-NEXT: bb0(%0 : $C): // CHECK-NEXT: strong_release %0 diff --git a/test/SILOptimizer/fold_enums.sil b/test/SILOptimizer/fold_enums.sil index 36ac9123a59..8ac3ddfa297 100644 --- a/test/SILOptimizer/fold_enums.sil +++ b/test/SILOptimizer/fold_enums.sil @@ -157,7 +157,7 @@ public enum F { case F3(Float, Float, Float) } -// CHECK-LABEL: sil {{.*}}@_TF10fold_enums13recreate_enumFOS_1FS0_ +// CHECK-LABEL: sil @_TF10fold_enums13recreate_enumFOS_1FS0_ // CHECK: bb0(%0 : $F) // CHECK-NOT: bb1 // CHECK: return %0 : $F diff --git a/test/SILOptimizer/function_effects.sil b/test/SILOptimizer/function_effects.sil deleted file mode 100644 index 958bdd21b8b..00000000000 --- a/test/SILOptimizer/function_effects.sil +++ /dev/null @@ -1,315 +0,0 @@ -// RUN: %target-sil-opt %s -compute-effects | %FileCheck %s - -// REQUIRES: swift_in_compiler - -sil_stage canonical - -import Builtin -import Swift -import SwiftShims - -protocol ClassP : AnyObject { - func foo() -} - -class X : ClassP { - func foo() - deinit -} - -class Derived : X { -} - -struct Str { - @_hasStorage var a: X - @_hasStorage var b: (X, X) -} - -class Y { - @_hasStorage var s: Str -} - -class Z { - @_hasStorage var y: Y -} - -class DerivedZ : Z { -} - -class LinkedNode { - @_hasStorage var next: LinkedNode; - @_hasStorage var x: X; -} - -enum E { - case A(Z) - case B(Z) -} - -struct PointerAndInt { - @_hasStorage var p: UnsafeMutablePointer - @_hasStorage var i: Int -} - -sil_global @globalY : $Y - -sil [ossa] @unknown_function : $@convention(thin) (@owned X) -> () -sil [ossa] @unknown_function_y : $@convention(thin) (@owned Y) -> () - -// CHECK-LABEL: sil [escapes %1.v** => %3.v**, !%2, %2.c*.v** -> %r.v**, !%3] [ossa] @test_basic -sil [ossa] @test_basic : $@convention(thin) (@owned X, @guaranteed Str, @guaranteed Z, @inout X) -> @owned Y { -bb0(%0 : @owned $X, %1 : @guaranteed $Str, %2 : @guaranteed $Z, %3 : $*X): - // %0 escapes to global - %4 = function_ref @unknown_function : $@convention(thin) (@owned X) -> () - %5 = apply %4(%0) : $@convention(thin) (@owned X) -> () - - // %1 escapes to argument %3 - %6 = struct_extract %1 : $Str, #Str.a - %7 = copy_value %6 : $X - store %7 to [assign] %3 : $*X - - // content of %2 escapes to return - // %2 does not escape - %8 = ref_element_addr %2 : $Z, #Z.y - %9 = load [copy] %8 : $*Y - return %9 : $Y -} - -// CHECK-LABEL: sil [escapes %0 => %r, %0.c*.v** => %r.c*.v**] @simple_forwarding -sil @simple_forwarding : $@convention(thin) (@owned Z) -> @owned Z { -bb0(%0 : $Z): - return %0 : $Z -} - -// CHECK-LABEL: sil [escapes %0.v** => %r.v**, %0.v**.c*.v** => %r.v**.c*.v**] @forwarding_struct_element -sil @forwarding_struct_element : $@convention(thin) (@owned Str) -> @owned X { -bb0(%0 : $Str): - %1 = struct_extract %0 : $Str, #Str.a - return %1 : $X -} - -// CHECK-LABEL: sil [escapes %0 => %r.s1.0, %0.c*.v** => %r.s1.0.c*.v**, %1 => %r.s1.1, %1.c*.v** => %r.s1.1.c*.v**, %2 => %r.s0, %2.c*.v** => %r.s0.c*.v**] @forwarding_in_struct -sil @forwarding_in_struct : $@convention(thin) (@owned X, @owned X, @owned X) -> @owned Str { -bb0(%0 : $X, %1 : $X, %2: $X): - %3 = tuple (%0 : $X, %1 : $X) - %4 = struct $Str(%2 : $X, %3 : $(X, X)) - return %4 : $Str -} - -// CHECK-LABEL: sil [escapes %0 -> %r.v**, %0.c*.v** -> %r.v**.c*.v**] @forwarding_same_arg_in_struct -sil @forwarding_same_arg_in_struct : $@convention(thin) (@owned X) -> @owned Str { -bb0(%0 : $X): - %1 = tuple (%0 : $X, %0 : $X) - %2 = struct $Str(%0 : $X, %1 : $(X, X)) - return %2 : $Str -} - -// CHECK-LABEL: sil [escapes !%0] [ossa] @test_escaping_content -sil [ossa] @test_escaping_content : $@convention(thin) (@guaranteed Z) -> () { -bb0(%0 : @guaranteed $Z): - %1 = ref_element_addr %0 : $Z, #Z.y - %2 = load [copy] %1 : $*Y - %3 = function_ref @unknown_function_y : $@convention(thin) (@owned Y) -> () - %4 = apply %3(%2) : $@convention(thin) (@owned Y) -> () - %5 = tuple () - return %5 : $() -} - -// CHECK-LABEL: sil [escapes !%0.**] @not_escaping_argument -sil @not_escaping_argument : $@convention(thin) (@guaranteed Z) -> () { -bb0(%0 : $Z): - %1 = ref_element_addr %0 : $Z, #Z.y - %2 = global_addr @globalY : $*Y - // Even a store does not make the argument escaping. - copy_addr %2 to [initialization] %1 : $*Y - %4 = tuple () - return %4 : $() -} - -// CHECK-LABEL: sil [escapes %0 -> %r, %0.c*.v** -> %r.c*.v**] @load_from_inout -sil @load_from_inout : $@convention(thin) (@inout Y) -> @owned Y { -bb0(%0 : $*Y): - %2 = load %0 : $*Y - return %2 : $Y -} - -// CHECK-LABEL: sil [escapes !%0, %0.c*.v** -> %r.v**, !%1] [ossa] @followstore_implies_non_exclusive -sil [ossa] @followstore_implies_non_exclusive : $@convention(thin) (@guaranteed Z, @owned Y) -> @owned Y { -bb0(%0 : @guaranteed $Z, %1 : @owned $Y): - %2 = ref_element_addr %0 : $Z, #Z.y - %3 = load [copy] %2 : $*Y - destroy_value %1 : $Y - return %3 : $Y -} - -// CHECK-LABEL: sil [escapes !%0, %0.c*.v** -> %r.v**, %1 -> %r] [ossa] @test_not_exclusive_escaping_through_phi -sil [ossa] @test_not_exclusive_escaping_through_phi : $@convention(thin) (@guaranteed Z, @owned Y) -> @owned Y { -bb0(%0 : @guaranteed $Z, %1 : @owned $Y): - cond_br undef, bb1, bb2 -bb1: - %3 = ref_element_addr %0 : $Z, #Z.y - %4 = load [copy] %3 : $*Y - destroy_value %1 : $Y - br bb3(%4 : $Y) -bb2: - br bb3(%1 : $Y) - -bb3(%7: @owned $Y): - return %7 : $Y -} - -// CHECK-LABEL: sil [escapes !%0, %0.c*.v** -> %r.v**] [ossa] @test_not_exclusive_through_store -sil [ossa] @test_not_exclusive_through_store : $@convention(thin) (@guaranteed Z, @owned Y) -> @owned Y { -bb0(%0 : @guaranteed $Z, %1 : @owned $Y): - %2 = ref_element_addr %0 : $Z, #Z.y - %3 = load [copy] %2 : $*Y - store %1 to [assign] %2 : $*Y - return %3 : $Y -} - -sil [escapes %0.v** => %0.v**] [ossa] @self_arg_callee : $@convention(thin) (@inout Str) -> () - -// CHECK-LABEL: sil [escapes %0.v** => %0.v**] [ossa] @test_self_arg_escape -sil [ossa] @test_self_arg_escape : $@convention(thin) (@inout Str) -> () { -bb0(%0 : $*Str): - %1 = function_ref @self_arg_callee : $@convention(thin) (@inout Str) -> () - %2 = apply %1(%0) : $@convention(thin) (@inout Str) -> () - %3 = tuple () - return %3 : $() -} - -// CHECK-LABEL: sil [escapes %0.v** => %0.s1.0.v**] [ossa] @test_self_arg_escape_with_copy -sil [ossa] @test_self_arg_escape_with_copy : $@convention(thin) (@inout Str) -> () { -bb0(%0 : $*Str): - %1 = struct_element_addr %0 : $*Str, #Str.a - %2 = struct_element_addr %0 : $*Str, #Str.b - %3 = tuple_element_addr %2 : $*(X,X), 0 - copy_addr %1 to %3 : $*X - %5 = tuple () - return %5 : $() -} - -// CHECK-LABEL: sil [escapes %0.v** => %0.v**] [ossa] @test_self_arg_escape_with_bidirectional_copy -sil [ossa] @test_self_arg_escape_with_bidirectional_copy : $@convention(thin) (@inout Str) -> () { -bb0(%0 : $*Str): - %1 = struct_element_addr %0 : $*Str, #Str.a - %2 = struct_element_addr %0 : $*Str, #Str.b - %3 = tuple_element_addr %2 : $*(X,X), 0 - copy_addr %1 to %3 : $*X - copy_addr %3 to %1 : $*X - %5 = tuple () - return %5 : $() -} - -// CHECK-LABEL: sil [escapes !%0.**, !%1, %1.c*.v** => %0.v**] [ossa] @test_content_to_arg_addr -sil [ossa] @test_content_to_arg_addr : $@convention(thin) (@guaranteed Y) -> @out Str { -bb0(%0 : $*Str, %1 : @guaranteed $Y): - %2 = ref_element_addr %1 : $Y, #Y.s - %3 = begin_access [read] [dynamic] %2 : $*Str - copy_addr %3 to [initialization] %0 : $*Str - end_access %3 : $*Str - %6 = tuple () - return %6 : $() -} - -// CHECK-LABEL: sil [escapes %0.v** => %r.v**, %0.v**.c*.v** => %r.v**.c*.v**] @escaping_pointer -sil @escaping_pointer : $@convention(thin) (PointerAndInt) -> UnsafeMutablePointer { -bb0(%0 : $PointerAndInt): - %1 = struct_extract %0 : $PointerAndInt, #PointerAndInt.p - return %1 : $UnsafeMutablePointer -} - -// CHECK-LABEL: sil [escapes !%0.**] @not_escaping_int -sil @not_escaping_int : $@convention(thin) (PointerAndInt) -> Int { -bb0(%0 : $PointerAndInt): - %1 = struct_extract %0 : $PointerAndInt, #PointerAndInt.i - return %1 : $Int -} - -// CHECK-LABEL: sil [escapes !%0.**] @test_simple_recursion -sil @test_simple_recursion : $@convention(thin) (@guaranteed Y) -> () { -bb0(%0 : $Y): - cond_br undef, bb1, bb2 - -bb1: - %2 = function_ref @test_simple_recursion : $@convention(thin) (@guaranteed Y) -> () - %3 = apply %2(%0) : $@convention(thin) (@guaranteed Y) -> () - br bb3 - -bb2: - br bb3 - -bb3: - %5 = tuple () - return %5 : $() -} - -// CHECK-LABEL: sil @test_recursion_with_escaping_param -sil @test_recursion_with_escaping_param : $@convention(thin) (@guaranteed Y, @guaranteed Y) -> Y { -bb0(%0 : $Y, %1 : $Y): - cond_br undef, bb1, bb2 - -bb1: - %2 = function_ref @test_recursion_with_escaping_param : $@convention(thin) (@guaranteed Y, @guaranteed Y) -> Y - %3 = apply %2(%1, %0) : $@convention(thin) (@guaranteed Y, @guaranteed Y) -> Y - br bb3(%3 : $Y) - -bb2: - br bb3(%1 : $Y) - -bb3(%5 : $Y): - return %5 : $Y -} - -// CHECK-LABEL: [escapes !%0.**] @inout_class_argument -sil @inout_class_argument : $@convention(thin) (@inout X) -> () { -bb0(%0 : $*X): - %1 = alloc_ref $X - store %1 to %0: $*X - %3 = tuple() - return %3 : $() -} - -// CHECK-LABEL: sil [escapes %0 -> %r, %0.c*.v** -> %r.c*.v**] @load_and_store_to_inout -sil @load_and_store_to_inout : $@convention(thin) (@inout Z, @guaranteed Y) -> Z { -bb0(%0 : $*Z, %1 : $Y): - %2 = load %0 : $*Z - %3 = ref_element_addr %2 : $Z, #Z.y - store %1 to %3 : $*Y - return %2 : $Z -} - -// CHECK-LABEL: sil [escapes %0 => %r, %0.c*.v** => %r.c*.v**] @store_to_content -sil @store_to_content : $@convention(thin) (@owned Z, @guaranteed Y) -> @owned Z { -bb0(%0 : $Z, %1 : $Y): - %2 = ref_element_addr %0 : $Z, #Z.y - store %1 to %2 : $*Y - return %0 : $Z -} - -// CHECK-LABEL: sil [escapes !%1.**] @non_returning_function -sil @non_returning_function : $@convention(thin) (Str, @inout Str) -> () { -bb0(%0 : $Str, %1 : $*Str): - store %0 to %1 : $*Str - unreachable -} - -// CHECK-LABEL: sil [escapes !%0] @followStore_introducing1 -sil @followStore_introducing1 : $@convention(thin) (@guaranteed Z) -> @owned Y { -bb0(%0 : $Z): - %1 = ref_element_addr %0 : $Z, #Z.y - %2 = load %1 : $*Y - store %2 to %1 : $*Y - %4 = load %1 : $*Y - return %4 : $Y -} - -// CHECK-LABEL: sil [escapes !%0.**] @followStore_introducing2 -sil @followStore_introducing2 : $@convention(thin) (@inout Z, @guaranteed Y) -> () { -bb0(%0 : $*Z, %1 : $Y): - %2 = load %0 : $*Z - %3 = ref_element_addr %2 : $Z, #Z.y - store %1 to %3 : $*Y - %5 = tuple () - return %5 : $() -} diff --git a/test/SILOptimizer/function_effects_objc.sil b/test/SILOptimizer/function_effects_objc.sil deleted file mode 100644 index 291651321e9..00000000000 --- a/test/SILOptimizer/function_effects_objc.sil +++ /dev/null @@ -1,52 +0,0 @@ -// RUN: %target-sil-opt %s -compute-effects | %FileCheck %s - -// REQUIRES: swift_in_compiler -// REQUIRES: objc_interop -// REQUIRES: PTRSIZE=64 - -sil_stage canonical - -import Builtin -import Swift -import SwiftShims - -class Y { - @_hasStorage var i: Int -} - -// CHECK-LABEL: sil [escapes %0 => %r.0.s0.s0.s0, %0.c*.v** -> %r.**] @array_adopt_storage -sil @array_adopt_storage : $@convention(thin) (@owned _ContiguousArrayStorage) -> (@owned Array, UnsafeMutablePointer) { -bb0(%0 : $_ContiguousArrayStorage): - %3 = upcast %0 : $_ContiguousArrayStorage to $__ContiguousArrayStorageBase - %12 = unchecked_ref_cast %0 : $_ContiguousArrayStorage to $Builtin.BridgeObject - %13 = struct $_BridgeStorage<__ContiguousArrayStorageBase> (%12 : $Builtin.BridgeObject) - %14 = struct $_ArrayBuffer (%13 : $_BridgeStorage<__ContiguousArrayStorageBase>) - %15 = struct $Array (%14 : $_ArrayBuffer) - %16 = ref_tail_addr %3 : $__ContiguousArrayStorageBase, $Y - %17 = address_to_pointer %16 : $*Y to $Builtin.RawPointer - %18 = struct $UnsafeMutablePointer (%17 : $Builtin.RawPointer) - %19 = tuple (%15 : $Array, %18 : $UnsafeMutablePointer) - return %19 : $(Array, UnsafeMutablePointer) -} - -// CHECK-LABEL: sil [escapes !%0, !%0.c*.v**] @array_destructor -sil @array_destructor : $@convention(method) (@owned _ContiguousArrayStorage) -> () { -bb0(%0 : $_ContiguousArrayStorage): - %1 = ref_tail_addr %0 : $_ContiguousArrayStorage, $Element - %2 = address_to_pointer %1 : $*Element to $Builtin.RawPointer - %3 = upcast %0 : $_ContiguousArrayStorage to $__ContiguousArrayStorageBase - %4 = ref_element_addr %3 : $__ContiguousArrayStorageBase, #__ContiguousArrayStorageBase.countAndCapacity - %5 = struct_element_addr %4 : $*_ArrayBody, #_ArrayBody._storage - %6 = struct_element_addr %5 : $*_SwiftArrayBodyStorage, #_SwiftArrayBodyStorage.count - %7 = struct_element_addr %6 : $*Int, #Int._value - %8 = load %7 : $*Builtin.Int64 - %9 = builtin "assumeNonNegative_Int64"(%8 : $Builtin.Int64) : $Builtin.Int64 - %10 = metatype $@thick Element.Type - %11 = builtin "truncOrBitCast_Int64_Word"(%9 : $Builtin.Int64) : $Builtin.Word - %12 = builtin "destroyArray"(%10 : $@thick Element.Type, %2 : $Builtin.RawPointer, %11 : $Builtin.Word) : $() - fix_lifetime %0 : $_ContiguousArrayStorage - dealloc_ref %0 : $_ContiguousArrayStorage - %15 = tuple () - return %15 : $() -} - diff --git a/test/SILOptimizer/generic_loop.swift b/test/SILOptimizer/generic_loop.swift index 51258274d41..55facdb5ab6 100644 --- a/test/SILOptimizer/generic_loop.swift +++ b/test/SILOptimizer/generic_loop.swift @@ -6,7 +6,7 @@ // Check that we can eliminate all optionals from a loop which is iterating // over an array of address-only elements. -// CHECK-LABEL: sil {{.*}}@$s4test0A18_no_optionals_usedyySayxGlF : $@convention(thin) (@guaranteed Array) -> () { +// CHECK-LABEL: sil @$s4test0A18_no_optionals_usedyySayxGlF : $@convention(thin) (@guaranteed Array) -> () { // CHECK-NOT: Optional // CHECK: } // end sil function '$s4test0A18_no_optionals_usedyySayxGlF' public func test_no_optionals_used(_ items: [T]) { diff --git a/test/SILOptimizer/inline_generic_coroutines.swift b/test/SILOptimizer/inline_generic_coroutines.swift index 5c82d0f595f..939db2c77a2 100644 --- a/test/SILOptimizer/inline_generic_coroutines.swift +++ b/test/SILOptimizer/inline_generic_coroutines.swift @@ -8,7 +8,7 @@ func useit(_ t: T) { // Check that we inline the Array.subscript.read coroutine -// CHECK-LABEL: sil {{.*@.*}}testit +// CHECK-LABEL: sil @{{.*}}testit // CHECK-NOT: begin_apply // CHECK-NOT: end_apply // CHECK: } // end sil function {{.*}}testit diff --git a/test/SILOptimizer/inline_self.swift b/test/SILOptimizer/inline_self.swift index a988efe5cb2..d8919e1d45f 100644 --- a/test/SILOptimizer/inline_self.swift +++ b/test/SILOptimizer/inline_self.swift @@ -71,7 +71,7 @@ class Z : BaseZ { _ = Z().capturesSelf() -// CHECK-LABEL: sil {{.*}}@main : $@convention(c) +// CHECK-LABEL: sil @main : $@convention(c) // CHECK: function_ref static inline_self.C.factory(Swift.Int) -> Self // CHECK: [[F:%[0-9]+]] = function_ref @$s11inline_self1CC7factory{{[_0-9a-zA-Z]*}}FZ : $@convention(method) (Int, @thick C.Type) -> @owned C // CHECK: apply [[F]](%{{.+}}, %{{.+}}) : $@convention(method) (Int, @thick C.Type) -> @owned C diff --git a/test/SILOptimizer/let_propagation.swift b/test/SILOptimizer/let_propagation.swift index 62c90c558d6..2c390774c4c 100644 --- a/test/SILOptimizer/let_propagation.swift +++ b/test/SILOptimizer/let_propagation.swift @@ -226,7 +226,7 @@ struct A1 { class A2 { let x: B2 = B2() - // CHECK-LABEL: sil hidden {{.*}}@$s15let_propagation2A2C2af{{[_0-9a-zA-Z]*}}F + // CHECK-LABEL: sil hidden @$s15let_propagation2A2C2af{{[_0-9a-zA-Z]*}}F // bb0 // CHECK: %[[X:[0-9]+]] = ref_element_addr {{.*}}A2.x // CHECK-NEXT: load %[[X]] diff --git a/test/SILOptimizer/licm_exclusivity.swift b/test/SILOptimizer/licm_exclusivity.swift index d8cb8b248ae..7ada653d674 100644 --- a/test/SILOptimizer/licm_exclusivity.swift +++ b/test/SILOptimizer/licm_exclusivity.swift @@ -69,7 +69,7 @@ public class ClassWithArrs { // TESTLICMWMO: Successfully hoisted and sank pair // TESTLICMWMO: Hoisted // TESTLICMWMO: Successfully hoisted and sank pair -// TESTSILWMO-LABEL: sil {{.*}}@$s16licm_exclusivity13ClassWithArrsC7readArryyF : $@convention(method) (@guaranteed ClassWithArrs) -> () { +// TESTSILWMO-LABEL: sil @$s16licm_exclusivity13ClassWithArrsC7readArryyF : $@convention(method) (@guaranteed ClassWithArrs) -> () { // TESTSILWMO: [[R1:%.*]] = ref_element_addr %0 : $ClassWithArrs, #ClassWithArrs.A // TESTSILWMO: [[R2:%.*]] = ref_element_addr %0 : $ClassWithArrs, #ClassWithArrs.B // TESTSILWMO: begin_access [read] [static] [no_nested_conflict] [[R1]] diff --git a/test/SILOptimizer/opened_archetype_operands_tracking.sil b/test/SILOptimizer/opened_archetype_operands_tracking.sil index 69708c468b2..995a632906d 100644 --- a/test/SILOptimizer/opened_archetype_operands_tracking.sil +++ b/test/SILOptimizer/opened_archetype_operands_tracking.sil @@ -34,7 +34,7 @@ bb0: return %2 : $() } -// CHECK-LABEL: sil {{.*}}@process +// CHECK-LABEL: sil @process // CHECK: bb0 // CHECK-NOT: try_apply // CHECK-NOT: unreachable @@ -241,7 +241,7 @@ bb0(%0 : $Int32): // was not aware of the opened archetype definition that becomes unused and gets removed // after the inlining. // -// CHECK-LABEL: sil {{.*}}@check_removal_of_unregistered_archetype_def +// CHECK-LABEL: sil @check_removal_of_unregistered_archetype_def // CHECK-NOT: init_existential // CHECK-NOT: open_existential // CHECK-NOT: function_ref @@ -274,7 +274,7 @@ class C { init() } -// CHECK-SIMPLIFY-CFG-LABEL: sil {{.*}}@test_infinite_loop_in_unreachable_block +// CHECK-SIMPLIFY-CFG-LABEL: sil @test_infinite_loop_in_unreachable_block // CHECK-SIMPLIFY-CFG: bb0 // CHECK-SIMPLIFY-CFG-NOT: bb1 // CHECK-SIMPLIFY-CFG: end sil function 'test_infinite_loop_in_unreachable_block' diff --git a/test/SILOptimizer/opt_enumerate.swift b/test/SILOptimizer/opt_enumerate.swift index dd2ad4cc0d1..3d17f989d48 100644 --- a/test/SILOptimizer/opt_enumerate.swift +++ b/test/SILOptimizer/opt_enumerate.swift @@ -8,14 +8,14 @@ func take(_ x: Int, _ y: Int) { gg = x + y } -// CHECK-LABEL: sil {{.*}}@$s4test23check_cond_fail_messageySiSaySiGF +// CHECK-LABEL: sil @$s4test23check_cond_fail_messageySiSaySiGF // CHECK: cond_fail {{.*}} "Index out of range" // CHECK: // end sil function '$s4test23check_cond_fail_messageySiSaySiGF' public func check_cond_fail_message(_ array: [Int]) -> Int { return array[2] } -// CHECK-LABEL: sil {{.*}}@$s4test22eliminate_bounds_checkyySaySiGF +// CHECK-LABEL: sil @$s4test22eliminate_bounds_checkyySaySiGF // CHECK-NOT: cond_fail {{.*}} "Index out of range" // CHECK: // end sil function '$s4test22eliminate_bounds_checkyySaySiGF' public func eliminate_bounds_check(_ array: [Int]) { @@ -24,7 +24,7 @@ public func eliminate_bounds_check(_ array: [Int]) { } } -// CHECK-LABEL: sil {{.*}}@$s4test27eliminate_two_bounds_checksyySaySiGF +// CHECK-LABEL: sil @$s4test27eliminate_two_bounds_checksyySaySiGF // CHECK-NOT: cond_fail {{.*}} "Index out of range" // CHECK: // end sil function '$s4test27eliminate_two_bounds_checksyySaySiGF' public func eliminate_two_bounds_checks(_ array: [Int]) { diff --git a/test/SILOptimizer/outliner.swift b/test/SILOptimizer/outliner.swift index 43a0b854eb1..99b2209f2a5 100644 --- a/test/SILOptimizer/outliner.swift +++ b/test/SILOptimizer/outliner.swift @@ -14,7 +14,7 @@ public class MyGizmo { gizmo = Gizmo() } - // CHECK-LABEL: sil {{.*}}@$s8outliner7MyGizmoC11usePropertyyyF : + // CHECK-LABEL: sil @$s8outliner7MyGizmoC11usePropertyyyF : // CHECK: [[P_FUN:%.*]] = function_ref @$sSo5GizmoC14stringPropertySSSgvgToTepb_ // CHECK: apply [[P_FUN]]({{.*}}) : $@convention(thin) (Gizmo) -> @owned Optional // CHECK-NOT: return diff --git a/test/SILOptimizer/pre_specialize-macos.swift b/test/SILOptimizer/pre_specialize-macos.swift index 7c2e17c92e9..71b2236d59f 100644 --- a/test/SILOptimizer/pre_specialize-macos.swift +++ b/test/SILOptimizer/pre_specialize-macos.swift @@ -26,5 +26,5 @@ public func usePrespecializedEntryPoints() { publicPrespecialized2(SomeOtherData()) } -// OPT: sil [available 10.50] [noinline] {{.*}}@$s22pre_specialized_module21publicPrespecialized2yyxlFAA8SomeDataV_Ts5 : $@convention(thin) (SomeData) -> () -// OPT: sil [available 10.50] [noinline] {{.*}}@$s22pre_specialized_module21publicPrespecialized2yyxlF0a1_B8_module213SomeOtherDataV_Ts5 : $@convention(thin) (SomeOtherData) -> () +// OPT: sil [available 10.50] [noinline] @$s22pre_specialized_module21publicPrespecialized2yyxlFAA8SomeDataV_Ts5 : $@convention(thin) (SomeData) -> () +// OPT: sil [available 10.50] [noinline] @$s22pre_specialized_module21publicPrespecialized2yyxlF0a1_B8_module213SomeOtherDataV_Ts5 : $@convention(thin) (SomeOtherData) -> () diff --git a/test/SILOptimizer/reverse-array.swift b/test/SILOptimizer/reverse-array.swift index 41a966ac538..8cea9dffe98 100644 --- a/test/SILOptimizer/reverse-array.swift +++ b/test/SILOptimizer/reverse-array.swift @@ -26,7 +26,7 @@ public func reverseArray(_ a: [Int]) -> [Int] { } -// CHECK-LABEL: sil [noinline] {{.*}}@$s4test12reverseArrayySaySiGACF +// CHECK-LABEL: sil [noinline] @$s4test12reverseArrayySaySiGACF // There must not be more than two begin_cow_mutation - end_cow_mutation pairs: // * the first one for the initial reserveCapacity diff --git a/test/SILOptimizer/sil_combine_concrete_existential.swift b/test/SILOptimizer/sil_combine_concrete_existential.swift index c26196bff04..5a840d7ffbc 100644 --- a/test/SILOptimizer/sil_combine_concrete_existential.swift +++ b/test/SILOptimizer/sil_combine_concrete_existential.swift @@ -123,7 +123,7 @@ extension P where Self : Q { public class C_PQ: P & Q {} // testExtensionProtocolComposition(c:) -// CHECK-LABEL: sil {{.*}}@$s32sil_combine_concrete_existential32testExtensionProtocolComposition1cyAA4C_PQC_tF : $@convention(thin) (@guaranteed C_PQ) -> () { +// CHECK-LABEL: sil @$s32sil_combine_concrete_existential32testExtensionProtocolComposition1cyAA4C_PQC_tF : $@convention(thin) (@guaranteed C_PQ) -> () { // CHECK-NOT: init_existential_ref // CHECK-NOT: function_ref // CHECK-NOT: apply diff --git a/test/SILOptimizer/sil_combine_protocol_conf.swift b/test/SILOptimizer/sil_combine_protocol_conf.swift index 98c0d20e952..1cff4ffae16 100644 --- a/test/SILOptimizer/sil_combine_protocol_conf.swift +++ b/test/SILOptimizer/sil_combine_protocol_conf.swift @@ -113,7 +113,7 @@ public class Other { self.s = s; } -// CHECK-LABEL: sil [noinline] {{.*}}@$s25sil_combine_protocol_conf5OtherC11doWorkClassSiyF : $@convention(method) (@guaranteed Other) -> Int { +// CHECK-LABEL: sil [noinline] @$s25sil_combine_protocol_conf5OtherC11doWorkClassSiyF : $@convention(method) (@guaranteed Other) -> Int { // CHECK: bb0 // CHECK: debug_value // CHECK: integer_literal @@ -234,7 +234,7 @@ public class OtherClass { self.arg4 = arg4 } -// CHECK-LABEL: sil [noinline] {{.*}}@$s25sil_combine_protocol_conf10OtherClassC12doWorkStructSiyF : $@convention(method) (@guaranteed OtherClass) -> Int { +// CHECK-LABEL: sil [noinline] @$s25sil_combine_protocol_conf10OtherClassC12doWorkStructSiyF : $@convention(method) (@guaranteed OtherClass) -> Int { // CHECK: bb0([[ARG:%.*]] : // CHECK: debug_value // CHECK: [[R1:%.*]] = ref_element_addr [[ARG]] : $OtherClass, #OtherClass.arg1 @@ -335,7 +335,7 @@ public class OtherKlass { self.arg2 = arg2 } -// CHECK-LABEL: sil [noinline] {{.*}}@$s25sil_combine_protocol_conf10OtherKlassC10doWorkEnumSiyF : $@convention(method) (@guaranteed OtherKlass) -> Int { +// CHECK-LABEL: sil [noinline] @$s25sil_combine_protocol_conf10OtherKlassC10doWorkEnumSiyF : $@convention(method) (@guaranteed OtherKlass) -> Int { // CHECK: bb0([[ARG:%.*]] : // CHECK: debug_value // CHECK: integer_literal diff --git a/test/SILOptimizer/simplify_switch_enum_objc.swift b/test/SILOptimizer/simplify_switch_enum_objc.swift index 4f87c40c05b..35598c004cc 100644 --- a/test/SILOptimizer/simplify_switch_enum_objc.swift +++ b/test/SILOptimizer/simplify_switch_enum_objc.swift @@ -28,7 +28,7 @@ public class InClass { var t: Test? var v: Test? -// CHECK-LABEL: sil {{.*}}@$s20objc_bridged_results7InClassC20testOptionalShortCutyyF +// CHECK-LABEL: sil @$s20objc_bridged_results7InClassC20testOptionalShortCutyyF // CHECK: bb0 // CHECK: switch_enum // CHECK: bb1 @@ -43,7 +43,7 @@ public class InClass { t?.other = v?.other } -// CHECK-LABEL: sil {{.*}}@$s20objc_bridged_results7InClassC21testOptionalShortCut2yyF +// CHECK-LABEL: sil @$s20objc_bridged_results7InClassC21testOptionalShortCut2yyF // CHECK: bb0 // CHECK: switch_enum // CHECK: bb1 diff --git a/test/SILOptimizer/spec_conf1.swift b/test/SILOptimizer/spec_conf1.swift index a7668ae42ab..ab18f49dba6 100644 --- a/test/SILOptimizer/spec_conf1.swift +++ b/test/SILOptimizer/spec_conf1.swift @@ -19,7 +19,7 @@ func inner_function(In In : T) { } @inline(never) func outer_function(In In : T) { inner_function(In: In) } -//CHECK: sil shared [noinline] {{.*}}@$s10spec_conf114outer_function2Inyx_tAA1PRzlFAA3FooC_Tg5 +//CHECK: sil shared [noinline] @$s10spec_conf114outer_function2Inyx_tAA1PRzlFAA3FooC_Tg5 //CHECK: $s10spec_conf114inner_function2Inyx_tAA1PRzlFAA3FooC_Tg5 //CHECK-NEXT: apply //CHECK: return diff --git a/test/SILOptimizer/spec_conf2.swift b/test/SILOptimizer/spec_conf2.swift index 6be2eb4c3e8..c146992ae5b 100644 --- a/test/SILOptimizer/spec_conf2.swift +++ b/test/SILOptimizer/spec_conf2.swift @@ -18,7 +18,7 @@ func inner_function(In In : T) { } @inline(never) func outer_function(In In : T) { inner_function(In: In) } -//CHECK: sil shared [noinline] {{.*}}@$s10spec_conf214outer_function2Inyx_tAA1PRzAA1QRzlFAA3FooC_Tg5 +//CHECK: sil shared [noinline] @$s10spec_conf214outer_function2Inyx_tAA1PRzAA1QRzlFAA3FooC_Tg5 //CHECK: function_ref @$s10spec_conf214inner_function2Inyx_tAA1PRzAA1QRzlFAA3FooC_Tg5 //CHECK-NEXT: apply //CHECK: return diff --git a/test/SILOptimizer/specialize_checked_cast_branch.swift b/test/SILOptimizer/specialize_checked_cast_branch.swift index 738659b6072..a22804aa295 100644 --- a/test/SILOptimizer/specialize_checked_cast_branch.swift +++ b/test/SILOptimizer/specialize_checked_cast_branch.swift @@ -25,7 +25,7 @@ public func ArchetypeToArchetypeCast(t1 : T1, t2 : T2) -> T2 { preconditionFailure("??? Profit?") } -// CHECK-LABEL: sil shared {{.*}}@$s30specialize_checked_cast_branch011ArchetypeToE4Cast2t12t2q_x_q_tr0_lFAA1CC_AA1DCTg5 : $@convention(thin) (@guaranteed C, @guaranteed D) -> @owned D +// CHECK-LABEL: sil shared @$s30specialize_checked_cast_branch011ArchetypeToE4Cast2t12t2q_x_q_tr0_lFAA1CC_AA1DCTg5 : $@convention(thin) (@guaranteed C, @guaranteed D) -> @owned D // CHECK: bb0([[ARG:%.*]] : $C, [[ARG2:%.*]] : $D): // CHECK: checked_cast_br [[ARG]] : $C to D, bb1, bb2 // @@ -40,7 +40,7 @@ public func ArchetypeToArchetypeCast(t1 : T1, t2 : T2) -> T2 { _ = ArchetypeToArchetypeCast(t1: c, t2: d) // x -> x where x is a class. -// CHECK-LABEL: sil shared {{.*}}@$s30specialize_checked_cast_branch011ArchetypeToE4Cast2t12t2q_x_q_tr0_lFAA1CC_AFTg5 : $@convention(thin) (@guaranteed C, @guaranteed C) -> @owned C { +// CHECK-LABEL: sil shared @$s30specialize_checked_cast_branch011ArchetypeToE4Cast2t12t2q_x_q_tr0_lFAA1CC_AFTg5 : $@convention(thin) (@guaranteed C, @guaranteed C) -> @owned C { // CHECK: bb0 // CHECK-NOT: bb1 // CHECK: strong_retain %0 : $C @@ -55,7 +55,7 @@ _ = ArchetypeToArchetypeCast(t1: b, t2: b) _ = ArchetypeToArchetypeCast(t1: b, t2: f) // x -> y where x is not a class but y is. -// CHECK-LABEL: sil shared {{.*}}@$s30specialize_checked_cast_branch011ArchetypeToE4Cast2t12t2q_x_q_tr0_lFAA8NotUInt8V_AA1CCTg5 : $@convention(thin) (NotUInt8, @guaranteed C) -> @owned C { +// CHECK-LABEL: sil shared @$s30specialize_checked_cast_branch011ArchetypeToE4Cast2t12t2q_x_q_tr0_lFAA8NotUInt8V_AA1CCTg5 : $@convention(thin) (NotUInt8, @guaranteed C) -> @owned C { // CHECK: bb0 // CHECK-NOT: bb1 // CHECK: cond_fail {{%.*}}, "precondition failure" @@ -64,7 +64,7 @@ _ = ArchetypeToArchetypeCast(t1: b, t2: f) _ = ArchetypeToArchetypeCast(t1: b, t2: c) // y -> x where x is a class but y is not. -// CHECK-LABEL: sil shared {{.*}}@$s30specialize_checked_cast_branch011ArchetypeToE4Cast2t12t2q_x_q_tr0_lFAA1CC_AA8NotUInt8VTg5 : $@convention(thin) (@guaranteed C, NotUInt8) -> NotUInt8 { +// CHECK-LABEL: sil shared @$s30specialize_checked_cast_branch011ArchetypeToE4Cast2t12t2q_x_q_tr0_lFAA1CC_AA8NotUInt8VTg5 : $@convention(thin) (@guaranteed C, NotUInt8) -> NotUInt8 { // CHECK: bb0 // CHECK-NOT: bb1 // CHECK: cond_fail {{%.*}}, "precondition failure" @@ -73,7 +73,7 @@ _ = ArchetypeToArchetypeCast(t1: b, t2: c) _ = ArchetypeToArchetypeCast(t1: c, t2: b) // y -> x where x is a super class of y. -// CHECK-LABEL: sil shared {{.*}}@$s30specialize_checked_cast_branch011ArchetypeToE4Cast2t12t2q_x_q_tr0_lFAA1DC_AA1CCTg5 : $@convention(thin) (@guaranteed D, @guaranteed C) -> @owned C { +// CHECK-LABEL: sil shared @$s30specialize_checked_cast_branch011ArchetypeToE4Cast2t12t2q_x_q_tr0_lFAA1DC_AA1CCTg5 : $@convention(thin) (@guaranteed D, @guaranteed C) -> @owned C { // CHECK: [[T1:%.*]] = upcast %0 : $D to $C // CHECK: strong_retain %0 : $D // CHECK: return [[T1]] : $C @@ -81,7 +81,7 @@ _ = ArchetypeToArchetypeCast(t1: c, t2: b) _ = ArchetypeToArchetypeCast(t1: d, t2: c) // x -> y where x and y are unrelated. -// CHECK-LABEL: sil shared {{.*}}@$s30specialize_checked_cast_branch011ArchetypeToE4Cast2t12t2q_x_q_tr0_lFAA1CC_AA1ECTg5 : $@convention(thin) (@guaranteed C, @guaranteed E) -> @owned E { +// CHECK-LABEL: sil shared @$s30specialize_checked_cast_branch011ArchetypeToE4Cast2t12t2q_x_q_tr0_lFAA1CC_AA1ECTg5 : $@convention(thin) (@guaranteed C, @guaranteed E) -> @owned E { // CHECK: bb0 // CHECK-NOT: bb1 // CHECK: cond_fail {{%.*}}, "precondition failure" @@ -148,7 +148,7 @@ _ = ArchetypeToConcreteCastUInt8(t: f) _ = ArchetypeToConcreteCastC(t: b) // C -> C -// CHECK-LABEL: sil shared {{.*}}@$s30specialize_checked_cast_branch24ArchetypeToConcreteCastC1tAA1CCx_tlFAE_Tg5 : $@convention(thin) (@guaranteed C) -> @owned C { +// CHECK-LABEL: sil shared @$s30specialize_checked_cast_branch24ArchetypeToConcreteCastC1tAA1CCx_tlFAE_Tg5 : $@convention(thin) (@guaranteed C) -> @owned C { // CHECK: bb0([[ARG:%.*]] : $C) // CHECK: strong_retain [[ARG]] // CHECK: return [[ARG]] : $C @@ -156,7 +156,7 @@ _ = ArchetypeToConcreteCastC(t: b) _ = ArchetypeToConcreteCastC(t: c) // D -> C -// CHECK-LABEL: sil shared {{.*}}@$s30specialize_checked_cast_branch24ArchetypeToConcreteCastC1tAA1CCx_tlFAA1DC_Tg5 : $@convention(thin) (@guaranteed D) -> @owned C { +// CHECK-LABEL: sil shared @$s30specialize_checked_cast_branch24ArchetypeToConcreteCastC1tAA1CCx_tlFAA1DC_Tg5 : $@convention(thin) (@guaranteed D) -> @owned C { // CHECK: bb0([[ARG:%.*]] : $D): // CHECK: [[CAST:%.*]] = upcast [[ARG]] : $D to $C // CHECK: strong_retain [[ARG]] @@ -165,7 +165,7 @@ _ = ArchetypeToConcreteCastC(t: c) _ = ArchetypeToConcreteCastC(t: d) // E -> C -// CHECK-LABEL: sil shared {{.*}}@$s30specialize_checked_cast_branch24ArchetypeToConcreteCastC1tAA1CCx_tlFAA1EC_Tg5 : $@convention(thin) (@guaranteed E) -> @owned C { +// CHECK-LABEL: sil shared @$s30specialize_checked_cast_branch24ArchetypeToConcreteCastC1tAA1CCx_tlFAA1EC_Tg5 : $@convention(thin) (@guaranteed E) -> @owned C { // CHECK: bb0 // CHECK: cond_fail {{%.*}}, "precondition failure" // CHECK: unreachable @@ -188,7 +188,7 @@ _ = ArchetypeToConcreteCastC(t: e) _ = ArchetypeToConcreteCastD(t: c) // C -> E -// CHECK-LABEL: sil shared {{.*}}@$s30specialize_checked_cast_branch24ArchetypeToConcreteCastE1tAA1ECx_tlFAA1CC_Tg5 : $@convention(thin) (@guaranteed C) -> @owned E { +// CHECK-LABEL: sil shared @$s30specialize_checked_cast_branch24ArchetypeToConcreteCastE1tAA1ECx_tlFAA1CC_Tg5 : $@convention(thin) (@guaranteed C) -> @owned E { // CHECK: bb0 // CHECK: cond_fail {{%.*}}, "precondition failure" // CHECK: unreachable @@ -233,33 +233,33 @@ _ = ConcreteToArchetypeCastUInt8(t: b, t2: b) // CHECK: } // end sil function '$s30specialize_checked_cast_branch28ConcreteToArchetypeCastUInt81t2t2xAA03NotI0V_xtlFAA0K6UInt64V_Tg5 _ = ConcreteToArchetypeCastUInt8(t: b, t2: f) -// CHECK-LABEL: sil shared {{.*}}@$s30specialize_checked_cast_branch28ConcreteToArchetypeCastUInt81t2t2xAA03NotI0V_xtlFAA1CC_Tg5 : $@convention(thin) (NotUInt8, @guaranteed C) -> @owned C +// CHECK-LABEL: sil shared @$s30specialize_checked_cast_branch28ConcreteToArchetypeCastUInt81t2t2xAA03NotI0V_xtlFAA1CC_Tg5 : $@convention(thin) (NotUInt8, @guaranteed C) -> @owned C // CHECK: bb0 // CHECK: unreachable _ = ConcreteToArchetypeCastUInt8(t: b, t2: c) -// CHECK-LABEL: sil shared {{.*}}@$s30specialize_checked_cast_branch24ConcreteToArchetypeCastC1t2t2xAA1CC_xtlFAF_Tg5 : $@convention(thin) (@guaranteed C, @guaranteed C) -> @owned C +// CHECK-LABEL: sil shared @$s30specialize_checked_cast_branch24ConcreteToArchetypeCastC1t2t2xAA1CC_xtlFAF_Tg5 : $@convention(thin) (@guaranteed C, @guaranteed C) -> @owned C // CHECK: bb0 // CHECK: return %0 _ = ConcreteToArchetypeCastC(t: c, t2: c) -// CHECK-LABEL: sil shared {{.*}}@$s30specialize_checked_cast_branch24ConcreteToArchetypeCastC1t2t2xAA1CC_xtlFAA8NotUInt8V_Tg5 : $@convention(thin) (@guaranteed C, NotUInt8) -> NotUInt8 +// CHECK-LABEL: sil shared @$s30specialize_checked_cast_branch24ConcreteToArchetypeCastC1t2t2xAA1CC_xtlFAA8NotUInt8V_Tg5 : $@convention(thin) (@guaranteed C, NotUInt8) -> NotUInt8 // CHECK: bb0 // CHECK: unreachable _ = ConcreteToArchetypeCastC(t: c, t2: b) -// CHECK-LABEL: sil shared {{.*}}@$s30specialize_checked_cast_branch24ConcreteToArchetypeCastC1t2t2xAA1CC_xtlFAA1DC_Tg5 : $@convention(thin) (@guaranteed C, @guaranteed D) -> @owned D +// CHECK-LABEL: sil shared @$s30specialize_checked_cast_branch24ConcreteToArchetypeCastC1t2t2xAA1CC_xtlFAA1DC_Tg5 : $@convention(thin) (@guaranteed C, @guaranteed D) -> @owned D // CHECK: bb0 // CHECK: checked_cast_br %0 : $C to D // CHECK: bb1 _ = ConcreteToArchetypeCastC(t: c, t2: d) -// CHECK-LABEL: sil shared {{.*}}@$s30specialize_checked_cast_branch24ConcreteToArchetypeCastC1t2t2xAA1CC_xtlFAA1EC_Tg5 : $@convention(thin) (@guaranteed C, @guaranteed E) -> @owned E +// CHECK-LABEL: sil shared @$s30specialize_checked_cast_branch24ConcreteToArchetypeCastC1t2t2xAA1CC_xtlFAA1EC_Tg5 : $@convention(thin) (@guaranteed C, @guaranteed E) -> @owned E // CHECK: bb0 // CHECK: unreachable _ = ConcreteToArchetypeCastC(t: c, t2: e) -// CHECK-LABEL: sil shared {{.*}}@$s30specialize_checked_cast_branch24ConcreteToArchetypeCastD1t2t2xAA1DC_xtlFAA1CC_Tg5 : $@convention(thin) (@guaranteed D, @guaranteed C) -> @owned C +// CHECK-LABEL: sil shared @$s30specialize_checked_cast_branch24ConcreteToArchetypeCastD1t2t2xAA1DC_xtlFAA1CC_Tg5 : $@convention(thin) (@guaranteed D, @guaranteed C) -> @owned C // CHECK: bb0 // CHECK: [[T0:%.*]] = upcast %0 : $D to $C // CHECK: return [[T0]] @@ -283,29 +283,29 @@ func SuperToArchetypeCastD(d : D, t : T) -> T { preconditionFailure("??? Profit?") } -// CHECK-LABEL: sil shared {{.*}}@$s30specialize_checked_cast_branch21SuperToArchetypeCastC1c1txAA1CC_xtlFAF_Tg5 : $@convention(thin) (@guaranteed C, @guaranteed C) -> @owned C +// CHECK-LABEL: sil shared @$s30specialize_checked_cast_branch21SuperToArchetypeCastC1c1txAA1CC_xtlFAF_Tg5 : $@convention(thin) (@guaranteed C, @guaranteed C) -> @owned C // CHECK: bb0 // CHECK: return %0 : $C _ = SuperToArchetypeCastC(c: c, t: c) -// CHECK-LABEL: sil shared {{.*}}@$s30specialize_checked_cast_branch21SuperToArchetypeCastC1c1txAA1CC_xtlFAA1DC_Tg5 : $@convention(thin) (@guaranteed C, @guaranteed D) -> @owned D +// CHECK-LABEL: sil shared @$s30specialize_checked_cast_branch21SuperToArchetypeCastC1c1txAA1CC_xtlFAA1DC_Tg5 : $@convention(thin) (@guaranteed C, @guaranteed D) -> @owned D // CHECK: bb0 // CHECK: checked_cast_br %0 : $C to D // CHECK: bb1 _ = SuperToArchetypeCastC(c: c, t: d) -// CHECK-LABEL: sil shared {{.*}}@$s30specialize_checked_cast_branch21SuperToArchetypeCastC1c1txAA1CC_xtlFAA8NotUInt8V_Tg5 : $@convention(thin) (@guaranteed C, NotUInt8) -> NotUInt8 +// CHECK-LABEL: sil shared @$s30specialize_checked_cast_branch21SuperToArchetypeCastC1c1txAA1CC_xtlFAA8NotUInt8V_Tg5 : $@convention(thin) (@guaranteed C, NotUInt8) -> NotUInt8 // CHECK: bb0 // CHECK: unreachable _ = SuperToArchetypeCastC(c: c, t: b) -// CHECK-LABEL: sil shared {{.*}}@$s30specialize_checked_cast_branch21SuperToArchetypeCastD1d1txAA1DC_xtlFAA1CC_Tg5 : $@convention(thin) (@guaranteed D, @guaranteed C) -> @owned C +// CHECK-LABEL: sil shared @$s30specialize_checked_cast_branch21SuperToArchetypeCastD1d1txAA1DC_xtlFAA1CC_Tg5 : $@convention(thin) (@guaranteed D, @guaranteed C) -> @owned C // CHECK: bb0 // CHECK: [[T0:%.*]] = upcast %0 : $D to $C // CHECK: return [[T0]] _ = SuperToArchetypeCastD(d: d, t: c) -// CHECK-LABEL: sil shared {{.*}}@$s30specialize_checked_cast_branch21SuperToArchetypeCastD1d1txAA1DC_xtlFAF_Tg5 : $@convention(thin) (@guaranteed D, @guaranteed D) -> @owned D +// CHECK-LABEL: sil shared @$s30specialize_checked_cast_branch21SuperToArchetypeCastD1d1txAA1DC_xtlFAF_Tg5 : $@convention(thin) (@guaranteed D, @guaranteed D) -> @owned D // CHECK: bb0 // CHECK: return %0 : $D _ = SuperToArchetypeCastD(d: d, t: d) @@ -321,7 +321,7 @@ func ExistentialToArchetypeCast(o : AnyObject, t : T) -> T { preconditionFailure("??? Profit?") } -// CHECK-LABEL: sil shared {{.*}}@$s30specialize_checked_cast_branch26ExistentialToArchetypeCast1o1txyXl_xtlFAA1CC_Tg5 : $@convention(thin) (@guaranteed AnyObject, @guaranteed C) -> @owned C +// CHECK-LABEL: sil shared @$s30specialize_checked_cast_branch26ExistentialToArchetypeCast1o1txyXl_xtlFAA1CC_Tg5 : $@convention(thin) (@guaranteed AnyObject, @guaranteed C) -> @owned C // CHECK: bb0 // CHECK: checked_cast_br %0 : $AnyObject to C // CHECK: bb1 @@ -333,7 +333,7 @@ _ = ExistentialToArchetypeCast(o: o, t: c) // CHECK: bb1 _ = ExistentialToArchetypeCast(o: o, t: b) -// CHECK-LABEL: sil shared {{.*}}@$s30specialize_checked_cast_branch26ExistentialToArchetypeCast1o1txyXl_xtlFyXl_Tg5 : $@convention(thin) (@guaranteed AnyObject, @guaranteed AnyObject) -> @owned AnyObject +// CHECK-LABEL: sil shared @$s30specialize_checked_cast_branch26ExistentialToArchetypeCast1o1txyXl_xtlFyXl_Tg5 : $@convention(thin) (@guaranteed AnyObject, @guaranteed AnyObject) -> @owned AnyObject // CHECK: bb0 // CHECK-NOT: checked_cast_br % // CHECK: return %0 : $AnyObject diff --git a/test/SILOptimizer/specialize_opaque_type_archetypes.swift b/test/SILOptimizer/specialize_opaque_type_archetypes.swift index 1fc79e1b939..2515868cb57 100644 --- a/test/SILOptimizer/specialize_opaque_type_archetypes.swift +++ b/test/SILOptimizer/specialize_opaque_type_archetypes.swift @@ -48,7 +48,7 @@ func identity(_ t: T) -> T { return t } -// CHECK-LABEL: sil {{.*}}@$s1A10testFooBaryyxAA1PRzlF : $@convention(thin) (@in_guaranteed T) -> () { +// CHECK-LABEL: sil @$s1A10testFooBaryyxAA1PRzlF : $@convention(thin) (@in_guaranteed T) -> () { // CHECK: bb3([[FOOS_INT:%.*]] : $Builtin.Int64): // CHECK: [[FOO_RES:%.*]] = struct $Int64 ([[FOOS_INT]] : $Builtin.Int64) // CHECK: [[ID:%.*]] = function_ref @$s1A8identityyxxlFs5Int64V_Tg5 : $@convention(thin) (Int64) -> Int64 diff --git a/test/SILOptimizer/specialize_unconditional_checked_cast.swift b/test/SILOptimizer/specialize_unconditional_checked_cast.swift index 2e2af8aceea..f19a713a28a 100644 --- a/test/SILOptimizer/specialize_unconditional_checked_cast.swift +++ b/test/SILOptimizer/specialize_unconditional_checked_cast.swift @@ -42,36 +42,36 @@ ArchetypeToArchetype(t: b, t2: f) // CHECK-NOT: unconditional_checked_cast archetype_to_archetype // x -> x where x is a class. -// CHECK-LABEL: sil shared [noinline] {{.*}}@$s37specialize_unconditional_checked_cast011ArchetypeToE0{{[_0-9a-zA-Z]*}}FAA1CC{{.*}}Tg5 : $@convention(thin) (@guaranteed C, @guaranteed C) -> @owned C { +// CHECK-LABEL: sil shared [noinline] @$s37specialize_unconditional_checked_cast011ArchetypeToE0{{[_0-9a-zA-Z]*}}FAA1CC{{.*}}Tg5 : $@convention(thin) (@guaranteed C, @guaranteed C) -> @owned C { // CHECK-NOT: unconditional_checked_cast archetype_to_archetype // x -> y where x is not a class but y is. -// CHECK-LABEL: sil shared [noinline] {{.*}}@$s37specialize_unconditional_checked_cast011ArchetypeToE0{{[_0-9a-zA-Z]*}}FAA8NotUInt8V_AA1CCTg5 : $@convention(thin) (NotUInt8, @guaranteed C) -> @owned C { +// CHECK-LABEL: sil shared [noinline] @$s37specialize_unconditional_checked_cast011ArchetypeToE0{{[_0-9a-zA-Z]*}}FAA8NotUInt8V_AA1CCTg5 : $@convention(thin) (NotUInt8, @guaranteed C) -> @owned C { // CHECK-NOT: unconditional_checked_cast_addr // CHECK-NOT: unconditional_checked_cast_addr // CHECK: builtin "int_trap" // CHECK-NOT: unconditional_checked_cast_addr // y -> x where x is not a class but y is. -// CHECK-LABEL: sil shared [noinline] {{.*}}@$s37specialize_unconditional_checked_cast011ArchetypeToE0{{[_0-9a-zA-Z]*}}FAA1CC_AA8NotUInt8VTg5 : $@convention(thin) (@guaranteed C, NotUInt8) -> NotUInt8 { +// CHECK-LABEL: sil shared [noinline] @$s37specialize_unconditional_checked_cast011ArchetypeToE0{{[_0-9a-zA-Z]*}}FAA1CC_AA8NotUInt8VTg5 : $@convention(thin) (@guaranteed C, NotUInt8) -> NotUInt8 { // CHECK-NOT: unconditional_checked_cast archetype_to_archetype // CHECK: builtin "int_trap" // CHECK-NOT: unconditional_checked_cast archetype_to_archetype // x -> y where x is a super class of y. -// CHECK-LABEL: sil shared [noinline] {{.*}}@$s37specialize_unconditional_checked_cast011ArchetypeToE0{{[_0-9a-zA-Z]*}}FAA1CC_AA1DCTg5 : $@convention(thin) (@guaranteed C, @guaranteed D) -> @owned D { +// CHECK-LABEL: sil shared [noinline] @$s37specialize_unconditional_checked_cast011ArchetypeToE0{{[_0-9a-zA-Z]*}}FAA1CC_AA1DCTg5 : $@convention(thin) (@guaranteed C, @guaranteed D) -> @owned D { // CHECK: [[STACK:%[0-9]+]] = alloc_stack $C // TODO: This should be optimized to an unconditional_checked_cast without the need of alloc_stack: rdar://problem/24775038 // CHECK: unconditional_checked_cast_addr C in [[STACK]] : $*C to D in // y -> x where x is a super class of y. -// CHECK-LABEL: sil shared [noinline] {{.*}}@$s37specialize_unconditional_checked_cast011ArchetypeToE0{{[_0-9a-zA-Z]*}}FAA1DC_AA1CCTg5 : $@convention(thin) (@guaranteed D, @guaranteed C) -> @owned C { +// CHECK-LABEL: sil shared [noinline] @$s37specialize_unconditional_checked_cast011ArchetypeToE0{{[_0-9a-zA-Z]*}}FAA1DC_AA1CCTg5 : $@convention(thin) (@guaranteed D, @guaranteed C) -> @owned C { // CHECK-NOT: unconditional_checked_cast archetype_to_archetype // CHECK: upcast {{%[0-9]+}} : $D to $C // CHECK-NOT: unconditional_checked_cast archetype_to_archetype // x -> y where x and y are unrelated classes. -// CHECK-LABEL: sil shared [noinline] {{.*}}@$s37specialize_unconditional_checked_cast011ArchetypeToE0{{[_0-9a-zA-Z]*}}FAA1CC_AA1ECTg5 : $@convention(thin) (@guaranteed C, @guaranteed E) -> @owned E { +// CHECK-LABEL: sil shared [noinline] @$s37specialize_unconditional_checked_cast011ArchetypeToE0{{[_0-9a-zA-Z]*}}FAA1CC_AA1ECTg5 : $@convention(thin) (@guaranteed C, @guaranteed E) -> @owned E { // CHECK-NOT: unconditional_checked_cast archetype_to_archetype // CHECK: builtin "int_trap" // CHECK-NOT: unconditional_checked_cast archetype_to_archetype @@ -103,7 +103,7 @@ ArchetypeToConcreteConvertUInt8(t: f) // CHECK-NEXT: return %0 // x -> y where y is a class but x is not. -// CHECK-LABEL: sil shared [noinline] {{.*}}@$s37specialize_unconditional_checked_cast31ArchetypeToConcreteConvertUInt8{{[_0-9a-zA-Z]*}}FAA1CC_Tg5 +// CHECK-LABEL: sil shared [noinline] @$s37specialize_unconditional_checked_cast31ArchetypeToConcreteConvertUInt8{{[_0-9a-zA-Z]*}}FAA1CC_Tg5 // CHECK: bb0 // CHECK: builtin "int_trap" // CHECK: unreachable @@ -117,7 +117,7 @@ ArchetypeToConcreteConvertUInt8(t: f) // CHECK-NEXT: } // x -> x where x is a class. -// CHECK-LABEL: sil shared [noinline] {{.*}}@$s37specialize_unconditional_checked_cast27ArchetypeToConcreteConvertC{{[_0-9a-zA-Z]*}}Tg5 : $@convention(thin) (@guaranteed C) -> @owned C { +// CHECK-LABEL: sil shared [noinline] @$s37specialize_unconditional_checked_cast27ArchetypeToConcreteConvertC{{[_0-9a-zA-Z]*}}Tg5 : $@convention(thin) (@guaranteed C) -> @owned C { // CHECK: bb0([[ARG:%.*]] : $C) // CHECK-NEXT: debug_value [[ARG]] // CHECK-NEXT: strong_retain [[ARG]] @@ -131,7 +131,7 @@ ArchetypeToConcreteConvertUInt8(t: f) // CHECK-NEXT: } // x -> y where x,y are classes and x is a super class of y. -// CHECK-LABEL: sil shared [noinline] {{.*}}@$s37specialize_unconditional_checked_cast27ArchetypeToConcreteConvertC{{[_0-9a-zA-Z]*}}FAA1DC_Tg5 : $@convention(thin) (@guaranteed D) -> @owned C { +// CHECK-LABEL: sil shared [noinline] @$s37specialize_unconditional_checked_cast27ArchetypeToConcreteConvertC{{[_0-9a-zA-Z]*}}FAA1DC_Tg5 : $@convention(thin) (@guaranteed D) -> @owned C { // CHECK: bb0([[ARG:%.*]] : $D): // CHECK: [[UPCAST:%.*]] = upcast [[ARG]] : $D to $C // CHECK: strong_retain [[ARG]] @@ -139,7 +139,7 @@ ArchetypeToConcreteConvertUInt8(t: f) // CHECK: } // end sil function '$s37specialize_unconditional_checked_cast27ArchetypeToConcreteConvertC{{[_0-9a-zA-Z]*}}FAA1DC_Tg5' // x -> y where x,y are classes, but x is unrelated to y. -// CHECK-LABEL: sil shared [noinline] {{.*}}@$s37specialize_unconditional_checked_cast27ArchetypeToConcreteConvertC{{[_0-9a-zA-Z]*}}FAA1EC_Tg5 +// CHECK-LABEL: sil shared [noinline] @$s37specialize_unconditional_checked_cast27ArchetypeToConcreteConvertC{{[_0-9a-zA-Z]*}}FAA1EC_Tg5 // CHECK: bb0 // CHECK: builtin "int_trap" // CHECK: unreachable @@ -183,7 +183,7 @@ ArchetypeToConcreteConvertE(t: c) // x -> y where x,y are classes, but y is unrelated to x. The idea is // to make sure that the fact that y is concrete does not affect the // result. -// CHECK-LABEL: sil shared [noinline] {{.*}}@$s37specialize_unconditional_checked_cast27ArchetypeToConcreteConvertE{{[_0-9a-zA-Z]*}}FAA1CC_Tg5 +// CHECK-LABEL: sil shared [noinline] @$s37specialize_unconditional_checked_cast27ArchetypeToConcreteConvertE{{[_0-9a-zA-Z]*}}FAA1CC_Tg5 // CHECK: bb0 // CHECK: builtin "int_trap" // CHECK: unreachable @@ -210,7 +210,7 @@ ConcreteToArchetypeConvertUInt8(t: b, t2: f) // CHECK: return %0 // x -> y where x is not a class but y is a class. -// CHECK-LABEL: sil shared [noinline] {{.*}}@$s37specialize_unconditional_checked_cast31ConcreteToArchetypeConvertUInt8{{[_0-9a-zA-Z]*}}FAA1CC_Tg5 : $@convention(thin) (NotUInt8, @guaranteed C) -> @owned C { +// CHECK-LABEL: sil shared [noinline] @$s37specialize_unconditional_checked_cast31ConcreteToArchetypeConvertUInt8{{[_0-9a-zA-Z]*}}FAA1CC_Tg5 : $@convention(thin) (NotUInt8, @guaranteed C) -> @owned C { // CHECK: bb0 // CHECK: builtin "int_trap" // CHECK: unreachable @@ -235,19 +235,19 @@ ConcreteToArchetypeConvertC(t: c, t2: e) // x -> x where x is a class. -// CHECK-LABEL: sil shared [noinline] {{.*}}@$s37specialize_unconditional_checked_cast27ConcreteToArchetypeConvertC{{[_0-9a-zA-Z]*}}Tg5 : $@convention(thin) (@guaranteed C, @guaranteed C) -> @owned C { +// CHECK-LABEL: sil shared [noinline] @$s37specialize_unconditional_checked_cast27ConcreteToArchetypeConvertC{{[_0-9a-zA-Z]*}}Tg5 : $@convention(thin) (@guaranteed C, @guaranteed C) -> @owned C { // CHECK: bb0(%0 : $C, %1 : $C): // CHECK: return %0 // x -> y where x is a class but y is not. -// CHECK-LABEL: sil shared [noinline] {{.*}}@$s37specialize_unconditional_checked_cast27ConcreteToArchetypeConvertC{{[_0-9a-zA-Z]*}}Not{{.*}}Tg5 : $@convention(thin) (@guaranteed C, NotUInt8) -> NotUInt8 { +// CHECK-LABEL: sil shared [noinline] @$s37specialize_unconditional_checked_cast27ConcreteToArchetypeConvertC{{[_0-9a-zA-Z]*}}Not{{.*}}Tg5 : $@convention(thin) (@guaranteed C, NotUInt8) -> NotUInt8 { // CHECK: bb0 // CHECK: builtin "int_trap" // CHECK: unreachable // CHECK-NEXT: } // x -> y where x is a super class of y. -// CHECK-LABEL: sil shared [noinline] {{.*}}@$s37specialize_unconditional_checked_cast27ConcreteToArchetypeConvertC{{[_0-9a-zA-Z]*}}FAA1DC_Tg5 : $@convention(thin) (@guaranteed C, @guaranteed D) -> @owned D { +// CHECK-LABEL: sil shared [noinline] @$s37specialize_unconditional_checked_cast27ConcreteToArchetypeConvertC{{[_0-9a-zA-Z]*}}FAA1DC_Tg5 : $@convention(thin) (@guaranteed C, @guaranteed D) -> @owned D { // CHECK: bb0(%0 : $C, %1 : $D): // CHECK-DAG: [[STACK_C:%[0-9]+]] = alloc_stack $C // CHECK-DAG: store %0 to [[STACK_C]] @@ -258,7 +258,7 @@ ConcreteToArchetypeConvertC(t: c, t2: e) // CHECK: return [[LOAD]] // x -> y where x and y are unrelated classes. -// CHECK-LABEL: sil shared [noinline] {{.*}}@$s37specialize_unconditional_checked_cast27ConcreteToArchetypeConvertC{{[_0-9a-zA-Z]*}}FAA1EC_Tg5 : $@convention(thin) (@guaranteed C, @guaranteed E) -> @owned E { +// CHECK-LABEL: sil shared [noinline] @$s37specialize_unconditional_checked_cast27ConcreteToArchetypeConvertC{{[_0-9a-zA-Z]*}}FAA1EC_Tg5 : $@convention(thin) (@guaranteed C, @guaranteed E) -> @owned E { // CHECK: bb0(%0 : $C, %1 : $E): // CHECK: builtin "int_trap" // CHECK-NEXT: unreachable @@ -272,7 +272,7 @@ public func ConcreteToArchetypeConvertD(t t: D, t2: T) -> T { ConcreteToArchetypeConvertD(t: d, t2: c) // x -> y where x is a subclass of y. -// CHECK-LABEL: sil shared [noinline] {{.*}}@$s37specialize_unconditional_checked_cast27ConcreteToArchetypeConvertD{{[_0-9a-zA-Z]*}}FAA1CC_Tg5 : $@convention(thin) (@guaranteed D, @guaranteed C) -> @owned C { +// CHECK-LABEL: sil shared [noinline] @$s37specialize_unconditional_checked_cast27ConcreteToArchetypeConvertD{{[_0-9a-zA-Z]*}}FAA1CC_Tg5 : $@convention(thin) (@guaranteed D, @guaranteed C) -> @owned C { // CHECK: bb0(%0 : $D, %1 : $C): // CHECK-DAG: [[UC:%[0-9]+]] = upcast %0 // CHECK: return [[UC]] @@ -293,17 +293,17 @@ SuperToArchetypeC(c: c, t: b) // x -> x where x is a class. -// CHECK-LABEL: sil shared [noinline] {{.*}}@$s37specialize_unconditional_checked_cast17SuperToArchetypeC{{[_0-9a-zA-Z]*}}Tg5 : $@convention(thin) (@guaranteed C, @guaranteed C) -> @owned C { +// CHECK-LABEL: sil shared [noinline] @$s37specialize_unconditional_checked_cast17SuperToArchetypeC{{[_0-9a-zA-Z]*}}Tg5 : $@convention(thin) (@guaranteed C, @guaranteed C) -> @owned C { // CHECK: bb0(%0 : $C, %1 : $C): // CHECK: return %0 // x -> y where x is a super class of y. -// CHECK-LABEL: sil shared [noinline] {{.*}}@$s37specialize_unconditional_checked_cast17SuperToArchetypeC{{[_0-9a-zA-Z]*}}FAA1DC_Tg5 : $@convention(thin) (@guaranteed C, @guaranteed D) -> @owned D { +// CHECK-LABEL: sil shared [noinline] @$s37specialize_unconditional_checked_cast17SuperToArchetypeC{{[_0-9a-zA-Z]*}}FAA1DC_Tg5 : $@convention(thin) (@guaranteed C, @guaranteed D) -> @owned D { // CHECK: bb0 // CHECK: unconditional_checked_cast_addr C in // x -> y where x is a class and y is not. -// CHECK-LABEL: sil shared [noinline] {{.*}}@$s37specialize_unconditional_checked_cast17SuperToArchetypeC{{[_0-9a-zA-Z]*}}FAA8NotUInt8V_Tg5 : $@convention(thin) (@guaranteed C, NotUInt8) -> NotUInt8 { +// CHECK-LABEL: sil shared [noinline] @$s37specialize_unconditional_checked_cast17SuperToArchetypeC{{[_0-9a-zA-Z]*}}FAA8NotUInt8V_Tg5 : $@convention(thin) (@guaranteed C, NotUInt8) -> NotUInt8 { // CHECK: bb0 // CHECK: builtin "int_trap" // CHECK: unreachable @@ -319,12 +319,12 @@ SuperToArchetypeD(d: d, t: d) // *NOTE* The frontend is smart enough to turn this into an upcast. When this // test is converted to SIL, this should be fixed appropriately. -// CHECK-LABEL: sil shared [noinline] {{.*}}@$s37specialize_unconditional_checked_cast17SuperToArchetypeD{{[_0-9a-zA-Z]*}}FAA1CC_Tg5 : $@convention(thin) (@guaranteed D, @guaranteed C) -> @owned C { +// CHECK-LABEL: sil shared [noinline] @$s37specialize_unconditional_checked_cast17SuperToArchetypeD{{[_0-9a-zA-Z]*}}FAA1CC_Tg5 : $@convention(thin) (@guaranteed D, @guaranteed C) -> @owned C { // CHECK-NOT: unconditional_checked_cast super_to_archetype // CHECK: upcast // CHECK-NOT: unconditional_checked_cast super_to_archetype -// CHECK-LABEL: sil shared [noinline] {{.*}}@$s37specialize_unconditional_checked_cast17SuperToArchetypeD{{[_0-9a-zA-Z]*}}Tg5 : $@convention(thin) (@guaranteed D, @guaranteed D) -> @owned D { +// CHECK-LABEL: sil shared [noinline] @$s37specialize_unconditional_checked_cast17SuperToArchetypeD{{[_0-9a-zA-Z]*}}Tg5 : $@convention(thin) (@guaranteed D, @guaranteed D) -> @owned D { // CHECK: bb0(%0 : $D, %1 : $D): // CHECK: return %0 @@ -338,7 +338,7 @@ public func ExistentialToArchetype(o o : AnyObject, t : T) -> T { } // AnyObject -> Class. -// CHECK-LABEL: sil shared [noinline] {{.*}}@$s37specialize_unconditional_checked_cast22ExistentialToArchetype{{[_0-9a-zA-Z]*}}FAA1CC_Tg5 : $@convention(thin) (@guaranteed AnyObject, @guaranteed C) -> @owned C { +// CHECK-LABEL: sil shared [noinline] @$s37specialize_unconditional_checked_cast22ExistentialToArchetype{{[_0-9a-zA-Z]*}}FAA1CC_Tg5 : $@convention(thin) (@guaranteed AnyObject, @guaranteed C) -> @owned C { // CHECK: unconditional_checked_cast_addr AnyObject in {{%.*}} : $*AnyObject to C // AnyObject -> Non Class (should always fail) @@ -348,7 +348,7 @@ public func ExistentialToArchetype(o o : AnyObject, t : T) -> T { // CHECK: return // AnyObject -> AnyObject -// CHECK-LABEL: sil shared [noinline] {{.*}}@$s37specialize_unconditional_checked_cast22ExistentialToArchetype{{[_0-9a-zA-Z]*}}yXl{{.*}}Tg5 : $@convention(thin) (@guaranteed AnyObject, @guaranteed AnyObject) -> @owned AnyObject { +// CHECK-LABEL: sil shared [noinline] @$s37specialize_unconditional_checked_cast22ExistentialToArchetype{{[_0-9a-zA-Z]*}}yXl{{.*}}Tg5 : $@convention(thin) (@guaranteed AnyObject, @guaranteed AnyObject) -> @owned AnyObject { // CHECK: bb0(%0 : $AnyObject, %1 : $AnyObject): // CHECK: return %0 diff --git a/test/SILOptimizer/stack_promotion.sil b/test/SILOptimizer/stack_promotion.sil index 23b2581941f..30d02cacd0f 100644 --- a/test/SILOptimizer/stack_promotion.sil +++ b/test/SILOptimizer/stack_promotion.sil @@ -1,6 +1,4 @@ -// rdar://92120075 -// XFAIL OS=windows -// RUN: %target-sil-opt -compute-effects -stack-promotion -enable-sil-verify-all %s | %FileCheck %s +// RUN: %target-sil-opt -stack-promotion -enable-sil-verify-all %s | %FileCheck %s sil_stage canonical @@ -247,7 +245,7 @@ bb2: return %t : $() } -// CHECK-LABEL: sil {{.*}} @dont_promote_use_before_alloc +// CHECK-LABEL: sil @dont_promote_use_before_alloc // CHECK: alloc_ref $XX // CHECK-NOT: dealloc_ref // CHECK: return @@ -861,7 +859,7 @@ final class UnownedLink { @_hasStorage unowned var link: @sil_unowned UnownedLink } -// CHECK-LABEL: sil {{.*}}@dont_promote_escaping_through_unowned +// CHECK-LABEL: sil @dont_promote_escaping_through_unowned // CHECK: alloc_ref $UnownedLink // CHECK-NOT: dealloc_ref // CHECK-LABEL: } // end sil function 'dont_promote_escaping_through_unowned' diff --git a/test/SILOptimizer/stack_promotion_escaping.swift b/test/SILOptimizer/stack_promotion_escaping.swift index d978f8f3372..ae1a6f6c0d8 100644 --- a/test/SILOptimizer/stack_promotion_escaping.swift +++ b/test/SILOptimizer/stack_promotion_escaping.swift @@ -11,7 +11,7 @@ final public class Escaper { myItem = items[0] } -// CHECK-LABEL: sil [noinline] {{.*}}@$s4test7EscaperC15badStuffHappensyyF : $@convention(method) (@guaranteed Escaper) -> () { +// CHECK-LABEL: sil [noinline] @$s4test7EscaperC15badStuffHappensyyF : $@convention(method) (@guaranteed Escaper) -> () { // CHECK: %2 = alloc_ref $Item // CHECK: alloc_ref{{(_dynamic)?}} [stack] [tail_elems $Item * %{{[0-9]+}} : $Builtin.Word]{{.*}} $_ContiguousArrayStorage<{{(Item|AnyObject)}}> // CHECK: return diff --git a/test/SILOptimizer/static_arrays.swift b/test/SILOptimizer/static_arrays.swift index d8981f0756e..297c146ed6a 100644 --- a/test/SILOptimizer/static_arrays.swift +++ b/test/SILOptimizer/static_arrays.swift @@ -91,7 +91,7 @@ // CHECK: object {{.*}} ({{[^,]*}}, [tail_elems] {{[^,]*}}, {{[^,]*}}, {{[^,]*}}) // CHECK-NEXT: } -// CHECK-LABEL: sil {{.*}}@main +// CHECK-LABEL: sil @main // CHECK: global_value @{{.*}}main{{.*}} // CHECK: return public let globalVariable = [ 100, 101, 102 ] diff --git a/test/SILOptimizer/templvalueopt.swift b/test/SILOptimizer/templvalueopt.swift index 288dce6df33..0cc9d9267dd 100644 --- a/test/SILOptimizer/templvalueopt.swift +++ b/test/SILOptimizer/templvalueopt.swift @@ -21,7 +21,7 @@ internal struct AddressOnlyPayload { public struct TestStruct { internal var e: Either - // CHECK-LABEL: sil [noinline] {{.*}}@$s4test10TestStructVyACyp_SitcfC + // CHECK-LABEL: sil [noinline] @$s4test10TestStructVyACyp_SitcfC // CHECK: [[E:%[0-9]+]] = struct_element_addr %0 : $*TestStruct, #TestStruct.e // CHECK: [[LEFT:%[0-9]+]] = init_enum_data_addr [[E]] : $*Either, #Either.left!enumelt // CHECK: [[A:%[0-9]+]] = struct_element_addr [[LEFT]] : $*AddressOnlyPayload, #AddressOnlyPayload.a @@ -36,7 +36,7 @@ public struct TestStruct { } } -// CHECK-LABEL: sil [noinline] {{.*}}@$s4test13createAnyLeftyAA6EitherOyypSgSiGypF +// CHECK-LABEL: sil [noinline] @$s4test13createAnyLeftyAA6EitherOyypSgSiGypF // CHECK: [[E:%[0-9]+]] = init_enum_data_addr %0 : $*Either, Int>, #Either.left!enumelt // CHECK: [[SOME:%[0-9]+]] = init_enum_data_addr [[E]] : $*Optional, #Optional.some!enumelt // CHECK: copy_addr %1 to [initialization] [[SOME]] : $*Any